From 4696e3f9c88cdf9e025205b0b525dec8c310b671 Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 00:36:40 +0100 Subject: [PATCH 01/52] uint8 enums fixed --- src/audio/AudioLogic.cpp | 4 ++-- src/control/AutoPilot.cpp | 6 +++--- src/control/AutoPilot.h | 12 ++++++------ src/control/CarAI.cpp | 2 +- src/control/CarAI.h | 2 +- src/control/Pickups.cpp | 2 +- src/control/Pickups.h | 4 ++-- src/control/Script.cpp | 4 ++-- src/control/Script4.cpp | 2 +- src/core/World.cpp | 2 +- src/entities/Entity.h | 12 ++++++------ src/modelinfo/BaseModelInfo.h | 7 +++---- src/peds/Ped.h | 4 ++-- src/peds/PedFight.cpp | 4 ++-- src/vehicles/Cranes.h | 8 ++++---- 15 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 7340e73e..af67b561 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -52,8 +52,8 @@ uint32 gHomeNextTime; uint32 gCellNextTime; uint32 gNextCryTime; -enum PLAY_STATUS : uint8 { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; -enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; +enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED }; +enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED }; void cAudioManager::PreInitialiseGameSpecificSetup() const diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp index b1fce95f..4038c93e 100644 --- a/src/control/AutoPilot.cpp +++ b/src/control/AutoPilot.cpp @@ -103,9 +103,9 @@ void CAutoPilot::Load(uint8*& buf) m_nNextDirection = ReadSaveBuf(buf); m_nCurrentLane = ReadSaveBuf(buf); m_nNextLane = ReadSaveBuf(buf); - m_nDrivingStyle = (eCarDrivingStyle)ReadSaveBuf(buf); - m_nCarMission = (eCarMission)ReadSaveBuf(buf); - m_nTempAction = (eCarTempAction)ReadSaveBuf(buf); + m_nDrivingStyle = ReadSaveBuf(buf); + m_nCarMission = ReadSaveBuf(buf); + m_nTempAction = ReadSaveBuf(buf); m_nTimeTempAction = ReadSaveBuf(buf); m_fMaxTrafficSpeed = ReadSaveBuf(buf); m_nCruiseSpeed = ReadSaveBuf(buf); diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index 337a93c1..6349fce6 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -4,7 +4,7 @@ class CVehicle; struct CPathNode; -enum eCarMission : uint8 +enum eCarMission { MISSION_NONE, MISSION_CRUISE, @@ -28,7 +28,7 @@ enum eCarMission : uint8 MISSION_BLOCKCAR_HANDBRAKESTOP, }; -enum eCarTempAction : uint8 +enum eCarTempAction { TEMPACT_NONE, TEMPACT_WAIT, @@ -43,7 +43,7 @@ enum eCarTempAction : uint8 TEMPACT_SWERVERIGHT }; -enum eCarDrivingStyle : uint8 +enum eCarDrivingStyle { DRIVINGSTYLE_STOP_FOR_CARS, DRIVINGSTYLE_SLOW_DOWN_FOR_CARS, @@ -69,9 +69,9 @@ public: int8 m_nNextDirection; int8 m_nCurrentLane; int8 m_nNextLane; - eCarDrivingStyle m_nDrivingStyle; - eCarMission m_nCarMission; - eCarTempAction m_nTempAction; + uint8 m_nDrivingStyle; + uint8 m_nCarMission; + uint8 m_nTempAction; uint32 m_nTimeTempAction; float m_fMaxTrafficSpeed; uint8 m_nCruiseSpeed; diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp index ab44510d..8c0c5966 100644 --- a/src/control/CarAI.cpp +++ b/src/control/CarAI.cpp @@ -539,7 +539,7 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget) pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed); } -eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() +uint8 CCarAI::FindPoliceCarMissionForWantedLevel() { switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel){ case 0: diff --git a/src/control/CarAI.h b/src/control/CarAI.h index e88807c8..9b731ad5 100644 --- a/src/control/CarAI.h +++ b/src/control/CarAI.h @@ -19,7 +19,7 @@ public: static void TellOccupantsToLeaveCar(CVehicle*); static void TellCarToRamOtherCar(CVehicle*, CVehicle*); static void TellCarToBlockOtherCar(CVehicle*, CVehicle*); - static eCarMission FindPoliceCarMissionForWantedLevel(); + static uint8 FindPoliceCarMissionForWantedLevel(); static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*); static void MellowOutChaseSpeed(CVehicle*); static void MakeWayForCarWithSiren(CVehicle *veh); diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 1b1c8cbc..19b3d3a7 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -535,7 +535,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan if (slot >= NUMPICKUPS) return -1; - aPickUps[slot].m_eType = (ePickupType)type; + aPickUps[slot].m_eType = type; aPickUps[slot].m_bRemoved = false; aPickUps[slot].m_nQuantity = quantity; if (type == PICKUP_ONCE_TIMEOUT) diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 95eb6fbf..72a37d99 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -1,7 +1,7 @@ #pragma once #include "Weapon.h" -enum ePickupType : uint8 +enum ePickupType { PICKUP_NONE = 0, PICKUP_IN_SHOP, @@ -29,7 +29,7 @@ class CPlayerPed; class CPickup { public: - ePickupType m_eType; + uint8 m_eType; bool m_bRemoved; uint16 m_nQuantity; CObject *m_pObject; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index dbd477e2..1b51e0d6 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -3593,7 +3593,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(car); - car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1]; + car->AutoPilot.m_nDrivingStyle = (uint8)ScriptParams[1]; return 0; } case COMMAND_SET_CAR_MISSION: @@ -3601,7 +3601,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(car); - car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1]; + car->AutoPilot.m_nCarMission = (uint8)ScriptParams[1]; car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); car->bEngineOn = true; return 0; diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index 78da2d96..feef70bc 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -1436,7 +1436,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - pVehicle->SetStatus((eEntityStatus)ScriptParams[1]); + pVehicle->SetStatus((uint8)ScriptParams[1]); return 0; } case COMMAND_IS_CHAR_MALE: diff --git a/src/core/World.cpp b/src/core/World.cpp index 0bc564ff..981d1395 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -1537,7 +1537,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1 if(pVehicle->m_scanCode != GetCurrentScanCode()) { pVehicle->m_scanCode = GetCurrentScanCode(); const CVector &vehiclePos = pVehicle->GetPosition(); - eCarMission carMission = pVehicle->AutoPilot.m_nCarMission; + uint8 carMission = pVehicle->AutoPilot.m_nCarMission; if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX && vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer && (carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE || diff --git a/src/entities/Entity.h b/src/entities/Entity.h index ba4f7ab0..9372c85d 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -6,7 +6,7 @@ struct CReference; class CPtrList; -enum eEntityType : uint8 +enum eEntityType { ENTITY_TYPE_NOTHING = 0, ENTITY_TYPE_BUILDING, @@ -16,7 +16,7 @@ enum eEntityType : uint8 ENTITY_TYPE_DUMMY, }; -enum eEntityStatus : uint8 +enum eEntityStatus { STATUS_PLAYER, STATUS_PLAYER_PLAYBACKFROMBUFFER, @@ -92,10 +92,10 @@ public: CReference *m_pFirstReference; public: - eEntityType GetType() const { return (eEntityType)m_type; } - void SetType(eEntityType type) { m_type = type; } - eEntityStatus GetStatus() const { return (eEntityStatus)m_status; } - void SetStatus(eEntityStatus status) { m_status = status; } + uint8 GetType() const { return m_type; } + void SetType(uint8 type) { m_type = type; } + uint8 GetStatus() const { return m_status; } + void SetStatus(uint8 status) { m_status = status; } CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } bool GetIsStatic(void) const { return bIsStatic; } void SetIsStatic(bool state) { bIsStatic = state; } diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h index 4c274aaf..ae2b6668 100644 --- a/src/modelinfo/BaseModelInfo.h +++ b/src/modelinfo/BaseModelInfo.h @@ -4,7 +4,7 @@ #define MAX_MODEL_NAME (24) -enum ModelInfoType : uint8 +enum ModelInfoType { MITYPE_NA = 0, MITYPE_SIMPLE = 1, @@ -15,7 +15,6 @@ enum ModelInfoType : uint8 MITYPE_PED = 6, MITYPE_XTRACOMPS = 7, }; -VALIDATE_SIZE(ModelInfoType, 1); class C2dEffect; @@ -28,7 +27,7 @@ protected: int16 m_objectId; uint16 m_refCount; int16 m_txdSlot; - ModelInfoType m_type; + uint8 m_type; uint8 m_num2dEffects; bool m_bOwnsColModel; #ifdef EXTRA_MODEL_FLAGS @@ -50,7 +49,7 @@ public: virtual RwObject *GetRwObject(void) = 0; // one day it becomes virtual - ModelInfoType GetModelType() const { return m_type; } + uint8 GetModelType() const { return m_type; } bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; } bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE || m_type == MITYPE_MLO || m_type == MITYPE_XTRACOMPS; // unused but what the heck diff --git a/src/peds/Ped.h b/src/peds/Ped.h index a3d4997d..7a9f4a9e 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -212,7 +212,7 @@ enum PedOnGroundState { PED_DEAD_ON_THE_FLOOR }; -enum PointBlankNecessity : uint8 { +enum PointBlankNecessity { NO_POINT_BLANK_PED, POINT_BLANK_FOR_WANTED_PED, POINT_BLANK_FOR_SOMEONE_ELSE @@ -598,7 +598,7 @@ public: #endif bool CheckForExplosions(CVector2D &area); CPed *CheckForGunShots(void); - PointBlankNecessity CheckForPointBlankPeds(CPed*); + uint8 CheckForPointBlankPeds(CPed*); bool CheckIfInTheAir(void); void ClearAll(void); void SetPointGunAt(CEntity*); diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index 21310aaa..c219d94f 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -329,7 +329,7 @@ CPed::SetAttack(CEntity *victim) if (IsPlayer()) CPad::GetPad(0)->ResetAverageWeapon(); - PointBlankNecessity pointBlankStatus; + uint8 pointBlankStatus; if ((curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT || GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER) && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT @@ -475,7 +475,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) ped->ClearAttack(); } -PointBlankNecessity +uint8 CPed::CheckForPointBlankPeds(CPed *pedToVerify) { float pbDistance = 1.1f; diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h index 6d877d82..0e134310 100644 --- a/src/vehicles/Cranes.h +++ b/src/vehicles/Cranes.h @@ -11,7 +11,7 @@ class CBuilding; class CCrane { public: - enum CraneState : uint8 { + enum CraneState { IDLE = 0, GOING_TOWARDS_TARGET = 1, LIFTING_TARGET = 2, @@ -19,7 +19,7 @@ public: ROTATING_TARGET = 4, DROPPING_TARGET = 5 }; - enum CraneStatus : uint8 { + enum CraneStatus { NONE = 0, ACTIVATED = 1, DEACTIVATED = 2 @@ -47,8 +47,8 @@ public: CVector2D m_vecHookVelocity; CVehicle *m_pVehiclePickedUp; uint32 m_nTimeForNextCheck; - CraneStatus m_nCraneStatus; - CraneState m_nCraneState; + uint8 m_nCraneStatus; + uint8 m_nCraneState; uint8 m_nVehiclesCollected; bool m_bIsCrusher; bool m_bIsMilitaryCrane; From afdf8c25a05f280f524d946384cf74d69aa16e8a Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 00:56:12 +0100 Subject: [PATCH 02/52] int8 enums fixed --- src/audio/AudioLogic.cpp | 2 +- src/control/Garages.cpp | 8 ++++---- src/control/Garages.h | 20 ++++++++++---------- src/control/Script3.cpp | 6 +++--- src/control/Script4.cpp | 2 +- src/peds/Ped.h | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index af67b561..ca395136 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -8121,7 +8121,7 @@ cAudioManager::ProcessGarages() const float SOUND_INTENSITY = 80.0f; CEntity *entity; - eGarageState state; + uint8 state; uint32 sampleIndex; uint8 j; float distSquared; diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 33137c69..ff11600b 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -202,7 +202,7 @@ void CGarages::Update(void) aGarages[GarageToBeTidied].TidyUpGarage(); } -int16 CGarages::AddOne(CVector p1, CVector p2, eGarageType type, int32 targetId) +int16 CGarages::AddOne(CVector p1, CVector p2, uint8 type, int32 targetId) { if (NumGarages >= NUM_GARAGES) { assert(0); @@ -285,7 +285,7 @@ int16 CGarages::AddOne(CVector p1, CVector p2, eGarageType type, int32 targetId) return NumGarages++; } -void CGarages::ChangeGarageType(int16 garage, eGarageType type, int32 mi) +void CGarages::ChangeGarageType(int16 garage, uint8 type, int32 mi) { CGarage* pGarage = &aGarages[garage]; pGarage->m_eGarageType = type; @@ -2172,7 +2172,7 @@ void CGarages::CloseHideOutGaragesBeforeSave() } } -int32 CGarages::CountCarsInHideoutGarage(eGarageType type) +int32 CGarages::CountCarsInHideoutGarage(uint8 type) { int32 total = 0; for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) { @@ -2192,7 +2192,7 @@ int32 CGarages::CountCarsInHideoutGarage(eGarageType type) return total; } -int32 CGarages::FindMaxNumStoredCarsForGarage(eGarageType type) +int32 CGarages::FindMaxNumStoredCarsForGarage(uint8 type) { switch (type) { case GARAGE_HIDEOUT_ONE: diff --git a/src/control/Garages.h b/src/control/Garages.h index 41b2afb7..79cef36e 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -7,7 +7,7 @@ class CVehicle; class CCamera; -enum eGarageState : int8 +enum eGarageState { GS_FULLYCLOSED, GS_OPENED, @@ -18,7 +18,7 @@ enum eGarageState : int8 GS_AFTERDROPOFF, }; -enum eGarageType : int8 +enum eGarageType { GARAGE_NONE, GARAGE_MISSION, @@ -81,8 +81,8 @@ VALIDATE_SIZE(CStoredCar, 0x28); class CGarage { - eGarageType m_eGarageType; - eGarageState m_eGarageState; + uint8 m_eGarageType; + uint8 m_eGarageState; bool field_2; // unused bool m_bClosingWithoutTargetCar; bool m_bDeactivated; @@ -207,8 +207,8 @@ public: #endif static void Update(void); - static int16 AddOne(CVector pos1, CVector pos2, eGarageType type, int32 targetId); - static void ChangeGarageType(int16, eGarageType, int32); + static int16 AddOne(CVector pos1, CVector pos2, uint8 type, int32 targetId); + static void ChangeGarageType(int16, uint8, int32); static void PrintMessages(void); static void TriggerMessage(const char* text, int16, uint16 time, int16); static void SetTargetCarForMissonGarage(int16, CVehicle*); @@ -244,10 +244,10 @@ private: static bool IsCarSprayable(CVehicle*); static float FindDoorHeightForMI(int32); static void CloseHideOutGaragesBeforeSave(void); - static int32 CountCarsInHideoutGarage(eGarageType); - static int32 FindMaxNumStoredCarsForGarage(eGarageType); - static int32 GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; } - static int32 GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; } + static int32 CountCarsInHideoutGarage(uint8); + static int32 FindMaxNumStoredCarsForGarage(uint8); + static int32 GetBombTypeForGarageType(uint8 type) { return type - GARAGE_BOMBSHOP1 + 1; } + static int32 GetCarsCollectedIndexForGarageType(uint8 type) { return type - GARAGE_COLLECTCARS_1; } friend class cAudioManager; friend class CGarage; diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp index 23ab453c..38bcb2ec 100644 --- a/src/control/Script3.cpp +++ b/src/control/Script3.cpp @@ -291,7 +291,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) infZ = *(float*)&ScriptParams[5]; supZ = *(float*)&ScriptParams[2]; } - ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), (eGarageType)ScriptParams[6], 0); + ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), ScriptParams[6], 0); StoreParameters(&m_nIp, 1); return 0; } @@ -316,7 +316,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) infZ = *(float*)&ScriptParams[5]; supZ = *(float*)&ScriptParams[2]; } - ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), (eGarageType)ScriptParams[6], ScriptParams[7]); + ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), ScriptParams[6], ScriptParams[7]); StoreParameters(&m_nIp, 1); return 0; } @@ -1826,7 +1826,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) } case COMMAND_CHANGE_GARAGE_TYPE: CollectParameters(&m_nIp, 2); - CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], 0); + CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], 0); return 0; case COMMAND_ACTIVATE_CRUSHER_CRANE: { diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index feef70bc..399765f0 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -1459,7 +1459,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL: { CollectParameters(&m_nIp, 3); - CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], ScriptParams[2]); + CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], ScriptParams[2]); return 0; } case COMMAND_FIND_DRUG_PLANE_COORDINATES: diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 7a9f4a9e..015ad677 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -43,7 +43,7 @@ enum eFormation FORMATION_FRONT }; -enum FightState : int8 { +enum FightState { FIGHTSTATE_MOVE_FINISHED = -2, FIGHTSTATE_JUST_ATTACKED, FIGHTSTATE_NO_MOVE, @@ -484,7 +484,7 @@ public: CVector m_vecHitLastPos; uint32 m_curFightMove; uint8 m_fightButtonPressure; - FightState m_fightState; + int8 m_fightState; bool m_takeAStepAfterAttack; CFire *m_pFire; CEntity *m_pLookTarget; From b5ffea5c6e824049194c495495af9ec66c0b208d Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 00:57:34 +0100 Subject: [PATCH 03/52] uint16 enums fixed --- src/audio/soundlist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h index 225ed56e..7c3b30a7 100644 --- a/src/audio/soundlist.h +++ b/src/audio/soundlist.h @@ -1,6 +1,6 @@ #pragma once -enum eSound : uint16 +enum eSound { SOUND_CAR_DOOR_CLOSE_BONNET = 0, SOUND_CAR_DOOR_CLOSE_BUMPER, @@ -173,7 +173,7 @@ enum eSound : uint16 }; -enum eScriptSounds : uint16 { +enum eScriptSounds { SCRIPT_SOUND_0 = 0, SCRIPT_SOUND_1, SCRIPT_SOUND_2, From 9e2ac26a1dd84f0701bbadea2d14e4cd6547d9f8 Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 01:04:23 +0100 Subject: [PATCH 04/52] uint32 enums fixed --- src/audio/AudioSamples.h | 2 +- src/peds/Ped.h | 2 +- src/vehicles/HandlingMgr.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audio/AudioSamples.h b/src/audio/AudioSamples.h index e2721888..df64521c 100644 --- a/src/audio/AudioSamples.h +++ b/src/audio/AudioSamples.h @@ -2,7 +2,7 @@ #include "common.h" -enum eSfxSample : uint32 +enum eSfxSample { SFX_CAR_HORN_JEEP = 0, SFX_CAR_HORN_BMW328, diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 015ad677..f8e619d7 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -153,7 +153,7 @@ enum eWaitState { WAITSTATE_FINISH_FLEE }; -enum eObjective : uint32 { +enum eObjective { OBJECTIVE_NONE, OBJECTIVE_WAIT_ON_FOOT, OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE, diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index 4d3b8389..23bd9681 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -65,7 +65,7 @@ enum tVehicleType NUMHANDLINGS }; -enum tField : uint32 // most likely a handling field enum, never used so :shrug: +enum tField // most likely a handling field enum, never used so :shrug: { }; From 5e9a433b7912a597ba0287b4d48332b29773594e Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 01:05:45 +0100 Subject: [PATCH 05/52] int32 enum fixed --- src/audio/audio_enums.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h index 20760859..8c6d35aa 100644 --- a/src/audio/audio_enums.h +++ b/src/audio/audio_enums.h @@ -235,7 +235,7 @@ enum AudioEntityHandle { AEHANDLE_ERROR_BADAUDIOTYPE = -1, }; -enum eAudioType : int32 +enum eAudioType { AUDIOTYPE_PHYSICAL = 0, AUDIOTYPE_EXPLOSION, From 7e11f639aa468eaf24e51fa04a59fbe966119892 Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 7 Dec 2020 01:43:03 +0100 Subject: [PATCH 06/52] don't cast script param to uint8 --- src/control/Script4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index 399765f0..3629bb4b 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -1436,7 +1436,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - pVehicle->SetStatus((uint8)ScriptParams[1]); + pVehicle->SetStatus(ScriptParams[1]); return 0; } case COMMAND_IS_CHAR_MALE: From 5a1ea7bcf579b616e349ed651c67e0f988592cbd Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sun, 6 Dec 2020 23:22:02 +0100 Subject: [PATCH 07/52] audio: define openal extensions in re3 owned namespace --- src/audio/oal/oal_utils.cpp | 11 +++++++++++ src/audio/oal/oal_utils.h | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp index e16de572..e4cb0b77 100644 --- a/src/audio/oal/oal_utils.cpp +++ b/src/audio/oal/oal_utils.cpp @@ -3,6 +3,14 @@ #ifdef AUDIO_OAL +/* + * When linking to a static openal-soft library, + * the extension function inside the openal library conflict with the variables here. + * Therefore declare these re3 owned symbols in a private namespace. + */ + +namespace re3_openal { + LPALGENEFFECTS alGenEffects; LPALDELETEEFFECTS alDeleteEffects; LPALISEFFECT alIsEffect; @@ -37,6 +45,9 @@ LPALGETFILTERIV alGetFilteriv; LPALGETFILTERF alGetFilterf; LPALGETFILTERFV alGetFilterfv; +} + +using namespace re3_openal; void EFXInit() { diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h index b89ccf36..f0fa090a 100644 --- a/src/audio/oal/oal_utils.h +++ b/src/audio/oal/oal_utils.h @@ -11,6 +11,8 @@ void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); void EAX3_SetReverbMix(ALuint filter, float mix); void SetEffectsLevel(ALuint uiFilter, float level); +namespace re3_openal { + extern LPALGENEFFECTS alGenEffects; extern LPALDELETEEFFECTS alDeleteEffects; extern LPALISEFFECT alIsEffect; @@ -44,4 +46,9 @@ extern LPALGETFILTERI alGetFilteri; extern LPALGETFILTERIV alGetFilteriv; extern LPALGETFILTERF alGetFilterf; extern LPALGETFILTERFV alGetFilterfv; + +} + +using namespace re3_openal; + #endif From 84cc31fea3b8205a03b930218f7190303e1fab39 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 8 Dec 2020 02:27:35 +0200 Subject: [PATCH 08/52] Fix wrong define --- src/control/Script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/Script.h b/src/control/Script.h index 12f3233f..7fc18727 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -396,7 +396,7 @@ private: friend class CRunningScript; friend class CHud; friend void CMissionCleanup::Process(); -#ifdef FIX_BUGS +#ifdef MISSION_REPLAY friend void RetryMission(int, int); #endif From 8d3864a4e5830785bf7721cce5896fa7dc7e96d5 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 8 Dec 2020 02:56:20 +0200 Subject: [PATCH 09/52] Fix CRecordDataForChase::ShouldThisPadBeLeftAlone --- src/control/Record.cpp | 10 ++++++---- src/control/Record.h | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 8a23ffde..7f636ec2 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -391,15 +391,17 @@ void CRecordDataForChase::ProcessControlCars(void) } } -#if (defined(GTA_PS2) || defined(FIX_BUGS)) bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad) { // may be wrong - if (Status == STATE_NONE || Status == STATE_PLAYBACK) + if (Status == STATE_PLAYBACK_INIT) // this is useless but ps2 def checks if it's STATE_PLAYBACK_INIT return false; - return pad != 0; + + if (Status == STATE_RECORD) + return pad != 0; + + return false; } -#endif void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2) { diff --git a/src/control/Record.h b/src/control/Record.h index 8b55b1f4..6a94c408 100644 --- a/src/control/Record.h +++ b/src/control/Record.h @@ -57,9 +57,7 @@ public: static void RestoreInfoForMatrix(CMatrix&, CCarStateEachFrame*); static void RestoreInfoForCar(CAutomobile*, CCarStateEachFrame*, bool); static void ProcessControlCars(void); -#if (defined(GTA_PS2) || defined(FIX_BUGS)) static bool ShouldThisPadBeLeftAlone(uint8 pad); -#endif static void GiveUsACar(int32, CVector, float, CAutomobile**, uint8, uint8); static void StartChaseScene(float); static void CleanUpChaseScene(void); From b13b26b5fb34ebff9f36cbe8e5e4527bb0435c34 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 8 Dec 2020 03:33:56 +0200 Subject: [PATCH 10/52] GenerateOneRandomCar cleanup --- src/control/CarCtrl.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 627d7bad..520efe75 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -408,11 +408,6 @@ CCarCtrl::GenerateOneRandomCar() float directionNextLinkX; float directionNextLinkY; if (positionBetweenNodes < 0.5f) { - float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); - float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); - float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); - float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); - pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; positionOnCurrentLinkIncludingLane = CVector( @@ -442,11 +437,6 @@ CCarCtrl::GenerateOneRandomCar() pVehicle->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - (uint32)((positionBetweenNodes - 0.5f) * pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); - float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX(); - float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY(); - float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX(); - float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY(); - pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; positionOnCurrentLinkIncludingLane = CVector( From 778d1381bb2dff5371782dbb773770f4adc17a35 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 8 Dec 2020 07:50:29 +0200 Subject: [PATCH 11/52] Add NUM_LEVELS --- src/core/Game.h | 3 ++- src/core/World.cpp | 8 ++++---- src/core/World.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/Game.h b/src/core/Game.h index 46e8fc68..b55793af 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -5,7 +5,8 @@ enum eLevelName { LEVEL_GENERIC = 0, LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, - LEVEL_SUBURBAN + LEVEL_SUBURBAN, + NUM_LEVELS }; class CGame diff --git a/src/core/World.cpp b/src/core/World.cpp index 0bc564ff..1c988894 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -33,7 +33,7 @@ CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -CPtrList CWorld::ms_bigBuildingsList[4]; +CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS]; CPtrList CWorld::ms_listMovingEntityPtrs; CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; uint16 CWorld::ms_nCurrentScanCode; @@ -1745,13 +1745,13 @@ CWorld::ShutDown(void) pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); #endif } - for(int32 i = 0; i < 4; i++) { - for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) { + for(int32 i = 0; i < NUM_LEVELS; i++) { + for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; // Maybe remove from world here? delete pEntity; } - GetBigBuildingList((eLevelName)i).Flush(); + ms_bigBuildingsList[i].Flush(); } for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) { CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); diff --git a/src/core/World.h b/src/core/World.h index 9465a914..197f3cee 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -55,7 +55,7 @@ struct CStoredCollPoly; class CWorld { - static CPtrList ms_bigBuildingsList[4]; + static CPtrList ms_bigBuildingsList[NUM_LEVELS]; static CPtrList ms_listMovingEntityPtrs; static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; static uint16 ms_nCurrentScanCode; From 306aba8b0c7608d50c9c284ddb28c7704864ae41 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Tue, 8 Dec 2020 18:32:59 +0100 Subject: [PATCH 12/52] remove appveyor for now, our bintray account is still locked --- .appveyor.yml | 54 --------------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 8d1d4e9d..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,54 +0,0 @@ -version: 1.0.{build} -image: Visual Studio 2019 -configuration: -- Debug -- Release -platform: -- win-x86-librw_d3d9-mss -- win-x86-librw_gl3_glfw-mss -environment: - APPVEYOR_SAVE_CACHE_ON_ERROR: true - GLEW_VER: "2.1.0" - GLFW_VER: "3.3.2" - GLEW_BASE: glew-%GLEW_VER% - GLFW_BASE: glfw-%GLFW_VER%.bin.WIN32 - GLEW_FILE: "%GLEW_BASE%-win32.zip" - GLFW_FILE: "%GLFW_BASE%.zip" - GLEW_URL: https://github.com/nigels-com/glew/releases/download/%GLEW_BASE%/%GLEW_FILE% - GLFW_URL: https://github.com/glfw/glfw/releases/download/%GLFW_VER%/%GLFW_FILE% -install: -- IF [%PLATFORM%] == [win-x86-librw_gl3_glfw-mss] IF NOT EXIST %GLEW_FILE% appveyor DownloadFile %GLEW_URL% -FileName "%APPVEYOR_BUILD_FOLDER%/%GLEW_FILE%" -- IF [%PLATFORM%] == [win-x86-librw_gl3_glfw-mss] 7z x "%APPVEYOR_BUILD_FOLDER%/%GLEW_FILE%" -- IF [%PLATFORM%] == [win-x86-librw_gl3_glfw-mss] IF NOT EXIST %GLFW_FILE% appveyor DownloadFile %GLFW_URL% -FileName "%APPVEYOR_BUILD_FOLDER%/%GLFW_FILE%" -- IF [%PLATFORM%] == [win-x86-librw_gl3_glfw-mss] 7z x "%APPVEYOR_BUILD_FOLDER%/%GLFW_FILE%" -- cmd: >- - git submodule update --init --recursive - - premake5 vs2019 --with-librw --glewdir=%APPVEYOR_BUILD_FOLDER%/%GLEW_BASE% --glfwdir32=%APPVEYOR_BUILD_FOLDER%/%GLFW_BASE% - -build: - project: build/re3.sln - verbosity: minimal -after_build: -- 7z a "re3_%configuration%_%platform%_%APPVEYOR_BUILD_VERSION%.zip" bin/%PLATFORM%/%CONFIGURATION%/re3.exe bin/%PLATFORM%/%CONFIGURATION%/re3.pdb -artifacts: -- path: "re3_%configuration%_%platform%_%APPVEYOR_BUILD_VERSION%.zip" - name: re3 -deploy: -- provider: BinTray - username: shfil119 - api_key: - secure: xWnYDfNWM87iPoBFbz6L1XAduxijJRWSpQLhMDOjznmzbMCsORtdx2tmWmFLTwf6 - subject: gtamodding - repo: re3 - package: "%configuration%_%platform%" - version: "%APPVEYOR_BUILD_VERSION%" - artifact: re3 - publish: true - on: - branch: master - APPVEYOR_REPO_TAG: true - -cache: -- "%GLEW_FILE%" -- "%GLFW_FILE%" From b1efa513551e51e537d43c1cca1c7105faebec30 Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Tue, 8 Dec 2020 18:38:49 +0100 Subject: [PATCH 13/52] Add basic clang format file --- .clang-format | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..7185ba37 --- /dev/null +++ b/.clang-format @@ -0,0 +1,28 @@ +--- +AllowShortBlocksOnASingleLine: 'true' +AllowShortCaseLabelsOnASingleLine: 'true' +AllowShortIfStatementsOnASingleLine: 'true' +AllowShortLoopsOnASingleLine: 'true' +AlwaysBreakAfterReturnType: TopLevel +AccessModifierOffset: -8 +BreakBeforeBraces: Linux +ColumnLimit: 160 +IndentCaseLabels: 'false' +IndentWidth: '8' +Language: Cpp +PointerAlignment: Right +SpaceAfterCStyleCast: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCtorInitializerColon: 'true' +SpaceBeforeInheritanceColon: 'true' +SpaceBeforeParens: Never +SpaceInEmptyParentheses: 'false' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'false' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +TabWidth: '8' +UseTab: ForIndentation + +... From e171ed49591acfb4568e76a2cbe7f74da92b436e Mon Sep 17 00:00:00 2001 From: Filip Gawin Date: Tue, 8 Dec 2020 18:46:18 +0100 Subject: [PATCH 14/52] Update Readme --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 56377cc0..27b8d8e9 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # re3 -[![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg/branch/master?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master) +[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGTAmodding%2Fre3%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/GTAmodding/re3/goto?ref=master) -| Platform | Debug | Release | -|------------------|-------------|-------------| -| Windows Direct3D9 | [![Download](https://api.bintray.com/packages/gtamodding/re3/Debug_win-x86-librw_d3d9-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Debug_win-x86-librw_d3d9-mss/_latestVersion) | [![Download](https://api.bintray.com/packages/gtamodding/re3/Release_win-x86-librw_d3d9-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Release_win-x86-librw_d3d9-mss/_latestVersion) | -| Windows OpenGL3.3 | [![Download](https://api.bintray.com/packages/gtamodding/re3/Debug_win-x86-librw_gl3_glfw-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Debug_win-x86-librw_gl3_glfw-mss/_latestVersion) | [![Download](https://api.bintray.com/packages/gtamodding/re3/Release_win-x86-librw_gl3_glfw-mss/images/download.svg)](https://bintray.com/gtamodding/re3/Release_win-x86-librw_gl3_glfw-mss/_latestVersion) | ## Intro From a35c96c5ec3f785bac87d34f3cfeaf60caa0f620 Mon Sep 17 00:00:00 2001 From: "Walied K. Yassen" Date: Tue, 8 Dec 2020 21:19:34 +0200 Subject: [PATCH 15/52] Fix DeleteAllTempObjectsInArea and bunch of random gen ranges --- src/objects/Object.cpp | 45 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index d91a0f13..466cecac 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -209,15 +209,15 @@ CObject::ObjectDamage(float amount) SetTurnSpeed(0.0f, 0.0f, 0.0f); const RwRGBA color = { 96, 48, 0, 255 }; for (int32 i = 0; i < 25; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); + CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ); ++nFrameGen; int32 currentFrame = nFrameGen & 3; float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f); RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom) , color.blue, color.alpha }; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); } PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos); @@ -232,15 +232,15 @@ CObject::ObjectDamage(float amount) SetTurnSpeed(0.0f, 0.0f, 0.0f); const RwRGBA color = { 128, 128, 128, 255 }; for (int32 i = 0; i < 45; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); + CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ); ++nFrameGen; int32 currentFrame = nFrameGen & 3; - float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 0.5f); + float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f); RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha }; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0); } PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos); @@ -256,16 +256,16 @@ CObject::ObjectDamage(float amount) const RwRGBA color1 = { 200, 0, 0, 255 }; const RwRGBA color2 = { 200, 200, 200, 255 }; for (int32 i = 0; i < 10; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); + CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ); ++nFrameGen; int32 currentFrame = nFrameGen & 3; RwRGBA color = color2; if (nFrameGen & 1) color = color1; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); } PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos); @@ -281,16 +281,16 @@ CObject::ObjectDamage(float amount) const RwRGBA color1 = { 200, 0, 0, 255 }; const RwRGBA color2 = { 200, 200, 200, 255 }; for (int32 i = 0; i < 32; i++) { - CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(-0.35f, 0.7f), - CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ); + CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(-0.35f, 0.35f), + CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ); ++nFrameGen; int32 currentFrame = nFrameGen & 3; RwRGBA color = color2; if (nFrameGen & 1) color = color1; - float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f); - int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80); + float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f); + int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40); CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0); } PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos); @@ -389,7 +389,8 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) CObjectPool *objectPool = CPools::GetObjectPool(); for (int32 i = 0; i < objectPool->GetSize(); i++) { CObject *pObject = objectPool->GetSlot(i); - if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && fRadius * fRadius > pObject->GetPosition().MagnitudeSqr()) { + CVector dist = point - pObject->GetPosition(); + if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && dist.MagnitudeSqr() < fRadius * fRadius) { CWorld::Remove(pObject); delete pObject; } From fc6f07345e8db32ec5e4f8abddb87d2c8263c96f Mon Sep 17 00:00:00 2001 From: erorcun Date: Tue, 8 Dec 2020 23:33:51 +0300 Subject: [PATCH 16/52] Red delete menu background --- src/core/Frontend.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 5597b358..c5eb70fe 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -42,6 +42,7 @@ #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result #define SCROLLABLE_PAGES +#define RED_DELETE_BACKGROUND #ifdef SCROLLABLE_STATS_PAGE #define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS) @@ -2930,6 +2931,45 @@ CMenuManager::DrawFrontEndNormal() } } +#ifdef RED_DELETE_BACKGROUND + if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT || m_nCurrScreen == MENUPAGE_DELETE_SLOT_CONFIRM) { + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(18.0f), MENU_Y(8.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), MENU_Y(8.0f), + SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f), + SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f), + SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_STRETCH_X(18.0f), SCREEN_SCALE_Y(438.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_Y(438.0f), + CRGBA(150, 0, 0, 140)); + + // yellow bar + CSprite2d::DrawRect(CRect(MENU_X(13.0f), SCREEN_STRETCH_FROM_BOTTOM(96.0f), + SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), + CRGBA(235, 170, 50, 255)); + } +#endif + // GTA LOGO RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); From f6cc178a502b276128d52ed976e8dbe53875da8a Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 8 Dec 2020 23:15:59 +0100 Subject: [PATCH 17/52] fix CObject::DeleteAllTempObjectsInArea --- src/objects/Object.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 466cecac..411e245a 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -389,8 +389,7 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius) CObjectPool *objectPool = CPools::GetObjectPool(); for (int32 i = 0; i < objectPool->GetSize(); i++) { CObject *pObject = objectPool->GetSlot(i); - CVector dist = point - pObject->GetPosition(); - if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && dist.MagnitudeSqr() < fRadius * fRadius) { + if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && (point - pObject->GetPosition()).MagnitudeSqr() < SQR(fRadius)) { CWorld::Remove(pObject); delete pObject; } From 122c7aa40dda35107312fe91e0c61852c3056ddc Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 03:41:45 +0300 Subject: [PATCH 18/52] Use SDL gamepad mapping in environment by @ZLau92, implement @Sergeanur 's idea to use PPSSPP's DB if available, disable DEV() messages by default --- src/core/common.h | 8 +- src/extras/gamecontrollerdb.txt | 199 ++++++++++++++++++++++++++++++++ src/skel/glfw/glfw.cpp | 33 +++++- 3 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 src/extras/gamecontrollerdb.txt diff --git a/src/core/common.h b/src/core/common.h index 48b20884..d5775e08 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -248,8 +248,14 @@ void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); -#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) +// Switch to enable development messages. +#if 1 +#define DEV(f, ...) +#else #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) +#endif + +#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) #define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) #define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) diff --git a/src/extras/gamecontrollerdb.txt b/src/extras/gamecontrollerdb.txt new file mode 100644 index 00000000..fcefb88a --- /dev/null +++ b/src/extras/gamecontrollerdb.txt @@ -0,0 +1,199 @@ +# Windows - DINPUT +8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, +4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, +25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, +4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13, +4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows, +00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows, +00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows, +28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7, +ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9, +8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5, +79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows, +4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows, +d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows, +4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows, +10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows, +4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows, +0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows, +10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,platform:Windows, +63252305000000000000504944564944,USB Vibration Joystick (BM),platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8, +02200090000000000000504944564944,8Bitdo NES30 PRO USB,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8, +ff113133000000000000504944564944,Gembird JPD-DualForce,platform:Windows,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11, +341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows, +c0111352000000000000504944564944,Battalife Joystick,platform:Windows,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1, +100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Windows, +4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows, +4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows, + +# OS X +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X, +4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X, +8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X, +83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X, +5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4, +050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X, +79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,platform:Mac OS X, +2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X, +b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X, +10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X, +d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7, +0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4, +5e04000000000000e002000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4, +79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,platform:Mac OS X, +4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X, +5e04000000000000ea02000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4, +81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,platform:Mac OS X, +bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X, +03000000632500002305000000010000,Redragon Saturn,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, + +# Linux +050000004c0500006802000000000000,Sony PLAYSTATION(R)3 Controller,platform:Linux,a:b14,b:b13,x:b15,y:b12,back:b0,guide:b16,start:b3,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpdown:b6,dpleft:b7,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a12,righttrigger:a13, +03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5, +030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, +030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +030000006d04000016c2000010010000,Logitech Logitech Dual Action,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,platform:Linux, +030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +05000000d6200000ad0d000001000000,Moga Pro,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, +030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7, +0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux, +0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux, +030000006f0e00001f01000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000280400000140000000010000,Gravis GamePad Pro USB ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1, +030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000005e0400008502000000010000,Microsoft X-Box pad (Japan),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,platform:Linux,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5, +030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux, +050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux, +03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13, +05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2, +05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2, +030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux, +03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1, +050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16, +030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1, +030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7 +03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03000000f0250000c283000010010000,Goodbetterbest Ltd PC USB Controller,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7 +0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000006f0e00001304000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux, +03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux, +03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,platform:Linux, +030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,platform:Linux,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3, +030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,platform:Linux,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7, +05000000102800000900000000010000,8Bitdo SFC30 GamePad,platform:Linux,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1, +03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1, +030000000d0f00000d00000000010000,hori,platform:Linux,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5, +030000000d0f00006700000001010000,HORIPAD ONE,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,platform:Linux,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7, +03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),platform:Linux,a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5, +05000000010000000100000003000000,Nintendo Wiimote,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000005e0400008e02000062230000,Microsoft X-Box 360 pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +06000000adde0000efbe000002010000,Hidromancer Game Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,platform:Linux,a:b12,b:b10,x:b13,y:b11,back:b4,start:b5,leftstick:b14,rightstick:b15,leftshoulder:b9,rightshoulder:b8,dpup:b0,dpdown:b2,dpleft:b3,dpright:b1,leftx:a1,lefty:a0,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +05000000a00500003232000001000000,8Bitdo Zero GamePad,platform:Linux,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1, +03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5, +03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5, +030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Linux, +030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux, +050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, +030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, +05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5, +030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, +030000004c050000cc09000011810000,Sony Interactive Entertainment Wireless Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, +050000004c050000cc09000000810000,Wireless Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000004c0500006802000011810000,Sony PLAYSTATION(R)3 Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, +050000004c0500006802000000810000,PLAYSTATION(R)3 Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5, +05000000c82d00002038000000010000,8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, +030000005e040000a102000000010000,Xbox 360 Wireless Receiver,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpdown:b14,dpleft:b11,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5, +050000004c050000cc09000001000000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, +03000000bc2000006412000011010000,BETOP CONTROLLER,a:b2,b:b1,y:b0,x:b3,start:b9,guide:b30,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +05000000c82d00000161000000010000,8Bitdo SN30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, +03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7, +030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000000d0f0000c100000011010000,HORI CO.,LTD. HORIPAD S,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +03000000ad1b000003f5000033050000,Hori Fighting Stick VX,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,-leftx:h0.8,+leftx:h0.2,-lefty:h0.1,+lefty:h0.4,lefttrigger:b6,righttrigger:b7, +03000000c82d00000260000011010000,8Bitdo SF30 Pro 8BitDo SN30 Pro+,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, +060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b9,guide:b11,start:b10,leftstick:b12,rightstick:b13,leftshoulder:b5,rightshoulder:b6,dpup:b14,dpdown:b15,dpleft:b16,dpright:b17,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b7,righttrigger:b8, diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index 7354c90a..3ebff16a 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -70,9 +70,6 @@ static psGlobalType PsGlobal; #define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var) -#undef MAKEPOINTS -#define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l))) - size_t _dwMemAvailPhys; RwUInt32 gGameState; @@ -870,6 +867,36 @@ void _InputInitialiseJoys() PSGLOBAL(joy1id) = -1; PSGLOBAL(joy2id) = -1; + // Load our gamepad mappings. +#define SDL_GAMEPAD_DB_PATH "gamecontrollerdb.txt" + FILE *f = fopen(SDL_GAMEPAD_DB_PATH, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + size_t fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *db = (char*)malloc(fsize + 1); + if (fread(db, 1, fsize, f) == fsize) { + db[fsize] = '\0'; + + if (glfwUpdateGamepadMappings(db) == GLFW_FALSE) + Error("glfwUpdateGamepadMappings didn't succeed, check " SDL_GAMEPAD_DB_PATH ".\n"); + } else + Error("fread on " SDL_GAMEPAD_DB_PATH " wasn't successful.\n"); + + free(db); + fclose(f); + } else + printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from re3/gamefiles to GTA3 directory. Some gamepads may not be recognized.\n"); + +#undef SDL_GAMEPAD_DB_PATH + + // But always overwrite it with the one in SDL_GAMECONTROLLERCONFIG. + char const* EnvControlConfig = getenv("SDL_GAMECONTROLLERCONFIG"); + if (EnvControlConfig != nil) { + glfwUpdateGamepadMappings(EnvControlConfig); + } + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { if (glfwJoystickPresent(i) && !IsThisJoystickBlacklisted(i)) { if (PSGLOBAL(joy1id) == -1) From 0dfa8336109c6f449664d83478bf1890d7df71a2 Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 03:55:30 +0300 Subject: [PATCH 19/52] Fix --- {src/extras => gamefiles}/gamecontrollerdb.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/extras => gamefiles}/gamecontrollerdb.txt (100%) diff --git a/src/extras/gamecontrollerdb.txt b/gamefiles/gamecontrollerdb.txt similarity index 100% rename from src/extras/gamecontrollerdb.txt rename to gamefiles/gamecontrollerdb.txt From e1044a79478a3e25bfc44e699eb1f419275e9a0f Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 04:57:45 +0300 Subject: [PATCH 20/52] AnimViewer fixes, commentary from miami --- src/core/AnimViewer.cpp | 19 ++++++----- src/core/main.cpp | 26 +++++++-------- src/skel/crossplatform.h | 3 -- src/skel/glfw/glfw.cpp | 70 +++++++++++++++++----------------------- src/skel/skeleton.cpp | 5 ++- src/skel/skeleton.h | 3 -- src/skel/win/win.cpp | 57 ++++++++++++++------------------ 7 files changed, 76 insertions(+), 107 deletions(-) diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index b8354d93..a888d528 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -45,7 +45,7 @@ CEntity *CAnimViewer::pTarget = nil; void CAnimViewer::Render(void) { if (pTarget) { -// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); +// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); // Only on Mobile if (pTarget) { #ifdef FIX_BUGS #ifdef PED_SKIN @@ -61,7 +61,9 @@ CAnimViewer::Render(void) { void CAnimViewer::Initialise(void) { - LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen()); + // we need messages, messages needs hud, hud needs this + CHud::m_Wants_To_Draw_Hud = false; + animTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(animTxdSlot); int hudSlot = CTxdStore::AddTxdSlot("hud"); @@ -75,9 +77,6 @@ CAnimViewer::Initialise(void) { TheCamera.SetRwCamera(Scene.camera); TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f; - gbModelViewer = true; - CHud::m_Wants_To_Draw_Hud = false; - ThePaths.Init(); ThePaths.AllocatePathFindInfoMem(4500); CCollision::Init(); @@ -113,7 +112,7 @@ CAnimViewer::Initialise(void) { CTimeCycle::Initialise(); CCarCtrl::Init(); CPlayerPed *player = new CPlayerPed(); - player->SetPosition(0.0f, 0.0f, 0.0f); + player->SetPosition(0.0f, 0.0f, 0.0f); // This is 1000.f for all axes on Xbox, but 0.f on mobile? CWorld::Players[0].m_pPed = player; CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; @@ -222,8 +221,7 @@ CAnimViewer::Update(void) { static int modelId = 0; static int animId = 0; - // Please don't make this bool, static bool's are problematic on my side. - static int reloadIFP = 0; + static bool reloadIFP = false; AssocGroupId animGroup = ASSOCGRP_STD; int nextModelId = modelId; @@ -248,7 +246,7 @@ CAnimViewer::Update(void) CAnimManager::Initialise(); CAnimManager::LoadAnimFiles(); - reloadIFP = 0; + reloadIFP = false; } } else { animGroup = ASSOCGRP_STD; @@ -302,6 +300,7 @@ CAnimViewer::Update(void) pTarget->GetMatrix().GetPosition().z = 10.0f; #else pTarget->GetMatrix().GetPosition().z = 0.0f; + #endif if (modelInfo->GetModelType() == MITYPE_PED) { @@ -309,7 +308,7 @@ CAnimViewer::Update(void) // Triangle in mobile if (pad->GetSquareJustDown()) { - reloadIFP = 1; + reloadIFP = true; AsciiToUnicode("IFP reloaded", gUString); CMessages::AddMessage(gUString, 1000, 0); diff --git a/src/core/main.cpp b/src/core/main.cpp index 54821979..cc20047f 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -616,8 +616,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) AsciiToUnicode(str1, tmpstr); CFont::PrintString(hpos, vpos, tmpstr); vpos += 22*yscale; - AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); + if (str2) { + AsciiToUnicode(str2, tmpstr); + CFont::PrintString(hpos, vpos, tmpstr); + } #endif } @@ -1513,15 +1515,6 @@ AppEventHandler(RsEvent event, void *param) return rsEVENTPROCESSED; } -#ifndef MASTER - case rsANIMVIEWER: - { - TheModelViewer(); - - return rsEVENTPROCESSED; - } -#endif - default: { return rsEVENTNOTPROCESSED; @@ -1536,8 +1529,11 @@ TheModelViewer(void) #if (defined(GTA_PS2) || defined(GTA_XBOX)) //TODO #else + // This is III Mobile code. III Xbox code run it like main function, which is impossible to implement on PC's state machine implementation. + // Also we want 2D things initialized in here to print animation ids etc., our additions for that marked with X + #ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); + CDraw::SetAspectRatio(CDraw::FindAspectRatio()); // X #endif CAnimViewer::Update(); CTimer::Update(); @@ -1547,12 +1543,12 @@ TheModelViewer(void) CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); + CSprite2d::InitPerFrame(); // X + CFont::InitPerFrame(); // X DefinedState(); CVisibilityPlugins::InitAlphaEntityList(); CAnimViewer::Render(); - Render2dStuff(); + Render2dStuff(); // X DoRWStuffEndOfFrame(); #endif } diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h index 1635781b..d8807f2b 100644 --- a/src/skel/crossplatform.h +++ b/src/skel/crossplatform.h @@ -83,9 +83,6 @@ enum eGameState GS_FRONTEND, GS_INIT_PLAYING_GAME, GS_PLAYING_GAME, -#ifndef MASTER - GS_ANIMVIEWER, -#endif }; extern RwUInt32 gGameState; diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index 3ebff16a..b7c4810e 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -1257,17 +1257,11 @@ void resizeCB(GLFWwindow* window, int width, int height) { * memory things don't work. */ /* redraw window */ -#ifndef MASTER - if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) - { - RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); - } -#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) { RsEventHandler(rsIDLE, (void *)TRUE); } -#endif if (RwInitialised && height > 0 && width > 0) { RwRect r; @@ -1646,18 +1640,6 @@ main(int argc, char *argv[]) FrontEndMenuManager.DrawMemoryCardStartUpMenus(); } #endif - - if (TurnOnAnimViewer) - { -#ifndef MASTER - CAnimViewer::Initialise(); -#ifndef PS2_MENU - FrontEndMenuManager.m_bGameNotLoaded = false; -#endif - gGameState = GS_ANIMVIEWER; - TurnOnAnimViewer = false; -#endif - } initkeymap(); @@ -1677,6 +1659,18 @@ main(int argc, char *argv[]) * Enter the message processing loop... */ +#ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewer in LCS, but not compiled on III Mobile. + LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen()); + CAnimViewer::Initialise(); + CTimer::Update(); +#ifndef PS2_MENU + FrontEndMenuManager.m_bGameNotLoaded = false; +#endif + } +#endif + #ifdef PS2_MENU if (TheMemoryCard.m_bWantToLoad) LoadSplash(GetLevelSplashScreen(CGame::currLevel)); @@ -1691,7 +1685,13 @@ main(int argc, char *argv[]) #endif { glfwPollEvents(); - if( ForegroundApp ) +#ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewerCore in LCS, but TheModelViewer on other state-machine III-VCs. + TheModelViewer(); + } else +#endif + if ( ForegroundApp ) { switch ( gGameState ) { @@ -1894,18 +1894,6 @@ main(int argc, char *argv[]) } break; } -#ifndef MASTER - case GS_ANIMVIEWER: - { - float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); - if (RwInitialised) - { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) - RsEventHandler(rsANIMVIEWER, (void*)TRUE); - } - break; - } -#endif } } else @@ -1977,12 +1965,13 @@ main(int argc, char *argv[]) } else { +#ifndef MASTER + if ( gbModelViewer ) + CAnimViewer::Shutdown(); + else +#endif if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); -#ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) - CAnimViewer::Shutdown(); -#endif CTimer::Stop(); @@ -2004,12 +1993,13 @@ main(int argc, char *argv[]) } +#ifndef MASTER + if ( gbModelViewer ) + CAnimViewer::Shutdown(); + else +#endif if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); -#ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) - CAnimViewer::Shutdown(); -#endif DMAudio.Terminate(); diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index 3166093e..98fc9843 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -10,14 +10,13 @@ #include "skeleton.h" #include "platform.h" +#include "main.h" #include "MemoryHeap.h" static RwBool DefaultVideoMode = TRUE; -bool TurnOnAnimViewer = false; - RsGlobalType RsGlobal; #ifdef _WIN32 @@ -162,7 +161,7 @@ rsPreInitCommandLine(RwChar *arg) #ifndef MASTER if (!strcmp(arg, RWSTRING("-animviewer"))) { - TurnOnAnimViewer = TRUE; + gbModelViewer = TRUE; return TRUE; } diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h index 1c468179..380b6c05 100644 --- a/src/skel/skeleton.h +++ b/src/skel/skeleton.h @@ -79,11 +79,8 @@ enum RsEvent rsPADANALOGUERIGHTRESET, rsPREINITCOMMANDLINE, rsACTIVATE, - rsANIMVIEWER, }; -extern bool TurnOnAnimViewer; - typedef enum RsEvent RsEvent; typedef RsEventStatus (*RsInputEventHandler)(RsEvent event, void *param); diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index c16ea2a1..388090fc 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1017,17 +1017,12 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) RECT rect; /* redraw window */ -#ifndef MASTER - if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) - { - RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); - } -#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) { RsEventHandler(rsIDLE, (void *)TRUE); } -#endif + /* Manually resize window */ rect.left = rect.top = 0; rect.bottom = newPos->bottom - newPos->top; @@ -2183,17 +2178,17 @@ WinMain(HINSTANCE instance, } #endif - if (TurnOnAnimViewer) - { #ifndef MASTER + if (gbModelViewer) { + // This is TheModelViewer in LCS, but not compiled on III Mobile. + LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen()); CAnimViewer::Initialise(); + CTimer::Update(); #ifndef PS2_MENU FrontEndMenuManager.m_bGameNotLoaded = false; -#endif - gGameState = GS_ANIMVIEWER; - TurnOnAnimViewer = false; #endif } +#endif while ( TRUE ) { @@ -2238,6 +2233,12 @@ WinMain(HINSTANCE instance, DispatchMessage(&message); } } +#ifndef MASTER + else if (gbModelViewer) { + // This is TheModelViewerCore in LCS + TheModelViewer(); + } +#endif else if( ForegroundApp ) { switch ( gGameState ) @@ -2451,18 +2452,6 @@ WinMain(HINSTANCE instance, } break; } -#ifndef MASTER - case GS_ANIMVIEWER: - { - float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond(); - if (RwInitialised) - { - if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms) - RsEventHandler(rsANIMVIEWER, (void*)TRUE); - } - break; - } -#endif } } else @@ -2534,13 +2523,14 @@ WinMain(HINSTANCE instance, } else { +#ifndef MASTER + if ( gbModelViewer ) + CAnimViewer::Shutdown(); + else +#endif if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); -#ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) - CAnimViewer::Shutdown(); -#endif - + CTimer::Stop(); if ( FrontEndMenuManager.m_bFirstTime == true ) @@ -2561,12 +2551,13 @@ WinMain(HINSTANCE instance, } +#ifndef MASTER + if ( gbModelViewer ) + CAnimViewer::Shutdown(); + else +#endif if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); -#ifndef MASTER - else if ( gGameState == GS_ANIMVIEWER ) - CAnimViewer::Shutdown(); -#endif DMAudio.Terminate(); From 33e1f28239e715aba0abbf417bbcf57e61985d65 Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 06:09:45 +0300 Subject: [PATCH 21/52] Vehicle cam fixes - @ZLau92 's idea to remove 3rd person check on num 2/8. It was meaningless on III, probably not on VC tho. - @Nick007J pointed out that camera wasn't checking objects, which was something done by someone to prevent camera to collide with traffic lights. Instead I enabled object check again, and comparing the result if it's a traffic light after the test. --- src/core/Cam.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index b20e6db3..7cb7564a 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -5042,9 +5042,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float stickX = -(pad->GetCarGunLeftRight()); float stickY = pad->GetCarGunUpDown(); - // In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used. - if (CCamera::m_bUseMouse3rdPerson) - stickY = 0.0f; + // In SA this is for not let num2/num8 move camera when Keyboard & Mouse controls are used. + // if (CCamera::m_bUseMouse3rdPerson) + // stickY = 0.0f; float xMovement = Abs(stickX) * (FOV / 80.0f * 5.f / 70.f) * stickX * 0.007f * 0.007f; float yMovement = Abs(stickY) * (FOV / 80.0f * 3.f / 70.f) * stickY * 0.007f * 0.007f; @@ -5238,11 +5238,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); + // Our addition +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex()) || ent->GetModelIndex() == MI_STREETLAMP1 || ent->GetModelIndex() == MI_STREETLAMP2)) + // Move cam if on collision CColPoint foundCol; CEntity* foundEnt; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { + if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) && !IS_TRAFFIC_LIGHT(foundEnt)) { float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); float obstacleCamDist = newDistance - obstacleTargetDist; if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { @@ -5251,7 +5254,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); } } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { + if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) || IS_TRAFFIC_LIGHT(foundEnt)) { float lessClip = obstacleCamDist - 0.35f; if (lessClip <= DEFAULT_NEAR) RwCameraSetNearClipPlane(Scene.camera, lessClip); @@ -5270,6 +5273,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, } } } + CWorld::pIgnoreEntity = nil; float nearClip = RwCameraGetNearClipPlane(Scene.camera); float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; @@ -5277,9 +5281,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. for (int i = 0; - i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false); + i <= 5 && (foundEnt = CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false)); i++) { + if (IS_TRAFFIC_LIGHT(foundEnt)) + break; + CVector surfaceCamDist = gaTempSphereColPoints->point - Source; CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; @@ -5297,6 +5304,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, nearClip = RwCameraGetNearClipPlane(Scene.camera); radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; } +#undef IS_TRAFFIC_LIGHT } TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; From 1caf5d087aeb84b1b21d5c0fc2863bec9975f93b Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 15:39:14 +0300 Subject: [PATCH 22/52] Sync Stats page style with miami - and a little veh. cam. fix --- src/core/Cam.cpp | 2 +- src/core/Frontend.cpp | 241 +++++++++++++++++++++++++----------------- 2 files changed, 147 insertions(+), 96 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 7cb7564a..ba7e5d15 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -5239,7 +5239,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); // Our addition -#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex()) || ent->GetModelIndex() == MI_STREETLAMP1 || ent->GetModelIndex() == MI_STREETLAMP2)) +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex()))) // Move cam if on collision CColPoint foundCol; diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index c5eb70fe..118fb8d6 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -132,7 +132,7 @@ const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color #define MILES_IN_METER 0.000621371192f #define FEET_IN_METER 3.28084f #else -#define MILES_IN_METER 0.00059880241f +#define MILES_IN_METER (1 / 1670.f) #define FEET_IN_METER 3.33f #endif @@ -6101,108 +6101,157 @@ CMenuManager::PrintMap(void) int CMenuManager::ConstructStatLine(int rowIdx) { -#define STAT_LINE(str, left, isFloat, right) \ +#define int_STAT_IS_FLOAT false +#define float_STAT_IS_FLOAT true +#define STAT_LINE_1(varType, left, right1) \ do { \ if(counter == rowIdx){ \ - BuildStatLine(str, left, isFloat, right); \ + varType a = right1; \ + BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, nil); \ return 0; \ } counter++; \ } while(0) - int counter = 0, nTemp; +#define STAT_LINE_2(varType, left, right1, right2) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + varType b = right2; \ + BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, &b); \ + return 0; \ + } counter++; \ + } while(0) - STAT_LINE("PL_STAT", nil, false, nil); +#define TEXT_ON_LEFT_GXT(name) \ + do { \ + if(counter == rowIdx){ \ + BuildStatLine(name, nil, false, nil); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_RIGHT(text) \ + do { \ + if(counter == rowIdx){ \ + gUString[0] = '\0'; \ + UnicodeStrcpy(gUString2, text); \ + return 0; \ + } counter++; \ + } while(0) + + // Like TEXT_ON_LEFT_GXT, but counter wasn't initialized yet I think + if (rowIdx == 0) { + BuildStatLine("PL_STAT", nil, false, nil); + return 0; + } int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1)); percentCompleted = Min(percentCompleted, 100); - STAT_LINE("PER_COM", &percentCompleted, false, nil); - STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); - STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); - if (CGame::nastyGame) { - STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies); + switch (rowIdx) { + // 0 is the heading text above + case 1: { + BuildStatLine("PER_COM", &percentCompleted, false, nil); + return 0; + } + case 2: { + BuildStatLine("NMISON", &CStats::MissionsGiven, false, nil); + return 0; + } + case 3: { + BuildStatLine("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); + return 0; + } } + int counter = 4; + + if (CGame::nastyGame) + STAT_LINE_2(int, "FEST_RP", CStats::NumberKillFrenziesPassed, CStats::TotalNumberKillFrenzies); CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; + + // Hidden packages shouldn't be shown with percent +#ifdef FIX_BUGS + STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, player.m_nTotalPackages); +#else float packagesPercent = 0.0f; if (player.m_nTotalPackages != 0) packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; - int nPackagesPercent = packagesPercent; - STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100)); - STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps); - STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil); + STAT_LINE_2(int, "PERPIC", packagesPercent, 100); +#endif + STAT_LINE_2(int, "NOUNIF", CStats::NumberOfUniqueJumpsFound, CStats::TotalNumberOfUniqueJumps); + STAT_LINE_1(int, "DAYSPS", CStats::DaysPassed); if (CGame::nastyGame) { - STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil); - STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil); + STAT_LINE_1(int, "PE_WAST", CStats::PeopleKilledByPlayer); + STAT_LINE_1(int, "PE_WSOT", CStats::PeopleKilledByOthers); } - STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil); - STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil); - STAT_LINE("TM_DED", &CStats::TimesDied, false, nil); - STAT_LINE("GNG_WST", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] + STAT_LINE_1(int, "CAR_EXP", CStats::CarsExploded); + STAT_LINE_1(int, "TM_BUST", CStats::TimesArrested); + STAT_LINE_1(int, "TM_DED", CStats::TimesDied); + STAT_LINE_1(int, "GNG_WST", CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6] + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4] + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]), false, nil); - STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil); - STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil); - STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil); - STAT_LINE("ACCURA", &(nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 : - CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)), false, nil); + + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]); + STAT_LINE_1(int, "DED_CRI", CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]); + STAT_LINE_1(int, "HEL_DST", CStats::HelisDestroyed); + STAT_LINE_1(int, "KGS_EXP", CStats::KgsOfExplosivesUsed); + STAT_LINE_1(int, "ACCURA", (CStats::InstantHitsFiredByPlayer == 0 ? 0 : + CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)); if (CStats::ElBurroTime > 0) { - STAT_LINE("ELBURRO", &CStats::ElBurroTime, false, nil); + STAT_LINE_1(int, "ELBURRO", CStats::ElBurroTime); } if (CStats::Record4x4One > 0) { - STAT_LINE("FEST_R1", &CStats::Record4x4One, false, nil); + STAT_LINE_1(int, "FEST_R1", CStats::Record4x4One); } if (CStats::Record4x4Two > 0) { - STAT_LINE("FEST_R2", &CStats::Record4x4Two, false, nil); + STAT_LINE_1(int, "FEST_R2", CStats::Record4x4Two); } if (CStats::Record4x4Three > 0) { - STAT_LINE("FEST_R3", &CStats::Record4x4Three, false, nil); + STAT_LINE_1(int, "FEST_R3", CStats::Record4x4Three); } if (CStats::Record4x4Mayhem > 0) { - STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, false, nil); + STAT_LINE_1(int, "FEST_RM", CStats::Record4x4Mayhem); } if (CStats::LongestFlightInDodo > 0) { - STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, false, nil); + STAT_LINE_1(int, "FEST_LF", CStats::LongestFlightInDodo); } if (CStats::TimeTakenDefuseMission > 0) { - STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, false, nil); + STAT_LINE_1(int, "FEST_BD", CStats::TimeTakenDefuseMission); } - STAT_LINE("CAR_CRU", &CStats::CarsCrushed, false, nil); + STAT_LINE_1(int, "CAR_CRU", CStats::CarsCrushed); if (CStats::HighestScores[0] > 0) { - STAT_LINE("FEST_BB", nil, false, nil); - STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil); + TEXT_ON_LEFT_GXT("FEST_BB"); + STAT_LINE_1(int, "FEST_H0", CStats::HighestScores[0]); } if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_GC", nil, false, nil); + TEXT_ON_LEFT_GXT("FEST_GC"); } if (CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil); + STAT_LINE_1(int, "FEST_H1", CStats::HighestScores[1]); } if (CStats::HighestScores[2] > 0) { - STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil); + STAT_LINE_1(int, "FEST_H2", CStats::HighestScores[2]); } if (CStats::HighestScores[3] > 0) { - STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil); + STAT_LINE_1(int, "FEST_H3", CStats::HighestScores[3]); } if (CStats::HighestScores[4] > 0) { - STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil); + STAT_LINE_1(int, "FEST_H4", CStats::HighestScores[4]); } switch (m_PrefsLanguage) { case LANGUAGE_AMERICAN: #ifndef USE_MEASUREMENTS_IN_METERS - float fTemp; - STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil); - STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledInVehicle * MILES_IN_METER), true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); - STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil); - STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil); + STAT_LINE_1(float, "FEST_DF", CStats::DistanceTravelledOnFoot * MILES_IN_METER); + STAT_LINE_1(float, "FEST_DC", CStats::DistanceTravelledInVehicle * MILES_IN_METER); + STAT_LINE_1(int, "MMRAIN", CStats::mmRain); + STAT_LINE_1(float, "MXCARD", CStats::MaximumJumpDistance * FEET_IN_METER); + STAT_LINE_1(float, "MXCARJ", CStats::MaximumJumpHeight * FEET_IN_METER); break; #endif case LANGUAGE_FRENCH: @@ -6214,63 +6263,65 @@ CMenuManager::ConstructStatLine(int rowIdx) case LANGUAGE_RUSSIAN: case LANGUAGE_JAPANESE: #endif - STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil); - STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); - STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil); - STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil); + STAT_LINE_1(float, "FESTDFM", CStats::DistanceTravelledOnFoot); + STAT_LINE_1(float, "FESTDCM", CStats::DistanceTravelledInVehicle); + STAT_LINE_1(int, "MMRAIN", CStats::mmRain); + STAT_LINE_1(float, "MXCARDM", CStats::MaximumJumpDistance); + STAT_LINE_1(float, "MXCARJM", CStats::MaximumJumpHeight); break; default: break; } - STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil); - STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil); - STAT_LINE("BSTSTU", nil, false, nil); + STAT_LINE_1(int, "MXFLIP", CStats::MaximumJumpFlips); + STAT_LINE_1(int, "MXJUMP", CStats::MaximumJumpSpins); + TEXT_ON_LEFT_GXT("BSTSTU"); - if (counter == rowIdx) { - gUString[0] = '\0'; - switch (CStats::BestStuntJump) { - case 1: - UnicodeStrcpy(gUString2, TheText.Get("INSTUN")); - return 0; - case 2: - UnicodeStrcpy(gUString2, TheText.Get("PRINST")); - return 0; - case 3: - UnicodeStrcpy(gUString2, TheText.Get("DBINST")); - return 0; - case 4: - UnicodeStrcpy(gUString2, TheText.Get("DBPINS")); - return 0; - case 5: - UnicodeStrcpy(gUString2, TheText.Get("TRINST")); - return 0; - case 6: - UnicodeStrcpy(gUString2, TheText.Get("PRTRST")); - return 0; - case 7: - UnicodeStrcpy(gUString2, TheText.Get("QUINST")); - return 0; - case 8: - UnicodeStrcpy(gUString2, TheText.Get("PQUINS")); - return 0; - default: - UnicodeStrcpy(gUString2, TheText.Get("NOSTUC")); - return 0; - } + switch (CStats::BestStuntJump) { + case 1: + TEXT_ON_RIGHT(TheText.Get("INSTUN")); + break; + case 2: + TEXT_ON_RIGHT(TheText.Get("PRINST")); + break; + case 3: + TEXT_ON_RIGHT(TheText.Get("DBINST")); + break; + case 4: + TEXT_ON_RIGHT(TheText.Get("DBPINS")); + break; + case 5: + TEXT_ON_RIGHT(TheText.Get("TRINST")); + break; + case 6: + TEXT_ON_RIGHT(TheText.Get("PRTRST")); + break; + case 7: + TEXT_ON_RIGHT(TheText.Get("QUINST")); + break; + case 8: + TEXT_ON_RIGHT(TheText.Get("PQUINS")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("NOSTUC")); + break; } - counter++; - STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil); - STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil); - STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil); - STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil); - STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil); - STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil); - STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil); + + STAT_LINE_1(int, "PASDRO", CStats::PassengersDroppedOffWithTaxi); + STAT_LINE_1(int, "MONTAX", CStats::MoneyMadeWithTaxi); + STAT_LINE_1(int, "FEST_LS", CStats::LivesSavedWithAmbulance); + STAT_LINE_1(int, "FEST_HA", CStats::HighestLevelAmbulanceMission); + STAT_LINE_1(int, "FEST_CC", CStats::CriminalsCaught); + STAT_LINE_1(int, "FEST_FE", CStats::FiresExtinguished); + STAT_LINE_1(int, "DAYPLC", CTimer::GetTimeInMilliseconds() + 100); return counter; -#undef STAT_LINE +#undef STAT_LINE_1 +#undef STAT_LINE_2 +#undef TEXT_ON_LEFT_GXT +#undef TEXT_ON_RIGHT +#undef int_STAT_IS_FLOAT +#undef float_STAT_IS_FLOAT } #undef GetBackJustUp From fc3cdf3b3ba9834fbdeb7cafe11669d862a92462 Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 9 Dec 2020 21:43:58 +0300 Subject: [PATCH 23/52] Sync Frontend with miami 1 --- src/core/Frontend.cpp | 229 +++++++++++++++++++++--------------------- src/core/Frontend.h | 2 - 2 files changed, 112 insertions(+), 119 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 118fb8d6..3bd359c8 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -38,6 +38,30 @@ #include "FileLoader.h" #include "frontendoption.h" +// Game has colors inlined in code. +// For easier modification we collect them here: +const CRGBA LABEL_COLOR(235, 170, 50, 255); +const CRGBA SELECTION_HIGHLIGHTBG_COLOR(100, 200, 50, 50); +const CRGBA MENUOPTION_COLOR = LABEL_COLOR; +const CRGBA SELECTEDMENUOPTION_COLOR(255, 217, 106, 255); +const CRGBA HEADER_COLOR(0, 0, 0, 255); +const CRGBA DARKMENUOPTION_COLOR(155, 117, 6, 255); +const CRGBA SLIDERON_COLOR = SELECTEDMENUOPTION_COLOR; +const CRGBA SLIDEROFF_COLOR(185, 120, 0, 255); +const CRGBA LIST_BACKGROUND_COLOR(200, 200, 50, 50); +const CRGBA LIST_OPTION_COLOR(155, 155, 155, 255); +const CRGBA INACTIVE_RADIO_COLOR(225, 0, 0, 170); +const CRGBA SCROLLBAR_COLOR = LABEL_COLOR; +const CRGBA CONTSETUP_HIGHLIGHTBG_COLOR(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 210); +const CRGBA CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 150); + +// This is PS2 menu leftover, and variable name is original. They forgot it here and used in PrintBriefs once (but didn't use the output) +#if defined(FIX_BUGS) && !defined(PS2_LIKE_MENU) +const CRGBA TEXT_COLOR = LABEL_COLOR; +#else +const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // PS2 option color +#endif + #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result @@ -91,8 +115,6 @@ int GetOptionCount(int screen) #ifdef MENU_MAP bool CMenuManager::bMenuMapActive = false; -bool CMenuManager::bMapMouseShownOnce = false; -bool CMenuManager::bMapLoaded = false; float CMenuManager::fMapSize; float CMenuManager::fMapCenterY; float CMenuManager::fMapCenterX; @@ -121,13 +143,6 @@ int8 CMenuManager::m_nDisplayMSAALevel = 0; int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; #endif -// Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway) -#ifdef PS2_LIKE_MENU -const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); -#else -const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color -#endif - #ifdef USE_PRECISE_MEASUREMENT_CONVERTION #define MILES_IN_METER 0.000621371192f #define FEET_IN_METER 3.28084f @@ -298,7 +313,7 @@ const char* MenuFilenames[][2] = { } while(0) #define PREPARE_MENU_HEADER \ - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -322,7 +337,8 @@ const char* MenuFilenames[][2] = { #define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \ do { \ - sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170)); \ + sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : \ + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, INACTIVE_RADIO_COLOR.a)); \ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \ m_nHoverOption = hoverOpt; \ } while (0) @@ -966,10 +982,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR curBarX = i * rectSize/16.0f + x; if (i / 16.0f + 1 / 32.0f < progress) { - color = CRGBA(255, 217, 106, FadeIn(255)); + color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255)); lastActiveBarX = curBarX; } else - color = CRGBA(185, 120, 0, FadeIn(255)); + color = CRGBA(SLIDEROFF_COLOR.r, SLIDEROFF_COLOR.g, SLIDEROFF_COLOR.b, FadeIn(255)); maxBarHeight = Max(mostLeftBarSize, mostRightBarSize); @@ -1012,7 +1028,7 @@ CMenuManager::Draw() CFont::SetBackGroundOnlyTextOn(); #if GTA_VERSION >= GTA3_PC_11 #ifdef DRAW_MENU_VERSION_TEXT - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); @@ -1059,7 +1075,7 @@ CMenuManager::Draw() CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y)); CFont::SetRightJustifyOff(); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); // Label wchar *str; @@ -1247,7 +1263,7 @@ CMenuManager::Draw() // Back button wchar *backTx = TheText.Get("FEDS_TB"); CFont::SetDropShadowPosition(1); - CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(MENU_X(60.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), backTx); CFont::SetDropShadowPosition(0); if (!CheckHover(MENU_X(30.0f), MENU_X(30.0f) + CFont::GetStringWidth(backTx), SCREEN_SCALE_FROM_BOTTOM(125.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f))) { @@ -1636,12 +1652,12 @@ CMenuManager::Draw() #ifdef PS2_LIKE_MENU CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(29.0f), MENU_Y(bitAboveNextItemY), MENU_X_RIGHT_ALIGNED(29.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a))); #else // We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY), SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a))); #endif } @@ -1665,14 +1681,14 @@ CMenuManager::Draw() || isOptionDisabled #endif ) - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); } if (i == m_nCurrOption && itemsAreSelectable){ - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1795,7 +1811,7 @@ CMenuManager::Draw() // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(235, 170, 50, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); } #endif @@ -1877,7 +1893,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { int nextX = xStart; int bindingsForThisOpt = 0; - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); if (column == CONTSETUP_PED_COLUMN) { switch (optionIdx) { @@ -2055,18 +2071,18 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 #ifdef FIX_BUGS if (controllerAction == -1) { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #else if (controllerAction == -1) { CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); @@ -2076,16 +2092,16 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 #ifdef FIX_BUGS if (controllerAction == -1) { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #else if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(235, 170, 50, FadeIn(150))); + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210))); + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); @@ -2244,7 +2260,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig if (waitingTextVisible) { CFont::SetColor(CRGBA(255, 255, 0, FadeIn(255))); CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_QUE")); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } yStart += lineHeight; @@ -2344,12 +2360,12 @@ CMenuManager::DrawControllerSetupScreen() // Gray panel background CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)), - CRGBA(200, 200, 50, FadeIn(50))); + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); // List header CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -2418,16 +2434,16 @@ CMenuManager::DrawControllerSetupScreen() m_nHoverOption = HOVEROPTION_NOT_HOVERING; } } - if (m_nSelectedListRow != 35) - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + if (m_nSelectedListRow != i) + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); else if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); - if (m_PrefsLanguage != LANGUAGE_GERMAN || i != 20 && i != 21) - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - else + if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21)) CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE)); + else + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -2458,9 +2474,9 @@ CMenuManager::DrawControllerSetupScreen() SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB")); if (m_nHoverOption == HOVEROPTION_BACK) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -2730,12 +2746,12 @@ CMenuManager::DrawFrontEndNormal() CFont::SetScale(MENU_X(0.35f), MENU_Y(0.7f)); CFont::SetRightJustifyOff(); if (hoveredBottomBarOption == i && hoveredBottomBarOption != curBottomBarOption) - CFont::SetColor(CRGBA(235, 170, 50, 255)); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 255)); else { if(bottomBarActive || curBottomBarOption == i) - CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 255)); else - CFont::SetColor(CRGBA(0, 0, 0, 110)); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 110)); } str = TheText.Get(bbNames[i].name); @@ -3124,13 +3140,14 @@ CMenuManager::DrawPlayerSetupScreen() m_bSkinsEnumerated = true; } CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), - MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(200, 200, 50, FadeIn(50))); + MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); // Header (Skin - Date) if (m_nCurrExLayer == HOVEROPTION_LIST) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); @@ -3200,7 +3217,7 @@ CMenuManager::DrawPlayerSetupScreen() } else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) { CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255))); } else { - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); } wchar unicodeTemp[80]; AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp); @@ -3252,7 +3269,7 @@ CMenuManager::DrawPlayerSetupScreen() // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(235, 170, 50, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); // FIX: Scroll button dimensions are buggy, because: // 1 - stretches the original image @@ -3321,7 +3338,7 @@ CMenuManager::DrawPlayerSetupScreen() CFont::SetScale(MENU_X(1.9f), MENU_Y(1.9f)); break; } - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(120))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(120))); CFont::SetRightJustifyOff(); CFont::PrintString(MENU_X_LEFT_ALIGNED(20.0f), MENU_Y(220.0f), TheText.Get("FET_APL")); } @@ -3412,9 +3429,9 @@ CMenuManager::DrawPlayerSetupScreen() for (int i = 0; i < 2; i++) { CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - i), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FEDS_TB")); if (m_nHoverOption == HOVEROPTION_BACK) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } CFont::SetRightJustifyOff(); @@ -3424,11 +3441,11 @@ CMenuManager::DrawPlayerSetupScreen() for (int i = 0; i < 2; i++) { CFont::PrintString(MENU_X_LEFT_ALIGNED(i + PLAYERSETUP_LIST_LEFT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FES_SET")); if (!strcmp(m_aSkinName, m_PrefsSkinFile)) { - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } else if (m_nHoverOption == HOVEROPTION_USESKIN) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -3607,6 +3624,9 @@ CMenuManager::LoadAllTextures() m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]); m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } + fMapSize = SCREEN_HEIGHT * 2.0f; + fMapCenterX = 0.0f; + fMapCenterY = 0.0f; #endif #if GTA_VERSION >= GTA3_PC_11 CStreaming::IHaveUsedStreamingMemory(); @@ -3820,7 +3840,7 @@ CMenuManager::MessageScreen(const char *text) CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetCentreSize(SCREEN_SCALE_X(380.0f)); CFont::SetCentreOn(); - CFont::SetColor(CRGBA(255, 217, 106, 255)); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 255)); CFont::SetScale(SCREEN_SCALE_X(SMALLTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLTEXT_Y_SCALE)); CFont::PrintString(StretchX(320.0f), StretchY(170.0f), TheText.Get(text)); CFont::DrawFonts(); @@ -3846,7 +3866,7 @@ CMenuManager::PickNewPlayerColour() void CMenuManager::PrintBriefs() { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetRightJustifyOff(); CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why @@ -3864,19 +3884,14 @@ CMenuManager::PrintBriefs() CMessages::InsertPlayerControlKeysInString(gUString); newColor = TEXT_COLOR; FilterOutColorMarkersFromString(gUString, newColor); - -#ifdef PS2_LIKE_MENU - // This PS2 code was always here, but unused - bool rgSame = newColor.r == TEXT_COLOR.r && newColor.g == TEXT_COLOR.g; - bool bSame = rgSame && newColor.b == TEXT_COLOR.b; - bool colorNotChanged = bSame; /* && newColor.a == TEXT_COLOR.a; */ - - if (!colorNotChanged) { + if (newColor != TEXT_COLOR) { newColor.r /= 2; newColor.g /= 2; newColor.b /= 2; } - CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // But this is from PS2 + +#ifdef PS2_LIKE_MENU + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetDropShadowPosition(1); #endif @@ -3970,7 +3985,7 @@ CMenuManager::PrintStats() } else alphaMult = 1.0f; - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255.0f * alphaMult))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255.0f * alphaMult))); CFont::SetRightJustifyOff(); CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString); CFont::SetRightJustifyOn(); @@ -3980,7 +3995,7 @@ CMenuManager::PrintStats() // Game doesn't do that, but it's better float nextX = MENU_X_LEFT_ALIGNED(STATS_RATING_X); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), TheText.Get("CRIMRA")); #ifdef MORE_LANGUAGES @@ -4818,12 +4833,6 @@ CMenuManager::ProcessButtonPresses(void) break; #endif } else { -#ifdef MENU_MAP - if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) { - bMapLoaded = false; - } - -#endif ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); } } @@ -5894,26 +5903,14 @@ CMenuManager::PrintMap(void) bMenuMapActive = true; CRadar::InitFrontEndMap(); - // Just entered to map - if (!bMapLoaded) { - fMapSize = SCREEN_HEIGHT * 2.0f; - fMapCenterX = 0.0f; - fMapCenterY = 0.0f; + if (m_nMenuFadeAlpha < 255 && fMapCenterX == 0.f && fMapCenterY == 0.f) { + // Just entered. We need to do these transformations in here, because Radar knows whether map is active or not CVector2D radarSpacePlayer; CVector2D screenSpacePlayer; CRadar::TransformRealWorldPointToRadarSpace(radarSpacePlayer, CVector2D(FindPlayerCoors())); CRadar::TransformRadarPointToScreenSpace(screenSpacePlayer, radarSpacePlayer); - fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2; fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2; - bMapMouseShownOnce = false; - bMapLoaded = true; - - // Let's wait for a frame to not toggle the waypoint - if (CPad::GetPad(0)->NewState.Cross) { - bMenuMapActive = false; - return; - } } // Because fMapSize is half of the map length, and map consists of 3x3 tiles. @@ -5972,34 +5969,35 @@ CMenuManager::PrintMap(void) } CRadar::DrawBlips(); + static CVector2D mapCrosshair; - CVector2D mapPoint; - mapPoint.x = m_nMousePosX; - mapPoint.y = m_nMousePosY; - - if (m_bShowMouse) { - bMapMouseShownOnce = true; - } else if (!bMapMouseShownOnce) { - mapPoint.x = SCREEN_WIDTH / 2; - mapPoint.y = SCREEN_HEIGHT / 2; + if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) { + mapCrosshair.x = SCREEN_WIDTH / 2; + mapCrosshair.y = SCREEN_HEIGHT / 2; + } else if (m_bShowMouse) { + mapCrosshair.x = m_nMousePosX; + mapCrosshair.y = m_nMousePosY; } - CSprite2d::DrawRect(CRect(mapPoint.x - MENU_X(1.0f), 0.0f, - mapPoint.x + MENU_X(1.0f), SCREEN_HEIGHT), + CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f, + mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT), CRGBA(0, 0, 0, 150)); - CSprite2d::DrawRect(CRect(0.0f, mapPoint.y + MENU_X(1.0f), - SCREEN_WIDTH, mapPoint.y - MENU_X(1.0f)), + CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f), + SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)), CRGBA(0, 0, 0, 150)); - if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize && - mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) { + // Adding marker + if (m_nMenuFadeAlpha >= 255) { + if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { + if (mapCrosshair.y > fMapCenterY - fMapSize && mapCrosshair.y < fMapCenterY + fMapSize && + mapCrosshair.x > fMapCenterX - fMapSize && mapCrosshair.x < fMapCenterX + fMapSize) { - float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; - float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; - float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f; - CRadar::ToggleTargetMarker(x, y); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; + float x = ((mapCrosshair.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; + float y = 2000.0f - ((mapCrosshair.y - diffY) / (fMapSize * 2)) * 4000.0f; + CRadar::ToggleTargetMarker(x, y); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + } } } @@ -6024,12 +6022,12 @@ CMenuManager::PrintMap(void) if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { if (CPad::GetPad(0)->GetMouseWheelDown()) - ZOOM(mapPoint.x, mapPoint.y, false); + ZOOM(mapCrosshair.x, mapCrosshair.y, false); else ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false); } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) { if (CPad::GetPad(0)->GetMouseWheelUp()) - ZOOM(mapPoint.x, mapPoint.y, true); + ZOOM(mapCrosshair.x, mapCrosshair.y, true); else ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); } @@ -6047,16 +6045,13 @@ CMenuManager::PrintMap(void) bMenuMapActive = false; - // CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); // From VC - // CFont::SetRightJustifyWrap(10.0f); - CSprite2d::DrawRect(CRect(MENU_X(14.0f), SCREEN_STRETCH_FROM_BOTTOM(95.0f), SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), CRGBA(235, 170, 50, 255)); CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f)); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); float nextX = MENU_X(30.0f), nextY = 95.0f; wchar *text; diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 21124fdb..9f935510 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -697,8 +697,6 @@ public: #ifdef MENU_MAP static bool bMenuMapActive; - static bool bMapMouseShownOnce; - static bool bMapLoaded; static float fMapSize; static float fMapCenterY; static float fMapCenterX; From 3038fba9ca6b2fcb3a4f95543db624fe81deb392 Mon Sep 17 00:00:00 2001 From: erorcun Date: Sat, 12 Dec 2020 18:20:21 +0300 Subject: [PATCH 24/52] Sync Frontend, Peds with miami 2 --- src/core/Frontend.cpp | 100 ++++++++++++++++++-------------------- src/peds/PedAI.cpp | 28 +++++------ src/peds/PlayerPed.cpp | 108 +++++++++++++++++++---------------------- 3 files changed, 111 insertions(+), 125 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 3bd359c8..6806230d 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -312,12 +312,33 @@ const char* MenuFilenames[][2] = { m_nMenuFadeAlpha = 0; \ } while(0) -#define PREPARE_MENU_HEADER \ +#define SET_FONT_FOR_MENU_HEADER \ CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); +#define RESET_FONT_FOR_NEW_PAGE \ + CFont::SetBackgroundOff(); \ + CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ + CFont::SetPropOn(); \ + CFont::SetCentreOff(); \ + CFont::SetJustifyOn(); \ + CFont::SetRightJustifyOff(); \ + CFont::SetBackGroundOnlyTextOn(); \ + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + +#define SET_FONT_FOR_HELPER_TEXT \ + CFont::SetCentreOn(); \ + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + +#define SET_FONT_FOR_LIST_ITEM \ + CFont::SetRightJustifyOff(); \ + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + #define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \ do { \ lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \ @@ -512,6 +533,7 @@ CMenuManager::ProcessList(bool &goBack, bool &optionSelected) m_nTotalListRow = m_nSkinsTotal; } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + // GetNumOptionsCntrlConfigScreens would have been a better choice m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; if (m_nSelectedListRow > m_nTotalListRow) m_nSelectedListRow = m_nTotalListRow - 1; @@ -932,10 +954,7 @@ CMenuManager::DisplayHelperText() alpha = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha; } - CFont::SetCentreOn(); - CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - + SET_FONT_FOR_HELPER_TEXT // TODO: name this cases? switch (m_nHelperTextMsgId) { case 0: @@ -1065,7 +1084,7 @@ CMenuManager::Draw() #endif if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); // Weird place to put that. @@ -1876,6 +1895,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 int controllerAction = PED_FIREWEAPON; // GetStartOptionsCntrlConfigScreens(); int numOptions = GetNumOptionsCntrlConfigScreens(); + int nextY = MENU_Y(yStart); int bindingMargin = MENU_X(3.0f); float rowHeight; switch (m_ControlMethod) { @@ -1890,9 +1910,10 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // MENU_Y(rowHeight * 0.0f + yStart); - for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { + for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { int nextX = xStart; int bindingsForThisOpt = 0; + int contSetOrder = SETORDER_1; CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); if (column == CONTSETUP_PED_COLUMN) { @@ -2112,7 +2133,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 // Print bindings, including seperator (-) between them CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); - for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { + for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { ++bindingsForThisOpt; @@ -2176,9 +2197,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???" } - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); if (m_bKeyChangeNotProcessed) { CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE @@ -2186,34 +2205,24 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL } - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM if (!m_bKeyIsOK) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); m_bKeyIsOK = true; } else { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM } } } @@ -2289,17 +2298,9 @@ CMenuManager::DrawControllerSetupScreen() default: break; } - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + RESET_FONT_FOR_NEW_PAGE - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER switch (m_ControlMethod) { case CONTROL_STANDARD: @@ -2374,15 +2375,15 @@ CMenuManager::DrawControllerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM + int yStart; if (m_ControlMethod == CONTROL_CLASSIC) - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29; + yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 1; else - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34; + yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 5; + float optionYBottom = yStart + rowHeight; for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) { wchar *actionText = actionTexts[i]; if (!actionText) @@ -2391,8 +2392,7 @@ CMenuManager::DrawControllerSetupScreen() if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) { - float curOptY = i * rowHeight + yStart; - if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { + if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) { if (m_nOptionMouseHovering != i && m_nCurrExLayer == HOVEROPTION_LIST) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); @@ -3042,17 +3042,9 @@ CMenuManager::DrawFrontEndNormal() void CMenuManager::DrawPlayerSetupScreen() { - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + RESET_FONT_FOR_NEW_PAGE - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS")); @@ -4018,7 +4010,7 @@ CMenuManager::PrintStats() // ::Draw already does that. /* - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); */ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 38303473..62b27134 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -972,9 +972,9 @@ CPed::ProcessObjective(void) } CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); float wepRange = wepInfo->m_fRange; - float wepRangeAdjusted; + float maxDistToKeep; if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) { - wepRangeAdjusted = wepRange / 3.0f; + maxDistToKeep = wepRange / 3.0f; } else { if (m_nPedState == PED_FIGHT) { if (!IsPlayer() && !(m_pedStats->m_flags & STAT_CAN_KICK)) @@ -982,10 +982,10 @@ CPed::ProcessObjective(void) } else { wepRange = 1.3f; } - wepRangeAdjusted = wepRange; + maxDistToKeep = wepRange; } - if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds() && wepRangeAdjusted < 2.5f) { - wepRangeAdjusted = 2.5f; + if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds() && maxDistToKeep < 2.5f) { + maxDistToKeep = 2.5f; } if (m_pedInObjective->IsPlayer() && m_nPedType != PEDTYPE_COP && CharCreatedBy != MISSION_CHAR && FindPlayerPed()->m_pWanted->m_CurrentCops) { @@ -1086,7 +1086,7 @@ CPed::ProcessObjective(void) || distWithTargetSc > m_distanceToCountSeekDone && !CanSeeEntity(m_pedInObjective)) { if (m_pedInObjective->EnteringCar()) - wepRangeAdjusted = 2.0f; + maxDistToKeep = 2.0f; if (bUsePedNodeSeek) { CVector bestCoords(0.0f, 0.0f, 0.0f); @@ -1100,7 +1100,7 @@ CPed::ProcessObjective(void) SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); } else { - SetSeek(m_pedInObjective, wepRangeAdjusted); + SetSeek(m_pedInObjective, maxDistToKeep); } bCrouchWhenShooting = false; if (m_pedInObjective->m_pCurrentPhysSurface && distWithTargetSc < 5.0f) { @@ -1172,7 +1172,7 @@ CPed::ProcessObjective(void) SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 2000.0f)); int time; - if (distWithTargetSc <= wepRangeAdjusted) + if (distWithTargetSc <= maxDistToKeep) time = CGeneral::GetRandomNumberInRange(100.0f, 500.0f); else time = CGeneral::GetRandomNumberInRange(1500.0f, 3000.0f); @@ -1230,17 +1230,17 @@ CPed::ProcessObjective(void) if (m_nPedType == PEDTYPE_COP) { if (GetWeapon()->m_eWeaponType > WEAPONTYPE_COLT45 || m_fleeFrom && m_fleeFrom->IsObject()) { - wepRangeAdjusted = 6.0f; + maxDistToKeep = 6.0f; } else if (m_fleeFrom && m_fleeFrom->IsVehicle()) { - wepRangeAdjusted = 4.0f; + maxDistToKeep = 4.0f; } else { - wepRangeAdjusted = 2.0f; + maxDistToKeep = 2.0f; } } else { - wepRangeAdjusted = 2.0f; + maxDistToKeep = 2.0f; } } - if (distWithTargetSc <= wepRangeAdjusted) { + if (distWithTargetSc <= maxDistToKeep) { SetMoveState(PEDMOVE_STILL); bIsPointingGunAt = true; if (m_nPedState != PED_AIM_GUN && !bDuckAndCover) { @@ -1251,7 +1251,7 @@ CPed::ProcessObjective(void) if (m_nPedState != PED_SEEK_ENTITY && m_nPedState != PED_SEEK_POS && !bStopAndShoot && !killPlayerInNoPoliceZone && !bKindaStayInSamePlace) { Say(SOUND_PED_ATTACK); - SetSeek(m_pedInObjective, wepRangeAdjusted); + SetSeek(m_pedInObjective, maxDistToKeep); bIsRunning = true; } } diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index fa865aec..f23aa378 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -113,14 +113,10 @@ CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity) { if (m_pedStats->m_temper < 52) { m_pedStats->m_temper++; - } else { - if (annoyedByPassingEntity) { - if (m_pedStats->m_temper < 55) { - m_pedStats->m_temper++; - } else { - m_pedStats->m_temper = 46; - } - } + } else if (annoyedByPassingEntity && m_pedStats->m_temper < 55) { + m_pedStats->m_temper++; + } else if (annoyedByPassingEntity) { + m_pedStats->m_temper = 46; } } @@ -215,7 +211,7 @@ CPlayerPed::ReApplyMoveAnims(void) for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) { CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]); if (curMoveAssoc) { - if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) { + if (CGeneral::faststrcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name)) { CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]); newMoveAssoc->blendDelta = curMoveAssoc->blendDelta; newMoveAssoc->blendAmount = curMoveAssoc->blendAmount; @@ -288,7 +284,7 @@ CPlayerPed::SetRealMoveAnim(void) if (!curIdleAssoc) curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); - if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) { + if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) { if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) { if (curRunStopAssoc) { @@ -340,8 +336,8 @@ CPlayerPed::SetRealMoveAnim(void) CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); } } - m_nMoveState = PEDMOVE_STILL; + } else { if (curIdleAssoc) { if (curWalkStartAssoc) { @@ -394,6 +390,7 @@ CPlayerPed::SetRealMoveAnim(void) } if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) { + // Stop sprinting in various conditions if (curSprintAssoc->blendAmount == 0.0f) { curSprintAssoc->blendDelta = -1000.0f; curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; @@ -417,8 +414,8 @@ CPlayerPed::SetRealMoveAnim(void) curRunAssoc->flags &= ~ASSOC_RUNNING; curRunAssoc->blendAmount = 0.0f; curRunAssoc->blendDelta = 0.0f; - } else if (curSprintAssoc->blendDelta >= 0.0f) { + } else if (curSprintAssoc->blendDelta >= 0.0f) { // Stop sprinting when tired curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT; curSprintAssoc->blendDelta = -1.0f; @@ -428,7 +425,9 @@ CPlayerPed::SetRealMoveAnim(void) curSprintAssoc->blendDelta = -8.0f; curRunAssoc->blendDelta = 8.0f; } + } else if (curWalkStartAssoc) { + // Walk start and walk/run shouldn't run at the same time curWalkAssoc->flags &= ~ASSOC_RUNNING; curRunAssoc->flags &= ~ASSOC_RUNNING; curWalkAssoc->blendAmount = 0.0f; @@ -436,11 +435,13 @@ CPlayerPed::SetRealMoveAnim(void) } else if (m_nMoveState == PEDMOVE_SPRINT) { if (curSprintAssoc) { + // We have anim, do it if (curSprintAssoc->blendDelta < 0.0f) { curSprintAssoc->blendDelta = 2.0f; curRunAssoc->blendDelta = -2.0f; } } else { + // Transition between run-sprint curWalkAssoc->blendAmount = 0.0f; curRunAssoc->blendAmount = 1.0f; curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f); @@ -703,14 +704,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) float padMove = CVector2D(leftRight, upDown).Magnitude(); float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE; if (padMoveInGameUnit > 0.0f) { -#ifdef FREE_CAM - if (!CCamera::bFreeCam) - m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation); - else - m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation; -#else m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation); -#endif m_fMoveSpeed = Min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed); } else { m_fMoveSpeed = 0.0f; @@ -718,8 +712,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) if (m_nPedState == PED_JUMP) { if (bIsInTheAir) { - if (bUsesCollision && !bHitSteepSlope && - (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) + if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) { float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O @@ -730,8 +723,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) m_fMoveSpeed = 0.0f; } } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) - && padUsed->GetSprint()) { + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { m_nMoveState = PEDMOVE_SPRINT; } if (m_nPedState != PED_FIGHT) @@ -856,10 +848,9 @@ CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft) { CEntity *nextTarget = nil; float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange; - // nextTarget = nil; + // nextTarget = nil; // duplicate float lastCloseness = -10000.0f; - // unused - // CGeneral::GetATanOfXY(GetForward().x, GetForward().y); + // CGeneral::GetATanOfXY(GetForward().x, GetForward().y); // unused CVector distVec = previousTarget->GetPosition() - GetPosition(); float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y); @@ -907,7 +898,7 @@ CPlayerPed::FindWeaponLockOnTarget(void) } } - // nextTarget = nil; + // nextTarget = nil; // duplicate float lastCloseness = -10000.0f; float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y); for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) { @@ -1105,7 +1096,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2; } } - } else if (weaponInfo->m_bCanAimWithArm) + } else if (weaponInfo->m_bCanAimWithArm && m_nPedState != PED_ATTACK) ClearPointGunAt(); } } @@ -1212,8 +1203,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) if (m_nPedState == PED_JUMP) { if (bIsInTheAir) { - if (bUsesCollision && !bHitSteepSlope && - (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) + if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f) && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) { float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O @@ -1225,8 +1215,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) } } - if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) - && padUsed->GetSprint()) { + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { m_nMoveState = PEDMOVE_SPRINT; } if (m_nPedState != PED_FIGHT) @@ -1291,25 +1280,26 @@ CPlayerPed::ProcessControl(void) if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_CAR) { if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) { CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR); - if (!rollDoorAssoc) { - rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW); - } - - // These comparisons are wrong, they return uint16 - if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed - && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f - || padUsed->GetBrake() != 0.0f)) { + if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || (rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW))) { if (rollDoorAssoc) m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime); - } else { - m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF; - if (m_pMyVehicle->bLowVehicle) - rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW); - else - rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR); - rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this); + } else { + // These comparisons are wrong, they return uint16 + if (padUsed && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f || padUsed->GetBrake() != 0.0f)) { + if (rollDoorAssoc) + m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime); + + } else { + m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF; + if (m_pMyVehicle->bLowVehicle) + rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW); + else + rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR); + + rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this); + } } } return; @@ -1338,12 +1328,18 @@ CPlayerPed::ProcessControl(void) case PED_FIGHT: case PED_AIM_GUN: if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK)) { - if (TheCamera.Cams[0].Using3rdPersonMouseCam()) { + if (TheCamera.Cams[0].Using3rdPersonMouseCam() +#ifdef FREE_CAM + && !CCamera::bFreeCam +#endif + ) { if (padUsed) PlayerControl1stPersonRunAround(padUsed); + } else if (m_nPedState == PED_FIGHT) { if (padUsed) PlayerControlFighter(padUsed); + } else if (padUsed) { PlayerControlZelda(padUsed); } @@ -1415,6 +1411,7 @@ CPlayerPed::ProcessControl(void) if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) { if (padUsed) PlayerControlM16(padUsed); + } else if (padUsed) { PlayerControlSniper(padUsed); } @@ -1477,20 +1474,17 @@ CPlayerPed::ProcessControl(void) m_lookTimer = 0; float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading()); float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur); - if (m_nPedState != PED_ATTACK - && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) { + if (m_nPedState != PED_ATTACK && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) { if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) { float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f)); float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur); - if (m_fLookDirection != 999999.0f) { - if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection)) - camAngle = rightTurnAngle; - else - camAngle = leftTurnAngle; - } else { + if (m_fLookDirection == 999999.0f) camAngle = rightTurnAngle; - } + else if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection)) + camAngle = rightTurnAngle; + else + camAngle = leftTurnAngle; } SetLookFlag(camAngle, true); SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f); From 82c40b73ca4a4e67e0e53a34caac546f012fe54d Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 12 Dec 2020 20:35:17 +0300 Subject: [PATCH 25/52] fixed a bug --- src/control/CarCtrl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 520efe75..cb4229eb 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -2338,7 +2338,11 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv switch (pVehicle->AutoPilot.m_nDrivingStyle) { case DRIVINGSTYLE_STOP_FOR_CARS: case DRIVINGSTYLE_SLOW_DOWN_FOR_CARS: - speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle) / pVehicle->AutoPilot.m_nCruiseSpeed; + speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle); +#ifdef FIX_BUGS + if (pVehicle->AutoPilot.m_nCruiseSpeed != 0) +#endif + speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed; break; default: speedStyleMultiplier = 1.0f; From c74f03b180c99b92ab68f999ab63a5e70b4b3ae0 Mon Sep 17 00:00:00 2001 From: erorcun Date: Sat, 12 Dec 2020 20:35:54 +0300 Subject: [PATCH 26/52] Kill obj. fix & style change --- src/peds/PedAI.cpp | 73 +++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 62b27134..8c066b8f 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -1015,14 +1015,14 @@ CPed::ProcessObjective(void) // I hope so CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); CVector maxShotPos = vehOfTarget->GetPosition() - ourHead; - maxShotPos.Normalise(); - maxShotPos = maxShotPos * wepInfo->m_fRange + ourHead; + maxShotPos *= wepInfo->m_fRange / maxShotPos.Magnitude(); + maxShotPos += ourHead; - CWorld::bIncludeDeadPeds = true; CColPoint foundCol; CEntity *foundEnt; - CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, - true, true, true, true, false, true, false); + + CWorld::bIncludeDeadPeds = true; + CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, true, true, true, true, false, true, false); CWorld::bIncludeDeadPeds = false; if (foundEnt == vehOfTarget) { SetAttack(vehOfTarget); @@ -1038,8 +1038,7 @@ CPed::ProcessObjective(void) SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000)); } } - } - else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace && !killPlayerInNoPoliceZone) { + } else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace && !killPlayerInNoPoliceZone) { if (vehOfTarget) { if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) { GoToNearestDoor(vehOfTarget); @@ -1152,17 +1151,15 @@ CPed::ProcessObjective(void) target = m_pedInObjective->GetPosition(); target -= ourHead; - target.Normalise(); - target = target * wepInfo->m_fRange + ourHead; + target *= wepInfo->m_fRange / target.Magnitude(); + target += ourHead; + + CColPoint foundCol; + CEntity *foundEnt = nil; CWorld::bIncludeDeadPeds = true; - CEntity *foundEnt = nil; - CColPoint foundCol; - - CWorld::ProcessLineOfSight( - ourHead, target, foundCol, foundEnt, - true, true, true, false, true, false); - CWorld::bIncludeDeadPeds = 0; + CWorld::ProcessLineOfSight(ourHead, target, foundCol, foundEnt, true, true, true, true, false, true, false); + CWorld::bIncludeDeadPeds = false; if (foundEnt == m_pedInObjective) { SetAttack(m_pedInObjective); m_pPointGunAt = m_pedInObjective; @@ -1180,25 +1177,27 @@ CPed::ProcessObjective(void) SetAttackTimer(time); bObstacleShowedUpDuringKillObjective = false; - } else if (foundEnt) { - if (foundEnt->IsPed()) { - SetAttackTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f)); - bObstacleShowedUpDuringKillObjective = false; - } else { - if (foundEnt->IsObject()) { - SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 400.0f)); - bObstacleShowedUpDuringKillObjective = true; - } else if (foundEnt->IsVehicle()) { - SetAttackTimer(CGeneral::GetRandomNumberInRange(400.0f, 600.0f)); - bObstacleShowedUpDuringKillObjective = true; + } else { + if (foundEnt) { + if (foundEnt->IsPed()) { + SetAttackTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f)); + bObstacleShowedUpDuringKillObjective = false; } else { - SetAttackTimer(CGeneral::GetRandomNumberInRange(700.0f, 1200.0f)); - bObstacleShowedUpDuringKillObjective = true; + if (foundEnt->IsObject()) { + SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 400.0f)); + bObstacleShowedUpDuringKillObjective = true; + } else if (foundEnt->IsVehicle()) { + SetAttackTimer(CGeneral::GetRandomNumberInRange(400.0f, 600.0f)); + bObstacleShowedUpDuringKillObjective = true; + } else { + SetAttackTimer(CGeneral::GetRandomNumberInRange(700.0f, 1200.0f)); + bObstacleShowedUpDuringKillObjective = true; + } } - } - m_fleeFrom = foundEnt; - m_fleeFrom->RegisterReference((CEntity**) &m_fleeFrom); + m_fleeFrom = foundEnt; + m_fleeFrom->RegisterReference((CEntity**) &m_fleeFrom); + } SetPointGunAt(m_pedInObjective); } } @@ -1541,14 +1540,14 @@ CPed::ProcessObjective(void) // I hope so CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); CVector maxShotPos = m_carInObjective->GetPosition() - ourHead; - maxShotPos.Normalise(); - maxShotPos = maxShotPos * wepInfo->m_fRange + ourHead; + maxShotPos *= wepInfo->m_fRange / maxShotPos.Magnitude(); + maxShotPos += ourHead; - CWorld::bIncludeDeadPeds = true; CColPoint foundCol; CEntity *foundEnt; - CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, - true, true, true, true, false, true, false); + + CWorld::bIncludeDeadPeds = true; + CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, true, true, true, true, false, true, false); CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); From 01c95378e1cffe7ef09f44d992a0144d9a5691a4 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 12 Dec 2020 23:05:12 +0300 Subject: [PATCH 27/52] fixed some replay bugs --- src/control/Garages.h | 3 +++ src/control/Replay.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- src/control/Replay.h | 5 +++++ src/core/Fire.cpp | 6 +++++- src/peds/PedAI.cpp | 8 +++++++- 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/control/Garages.h b/src/control/Garages.h index 79cef36e..34b74fb6 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -251,4 +251,7 @@ private: friend class cAudioManager; friend class CGarage; +#ifdef FIX_BUGS + friend class CReplay; +#endif }; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 757af0a9..4732ba2f 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -10,6 +10,10 @@ #include "DMAudio.h" #include "Draw.h" #include "FileMgr.h" +#ifdef FIX_BUGS +#include "Fire.h" +#include "Garages.h" +#endif #include "Heli.h" #include "main.h" #include "Matrix.h" @@ -22,6 +26,10 @@ #include "Plane.h" #include "Pools.h" #include "Population.h" +#ifdef FIX_BUGS +#include "Projectile.h" +#include "ProjectileInfo.h" +#endif #include "Replay.h" #include "References.h" #include "Pools.h" @@ -102,6 +110,11 @@ float CReplay::fDistanceLookAroundCam; float CReplay::fBetaAngleLookAroundCam; float CReplay::fAlphaAngleLookAroundCam; #ifdef FIX_BUGS +uint8* CReplay::pGarages; +CFire* CReplay::FireArray; +uint32 CReplay::NumOfFires; +uint8* CReplay::paProjectileInfo; +uint8* CReplay::paProjectiles; int CReplay::nHandleOfPlayerPed[NUMPLAYERS]; #endif @@ -1156,6 +1169,17 @@ void CReplay::StoreStuffInMem(void) if (ped) StoreDetailedPedAnimation(ped, &pPedAnims[i]); } +#ifdef FIX_BUGS + pGarages = new uint8[sizeof(CGarages::aGarages)]; + memcpy(pGarages, CGarages::aGarages, sizeof(CGarages::aGarages)); + FireArray = new CFire[NUM_FIRES]; + memcpy(FireArray, gFireManager.m_aFires, sizeof(gFireManager.m_aFires)); + NumOfFires = gFireManager.m_nTotalFires; + paProjectileInfo = new uint8[sizeof(gaProjectileInfo)]; + memcpy(paProjectileInfo, gaProjectileInfo, sizeof(gaProjectileInfo)); + paProjectiles = new uint8[sizeof(CProjectileInfo::ms_apProjectile)]; + memcpy(paProjectiles, CProjectileInfo::ms_apProjectile, sizeof(CProjectileInfo::ms_apProjectile)); +#endif } void CReplay::RestoreStuffFromMem(void) @@ -1206,7 +1230,7 @@ void CReplay::RestoreStuffFromMem(void) ped->m_rwObject = nil; ped->m_modelIndex = -1; ped->SetModelIndex(mi); - ped->m_pVehicleAnim = 0; + ped->m_pVehicleAnim = nil; ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped); DMAudio.SetEntityStatus(ped->m_audioEntityId, true); CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false); @@ -1322,6 +1346,22 @@ void CReplay::RestoreStuffFromMem(void) } delete[] pPedAnims; pPedAnims = nil; +#ifdef FIX_BUGS + memcpy(CGarages::aGarages, pGarages, sizeof(CGarages::aGarages)); + delete[] pGarages; + pGarages = nil; + memcpy(gFireManager.m_aFires, FireArray, sizeof(gFireManager.m_aFires)); + delete[] FireArray; + FireArray = nil; + gFireManager.m_nTotalFires = NumOfFires; + memcpy(gaProjectileInfo, paProjectileInfo, sizeof(gaProjectileInfo)); + delete[] paProjectileInfo; + paProjectileInfo = nil; + memcpy(CProjectileInfo::ms_apProjectile, paProjectiles, sizeof(CProjectileInfo::ms_apProjectile)); + delete[] paProjectiles; + paProjectiles = nil; + //CExplosion::ClearAllExplosions(); not in III +#endif DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); DMAudio.SetRadioInCar(OldRadioStation); DMAudio.ChangeMusicMode(MUSICMODE_GAME); diff --git a/src/control/Replay.h b/src/control/Replay.h index cb58a602..aa2ecd86 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -275,6 +275,11 @@ private: static float fAlphaAngleLookAroundCam; static float fBetaAngleLookAroundCam; #ifdef FIX_BUGS + static uint8* pGarages; + static CFire* FireArray; + static uint32 NumOfFires; + static uint8* paProjectileInfo; + static uint8* paProjectiles; static int nHandleOfPlayerPed[NUMPLAYERS]; #endif diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index c6dece6a..e1be4194 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -90,7 +90,11 @@ CFire::ProcessFire(void) } } } - if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) + if (!FindPlayerVehicle() && +#ifdef FIX_BUGS + FindPlayerPed() && +#endif + !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) && ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) { FindPlayerPed()->DoStuffToGoOnFire(); gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1); diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 62b27134..367c876c 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -2990,9 +2990,15 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg) } if (ped->bFleeAfterExitingCar || ped->bGonnaKillTheCarJacker) { - // POTENTIAL BUG? Why DOOR_FRONT_LEFT instead of door variable? or vice versa? +#ifdef FIX_BUGS + if (!veh->IsDoorMissing(door)) + ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING); + PedSetOutCarCB(nil, ped); + return; +#else if (!veh->IsDoorMissing(door)) ((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING); +#endif } else { switch (door) { case DOOR_FRONT_LEFT: From 8fb461b873580fd48539abc26368b7b8082eec3a Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 13 Dec 2020 00:20:44 +0300 Subject: [PATCH 28/52] removed obsolete ifdef (since we have GTA_REPLAY) --- src/control/Garages.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index ff11600b..07fc0612 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -179,10 +179,8 @@ void CGarages::Shutdown(void) void CGarages::Update(void) { static int GarageToBeTidied = 0; -#ifndef GTA_PS2 if (CReplay::IsPlayingBack()) return; -#endif bCamShouldBeOutisde = false; TheCamera.pToGarageWeAreIn = nil; TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = nil; From 9be5bfe75bbfa6d334656fbc27cfafdeef1eb300 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 13 Dec 2020 12:58:15 +0100 Subject: [PATCH 29/52] sync vis-plugins with miami --- src/rw/VisibilityPlugins.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index b27d96c8..21e00725 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -203,6 +203,10 @@ CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist) return ret; } +// can't increase this yet unfortunately... +// probably have to fix fading for this so material alpha isn't overwritten +#define VEHICLE_LODDIST_MULTIPLIER (TheCamera.GenerationDistMultiplier) + void CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) { @@ -215,11 +219,11 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) else ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f); - ms_vehicleLod0Dist = sq(70.0f * TheCamera.GenerationDistMultiplier); - ms_vehicleLod1Dist = sq(90.0f * TheCamera.GenerationDistMultiplier); - ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier); - ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier); - ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier); + ms_vehicleLod0Dist = sq(70.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_vehicleLod1Dist = sq(90.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_vehicleFadeDist = sq(100.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_bigVehicleLod0Dist = sq(60.0f * VEHICLE_LODDIST_MULTIPLIER); + ms_bigVehicleLod1Dist = sq(150.0f * VEHICLE_LODDIST_MULTIPLIER); ms_pedLod0Dist = sq(25.0f * TheCamera.LODDistMultiplier); ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier); ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); @@ -311,7 +315,12 @@ CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic) m = RwFrameGetLTM(RpAtomicGetFrame(atomic)); RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn); len = RwV3dLength(&view); +#ifdef FIX_BUGS + // from VC + lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / VEHICLE_LODDIST_MULTIPLIER); +#else lodatm = mi->GetAtomicFromDistance(len); +#endif if(lodatm){ if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic)) RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE); From 8c31e1bab0961bb79f468dcac201624d44a4528e Mon Sep 17 00:00:00 2001 From: IlDucci Date: Sun, 13 Dec 2020 16:52:23 +0100 Subject: [PATCH 30/52] Final update on the Spanish translation Did one last proofread/editing pass, but also a full test of the game's main story and some side missions. Here's a list of the most relevant changes: - Changed a few terms to match later games (Wanted level, Paramedic, dollar sign order, Insane Stunt, Wasted!...) - Changed all the control help messages from "Press the X button" to "Press X", as the PC version can display more than one key/input per control. That way, both a single button and multiple buttons won't read wrong. - Added some missing accents on demostrative pronouns and the word "solo" (following the old RAE grammar rules from 1999, this is a stylistic choice to respect the translations of the era). - Fixed a couple of Latin American dialogues. - Fixed some strings from the credits cutting into two lines and blocking the next text. - Overall fine-tuning and naturalization of the text. --- gamefiles/TEXT/spanish.gxt | Bin 236534 -> 234848 bytes utils/gxt/spanish.txt | 754 ++++++++++++++++++------------------- 2 files changed, 377 insertions(+), 377 deletions(-) diff --git a/gamefiles/TEXT/spanish.gxt b/gamefiles/TEXT/spanish.gxt index 7321c2ccefaf9707cfbfe07930b2aee512c3b2b2..3342340641c0077e5f8249498381d25c5c10336c 100644 GIT binary patch delta 42103 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 delta 42520 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 bA6EwW&vo#tuJ+qqn&djNC+g!T{3`kfz7-XV diff --git a/utils/gxt/spanish.txt b/utils/gxt/spanish.txt index bba7091c..f9441ed6 100644 --- a/utils/gxt/spanish.txt +++ b/utils/gxt/spanish.txt @@ -21,7 +21,7 @@ Claude---------------------- ~g~¡No te vayas por tu cuenta! ¡Mantén a tu grupo unido! [HEY2] -~g~¡No os dividáis, mantened al grupo unido! +~g~¡No te separes del grupo! [HEY3] ~g~¡Has perdido a tu colega! ¡Vuelve a por 8-Ball! @@ -33,67 +33,67 @@ Claude---------------------- ~g~Una de las chicas se ha escapado, ¡vuelve y recógela! [HEY6] -~g~Dejaste tu honor con el yakuza Kanbu. ¡Debes protegerlo! +~g~Abandonaste tu honor con el kanbu de la yakuza. ¡Debes protegerlo! [HEY7] -~g~Vendría bien tener una ayudita. ¡Vuelve y encuentra a tu contacto! +~g~Te vendría bien una ayudita. ¡Vuelve y encuentra a tu contacto! [HEY8] ~g~Protección significa exactamente eso: ¡Protege al anciano oriental! [HEY9] -~g~¿Quieres que corra la voz por las calles? ¡Ve a ver al contacto! +~g~¿Sabes lo que tienes que hacer? ¡Ver a tu contacto! [HELP2_A] Pulsa el ~h~botón /~w~ mientras corres para ~h~esprintar~w~. [HELP3] -Sólo puedes esprintar durante cortos períodos antes de cansarte. +Sólo puedes esprintar durante cortos periodos de tiempo antes de cansarte. [HELP4_A] -Pulsa el~h~ botón ~k~~VEHICLE_ACCELERATE~~w~ para ~h~acelerar~w~. +Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para ~h~acelerar~w~. [HELP4_D] Mueve el~h~ joystick analógico derecho~w~ hacia arriba para ~h~acelerar~w~. [HELP5_A] -Pulsa el~h~ botón ~k~~VEHICLE_BRAKE~~w~ para ~h~frenar~w~, o para ~h~dar marcha atrás~w~ si el vehículo está detenido. +Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido. [HELP5_D] -Mueve el ~h~joystick analógico derecho~w~ hacia atrás para ~h~frenar~w~, o para ~h~dar marcha atrás~w~ si el vehículo se ha detenido. +Mueve el ~h~joystick analógico derecho~w~ para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido. [HELP6_A] -Pulsa el~h~ botón ~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. +Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. [HELP6_C] -Pulsa el~h~ botón ~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. +Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. [HELP6_D] -Pulsa el~h~ botón ~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. +Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. [HELP7_A] -Pulsa y mantén el~h~ botón ~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador. +Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador. [HELP7_D] -Pulsa y mantén el~h~ botón ~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador. +Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador. [HELP8_A] -Pulsa el~h~ botón ~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~acercar el zoom ~w~con el fusil y el ~h~botón ~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~alejarlo~w~. +Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~aumentar el zoom ~w~de la mira del fusil y ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~reducirlo~w~. [HELP9_A] -Pulsa el~h~ botón ~k~~PED_FIREWEAPON~ ~w~para ~h~disparar~w~ el fusil de francotirador. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador. [HELP10] -Esta insignia indica que la policía va a por ti. +Esta insignia indica que la policía te está buscando. [HELP11] -Cuantas más insignias tengas, más peligroso te considerarán. +Cuantas más insignias tengas, mayor será tu nivel de búsqueda. [HELP13] -Algunas veces tendrás que usar caminos no mostrados en el radar. +En ocasiones necesitarás ir por caminos que no aparecen en el radar. [TIMER] -Esta es una misión cronometrada, debes completarla antes de que el temporizador llegue a cero. +Ésta es una misión cronometrada, debes completarla antes de que el temporizador llegue a cero. [MISTY1] ~r~¡Misty está para el arrastre! @@ -102,10 +102,10 @@ Esta es una misión cronometrada, debes completarla antes de que el temporizador ~g~¡Sal del vehículo! [GARAGE] -Mete el vehículo dentro del garaje y luego sal caminando. +Mete el vehículo dentro del garaje y sal andando. [WANTED1] -~g~¡Despista a la poli! +~g~¡Despista a la poli y pierde tu nivel de búsqueda! [NODOORS] ~g~¡No son sardinas! Consigue un vehículo con suficientes asientos. @@ -132,7 +132,7 @@ Pulsa el ~h~botón L3~w~ para tocar el ~h~claxon. ~r~¡Te siguen la pista! [REWARD] -RECOMPENSA: $~1~ +RECOMPENSA: ~1~ $ [GAMEOVR] FIN DE LA PARTIDA @@ -141,10 +141,10 @@ FIN DE LA PARTIDA Valor del eje Z: ~1~ [M_FAIL] -¡MISIÓN FRACASADA! +¡MISIÓN FALLIDA! [M_PASS] -¡MISIÓN SUPERADA! $~1~ +¡MISIÓN SUPERADA! ~1~ $ [O_PASS] ¡TRABAJO ESPORÁDICO SUPERADO! @@ -153,7 +153,7 @@ Valor del eje Z: ~1~ ¡TRABAJO ESPORÁDICO FRACASADO! [DEAD] -¡LIQUIDADO! +¡ELIMINADO! [BUSTED] ¡TRINCADO! @@ -165,7 +165,7 @@ Cuando no estés en una misión, podrás ~h~guardar tu partida aquí~w~. Esto ha ~1~ [SCORE] -~1~$ +~1~ $ [LOADCAR] CARGANDO VEHÍCULO... (PULSA EL BOTÓN L1 PARA CANCELAR) @@ -192,46 +192,46 @@ Trucos DESACTIVADOS Sal y espera a tu vehículo. [PAGEB1] -Pistola ya disponible en tu guarida. +Pistola entregada en tu guarida. [PAGEB2] -Uzi ya disponible en tu guarida. +Uzi entregada en tu guarida. [PAGEB3] -Chaleco antibalas ya disponible en tu guarida. +Chaleco antibalas entregado en tu guarida. [PAGEB4] -Escopeta ya disponible en tu guarida. +Escopeta entregada en tu guarida. [PAGEB5] -Granadas ya disponibles en tu guarida. +Granadas entregadas en tu guarida. [PAGEB6] -Molotovs ya disponibles en tu guarida. +Molotovs entregados en tu guarida. [PAGEB7] -AK47 ya disponible en tu guarida. +AK47 entregado en tu guarida. [PAGEB8] -Fusil de francotirador ya disponible en tu guarida. +Fusil de francotirador entregado en tu guarida. [PAGEB9] -M16 ya disponible en tu guarida. +M16 entregado en tu guarida. [PAGEB10] -Lanzacohetes ya disponible en tu guarida. +Lanzacohetes entregado en tu guarida. [PAGEB11] -Lanzallamas ya disponible en tu guarida. +Lanzallamas entregado en tu guarida. [WANT_A] -Sólo serás arrestado si estás en ~h~búsqueda y captura~w~. +Sólo serás arrestado si tienes un ~h~nivel de búsqueda~w~. [WANT_B] -Tu ~h~grado de peligrosidad asignado a tu búsqueda y captura~w~ está representado por la hilera de estrellas en la parte superior derecha de la pantalla. +Tu ~h~nivel de búsqueda~w~ está representado por una hilera de estrellas en la parte superior derecha de la pantalla. [WANT_C] -Ahora tienes un ~h~grado de búsqueda y captura~w~ de uno... +Ahora tienes un ~h~nivel de búsqueda~w~ de una estrella... [WANT_D] dos... @@ -240,31 +240,31 @@ dos... tres... [WANT_F] -A medida que tu ~h~grado de búsqueda y captura~w~ vaya aumentando, te verás acosado por cuerpos policiales con una mayor potencia de fuego. +A medida que aumente tu ~h~nivel de búsqueda~w~, serás perseguido por fuerzas con una mayor potencia de fuego. [WANT_G] -Cuando seas ~h~''trincado''~w~ serás llevado a la comisaría de policía más cercana. +Si te ~h~trinca~w~ la poli, te llevarán a la comisaría más cercana. [WANT_H] -Los polis requisarán todas tus armas y algo de tu dinero como soborno. +Los agentes te requisarán todas tus armas y se quedarán con parte de tu dinero como soborno. [WANT_I] -Habrás fracasado en cualquier misión que estuvieses llevando a cabo. +Fracasarás cualquier misión que estuvieses llevando a cabo. [WANT_J] -A medida que avances en el juego encontrarás formas de reducir tu grado de búsqueda y captura. +A medida que avances en el juego, encontrarás formas de reducir tu nivel de búsqueda. [WANT_K] -Si estás en un coche, los ~h~TALLERES DE PINTURA~w~ te quitarán ~h~tu grado de búsqueda y captura~w~. +Si estás en un coche, los ~h~TALLERES DE PINTURA~w~ te quitarán ~h~tu nivel de búsqueda~w~. [HEAL_B] -Cuando seas ~h~''liquidado''~w~ volverás al hospital más cercano. +Cuando seas ~h~eliminado~w~, te llevarán al hospital más cercano. [HEAL_C] -Los doctores te quitarán tus armas y te cobrarán un dinero por remendarte. +Te quitarán tus armas y los médicos te cobrarán un dinero por curarte. [HEAL_E] -A medida que avances en el juego encontrarás modos de curarte o de protegerte. +A medida que avances en el juego, encontrarás modos de curarte o de protegerte. [DAM] DAÑO: @@ -288,7 +288,7 @@ ESTADO DEL COCHE: RECOGIDOS: [BOMB] -Mete tu vehículo en la tienda de ~h~bombas~w~ para poner una. Coste: ~h~1.000$~w~. +Mete tu vehículo en la tienda de ~h~bombas~w~ para poner una. Coste: ~h~1.000 $~w~. [SAVE1] Pasa por la puerta para ~h~guardar la partida~w~. No podrás guardar durante una misión. @@ -297,13 +297,13 @@ Pasa por la puerta para ~h~guardar la partida~w~. No podrás guardar durante una Cualquier vehículo que dejes en este garaje se conservará al guardar la partida. [AMMU] -Entra a la tienda Ammu-Nation para comprar armas. +Entra en la tienda Ammu-Nation para comprar armas. [BRIDGE1] -Cuando el puente Callahan esté reparado podrás conducir hasta Staunton Island. +Podrás conducir hasta Staunton Island cuando el puente Callahan esté reparado. [TUNNEL] -Cuando el túnel Porter esté abierto podrás conducir hasta Staunton Island. +Podrás conducir hasta Staunton Island cuando el túnel Porter esté abierto. [LUIGI] MISIONES DE LUIGI @@ -573,13 +573,13 @@ Club de Luigi ~g~Joey ha salido con Misty. ¡Pásate más tarde! [TONIGO] -~g~Toni ha llevado a su mamá a la ópera... ¡Llama en otro momento! +~g~Toni ha llevado a su mamá a la ópera... ¡Vente en otro momento! [KEMUGO] ~g~María y Kemuri están muy liadas... ¡Pásate más tarde! [KENJGO] -~g~Kenji está reunido con la yakuza, ¡llama en otro momento! +~g~Kenji está reunido con la yakuza, ¡ven en otro momento! [RAYGO] ~g~Ray tiene otros baños por los que rondar, ¡ven en otro momento! @@ -606,31 +606,31 @@ Club de Luigi ~g~Vuelve entre las 15:00 y las 00:00 para buscar trabajo. [GUN_1A] -Pulsa el ~h~botón ~k~~PED_CYCLE_WEAPON_RIGHT~~w~ y el ~h~botón ~k~~PED_CYCLE_WEAPON_LEFT~ ~w~para cambiar de arma. +Pulsa ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ y ~h~~k~~PED_CYCLE_WEAPON_LEFT~ ~w~para cambiar de arma. [GUN_2A] -¡Mantén pulsado el ~h~botón ~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar de modo automático~w~ y pulsa el ~h~botón ~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a los objetivos... +¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas... [GUN_2C] -¡Mantén pulsado el ~h~botón ~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar de modo automático~w~ y pulsa el ~h~botón ~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a los objetivos... +¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas... [GUN_2D] -¡Mantén pulsado el ~h~botón ~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar de modo automático~w~ y pulsa el ~h~botón ~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a los objetivos... +¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas... [GUN_3A] -Mientras mantienes pulsado el ~h~botón ~k~~PED_LOCK_TARGET~,~w~ pulsa el ~h~botón ~k~~PED_CYCLE_TARGET_LEFT~~w~ o el ~h~botón ~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo. +Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~,~w~ pulsa ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo. [GUN_3B] -Mientras mantienes pulsado el ~h~botón ~k~~PED_LOCK_TARGET~,~w~ pulsa el ~h~botón ~k~~PED_CYCLE_TARGET_LEFT~~w~ o el ~h~botón ~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo. +Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~,~w~ pulsa ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo. [GUN_4A] -Mientras mantienes pulsado el ~h~botón ~k~~PED_LOCK_TARGET~~w~, puedes caminar o correr y seguir teniendo en la mira a un objetivo. +Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu objetivo. [GUN_4B] -Mientras mantienes pulsado el ~h~botón ~k~~PED_LOCK_TARGET~~w~, puedes caminar o correr y seguir teniendo en la mira a un objetivo. +Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu objetivo. [GUN_5] -Puedes practicar disparando a estos blancos. Cuando hayas terminado puedes continuar la misión. +Puedes practicar disparando a estas dianas. Vuelve a la misión cuando hayas terminado. [TAXI1] ~g~Busca un cliente. @@ -708,22 +708,22 @@ Puedes practicar disparando a estos blancos. Cuando hayas terminado puedes conti ~g~Ve a las ~w~Torres del Noroeste ~g~de Wichita Gardens. [NEW_TAX] -¡MÁS GRANDES! ¡MÁS RÁPIDO! ¡MÁS DUROS! Los nuevos taxis Borgnine abren su negocio en Harwood. ¡Llame hoy al 555-BORGNINE! +¡MÁS GRANDES! ¡MÁS RÁPIDOS! ¡MÁS DUROS! Los nuevos taxis Borgnine abren sus puertas en Harwood. ¡Llame hoy al 555-BORGNINE! [TSCORE2] -$~1~ +~1~ $ [IN_ROW] -¡~1~ CONSECUTIVOS! $~1~ +¡Racha de ~1~ clientes! Premio de ~1~ $. [TTUTOR] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi. [TTUTOR2] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi. [ATUTOR2] -~g~Conduce a los pacientes hasta el hospital con mucho cuidado. Cada golpe reducirá sus posibilidades de supervivencia. +~g~Lleva a los pacientes al hospital CON CUIDADO. Cada golpe reducirá sus posibilidades de supervivencia. [A_TIME] +~1~ segundos @@ -735,10 +735,10 @@ Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misi ~g~La radio de la ambulancia está fuera de cobertura, ¡acércate a un hospital! [FTUTOR] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos. [FTUTOR2] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos. [F_PASS1] ¡Fuego apagado! @@ -753,7 +753,7 @@ Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misi ~g~La radio de la policía está fuera de cobertura, ¡acércate a una comisaría! [DODO_FT] -¡Volaste durante ~1~ segundos! +¡Has volado durante ~1~ segundos! [EBAL_A] Conozco un lugar en las afueras del barrio rojo donde podemos escondernos, @@ -762,16 +762,16 @@ Conozco un lugar en las afueras del barrio rojo donde podemos escondernos, pero mis manos están destrozadas, así que conduce tú, hermano. [EBAL_1] -Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo. +Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo. [EBAL_1B] -Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo. +Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo. [EBAL_2] ~g~¡Vuelve al coche! [EBAL_3] -Este es el ~h~radar~w~. Utilízalo para recorrer la ciudad: ¡sigue el ~h~punto~w~ en el ~h~radar~w~ para encontrar el escondite! +Éste es el ~h~radar~w~. Utilízalo para guiarte por la ciudad. ¡Ve hasta la ~h~señal~w~ del ~h~radar~w~ para encontrar el escondite! [EBAL_D] Conozco a un tipo con contactos, se llama Luigi. @@ -788,13 +788,13 @@ Venga, vamos a pasarnos por allí y te presentaré. El jefe os recibirá enseguida... [EBAL_J] -8-Ball que ocuparse de una cosa arriba. +8-Ball tiene cosas que hacer arriba. [EBAL_K] Quizá puedas hacerme un favor. [EBAL_L] -Una de mis chicas necesita que la lleven, así que consigue un coche, recoge a Misty en la clínica y luego tráela aquí. +Una de mis chicas necesita que la lleven, así que consigue un coche, recoge a Misty en la clínica y tráela aquí. [EBAL_N] ¡Así que no quites las manos del volante! @@ -830,34 +830,34 @@ Una de mis chicas necesita que la lleven, así que consigue un coche, recoge a M ~g~¡Vuelve al coche! [LM1_7] -Detén el vehículo junto a Misty y déjala subir. +Para el vehículo junto a Misty y déjala que suba. [LM1_8] -Puedes ir a ver a Luigi y buscar más trabajo o darte un paseo por Liberty City. +Puedes ir a ver a Luigi para que te dé más trabajo o explorar Liberty City. [LM2_A] Hay una nueva droga en la ciudad llamada SPANK. [LM2_E] -Algún listillo ha estado dando esta basura a mis chicas en el puerto de Portland. +Algún listillo ha pasado esta basura a mis chicas en el puerto de Portland. [LM2_B] -¡Ve y dale con un bate de béisbol en su cara! +¡Ve y repásale la cara con un bate de béisbol! [LM2_G] ¡Quiero una compensación por este insulto! [LM2_1] -~g~Coge su coche y haz que cambien su pintura. +~g~Llévate su coche y repíntalo. [LM2_2A] -¡Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! +¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! [LM2_2C] -¡Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! +¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! [LM2_2D] -¡Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! +¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate! [LM2_3] ~g~¡Mete el coche en el garaje de Luigi! @@ -884,10 +884,10 @@ pero cuidado, ese es territorio de los Diablos. Luego llévala rapidito hasta su taller en Trenton, [LM3_H] -¡así que estate pendiente del camino y no de Misty! +¡así que fíjate en el camino y no en Misty! [LM3_1D] -Pulsa el ~h~botón L3 ~w~para tocar el ~h~claxon~w~ y hacer saber a Misty que estás aquí. +Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty. [LM3_2] ~g~Lleva a Misty al local de Joey. @@ -899,16 +899,16 @@ Pulsa el ~h~botón L3 ~w~para tocar el ~h~claxon~w~ y hacer saber a Misty que es Ahora trabajas para Luigi, ¿no? ¡Ya era hora de que tuviese un conductor de confianza! [LM3_7] -Estaré contigo en un minuto, bujía mía. +Estaré contigo en un momento, bujía mía. [LM3_10] ~g~¡Consigue un vehículo! [LM4_B] -Ve y resuélvelo de mi parte. +Resuelve esto por mí. [LM4_C] -Si necesitas un arma, ve a la puerta trasera de la tienda Ammu-Nation que está enfrente del metro. +Si necesitas un arma, ve a la parte de atrás del Ammu-Nation que está enfrente del metro. [LM5_A] El baile de la policía se está celebrando en la sala Clásica, cerca del puente, @@ -917,16 +917,16 @@ El baile de la policía se está celebrando en la sala Clásica, cerca del puent y parece que tienen ganas de una fiesta más ''clásica''. [LM5_C] -Tengo chicas haciendo la calles. +Tengo chicas haciendo la calle. [LM5_D] Llévalas al baile, sacarán una buena tajada. [LM5_1] -~g~¡Tienes a las chicas tan embutidas que les van a salir moratones! ~g~Primero deja a las que llevas y luego ve a por más. +~g~¡Tienes a las chicas tan embutidas que les van a salir moratones! Primero deja a las que llevas y luego ve a por más. [LM5_2] -~r~¡Te has cargado a una de las chicas de Luigi! +~r~¡Una chica de Luigi la ha espichado! [LM5_3] ~g~¡Necesitas un coche! @@ -971,13 +971,13 @@ Llévalas al baile, sacarán una buena tajada. ~y~¡Ey, pero si es mi colega! [JM1_8B] -~y~El taller de bombas está automatizado. Solo tienes que meter el coche, pararlo y el taller hará el resto. +~y~El taller de bombas está automatizado. Sólo tienes que meter el coche, pararlo y el taller hará el resto. [JM1_8C] ~y~Ten, tu primer coche es gratis, pero los siguientes te los cobraré. [JM2_A] -Lee Chong ''el Gordo'' está traficando SPANK para una nueva banda de Colombia... o Colorado... O como se llame. +Lee Chong ''el Gordo'' está traficando SPANK para una nueva banda de Colombia, o Colorado... O como se llame. [JM2_B] No me acuerdo. El caso es que no importa. @@ -995,7 +995,7 @@ Búscate un nueve, queda claro, ¿no? Y recuerda, ve con ojo en Chinatown: es territorio de las Tríadas. [JM3_A] -Vamos a asaltar un furgón blindado. +Vamos a robar un furgón blindado. [JM3_B] Sale de Chinatown todos los días. @@ -1007,7 +1007,7 @@ Las balas ni siquiera abollarán el furgón, así que coge un coche y échalo de Si lo zurras bien, los imbéciles de los guardias se achantarán. [JM3_E] -Luego llévalo al almacén de los muelles y mis chicos se encargarán desde ahí. +Luego llévalo al almacén de los muelles y mis chicos se encargarán del resto. [JM3_F] El furgón no estará fuera todo el día, así que no pierdas el tiempo. @@ -1016,16 +1016,16 @@ El furgón no estará fuera todo el día, así que no pierdas el tiempo. ~g~Lleva el furgón al almacén. [JM3_2] -~g~Carga contra la furgoneta hasta que su daño esté por debajo del 70 por ciento. +~g~Carga contra el furgón hasta que su daño esté por debajo del 70 por ciento. [JM4_B] ¡Ah, aquí está el tío que te decía! [JM4_C] -Bueno, este no es italiano ni tampoco mecánico, pero sabe arreglar cosas. +Bueno, éste no es italiano ni tampoco mecánico, pero sabe arreglar cosas. [JM4_D] -Este es el capo de papá, Toni Cipriani. +Él es el capo de papá, Toni Cipriani. [JM4_E] Sí, soy Toni Cipriani. @@ -1037,7 +1037,7 @@ Llévale al restaurante de Mamma en Saint Mark's, ¿va? Oye, estoy planeando un curro que necesita un buen conductor, pásate por aquí más tarde, ¿estamos? [JM4_2] -¡Espera aquí! Deja el motor en marcha. Esta no es una visita social. +¡Espera aquí! Deja el motor en marcha. Ésta no es una visita social. [JM4_3] ¡Es una emboscada de las Tríadas! ¡Sácanos de aquí, chico! @@ -1046,13 +1046,13 @@ Oye, estoy planeando un curro que necesita un buen conductor, pásate por aquí Las Tríadas creen que pueden meterse conmigo. ¡Las Tríadas, CONMIGO! [JM4_6] -¡Mi coche! Dije que con cuidado. +¡Mi coche! Dije que fueras con cuidado. [JM4_7] ~g~Lleva a Toni al restaurante de Mamma. [JM4_8] -~r~¡Han liquidado a Toni! +~r~¡Toni la ha palmado! [JM5_A] Guapo, muy guapo... @@ -1085,7 +1085,7 @@ Van a atracar un banco y necesitan un conductor. Di mi palabra de que eras su hombre, así que no la cagues. [JM6_E] -Llévales al banco antes de las cinco en punto, ni un minuto después. +Llévalos al banco antes de las cinco en punto, ni un minuto después. [JM6_2] Mantén el motor en marcha, entraremos y saldremos enseguida. @@ -1130,7 +1130,7 @@ La lavandería no quiere pagar la protección, ¿eh? ¿Las Tríadas creen que pueden meterse conmigo? [TM1_D] -¡Esos aspirantes a tipos duros van a saber lo que es ser un tipo duro! +¡Se van a enterar esos aspirantes a tipos duros de lo que es ser un tipo duro! [TM1_E] ¡Eso, enséñales respeto! ¡Las Tríadas no se ríen de ninguno de mis hijos! @@ -1250,7 +1250,7 @@ Vale, ya me he hartado de esta mierda. 8-Ball ha instalado una bomba en un camión de la basura. [TM5_E] -Tiene un temporizador, así que si la lías no quedará nada de ti. Ve a por el camión. +Lleva un temporizador, así que si te despistas, no quedará nada de ti. Ve a por el camión. [TM5_F] ¡Cuidado, 8-Ball dice que es muy sensible y que cualquier golpe puede hacerlo estallar! @@ -1307,7 +1307,7 @@ Llévate la limusina, pero devuélvela de una pieza, ¿me has oído? Y cuidado con ella, es una lianta. [FM1_L] -¡Sí, sí, sí! Seguro que tu nuevo perrito faldero tiene todo previsto. +¡Sí, sí, sí! Seguro que tu nuevo perrito faldero está pendiente de todo. [FM1_M] ¿No es fuerte y grande? @@ -1316,7 +1316,7 @@ Y cuidado con ella, es una lianta. ¡Oye, tú, vamos a ver a Chico para que nos dé unas pirulas! [FM1_P] -~g~Ese de ahí es Chico, párate cerca. +~g~Ése de ahí es Chico, párate cerca. [FM1_S] Aquí tienes, señorita. @@ -1331,7 +1331,7 @@ Aquí tienes, señorita. ~g~¡Entra en el Stretch! [FM1_3] -~r~Si abandonas a María, Salvatore hará que te maten. Vuelve y recógela. +~r~Si abandonas a María, Salvatore hará que te maten. Vuelve a por ella. [FM1_4] ~g~¡Has dejado a la chica del Don tirada! ¡Vuelve al almacén y espera a María! @@ -1367,10 +1367,10 @@ Ha estado gastando más dinero del que gana. Suele ir del trabajo a casa en taxi, así que síguelo. [FM2_O] -Y si nos está vendiendo... mátalo. +Y si nos está vendiendo..., mátalo. [FM2_F] -Aquí viene nuestro amiguito. El señor Bocazas en persona. +Aquí viene nuestro amiguito. El señor Bocón en persona. [FM2_G] ¿Te han seguido? Ya sabes que esto es nuestro secretito. @@ -1424,7 +1424,7 @@ Con lo leales que son algunos, ¿de qué tendría que preocuparse? ~r~¡Curly se ha largado! [FM2_11] -~g~Aparca enfrente del club de Luigi; Curly Bob saldrá pronto. +~g~Aparca enfrente del club de Luigi;Curly Bob saldrá pronto. [FM2_12] ~r~¡Te ha dado esquinazo! @@ -1451,7 +1451,7 @@ Así que tenemos que actuar con cuidado, o mejor dicho, tú tienes que hacerlo. Te estoy pidiendo que destruyas esa fábrica de SPANK como un favor personal para mí, Salvatore Leone. [FM3_H] -Si haces esto por mí, serás como de la familia. Todo lo que quieras. +Si lo haces, entrarás en la familia. Tendrás todo lo que quieras. [FM3_I] Ve a ver a 8-Ball, necesitarás su ayuda para volar ese barco. @@ -1472,7 +1472,7 @@ Venga, ¡vamos allá! Puedo reventar el barco, pero aún no puedo usar una pipa con estas manos. [FM3_8G] -¡Toma, este fusil te ayudará a volar unas cuántas cabezas! +¡Toma, con este fusil podrás reventar unas cuantas cabezas! [FM3_4] ~g~¡Para el coche y deja que 8-Ball salga! @@ -1487,7 +1487,7 @@ Puedo reventar el barco, pero aún no puedo usar una pipa con estas manos. ¡Mi socio favorito! [FM4_B] -Estoy orgulloso de ti, hijo, pusiste finos a esos sudacas. +Estoy orgulloso, hijo, pusiste finos a esos sudacas. [FM4_C] Tengo un trabajito más para ti antes de que podamos celebrarlo. @@ -1505,7 +1505,7 @@ Tuvimos que ayudar a un tipo a que se decidiera y fue un poco... sucio. Llévalo a la trituradora antes de que lo encuentre la pasma. [AM3] -'PURGA DE PAPARAZZIS' +'PURGA DEL PAPARAZZI' [AM4] 'LA PAGA DE RAY' @@ -1532,7 +1532,7 @@ pero primero debes demostrarme que has cortado todos tus lazos con la mafia. Asegúrate de que no salga con vida. [AM1_H] -Mientras tanto María y yo nos pondremos al día. +Mientras tanto, María y yo nos pondremos al día. [AM1_I] Uy, Asuka, tienes un masajeador... @@ -1568,10 +1568,10 @@ Eso no es un masajeador. Un periodista ha estado husmeando por aquí. [AM3_B] -María y yo nos ido de vacaciones juntas hasta que puedas librarte de ese mirón pervertido. +María y yo nos hemos ido de vacaciones hasta que puedas librarte de ese mirón pervertido. [AM4_A] -¡Si es guapo manitas! +¡Si es mi guapo manitas! [AM4_B] María está un poquito liada, pero le diré que has venido. @@ -1595,10 +1595,10 @@ Ve a la cabina en Torrington tan rápido como puedas y espera sus instrucciones. María y yo hemos ido de compras. [AM5_B] -¡Nuestro contacto en la policía nos ha informado que uno de nuestros conductores es un poli infiltrado que se mueve de forma extraña! +¡Nuestro contacto en la policía nos ha informado de que uno de nuestros conductores es un poli infiltrado que se mueve de forma extraña! [AM5_C] -Fuera de su coche no sabe hacer casi nada, así que le hemos puesto un localizador. +Sin un coche es prácticamente un inútil, así que le hemos puesto un localizador. [AM5_D] ¡Haz que sufra! @@ -1673,10 +1673,10 @@ Dale un toque rápido... ¡Mi manitas! [AS3_E] -Me aburría, así que vine a hacerle compañía a Asuka. +Me aburría, así que vine a hacer compañía a Asuka. [AS3_1] -~g~¡Busca una ~r~lancha~g~ y ve a la ~b~boya señalada! +~g~¡Busca una ~r~lancha~g~ y ve a la ~b~boya señalada~g~! [AS3_3] ~g~¡Espera a que la ~y~avioneta~g~ comience a acercarse! @@ -1709,10 +1709,10 @@ Me aburría, así que vine a hacerle compañía a Asuka. Mi hermana te tiene en gran estima, [KM1_E] -pero yo debo convencerme de que un gaijin puede ofrecerme algo más que desilusiones. +pero yo no estoy convencido de que un gaijin pueda ofrecerme algo más que desilusiones. [KM1_B] -Tal vez puedas ayudar con una situación que me tiene en desventaja. +Tal vez puedas ayudar con una situación que me perjudica. [KM1_F] Por supuesto, el fracaso conllevará una desgracia. @@ -1724,10 +1724,10 @@ Un kanbu, o jefe de la yakuza, está bajo custodia a la espera de juicio. Es un miembro importante de la familia. [KM1_H] -Libéralo y llévatelo al dojo de Bedford Point. +Libéralo y llévalo al dojo de Bedford Point. [KM1_D] -Te damos las gracias por tus generosas acciones. Si alguna vez necesitas ayuda, el dojo tendrá el honor de proporcionarte dos hombres que te ayudarán. +Agradecemos tus generosas acciones. Si alguna vez necesitas ayuda, el dojo tendrá el honor de proporcionarte dos hombres que te ayudarán. [KM1_1] ~g~¡Roba un coche de la policía! @@ -1817,7 +1817,7 @@ Para ser verdaderamente fuerte, es importante no mostrar debilidad. Hazte con el dinero inmediatamente para que podamos ingresarlo en las cuentas del casino. [KM4_1] -¡No puedo pagarte y no lo haría aunque pudiera! +¡Ni puedo pagarte, ni lo haría aunque pudiera! [KM4_9] ¡Una banda de chavales acaba de arrasar el local! ¡Se han llevado todo! @@ -1840,34 +1840,34 @@ No pago a matones como vosotros para esto. Si quisiera esta clase de protección ~r~¡El tendero la acaba de palmar! [KM4_5] -Donald Love desea que te pases por su jardín de té para tener una charla. +Donald Love desea que te pases por su terraza para tener una charla. [KM4_6] ¡Aquí está todo el dinero! [KM4_8] -~g~¡Maletín recolectado! +~g~¡Maletín conseguido! [KM5_A] ¡Tú! ¡Qué oportuno por tu parte que muestres ahora tu despreciable cara! [KM5_B] -¡Parece que tus intentos para disuadir a los jamaicanos +¡Parece que tu ataque para disuadir a los jamaicanos [KM5_B1] -de convertirse en aliados del cártel han sido totalmente inútiles! +de convertirse en aliados del cártel ha sido completamente inútil! [KM5_C] -¡Los traficantes jamaicanos están llenando las calles de Liberty, vendiendo SPANK como si fueran perritos calientes! +¡Los traficantes jamaicanos están vendiendo SPANK por las calles de Liberty como si fueran perritos calientes! [KM5_D] Estos cerdos del cártel se están riendo de nosotros, ¡de mí! [KM5_E] -¡Te daré una última oportunidad para demostrar que la fe que tiene mi hermana en ti tiene un buen motivo! +¡Te daré una última oportunidad para demostrar que la fe que tiene mi hermana en ti está justificada! [KM5_F] -¡Arrolla a estos canallas y lava tu vergüenza en el río de la sangre de nuestros enemigos! +¡Aplasta a estos canallas y lava tu vergüenza en el río de la sangre de nuestros enemigos! [KM5_3] ~r~No has matado a ~1~ jamaicanos. @@ -1876,7 +1876,7 @@ Estos cerdos del cártel se están riendo de nosotros, ¡de mí! ~g~Enhorabuena, has matado a ~1~ jamaicanos. [KM5_5] -~g~Enhorabuena, has matado a ~1~ jamaicanos. ~1~$ ADICIONALES +~g~Enhorabuena, has matado a ~1~ jamaicanos. PREMIO DE ~1~ $ [RM1] 'SILENCIA AL SOPLÓN' @@ -1909,7 +1909,7 @@ Quema el lugar, así saldrán y podrás cazarlos. Asegúrate de que no hable con Un viejo colega del ejército tiene un negocio en Rockford. [RM2_D] -Va a necesitar respaldo y a cambio te venderá material de todo tipo a precios de ganga. +Necesitará refuerzos y a cambio te venderá todo su material a precios de ganga. [RM2_E] Ray me avisó... Pero pensé que vendría más gente. @@ -1921,7 +1921,7 @@ Bueno, tres brazos son mejor que uno, así que sírvete. ~g~¡Ve a ver a Phil! [RM2_H] -~r~¡Han matado a Phil! +~r~¡Phil ha muerto! [RM2_L] ¡Caray! ¡Si hubieras estado a mi lado en Nicaragua, a lo mejor conservaría el brazo! @@ -1960,13 +1960,13 @@ Creo que mi socio es un soplón. Casi todas las noches sale a pescar con su lancha cerca del faro que hay en Portland Rock. [RM4_D] -¡Roba una lancha de la policía y asegúrate de que se le acaben las ganas de dar puñaladas traperas! +¡Roba una lancha de la policía y húndele las ganas de dar puñaladas traperas! [RM4_1] -~g~Ve y roba una lancha de la policía. +~g~Roba una lancha de la policía. [RM4_2] -~g~¡Ve al faro y ''hunde'' al socio de Ray! +~g~¡Ve al faro y despacha al socio de Ray! [RM5_A] ¡Inútil de mierda! @@ -1984,10 +1984,10 @@ Casi todas las noches sale a pescar con su lancha cerca del faro que hay en Port Está a punto de ser trasladado del hospital general Carson, en Rockford. [RM5_D] -Si él canta, yo canto... +¡Si él canta, yo canto! [RM5_E] -¡así que termina el trabajo por el que te pagué! +¡Así que termina el trabajo por el que te pagué! [RM5_1] ~g~Intercepta la ambulancia. @@ -1999,7 +1999,7 @@ Si él canta, yo canto... ~g~¡Era un señuelo! [RM5_4] -~g~¡Las balas no penetran en esa escayola de cuerpo entero! +~g~¡Las balas no atraviesan esa escayola de cuerpo entero! [RM5_5] ~g~¡Esa escayola de cuerpo entero es ignífugo! @@ -2047,7 +2047,7 @@ Rescata a mi amigo cueste lo que cueste. ~g~La puerta sólo se abrirá ante un coche de los colombianos. [LOVE2_A] -No hay nada como una clásica guerra de bandas para hacer que bajen los precios de las viviendas, +No hay nada como una clásica guerra de bandas para hacer que bajen los precios de los bienes inmuebles, [LOVE2_B] excepto una plaga... pero eso sería excesivo en este caso. @@ -2131,13 +2131,13 @@ He sobornado a los funcionarios. ~g~¡Usa el ascensor! [LOVE5_B] -Mi amigo oriental necesitará que le escolten mientras comprueba la autenticidad de mi última adquisición. +Mi amigo oriental necesita que le escolten mientras comprueba la autenticidad de mi última adquisición. [LOVE5_1] ~g~¡En marcha! [LOVE5_2] -~g~¡Vas a necesitar un coche! +~g~¡Necesitas un coche! [LOVE5_3] ~g~¡Comprueba la salida del túnel! @@ -2247,10 +2247,10 @@ Una bomba de coche vale 1.000 dólares. Tu coche ya tiene una bomba instalada. [GA_6] -¡Apárcalo, activa el detonador pulsando el ~h~botón ~k~~PED_FIREWEAPON~~w~ y SAL DE AHÍ! +¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO! [GA_7] -Activa la bomba con el ~h~botón ~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor. +Activa la bomba pulsando ~h~~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor. [GA_8] Utiliza el detonador para activar la bomba. @@ -2641,7 +2641,7 @@ Mujeres civiles asesinadas Polis asesinados [GNG_WST] -Maleantes asesinados +Miembros de bandas asesinados [MED_WST] Médicos asesinados @@ -2689,49 +2689,49 @@ Días de juego transcurridos mm de lluvia caídos [MXCARD] -Dist. máx. de salto acrobático (pies) +Dist. máx. de salto demencial (pies) [MXCARJ] -Altitud máx. de salto acrobático (pies) +Altura máx. de salto demencial (pies) [MXCARDM] -Dist. máx. de salto acrobático (metros) +Dist. máx. de salto demencial (metros) [MXCARJM] -Altitud máx. de salto acrobático (metros) +Altura máx. de salto demencial (metros) [MXFLIP] -Vueltas durante salto acrobático +Vueltas máximas en salto demencial [MXJUMP] -Rotación máx. de salto acrobático +Rotación máxima en salto demencial [BSTSTU] -Mejor acrobacia hasta ahora: +Mayor acrobacia demencial: [INSTUN] -Acrobacia +Acrobacia demencial [PRINST] -Acrobacia perfecta +Acrobacia demencial perfecta [DBINST] -Acrobacia doble +Acrobacia demencial doble [DBPINS] -Acrobacia doble perfecta +Acrobacia demencial doble perfecta [TRINST] -Acrobacia triple +Acrobacia demencial triple [PRTRST] -Acrobacia triple perfecta +Acrobacia demencial triple perfecta [QUINST] -Acrobacia cuádruple +Acrobacia demencial cuádruple [PQUINS] -Acrobacia cuádruple perfecta +Acrobacia demencial cuádruple perfecta [NOSTUC] No se han hecho acrobacias @@ -2743,7 +2743,7 @@ Saltos únicos completados Saltos únicos [NMISON] -Misiones intentadas +Intentos de misión [NMMISP] Misiones superadas @@ -2755,7 +2755,7 @@ Pasajeros transportados Dinero conseguido en taxi [DAYPLC] -Gasto diario de la policía +Gastos diarios provocados a la policía [CRIMRA] Rango de criminal: @@ -3061,7 +3061,7 @@ Claxon (botón L3) 'A LA HOGUERA' [DIAB4] -'GRANDE Y VENOSO' +'GRANDE Y VENOSA' [DIAB1_A] El Burro quiere ofrecerte una oportunidad. Ve al teléfono público de los cerros de Hepburn si te interesa. @@ -3082,16 +3082,16 @@ Se te da bien correr. Pásate por el teléfono público y puede que El Burro ten ~g~Felicidades, has ganado con un tiempo increíble de ~1~ segundos. [FIRST] -~g~1.° +~g~1 [SECOND] -~g~2.° +~g~2 [THIRD] -~g~3.° +~g~3 [FOURTH] -~g~4.° +~g~4 [DIAB2_1] ~g~Recoge el maletín en Harwood. @@ -3103,13 +3103,13 @@ Se te da bien correr. Pásate por el teléfono público y puede que El Burro ten ~g~Aparca el camión de helados en el muelle Atlantic. [DIAB2_4] -~g~Pulsa el ~w~botón ~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. +~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. [DIAB2_6] -~g~Pulsa el ~w~botón ~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. +~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. [DIAB2_7] -~g~Pulsa el ~w~botón ~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. +~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados. [DIAB2_5] ~g~Sal del camión y luego usa el mando a distancia para detonarlo. @@ -3133,10 +3133,10 @@ El Rey Courtney quiere hablarte. ¡Ve al teléfono público de Aspatria! Habla el rey Courtney. [YD1_A1] -Mi banda jamaicana necesita un conductor y tú tienes reputación de ser bueno. +Mi banda jamaicana necesita un conductor y tú tienes buena reputación. [YD1_B] -Ve en un coche al basurero que hay detrás del estadio y a los otros candidatos. +Ve en un coche al vertedero que hay detrás del estadio y espera a los otros candidatos. [YD1_C] Tengo hombres vigilando puntos de control por toda Staunton. @@ -3169,7 +3169,7 @@ Si ganas más puntos de control que los demás, podría tener trabajo para ti. ~r~3 [YD1_BON] -¡1.000$! +¡1.000 $! [Y1_1ST] ~G~¡Has quedado primero con ~1~ puntos de control! @@ -3235,7 +3235,7 @@ Pero recuerda, ~r~¡no salgas de este coche! ¡Eres la Muerte personificada! [YD2_M] -~r~¡Ha destrozado mi coche! ¡Liquídale! +~r~¡Ha destrozado mi coche! ¡Liquídalo! [YD2_N] ¡Vuelve al coche! @@ -3304,7 +3304,7 @@ Mueve el culo a Bedford Point. CARTA: Dicen que estuviste entretenido. Igual que yo. [YD4_C] -¡Es hora de que seas testigo del verdadero poder del 'SPANK'! Con mucho amor, Catalina. +¡Es hora de que seas testigo del verdadero poder del SPANK! Con mucho amor, Catalina. [YD4_D] P.D. ¡MUERE, BASURA, MUERE! @@ -3343,7 +3343,7 @@ Hay unos macarrillas en la calle que no piensan más que en pistolas y en SPANK. ¡Si golpeas las ruedas de un vehículo, el coche teledirigido estallará! [HM2_4] -¡Si el coche teledirigido se sale fuera de cobertura, estallará solo! +¡Si el coche teledirigido sale fuera de cobertura, estallará solo! [HM2_5] ~r~¡Te has ido de cobertura! @@ -3421,22 +3421,22 @@ Un amigo dijo que tú podías arreglar algunos problemas que tengo. Ve al teléf ~r~¡Un ladrón ha muerto! [MEA2_4] -~r~¡Has dejado atrás a un ladrón! +~r~¡Has abandonado a un ladrón! [MEA3_B3] ~g~Recoge a la Sra. Chonks. [MEA3_B6] -~g~Llévate el coche y tíralo al mar, así eliminaremos las pruebas. +~g~Llévate el coche y tíralo al mar para eliminar las pruebas. [MEA3_1] -~r~¡La mujer está muerta! +~r~¡La mujer ha muerto! [MEA3_2] ~r~¡Se suponía que debías tirar el coche al agua! [MEA3_3] -~r~¡Has dejado atrás a su mujer! +~r~¡Has abandonado a su mujer! [MEA4_B3] ~g~Recoge al amante de su mujer. @@ -3451,10 +3451,10 @@ Ya es muy tarde, Marty. Tuviste tu oportunidad, pero ahora yo me ocuparé de tu ~r~¡Has abandonado a Carlos, el usurero! [LOOK_A] -Pulsa y mantén pulsado el ~h~botón ~k~~VEHICLE_LOOKLEFT~~w~ o el ~h~botón ~k~~VEHICLE_LOOKRIGHT~~w~ para mirar~h~ a la izquierda~w~ o ~h~a la derecha ~w~mientras te encuentres en un vehículo. Pulsa ambos para mirar~h~ atrás~w~. +Mantén pulsado ~h~~k~~VEHICLE_LOOKLEFT~~w~ o ~h~~k~~VEHICLE_LOOKRIGHT~~w~ para mirar~h~ a la izquierda~w~ o ~h~a la derecha ~w~estando dentro de un vehículo. Pulsa ambos para mirar~h~ atrás~w~. [LOVE6_1] -~g~¡Ahora llévate a los policías lejos del almacén! +~g~¡Ahora aleja a los policías del almacén! [LOVE6_2] ~r~¡No has distraído a la policía! @@ -3463,19 +3463,19 @@ Pulsa y mantén pulsado el ~h~botón ~k~~VEHICLE_LOOKLEFT~~w~ o el ~h~botón ~k~ ~r~¡El socio de Ray ha escapado! [RM6_C] -La CIA parece estar interesada en el SPANK +La CIA parece tener intereses con el SPANK [RM6_C1] -y no les gusta que nos metamos con el cártel. +y no les gusta que incordiemos al cártel. [C_PASS] ¡AMENAZA ELIMINADA! [CTUTOR] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero. [CTUTOR2] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero. [COPCART] ~g~Tienes ~1~ segundos para volver a un vehículo de la policía antes de que termine la misión. @@ -3502,7 +3502,7 @@ Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misi ~r~¡El paciente está muerto! [A_PASS] -¡Rescatado! +¡Paciente a salvo! [F_FAIL2] ~r~¡Llegas demasiado tarde! @@ -3565,7 +3565,7 @@ Vuelve cuando no estés tan ocupado... Puedes alojar un vehículo en el garaje de al lado al guardar tu partida. [STOCK] -mercancía agotada +Mercancía agotada [FM1_O] Creo que está en la estación de ferrocarril del muelle de Chinatown. @@ -3574,22 +3574,22 @@ Creo que está en la estación de ferrocarril del muelle de Chinatown. Es aquí, ¡entremos y cambiémonos de ropa! [EBAL_G] -Este es el club de Luigi. Vamos a la parte de atrás, a la puerta de servicio. +Éste es el club de Luigi. Vamos a la parte de atrás, a la puerta de servicio. [AM4_3] -¡Tú debes de ser el nuevo chico de los recados de Asuka! +¡Tú debes de ser el nuevo recadero de Asuka! [AM4_4] ¿Tienes el dinero? ¿Está todo? [AM4_5] -Ya sé lo que estás pensando, otro policía corrupto. +Sé lo que estás pensando: ''otro poli corrupto''. [AM4_6] -Bueno, éste es un mundo corrupto. +Pues éste es un mundo corrupto. [AM4_7] -Pierdo a un par de socios y esos idiotas de asuntos internos empiezan a meter las narices. +He perdido a un par de socios y esos papanatas de Asuntos Internos ya se han puesto a husmear. [AM4_8] ¡Y seguro que les llega mi olor! @@ -3604,10 +3604,10 @@ Pero voy a necesitar un ayudita ajena al cuerpo. Si estás interesado, ya sabes dónde encontrarme. [CAM_A] -Pulsa el ~h~botón ~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para cambiar la ~h~cámara ~w~cuando vayas a pie o estés en un vehículo. +Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para cambiar la ~h~cámara ~w~cuando vayas a pie o estés en un vehículo. [CAM_B] -Pulsa el ~h~botón de dirección hacia arriba ~w~y ~h~abajo ~w~para cambiar los modos de ~h~cámara ~w~cuando vayas a pie o estés en un vehículo. +Pulsa el ~h~botón de dirección hacia arriba ~w~y ~h~abajo~w~ para cambiar la ~h~cámara ~w~cuando vayas a pie o estés en un vehículo. [KM2_1] ~g~Repara el coche, tiene que estar en perfecto estado. @@ -3628,16 +3628,16 @@ que tendré trabajo para ti. ~r~Se ha escapado. [AWAY] -~r~¡Se ha pirado de aquí! +~r~¡Se ha pirado! [JM6_1] Llévanos al banco de la avenida principal. [GA_6B] -¡Apárcalo, activa el detonador pulsando el ~h~botón ~k~~PED_FIREWEAPON~~w~ y SAL DE AHÍ! +¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO! [GA_7B] -Activa la bomba con el ~h~botón ~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor. +Activa la bomba pulsando ~h~~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor. [BAT1] ~g~¡Coge el bate! @@ -3646,10 +3646,10 @@ Activa la bomba con el ~h~botón ~k~~PED_FIREWEAPON~~w~. Estallará cuando se ar Si no la cagas, puede que haya más trabajo para ti. ¡Ahora largo! [HELP9_B] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador. [HELP9_C] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador. [JM6_8] ~r~¡Has perdido a todos los ladrones! @@ -3664,7 +3664,7 @@ Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de franco ~r~¡Tu cliente ha salido por patas! [TAXI7] -~r~Tu coche está destrozado, haz que lo reparen. +~r~Tu coche está destrozado, repáralo. [TAXI4] ¡Carrera terminada! @@ -3673,19 +3673,19 @@ Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de franco ¡VIAJE RÁPIDO! [TAXI6] -Misión de taxi terminada +Misión de taxista cancelada [FRANGO] ~g~¡Salvatore quiere que ayudes primero a Toni a ocuparse de las Tríadas! [PAGEB12] -Soborno policial ya disponible en tu guarida. +Soborno policial entregado en tu guarida. [PAGEB13] -Salud ya disponible en tu guarida. +Salud entregada en tu guarida. [PAGEB14] -Adrenalina ya disponible en tu guarida. +Adrenalina entregada en tu guarida. [KM1_4] ~g~¡Necesitas un coche de policía para hacer el trabajo! @@ -3748,7 +3748,7 @@ Perderás todo el progreso en tu partida actual. ¿Quieres continuar con la carg Puerto 1. Archivo protegido. [T4X4_1] -'PATIO DE RECREO' +'PATIO DE RECREO DEL PATRIOT' [T4X4_2] 'UN PASEO POR EL PARQUE' @@ -3760,28 +3760,28 @@ Puerto 1. Archivo protegido. 'CAOS EN EL APARCAMIENTO' [T4X4_1A] -~g~Tienes ~y~5 minutos~g~ para pasar por ~y~15~g~ puntos de control. ~g~Puedes tocarlos en ~y~CUALQUIER ORDEN. +~g~Tienes ~y~5 minutos~g~ para pasar por ~y~15~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN. [T4X4_1B] ¡~1~ de 15! [T4X4_1C] -~y~PASA A TRAVÉS~g~ del primer punto de control para que comience el cronómetro. ~g~Cada punto de control te brindará ~y~20 SEGUNDOS~g~ adicionales. +~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~20 SEGUNDOS~g~ adicionales. [T4X4_2A] -~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~12~g~ puntos de control! ~g~Puedes tocarlos en ~y~CUALQUIER ORDEN. +~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~12~g~ puntos de control! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN. [T4X4_2B] ¡~1~ de 12! [T4X4_2C] -~y~PASA A TRAVÉS~g~ del primer punto de control para que comience el cronómetro. ~g~Cada punto de control te brindará ~y~10 SEGUNDOS~g~ adicionales. +~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~10 SEGUNDOS~g~ adicionales. [T4X4_3A] -~g~Tienes ~y~5 minutos~g~ para pasar por ~y~20~g~ puntos de control. ~g~Puedes tocarlos en ~y~CUALQUIER ORDEN. +~g~Tienes ~y~5 minutos~g~ para pasar por ~y~20~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN. [T4X4_3B] -~Y~PASA A TRAVÉS~g~ del primer punto de control para que comience el cronómetro. ~g~Cada punto de control te brindará ~y~15 SEGUNDOS~g~ adicionales. +~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~15 SEGUNDOS~g~ adicionales. [T4X4_3C] ¡~1~ de 20! @@ -3790,7 +3790,7 @@ Puerto 1. Archivo protegido. ~r~¡Te has escapado! ¿Demasiado difícil para ti? [MM_1_A] -~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~20 puntos de control~g~ en el aparcamiento! ~g~Puedes tocarlos en ~y~CUALQUIER ORDEN. +~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~20 puntos de control~g~ en el aparcamiento! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN. [MM_1_B] ¡~1~ de 20! @@ -3997,7 +3997,7 @@ Distancia recorrida a pie (metros) Distancia recorrida en coche (metros) [FEST_R1] -''Patio de recreo'' en segundos +''Patio de recreo del Patriot'' en segundos [FEST_R2] ''Un paseo por el parque'' en segundos @@ -4030,7 +4030,7 @@ Masacres superadas Misiones superadas [FEST_BB] -Carrera forrada: +''Corre a por la pasta'': [FEST_H0] Máximo de puntos de control @@ -4054,16 +4054,16 @@ Exterminio de Rumpos ¡PREMIO POR ACROBACIA ÚNICA! [SPRAY] -Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 dólares +Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 $~w~. [HM1_1] ~g~Cepíllate a 20 Purple Nines en 2 minutos y 30 segundos. [KM1_8A] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~; acuérdate de alejarte de ella. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella. [KM1_8D] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~; acuérdate de alejarte de ella. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella. [KM1_12] ~g~¡Llévalo al dojo, pero deshazte primero de la policía! @@ -4138,7 +4138,7 @@ Las lavanderas no están pagando por su protección. Y ojo con el coche, Joey acaba de arreglar esta chatarra. [JM4_13] -Así que con cuidado, ¿vale? +Así que ve con cuidado, ¿vale? [KM4_11] ~g~¡Lleva el dinero de vuelta al casino! @@ -4171,7 +4171,7 @@ Terminal Shoreside ~r~¡Marty Chonks ha muerto! [SPRAY1] -Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 dólares~w~. Esta vez es gratis. +Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 $~w~. Esta vez es gratis. [JM4_A] Sí, Toni, ya está a punto. Ahora es una delicia, ¿sabes? @@ -4183,7 +4183,7 @@ Pasa más tarde y les daremos algo que lavar... ¡Su propia ropa manchada de san Luigi dijo que necesitabas una pipa... [AMMU_B] -Joey me pidió que te armáramos... +Joey me pidió que te armara... [AMMU_C] Ve a la parte de atrás. Te dejé un nueve en el patio. @@ -4201,10 +4201,10 @@ No necesito tu documentación, pareces de fiar. DETONACIÓN: [DRIVE_A] -Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar. +Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar. [DRIVE_B] -Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar. +Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar. [RECORD] ~g~¡NUEVO RÉCORD! @@ -4213,10 +4213,10 @@ Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierd ~r~¡NO HAY UN NUEVO RÉCORD! [RCHELP] -Pulsa el botón ~k~~PED_FIREWEAPON~ o conduce el coche teledirigido hasta las ruedas de otro coche para detonarlo. +Pulsa ~k~~PED_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo. [RCHELPA] -Pulsa el botón ~k~~PED_FIREWEAPON~ o conduce el coche teledirigido hasta las ruedas de otro coche para detonarlo. +Pulsa ~k~~PED_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo. [RC_1] ¡Tienes 2 minutos para destruir todos los coches de los Diablos que puedas! @@ -4249,7 +4249,7 @@ MASACRE FALLIDA . [PAGE_01] -¡Mata a ~1~ Diablos en 120 segundos! +¡Liquida a ~1~ Diablos en 120 segundos! [PAGE_02] ¡Destruye ~1~ vehículos en 120 segundos! @@ -4321,10 +4321,10 @@ Tengo un trabajito para ti, colega. Los hermanos Forelli me deben dinero desde hace mucho tiempo [JM1_E] -y hay que enseñarles respeto. +y hay que enseñarles modales. [JM1_F] -Labios Forelli está atiborrándose en el restaurante de Saint Mark's, +''Labios'' Forelli está atiborrándose en el restaurante de Saint Mark's, [JM1_G] así que róbale el coche y llévalo al taller de bombas de 8-Ball en Harwood. @@ -4333,7 +4333,7 @@ así que róbale el coche y llévalo al taller de bombas de 8-Ball en Harwood. Conoces a 8-Ball, ¿verdad? [JM1_I] -En cuanto esté cargado con una bomba, aparca el coche donde lo encontraste. +En cuanto le ponga una bomba, aparca el coche donde lo encontraste. [JM1_J] Luego salte y disfruta del espectáculo. @@ -4378,7 +4378,7 @@ Hola, Ice dijo que vendrías. Las reglas son sólo bates. Cero armas, cero coche Es una batalla por respeto, ¿vale? [HELP14] -Para conseguir un arma, pasa sobre ella. No puedes recogerlas estando dentro de un vehículo. +Para conseguir un arma, pasa sobre ella. No podrás recogerlas estando dentro de un vehículo. [CRUSH] Aparca en la zona señalada y sal de tu vehículo para que sea triturado. @@ -4417,7 +4417,7 @@ En el baúl había algunas de mis más preciadas posesiones sobre burros... Objetos de coleccionista irremplazables, amigo. [DIAB3_E] -Escondí un arma en el borde de Chinatown. +Escondí un arma caliente en el borde de Chinatown. [DIAB3_F] Tómala y enseña a esos vándalos de las Tríadas a tenerle miedo a la ira pijuda de El Burro. @@ -4438,7 +4438,7 @@ Pero ese idiota drogado de SPANK dejó las puertas de atrás abiertas, tan bellamente producida, tan gustosamente fotografiada, está siendo esparcida por toda Liberty! [DIAB4_E] -Toma la camioneta y sigue el rastro de los volúmenes 1, 2 y 3 de Donkey Does Dallas, +Monta en la camioneta y sigue el rastro de los volúmenes 1, 2 y 3 de Donkey Does Dallas, [DIAB4_F] tomándolos por el camino. @@ -4462,7 +4462,7 @@ Quiero que esos mierdecillas sepan lo que es un verdadero tiroteo desde un vehí Los Nines me están presionando. [HM2_B] -Tienen coches blindados y ahora están traficando SPANK +Tienen coches blindados y ahora están pasando SPANK [HM2_C] a los hermanos sin ningún pudor. @@ -4471,7 +4471,7 @@ a los hermanos sin ningún pudor. Hay un coche aparcado en la calle. [HM2_E] -Dentro verás algo que te servirá para poner a esos gallinas en su sitio +Dentro lleva algo que te servirá para poner a esos gallinas en su sitio [HM3_A] Algún cazurro me ha puesto una bomba en el coche. @@ -4486,7 +4486,7 @@ Coge mi coche y llévalo al taller de Saint Mark's, ¿valiendo? Que se encarguen ellos de desarmar la bomba. [HM3_E] -El tiempo avanza y ese trasto es un peligro. +El tiempo corre y ese trasto es un peligro. [HM3_F] Un golpe más de la cuenta y podría saltar por los aires. @@ -4513,7 +4513,7 @@ El platino pesa un huevo y hará que tu buga vaya a paso de tortuga, así que ve dejándolo de vez en cuando en el garaje. [HM5_A] -Ya solo quedan unos pocos Nines, +Ya sólo quedan unos pocos Nines, [HM5_B] pero todavía quieren guerra. @@ -4558,7 +4558,7 @@ He quedado con el director de mi banco. Es un chorizo que no para de inflar los intereses del préstamo para sacarme una buena tajada. [MEA1_G] -Coge mi coche, búscale y tráelo de vuelta. +Coge mi coche, búscale y tráelo aquí. [MEA1_H] ¡Tengo una sorpresita para ese parásito chupasangre! @@ -4567,7 +4567,7 @@ Coge mi coche, búscale y tráelo de vuelta. Contraté a unos ladrones para que entraran en mi piso [MEA2_C] -Ahora los muy cabritos me amenazan con delatarme +Ahora los muy cabritos me han amenazado con delatarme [MEA2_D] si no les doy una parte. @@ -4621,7 +4621,7 @@ BIENVENIDO A ~g~Hazte con un vehículo y recuerda que sólo cuentan las muertes a tiros desde el coche. [HELP8_B] -Pulsa el ~h~botón ~k~~PED_SNIPER_ZOOM_IN~~w~ para ~h~acercar el zoom ~w~con el fusil y el ~h~botón ~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~alejarlo~w~. +Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~aumentar el zoom ~w~de la mira del fusil y ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~reducirlo~w~. [LRQC_1] Asuka y yo tenemos que hablar... @@ -4648,7 +4648,7 @@ y podremos tener una charla. Si necesitas una pipa, ve a la parte de atrás del Ammu-Nation que está enfrente del metro. [LOVE4_7] -~g~Hay una zona en obras en Staunton Island, puede que hayan llevado el paquete allí. +~g~Hay un edificio en construcción en Staunton Island, puede que hayan llevado el paquete allí. [LOVE4_8] ~g~Necesitarás un coche para abrir el garaje. @@ -4669,7 +4669,7 @@ GANANCIAS: ~1~ $ Soy María. ¡El coche es una trampa! Estoy en el lado sur del puente Callahan. [JM1_7] -~g~¡Cierra la puerta del coche! ¡Se dará cuenta! +~g~¡Cierra la puerta del coche o se dará cuenta! [KM5_1] ~g~¡TRAFICANTE LIQUIDADO! @@ -4717,10 +4717,10 @@ Luigi dijo que eras de fiar, así que vuelve más tarde, ~g~¡Ha salido de la ambulancia! ¡Cárgate su escayola con un vehículo o una explosión! [PBOAT_1] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha. [PBOAT_2] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha. [DIAB1_B] Al habla El Burro, de los Diablos. @@ -4735,10 +4735,10 @@ Hay una carrera que empezará junto a la sala Clásica, cerca del puente Callaha Consíguete un buen carro y el primero que pase por todos los puntos de control se llevará el premio. [HM2_1] -Usa los coches teledirigidos para destruir los furgones blindados. Pulsa el ~h~botón ~k~~PED_FIREWEAPON~ ~w~para detonarlos. +Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para detonarlos. [HM2_1A] -Usa los coches teledirigidos para destruir los furgones blindados. Pulsa el ~h~botón ~k~~PED_FIREWEAPON~ ~w~para detonarlos. +Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para detonarlos. [HM2_2] ~r~¡No has destruido todos los furgones blindados! @@ -4771,10 +4771,10 @@ Unos SWAT han acordonado la zona donde se encuentran mi socio y el paquete. Ve allí, recoge la furgoneta y haz de señuelo. [LOVE6_F] -Mantenles ocupados y él podrá escaparse. +Mantenlos ocupados para que él pueda escapar. [AM3_C] -Ahora mismo estará probablemente en la bahía. ¡Roba una lancha de la policía y hunde su carrera! +Ahora mismo estará en la bahía. ¡Roba una lancha de la policía y hunde su carrera! [FESZ_UC] CANCELAR @@ -4828,7 +4828,7 @@ Pero si pasas por mi oficina... ¿Marty quiere verme? Bueno, pues que sea rápido, porque tengo que ir a la peluquería. [KM3_7] -¡Es una trampa de la yakuza, tío! +¡Es una trampa de la yakuza, man! [FES_LOF] Fallo al cargar. @@ -4870,10 +4870,10 @@ Reiniciando partida. ~r~¡Has abandonado el Securicar señuelo! [HELP1] -Detente en el centro de la señal azul. +Detente en el centro del marcador azul. [HELP12] -Entra en la señal azul para comenzar una misión. +Entra en el marcador azul para comenzar una misión. [HJSTAT] Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_. @@ -4885,7 +4885,7 @@ Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_. ¡Y qué TIEMPO DE CARRERA: [LOVE3_4] -~r~¡Has destruido el avión! +~r~¡Has destruido la avioneta! [F_FAIL1] ¡Misión del camión de bomberos terminada! @@ -4897,31 +4897,31 @@ TIEMPO DE CARRERA: INCENDIOS: [A_COMP1] -¡Misiones de sanitario completadas! +¡Misiones de conductor de ambulancia completadas! [A_CANC] -~r~¡Misión de sanitario cancelada! +~r~¡Misión de conductor de ambulancia cancelada! [A_COMP3] -¡Misiones de sanitario completadas! ¡Ahora no te cansarás al correr! +¡Misiones de conductor de ambulancia completadas! ¡Ahora no te cansarás al esprintar! [ATUTOR] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de sanitario. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia. [ATUTOR3] -Pulsa el ~h~botón ~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de sanitario. +Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia. [ALEVEL] -Nivel de misión de sanitario: ~1~ +Nivel de misión de conductor de ambulancia: ~1~ [A_FAIL1] -Misión de sanitario terminada. +Misión de conductor de ambulancia terminada. [FEST_HA] -Nivel más alto de misión de sanitario +Mayor nivel de misión de cond. de ambulancia [A_SAVES] -GENTE SALVADA: ~1~ +PERSONAS SALVADAS: ~1~ [C_KILLS] CRIMINALES ABATIDOS: ~1~ @@ -4936,7 +4936,7 @@ La muerte de Salvatore es una placentera noticia, eres un asesino eficaz. Eso me gusta en un hombre. [AM2_B] -Este es mi hermano Kenji. +Éste es mi hermano Kenji. [AM2_C] Asuka tiene un trabajito para ti, pero cuando acabes, pásate por mi casino y podremos hablar. @@ -4965,16 +4965,16 @@ No tenemos tiempo para contactar con nadie y evitar que nos incriminen. Liquida a esos polis espías, pero cuidado: tendrán apoyo. [F_START] -~g~Informe de vehículo en llamas en: ~a~. Ve y extingue el fuego. +~g~Se ha avistado un vehículo en llamas en: ~a~. Ve y extingue el fuego. [AM4_1A] -Ve a la cabina al oeste del Parque Belleville. +Ve a la cabina al oeste del parque Belleville. [AM4_1B] -Ve a la cabina del Campus de Liberty. +Ve a la cabina del campus de Liberty. [AM4_1C] -Ve a la cabina al sur del Parque Belleville. +Ve a la cabina al sur del parque Belleville. [AM4_1D] Ven a verme a los baños públicos del parque. @@ -5007,7 +5007,7 @@ Vente, te presentaré al Don. ¡Hola! ¡Luigi! [TM3_K] -Mis chicas te han echado de menos, Salvatore. Hace mucho que no te vemos. +Mis chicas te han echado de menos, Salvatore. Hace bastante que no te vemos. [TM3_L] Diles que en cuanto resolvamos este desafortunado incidente @@ -5019,7 +5019,7 @@ iremos todos al club para celebrarlo, ¿vale? ¡Mi niño! [TM3_N2] -¿Cómo lo llevas, papá? +¿Cómo estás, papá? [TM3_O] ¿Has encontrado ya una buena mujer? @@ -5061,13 +5061,13 @@ se piensa que le darán la pensión completa si se convierte en un testigo de ca Tenemos que cerrarle la boca para siempre. [RM4_E] -¡Quiero que se vaya a dormir con los peces, en vez de comérselos! +¡Quiero que deje de comer peces y se vaya a dormir con ellos! [LOVE3_B] Esta noche, durante su aproximación al aeropuerto, una avioneta sobrevolará la bahía. [LOVE4_D] -Desgraciadamente, las autoridades aduaneras registraron la avioneta y la comenzaron a desmontar +Desgraciadamente, las autoridades aduaneras incautaron la avioneta y la comenzaron a desmontar [LOVE4_H] hasta que yo intervine a través de mi fortuna. @@ -5106,7 +5106,7 @@ No dispares, amigo. No hay problema. Somos amigos. Mira, coge esto. ¡Siempre la hay, imbécil! [GTAB_K] -¡Siento mucho lo de esa perra enloquecida, todas son iguales... ¿Por favor? +¡Siento mucho lo de esa perra enloquecida, todas son iguales...! ¿Por favor? [GTAB_L] Así que la zorra se fue. @@ -5142,16 +5142,16 @@ Tú, ven más tarde, estoy segura de que voy a necesitar tus servicios. Estás demostrando ser una inversión segura, algo muy raro en estos días. [KM3_1] -~g~El cártel espera a una banda jamaicana, ¡así que roba uno de sus coches! Dirígete al norte; encontrarás uno en Newport. +~g~El cártel espera a una banda jamaicana, ¡así que roba uno de sus coches! Dirígete al norte, encontrarás uno en Newport. [LOVE1_1] -~g~Roba un coche de la banda colombiana para que puedas entrar en su escondite. Dirígete hacia el norte; podrás encontrar uno en Fort Staunton. +~g~Roba un coche de la banda colombiana para que puedas entrar en su escondite. Ve al norte, encontrarás uno en Fort Staunton. [FM1_Q1] ¿Quieres un poco de diversión? ¿Un poco de... hmmm, de SPANK? [FM1_R] -Hola, Chico. No, solo lo de siempre. +Hola, Chico. No, sólo lo de siempre. [FM1_T] Gracias, Chico, nos vemos. @@ -5214,10 +5214,10 @@ Mira, la mafia te quiere muerto y yo también tengo que salir de aquí. Es una amiga mía, ¿vale?, una vieja amiga... Es Asuka, es de fiar. [FM4_8] -Vamos, dejémonos de discursos. +Venga, dejémonos de discursos. [FM4_9] -Mejor nos vamos antes de que haya más italianos histéricos con intenciones menos amistosas. +Mejor nos vamos antes de que lleguen más italianos histéricos con intenciones menos amistosas. [CRED001] ROCKSTAR STUDIOS @@ -5286,7 +5286,7 @@ ALEX HORTON LEE MONTGOMERY [CRED023] -AUTO DESIGN +DISEÑO DE VEHÍCULOS [CRED024] PAUL KUROWSKI @@ -5340,13 +5340,13 @@ CRAIG CONNER STUART ROSS [CRED041] -DISEÑO DE SONIDO Y MASTERIZADO +DISEÑO DE SONIDO Y MÁSTER [CRED042] ALLAN WALKER [CRED043] -PROGRAMACIÓN DE AUDIO +PROGRAM. DE AUDIO [CRED044] RAYMOND USHER @@ -5475,7 +5475,7 @@ PAUL YEATES STANTON SARJEANT [CRED085] -VICEPRESIDENTE DE MÁRKETING +V.P. DE MÁRKETING [CRED086] TERRY DONOVAN @@ -5487,7 +5487,7 @@ COORDINADOR TÉCNICO BRANDON ROSE [CRED089] -DIRECTOR DE C.C. +DIRECTOR DE CONTROL DE CALIDAD [CRED090] JEFF ROSA @@ -5556,76 +5556,76 @@ AUDIO PRODUCIDO POR RENAUD SEBBANE REPARTO [CRED112] -FRANK VINCENT COMO SALVATORE LEONE +FRANK VINCENT - SALVATORE LEONE [CRED113] -JOE PANTOLIANO COMO LUIGI GOTERELLI +JOE PANTOLIANO - LUIGI GOTERELLI [CRED114] -MICHAEL MADSEN COMO TONI CIPRIANI +MICHAEL MADSEN - TONI CIPRIANI [CRED115] -MICHAEL RAPAPORT COMO JOEY LEONE +MICHAEL RAPAPORT - JOEY LEONE [CRED116] -DEBBI MAZAR COMO MARÍA +DEBBI MAZAR - MARÍA [CRED117] -KYLE MACLACHAN COMO DONALD LOVE +KYLE MACLACHAN - DONALD LOVE [CRED118] -ROBERT LOGGIA COMO RAY MACHOWSKI +ROBERT LOGGIA - RAY MACHOWSKI [CRED119] -GURU COMO 8-BALL +GURU - 8-BALL [CRED120] -SONDRA JAMES COMO MAMMA +SONDRA JAMES - MAMMA [CRED121] -LIANA PAI COMO ASUKA +LIANA PAI - ASUKA [CRED122] -LES MAU COMO KENJI +LES MAU - KENJI [CRED123] -CYNTHIA FARRELL COMO CATALINA +CYNTHIA FARRELL - CATALINA [CRED124] -AL ESPINOSA COMO MIGUEL +AL ESPINOSA - MIGUEL [CRED125] -CHRIS PHILLIPS COMO EL BURRO +CHRIS PHILLIPS - EL BURRO [CRED126] -HUNTER PLATIN COMO CHICO +HUNTER PLATIN - CHICO [CRED127] -WALTER MUDU COMO D-ICE +WALTER MUDU - D-ICE [CRED128] -CURTIS MCCLARIN COMO CURTLY +CURTIS MCCLARIN - CURTLY [CRED129] -BILL FIORE COMO DARKEL +BILL FIORE - DARKEL [CRED130] -CHRIS PHILLIPS COMO MARTY CHONKS +CHRIS PHILLIPS - MARTY CHONKS [CRED131] -HUNTER PLATIN COMO CURLY BOB +HUNTER PLATIN - CURLY BOB [CRED132] -WALTER MUDU COMO KING COURTNEY +WALTER MUDU - REY COURTNEY [CRED133] -HUNTER PLATIN COMO ONE-ARMED PHIL +HUNTER PLATIN - PHIL EL MANCO [CRED134] -KIM GURNEY COMO MISTY +KIM GURNEY - MISTY [CRED135] -CAPTURA DE MOVIMIENTOS +CAPTURA DE MOVIM. [CRED136] ANIMACIÓN @@ -5943,7 +5943,7 @@ DAN HOUSER LAZLOW [CRED230] -AGRADECIMIENTOS ESPECIALES +AGRADECIMIENTOS [CRED231] ADAM TEDMAN @@ -6078,7 +6078,7 @@ Espera, tío, que voy a hablar con Luigi. Luego coge su coche y repíntalo. [LM2_D] -toma, toma, para ti. +Toma, toma, para ti. [LM1_9] Hola, soy Misty. @@ -6111,7 +6111,7 @@ Regresa cuando tengas el dinero. ~g~Has abandonado a Ray, vuelve a por él. [FM1_10] -~g~Has abandonado a María, vuelve y recógela. +~g~Has abandonado a María, vuelve a por ella. [LOVE4_9] ~r~¡El avión ha sido destruido! @@ -6120,7 +6120,7 @@ Regresa cuando tengas el dinero. ~r~¡La única pista sobre dónde se encuentra el paquete ha sido destruida! [KM2_D] -No hace falta decir que debemos darle los coches como un regalo, para pagar mi deuda con él. +No hace falta decir que debemos darle los coches como un regalo para pagar mi deuda con él. [KM4_B] El negocio es lo bastante afortunado como para permitir que nuestra protección salde sus cuentas hoy mismo. @@ -6144,16 +6144,16 @@ Un activo valioso, un anciano oriental que conozco, está siendo retenido por unos sudamericanos en Aspatria. [MEA4_D] -He aceptado verle, +He quedado con él, [MEA4_B4] -¿Marty te envía? Vale, le voy a enseñar a ese sinvergüenza el significado de la palabra negocio. +¿Te envía Marty? Vale, le voy a enseñar a ese sinvergüenza el significado de la palabra negocio. [MEA4_B5] ¡Carl, hola! Ehhh... Necesito más tiempo para conseguir tu dinero. [MEA1_B4] -Ah, te envió el Sr. Chonks, ¿verdad? Visitemos a nuestro amigo. +Ah, te envió el Sr. Chonks, ¿verdad? Vayamos a visitarlo. [HM5_6] Vamos a partir cabezas... @@ -6183,10 +6183,10 @@ No tenemos otra opción más que sabotear esos puntos de venta. Estoy agotada. [SIREN_3] -Para activar la sirena de este vehículo, pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~. +Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~. [SIREN_4] -Para activar la sirena de este vehículo, pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~. +Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~. [AS3_C] ¡Buaj! ¿Qué es esa cosa amarilla pegajosa? @@ -6204,7 +6204,7 @@ Se las ha arreglado para extraerle esta joyita a nuestro invitado. Hay una avioneta que llegará al Aeropuerto Francis en dos horas. [AS3_G1] -Está lleno del veneno de Catalina. +Está llena del veneno de Catalina. [AS3_H] Podrás evitar la seguridad del aeropuerto si conduces una lancha hasta las boyas luminosas, @@ -6237,7 +6237,7 @@ Maldita sea, ¡están aquí! ¡FUEGO A DISCRECIÓN! Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (~1~:~1~) [LOVE5_C] -Quiero que le sigas, asegúrate que tanto él como mi paquete llegan a Pike Creek sin daño alguno. +Quiero que le sigas y que te asegures de que tanto él como mi paquete llegan a Pike Creek sin daño alguno. [FESZ_SR] ¡Error al guardar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo. @@ -6336,7 +6336,7 @@ Vale, hay un coche cargado con un fiambre en el bar cercano a Callahan Point. Combatimos juntos en Nicaragua, cuando el país sabía lo que hacía. [RM2_C] -En fin, ayer unos cerdos del cártel lo zurraron y le dijeron que volverían hoy para quitarle parte de su stock. +En fin, ayer unos cerdos del cártel lo zurraron y le dijeron que volverían hoy para quitarle parte de su género. [RM2_D1] Iría yo mismo, pero la ciática ya está en sus trece... ¡Cof, cof! Así que... buena suerte. @@ -6345,19 +6345,19 @@ Iría yo mismo, pero la ciática ya está en sus trece... ¡Cof, cof! Así que.. ~g~¡Liquida a Catalina! [CATINF2] -~g~Sigue al helicóptero para encontrar a Catalina. +~g~Sigue al helicóptero para dar con Catalina. [BOATIN1] -Sube a una lancha y pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para entrar. +Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos. [BOATIN2] -Puedes pulsar el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla. +Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla. [BOATIN3] -Sube a una lancha y pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para entrar. +Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos. [BOATIN4] -Puedes pulsar el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla. +Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla. [JM6] 'LA HUIDA' @@ -6411,13 +6411,13 @@ Puedes pulsar el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lan ¡No puedo creer que esos mamones amarillos me hayan vuelto a dejar con el culo al aire! [GREN_1] -Cuanto más tiempo mantengas pulsado el ~h~botón ~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. +Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. [GREN_2] -Cuanto más tiempo mantengas pulsado el ~h~botón ~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. +Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. [GREN_3] -Cuanto más tiempo mantengas pulsado el ~h~botón ~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. +Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada. [LOVE4_G] Mis pertenencias estarán esperándote en el hangar de aduanas, dentro de la avioneta. @@ -6432,7 +6432,7 @@ Mis pertenencias estarán esperándote en el hangar de aduanas, dentro de la avi ¡APLASTADO! [SOAKED] -¡AGUADO! +¡AHOGADO! [HEAD] Head Radio @@ -6462,10 +6462,10 @@ Game Radio FM MSX FM [TUBE1] -Cuando el metro abra, podrás coger un tren hasta Staunton Island. +Cuando abra el metro, podrás usarlo para ir a Staunton Island. [TUBE2] -Cuando Shoreside Vale abra podrás salir por la terminal de Shoreside al Aeropuerto Internacional Francis. +Cuando abra Shoreside Vale, podrás salir por la terminal Shoreside al Aeropuerto Internacional Francis. [TUBE_2] Para subirte a un vagón, pulsa el ~h~botón Entrar al vehículo~w~. @@ -6480,10 +6480,10 @@ He cambiado el motor y la mano de pintura. ¡La poli no te reconocerá! Si quieres ganar un dinerillo extra, siempre puedes ''coger prestado'' un taxi... [TAXIH1] -Para cerca de un peatón señalado para recogerlo y luego condúcelo a su destino antes de que se acabe el tiempo. +Para cerca de un peatón señalado para recogerlo y llevarlo a su destino antes de que se acabe el tiempo. [LM5_7] -~g~¡Si hay menos de cuatro chicas trabajando en el ~p~baile de la policía~g~, Luigi no estará contento! +~g~¡Luigi no estará contento si hay menos de cuatro chicas trabajando en el ~p~baile de la policía~g~! [KM2_3] ~g~Recuerda que los ~r~coches ~g~tienen que estar en perfecto estado para ser aceptados en el ~p~garaje~g~. @@ -6495,16 +6495,16 @@ Para cerca de un peatón señalado para recogerlo y luego condúcelo a su destin Lo siento, cariño. [BETRA_B] -Soy una chica ambiciosa, ¿y tú? +Soy una chica ambiciosa, ¿pero tú? [BETRA_C] -Un Don Nadie. +Eres un pez pequeñito. [JAILB_Q] -¡Vamos! +¡Ándele! [JAILB_R] -¡Señor pendejo! +¡Señor malparido! [JAILB_S] No nos importará matarte. @@ -6516,7 +6516,7 @@ Os vais a arrepentir. Bien, bien, piérdete. [HELP15] -Cuando vayas a pie mantén pulsado el ~h~botón ~k~~PED_LOOKBEHIND~~w~ para~h~ mirar atrás~w~. +Cuando vayas a pie, mantén pulsado ~h~~k~~PED_LOOKBEHIND~~w~ para~h~ mirar atrás~w~. [FEC_LB3] Mirar atrás @@ -6546,10 +6546,10 @@ Esta Memory Card (PS2) ya está formateada. ;=<> - CAMBIAR SELECCIÓN [SPRAY_4] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua. [SPRAY_1] -Pulsa el ~h~botón ~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua. +Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua. [LITTLE] LITTLE T @@ -6567,7 +6567,7 @@ Hoy, Liberty City se ha visto conmocionada. La policía y los servicios de emergencia lidian con las consecuencias [JAILB_B] -de un ataque devastador a un convoy policial ocurrido esta mañana. +de un devastador ataque a un convoy policial ocurrido esta mañana. [JAILB_C] No se ha informado de quiénes eran los prisioneros trasladados en el convoy @@ -6645,7 +6645,7 @@ Paquete oculto ~1~ de ~1~ ~g~La avioneta ha tirado ~1~ de los 6 paquetes. [FARE11] -~g~Ve a la ~w~zona en obras~g~ de Fort Staunton. +~g~Ve al ~w~edificio en construcción ~g~de Fort Staunton. [GA_21] No puedes guardar más coches en este garaje. @@ -6687,16 +6687,16 @@ Botón " - VOLVER ~g~Ve al ~w~taller de importación/exportación~g~ en el distrito de la presa Cochrane. [L_TRN_1] -Puedes coger el tren para recorrer Portland. Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. +Puedes coger el tren para recorrer Portland. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. [L_TRN_2] -Puedes coger el tren para recorrer Portland. Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. +Puedes coger el tren para recorrer Portland. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. [S_TRN_1] -Puedes coger el metro para recorrer Liberty City. Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. +Puedes coger el metro para recorrer Liberty City. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. [S_TRN_2] -Puedes coger el metro para recorrer Liberty City. Pulsa el ~h~botón ~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. +Puedes coger el metro para recorrer Liberty City. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren. [AS1_C] Ella cuenta con tres escuadrones de la muerte que patrullan por Liberty con el único fin de darte caza. @@ -6747,7 +6747,7 @@ Dic COCHES RESTANTES: [BONUS] -~g~~1~$ ADICIONALES +~g~PRIMA DE ~1~ $ [HORN1] Pulsa el ~h~botón L3~w~ para tocar el ~h~claxon. @@ -6759,25 +6759,25 @@ Pulsa el ~h~botón L1~w~ para tocar el ~h~claxon. Pulsa el ~h~botón R1~w~ para tocar el ~h~claxon. [LM3_1A] -Pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon y avisar a Misty. +Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty. [LM3_1B] -Pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon y avisar a Misty. +Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty. [LM3_1C] -Pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon y avisar a Misty. +Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty. [RADIO_A] -Pulsa el ~h~botón ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. +Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. [RADIO_B] -Pulsa el ~h~botón ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. +Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. [RADIO_C] -Pulsa el ~h~botón ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. +Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. [RADIO_D] -Pulsa el ~h~botón ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. +Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio. [FEC_EXV] Entrar/salir de vehículo @@ -6792,37 +6792,37 @@ Entrar/salir de vehículo 'BOMBERO' [AMBUL_M] -'SANITARIO' +'CONDUCTOR DE AMBULANCIA' [HJ_IS] -PREMIO POR ACROBACIA: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL: ~1~ $ [HJ_PIS] -PREMIO POR ACROBACIA PERFECTA: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL PERFECTA: ~1~ $ [HJ_DIS] -PREMIO POR ACROBACIA DOBLE: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL DOBLE: ~1~ $ [HJ_PDIS] -PREMIO POR ACROBACIA DOBLE PERFECTA: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL DOBLE PERFECTA: ~1~ $ [HJ_TIS] -PREMIO POR ACROBACIA TRIPLE: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL TRIPLE: ~1~ $ [HJ_PTIS] -PREMIO POR ACROBACIA TRIPLE PERFECTA: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL TRIPLE PERFECTA: ~1~ $ [HJ_QIS] -PREMIO POR ACROBACIA CUÁDRUPLE: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE: ~1~ $ [HJ_PQIS] -PREMIO POR ACROBACIA CUÁDRUPLE PERFECTA: ~1~$ +PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE PERFECTA: ~1~ $ [AM1_K] Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (0~1~:~1~) [IMPEXPP] -Garaje de Importación/Exportación, puerto de Portland. Requerimos varios vehículos; revisa nuestro tablón de notas para saber más. +Garaje de importación y exportación, puerto de Portland. Requerimos varios vehículos, revisa nuestro tablón de notas para saber más. [VANHSTP] ¿Quieres abrir algún Securicar? Llévalo a nuestro garaje en el puerto de Portland. @@ -6834,25 +6834,25 @@ Se compran vehículos de emergencia nuevos y usados a buen precio. Llévalos a l PUESTOS DESTROZADOS: [STASH] -~g~¡Lleva el SPANK de vuelta a la ~p~zona en obras~g~! +~g~¡Lleva el SPANK de vuelta al ~p~edificio en construcción~g~! [MCSTNS] No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1. ¿Quieres empezar? (SÍ o NO) [LOVE3_5] -~g~La avioneta está ahora a tu alcance. +~g~La avioneta ha llegado a la zona. [LOVE3_6] ~r~¡La bofia ha llegado a los paquetes antes que tú! [SIREN_1] -Para activar la sirena de este vehículo, pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~. +Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~. [SIREN_2] -Para activar la sirena de este vehículo, pulsa el ~h~botón ~k~~VEHICLE_HORN~~w~. +Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~. [FM3_8C] -Necesitaré 100.000 $ para cubrir gastos, +Necesitaré 100.000 dólares para cubrir gastos, [MCLOAD] Cargando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola. @@ -6896,7 +6896,7 @@ Vuelve a conectar un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK TRAICIONADO POR SU AMANTE CATALINA Y DADO POR MUERTO. TRAS SER CONDENADO Y SENTENCIADO, INICIA SU VIAJE A LA PRISIÓN DE LIBERTY CITY. PERO SÓLO TIENE UN PENSAMIENTO... ¡VENGANZA! [END_A] -Los residentes de Cedar Groove todavía están asumiendo +Los residentes de Cedar Grove todavía están asumiendo [END_B] las consecuencias emocionales provocadas @@ -6926,19 +6926,19 @@ Bueno, ¿qué estaba diciendo? Lo he olvidado. Pero me entiendes, ¿verdad? [END_K] -Las explosiones sacudieron las casas más próximas y a sus residentes. +Las explosiones sacudieron las casas más próximas mientra sus residentes buscaban refugio. [END_L] -Varios ciudadanos resultaron heridos a causa del tiroteo +Varios ciudadanos resultaron heridos entre el caos debido al tiroteo [END_M] entre las fuerzas terrestres y un helicóptero que rodeaba a la presa. [END_N] -Sí, en estos jardínes tuvimos una vista excelente. +Sí, en estos jardines tuvimos una vista excelente. [END_O] -Cuando el helicóptero estalló, +El momento en el que derribaron el helicóptero [END_P] fue mejor que los fuegos artificiales del 4 de julio. @@ -7947,7 +7947,7 @@ SUBTÍTULOS Apariencia predeterminada del jugador.bmp [JM3] -'EL ROBO DE LA FURGONETA' +'EL ROBO DEL FURGÓN' [EBAL] 'DAME LIBERTAD' From c058310f765beff7a43c42ac17be74448c4aa06b Mon Sep 17 00:00:00 2001 From: IlDucci Date: Mon, 14 Dec 2020 00:19:12 +0100 Subject: [PATCH 31/52] Never say never. Syncing two strings with VC and a minor style fix. --- gamefiles/TEXT/spanish.gxt | Bin 234848 -> 234866 bytes utils/gxt/spanish.txt | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gamefiles/TEXT/spanish.gxt b/gamefiles/TEXT/spanish.gxt index 3342340641c0077e5f8249498381d25c5c10336c..384c79a0c8a281463e150fe39eb2eb201cb3fad4 100644 GIT binary patch delta 32466 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 z
)vR*@EtoP;kQ(Us+Qj>Hiiuf{1Sw;q(iE_ZV3J-ozPry}8?-?XL_yx31_~p(> z#}yg#h@8hZPe#IMOZ>beHZ$>RKE8g{gJ*@?(NB*mr+YCu;XNSAE7d+3p>jM;BGd6k zJ>}i$f^==b{trHzW%h1&1jy8IMz*2taib_T2fgmvM#{0FjeXM@D8w+nSKutiTWLUk7H3EFg9nZe|RGK0w?HIBh#Cu@+VX}DgXSJHMrU`$;Z z`Q(*p(CdyNAKPto0uv^u^wcnt(-%sk4@7= zL5LqeMIF0OFnW&W60DM+lZl_JFKzlxed$Z@{K)?Y DOj(%x delta 32496 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 diff --git a/utils/gxt/spanish.txt b/utils/gxt/spanish.txt index f9441ed6..425899e4 100644 --- a/utils/gxt/spanish.txt +++ b/utils/gxt/spanish.txt @@ -60,7 +60,7 @@ Mueve el~h~ joystick analógico derecho~w~ hacia arriba para ~h~acelerar~w~. Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido. [HELP5_D] -Mueve el ~h~joystick analógico derecho~w~ para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido. +Mueve el ~h~joystick analógico derecho~w~ hacia atrás para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido. [HELP6_A] Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~. @@ -93,7 +93,7 @@ Cuantas más insignias tengas, mayor será tu nivel de búsqueda. En ocasiones necesitarás ir por caminos que no aparecen en el radar. [TIMER] -Ésta es una misión cronometrada, debes completarla antes de que el temporizador llegue a cero. +Ésta es una misión cronometrada, debes completarla antes de que el cronómetro llegue a cero. [MISTY1] ~r~¡Misty está para el arrastre! @@ -4549,7 +4549,7 @@ Me llamo Chonks, Marty Chonks. Soy el dueño de la fábrica de comestibles Bitch'n' Dog que está a la vuelta de la esquina. [MEA1_D] -Tengo problemas económicos, pero, ¿y quién no? +Tengo problemas económicos, ¿pero y quién no? [MEA1_E] He quedado con el director de mi banco. From 0448ae662fd777f7640a0f4486a731a6269e1997 Mon Sep 17 00:00:00 2001 From: erorcun Date: Mon, 14 Dec 2020 02:46:55 +0300 Subject: [PATCH 32/52] Fix language initialization call order --- src/skel/glfw/glfw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index b7c4810e..93bfde5a 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -1202,15 +1202,15 @@ void InitialiseLanguage() } } - TheText.Unload(); - TheText.Load(); - #ifndef _WIN32 // TODO this is needed for strcasecmp to work correctly across all languages, but can these cause other problems?? setlocale(LC_CTYPE, "C"); setlocale(LC_COLLATE, "C"); setlocale(LC_NUMERIC, "C"); #endif + + TheText.Unload(); + TheText.Load(); } /* From f42a01f653c860b5df3cfdbe34cc37f25dc3c36a Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Mon, 14 Dec 2020 09:47:07 +0200 Subject: [PATCH 33/52] CPed::SetWeaponLockOnTarget --- src/control/RoadBlocks.cpp | 3 +-- src/peds/CopPed.cpp | 7 ++----- src/peds/Ped.h | 7 +++++++ src/peds/PedAI.cpp | 19 ++++--------------- src/peds/PlayerPed.cpp | 16 ++++++---------- 5 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index 1496b307..170c5ff8 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -90,8 +90,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType pCopPed->m_nRoadblockNode = roadBlockNode; pCopPed->bCrouchWhenShooting = roadBlockType != 2; if (pEntityToAttack) { - pCopPed->m_pPointGunAt = pEntityToAttack; - pEntityToAttack->RegisterReference(&pCopPed->m_pPointGunAt); + pCopPed->SetWeaponLockOnTarget(pEntityToAttack); pCopPed->SetAttack(pEntityToAttack); } pCopPed->m_pMyVehicle = pVehicle; diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index d9f55559..de7b8ad2 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -69,7 +69,7 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP) m_bStopAndShootDisabledZone = false; m_bZoneDisabled = false; field_1364 = -1; - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); // VC also initializes in here, but as nil #ifdef FIX_BUGS @@ -472,10 +472,7 @@ CCopPed::CopAI(void) if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt, false, true, false, false, true, false, false) || foundEnt && foundEnt == playerOrHisVeh) { - m_pPointGunAt = playerOrHisVeh; - if (playerOrHisVeh) - playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt); - + SetWeaponLockOnTarget(playerOrHisVeh); SetAttack(playerOrHisVeh); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000)); } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index f8e619d7..0e398b25 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -863,6 +863,13 @@ public: SetMoveState(PEDMOVE_WALK); } + inline void SetWeaponLockOnTarget(CEntity *target) + { + m_pPointGunAt = (CPed *)target; + if(target) + ((CEntity *)target)->RegisterReference(&m_pPointGunAt); + } + // Using this to abstract nodes of skinned and non-skinned meshes CVector GetNodePosition(int32 node) { diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index f1d16119..5eaf8cd8 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -620,9 +620,7 @@ CPed::UpdateFromLeader(void) m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget); TurnBody(); if (m_attackTimer < CTimer::GetTimeInMilliseconds() && !GetWeapon()->IsTypeMelee()) { - m_pPointGunAt = m_threatEntity; - if (m_threatEntity) - m_threatEntity->RegisterReference((CEntity **) &m_pPointGunAt); + SetWeaponLockOnTarget(m_threatEntity); SetAttack(m_threatEntity); } } @@ -1026,10 +1024,7 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == vehOfTarget) { SetAttack(vehOfTarget); - m_pPointGunAt = vehOfTarget; - if (vehOfTarget) - vehOfTarget->RegisterReference((CEntity **) &m_pPointGunAt); - + SetWeaponLockOnTarget(vehOfTarget); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000)); if (distWithTargetSc <= m_distanceToCountSeekDone) { SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 500)); @@ -1162,10 +1157,7 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == m_pedInObjective) { SetAttack(m_pedInObjective); - m_pPointGunAt = m_pedInObjective; - if (m_pedInObjective) - m_pedInObjective->RegisterReference((CEntity **) &m_pPointGunAt); - + SetWeaponLockOnTarget(m_pedInObjective); SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 2000.0f)); int time; @@ -1551,10 +1543,7 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); - m_pPointGunAt = m_carInObjective; - if (m_pPointGunAt) - m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt); - + SetWeaponLockOnTarget(m_carInObjective); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000)); if (distWithTargetSc > 10.0f && !bKindaStayInSamePlace) { SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000)); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index f23aa378..ef9cf201 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -47,8 +47,8 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_nSelectedWepSlot = WEAPONTYPE_UNARMED; m_nSpeedTimer = 0; m_bSpeedTimerFlag = false; - m_pPointGunAt = nil; - m_nPedState = PED_IDLE; + SetWeaponLockOnTarget(nil); + SetPedState(PED_IDLE); #ifndef FIX_BUGS m_fCurrentStamina = m_fMaxStamina = 150.0f; #endif @@ -73,7 +73,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) void CPlayerPed::ClearWeaponTarget() { if (m_nPedType == PEDTYPE_PLAYER1) { - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); TheCamera.ClearPlayerWeaponMode(); CWeaponEffects::ClearCrossHair(); } @@ -875,9 +875,7 @@ CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft) if (!nextTarget) return false; - m_pPointGunAt = nextTarget; - if (nextTarget) - nextTarget->RegisterReference((CEntity**)&m_pPointGunAt); + SetWeaponLockOnTarget(nextTarget); SetPointGunAt(nextTarget); return true; } @@ -891,7 +889,7 @@ CPlayerPed::FindWeaponLockOnTarget(void) if (m_pPointGunAt) { CVector distVec = m_pPointGunAt->GetPosition() - GetPosition(); if (distVec.Magnitude2D() > weaponRange) { - m_pPointGunAt = nil; + SetWeaponLockOnTarget(nil); return false; } else { return true; @@ -922,9 +920,7 @@ CPlayerPed::FindWeaponLockOnTarget(void) if (!nextTarget) return false; - m_pPointGunAt = nextTarget; - if (nextTarget) - nextTarget->RegisterReference((CEntity**)&m_pPointGunAt); + SetWeaponLockOnTarget(nextTarget); SetPointGunAt(nextTarget); return true; } From 0563478de049c5d3c23656b872c14ae6f6d7eeef Mon Sep 17 00:00:00 2001 From: Seemann Date: Mon, 14 Dec 2020 01:52:49 -0500 Subject: [PATCH 34/52] Fix some formatting issues --- src/control/Script.cpp | 12 ++++++------ src/control/Script3.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 1b51e0d6..67d2e618 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -238,12 +238,12 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="), REGISTER_COMMAND(COMMAND_DIV_INT_LVAR_BY_INT_VAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " /="), REGISTER_COMMAND(COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="), - REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), - REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), + REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), REGISTER_COMMAND(COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"), diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp index 38bcb2ec..1f1ed537 100644 --- a/src/control/Script3.cpp +++ b/src/control/Script3.cpp @@ -996,7 +996,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) CollectParameters(&m_nIp, 4); int mi = ScriptParams[0] >= 0 ? ScriptParams[0] : CTheScripts::UsedObjectArray[-ScriptParams[0]].index; CObject* pObj = new CObject(mi, false); -; pObj->ObjectCreatedBy = MISSION_OBJECT; + pObj->ObjectCreatedBy = MISSION_OBJECT; CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); From 3b8ac474a20d7b94049cfb5ae36a9f317176278c Mon Sep 17 00:00:00 2001 From: shfil Date: Mon, 14 Dec 2020 15:33:16 +0100 Subject: [PATCH 35/52] Implement COMMAND_IS_CAR_PASSENGER_SEAT_FREE Fixes 881 --- src/control/Script6.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/control/Script6.cpp b/src/control/Script6.cpp index acd9e424..c2937e1d 100644 --- a/src/control/Script6.cpp +++ b/src/control/Script6.cpp @@ -545,7 +545,14 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CStats::RegisterHighestScore(ScriptParams[0], ScriptParams[1]); return 0; //case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER: - //case COMMAND_IS_CAR_PASSENGER_SEAT_FREE: + case COMMAND_IS_CAR_PASSENGER_SEAT_FREE: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + script_assert(pVehicle); + UpdateCompareFlag(ScriptParams[1] < pVehicle->m_nNumMaxPassengers && pVehicle->pPassengers[ScriptParams[1]] == nil); + return 0; + } case COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT: { CollectParameters(&m_nIp, 2); From 7be7845db00f5ee933479b2716af66066f80d0dc Mon Sep 17 00:00:00 2001 From: withmorten Date: Mon, 14 Dec 2020 23:30:07 +0100 Subject: [PATCH 36/52] add dev build code for generating waterpro.dat --- src/render/WaterLevel.cpp | 373 ++++++++++++++++++++++++++++++++++---- src/render/WaterLevel.h | 11 +- 2 files changed, 343 insertions(+), 41 deletions(-) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index ecfccc90..ef5c4c58 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "main.h" #include "FileMgr.h" +#include "FileLoader.h" #include "TxdStore.h" #include "Timer.h" #include "Weather.h" @@ -30,8 +31,8 @@ float TEXTURE_ADDV; int32 CWaterLevel::ms_nNoOfWaterLevels; float CWaterLevel::ms_aWaterZs[48]; CRect CWaterLevel::ms_aWaterRects[48]; -uint8 CWaterLevel::aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; -uint8 CWaterLevel::aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; +int8 CWaterLevel::aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; +int8 CWaterLevel::aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; bool CWaterLevel::WavesCalculatedThisFrame; RpAtomic *CWaterLevel::ms_pWavyAtomic; RpGeometry *CWaterLevel::apGeomArray[8]; @@ -58,28 +59,158 @@ void CWaterLevel::Initialise(Const char *pWaterDat) { ms_nNoOfWaterLevels = 0; - + +#ifdef MASTER int32 hFile = -1; - - do + + while ((hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb")) < 0); +#else + int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); +#endif + + if (hFile > 0) { - hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); - } - while ( hFile < 0 ); - - if ( hFile > 0 ) - { - if ( hFile >= 0 ) - { - CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); - CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); - CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); - CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); - CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); - } - + CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); + CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); + CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); + CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); + CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); + CFileMgr::CloseFile(hFile); } +#ifndef MASTER + else + { + printf("Init waterlevels\n"); + + CFileMgr::SetDir(""); + hFile = CFileMgr::OpenFile(pWaterDat, "r"); + + char *line; + + while ((line = CFileLoader::LoadLine(hFile))) + { + if (*line && *line != ';') + { + float z, l, b, r, t; + sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t); + AddWaterLevel(l, b, r, t, z); + } + } + + CFileMgr::CloseFile(hFile); + + for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + { + for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + { + aWaterFineBlockList[x][y] = NO_WATER; + } + } + + for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) + { + int32 l = WATER_HUGE_X(ms_aWaterRects[i].left); + int32 r = WATER_HUGE_X(ms_aWaterRects[i].right) + 1.0f; + int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top); + int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f; + + // originally this writes *god* knows where everywhere in game memory ... + // even in debug it manages to reach some textures so librw crashes with a ptr being 0x15151515 .... +#ifdef FIX_BUGS + l = clamp(l, 0, WATER_FINEBLOCK_SIZE - 1); + r = clamp(r, 0, WATER_FINEBLOCK_SIZE - 1); + t = clamp(t, 0, WATER_FINEBLOCK_SIZE - 1); + b = clamp(b, 0, WATER_FINEBLOCK_SIZE - 1); +#endif + + for (int32 x = l; x <= r; x++) + { + for (int32 y = t; y <= b; y++) + { + aWaterFineBlockList[x][y] = i; + } + } + } + + for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + { + int32 worldX = WATER_START_X + x * SMALL_SECTOR_WIDTH; + + for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + { + if (aWaterBlockList[x][y] >= 0) + { + int32 worldY = WATER_START_Y + y * SMALL_SECTOR_WIDTH; + + int32 i; + for (i = 0; i <= 8; i++) + { + for (int32 j = 0; j <= 8; j++) + { + CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_WIDTH / 8), worldY + j * (SMALL_SECTOR_WIDTH / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]); + + if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y)) + { + if (WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) && !TestVisibilityForFineWaterBlocks(worldPos)) + { + i = 1000; + break; + } + } + } + + if (i == 1000) break; + } + + if (i < 1000) aWaterFineBlockList[x][y] = NO_WATER; + } + } + } + + RemoveIsolatedWater(); + + for (int32 x = 0; x < WATER_BLOCK_SIZE; x++) + { + for (int32 y = 0; y < WATER_BLOCK_SIZE; y++) + { + if (aWaterFineBlockList[x * 2][y * 2] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2]; + } + else if (aWaterFineBlockList[x * 2 + 1][y * 2] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2]; + } + else if (aWaterFineBlockList[x * 2][y * 2 + 1] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2 + 1]; + } + else if (aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0) + { + aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2 + 1]; + } + else + { + aWaterBlockList[x][y] = NO_WATER; + } + } + } + + hFile = CFileMgr::OpenFileForWriting("data\\waterpro.dat"); + + if (hFile > 0) + { + CFileMgr::Write(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels)); + CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs)); + CFileMgr::Write(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects)); + CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList)); + CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList)); + + CFileMgr::CloseFile(hFile); + } + } +#endif CTxdStore::PushCurrentTxd(); @@ -222,6 +353,170 @@ CWaterLevel::DestroyWavyAtomic() RwFrameDestroy(frame); } +#ifndef MASTER +void +CWaterLevel::AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel) +{ + ms_aWaterRects[ms_nNoOfWaterLevels] = CRect(fXLeft, fYBottom, fXRight, fYTop); + ms_aWaterZs[ms_nNoOfWaterLevels] = fLevel; + ms_nNoOfWaterLevels++; +} + +bool +CWaterLevel::WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel) +{ + if (ms_nNoOfWaterLevels <= 0) return false; + + for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) + { + if (fX >= ms_aWaterRects[i].left && fX <= ms_aWaterRects[i].right + && fY >= ms_aWaterRects[i].top && fY <= ms_aWaterRects[i].bottom) + { + if (pfOutLevel) *pfOutLevel = ms_aWaterZs[i]; + + return true; + } + } + + return false; +} + +bool +CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos) +{ + static CVector2D tab[] = + { + { 50.0f, 50.0f }, + { -50.0f, 50.0f }, + { -50.0f, -50.0f }, + { 50.0f, -50.0f }, + { 50.0f, 0.0f }, + { -50.0f, 0.0f }, + { 0.0f, -50.0f }, + { 0.0f, 50.0f }, + }; + + CEntity *entity; + CColPoint col; + CVector lineStart, lineEnd; + + lineStart = worldPos; + + if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) + { + lineStart.x += 0.4f; + lineStart.y += 0.4f; + + if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil)) + { + return false; + } + } + + for (int32 i = 0; i < ARRAY_SIZE(tab); i++) + { + lineStart = worldPos; + lineEnd = worldPos; + + lineEnd.x += tab[i].x; + lineEnd.y += tab[i].y; + lineEnd.z += 100.0f; + + if ((lineEnd.x > WORLD_MIN_X && lineEnd.x < WORLD_MAX_X) && (lineEnd.y > WORLD_MIN_Y && lineEnd.y < WORLD_MAX_Y)) + { + if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil)) + { + lineStart.x += 0.4f; + lineStart.y += 0.4f; + lineEnd.x += 0.4f; + lineEnd.y += 0.4f; + + if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil)) + { + return false; + } + } + } + } + + return true; +} + +void +CWaterLevel::RemoveIsolatedWater() +{ + bool (*isConnected)[WATER_FINEBLOCK_SIZE] = new bool[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; + + for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + { + for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + { + isConnected[x][y] = false; + } + } + + isConnected[0][0] = true; + bool keepGoing; + + do + { + keepGoing = false; + + for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + { + for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + { + if (aWaterBlockList[x][y] >= 0 && !isConnected[x][y]) + { + if (x > 0 && isConnected[x - 1][y]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (y > 0 && isConnected[x][y - 1]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (x + 1 < WATER_FINEBLOCK_SIZE && isConnected[x + 1][y]) + { + isConnected[x][y] = true; + keepGoing = true; + } + + if (y + 1 < WATER_FINEBLOCK_SIZE && isConnected[x][y + 1]) + { + isConnected[x][y] = true; + keepGoing = true; + } + } + } + } + } + while (keepGoing); + + int32 numRemoved = 0; + + for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + { + for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + { + if (aWaterBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] != 0.0f) + { + numRemoved++; + aWaterFineBlockList[x][y] = NO_WATER; + } + } + } + + printf("Removed %d isolated patches of water\n", numRemoved); + + delete[] isConnected; +} +#endif + bool CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ) { @@ -231,9 +526,9 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE ); ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE ); - uint8 nBlock = aWaterFineBlockList[x][y]; + int8 nBlock = aWaterFineBlockList[x][y]; - if ( nBlock == 128 ) + if ( nBlock == NO_WATER ) return false; ASSERT( pfOutLevel != NULL ); @@ -270,9 +565,9 @@ CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLeve ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE ); ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE ); - uint8 nBlock = aWaterFineBlockList[x][y]; + int8 nBlock = aWaterFineBlockList[x][y]; - if ( nBlock == 128 ) + if ( nBlock == NO_WATER ) return false; ASSERT( pfOutLevel != NULL ); @@ -418,10 +713,10 @@ CWaterLevel::RenderWater() { for ( int32 y = nStartY; y <= nEndY; y++ ) { - if ( !(aWaterBlockList[2*x+0][2*y+0] & 128) - || !(aWaterBlockList[2*x+1][2*y+0] & 128) - || !(aWaterBlockList[2*x+0][2*y+1] & 128) - || !(aWaterBlockList[2*x+1][2*y+1] & 128) ) + if ( aWaterBlockList[2*x+0][2*y+0] >= 0 + || aWaterBlockList[2*x+1][2*y+0] >= 0 + || aWaterBlockList[2*x+0][2*y+1] >= 0 + || aWaterBlockList[2*x+1][2*y+1] >= 0 ) { float fX = WATER_FROM_HUGE_SECTOR_X(x); float fY = WATER_FROM_HUGE_SECTOR_Y(y); @@ -443,16 +738,16 @@ CWaterLevel::RenderWater() { float fZ; - if ( !(aWaterBlockList[2*x+0][2*y+0] & 128) ) + if ( aWaterBlockList[2*x+0][2*y+0] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ]; - if ( !(aWaterBlockList[2*x+1][2*y+0] & 128) ) + if ( aWaterBlockList[2*x+1][2*y+0] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ]; - if ( !(aWaterBlockList[2*x+0][2*y+1] & 128) ) + if ( aWaterBlockList[2*x+0][2*y+1] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ]; - if ( !(aWaterBlockList[2*x+1][2*y+1] & 128) ) + if ( aWaterBlockList[2*x+1][2*y+1] >= 0 ) fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ]; RenderOneFlatHugeWaterPoly(fX, fY, fZ, color); @@ -463,7 +758,7 @@ CWaterLevel::RenderWater() { for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ ) { - if ( !(aWaterBlockList[x2][y2] & 128) ) + if ( aWaterBlockList[x2][y2] >= 0 ) { float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2); float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2); @@ -498,7 +793,7 @@ CWaterLevel::RenderWater() float fZ; // WS - if ( !(aWaterFineBlockList[2*x2+0][2*y2+0] & 128) ) + if ( aWaterFineBlockList[2*x2+0][2*y2+0] >= 0 ) { float fSmallX = fLargeX; float fSmallY = fLargeY; @@ -519,7 +814,7 @@ CWaterLevel::RenderWater() } // SE - if ( !(aWaterFineBlockList[2*x2+1][2*y2+0] & 128) ) + if ( aWaterFineBlockList[2*x2+1][2*y2+0] >= 0 ) { float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); float fSmallY = fLargeY; @@ -540,7 +835,7 @@ CWaterLevel::RenderWater() } // WN - if ( !(aWaterFineBlockList[2*x2+0][2*y2+1] & 128) ) + if ( aWaterFineBlockList[2*x2+0][2*y2+1] >= 0 ) { float fSmallX = fLargeX; float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); @@ -561,7 +856,7 @@ CWaterLevel::RenderWater() } //NE - if ( !(aWaterFineBlockList[2*x2+1][2*y2+1] & 128) ) + if ( aWaterFineBlockList[2*x2+1][2*y2+1] >= 0 ) { float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2); float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2); @@ -591,7 +886,7 @@ CWaterLevel::RenderWater() } } // if ( TheCamera.IsSphereVisible } // if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr ) - } // if ( !(aWaterBlockList[x2][y2] & 128) ) + } // if ( aWaterBlockList[x2][y2] >= 0 ) } // for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ ) } // for ( int32 x2 = 2*x; x2 <= 2*x+1; x2++ ) // @@ -1116,7 +1411,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY) { for ( int32 y = nStartY; y <= nEndY; y++ ) { - if ( !(aWaterFineBlockList[x][y] & 128) ) + if ( aWaterFineBlockList[x][y] >= 0 ) { float fSectorX = WATER_FROM_SMALL_SECTOR_X(x); float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y); diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h index 269d6091..cff1a995 100644 --- a/src/render/WaterLevel.h +++ b/src/render/WaterLevel.h @@ -4,6 +4,8 @@ #define WATER_FINEBLOCK_SIZE HUGE_SECTOR_SIZE #define WATER_Z_OFFSET (1.5f) +#define NO_WATER -128 + #define MAX_SMALL_SECTORS 128 #define MAX_LARGE_SECTORS 64 #define MAX_HUGE_SECTORS 32 @@ -23,6 +25,7 @@ #define WATER_WIDTH ((WATER_END_X - WATER_START_X)) #define WATER_HEIGHT ((WATER_END_Y - WATER_START_Y)) +#define SMALL_SECTOR_WIDTH (WATER_WIDTH/MAX_SMALL_SECTORS) #define WATER_UNSIGN_X(x) ( (x) + (WATER_WIDTH /2) ) #define WATER_UNSIGN_Y(y) ( (y) + (WATER_HEIGHT/2) ) @@ -72,8 +75,8 @@ class CWaterLevel static int32 ms_nNoOfWaterLevels; static float ms_aWaterZs[48]; static CRect ms_aWaterRects[48]; - static uint8 aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; - static uint8 aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; + static int8 aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; + static int8 aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; static bool WavesCalculatedThisFrame; static RpAtomic *ms_pWavyAtomic; static RpGeometry *apGeomArray[MAX_BOAT_WAKES]; @@ -84,6 +87,10 @@ public: static void Shutdown(); static void CreateWavyAtomic(); static void DestroyWavyAtomic(); + static void AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel); + static bool WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel = nil); + static bool TestVisibilityForFineWaterBlocks(const CVector &worldPos); + static void RemoveIsolatedWater(); static bool GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ); static bool GetWaterLevel(CVector coors, float *pfOutLevel, bool bDontCheckZ) { return GetWaterLevel(coors.x, coors.y, coors.z, pfOutLevel, bDontCheckZ); } static bool GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel); From f76dfaee82c0573518d247f7d5666151ccfed765 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Tue, 15 Dec 2020 05:11:02 +0200 Subject: [PATCH 37/52] Use SetPedState --- src/control/Phones.cpp | 6 +-- src/control/Script5.cpp | 2 +- src/core/Fire.cpp | 4 +- src/core/PlayerInfo.cpp | 2 +- src/peds/CivilianPed.cpp | 8 ++-- src/peds/CopPed.cpp | 6 +-- src/peds/EmergencyPed.cpp | 14 +++--- src/peds/Ped.cpp | 99 ++++++++++++++------------------------- src/peds/PedAI.cpp | 34 +++++++------- src/peds/PedFight.cpp | 14 +++--- src/peds/PlayerPed.cpp | 41 ++-------------- src/peds/Population.cpp | 6 +-- 12 files changed, 87 insertions(+), 149 deletions(-) diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index c951e868..4769559c 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -67,7 +67,7 @@ CPhoneInfo::Update(void) } else { CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PHONE); if (player->m_nPedState == PED_MAKE_CALL) - player->m_nPedState = PED_IDLE; + player->SetPedState(PED_IDLE); } } bool notInCar; @@ -114,7 +114,7 @@ CPhoneInfo::Update(void) player->m_fRotationCur = angleToFace; player->m_fRotationDest = angleToFace; player->SetHeading(angleToFace); - player->m_nPedState = PED_MAKE_CALL; + player->SetPedState(PED_MAKE_CALL); CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PHONE); TheCamera.SetWideScreenOn(); playerInfo->MakePlayerSafe(true); @@ -412,7 +412,7 @@ PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) ped->bUpdateAnimHeading = true; if (ped->m_nPedState == PED_MAKE_CALL) - ped->m_nPedState = PED_IDLE; + ped->SetPedState(PED_IDLE); } void diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index 164ca036..4826192e 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -1921,7 +1921,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) if (pPed->IsPedInControl()) pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7); if (flees) { - pPed->m_nPedState = state; + pPed->SetPedState(state); pPed->SetMoveState(ms); } --CPopulation::ms_nTotalMissionPeds; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index e1be4194..2c57c066 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -228,7 +228,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength ped->bDrawLast = false; ped->SetMoveState(PEDMOVE_SPRINT); ped->SetMoveAnim(); - ped->m_nPedState = PED_ON_FIRE; + ped->SetPedState(PED_ON_FIRE); } if (fleeFrom) { if (ped->m_nPedType == PEDTYPE_COP) { @@ -401,7 +401,7 @@ CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strengt CVector2D pos = target->GetPosition(); ped->SetFlee(pos, 10000); ped->SetMoveAnim(); - ped->m_nPedState = PED_ON_FIRE; + ped->SetPedState(PED_ON_FIRE); } } else if (target->IsVehicle()) { veh->m_pCarFire = fire; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 09b3a499..5866485d 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -419,7 +419,7 @@ CPlayerInfo::Process(void) if (found) sth.z = 1.0f + groundZ; - m_pPed->m_nPedState = PED_IDLE; + m_pPed->SetPedState(PED_IDLE); m_pPed->SetMoveState(PEDMOVE_STILL); CPed::PedSetOutCarCB(0, m_pPed); CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f); diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index 401d2e67..a2f44357 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -274,7 +274,7 @@ CCivilianPed::ProcessControl(void) } else { crimeReporters[m_phoneId] = this; m_facePhoneStart = true; - m_nPedState = PED_FACE_PHONE; + SetPedState(PED_FACE_PHONE); } #else } else if (bRunningToPhone) { @@ -283,7 +283,7 @@ CCivilianPed::ProcessControl(void) m_phoneId = -1; } else { gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME; - m_nPedState = PED_FACE_PHONE; + SetPedState(PED_FACE_PHONE); } #endif } else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) { @@ -305,7 +305,7 @@ CCivilianPed::ProcessControl(void) break; case PED_FACE_PHONE: if (FacePhone()) - m_nPedState = PED_MAKE_CALL; + SetPedState(PED_MAKE_CALL); break; case PED_MAKE_CALL: if (MakePhonecall()) @@ -331,7 +331,7 @@ CCivilianPed::ProcessControl(void) for (int j = 0; j < m_numNearPeds; ++j) { CPed *nearPed = m_nearPeds[j]; if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_WANDER_PATH) { - nearPed->m_nPedState = PED_UNKNOWN; + nearPed->SetPedState(PED_UNKNOWN); } } } diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index de7b8ad2..b2888082 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -114,14 +114,14 @@ CCopPed::SetArrestPlayer(CPed *player) } else if (player->m_nPedState != PED_DIE && player->m_nPedState != PED_DEAD && player->m_nPedState != PED_ARRESTED) { player->m_nLastPedState = player->m_nPedState; - player->m_nPedState = PED_ARRESTED; + player->SetPedState(PED_ARRESTED); FindPlayerPed()->m_bCanBeDamaged = false; ((CPlayerPed*)player)->m_pArrestingCop = this; this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop); } - m_nPedState = PED_ARREST_PLAYER; + SetPedState(PED_ARREST_PLAYER); SetObjective(OBJECTIVE_NONE); m_prevObjective = OBJECTIVE_NONE; bIsPointingGunAt = false; @@ -229,7 +229,7 @@ CCopPed::ArrestPlayer(void) CPed *suspect = (CPed*)m_pSeekTarget; if (suspect) { if (suspect->CanSetPedState()) - suspect->m_nPedState = PED_ARRESTED; + suspect->SetPedState(PED_ARRESTED); if (suspect->bInVehicle && m_pMyVehicle && suspect->m_pMyVehicle == m_pMyVehicle) { diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 8d6999c3..65aa97ef 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -100,7 +100,7 @@ CEmergencyPed::FiremanAI(void) case EMERGENCY_PED_READY: nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist); if (nearestFire) { - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetSeek(nearestFire->m_vecPos, 1.0f); SetMoveState(PEDMOVE_RUN); m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; @@ -114,7 +114,7 @@ CEmergencyPed::FiremanAI(void) case EMERGENCY_PED_DETERMINE_NEXT_STATE: nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist); if (nearestFire && nearestFire != m_pAttendedFire) { - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetSeek(nearestFire->m_vecPos, 1.0f); SetMoveState(PEDMOVE_RUN); #ifdef FIX_BUGS @@ -160,7 +160,7 @@ CEmergencyPed::FiremanAI(void) #endif --m_pAttendedFire->m_nFiremenPuttingOut; - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetWanderPath(CGeneral::GetRandomNumber() & 7); m_pAttendedFire = nil; m_nEmergencyPedState = EMERGENCY_PED_READY; @@ -307,7 +307,7 @@ CEmergencyPed::MedicAI(void) } else { m_pRevivedPed->m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds(); SetMoveState(PEDMOVE_STILL); - m_nPedState = PED_CPR; + SetPedState(PED_CPR); m_nLastPedState = PED_CPR; SetLookFlag(m_pRevivedPed, 0); SetLookTimer(500); @@ -366,12 +366,12 @@ CEmergencyPed::MedicAI(void) break; } m_nEmergencyPedState = EMERGENCY_PED_STOP_CPR; - m_nPedState = PED_NONE; + SetPedState(PED_NONE); SetMoveState(PEDMOVE_WALK); m_pVehicleAnim = nil; if (!m_pRevivedPed->bBodyPartJustCameOff) { m_pRevivedPed->m_fHealth = 100.0f; - m_pRevivedPed->m_nPedState = PED_NONE; + m_pRevivedPed->SetPedState(PED_NONE); m_pRevivedPed->m_nLastPedState = PED_WANDER_PATH; m_pRevivedPed->SetGetUp(); m_pRevivedPed->bUsesCollision = true; @@ -400,7 +400,7 @@ CEmergencyPed::MedicAI(void) break; case EMERGENCY_PED_STOP: m_bStartedToCPR = false; - m_nPedState = PED_NONE; + SetPedState(PED_NONE); if (m_pAttendedAccident) { m_pAttendedAccident->m_pVictim = nil; --m_pAttendedAccident->m_nMedicsAttending; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index c41c1f0c..5e1911ec 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -641,7 +641,7 @@ CPed::RestorePreviousState(void) return; if (InVehicle()) { - m_nPedState = PED_DRIVING; + SetPedState(PED_DRIVING); m_nLastPedState = PED_NONE; } else { if (m_nLastPedState == PED_NONE) { @@ -658,7 +658,7 @@ CPed::RestorePreviousState(void) SetIdle(); break; case PED_WANDER_PATH: - m_nPedState = PED_WANDER_PATH; + SetPedState(PED_WANDER_PATH); bIsRunning = false; if (bFindNewNodeAfterStateRestore) { if (m_pNextPathNode) { @@ -672,7 +672,7 @@ CPed::RestorePreviousState(void) SetWanderPath(CGeneral::GetRandomNumber() & 7); break; default: - m_nPedState = m_nLastPedState; + SetPedState(m_nLastPedState); SetMoveState((eMoveState) m_nPrevMoveState); break; } @@ -1511,8 +1511,8 @@ CPed::ClearAll(void) if (!IsPedInControl() && m_nPedState != PED_DEAD) return; - m_nPedState = PED_NONE; - m_nMoveState = PEDMOVE_NONE; + SetPedState(PED_NONE); + SetMoveState(PEDMOVE_NONE); m_pSeekTarget = nil; m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f); m_fleeFromPosX = 0.0f; @@ -1585,7 +1585,7 @@ CPed::ProcessBuoyancy(void) CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true); #endif m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); return; } } @@ -2692,36 +2692,6 @@ CPed::ProcessControl(void) case PED_WANDER_PATH: WanderPath(); break; - case PED_SEEK_POS: - case PED_SEEK_ENTITY: - case PED_PURSUE: - case PED_SNIPER_MODE: - case PED_ROCKET_MODE: - case PED_DUMMY: - case PED_FACE_PHONE: - case PED_MAKE_CALL: - case PED_MUG: - case PED_AI_CONTROL: - case PED_FOLLOW_ROUTE: - case PED_CPR: - case PED_SOLICIT: - case PED_BUY_ICECREAM: - case PED_STEP_AWAY: - case PED_UNKNOWN: - case PED_STATES_NO_AI: - case PED_JUMP: - case PED_STAGGER: - case PED_DIVE_AWAY: - case PED_STATES_NO_ST: - case PED_ARREST_PLAYER: - case PED_PASSENGER: - case PED_TAXI_PASSENGER: - case PED_OPEN_DOOR: - case PED_DEAD: - case PED_DRAG_FROM_CAR: - case PED_EXIT_CAR: - case PED_STEAL_CAR: - break; case PED_ENTER_CAR: case PED_CARJACK: { @@ -4467,7 +4437,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) if (!veh->bEngineOn) veh->bEngineOn = true; - ped->m_nPedState = PED_DRIVING; + ped->SetPedState(PED_DRIVING); ped->StopNonPartialAnims(); return; } @@ -4512,7 +4482,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) { if (ped->m_nPedState == PED_CARJACK) { veh->AddPassenger(ped, 0); - ped->m_nPedState = PED_DRIVING; + ped->SetPedState(PED_DRIVING); ped->RestorePreviousObjective(); ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh); } else if (veh->pDriver && ped->CharCreatedBy == RANDOM_CHAR) { @@ -4552,7 +4522,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) veh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; veh->AutoPilot.m_nCruiseSpeed = 25; } - ped->m_nPedState = PED_DRIVING; + ped->SetPedState(PED_DRIVING); if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) { if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT) @@ -4580,7 +4550,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) break; } } - ped->m_nPedState = PED_DRIVING; + ped->SetPedState(PED_DRIVING); if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT) ped->m_prevObjective = OBJECTIVE_NONE; @@ -4967,7 +4937,7 @@ CPed::SetIdle(void) m_nLastPedState = PED_NONE; #endif - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); SetMoveState(PEDMOVE_STILL); } if (m_nWaitState == WAITSTATE_FALSE) { @@ -5055,7 +5025,7 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl) ClearLookFlag(); ClearAimFlag(); SetStoredState(); - m_nPedState = PED_FALL; + SetPedState(PED_FALL); CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), animId); if (fallAssoc) { @@ -5220,7 +5190,7 @@ CPed::SetGetUp(void) } if (m_nPedState != PED_GETUP) { SetStoredState(); - m_nPedState = PED_GETUP; + SetPedState(PED_GETUP); } CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity; @@ -5375,7 +5345,7 @@ CPed::SetSeek(CVector pos, float distanceToCountDone) if (m_nPedState != PED_SEEK_POS) SetStoredState(); - m_nPedState = PED_SEEK_POS; + SetPedState(PED_SEEK_POS); m_distanceToCountSeekDone = distanceToCountDone; m_vecSeekPos = pos; } @@ -5395,7 +5365,7 @@ CPed::SetSeek(CEntity *seeking, float distanceToCountDone) if (m_nPedState != PED_SEEK_ENTITY) SetStoredState(); - m_nPedState = PED_SEEK_ENTITY; + SetPedState(PED_SEEK_ENTITY); m_distanceToCountSeekDone = distanceToCountDone; m_pSeekTarget = seeking; m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); @@ -5572,7 +5542,7 @@ CPed::SetFlee(CVector2D const &from, int time) if (m_nPedState != PED_FLEE_ENTITY) { SetStoredState(); - m_nPedState = PED_FLEE_POS; + SetPedState(PED_FLEE_POS); SetMoveState(PEDMOVE_RUN); m_fleeFromPosX = from.x; m_fleeFromPosY = from.y; @@ -5601,7 +5571,7 @@ CPed::SetFlee(CEntity *fleeFrom, int time) return; SetStoredState(); - m_nPedState = PED_FLEE_ENTITY; + SetPedState(PED_FLEE_ENTITY); bUsePedNodeSeek = true; SetMoveState(PEDMOVE_RUN); m_fleeFrom = fleeFrom; @@ -5862,7 +5832,7 @@ CPed::SetWanderPath(int8 pathStateDest) // We did it, save next path state and return true m_nPathDir = nextPathState; - m_nPedState = PED_WANDER_PATH; + SetPedState(PED_WANDER_PATH); SetMoveState(PEDMOVE_WALK); bIsRunning = false; return true; @@ -6047,7 +6017,7 @@ CPed::SetFollowPath(CVector dest) return false; SetStoredState(); - m_nPedState = PED_FOLLOW_PATH; + SetPedState(PED_FOLLOW_PATH); SetMoveState(PEDMOVE_WALK); return true; } @@ -6150,7 +6120,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType) m_fRotationCur = CGeneral::LimitRadianAngle(angleToFace); ClearAimFlag(); SetStoredState(); - m_nPedState = PED_STEP_AWAY; + SetPedState(PED_STEP_AWAY); } } } @@ -6247,13 +6217,13 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump) animAssoc->flags &= ~ASSOC_DELETEFADEDOUT; animAssoc->SetFinishCallback(PedEvadeCB, this); SetStoredState(); - m_nPedState = PED_STEP_AWAY; + SetPedState(PED_STEP_AWAY); } else { m_fRotationCur = angleToFace; ClearLookFlag(); ClearAimFlag(); SetStoredState(); - m_nPedState = PED_DIVE_AWAY; + SetPedState(PED_DIVE_AWAY); animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_EV_DIVE, 8.0f); animAssoc->SetFinishCallback(PedEvadeCB, this); } @@ -6291,7 +6261,7 @@ CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg) if (ped->m_nPedState == PED_DIVE_AWAY) { ped->m_getUpTimer = CTimer::GetTimeInMilliseconds() + 1; - ped->m_nPedState = PED_FALL; + ped->SetPedState(PED_FALL); } animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; animAssoc->flags |= ASSOC_DELETEFADEDOUT; @@ -6342,7 +6312,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) QuitEnteringCar(); } - m_nPedState = PED_DIE; + SetPedState(PED_DIE); if (animId == NUM_ANIMS) { bIsPedDieAnimPlaying = false; } else { @@ -6384,7 +6354,7 @@ CPed::SetDead(void) if (m_nPedState == PED_DRIVING) bIsVisible = false; - m_nPedState = PED_DEAD; + SetPedState(PED_DEAD); m_pVehicleAnim = nil; m_pCollidingEntity = nil; @@ -6417,7 +6387,7 @@ CPed::SetChat(CEntity *chatWith, uint32 time) if(m_nPedState != PED_CHAT) SetStoredState(); - m_nPedState = PED_CHAT; + SetPedState(PED_CHAT); SetMoveState(PEDMOVE_STILL); #if defined VC_PED_PORTS || defined FIX_BUGS m_lookTimer = 0; @@ -6658,7 +6628,7 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode) // m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget); m_vehEnterType = doorNode; m_distanceToCountSeekDone = 0.5f; - m_nPedState = PED_SEEK_CAR; + SetPedState(PED_SEEK_CAR); } @@ -7683,10 +7653,11 @@ CPed::FlagToDestroyWhenNextProcessed(void) } bInVehicle = false; m_pMyVehicle = nil; + if (CharCreatedBy == MISSION_CHAR) - m_nPedState = PED_DEAD; + SetPedState(PED_DEAD); else - m_nPedState = PED_NONE; + SetPedState(PED_NONE); m_pVehicleAnim = nil; } @@ -7710,7 +7681,7 @@ CPed::SetSolicit(uint32 time) if(!m_carInObjective->bIsVan && !m_carInObjective->bIsBus) m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_HOOKERTALK, 4.0f); - m_nPedState = PED_SOLICIT; + SetPedState(PED_SOLICIT); } } } @@ -7769,7 +7740,7 @@ CPed::SetBuyIceCream(void) // Simulating BuyIceCream CPed* driver = m_carInObjective->pDriver; if (driver) { - m_nPedState = PED_BUY_ICECREAM; + SetPedState(PED_BUY_ICECREAM); bFindNewNodeAfterStateRestore = true; SetObjectiveTimer(8000); SetChat(driver, 8000); @@ -7783,7 +7754,7 @@ CPed::SetBuyIceCream(void) if (Abs(m_fRotationDest - m_fRotationCur) < HALFPI) { m_standardTimer = CTimer::GetTimeInMilliseconds() + 3000; - m_nPedState = PED_BUY_ICECREAM; + SetPedState(PED_BUY_ICECREAM); } } @@ -7985,7 +7956,7 @@ CPed::SetJump(void) #endif (m_nSurfaceTouched != SURFACE_STEEP_CLIFF || DotProduct(GetForward(), m_vecDamageNormal) >= 0.0f)) { SetStoredState(); - m_nPedState = PED_JUMP; + SetPedState(PED_JUMP); CAnimBlendAssociation *jumpAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAUNCH, 8.0f); jumpAssoc->SetFinishCallback(FinishLaunchCB, this); m_fRotationDest = m_fRotationCur; @@ -8287,7 +8258,7 @@ CPed::WarpPedIntoCar(CVehicle *car) m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); m_carInObjective = car; m_carInObjective->RegisterReference((CEntity **) &m_carInObjective); - m_nPedState = PED_DRIVING; + SetPedState(PED_DRIVING); bUsesCollision = false; bIsInTheAir = false; bVehExitWillBeInstant = true; diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 5eaf8cd8..d4385385 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -809,10 +809,10 @@ CPed::ProcessObjective(void) break; } case OBJECTIVE_WAIT_IN_CAR: - m_nPedState = PED_DRIVING; + SetPedState(PED_DRIVING); break; case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT: - m_nPedState = PED_DRIVING; + SetPedState(PED_DRIVING); break; case OBJECTIVE_KILL_CHAR_ANY_MEANS: { @@ -2617,7 +2617,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg) if (ped->IsPlayer() && ped->bGonnaKillTheCarJacker && ((CPlayerPed*)ped)->m_pArrestingCop) { PedSetInCarCB(nil, ped); ped->m_nLastPedState = ped->m_nPedState; - ped->m_nPedState = PED_ARRESTED; + ped->SetPedState(PED_ARRESTED); ped->bGonnaKillTheCarJacker = false; if (veh) { veh->m_nNumGettingIn = 0; @@ -3340,7 +3340,7 @@ CPed::SetCarJack_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) m_pSeekTarget = car; m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget); - m_nPedState = PED_CARJACK; + SetPedState(PED_CARJACK); car->bIsBeingCarJacked = true; m_pMyVehicle = (CVehicle*)m_pSeekTarget; m_pMyVehicle->RegisterReference((CEntity**)&m_pMyVehicle); @@ -3387,7 +3387,7 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) SetMoveState(PEDMOVE_NONE); LineUpPedWithCar(LINE_UP_TO_CAR_START); m_pVehicleAnim = nil; - m_nPedState = PED_DRAG_FROM_CAR; + SetPedState(PED_DRAG_FROM_CAR); bChangedSeat = false; bWillBeQuickJacked = quickJack; @@ -3512,7 +3512,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag) m_pSeekTarget = car; m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); m_vehEnterType = doorNode; - m_nPedState = PED_ENTER_CAR; + SetPedState(PED_ENTER_CAR); if (m_vehEnterType == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && car->m_vehType != VEHICLE_TYPE_BIKE) { car->bIsBeingCarJacked = true; } @@ -3674,14 +3674,14 @@ void CPed::SetExitBoat(CVehicle *boat) { #ifndef VC_PED_PORTS - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); CVector firstPos = GetPosition(); CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f); if (boat->GetModelIndex() == MI_SPEEDER && boat->IsUpsideDown()) { m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS, 8.0f); m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this); m_vehEnterType = CAR_DOOR_RF; - m_nPedState = PED_EXIT_CAR; + SetPedState(PED_EXIT_CAR); } else { m_vehEnterType = CAR_DOOR_RF; PedSetOutCarCB(nil, this); @@ -3694,7 +3694,7 @@ CPed::SetExitBoat(CVehicle *boat) m_vecMoveSpeed = boat->m_vecMoveSpeed; bTryingToReachDryLand = true; #else - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); CVector newPos = GetPosition(); RemoveInCarAnims(); CColModel* boatCol = boat->GetColModel(); @@ -3921,7 +3921,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) m_pSeekTarget = veh; m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget); m_vehEnterType = optedDoorNode; - m_nPedState = PED_EXIT_CAR; + SetPedState(PED_EXIT_CAR); if (m_pVehicleAnim && m_pVehicleAnim->flags & ASSOC_PARTIAL) m_pVehicleAnim->blendDelta = -1000.0f; SetMoveState(PEDMOVE_NONE); @@ -4469,7 +4469,7 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) ped->bGonnaKillTheCarJacker = false; if (!ped->m_pedInObjective || !(CGeneral::GetRandomNumber() & 1)) { if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) { - ped->m_nPedState = PED_NONE; + ped->SetPedState(PED_NONE); ped->m_nLastPedState = PED_NONE; ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000); } else { @@ -4498,7 +4498,7 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg) else #endif { - ped->m_nPedState = PED_NONE; + ped->SetPedState(PED_NONE); ped->m_nLastPedState = PED_NONE; ped->SetFindPathAndFlee(ped->m_pMyVehicle->GetPosition(), 10000); } @@ -4591,7 +4591,7 @@ CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg) return; ped->bInVehicle = true; - ped->m_nPedState = PED_DRIVING; + ped->SetPedState(PED_DRIVING); ped->RestorePreviousObjective(); ped->SetMoveState(PEDMOVE_STILL); veh->AddPassenger(ped); @@ -4612,7 +4612,7 @@ CPed::SetEnterTrain(CVehicle *train, uint32 unused) m_pMyVehicle = train; m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); - m_nPedState = PED_ENTER_TRAIN; + SetPedState(PED_ENTER_TRAIN); m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETIN, 4.0f); m_pVehicleAnim->SetFinishCallback(PedSetInTrainCB, this); bUsesCollision = false; @@ -4686,7 +4686,7 @@ CPed::SetExitTrain(CVehicle* train) CVector exitPos; GetNearestTrainPedPosition(train, exitPos); */ - m_nPedState = PED_EXIT_TRAIN; + SetPedState(PED_EXIT_TRAIN); m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETOUT, 4.0f); m_pVehicleAnim->SetFinishCallback(PedSetOutTrainCB, this); bUsesCollision = false; @@ -4712,7 +4712,7 @@ CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg) ped->bUsesCollision = true; ped->m_pVehicleAnim = nil; ped->bInVehicle = false; - ped->m_nPedState = PED_IDLE; + ped->SetPedState(PED_IDLE); ped->RestorePreviousObjective(); ped->SetMoveState(PEDMOVE_STILL); @@ -5180,7 +5180,7 @@ CPed::SetSeekBoatPosition(CVehicle *boat) m_pMyVehicle = boat; m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); m_distanceToCountSeekDone = 0.5f; - m_nPedState = PED_SEEK_IN_BOAT; + SetPedState(PED_SEEK_IN_BOAT); } void diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index c219d94f..b4be0954 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -164,7 +164,7 @@ CPed::SetPointGunAt(CEntity *to) if (m_nPedState != PED_ATTACK) SetStoredState(); - m_nPedState = PED_AIM_GUN; + SetPedState(PED_AIM_GUN); bIsPointingGunAt = true; CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); SetMoveState(PEDMOVE_NONE); @@ -222,7 +222,7 @@ CPed::ClearPointGunAt(void) RestorePreviousState(); #else if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) { - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); RestorePreviousState(); } #endif @@ -281,7 +281,7 @@ CPed::SetAttack(CEntity *victim) (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS))) { if (m_nPedState != PED_ATTACK) { - m_nPedState = PED_ATTACK; + SetPedState(PED_ATTACK); bIsAttacking = false; animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, 8.0f); animAssoc->SetRun(); @@ -348,7 +348,7 @@ CPed::SetAttack(CEntity *victim) if (m_nPedState != PED_AIM_GUN) SetStoredState(); - m_nPedState = PED_ATTACK; + SetPedState(PED_ATTACK); SetMoveState(PEDMOVE_NONE); if (bCrouchWhenShooting) { animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f); @@ -786,7 +786,7 @@ CPed::StartFightAttack(uint8 buttonPressure) RestoreHeadingRate(); } - m_nPedState = PED_FIGHT; + SetPedState(PED_FIGHT); m_fightButtonPressure = 0; RpAnimBlendClumpRemoveAssociations(GetClump(), ASSOC_REPEAT); CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START); @@ -1062,7 +1062,7 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) m_nWaitState = WAITSTATE_FALSE; RestoreHeadingRate(); } - m_nPedState = PED_FIGHT; + SetPedState(PED_FIGHT); m_fightButtonPressure = 0; RpAnimBlendClumpRemoveAssociations(GetClump(), ASSOC_REPEAT); CAnimBlendAssociation *walkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START); @@ -1796,7 +1796,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount SetStoredState(); bFindNewNodeAfterStateRestore = false; - m_nPedState = PED_INVESTIGATE; + SetPedState(PED_INVESTIGATE); m_standardTimer = CTimer::GetTimeInMilliseconds() + time; m_eventType = event; m_eventOrThreat = pos; diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index ef9cf201..86d8e9f5 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -244,7 +244,7 @@ CPlayerPed::SetInitialState(void) if (m_pFire) m_pFire->Extinguish(); RpAnimBlendClumpRemoveAllAssociations(GetClump()); - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); SetMoveState(PEDMOVE_STILL); m_nLastPedState = PED_NONE; m_animGroup = ASSOCGRP_PLAYER; @@ -989,7 +989,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) { if (padUsed->TargetJustDown()) { SetStoredState(); - m_nPedState = PED_SNIPER_MODE; + SetPedState(PED_SNIPER_MODE); #ifdef FREE_CAM if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) { m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation); @@ -1343,41 +1343,6 @@ CPlayerPed::ProcessControl(void) if (IsPedInControl() && padUsed) ProcessPlayerWeapon(padUsed); break; - case PED_LOOK_ENTITY: - case PED_LOOK_HEADING: - case PED_WANDER_RANGE: - case PED_WANDER_PATH: - case PED_PURSUE: - case PED_FOLLOW_PATH: - case PED_ROCKET_MODE: - case PED_DUMMY: - case PED_PAUSE: - case PED_FACE_PHONE: - case PED_MAKE_CALL: - case PED_CHAT: - case PED_MUG: - case PED_AI_CONTROL: - case PED_FOLLOW_ROUTE: - case PED_CPR: - case PED_SOLICIT: - case PED_BUY_ICECREAM: - case PED_INVESTIGATE: - case PED_STEP_AWAY: - case PED_ON_FIRE: - case PED_UNKNOWN: - case PED_STATES_NO_AI: - case PED_STAGGER: - case PED_DIVE_AWAY: - case PED_STATES_NO_ST: - case PED_ARREST_PLAYER: - case PED_DRIVING: - case PED_PASSENGER: - case PED_TAXI_PASSENGER: - case PED_OPEN_DOOR: - case PED_DIE: - case PED_DEAD: - case PED_HANDS_UP: - break; case PED_SEEK_ENTITY: m_vecSeekPos = m_pSeekTarget->GetPosition(); @@ -1457,6 +1422,8 @@ CPlayerPed::ProcessControl(void) if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim) BeingDraggedFromCar(); break; + default: + break; } if (padUsed && IsPedShootable()) { ProcessWeaponSwitch(padUsed); diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index b3eaf471..5dbde649 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -718,10 +718,10 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree if (i != 0) { // Gang member newPed->SetLeader(gangLeader); -#ifndef FIX_BUGS +#if !defined(FIX_BUGS) && GTA_VERSION >= GTA3_PC_10 // seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen - newPed->m_nPedState = PED_UNKNOWN; - gangLeader->m_nPedState = PED_UNKNOWN; + newPed->SetPedState(PED_UNKNOWN); + gangLeader->SetPedState(PED_UNKNOWN); newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints( gangLeader->GetPosition().x, gangLeader->GetPosition().y, newPed->GetPosition().x, newPed->GetPosition().y); From 6d3adf57e8968071d16de8746cebf366543039bb Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 15 Dec 2020 14:36:30 +0100 Subject: [PATCH 38/52] fixed water.dat code --- src/render/WaterLevel.cpp | 118 +++++++++++++++++++------------------- src/render/WaterLevel.h | 8 +-- 2 files changed, 61 insertions(+), 65 deletions(-) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index ef5c4c58..49fc3a22 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -31,8 +31,8 @@ float TEXTURE_ADDV; int32 CWaterLevel::ms_nNoOfWaterLevels; float CWaterLevel::ms_aWaterZs[48]; CRect CWaterLevel::ms_aWaterRects[48]; -int8 CWaterLevel::aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; -int8 CWaterLevel::aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; +int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; +int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; bool CWaterLevel::WavesCalculatedThisFrame; RpAtomic *CWaterLevel::ms_pWavyAtomic; RpGeometry *CWaterLevel::apGeomArray[8]; @@ -54,7 +54,6 @@ const float fGreenMult = 1.0f; const float fBlueMult = 1.4f; - void CWaterLevel::Initialise(Const char *pWaterDat) { @@ -100,14 +99,15 @@ CWaterLevel::Initialise(Const char *pWaterDat) CFileMgr::CloseFile(hFile); - for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) { - for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) { aWaterFineBlockList[x][y] = NO_WATER; } } + // rasterize water rects read from file for (int32 i = 0; i < ms_nNoOfWaterLevels; i++) { int32 l = WATER_HUGE_X(ms_aWaterRects[i].left); @@ -115,13 +115,13 @@ CWaterLevel::Initialise(Const char *pWaterDat) int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top); int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f; - // originally this writes *god* knows where everywhere in game memory ... - // even in debug it manages to reach some textures so librw crashes with a ptr being 0x15151515 .... #ifdef FIX_BUGS - l = clamp(l, 0, WATER_FINEBLOCK_SIZE - 1); - r = clamp(r, 0, WATER_FINEBLOCK_SIZE - 1); - t = clamp(t, 0, WATER_FINEBLOCK_SIZE - 1); - b = clamp(b, 0, WATER_FINEBLOCK_SIZE - 1); + // water.dat has rects that go out of bounds + // which causes memory corruption + l = clamp(l, 0, MAX_SMALL_SECTORS - 1); + r = clamp(r, 0, MAX_SMALL_SECTORS - 1); + t = clamp(t, 0, MAX_SMALL_SECTORS - 1); + b = clamp(b, 0, MAX_SMALL_SECTORS - 1); #endif for (int32 x = l; x <= r; x++) @@ -133,46 +133,46 @@ CWaterLevel::Initialise(Const char *pWaterDat) } } - for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + // remove tiles that are obscured by land + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) { - int32 worldX = WATER_START_X + x * SMALL_SECTOR_WIDTH; + float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE; - for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) { - if (aWaterBlockList[x][y] >= 0) + if (aWaterFineBlockList[x][y] >= 0) { - int32 worldY = WATER_START_Y + y * SMALL_SECTOR_WIDTH; + float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE; int32 i; for (i = 0; i <= 8; i++) { for (int32 j = 0; j <= 8; j++) { - CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_WIDTH / 8), worldY + j * (SMALL_SECTOR_WIDTH / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]); + CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]); - if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y)) - { - if (WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) && !TestVisibilityForFineWaterBlocks(worldPos)) - { - i = 1000; - break; - } - } + if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y) && + (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos))) + continue; + + // at least one point in the tile wasn't blocked, so don't remove water + i = 1000; + break; } - - if (i == 1000) break; } - if (i < 1000) aWaterFineBlockList[x][y] = NO_WATER; + if (i < 1000) + aWaterFineBlockList[x][y] = NO_WATER; } } } RemoveIsolatedWater(); - for (int32 x = 0; x < WATER_BLOCK_SIZE; x++) + // calculate coarse tiles from fine tiles + for (int32 x = 0; x < MAX_LARGE_SECTORS; x++) { - for (int32 y = 0; y < WATER_BLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_LARGE_SECTORS; y++) { if (aWaterFineBlockList[x * 2][y * 2] >= 0) { @@ -445,11 +445,11 @@ CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos) void CWaterLevel::RemoveIsolatedWater() { - bool (*isConnected)[WATER_FINEBLOCK_SIZE] = new bool[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; + bool (*isConnected)[MAX_SMALL_SECTORS] = new bool[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; - for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) { - for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) { isConnected[x][y] = false; } @@ -462,35 +462,35 @@ CWaterLevel::RemoveIsolatedWater() { keepGoing = false; - for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) { - for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) { - if (aWaterBlockList[x][y] >= 0 && !isConnected[x][y]) + if (aWaterFineBlockList[x][y] < 0 || isConnected[x][y]) + continue; + + if (x > 0 && isConnected[x - 1][y]) { - if (x > 0 && isConnected[x - 1][y]) - { - isConnected[x][y] = true; - keepGoing = true; - } + isConnected[x][y] = true; + keepGoing = true; + } - if (y > 0 && isConnected[x][y - 1]) - { - isConnected[x][y] = true; - keepGoing = true; - } + if (y > 0 && isConnected[x][y - 1]) + { + isConnected[x][y] = true; + keepGoing = true; + } - if (x + 1 < WATER_FINEBLOCK_SIZE && isConnected[x + 1][y]) - { - isConnected[x][y] = true; - keepGoing = true; - } + if (x + 1 < MAX_SMALL_SECTORS && isConnected[x + 1][y]) + { + isConnected[x][y] = true; + keepGoing = true; + } - if (y + 1 < WATER_FINEBLOCK_SIZE && isConnected[x][y + 1]) - { - isConnected[x][y] = true; - keepGoing = true; - } + if (y + 1 < MAX_SMALL_SECTORS && isConnected[x][y + 1]) + { + isConnected[x][y] = true; + keepGoing = true; } } } @@ -499,11 +499,11 @@ CWaterLevel::RemoveIsolatedWater() int32 numRemoved = 0; - for (int32 x = 0; x < WATER_FINEBLOCK_SIZE; x++) + for (int32 x = 0; x < MAX_SMALL_SECTORS; x++) { - for (int32 y = 0; y < WATER_FINEBLOCK_SIZE; y++) + for (int32 y = 0; y < MAX_SMALL_SECTORS; y++) { - if (aWaterBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] != 0.0f) + if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 0.0f) { numRemoved++; aWaterFineBlockList[x][y] = NO_WATER; diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h index cff1a995..cf3537ae 100644 --- a/src/render/WaterLevel.h +++ b/src/render/WaterLevel.h @@ -1,7 +1,5 @@ #pragma once -#define WATER_BLOCK_SIZE LARGE_SECTOR_SIZE -#define WATER_FINEBLOCK_SIZE HUGE_SECTOR_SIZE #define WATER_Z_OFFSET (1.5f) #define NO_WATER -128 @@ -25,8 +23,6 @@ #define WATER_WIDTH ((WATER_END_X - WATER_START_X)) #define WATER_HEIGHT ((WATER_END_Y - WATER_START_Y)) -#define SMALL_SECTOR_WIDTH (WATER_WIDTH/MAX_SMALL_SECTORS) - #define WATER_UNSIGN_X(x) ( (x) + (WATER_WIDTH /2) ) #define WATER_UNSIGN_Y(y) ( (y) + (WATER_HEIGHT/2) ) #define WATER_SIGN_X(x) ( (x) - (WATER_WIDTH /2) ) @@ -75,8 +71,8 @@ class CWaterLevel static int32 ms_nNoOfWaterLevels; static float ms_aWaterZs[48]; static CRect ms_aWaterRects[48]; - static int8 aWaterBlockList[WATER_BLOCK_SIZE][WATER_BLOCK_SIZE]; - static int8 aWaterFineBlockList[WATER_FINEBLOCK_SIZE][WATER_FINEBLOCK_SIZE]; + static int8 aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; + static int8 aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; static bool WavesCalculatedThisFrame; static RpAtomic *ms_pWavyAtomic; static RpGeometry *apGeomArray[MAX_BOAT_WAKES]; From 64b509af52afa88cbbbe6feea05605eb5905176b Mon Sep 17 00:00:00 2001 From: erorcun Date: Tue, 15 Dec 2020 17:33:29 +0300 Subject: [PATCH 39/52] Make free cam collision code readable by aap, fixes --- src/core/Cam.cpp | 112 +++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index ba7e5d15..65a867be 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -3003,8 +3003,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float UseMouse = false; int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN); int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT); - // TODO: enum? this should be mouse wheel up and down - if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){ + if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){ if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){ if(CPad::GetPad(0)->SniperZoomIn()){ TargetFOV = FOV - 10.0f; @@ -4894,13 +4893,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (FOV > DefaultFOV) // 0.98f: CAR_FOV_FADE_MULT - FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; + FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; - if (FOV <= DefaultFOV + 30.0f) { - if (FOV < DefaultFOV) - FOV = DefaultFOV; - } else - FOV = DefaultFOV + 30.0f; + FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f); } // WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta) @@ -5030,7 +5025,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, targetAlpha = maxAlphaAllowed; } float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6]; - float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); + float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); if (targetAlphaBlendAmount <= maxAlphaBlendAmount) { if (targetAlphaBlendAmount < -maxAlphaBlendAmount) targetAlphaBlendAmount = -maxAlphaBlendAmount; @@ -5122,7 +5117,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12]; float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9]; - float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); + float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f); if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount) @@ -5234,75 +5229,76 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // SA calls SetColVarsVehicle in here if (nextDirectionIsForward) { - // This is new in LCS! + // LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so. + + // This is only in LCS! float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); // Our addition #define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex()))) - // Move cam if on collision - CColPoint foundCol; - CEntity* foundEnt; + // Clip Source and fix near clip + CColPoint colPoint; + CEntity* entity; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) && !IS_TRAFFIC_LIGHT(foundEnt)) { - float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - float obstacleCamDist = newDistance - obstacleTargetDist; - if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); - } - } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) || IS_TRAFFIC_LIGHT(foundEnt)) { - float lessClip = obstacleCamDist - 0.35f; - if (lessClip <= DEFAULT_NEAR) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - } else { - obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - float lessClip = obstacleTargetDist - 0.3f; - if (lessClip >= 0.05f) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } + if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){ + float PedColDist = (TargetCoors - colPoint.point).Magnitude(); + float ColCamDist = newDistance - PedColDist; + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ + // Ped in the way but not clipping through + if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){ + PedColDist = (TargetCoors - colPoint.point).Magnitude(); + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); + }else{ + RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR)); } + }else{ + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); } } CWorld::pIgnoreEntity = nil; - float nearClip = RwCameraGetNearClipPlane(Scene.camera); - float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. - for (int i = 0; - i <= 5 && (foundEnt = CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false)); - i++) { - if (IS_TRAFFIC_LIGHT(foundEnt)) + float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); + float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + float Near = RwCameraGetNearClipPlane(Scene.camera); + float radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + int i = 0; + while(entity){ + + if (IS_TRAFFIC_LIGHT(entity)) break; - CVector surfaceCamDist = gaTempSphereColPoints->point - Source; - CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; - float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; + CVector CamToCol = gaTempSphereColPoints[0].point - Source; + float frontDist = DotProduct(CamToCol, Front); + float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; - if (newNearClip > nearClip) - newNearClip = nearClip; - if (newNearClip < 0.1f) - newNearClip = 0.1f; - if (nearClip > newNearClip) - RwCameraSetNearClipPlane(Scene.camera, newNearClip); + // Try to decrease near clip + dist = Max(Min(Near, dist), 0.1f); + if(dist < Near) + RwCameraSetNearClipPlane(Scene.camera, dist); - if (newNearClip == 0.1f) - Source += (TargetCoors - Source) * 0.3f; + // Move forward a bit + if(dist == 0.1f) + Source += (TargetCoors - Source)*0.3f; - nearClip = RwCameraGetNearClipPlane(Scene.camera); - radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; + // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + + i++; + if(i > 5) + entity = nil; } #undef IS_TRAFFIC_LIGHT } From 55414f7ef2424e7b6804bae7b144a8be66b187bd Mon Sep 17 00:00:00 2001 From: "Walied K. Yassen" Date: Tue, 15 Dec 2020 18:05:37 +0200 Subject: [PATCH 40/52] Few bug fixes in CAutomobile --- src/vehicles/Automobile.cpp | 16 ++++++++-------- src/vehicles/Automobile.h | 2 -- src/vehicles/Vehicle.h | 8 -------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index ec71f690..79d3f6af 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -768,7 +768,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB); WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT], m_nWheelsOnGround, fThrust, @@ -802,7 +802,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB); WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT]; - if(Damage.GetWheelStatus(VEHWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT], m_nWheelsOnGround, fThrust, @@ -883,7 +883,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB); WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT]; - if(Damage.GetWheelStatus(VEHWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT], m_nWheelsOnGround, fThrust, @@ -917,7 +917,7 @@ CAutomobile::ProcessControl(void) adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB); WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT]; - if(Damage.GetWheelStatus(VEHWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST) + if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST) ProcessWheel(wheelFwd, wheelRight, contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT], m_nWheelsOnGround, fThrust, @@ -3946,10 +3946,10 @@ void CAutomobile::BurstTyre(uint8 wheel) { switch(wheel){ - case CAR_PIECE_WHEEL_LF: wheel = VEHWHEEL_FRONT_LEFT; break; - case CAR_PIECE_WHEEL_LR: wheel = VEHWHEEL_REAR_LEFT; break; - case CAR_PIECE_WHEEL_RF: wheel = VEHWHEEL_FRONT_RIGHT; break; - case CAR_PIECE_WHEEL_RR: wheel = VEHWHEEL_REAR_RIGHT; break; + case CAR_PIECE_WHEEL_LF: wheel = CARWHEEL_FRONT_LEFT; break; + case CAR_PIECE_WHEEL_RF: wheel = CARWHEEL_FRONT_RIGHT; break; + case CAR_PIECE_WHEEL_LR: wheel = CARWHEEL_REAR_LEFT; break; + case CAR_PIECE_WHEEL_RR: wheel = CARWHEEL_REAR_RIGHT; break; } int status = Damage.GetWheelStatus(wheel); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 604bed17..a5bee226 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -30,8 +30,6 @@ enum eCarNodes NUM_CAR_NODES, }; -// These are used for all the wheel arrays -// DON'T confuse with VEHWHEEL, which are vehicle components enum { CARWHEEL_FRONT_LEFT, CARWHEEL_REAR_LEFT, diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 3933f1dd..7066a0ea 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -57,14 +57,6 @@ enum eLights VEHLIGHT_REAR_RIGHT, }; -enum eWheels -{ - VEHWHEEL_FRONT_LEFT, - VEHWHEEL_FRONT_RIGHT, - VEHWHEEL_REAR_LEFT, - VEHWHEEL_REAR_RIGHT, -}; - enum { CAR_PIECE_BONNET = 1, From 23b5e664dcd5c178c6f7d4c06bc0e12057d898c9 Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 16 Dec 2020 00:38:26 +0300 Subject: [PATCH 41/52] Sync Frontend with miami 3/3 --- src/core/Frontend.cpp | 107 +++++++++++++++++++----------------------- src/core/Frontend.h | 13 ++--- 2 files changed, 55 insertions(+), 65 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 6806230d..5ea756e7 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -80,6 +80,7 @@ const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // PS2 option color #ifdef SCROLLABLE_PAGES #define MAX_VISIBLE_OPTION 12 #define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) +#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) int GetOptionCount(int screen) { @@ -176,7 +177,6 @@ int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; int32 CMenuManager::m_PrefsMusicVolume = 102; int32 CMenuManager::m_PrefsSfxVolume = 102; - char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; int32 CMenuManager::m_KeyPressedCode = -1; @@ -208,7 +208,6 @@ bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x5F311C const char* FrontendFilenames[][2] = { {"fe2_mainpanel_ul", "" }, {"fe2_mainpanel_ur", "" }, @@ -477,7 +476,7 @@ CMenuManager::ThingsToDoBeforeGoingBack() } #ifdef SCROLLABLE_PAGES - if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + if (SCREEN_HAS_AUTO_SCROLLBAR) { m_nSelectedListRow = 0; m_nFirstVisibleRowOnList = 0; m_nScrollbarTopMargin = 0; @@ -962,25 +961,25 @@ CMenuManager::DisplayHelperText() int action = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; if (action != MENUACTION_CHANGEMENU && action != MENUACTION_KEYBOARDCTRLS && action != MENUACTION_RESTOREDEF) { CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_MIG")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_MIG")); } break; } case 1: CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_APP")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP")); break; case 2: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_HRD")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD")); break; case 3: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSO")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO")); break; case 4: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC")); break; default: break; @@ -1045,8 +1044,7 @@ CMenuManager::Draw() CFont::SetCentreOff(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); -#if GTA_VERSION >= GTA3_PC_11 -#ifdef DRAW_MENU_VERSION_TEXT +#if GTA_VERSION >= GTA3_PC_11 && defined(DRAW_MENU_VERSION_TEXT) CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); @@ -1056,7 +1054,6 @@ CMenuManager::Draw() strcpy(gString, "V1.1"); AsciiToUnicode(gString, gUString); CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString); -#endif #endif CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); @@ -1297,11 +1294,12 @@ CMenuManager::Draw() #endif #ifdef CUSTOM_FRONTEND_OPTIONS + // Thanks R*, for checking mouse hovering in Draw(). static int lastSelectedOpt = m_nCurrOption; #endif #ifdef SCROLLABLE_PAGES - int firstOption = m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen) ? m_nFirstVisibleRowOnList : 0; + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { #else for (int i = 0; i < NUM_MENUROWS; ++i) { @@ -1334,38 +1332,6 @@ CMenuManager::Draw() leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName); } -#ifdef CUSTOM_FRONTEND_OPTIONS - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action < MENUACTION_NOTHING) { // CFO check - CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; - if (option.m_Action == MENUACTION_CFO_SELECT) { - if (option.m_CFOSelect->onlyApplyOnEnter){ - if (m_nCurrOption != i) { - if (option.m_CFOSelect->displayedValue != option.m_CFOSelect->lastSavedValue) - SetHelperText(3); // Restored original value - -// option.displayedValue = option.lastSavedValue = *option.m_CFO->value; - - } else { - if (option.m_CFOSelect->displayedValue != *option.m_CFO->value) - SetHelperText(1); // Enter to apply - else if (m_nHelperTextMsgId == 1) - ResetHelperText(); // Applied - } - } - } - - if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) { - CMenuScreenCustom::CMenuEntry &oldOption = aScreens[m_nCurrScreen].m_aEntries[lastSelectedOpt]; - if (oldOption.m_Action == MENUACTION_CFO_DYNAMIC) - if(oldOption.m_CFODynamic->buttonPressFunc) - oldOption.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - - if (oldOption.m_Action == MENUACTION_CFO_SELECT && oldOption.m_CFOSelect->onlyApplyOnEnter) - oldOption.m_CFOSelect->displayedValue = oldOption.m_CFOSelect->lastSavedValue = *oldOption.m_CFO->value; - } - } -#endif - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { case MENUACTION_CHANGEMENU: { switch (aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu) { @@ -1584,7 +1550,25 @@ CMenuManager::Draw() case MENUACTION_CFO_SELECT: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; if (option.m_Action == MENUACTION_CFO_SELECT) { - // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) + + if (option.m_CFOSelect->onlyApplyOnEnter){ + if (m_nCurrOption != i) { + if (option.m_CFOSelect->displayedValue != option.m_CFOSelect->lastSavedValue) + SetHelperText(3); // Restored original value + + // If that was previously selected option, restore it to default value. + // if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; + + } else { + if (option.m_CFOSelect->displayedValue != *option.m_CFO->value) + SetHelperText(1); // Enter to apply + else if (m_nHelperTextMsgId == 1) + ResetHelperText(); // Applied + } + } + + // To whom manipulate option.m_CFO->value of select options externally (like RestoreDef functions) if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; @@ -1594,6 +1578,11 @@ CMenuManager::Draw() rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]); } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) { + if(option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + } + if (option.m_CFODynamic->drawFunc) { rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i); } @@ -1730,7 +1719,9 @@ CMenuManager::Draw() if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 // To make assigning built-in actions to new custom options possible. -#ifndef CUSTOM_FRONTEND_OPTIONS +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FEA_3DH") +#else && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS #endif && m_nPrefsAudio3DProviderIndex != -1) { @@ -1807,21 +1798,21 @@ CMenuManager::Draw() #endif #ifdef SCROLLABLE_PAGES - #define SCROLLBAR_BOTTOM_X 125.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_BOTTOM_Y 125.0f // only for background, scrollbar's itself is calculated #define SCROLLBAR_RIGHT_X 36.0f #define SCROLLBAR_WIDTH 9.5f - #define SCROLLBAR_TOP_X 64 + #define SCROLLBAR_TOP_Y 64 - if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + if (SCREEN_HAS_AUTO_SCROLLBAR) { // Scrollbar background - CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_X), - MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_X)), CRGBA(100, 100, 66, FadeIn(205))); + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(100, 100, 66, FadeIn(205))); float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); float scrollbarBottom, scrollbarTop; - scrollbarBottom = MENU_Y(SCROLLBAR_TOP_X - 8 + m_nScrollbarTopMargin + scrollbarHeight); - scrollbarTop = MENU_Y(SCROLLBAR_TOP_X + m_nScrollbarTopMargin); + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 8 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + m_nScrollbarTopMargin); // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), @@ -2132,7 +2123,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // Print bindings, including seperator (-) between them - CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(0.25f), MENU_Y(SMALLESTTEXT_Y_SCALE)); for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { @@ -3158,9 +3149,7 @@ CMenuManager::DrawPlayerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_SKIN_COLUMN_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_SKN")); // Skin list - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM if (m_nSkinsTotal > 0) { for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList; m_pSelectedSkin = m_pSelectedSkin->nextSkin); @@ -5175,7 +5164,7 @@ CMenuManager::ProcessButtonPresses(void) increase = true; } else if ( #ifdef SCROLLABLE_PAGES - !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && + !SCREEN_HAS_AUTO_SCROLLBAR && #endif CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { increase = true; @@ -5188,7 +5177,7 @@ CMenuManager::ProcessButtonPresses(void) decrease = true; } else if ( #ifdef SCROLLABLE_PAGES - !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && + !SCREEN_HAS_AUTO_SCROLLBAR && #endif CPad::GetPad(0)->GetMouseWheelDownJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { decrease = true; diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 9f935510..e749069d 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -25,15 +25,18 @@ #define MENUSLIDER_X 256.0f #define MENUSLIDER_UNK 256.0f -#define BIGTEXT_X_SCALE 0.75f +#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING #define BIGTEXT_Y_SCALE 0.9f -#define MEDIUMTEXT_X_SCALE 0.55f +#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING #define MEDIUMTEXT_Y_SCALE 0.8f -#define SMALLTEXT_X_SCALE 0.45f +#define SMALLTEXT_X_SCALE 0.45f // used for FONT_HEADING and FONT_BANK, but looks off for HEADING #define SMALLTEXT_Y_SCALE 0.7f -#define SMALLESTTEXT_X_SCALE 0.4f +#define SMALLESTTEXT_X_SCALE 0.4f // used for both FONT_HEADING and FONT_BANK #define SMALLESTTEXT_Y_SCALE 0.6f +#define HELPER_TEXT_LEFT_MARGIN 320.0f +#define HELPER_TEXT_BOTTOM_MARGIN 120.0f + #define PLAYERSETUP_LIST_TOP 28.0f #define PLAYERSETUP_LIST_BOTTOM 125.0f #define PLAYERSETUP_LIST_LEFT 200.0f @@ -45,8 +48,6 @@ #endif #define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f #define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64 -#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f -#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f #define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f #define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f #define PLAYERSETUP_LIST_BODY_TOP 47 From c4c92c357fac073c80ef256f5be005ff9ce43e7a Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 16 Dec 2020 13:25:23 +0100 Subject: [PATCH 42/52] tidy water sync --- src/render/WaterLevel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 49fc3a22..6cd3fdad 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -62,7 +62,11 @@ CWaterLevel::Initialise(Const char *pWaterDat) #ifdef MASTER int32 hFile = -1; - while ((hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb")) < 0); + do + { + hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); + } + while ( hFile < 0 ); #else int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb"); #endif From c42463bf4e26bc889130d2b3f441f516ca207246 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 16 Dec 2020 13:32:13 +0100 Subject: [PATCH 43/52] more tidy water sync --- src/render/WaterLevel.cpp | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 6cd3fdad..977b61f3 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -221,8 +221,8 @@ CWaterLevel::Initialise(Const char *pWaterDat) int32 slot = CTxdStore::FindTxdSlot("particle"); CTxdStore::SetCurrentTxd(slot); - if ( gpWaterTex == NULL ) - gpWaterTex = RwTextureRead("water_old", NULL); + if ( gpWaterTex == nil ) + gpWaterTex = RwTextureRead("water_old", nil); gpWaterRaster = RwTextureGetRaster(gpWaterTex); CTxdStore::PopCurrentTxd(); @@ -239,10 +239,10 @@ CWaterLevel::Shutdown() FreeBoatWakeArray(); DestroyWavyAtomic(); - if ( gpWaterTex != NULL ) + if ( gpWaterTex != nil ) { RwTextureDestroy(gpWaterTex); - gpWaterTex = NULL; + gpWaterTex = nil; } } @@ -264,15 +264,15 @@ CWaterLevel::CreateWavyAtomic() |rpGEOMETRYPRELIT |rpGEOMETRYMODULATEMATERIALCOLOR); - ASSERT(wavyGeometry != NULL); + ASSERT(wavyGeometry != nil); } { wavyMaterial = RpMaterialCreate(); - ASSERT(wavyMaterial != NULL); - ASSERT(gpWaterTex != NULL); + ASSERT(wavyMaterial != nil); + ASSERT(gpWaterTex != nil); RpMaterialSetTexture(wavyMaterial, gpWaterTex); } @@ -280,7 +280,7 @@ CWaterLevel::CreateWavyAtomic() { wavyTriangles = RpGeometryGetTriangles(wavyGeometry); - ASSERT(wavyTriangles != NULL); + ASSERT(wavyTriangles != nil); /* [B] [C] *********** @@ -311,9 +311,9 @@ CWaterLevel::CreateWavyAtomic() { wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0); - ASSERT(wavyMorphTarget != NULL); + ASSERT(wavyMorphTarget != nil); wavyVert = RpMorphTargetGetVertices(wavyMorphTarget); - ASSERT(wavyVert != NULL); + ASSERT(wavyVert != nil); for ( int32 i = 0; i < 9; i++ ) { @@ -333,10 +333,10 @@ CWaterLevel::CreateWavyAtomic() { wavyFrame = RwFrameCreate(); - ASSERT( wavyFrame != NULL ); + ASSERT( wavyFrame != nil ); ms_pWavyAtomic = RpAtomicCreate(); - ASSERT( ms_pWavyAtomic != NULL ); + ASSERT( ms_pWavyAtomic != nil ); RpAtomicSetGeometry(ms_pWavyAtomic, wavyGeometry, 0); RpAtomicSetFrame(ms_pWavyAtomic, wavyFrame); @@ -535,7 +535,7 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool if ( nBlock == NO_WATER ) return false; - ASSERT( pfOutLevel != NULL ); + ASSERT( pfOutLevel != nil ); *pfOutLevel = ms_aWaterZs[nBlock]; float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f); @@ -574,7 +574,7 @@ CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLeve if ( nBlock == NO_WATER ) return false; - ASSERT( pfOutLevel != NULL ); + ASSERT( pfOutLevel != nil ); *pfOutLevel = ms_aWaterZs[nBlock]; return true; @@ -1247,19 +1247,19 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col CBoat::FillBoatList(); - ASSERT( ms_pWavyAtomic != NULL ); + ASSERT( ms_pWavyAtomic != nil ); RpGeometry *geometry = RpAtomicGetGeometry(ms_pWavyAtomic); - ASSERT( geometry != NULL ); + ASSERT( geometry != nil ); RwRGBA *wavyPreLights = RpGeometryGetPreLightColors(geometry); RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(geometry, rwTEXTURECOORDINATEINDEX0); RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geometry, 0)); - ASSERT( wavyPreLights != NULL ); - ASSERT( wavyTexCoords != NULL ); - ASSERT( wavyVertices != NULL ); + ASSERT( wavyPreLights != nil ); + ASSERT( wavyTexCoords != nil ); + ASSERT( wavyVertices != nil ); RpGeometryLock(geometry, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKPRELIGHT @@ -1282,7 +1282,7 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col RpGeometryUnlock(geometry); } - static CBoat *apBoatList[4] = { NULL }; + static CBoat *apBoatList[4] = { nil }; if ( apGeomArray[0] && nGeomUsed < MAX_BOAT_WAKES @@ -1296,16 +1296,16 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); RpGeometry *geom = apGeomArray[nGeomUsed++]; - ASSERT( wavyGeometry != NULL ); - ASSERT( geom != NULL ); + ASSERT( wavyGeometry != nil ); + ASSERT( geom != nil ); RpAtomic *atomic = RpAtomicCreate(); - ASSERT( atomic != NULL ); + ASSERT( atomic != nil ); RpAtomicSetGeometry(atomic, geom, 0); RwFrame *frame = RwFrameCreate(); - ASSERT( frame != NULL ); + ASSERT( frame != nil ); RwMatrixCopy(RwFrameGetMatrix(frame), RwFrameGetMatrix(RpAtomicGetFrame(ms_pWavyAtomic))); RpAtomicSetFrame(atomic, frame); @@ -1316,11 +1316,11 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col RwV3d *geomVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geom, 0)); RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(wavyGeometry, 0)); - ASSERT( geomTexCoords != NULL ); - ASSERT( wavyTexCoord != NULL ); - ASSERT( geomPreLights != NULL ); - ASSERT( geomVertices != NULL ); - ASSERT( wavyVertices != NULL ); + ASSERT( geomTexCoords != nil ); + ASSERT( wavyTexCoord != nil ); + ASSERT( geomPreLights != nil ); + ASSERT( geomVertices != nil ); + ASSERT( wavyVertices != nil ); RpGeometryLock(geom, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS); @@ -1337,7 +1337,7 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col for ( int32 k = 0; k < 4; k++ ) { - if ( apBoatList[k] != NULL ) + if ( apBoatList[k] != nil ) fDistMult += CBoat::IsVertexAffectedByWake(CVector(fVertexX, fVertexY, 0.0f), apBoatList[k]); } @@ -1386,7 +1386,7 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col pos.y = fY; pos.z = fZ; - ASSERT( ms_pWavyAtomic != NULL ); + ASSERT( ms_pWavyAtomic != nil ); RwFrameTranslate(RpAtomicGetFrame(ms_pWavyAtomic), &pos, rwCOMBINEREPLACE); @@ -1441,7 +1441,7 @@ CWaterLevel::RenderAndEmptyRenderBuffer() { LittleTest(); - if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, NULL, rwIM3D_VERTEXUV) ) + if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV) ) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); RwIm3DEnd(); @@ -1459,29 +1459,29 @@ CWaterLevel::AllocateBoatWakeArray() PUSH_MEMID(MEMID_STREAM); - ASSERT(ms_pWavyAtomic != NULL ); + ASSERT(ms_pWavyAtomic != nil ); RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic); - ASSERT(wavyGeometry != NULL ); + ASSERT(wavyGeometry != nil ); RpMorphTarget *wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0); RpMaterial *wavyMaterial = RpGeometryGetMaterial(wavyGeometry, 0); - ASSERT(wavyMorphTarget != NULL ); - ASSERT(wavyMaterial != NULL ); + ASSERT(wavyMorphTarget != nil ); + ASSERT(wavyMaterial != nil ); for ( int32 geom = 0; geom < MAX_BOAT_WAKES; geom++ ) { - if ( apGeomArray[geom] == NULL ) + if ( apGeomArray[geom] == nil ) { apGeomArray[geom] = RpGeometryCreate(9*9, 8*8*2, rpGEOMETRYTRISTRIP | rpGEOMETRYPRELIT | rpGEOMETRYMODULATEMATERIALCOLOR | rpGEOMETRYTEXTURED); - ASSERT(apGeomArray[geom] != NULL); + ASSERT(apGeomArray[geom] != nil); RpTriangle *geomTriangles = RpGeometryGetTriangles(apGeomArray[geom]); - ASSERT( geomTriangles != NULL ); + ASSERT( geomTriangles != nil ); for ( int32 i = 0; i < 8; i++ ) { @@ -1515,8 +1515,8 @@ CWaterLevel::AllocateBoatWakeArray() RpMorphTarget *geomMorphTarget = RpGeometryGetMorphTarget(apGeomArray[geom], 0); RwV3d *geomVertices = RpMorphTargetGetVertices(geomMorphTarget); - ASSERT( geomMorphTarget != NULL ); - ASSERT( geomVertices != NULL ); + ASSERT( geomMorphTarget != nil ); + ASSERT( geomVertices != nil ); for ( int32 i = 0; i < 9; i++ ) { @@ -1541,10 +1541,10 @@ CWaterLevel::FreeBoatWakeArray() { for ( int32 i = 0; i < MAX_BOAT_WAKES; i++ ) { - if ( apGeomArray[i] != NULL ) + if ( apGeomArray[i] != nil ) { RpGeometryDestroy(apGeomArray[i]); - apGeomArray[i] = NULL; + apGeomArray[i] = nil; } } From 7d89e955fe20696130fe76ed3d4582a756bd3621 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 16 Dec 2020 13:38:09 +0100 Subject: [PATCH 44/52] ;end of fucking waterlevel --- src/render/WaterLevel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 977b61f3..a0c7ae31 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -93,7 +93,11 @@ CWaterLevel::Initialise(Const char *pWaterDat) while ((line = CFileLoader::LoadLine(hFile))) { +#ifdef FIX_BUGS + if (*line && *line != ';' && !strstr(line, "* ;end of file")) +#else if (*line && *line != ';') +#endif { float z, l, b, r, t; sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t); From 387a6a087706fff5fdd26cba9deb0c92c700a683 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 16 Dec 2020 15:49:51 +0100 Subject: [PATCH 45/52] update librw --- vendor/librw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/librw b/vendor/librw index 2066cf66..ed9cb45e 160000 --- a/vendor/librw +++ b/vendor/librw @@ -1 +1 @@ -Subproject commit 2066cf6634383e056cd5dda105e87f8da04b1ed8 +Subproject commit ed9cb45ee9a2749a0a89231bf16f09a5c53bfc92 From 8e454392059a07be3d8b5fa9ee01f27220980230 Mon Sep 17 00:00:00 2001 From: erorcun Date: Wed, 16 Dec 2020 23:45:18 +0300 Subject: [PATCH 46/52] Use scrolling if GRAPHICS_MENU_OPTIONS not defined, like miami --- src/core/Frontend.h | 2 -- src/core/MenuScreensCustom.cpp | 26 ++++++-------------------- src/core/config.h | 2 +- 3 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/core/Frontend.h b/src/core/Frontend.h index e749069d..8cf3dd28 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -242,8 +242,6 @@ enum eMenuScreen #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, -#else - MENUPAGE_ADVANCED_DISPLAY_SETTINGS, #endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS MENUPAGE_DETECT_JOYSTICK, diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp index ae08f5f5..3a6d9c8b 100644 --- a/src/core/MenuScreensCustom.cpp +++ b/src/core/MenuScreensCustom.cpp @@ -399,7 +399,12 @@ CMenuScreenCustom aScreens[MENUPAGES] = { MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, VIDEOMODE_SELECTOR MULTISAMPLING_SELECTOR - MENUACTION_CHANGEMENU, "FET_ADV", { nil, SAVESLOT_NONE, MENUPAGE_ADVANCED_DISPLAY_SETTINGS }, + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + POSTFX_SELECTORS + PIPELINES_SELECTOR MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, @@ -829,31 +834,12 @@ CMenuScreenCustom aScreens[MENUPAGES] = { #else MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, #endif -#ifdef EXTENDED_PIPELINES PIPELINES_SELECTOR -#endif ISLAND_LOADING_SELECTOR DUALPASS_SELECTOR MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, -#else - // MENUPAGE_ADVANCED_DISPLAY_SETTINGS - { "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, - new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil, - - ISLAND_LOADING_SELECTOR - DUALPASS_SELECTOR - CUTSCENE_BORDERS_TOGGLE - FREE_CAM_TOGGLE -#ifdef EXTENDED_COLOURFILTER - POSTFX_SELECTORS -#endif -#ifdef EXTENDED_PIPELINES - PIPELINES_SELECTOR -#endif - MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, - }, #endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS diff --git a/src/core/config.h b/src/core/config.h index ad0df2da..8c9c1ccd 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -299,7 +299,7 @@ enum Config { # define CUSTOM_FRONTEND_OPTIONS # ifdef CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full +# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable # define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU # define CUTSCENE_BORDERS_SWITCH # define MULTISAMPLING // adds MSAA option From 9a9b1e757495be1eca3477353e040219b9bb7eb7 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Wed, 16 Dec 2020 23:28:06 +0200 Subject: [PATCH 47/52] Fix placement of some script functions --- src/control/Script4.cpp | 140 +++++++++++++++++++++++++++++++++++++++ src/control/Script5.cpp | 141 ---------------------------------------- 2 files changed, 140 insertions(+), 141 deletions(-) diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index 3629bb4b..afd6eba4 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -2025,3 +2025,143 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } return -1; } + +int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) +{ + if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) + ScriptSphereArray[index].m_Index = 1; + else + ScriptSphereArray[index].m_Index++; + return (uint16)index | ScriptSphereArray[index].m_Index << 16; +} + +int32 CTheScripts::GetActualScriptSphereIndex(int32 index) +{ + if (index == -1) + return -1; + uint16 check = (uint32)index >> 16; + uint16 array_idx = index & (0xFFFF); + script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray)); + if (check != ScriptSphereArray[array_idx].m_Index) + return -1; + return array_idx; +} + +void CTheScripts::DrawScriptSpheres() +{ + for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { + if (ScriptSphereArray[i].m_bInUse) + C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius, + SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); + } +} + +int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius) +{ + int16 i = 0; + for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { + if (!ScriptSphereArray[i].m_bInUse) + break; + } +#ifdef FIX_BUGS + if (i == MAX_NUM_SCRIPT_SPHERES) + return -1; +#endif + ScriptSphereArray[i].m_bInUse = true; + ScriptSphereArray[i].m_Id = id; + ScriptSphereArray[i].m_vecCenter = pos; + ScriptSphereArray[i].m_fRadius = radius; + return GetNewUniqueScriptSphereIndex(i); +} + +void CTheScripts::RemoveScriptSphere(int32 index) +{ + index = GetActualScriptSphereIndex(index); + if (index == -1) + return; + ScriptSphereArray[index].m_bInUse = false; + ScriptSphereArray[index].m_Id = 0; +} + +void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model) +{ + int i = 0; + bool found = false; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == pBuilding) + found = true; + else + i++; + } + if (found) { + if (BuildingSwapArray[i].m_nOldModel == new_model) { + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; + } + else { + BuildingSwapArray[i].m_nNewModel = new_model; + } + } + else { + i = 0; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == nil) + found = true; + else + i++; + } + if (found) { + BuildingSwapArray[i].m_pBuilding = pBuilding; + BuildingSwapArray[i].m_nNewModel = new_model; + BuildingSwapArray[i].m_nOldModel = old_model; + } + } +} + +void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove) +{ + int i = 0; + bool found = false; + while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { + if (InvisibilitySettingArray[i] == pEntity) + found = true; + else + i++; + } + if (found) { + if (remove) + InvisibilitySettingArray[i] = nil; + } + else if (!remove) { + i = 0; + while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { + if (InvisibilitySettingArray[i] == nil) + found = true; + else + i++; + } + if (found) + InvisibilitySettingArray[i] = pEntity; + } +} + +void CTheScripts::UndoBuildingSwaps() +{ + for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { + if (BuildingSwapArray[i].m_pBuilding) { + BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel); + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; + } + } +} + +void CTheScripts::UndoEntityInvisibilitySettings() +{ + for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) { + if (InvisibilitySettingArray[i]) { + InvisibilitySettingArray[i]->bIsVisible = true; + InvisibilitySettingArray[i] = nil; + } + } +} diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index 4826192e..153f2393 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -17,147 +17,6 @@ #include "World.h" #include "main.h" -int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) -{ - if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) - ScriptSphereArray[index].m_Index = 1; - else - ScriptSphereArray[index].m_Index++; - return (uint16)index | ScriptSphereArray[index].m_Index << 16; -} - -int32 CTheScripts::GetActualScriptSphereIndex(int32 index) -{ - if (index == -1) - return -1; - uint16 check = (uint32)index >> 16; - uint16 array_idx = index & (0xFFFF); - script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray)); - if (check != ScriptSphereArray[array_idx].m_Index) - return -1; - return array_idx; -} - -void CTheScripts::DrawScriptSpheres() -{ - for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { - if (ScriptSphereArray[i].m_bInUse) - C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius, - SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); - } -} - -int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius) -{ - int16 i = 0; - for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { - if (!ScriptSphereArray[i].m_bInUse) - break; - } -#ifdef FIX_BUGS - if (i == MAX_NUM_SCRIPT_SPHERES) - return -1; -#endif - ScriptSphereArray[i].m_bInUse = true; - ScriptSphereArray[i].m_Id = id; - ScriptSphereArray[i].m_vecCenter = pos; - ScriptSphereArray[i].m_fRadius = radius; - return GetNewUniqueScriptSphereIndex(i); -} - -void CTheScripts::RemoveScriptSphere(int32 index) -{ - index = GetActualScriptSphereIndex(index); - if (index == -1) - return; - ScriptSphereArray[index].m_bInUse = false; - ScriptSphereArray[index].m_Id = 0; -} - -void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model) -{ - int i = 0; - bool found = false; - while (i < MAX_NUM_BUILDING_SWAPS && !found) { - if (BuildingSwapArray[i].m_pBuilding == pBuilding) - found = true; - else - i++; - } - if (found) { - if (BuildingSwapArray[i].m_nOldModel == new_model) { - BuildingSwapArray[i].m_pBuilding = nil; - BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; - } - else { - BuildingSwapArray[i].m_nNewModel = new_model; - } - } - else { - i = 0; - while (i < MAX_NUM_BUILDING_SWAPS && !found) { - if (BuildingSwapArray[i].m_pBuilding == nil) - found = true; - else - i++; - } - if (found) { - BuildingSwapArray[i].m_pBuilding = pBuilding; - BuildingSwapArray[i].m_nNewModel = new_model; - BuildingSwapArray[i].m_nOldModel = old_model; - } - } -} - -void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove) -{ - int i = 0; - bool found = false; - while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { - if (InvisibilitySettingArray[i] == pEntity) - found = true; - else - i++; - } - if (found) { - if (remove) - InvisibilitySettingArray[i] = nil; - } - else if (!remove) { - i = 0; - while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) { - if (InvisibilitySettingArray[i] == nil) - found = true; - else - i++; - } - if (found) - InvisibilitySettingArray[i] = pEntity; - } -} - -void CTheScripts::UndoBuildingSwaps() -{ - for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { - if (BuildingSwapArray[i].m_pBuilding) { - BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel); - BuildingSwapArray[i].m_pBuilding = nil; - BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; - } - } -} - -void CTheScripts::UndoEntityInvisibilitySettings() -{ - for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) { - if (InvisibilitySettingArray[i]) { - InvisibilitySettingArray[i]->bIsVisible = true; - InvisibilitySettingArray[i] = nil; - } - } -} - - void CRunningScript::UpdateCompareFlag(bool flag) { if (m_bNotFlag) From dd579c40800856a427274f7491bb7bcc00df9e00 Mon Sep 17 00:00:00 2001 From: erorcun Date: Thu, 17 Dec 2020 02:47:48 +0300 Subject: [PATCH 48/52] Fix --- src/core/World.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/World.cpp b/src/core/World.cpp index da565f22..a7531c83 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -1955,12 +1955,11 @@ CWorld::Process(void) } else { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { CEntity *movingEnt = (CEntity *)node->item; -#ifdef SQUEEZE_PERFORMANCE - if (movingEnt->bRemoveFromWorld) { - RemoveEntityInsteadOfProcessingIt(movingEnt); - } else -#endif +#ifdef FIX_BUGS // from VC + if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && +#else if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && +#endif RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * (movingEnt->IsObject() From cc5af26417d446ccadb6a8f885926c734d29131f Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 17 Dec 2020 12:47:00 +0100 Subject: [PATCH 49/52] PreAllocateRwObjects --- src/core/main.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/main.h | 1 + 2 files changed, 58 insertions(+) diff --git a/src/core/main.cpp b/src/core/main.cpp index cc20047f..51c48452 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -415,6 +415,63 @@ PluginAttach(void) return TRUE; } +#ifdef GTA_PS2 +#define NUM_PREALLOC_ATOMICS 3245 +#define NUM_PREALLOC_CLUMPS 101 +#define NUM_PREALLOC_FRAMES 2821 +#define NUM_PREALLOC_GEOMETRIES 1404 +#define NUM_PREALLOC_TEXDICTS 106 +#define NUM_PREALLOC_TEXTURES 1900 +#define NUM_PREALLOC_MATERIALS 3300 +bool preAlloc; + +void +PreAllocateRwObjects(void) +{ + int i; + void **tmp = new void*[0x8000]; + preAlloc = true; + + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + tmp[i] = RpAtomicCreate(); + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + RpAtomicDestroy((RpAtomic*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + tmp[i] = RpClumpCreate(); + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + RpClumpDestroy((RpClump*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + tmp[i] = RwFrameCreate(); + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + RwFrameDestroy((RwFrame*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + tmp[i] = RpGeometryCreate(0, 0, 0); + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + RpGeometryDestroy((RpGeometry*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + tmp[i] = RwTexDictionaryCreate(); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTexDictionaryDestroy((RwTexDictionary*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXTURES; i++) + tmp[i] = RwTextureCreate(RwRasterCreate(0, 0, 0, 0)); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTextureDestroy((RwTexture*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + tmp[i] = RpMaterialCreate(); + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + RpMaterialDestroy((RpMaterial*)tmp[i]); + + delete[] tmp; + preAlloc = false; +} +#endif + static RwBool Initialise3D(void *param) { diff --git a/src/core/main.h b/src/core/main.h index 77fac46a..149c0878 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -29,6 +29,7 @@ class CSprite2d; bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); +void PreAllocateRwObjects(void); void InitialiseGame(void); void LoadingScreen(const char *str1, const char *str2, const char *splashscreen); void LoadingIslandScreen(const char *levelName); From e9a567034818c5e3338120958061e4a4278d97da Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 18 Dec 2020 02:57:54 +0200 Subject: [PATCH 50/52] PlayerInfo functions reordered into original order, FindPlayer... functions moved to PlayerInfo, improved CVector <-> RwV3d conversion, small fixes --- src/collision/Collision.cpp | 14 +- src/control/Replay.cpp | 24 +- src/core/Cam.cpp | 12 +- src/core/PlayerInfo.cpp | 640 +++++++++++++++++------------ src/core/PlayerInfo.h | 21 +- src/core/World.cpp | 96 ----- src/core/World.h | 11 - src/extras/screendroplets.cpp | 6 +- src/math/Vector.h | 25 +- src/math/VuVector.h | 13 +- src/modelinfo/VehicleModelInfo.cpp | 2 +- src/peds/CopPed.cpp | 2 +- src/peds/EmergencyPed.cpp | 16 +- src/peds/Ped.cpp | 2 +- src/peds/Ped.h | 4 +- src/peds/PedAI.cpp | 2 +- src/peds/PedFight.cpp | 2 +- src/peds/PedIK.cpp | 14 +- src/peds/PedIK.h | 2 +- src/peds/PlayerPed.cpp | 2 +- src/render/Clouds.cpp | 2 +- src/render/Coronas.cpp | 6 +- src/render/Fluff.cpp | 10 +- src/render/Particle.cpp | 4 +- src/render/PointLights.cpp | 4 +- src/render/Renderer.cpp | 4 +- src/render/Weather.cpp | 2 +- src/weapons/Weapon.cpp | 4 +- 28 files changed, 470 insertions(+), 476 deletions(-) diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp index 41997e32..7fb5c30b 100644 --- a/src/collision/Collision.cpp +++ b/src/collision/Collision.cpp @@ -665,7 +665,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); // If we don't intersect with the bounding box, no chance on the rest if(!TestLineBox(*(CColLine*)newline, model.boundingBox)) @@ -1474,7 +1474,7 @@ CCollision::ProcessLineOfSight(const CColLine &line, // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); if(mindist < 1.0f) newline[1] = newline[0] + (newline[1] - newline[0])*mindist; @@ -1606,7 +1606,7 @@ CCollision::ProcessVerticalLine(const CColLine &line, // transform line to model space Invert(matrix, matTransform); CVuVector newline[2]; - TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2); + TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2); if(mindist < 1.0f) newline[1] = newline[0] + (newline[1] - newline[0])*mindist; @@ -1806,16 +1806,16 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, matAB *= matrixA; CVuVector bsphereAB; // bounding sphere of A in B space - TransformPoint(bsphereAB, matAB, *(RwV3d*)modelA.boundingSphere.center); // inlined + TransformPoint(bsphereAB, matAB, modelA.boundingSphere.center); // inlined bsphereAB.w = modelA.boundingSphere.radius; if(!TestSphereBox(*(CColSphere*)&bsphereAB, modelB.boundingBox)) return 0; // transform modelA's spheres and lines to B space - TransformPoints(aSpheresA, modelA.numSpheres, matAB, (RwV3d*)&modelA.spheres->center, sizeof(CColSphere)); + TransformPoints(aSpheresA, modelA.numSpheres, matAB, &modelA.spheres->center, sizeof(CColSphere)); for(i = 0; i < modelA.numSpheres; i++) aSpheresA[i].w = modelA.spheres[i].radius; - TransformPoints(aLinesA, modelA.numLines*2, matAB, (RwV3d*)&modelA.lines->p0, sizeof(CColLine)/2); + TransformPoints(aLinesA, modelA.numLines*2, matAB, &modelA.lines->p0, sizeof(CColLine)/2); // Test them against model B's bounding volumes int numSpheresA = 0; @@ -1832,7 +1832,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, matBA *= matrixB; // transform modelB's spheres to A space - TransformPoints(aSpheresB, modelB.numSpheres, matBA, (RwV3d*)&modelB.spheres->center, sizeof(CColSphere)); + TransformPoints(aSpheresB, modelB.numSpheres, matBA, &modelB.spheres->center, sizeof(CColSphere)); for(i = 0; i < modelB.numSpheres; i++) aSpheresB[i].w = modelB.spheres[i].radius; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 4732ba2f..d9e5e675 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1038,10 +1038,10 @@ void CReplay::ProcessReplayCamera(void) TheCamera.GetUp() = CVector(0.0f, 1.0f, 0.0f); TheCamera.GetRight() = CVector(1.0f, 0.0f, 0.0f); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetRight(); + pm->pos = TheCamera.GetPosition(); + pm->at = TheCamera.GetForward(); + pm->up = TheCamera.GetUp(); + pm->right = TheCamera.GetRight(); break; } case REPLAYCAMMODE_FIXED: @@ -1057,10 +1057,10 @@ void CReplay::ProcessReplayCamera(void) TheCamera.GetMatrix().GetUp() = up; TheCamera.GetMatrix().GetRight() = right; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); + pm->pos = TheCamera.GetMatrix().GetPosition(); + pm->at = TheCamera.GetMatrix().GetForward(); + pm->up = TheCamera.GetMatrix().GetUp(); + pm->right = TheCamera.GetMatrix().GetRight(); break; } default: @@ -1581,10 +1581,10 @@ void CReplay::ProcessLookAroundCam(void) TheCamera.GetRight() = right; TheCamera.SetPosition(camera_pt); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetRight(); + pm->pos = TheCamera.GetPosition(); + pm->at = TheCamera.GetForward(); + pm->up = TheCamera.GetUp(); + pm->right = TheCamera.GetRight(); TheCamera.CalculateDerivedValues(); RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 65a867be..5906310b 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -2472,7 +2472,7 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2573,7 +2573,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) } #if GTA_VERSION < GTA3_PC_11 - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2611,7 +2611,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) HeadPos.x = 0.0f; HeadPos.y = 0.0f; HeadPos.z = 0.0f; - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f * Cos(m_fInitialPlayerOrientation); @@ -2700,7 +2700,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2868,7 +2868,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, Source = HeadPos; // unused: - // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID); + // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID); // Source - MidPos; // Look around @@ -2963,7 +2963,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 5866485d..07424736 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -3,6 +3,7 @@ #include "Automobile.h" #include "Bridge.h" #include "Camera.h" +#include "CarCtrl.h" #include "Cranes.h" #include "Darkel.h" #include "Explosion.h" @@ -31,83 +32,6 @@ #include "ZoneCull.h" #include "main.h" -void -CPlayerInfo::SetPlayerSkin(char *skin) -{ - strncpy(m_aSkinName, skin, 32); - LoadPlayerSkin(); -} - -const CVector & -CPlayerInfo::GetPos() -{ -#ifdef FIX_BUGS - if (!m_pPed) - return TheCamera.GetPosition(); -#endif - if (m_pPed->InVehicle()) - return m_pPed->m_pMyVehicle->GetPosition(); - return m_pPed->GetPosition(); -} - -void -CPlayerInfo::LoadPlayerSkin() -{ - DeletePlayerSkin(); - - m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); - if (!m_pSkinTexture) - m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME); -} - -void -CPlayerInfo::DeletePlayerSkin() -{ - if (m_pSkinTexture) { - RwTextureDestroy(m_pSkinTexture); - m_pSkinTexture = nil; - } -} - -void -CPlayerInfo::KillPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_WASTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); - CStats::TimesDied++; -} - -void -CPlayerInfo::ArrestPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_BUSTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); - CStats::TimesArrested++; -} - -bool -CPlayerInfo::IsPlayerInRemoteMode() -{ - return m_pRemoteVehicle || m_bInRemoteMode; -} - -void -CPlayerInfo::PlayerFailedCriticalMission() -{ - if (m_WBState != WBSTATE_PLAYING) - return; - m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); -} void CPlayerInfo::Clear(void) @@ -146,197 +70,6 @@ CPlayerInfo::Clear(void) m_nExplosionsSinceLastReward = 0; } -void -CPlayerInfo::BlowUpRCBuggy(void) -{ - if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) - return; - - CRemote::TakeRemoteControlledCarFromPlayer(); - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); -} - -void -CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) -{ - if (!car || car == m_pPed->m_pMyVehicle) { - if (m_pPed->EnteringCar()) - m_pPed->QuitEnteringCar(); - } - if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) - m_pPed->ClearObjective(); -} - -void -CPlayerInfo::MakePlayerSafe(bool toggle) -{ - if (toggle) { - CTheScripts::ResetCountdownToMakePlayerUnsafe(); - m_pPed->m_pWanted->m_bIgnoredByEveryone = true; - CWorld::StopAllLawEnforcersInTheirTracks(); - CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); - CPad::StopPadsShaking(); - m_pPed->bBulletProof = true; - m_pPed->bFireProof = true; - m_pPed->bCollisionProof = true; - m_pPed->bMeleeProof = true; - m_pPed->bOnlyDamagedByPlayer = true; - m_pPed->bExplosionProof = true; - m_pPed->m_bCanBeDamaged = false; - ((CPlayerPed*)m_pPed)->ClearAdrenaline(); - CancelPlayerEnteringCars(nil); - gFireManager.ExtinguishPoint(GetPos(), 4000.0f); - CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); - CProjectileInfo::RemoveAllProjectiles(); - CWorld::SetAllCarsCanBeDamaged(false); - CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); - CReplay::DisableReplays(); - - } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { - m_pPed->m_pWanted->m_bIgnoredByEveryone = false; - CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); - m_pPed->bBulletProof = false; - m_pPed->bFireProof = false; - m_pPed->bCollisionProof = false; - m_pPed->bMeleeProof = false; - m_pPed->bOnlyDamagedByPlayer = false; - m_pPed->bExplosionProof = false; - m_pPed->m_bCanBeDamaged = true; - CWorld::SetAllCarsCanBeDamaged(true); - CReplay::EnableReplays(); - } -} - -bool -CPlayerInfo::IsRestartingAfterDeath() -{ - return m_WBState == WBSTATE_WASTED; -} - -bool -CPlayerInfo::IsRestartingAfterArrest() -{ - return m_WBState == WBSTATE_BUSTED; -} - -// lastCloseness is passed to other calls of this function -void -CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) -{ - // This dist used for determining the angle to face - CVector2D dist(carToTest->GetPosition() - player->GetPosition()); - float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); - while (neededTurn >= PI) { - neededTurn -= 2 * PI; - } - - while (neededTurn < -PI) { - neededTurn += 2 * PI; - } - - // This dist used for evaluating cars' distances, weird... - // Accounts inverted needed turn (or needed turn in long way) and car dist. - float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); - if (closeness > *lastCloseness) { - *lastCloseness = closeness; - *closestCarOutput = (CVehicle*)carToTest; - } -} - -// There is something unfinished in here... Sadly all IDBs we have have it unfinished. -void -CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar) -{ - if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000) - ++m_nExplosionsSinceLastReward; - else - m_nExplosionsSinceLastReward = 1; - - m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds(); - int award = wreckedCar->pHandling->nMonetaryValue * 0.002f; - sprintf(gString, "$%d", award); -#ifdef MONEY_MESSAGES - // This line is a leftover from PS2, I don't know what it was meant to be. - // CVector sth(TheCamera.GetPosition() * 4.0f); - - CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f); -#endif - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; - - for (int i = m_nExplosionsSinceLastReward; i > 1; --i) { - CGeneral::GetRandomNumber(); - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; - } -} - -void -CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) -{ - // Interesting - *size = sizeof(CPlayerInfo); - -#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); -#undef CopyToBuf -} - -void -CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) -{ -#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName) -#undef CopyFromBuf -} - -void -CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) -{ - for (CPtrNode* node = carList.first; node; node = node->next) { - CVehicle *car = (CVehicle*)node->item; - if(car->m_scanCode != CWorld::GetCurrentScanCode()) { - if (!car->bUsesCollision || !car->IsVehicle()) - continue; - - car->m_scanCode = CWorld::GetCurrentScanCode(); - if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING - && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { - CVector carCentre = car->GetBoundCentre(); - - if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) { - float dist = (ped->GetPosition() - carCentre).Magnitude2D(); - if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { - EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); - } - } - } - } - } -} - void CPlayerInfo::Process(void) { @@ -503,13 +236,13 @@ CPlayerInfo::Process(void) uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar; if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) { TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 0); + TheCamera.Fade(1.0f, FADE_OUT); } if (timeWithoutRemoteCar > 2000) { if (m_WBState == WBSTATE_PLAYING) { TheCamera.RestoreWithJumpCut(); TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 1); + TheCamera.Fade(1.0f, FADE_IN); TheCamera.Process(); CTimer::Stop(); CCullZones::ForceCullZoneCoors(TheCamera.GetPosition()); @@ -560,3 +293,370 @@ CPlayerInfo::Process(void) CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled; } } + +bool +CPlayerInfo::IsPlayerInRemoteMode() +{ + return m_pRemoteVehicle || m_bInRemoteMode; +} + +void +CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) +{ + // Interesting + *size = sizeof(CPlayerInfo); + +#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); +#undef CopyToBuf +} + +void +CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) +{ +#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName) +#undef CopyFromBuf +} + +void +CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) +{ + for (CPtrNode* node = carList.first; node; node = node->next) { + CVehicle *car = (CVehicle*)node->item; + if(car->m_scanCode != CWorld::GetCurrentScanCode()) { + if (!car->bUsesCollision || !car->IsVehicle()) + continue; + + car->m_scanCode = CWorld::GetCurrentScanCode(); + if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING + && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { + CVector carCentre = car->GetBoundCentre(); + + if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) { + float dist = (ped->GetPosition() - carCentre).Magnitude2D(); + if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { + EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); + } + } + } + } + } +} + +// lastCloseness is passed to other calls of this function +void +CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) +{ + // This dist used for determining the angle to face + CVector2D dist(carToTest->GetPosition() - player->GetPosition()); + float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); + while (neededTurn >= PI) { + neededTurn -= 2 * PI; + } + + while (neededTurn < -PI) { + neededTurn += 2 * PI; + } + + // This dist used for evaluating cars' distances, weird... + // Accounts inverted needed turn (or needed turn in long way) and car dist. + float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); + if (closeness > *lastCloseness) { + *lastCloseness = closeness; + *closestCarOutput = (CVehicle*)carToTest; + } +} + +const CVector & +CPlayerInfo::GetPos() +{ +#ifdef FIX_BUGS + if (!m_pPed) + return TheCamera.GetPosition(); +#endif + if (m_pPed->InVehicle()) + return m_pPed->m_pMyVehicle->GetPosition(); + return m_pPed->GetPosition(); +} + +CVector +FindPlayerCoors(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) + return TheCamera.GetPosition(); +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->GetPosition(); + else + return ped->GetPosition(); +} + +const CVector & +FindPlayerSpeed(void) +{ +#ifdef FIX_BUGS + static CVector vecTmpVector(0.0f, 0.0f, 0.0f); + if (CReplay::IsPlayingBack()) + return vecTmpVector; +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->m_vecMoveSpeed; + else + return ped->m_vecMoveSpeed; +} + +CVehicle * +FindPlayerVehicle(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped && ped->InVehicle()) return ped->m_pMyVehicle; + return nil; +} + +CEntity * +FindPlayerEntity(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle; + else + return ped; +} + +CVehicle * +FindPlayerTrain(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) + return FindPlayerVehicle(); + else + return nil; +} + +CPlayerPed * +FindPlayerPed(void) +{ + return CWorld::Players[CWorld::PlayerInFocus].m_pPed; +} + +const CVector & +FindPlayerCentreOfWorld(int32 player) +{ +#ifdef FIX_BUGS + if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return CWorld::Players[player].m_pPed->GetPosition(); +} + +const CVector & +FindPlayerCentreOfWorld_NoSniperShift(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return FindPlayerPed()->GetPosition(); +} + +float +FindPlayerHeading(void) +{ + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); + return FindPlayerPed()->GetForward().Heading(); +} + +bool +CPlayerInfo::IsRestartingAfterDeath() +{ + return m_WBState == WBSTATE_WASTED; +} + +bool +CPlayerInfo::IsRestartingAfterArrest() +{ + return m_WBState == WBSTATE_BUSTED; +} + +void +CPlayerInfo::KillPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_WASTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); + CStats::TimesDied++; +} + +void +CPlayerInfo::ArrestPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_BUSTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); + CStats::TimesArrested++; +} + +void +CPlayerInfo::PlayerFailedCriticalMission() +{ + if (m_WBState != WBSTATE_PLAYING) + return; + m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); +} + +void +CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) +{ + if (!car || car == m_pPed->m_pMyVehicle) { + if (m_pPed->EnteringCar()) + m_pPed->QuitEnteringCar(); + } + if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) + m_pPed->ClearObjective(); +} + +void +CPlayerInfo::MakePlayerSafe(bool toggle) +{ + if (toggle) { + CTheScripts::ResetCountdownToMakePlayerUnsafe(); + m_pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); + CPad::StopPadsShaking(); + m_pPed->bBulletProof = true; + m_pPed->bFireProof = true; + m_pPed->bCollisionProof = true; + m_pPed->bMeleeProof = true; + m_pPed->bOnlyDamagedByPlayer = true; + m_pPed->bExplosionProof = true; + m_pPed->m_bCanBeDamaged = false; + ((CPlayerPed*)m_pPed)->ClearAdrenaline(); + CancelPlayerEnteringCars(nil); + gFireManager.ExtinguishPoint(GetPos(), 4000.0f); + CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); + CProjectileInfo::RemoveAllProjectiles(); + CWorld::SetAllCarsCanBeDamaged(false); + CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); + CReplay::DisableReplays(); + + } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { + m_pPed->m_pWanted->m_bIgnoredByEveryone = false; + CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); + m_pPed->bBulletProof = false; + m_pPed->bFireProof = false; + m_pPed->bCollisionProof = false; + m_pPed->bMeleeProof = false; + m_pPed->bOnlyDamagedByPlayer = false; + m_pPed->bExplosionProof = false; + m_pPed->m_bCanBeDamaged = true; + CWorld::SetAllCarsCanBeDamaged(true); + CReplay::EnableReplays(); + } +} + +void +CPlayerInfo::BlowUpRCBuggy(void) +{ + if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) + return; + + CRemote::TakeRemoteControlledCarFromPlayer(); + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); +} + +// There is something unfinished in here... Sadly all IDBs we have have it unfinished. +void +CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar) +{ + if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000) + ++m_nExplosionsSinceLastReward; + else + m_nExplosionsSinceLastReward = 1; + + m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds(); + int award = wreckedCar->pHandling->nMonetaryValue * 0.002f; + sprintf(gString, "$%d", award); +#ifdef MONEY_MESSAGES + // This line is a leftover from PS2, I don't know what it was meant to be. + // CVector sth(TheCamera.GetPosition() * 4.0f); + + CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f); +#endif + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + + for (int i = m_nExplosionsSinceLastReward; i > 1; --i) { + CGeneral::GetRandomNumber(); + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + } +} + +#ifdef GTA_PC +void +CPlayerInfo::SetPlayerSkin(const char *skin) +{ + strncpy(m_aSkinName, skin, 32); + LoadPlayerSkin(); +} + +void +CPlayerInfo::LoadPlayerSkin() +{ + DeletePlayerSkin(); + + m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); + if (!m_pSkinTexture) + m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME); +} + +void +CPlayerInfo::DeletePlayerSkin() +{ + if (m_pSkinTexture) { + RwTextureDestroy(m_pSkinTexture); + m_pSkinTexture = nil; + } +} +#endif \ No newline at end of file diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 94410753..49424b8b 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -54,14 +54,13 @@ public: bool m_bFastReload; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; +#ifdef GTA_PC char m_aSkinName[32]; RwTexture *m_pSkinTexture; +#endif void MakePlayerSafe(bool); - void LoadPlayerSkin(); - void DeletePlayerSkin(); void AwardMoneyForExplosion(CVehicle *vehicle); - void SetPlayerSkin(char* skin); const CVector &GetPos(); void Process(void); void KillPlayer(void); @@ -78,7 +77,21 @@ public: void SavePlayerInfo(uint8 *buf, uint32* size); void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**); - ~CPlayerInfo() { }; +#ifdef GTA_PC + void LoadPlayerSkin(); + void SetPlayerSkin(const char *skin); + void DeletePlayerSkin(); +#endif }; +CPlayerPed *FindPlayerPed(void); +CVehicle *FindPlayerVehicle(void); +CVehicle *FindPlayerTrain(void); +CEntity *FindPlayerEntity(void); +CVector FindPlayerCoors(void); +const CVector &FindPlayerSpeed(void); +const CVector &FindPlayerCentreOfWorld(int32 player); +const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); +float FindPlayerHeading(void); + VALIDATE_SIZE(CPlayerInfo, 0x13C); diff --git a/src/core/World.cpp b/src/core/World.cpp index a7531c83..b2c1696c 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -1361,102 +1361,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec } } -CPlayerPed * -FindPlayerPed(void) -{ - return CWorld::Players[CWorld::PlayerInFocus].m_pPed; -} - -CVehicle * -FindPlayerVehicle(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped && ped->InVehicle()) return ped->m_pMyVehicle; - return nil; -} - -CVehicle * -FindPlayerTrain(void) -{ - if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) - return FindPlayerVehicle(); - else - return nil; -} - -CEntity * -FindPlayerEntity(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle; - else - return ped; -} - -CVector -FindPlayerCoors(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) - return TheCamera.GetPosition(); -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->GetPosition(); - else - return ped->GetPosition(); -} - -CVector & -FindPlayerSpeed(void) -{ -#ifdef FIX_BUGS - static CVector vecTmpVector(0.0f, 0.0f, 0.0f); - if (CReplay::IsPlayingBack()) - return vecTmpVector; -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->m_vecMoveSpeed; - else - return ped->m_vecMoveSpeed; -} - -const CVector & -FindPlayerCentreOfWorld(int32 player) -{ -#ifdef FIX_BUGS - if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return CWorld::Players[player].m_pPed->GetPosition(); -} - -const CVector & -FindPlayerCentreOfWorld_NoSniperShift(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return FindPlayerPed()->GetPosition(); -} - -float -FindPlayerHeading(void) -{ - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); - return FindPlayerPed()->GetForward().Heading(); -} - void CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2) { diff --git a/src/core/World.h b/src/core/World.h index 197f3cee..9d62e79b 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -157,14 +157,3 @@ public: extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -class CPlayerPed; -class CVehicle; -CPlayerPed *FindPlayerPed(void); -CVehicle *FindPlayerVehicle(void); -CVehicle *FindPlayerTrain(void); -CEntity *FindPlayerEntity(void); -CVector FindPlayerCoors(void); -CVector &FindPlayerSpeed(void); -const CVector &FindPlayerCentreOfWorld(int32 player); -const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); -float FindPlayerHeading(void); diff --git a/src/extras/screendroplets.cpp b/src/extras/screendroplets.cpp index 2d34cdcb..3f91a754 100644 --- a/src/extras/screendroplets.cpp +++ b/src/extras/screendroplets.cpp @@ -384,9 +384,9 @@ ScreenDroplets::ProcessCameraMovement(void) ms_prevCamUp = camUp; ms_prevCamPos = camPos; - ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, (RwV3d*)&ms_camMoveDelta); - ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, (RwV3d*)&ms_camMoveDelta); - ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, (RwV3d*)&ms_camMoveDelta); + ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, &ms_camMoveDelta); + ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, &ms_camMoveDelta); + ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, &ms_camMoveDelta); ms_screenMoveDelta *= 10.0f; ms_screenMoveDist = ms_screenMoveDelta.Magnitude2D(); diff --git a/src/math/Vector.h b/src/math/Vector.h index 082b296f..776bfcfe 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -1,23 +1,22 @@ #pragma once -class CVector +class CVector : public RwV3d { public: - float x, y, z; CVector(void) {} - CVector(float x, float y, float z) : x(x), y(y), z(z) {} -#ifdef RWCORE_H - CVector(const RwV3d &v) : x(v.x), y(v.y), z(v.z) {} + CVector(float x, float y, float z) + { + this->x = x; + this->y = y; + this->z = z; + } - operator RwV3d (void) const { - RwV3d vecRw = { this->x, this->y, this->z }; - return vecRw; + CVector(const RwV3d &v) + { + x = v.x; + y = v.y; + z = v.z; } - - operator RwV3d *(void) { - return (RwV3d*)this; - } -#endif // (0,1,0) means no rotation. So get right vector and its atan float Heading(void) const { return Atan2(-x, y); } float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); } diff --git a/src/math/VuVector.h b/src/math/VuVector.h index f90818e0..30d62cfc 100644 --- a/src/math/VuVector.h +++ b/src/math/VuVector.h @@ -8,18 +8,7 @@ public: CVuVector(float x, float y, float z) : CVector(x, y, z) {} CVuVector(float x, float y, float z, float w) : CVector(x, y, z), w(w) {} CVuVector(const CVector &v) : CVector(v.x, v.y, v.z) {} -#ifdef RWCORE_H - CVuVector(const RwV3d &v) : CVector(v.x, v.y, v.z) {} - - operator RwV3d (void) const { - RwV3d vecRw = { this->x, this->y, this->z }; - return vecRw; - } - - operator RwV3d *(void) { - return (RwV3d*)this; - } -#endif + CVuVector(const RwV3d &v) : CVector(v) {} /* void Normalise(void) { float sq = MagnitudeSqr(); diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index 17754211..cc2a7e34 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -471,7 +471,7 @@ CVehicleModelInfo::PreprocessHierarchy(void) if(desc[i].flags & VEHICLE_FLAG_POS){ f = assoc.frame; - rwvec = (RwV3d*)&m_positions[desc[i].hierId]; + rwvec = &m_positions[desc[i].hierId]; *rwvec = *RwMatrixGetPos(RwFrameGetMatrix(f)); for(f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) RwV3dTransformPoints(rwvec, rwvec, 1, RwFrameGetMatrix(f)); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index b2888082..e518fae4 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -244,7 +244,7 @@ CCopPed::ArrestPlayer(void) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ARREST_GUN, 4.0f); CVector suspMidPos; - suspect->m_pedIK.GetComponentPosition((RwV3d*)suspMidPos, PED_MID); + suspect->m_pedIK.GetComponentPosition(suspMidPos, PED_MID); m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(suspMidPos.x, suspMidPos.y, GetPosition().x, GetPosition().y); diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 65aa97ef..9f87c12b 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -234,8 +234,8 @@ CEmergencyPed::MedicAI(void) if (nearestAccident) { m_pRevivedPed = nearestAccident->m_pVictim; m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); SetSeek((headPos + midPos) * 0.5f, 1.0f); SetObjective(OBJECTIVE_NONE); bIsRunning = true; @@ -274,8 +274,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_STOP; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); SetSeek((headPos + midPos) * 0.5f, nearestAccident->m_nMedicsPerformingCPR * 0.5f + 1.0f); SetObjective(OBJECTIVE_NONE); bIsRunning = true; @@ -329,8 +329,8 @@ CEmergencyPed::MedicAI(void) if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; else { - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, @@ -351,8 +351,8 @@ CEmergencyPed::MedicAI(void) m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE; break; } - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID); - m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD); + m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID); + m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD); midPos = (headPos + midPos) * 0.5f; m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( midPos.x, midPos.y, diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 5e1911ec..df78902f 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -960,7 +960,7 @@ CPed::MoveHeadToLook(void) } if (m_pLookTarget->IsPed()) { - ((CPed*)m_pLookTarget)->m_pedIK.GetComponentPosition((RwV3d*) &lookPos, PED_MID); + ((CPed*)m_pLookTarget)->m_pedIK.GetComponentPosition(lookPos, PED_MID); } else { lookPos = m_pLookTarget->GetPosition(); } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 0e398b25..d27853d6 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -898,13 +898,13 @@ public: RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID); RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); - RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, &mats[idx]); + RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]); }else #endif { RwFrame *frame; for (frame = m_pFrames[node]->frame; frame; frame = RwFrameGetParent(frame)) - RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, RwFrameGetMatrix(frame)); + RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(frame)); } } diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index d4385385..a747c684 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -1141,7 +1141,7 @@ CPed::ProcessObjective(void) CVector target; CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); if (m_pedInObjective->IsPed()) - m_pedInObjective->m_pedIK.GetComponentPosition((RwV3d*)&target, PED_MID); + m_pedInObjective->m_pedIK.GetComponentPosition(target, PED_MID); else target = m_pedInObjective->GetPosition(); diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index b4be0954..b57364d8 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -1690,7 +1690,7 @@ CPed::FightStrike(CVector &touchedNodePos) if (m_fightState == FIGHTSTATE_NO_MOVE) m_fightState = FIGHTSTATE_1; - m_vecHitLastPos = *touchedNodePos; + m_vecHitLastPos = touchedNodePos; return false; } diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp index ebd41296..8bace9a0 100644 --- a/src/peds/PedIK.cpp +++ b/src/peds/PedIK.cpp @@ -137,28 +137,28 @@ CPedIK::RotateTorso(AnimBlendFrameData *node, LimbOrientation *limb, bool change } void -CPedIK::GetComponentPosition(RwV3d *pos, uint32 node) +CPedIK::GetComponentPosition(RwV3d &pos, uint32 node) { RwFrame *f; RwMatrix *mat; #ifdef PED_SKIN if(IsClumpSkinned(m_ped->GetClump())){ - pos->x = 0.0f; - pos->y = 0.0f; - pos->z = 0.0f; + pos.x = 0.0f; + pos.y = 0.0f; + pos.z = 0.0f; mat = GetComponentMatrix(m_ped, node); // could just copy the position out of the matrix... - RwV3dTransformPoints(pos, pos, 1, mat); + RwV3dTransformPoints(&pos, &pos, 1, mat); }else #endif { f = m_ped->m_pFrames[node]->frame; mat = RwFrameGetMatrix(f); - *pos = mat->pos; + pos = mat->pos; for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) - RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(f)); + RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(f)); } } diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h index e91d7c06..4eeef6f0 100644 --- a/src/peds/PedIK.h +++ b/src/peds/PedIK.h @@ -51,7 +51,7 @@ public: bool PointGunInDirection(float targetYaw, float targetPitch); bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch); bool PointGunAtPosition(CVector const& position); - void GetComponentPosition(RwV3d *pos, uint32 node); + void GetComponentPosition(RwV3d &pos, uint32 node); static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination); void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 86d8e9f5..8a6adbeb 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -1146,7 +1146,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) #else CVector markPos; if (m_pPointGunAt->IsPed()) { - ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID); + ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(markPos, PED_MID); } else { markPos = m_pPointGunAt->GetPosition(); } diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index 161418b9..b5af6619 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -133,7 +133,7 @@ CClouds::Render(void) CSprite::InitSpriteBuffer(); int minute = CClock::GetHours()*60 + CClock::GetMinutes(); - RwV3d campos = *(RwV3d*)&TheCamera.GetPosition(); + RwV3d campos = TheCamera.GetPosition(); // Moon int moonfadeout = Abs(minute - 180); // fully visible at 3AM diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp index 33c3f4bf..48f0f6b9 100644 --- a/src/render/Coronas.cpp +++ b/src/render/Coronas.cpp @@ -255,7 +255,7 @@ CCoronas::Render(void) CVector spriteCoors; float spritew, spriteh; - if(!CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){ + if(!CSprite::CalcScreenCoors(aCoronas[i].coors, &spriteCoors, &spritew, &spriteh, true)){ aCoronas[i].offScreen = true; aCoronas[i].sightClear = false; }else{ @@ -464,7 +464,7 @@ CCoronas::RenderReflections(void) CVector spriteCoors; float spritew, spriteh; - if(CSprite::CalcScreenCoors(coors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(coors, &spriteCoors, &spritew, &spriteh, true)){ float drawDist = 0.75f * aCoronas[i].drawDist; drawDist = Min(drawDist, 55.0f); if(spriteCoors.z < drawDist){ @@ -531,7 +531,7 @@ CCoronas::DoSunAndMoon(void) CVector spriteCoors; float spritew, spriteh; - if(CSprite::CalcScreenCoors(sunCoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(sunCoors, &spriteCoors, &spritew, &spriteh, true)){ SunScreenX = spriteCoors.x; SunScreenY = spriteCoors.y; }else{ diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 690a1d3f..c76d6109 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -655,7 +655,7 @@ void CScrollBar::Render() RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); CVector coronaCoord, screenCoord; - float screenW, screenH; + float screenW, screenH; for (int i = 1; i < ARRAY_SIZE(m_MessageBar); ++i) { for (int j = 0; j < 5; ++j) @@ -667,7 +667,7 @@ void CScrollBar::Render() // Render main coronas if (m_MessageBar[i] & (1 << j)) { - if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true)) + if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true)) { CSprite::RenderBufferedOneXLUSprite( screenCoord.x, screenCoord.y, screenCoord.z, @@ -679,7 +679,7 @@ void CScrollBar::Render() // Render smaller and faded coronas for a trailing effect else if (m_MessageBar[i - 1] & (1 << j)) { - if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true)) + if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true)) { CSprite::RenderBufferedOneXLUSprite( screenCoord.x, screenCoord.y, screenCoord.z, @@ -834,7 +834,7 @@ void CDigitalClock::Render() const char* clockMessage = FindDigitalClockMessage(); CVector coronaCoord, screenCoord; - float screenW, screenH; + float screenW, screenH; for (int c = 0; c < 5; ++c) // for each char to be displayed { for (int i = 0; i < 5; ++i) // for each column of coronas @@ -847,7 +847,7 @@ void CDigitalClock::Render() coronaCoord.y = m_Position.y + (8 * c + i) * m_Size.y * m_fScale / 8.0f; coronaCoord.z = m_Position.z + j * m_fScale / 8.0f; - if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true)) + if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true)) { CSprite::RenderBufferedOneXLUSprite( screenCoord.x, screenCoord.y, screenCoord.z, diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index 2b19486e..f175c264 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -1570,7 +1570,7 @@ void CParticle::Render() float w; float h; - if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) ) + if ( CSprite::CalcScreenCoors(particle->m_vecPosition, &coors, &w, &h, true) ) { #ifdef PC_PARTICLE if ( (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w) @@ -1650,7 +1650,7 @@ void CParticle::Render() float fRotation; float fTrailLength; - if ( CSprite::CalcScreenCoors(vecPrevPos, particle->m_vecScreenPosition, &fTrailLength, &fRotation, true) ) + if ( CSprite::CalcScreenCoors(vecPrevPos, &particle->m_vecScreenPosition, &fTrailLength, &fRotation, true) ) { CVector2D vecDist ( diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp index 0713dc6d..6f0b4d46 100644 --- a/src/render/PointLights.cpp +++ b/src/render/PointLights.cpp @@ -218,7 +218,7 @@ CPointLights::RenderFogEffect(void) // more intensity the closer to line intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH); - if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){ float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000; float size = FogSizes[r>>1]; CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, @@ -267,7 +267,7 @@ CPointLights::RenderFogEffect(void) intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS); CVector fogcoors(xi, yi, point.point.z + 1.6f); - if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ + if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){ float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000; float size = FogSizes[r>>1]; CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index a0f66819..d47cac31 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -741,7 +741,7 @@ CRenderer::ScanWorld(void) vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix); + RwV3dTransformPoints(vectors, vectors, 9, cammatrix); m_loadingPriority = false; if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || @@ -881,7 +881,7 @@ CRenderer::RequestObjectsInFrustum(void) vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix); + RwV3dTransformPoints(vectors, vectors, 9, cammatrix); if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || #ifdef FIX_BUGS diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index f16467b6..e765f306 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -359,7 +359,7 @@ void CWeather::AddRain() RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); - RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); + RwV3dTransformPoints(splash_points, splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4; for (int i = 0; i < num_splash_attempts; i++) { CColPoint point; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index dc15485e..a987a4c7 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -385,7 +385,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() ) { CVector victimPedPos = victimPed->GetPosition(); - if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() ) + if ( SQR(victimPedRadius) > (victimPedPos-fireSource).MagnitudeSqr() ) { CVector collisionDist; @@ -393,7 +393,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) while ( s < victimPedCol->numSpheres ) { CColSphere *sphere = &victimPedCol->spheres[s]; - collisionDist = victimPedPos+sphere->center-(*fireSource); + collisionDist = victimPedPos+sphere->center-fireSource; if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() ) { From a080fbfbd41ac8a2bc6cfe053d4fa0932dd8d334 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 18 Dec 2020 13:58:59 +0100 Subject: [PATCH 51/52] little cleanup of templates --- src/core/FileLoader.cpp | 4 +-- src/core/templates.h | 49 ++++++++++++++++++------------------ src/modelinfo/ModelInfo.cpp | 50 ++++++++++++++++++------------------- 3 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index b9d475b8..0ad03f61 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -1065,7 +1065,7 @@ CFileLoader::LoadMLOInstance(int id, const char *line) &rot.x, &rot.y, &rot.z, &angle); float rad = Acos(angle) * 2.0f; - CInstance *inst = CModelInfo::GetMloInstanceStore().alloc(); + CInstance *inst = CModelInfo::GetMloInstanceStore().Alloc(); minfo->lastInstance++; RwMatrix *matrix = RwMatrixCreate(); @@ -1305,7 +1305,7 @@ CFileLoader::Load2dEffect(const char *line) CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); mi = CModelInfo::GetModelInfo(id); - effect = CModelInfo::Get2dEffectStore().alloc(); + effect = CModelInfo::Get2dEffectStore().Alloc(); mi->Add2dEffect(effect); effect->pos = CVector(x, y, z); effect->col = CRGBA(r, g, b, a); diff --git a/src/core/templates.h b/src/core/templates.h index 166f865c..3a5b314f 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -1,31 +1,31 @@ #pragma once -template +template class CStore { public: - int allocPtr; + int32 allocPtr; T store[n]; - T *alloc(void){ - if(this->allocPtr >= n){ + T *Alloc(void){ + if(allocPtr >= n){ printf("Size of this thing:%d needs increasing\n", n); assert(0); } - return &this->store[this->allocPtr++]; + return &store[allocPtr++]; } - void clear(void){ - this->allocPtr = 0; + void Clear(void){ + allocPtr = 0; } - int getIndex(T *item){ - assert(item >= &this->store[0]); - assert(item < &this->store[n]); - return item - this->store; + int32 GetIndex(T *item){ + assert(item >= &store[0]); + assert(item < &store[n]); + return item - store; } - T *getItem(int index){ + T *GetItem(int32 index){ assert(index >= 0); assert(index < n); - return &this->store[index]; + return &store[index]; } }; @@ -40,12 +40,11 @@ class CPool }; uint8 u; } *m_flags; - int m_size; - int m_allocPtr; + int32 m_size; + int32 m_allocPtr; public: - CPool(int size){ - // TODO: use new here + CPool(int32 size){ m_entries = (U*)new uint8[sizeof(U)*size]; m_flags = (Flags*)new uint8[sizeof(Flags)*size]; m_size = size; @@ -69,7 +68,7 @@ public: m_allocPtr = 0; } } - int GetSize(void) const { return m_size; } + int32 GetSize(void) const { return m_size; } T *New(void){ bool wrapped = false; do @@ -93,12 +92,12 @@ public: m_flags[m_allocPtr].id++; return (T*)&m_entries[m_allocPtr]; } - T *New(int handle){ + T *New(int32 handle){ T *entry = (T*)&m_entries[handle>>8]; SetNotFreeAt(handle); return entry; } - void SetNotFreeAt(int handle){ + void SetNotFreeAt(int32 handle){ int idx = handle>>8; m_flags[idx].free = 0; m_flags[idx].id = handle & 0x7F; @@ -123,21 +122,21 @@ public: return m_flags[handle>>8].u == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } - int GetIndex(T *entry){ + int32 GetIndex(T *entry){ int i = GetJustIndex_NoFreeAssert(entry); return m_flags[i].u + (i<<8); } - int GetJustIndex(T *entry){ + int32 GetJustIndex(T *entry){ int index = GetJustIndex_NoFreeAssert(entry); assert(!IsFreeSlot(index)); return index; } - int GetJustIndex_NoFreeAssert(T* entry){ + int32 GetJustIndex_NoFreeAssert(T* entry){ int index = ((U*)entry - m_entries); assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required return index; } - int GetNoOfUsedSpaces(void) const{ + int32 GetNoOfUsedSpaces(void) const{ int i; int n = 0; for(i = 0; i < m_size; i++) @@ -241,7 +240,7 @@ public: link->Remove(); // remove from list freeHead.Insert(link); // insert into free list } - int Count(void){ + int32 Count(void){ int n = 0; CLink *lnk; for(lnk = head.next; lnk != &tail; lnk = lnk->next) diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index 4ee8e72b..dcde0df3 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -26,15 +26,15 @@ CModelInfo::Initialise(void) for(i = 0; i < MODELINFOSIZE; i++) ms_modelInfoPtrs[i] = nil; - ms_2dEffectStore.clear(); - ms_mloInstanceStore.clear(); - ms_xtraCompsModelStore.clear(); - ms_simpleModelStore.clear(); - ms_timeModelStore.clear(); - ms_mloModelStore.clear(); - ms_clumpModelStore.clear(); - ms_pedModelStore.clear(); - ms_vehicleModelStore.clear(); + ms_2dEffectStore.Clear(); + ms_mloInstanceStore.Clear(); + ms_xtraCompsModelStore.Clear(); + ms_simpleModelStore.Clear(); + ms_timeModelStore.Clear(); + ms_mloModelStore.Clear(); + ms_clumpModelStore.Clear(); + ms_pedModelStore.Clear(); + ms_vehicleModelStore.Clear(); m = AddSimpleModel(MI_CAR_DOOR); m->SetColModel(&CTempColModels::ms_colModelDoor1); @@ -108,22 +108,22 @@ CModelInfo::ShutDown(void) for(i = 0; i < ms_2dEffectStore.allocPtr; i++) ms_2dEffectStore.store[i].Shutdown(); - ms_2dEffectStore.clear(); - ms_simpleModelStore.clear(); - ms_mloInstanceStore.clear(); - ms_mloModelStore.clear(); - ms_xtraCompsModelStore.clear(); - ms_timeModelStore.clear(); - ms_pedModelStore.clear(); - ms_clumpModelStore.clear(); - ms_vehicleModelStore.clear(); + ms_2dEffectStore.Clear(); + ms_simpleModelStore.Clear(); + ms_mloInstanceStore.Clear(); + ms_mloModelStore.Clear(); + ms_xtraCompsModelStore.Clear(); + ms_timeModelStore.Clear(); + ms_pedModelStore.Clear(); + ms_clumpModelStore.Clear(); + ms_vehicleModelStore.Clear(); } CSimpleModelInfo* CModelInfo::AddSimpleModel(int id) { CSimpleModelInfo *modelinfo; - modelinfo = CModelInfo::ms_simpleModelStore.alloc(); + modelinfo = CModelInfo::ms_simpleModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->Init(); return modelinfo; @@ -133,7 +133,7 @@ CMloModelInfo * CModelInfo::AddMloModel(int id) { CMloModelInfo *modelinfo; - modelinfo = CModelInfo::ms_mloModelStore.alloc(); + modelinfo = CModelInfo::ms_mloModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; modelinfo->firstInstance = 0; @@ -145,7 +145,7 @@ CTimeModelInfo* CModelInfo::AddTimeModel(int id) { CTimeModelInfo *modelinfo; - modelinfo = CModelInfo::ms_timeModelStore.alloc(); + modelinfo = CModelInfo::ms_timeModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->Init(); return modelinfo; @@ -155,7 +155,7 @@ CClumpModelInfo* CModelInfo::AddClumpModel(int id) { CClumpModelInfo *modelinfo; - modelinfo = CModelInfo::ms_clumpModelStore.alloc(); + modelinfo = CModelInfo::ms_clumpModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; return modelinfo; @@ -165,7 +165,7 @@ CPedModelInfo* CModelInfo::AddPedModel(int id) { CPedModelInfo *modelinfo; - modelinfo = CModelInfo::ms_pedModelStore.alloc(); + modelinfo = CModelInfo::ms_pedModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; return modelinfo; @@ -175,7 +175,7 @@ CVehicleModelInfo* CModelInfo::AddVehicleModel(int id) { CVehicleModelInfo *modelinfo; - modelinfo = CModelInfo::ms_vehicleModelStore.alloc(); + modelinfo = CModelInfo::ms_vehicleModelStore.Alloc(); CModelInfo::ms_modelInfoPtrs[id] = modelinfo; modelinfo->m_clump = nil; modelinfo->m_vehicleType = -1; @@ -245,7 +245,7 @@ CModelInfo::ConstructMloClumps() void CModelInfo::ReInit2dEffects() { - ms_2dEffectStore.clear(); + ms_2dEffectStore.Clear(); for (int i = 0; i < MODELINFOSIZE; i++) { if (ms_modelInfoPtrs[i]) From df5bafc80c544382b3def3925e50cf2ad3382a03 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 18 Dec 2020 23:47:38 +0100 Subject: [PATCH 52/52] anim fixes --- src/animation/AnimBlendHierarchy.cpp | 3 +- src/animation/AnimBlendHierarchy.h | 2 +- src/animation/AnimBlendSequence.cpp | 3 +- src/animation/AnimManager.cpp | 73 +++++++++++++++------------- src/animation/RpAnimBlend.cpp | 3 +- src/math/Quaternion.h | 5 ++ 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp index c7800de5..ea669999 100644 --- a/src/animation/AnimBlendHierarchy.cpp +++ b/src/animation/AnimBlendHierarchy.cpp @@ -52,8 +52,7 @@ CAnimBlendHierarchy::RemoveQuaternionFlips(void) void CAnimBlendHierarchy::RemoveAnimSequences(void) { - if(sequences) - delete[] sequences; + delete[] sequences; numSequences = 0; } diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h index e35b4925..40d2731b 100644 --- a/src/animation/AnimBlendHierarchy.h +++ b/src/animation/AnimBlendHierarchy.h @@ -15,7 +15,7 @@ public: char name[24]; CAnimBlendSequence *sequences; int16 numSequences; - int16 compressed; // not really used + int16 compressed; float totalLength; CLink *linkPtr; diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp index c958b71a..2ae150c1 100644 --- a/src/animation/AnimBlendSequence.cpp +++ b/src/animation/AnimBlendSequence.cpp @@ -16,9 +16,10 @@ CAnimBlendSequence::CAnimBlendSequence(void) CAnimBlendSequence::~CAnimBlendSequence(void) { - assert(keyFramesCompressed == nil); if(keyFrames) RwFree(keyFrames); + if(keyFramesCompressed) + RwFree(keyFramesCompressed); } void diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index 877dcd76..e701018e 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -841,54 +841,57 @@ CAnimManager::LoadAnimFile(int fd, bool compress) ROUNDSIZE(anim.size); CFileMgr::Read(fd, buf, anim.size); int numFrames = *(int*)(buf+28); + seq->SetName(buf); #ifdef PED_SKIN if(anim.size == 44) seq->SetBoneTag(*(int*)(buf+40)); #endif - seq->SetName(buf); if(numFrames == 0) continue; + bool hasScale = false; + bool hasTranslation = false; CFileMgr::Read(fd, (char*)&info, sizeof(info)); - if(strncmp(info.ident, "KR00", 4) == 0){ - seq->SetNumFrames(numFrames, false); - KeyFrame *kf = seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ - CFileMgr::Read(fd, buf, 0x14); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->deltaTime = fbuf[4]; // absolute time here - } + if(strncmp(info.ident, "KRTS", 4) == 0){ + hasScale = true; + seq->SetNumFrames(numFrames, true); }else if(strncmp(info.ident, "KRT0", 4) == 0){ + hasTranslation = true; seq->SetNumFrames(numFrames, true); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ - CFileMgr::Read(fd, buf, 0x20); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; - kf->deltaTime = fbuf[7]; // absolute time here - } - }else if(strncmp(info.ident, "KRTS", 4) == 0){ - seq->SetNumFrames(numFrames, true); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ + }else if(strncmp(info.ident, "KR00", 4) == 0){ + seq->SetNumFrames(numFrames, false); + } + + for(l = 0; l < numFrames; l++){ + if(hasScale){ CFileMgr::Read(fd, buf, 0x2C); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + CVector trans(fbuf[4], fbuf[5], fbuf[6]); + + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->translation = trans; // scaling ignored kf->deltaTime = fbuf[10]; // absolute time here + }else if(hasTranslation){ + CFileMgr::Read(fd, buf, 0x20); + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + CVector trans(fbuf[4], fbuf[5], fbuf[6]); + + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->translation = trans; + kf->deltaTime = fbuf[7]; // absolute time here + }else{ + CFileMgr::Read(fd, buf, 0x14); + CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); + rot.Invert(); + + KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l); + kf->rotation = rot; + kf->deltaTime = fbuf[4]; // absolute time here } } diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp index dcb656ee..e430e52a 100644 --- a/src/animation/RpAnimBlend.cpp +++ b/src/animation/RpAnimBlend.cpp @@ -8,6 +8,7 @@ #include "AnimBlendClumpData.h" #include "AnimBlendHierarchy.h" #include "AnimBlendAssociation.h" +#include "AnimManager.h" #include "RpAnimBlend.h" #ifdef PED_SKIN #include "PedModelInfo.h" @@ -441,7 +442,7 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta) next = link->next; CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link); if(assoc->UpdateBlend(timeDelta)){ - // CAnimManager::UncompressAnimation(v6->hierarchy) + CAnimManager::UncompressAnimation(assoc->hierarchy); updateData.nodes[i++] = assoc->GetNode(0); if(assoc->flags & ASSOC_MOVEMENT){ totalLength += assoc->hierarchy->totalLength/assoc->speed * assoc->blendAmount; diff --git a/src/math/Quaternion.h b/src/math/Quaternion.h index a5a34626..47c94f7c 100644 --- a/src/math/Quaternion.h +++ b/src/math/Quaternion.h @@ -12,6 +12,11 @@ public: float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; } void Normalise(void); void Multiply(const CQuaternion &q1, const CQuaternion &q2); + void Invert(void){ // Conjugate would have been a better name + x = -x; + y = -y; + z = -z; + } const CQuaternion &operator+=(CQuaternion const &right) { x += right.x;