summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2020-04-26 21:03:15 +0200
committerSergeanur <s.anureev@yandex.ua>2020-04-26 21:03:15 +0200
commitf0890b11122291a22d6a65f349281cf1aed49bd0 (patch)
tree3b418b522c5fd097abac916693e59808ea4f5b4f /src
parentMore japanese (diff)
parentRemove little hack (diff)
downloadre3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar.gz
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar.bz2
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar.lz
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar.xz
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.tar.zst
re3-f0890b11122291a22d6a65f349281cf1aed49bd0.zip
Diffstat (limited to '')
-rw-r--r--src/animation/AnimBlendAssocGroup.cpp29
-rw-r--r--src/animation/AnimBlendAssociation.cpp36
-rw-r--r--src/animation/AnimBlendClumpData.cpp19
-rw-r--r--src/animation/AnimBlendClumpData.h4
-rw-r--r--src/animation/AnimBlendHierarchy.cpp14
-rw-r--r--src/animation/AnimBlendNode.cpp12
-rw-r--r--src/animation/AnimBlendSequence.cpp8
-rw-r--r--src/animation/AnimManager.cpp40
-rw-r--r--src/animation/AnimManager.h192
-rw-r--r--src/animation/AnimationId.h180
-rw-r--r--src/animation/Bones.cpp52
-rw-r--r--src/animation/Bones.h24
-rw-r--r--src/animation/CutsceneMgr.cpp47
-rw-r--r--src/animation/CutsceneMgr.h27
-rw-r--r--src/animation/FrameUpdate.cpp251
-rw-r--r--src/animation/RpAnimBlend.cpp141
-rw-r--r--src/animation/RpAnimBlend.h9
-rw-r--r--src/audio/AudioCollision.cpp15
-rw-r--r--src/audio/AudioManager.cpp319
-rw-r--r--src/audio/AudioManager.h41
-rw-r--r--src/audio/AudioScriptObject.cpp9
-rw-r--r--src/audio/DMAudio.cpp58
-rw-r--r--src/audio/DMAudio.h4
-rw-r--r--src/audio/MusicManager.cpp49
-rw-r--r--src/audio/MusicManager.h2
-rw-r--r--src/audio/PoliceRadio.cpp44
-rw-r--r--src/audio/miles/sampman_mss.cpp2257
-rw-r--r--src/audio/miles/sampman_mss.h339
-rw-r--r--src/audio/openal/samp_oal.cpp1404
-rw-r--r--src/audio/openal/samp_oal.h340
-rw-r--r--src/audio/sampman.cpp2339
-rw-r--r--src/audio/sampman.h342
-rw-r--r--src/control/AutoPilot.cpp6
-rw-r--r--src/control/Bridge.cpp30
-rw-r--r--src/control/Bridge.h10
-rw-r--r--src/control/CarAI.cpp12
-rw-r--r--src/control/CarCtrl.cpp153
-rw-r--r--src/control/CarCtrl.h36
-rw-r--r--src/control/Curves.cpp2
-rw-r--r--src/control/Darkel.cpp60
-rw-r--r--src/control/Darkel.h35
-rw-r--r--src/control/GameLogic.cpp16
-rw-r--r--src/control/Garages.cpp142
-rw-r--r--src/control/Garages.h44
-rw-r--r--src/control/OnscreenTimer.cpp17
-rw-r--r--src/control/PathFind.cpp291
-rw-r--r--src/control/PathFind.h39
-rw-r--r--src/control/Phones.cpp38
-rw-r--r--src/control/Phones.h12
-rw-r--r--src/control/Pickups.cpp100
-rw-r--r--src/control/Pickups.h10
-rw-r--r--src/control/Record.cpp34
-rw-r--r--src/control/Record.h30
-rw-r--r--src/control/Remote.cpp7
-rw-r--r--src/control/Replay.cpp200
-rw-r--r--src/control/Replay.h129
-rw-r--r--src/control/Restart.cpp41
-rw-r--r--src/control/Restart.h32
-rw-r--r--src/control/RoadBlocks.cpp14
-rw-r--r--src/control/RoadBlocks.h6
-rw-r--r--src/control/SceneEdit.cpp1101
-rw-r--r--src/control/SceneEdit.h93
-rw-r--r--src/control/Script.cpp201
-rw-r--r--src/control/Script.h80
-rw-r--r--src/control/TrafficLights.cpp34
-rw-r--r--src/core/Accident.cpp14
-rw-r--r--src/core/Accident.h2
-rw-r--r--src/core/AnimViewer.cpp11
-rw-r--r--src/core/Cam.cpp129
-rw-r--r--src/core/Camera.cpp124
-rw-r--r--src/core/Camera.h10
-rw-r--r--src/core/CdStream.cpp25
-rw-r--r--src/core/Clock.cpp33
-rw-r--r--src/core/Clock.h18
-rw-r--r--src/core/Collision.cpp82
-rw-r--r--src/core/Collision.h11
-rw-r--r--src/core/ControllerConfig.cpp154
-rw-r--r--src/core/ControllerConfig.h28
-rw-r--r--src/core/Crime.h36
-rw-r--r--src/core/Debug.cpp37
-rw-r--r--src/core/Debug.h11
-rw-r--r--src/core/Directory.cpp23
-rw-r--r--src/core/Directory.h1
-rw-r--r--src/core/EventList.cpp14
-rw-r--r--src/core/EventList.h3
-rw-r--r--src/core/FileLoader.cpp42
-rw-r--r--src/core/FileMgr.cpp22
-rw-r--r--src/core/FileMgr.h4
-rw-r--r--src/core/Fire.cpp22
-rw-r--r--src/core/Fire.h2
-rw-r--r--src/core/Frontend.cpp300
-rw-r--r--src/core/Frontend.h25
-rw-r--r--src/core/Game.cpp64
-rw-r--r--src/core/Game.h21
-rw-r--r--src/core/General.h7
-rw-r--r--src/core/IniFile.cpp10
-rw-r--r--src/core/IniFile.h4
-rw-r--r--src/core/Instance.cpp20
-rw-r--r--src/core/MenuScreens.h7
-rw-r--r--src/core/Pad.cpp212
-rw-r--r--src/core/Pad.h23
-rw-r--r--src/core/Placeable.cpp20
-rw-r--r--src/core/PlayerInfo.cpp75
-rw-r--r--src/core/PlayerInfo.h12
-rw-r--r--src/core/Pools.cpp46
-rw-r--r--src/core/Pools.h18
-rw-r--r--src/core/Profile.cpp28
-rw-r--r--src/core/Radar.cpp102
-rw-r--r--src/core/Radar.h5
-rw-r--r--src/core/References.cpp21
-rw-r--r--src/core/References.h4
-rw-r--r--src/core/Stats.cpp124
-rw-r--r--src/core/Stats.h106
-rw-r--r--src/core/Streaming.cpp231
-rw-r--r--src/core/Streaming.h57
-rw-r--r--src/core/SurfaceTable.cpp11
-rw-r--r--src/core/SurfaceTable.h3
-rw-r--r--src/core/TempColModels.cpp74
-rw-r--r--src/core/TempColModels.h26
-rw-r--r--src/core/TimeStep.cpp6
-rw-r--r--src/core/TimeStep.h6
-rw-r--r--src/core/Timer.cpp59
-rw-r--r--src/core/Timer.h20
-rw-r--r--src/core/User.cpp28
-rw-r--r--src/core/User.h8
-rw-r--r--src/core/Wanted.cpp32
-rw-r--r--src/core/Wanted.h42
-rw-r--r--src/core/World.cpp2038
-rw-r--r--src/core/World.h64
-rw-r--r--src/core/ZoneCull.cpp46
-rw-r--r--src/core/ZoneCull.h28
-rw-r--r--src/core/Zones.cpp334
-rw-r--r--src/core/Zones.h22
-rw-r--r--src/core/common.h93
-rw-r--r--src/core/config.h19
-rw-r--r--src/core/debugmenu_public.h154
-rw-r--r--src/core/main.cpp70
-rw-r--r--src/core/main.h19
-rw-r--r--src/core/patcher.cpp3
-rw-r--r--src/core/re3.cpp152
-rw-r--r--src/core/timebars.cpp6
-rw-r--r--src/entities/Building.cpp17
-rw-r--r--src/entities/Dummy.cpp16
-rw-r--r--src/entities/Entity.cpp109
-rw-r--r--src/entities/Entity.h43
-rw-r--r--src/entities/Physical.cpp117
-rw-r--r--src/entities/Physical.h6
-rw-r--r--src/entities/Treadable.cpp12
-rw-r--r--src/extras/arrow.inc16
-rw-r--r--src/extras/cursor.inc16
-rw-r--r--src/extras/debugmenu.cpp1294
-rw-r--r--src/extras/debugmenu.h86
-rw-r--r--src/extras/inttypes.h216
-rw-r--r--src/fakerw/fake.cpp833
-rw-r--r--src/fakerw/rphanim.h64
-rw-r--r--src/fakerw/rpmatfx.h43
-rw-r--r--src/fakerw/rpskin.h26
-rw-r--r--src/fakerw/rpworld.h336
-rw-r--r--src/fakerw/rtbmp.h4
-rw-r--r--src/fakerw/rtcharse.h14
-rw-r--r--src/fakerw/rtquat.h15
-rw-r--r--src/fakerw/rwcore.h413
-rw-r--r--src/fakerw/rwplcore.h498
-rw-r--r--src/math/Quaternion.h12
-rw-r--r--src/math/Vector.h12
-rw-r--r--src/math/Vector2D.h7
-rw-r--r--src/math/math.cpp20
-rw-r--r--src/modelinfo/BaseModelInfo.cpp24
-rw-r--r--src/modelinfo/ClumpModelInfo.cpp101
-rw-r--r--src/modelinfo/MloModelInfo.cpp2
-rw-r--r--src/modelinfo/ModelIndices.cpp9
-rw-r--r--src/modelinfo/ModelIndices.h16
-rw-r--r--src/modelinfo/ModelInfo.cpp19
-rw-r--r--src/modelinfo/ModelInfo.h2
-rw-r--r--src/modelinfo/PedModelInfo.cpp174
-rw-r--r--src/modelinfo/PedModelInfo.h17
-rw-r--r--src/modelinfo/SimpleModelInfo.cpp27
-rw-r--r--src/modelinfo/TimeModelInfo.cpp6
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp78
-rw-r--r--src/modelinfo/VehicleModelInfo.h10
-rw-r--r--src/objects/CutsceneHead.cpp114
-rw-r--r--src/objects/CutsceneHead.h9
-rw-r--r--src/objects/CutsceneObject.cpp89
-rw-r--r--src/objects/CutsceneObject.h16
-rw-r--r--src/objects/DummyObject.cpp18
-rw-r--r--src/objects/Object.cpp50
-rw-r--r--src/objects/Object.h15
-rw-r--r--src/objects/ObjectData.cpp7
-rw-r--r--src/objects/ParticleObject.cpp194
-rw-r--r--src/objects/ParticleObject.h15
-rw-r--r--src/objects/Projectile.cpp16
-rw-r--r--src/peds/CivilianPed.cpp28
-rw-r--r--src/peds/CivilianPed.h2
-rw-r--r--src/peds/CopPed.cpp35
-rw-r--r--src/peds/CopPed.h19
-rw-r--r--src/peds/EmergencyPed.cpp19
-rw-r--r--src/peds/EmergencyPed.h7
-rw-r--r--src/peds/Gangs.cpp12
-rw-r--r--src/peds/Ped.cpp802
-rw-r--r--src/peds/Ped.h256
-rw-r--r--src/peds/PedIK.cpp447
-rw-r--r--src/peds/PedIK.h2
-rw-r--r--src/peds/PedPlacement.cpp9
-rw-r--r--src/peds/PedRoutes.cpp4
-rw-r--r--src/peds/PedStats.cpp10
-rw-r--r--src/peds/PedType.cpp13
-rw-r--r--src/peds/PedType.h2
-rw-r--r--src/peds/PlayerPed.cpp65
-rw-r--r--src/peds/PlayerPed.h13
-rw-r--r--src/peds/Population.cpp97
-rw-r--r--src/render/Antennas.cpp16
-rw-r--r--src/render/Clouds.cpp35
-rw-r--r--src/render/Clouds.h12
-rw-r--r--src/render/Console.cpp5
-rw-r--r--src/render/Console.h2
-rw-r--r--src/render/Coronas.cpp52
-rw-r--r--src/render/Coronas.h16
-rw-r--r--src/render/Credits.cpp16
-rw-r--r--src/render/Credits.h4
-rw-r--r--src/render/Draw.cpp25
-rw-r--r--src/render/Draw.h16
-rw-r--r--src/render/Fluff.cpp42
-rw-r--r--src/render/Fluff.h2
-rw-r--r--src/render/Font.cpp117
-rw-r--r--src/render/Font.h12
-rw-r--r--src/render/Glass.cpp55
-rw-r--r--src/render/Glass.h1
-rw-r--r--src/render/Hud.cpp125
-rw-r--r--src/render/Instance.cpp9
-rw-r--r--src/render/Instance.h (renamed from src/core/Instance.h)0
-rw-r--r--src/render/Lines.cpp2
-rw-r--r--src/render/MBlur.cpp16
-rw-r--r--src/render/MBlur.h6
-rw-r--r--src/render/Particle.cpp75
-rw-r--r--src/render/Particle.h13
-rw-r--r--src/render/ParticleMgr.cpp13
-rw-r--r--src/render/ParticleMgr.h84
-rw-r--r--src/render/ParticleType.h77
-rw-r--r--src/render/PlayerSkin.cpp11
-rw-r--r--src/render/PointLights.cpp17
-rw-r--r--src/render/PointLights.h4
-rw-r--r--src/render/RenderBuffer.cpp21
-rw-r--r--src/render/RenderBuffer.h12
-rw-r--r--src/render/Renderer.cpp58
-rw-r--r--src/render/Renderer.h16
-rw-r--r--src/render/Rubbish.cpp6
-rw-r--r--src/render/Shadows.cpp118
-rw-r--r--src/render/Shadows.h37
-rw-r--r--src/render/Skidmarks.cpp5
-rw-r--r--src/render/SpecialFX.cpp41
-rw-r--r--src/render/Sprite.cpp50
-rw-r--r--src/render/Sprite.h8
-rw-r--r--src/render/Sprite2d.cpp50
-rw-r--r--src/render/Sprite2d.h14
-rw-r--r--src/render/Timecycle.cpp203
-rw-r--r--src/render/Timecycle.h184
-rw-r--r--src/render/WaterCannon.cpp28
-rw-r--r--src/render/WaterCannon.h1
-rw-r--r--src/render/WaterLevel.cpp35
-rw-r--r--src/render/WaterLevel.h2
-rw-r--r--src/render/Weather.cpp58
-rw-r--r--src/render/Weather.h50
-rw-r--r--src/rw/ClumpRead.cpp14
-rw-r--r--src/rw/Lights.cpp77
-rw-r--r--src/rw/NodeName.cpp4
-rw-r--r--src/rw/RwHelper.cpp233
-rw-r--r--src/rw/RwHelper.h14
-rw-r--r--src/rw/RwMatFX.cpp13
-rw-r--r--src/rw/TexRead.cpp54
-rw-r--r--src/rw/TxdStore.cpp28
-rw-r--r--src/rw/TxdStore.h4
-rw-r--r--src/rw/VisibilityPlugins.cpp124
-rw-r--r--src/rw/VisibilityPlugins.h37
-rw-r--r--src/rw/rw.cpp839
-rw-r--r--src/save/GenericGameStorage.cpp87
-rw-r--r--src/save/GenericGameStorage.h32
-rw-r--r--src/save/PCSave.cpp25
-rw-r--r--src/save/PCSave.h2
-rw-r--r--src/skel/crossplatform.cpp81
-rw-r--r--src/skel/crossplatform.h114
-rw-r--r--src/skel/events.cpp22
-rw-r--r--src/skel/glfw/glfw.cpp1652
-rw-r--r--src/skel/skeleton.cpp30
-rw-r--r--src/skel/skeleton.h2
-rw-r--r--src/skel/win/win.cpp135
-rw-r--r--src/skel/win/win.h43
-rw-r--r--src/text/Messages.cpp41
-rw-r--r--src/text/Messages.h6
-rw-r--r--src/text/Pager.cpp18
-rw-r--r--src/text/Pager.h2
-rw-r--r--src/text/Text.cpp26
-rw-r--r--src/text/Text.h2
-rw-r--r--src/vehicles/Automobile.cpp220
-rw-r--r--src/vehicles/Automobile.h3
-rw-r--r--src/vehicles/Boat.cpp110
-rw-r--r--src/vehicles/Boat.h2
-rw-r--r--src/vehicles/CarGen.cpp11
-rw-r--r--src/vehicles/Cranes.cpp10
-rw-r--r--src/vehicles/DamageManager.cpp23
-rw-r--r--src/vehicles/Door.cpp18
-rw-r--r--src/vehicles/Floater.cpp16
-rw-r--r--src/vehicles/Floater.h2
-rw-r--r--src/vehicles/HandlingMgr.cpp12
-rw-r--r--src/vehicles/HandlingMgr.h6
-rw-r--r--src/vehicles/Heli.cpp192
-rw-r--r--src/vehicles/Heli.h13
-rw-r--r--src/vehicles/Plane.cpp93
-rw-r--r--src/vehicles/Plane.h8
-rw-r--r--src/vehicles/Train.cpp61
-rw-r--r--src/vehicles/Transmission.cpp7
-rw-r--r--src/vehicles/Vehicle.cpp85
-rw-r--r--src/vehicles/Vehicle.h15
-rw-r--r--src/weapons/BulletInfo.cpp268
-rw-r--r--src/weapons/BulletInfo.h18
-rw-r--r--src/weapons/Explosion.cpp19
-rw-r--r--src/weapons/Explosion.h2
-rw-r--r--src/weapons/ProjectileInfo.cpp19
-rw-r--r--src/weapons/ProjectileInfo.h11
-rw-r--r--src/weapons/ShotInfo.cpp15
-rw-r--r--src/weapons/ShotInfo.h3
-rw-r--r--src/weapons/Weapon.cpp2215
-rw-r--r--src/weapons/Weapon.h106
-rw-r--r--src/weapons/WeaponEffects.cpp (renamed from src/render/WeaponEffects.cpp)14
-rw-r--r--src/weapons/WeaponEffects.h (renamed from src/render/WeaponEffects.h)1
-rw-r--r--src/weapons/WeaponInfo.cpp14
-rw-r--r--src/weapons/WeaponInfo.h6
-rw-r--r--src/weapons/WeaponType.h49
327 files changed, 21953 insertions, 11932 deletions
diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp
index ecdebd29..bdcca2f8 100644
--- a/src/animation/AnimBlendAssocGroup.cpp
+++ b/src/animation/AnimBlendAssocGroup.cpp
@@ -1,5 +1,7 @@
#include "common.h"
-#include "patcher.h"
+
+#include "ctype.h"
+
#include "General.h"
#include "ModelInfo.h"
#include "AnimManager.h"
@@ -75,12 +77,21 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
c2 = *s2;
if(c1) s1++;
if(c2) s2++;
- if(c1 == '\0' && c2 == '\0')
- return true;
+ if(c1 == '\0' && c2 == '\0') return true;
+#if defined _WIN32 && !defined __MINGW32__
if(__ascii_iswdigit(c1) && __ascii_iswdigit(c2))
+#else
+ if(iswdigit(c1) && iswdigit(c2))
+#endif
continue;
+#if defined _WIN32 && !defined __MINGW32__
c1 = __ascii_toupper(c1);
c2 = __ascii_toupper(c2);
+#else
+ c1 = toupper(c1);
+ c2 = toupper(c2);
+#endif
+
if(c1 != c2)
return false;
}
@@ -148,15 +159,3 @@ CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump,
}
numAssociations = numAssocs;
}
-
-
-
-STARTPATCHES
- InjectHook(0x4012D0, &CAnimBlendAssocGroup::DestroyAssociations, PATCH_JUMP);
- InjectHook(0x4013D0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
- InjectHook(0x401300, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
- InjectHook(0x401420, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
- InjectHook(0x4013E0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
- InjectHook(0x401130, (void (CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
- InjectHook(0x401220, (void (CAnimBlendAssocGroup::*)(const char*, RpClump*, const char**, int))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp
index 246322ba..daca7d68 100644
--- a/src/animation/AnimBlendAssociation.cpp
+++ b/src/animation/AnimBlendAssociation.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendHierarchy.h"
#include "AnimBlendClumpData.h"
#include "RpAnimBlend.h"
@@ -185,7 +185,7 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
if(blendAmount <= 0.0f && blendDelta < 0.0f){
// We're faded out and are not fading in
blendAmount = 0.0f;
- blendDelta = max(0.0f, blendDelta);
+ blendDelta = Max(0.0f, blendDelta);
if(flags & ASSOC_DELETEFADEDOUT){
if(callbackType == CB_FINISH || callbackType == CB_DELETE)
callback(this, callbackArg);
@@ -197,38 +197,8 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
if(blendAmount > 1.0f){
// Maximally faded in, clamp values
blendAmount = 1.0f;
- blendDelta = min(0.0f, blendDelta);
+ blendDelta = Min(0.0f, blendDelta);
}
return true;
}
-
-#include <new>
-
-class CAnimBlendAssociation_ : public CAnimBlendAssociation
-{
-public:
- CAnimBlendAssociation *ctor1(void) { return ::new (this) CAnimBlendAssociation(); }
- CAnimBlendAssociation *ctor2(CAnimBlendAssociation &other) { return ::new (this) CAnimBlendAssociation(other); }
- void dtor(void) { this->CAnimBlendAssociation::~CAnimBlendAssociation(); }
-};
-
-STARTPATCHES
- InjectHook(0x4016A0, &CAnimBlendAssociation::AllocateAnimBlendNodeArray, PATCH_JUMP);
- InjectHook(0x4016F0, &CAnimBlendAssociation::FreeAnimBlendNodeArray, PATCH_JUMP);
- InjectHook(0x4017B0, &CAnimBlendAssociation::GetNode, PATCH_JUMP);
- InjectHook(0x401560, (void (CAnimBlendAssociation::*)(RpClump*, CAnimBlendHierarchy*))&CAnimBlendAssociation::Init, PATCH_JUMP);
- InjectHook(0x401620, (void (CAnimBlendAssociation::*)(CAnimBlendAssociation&))&CAnimBlendAssociation::Init, PATCH_JUMP);
- InjectHook(0x4017E0, &CAnimBlendAssociation::SetBlend, PATCH_JUMP);
- InjectHook(0x401820, &CAnimBlendAssociation::SetFinishCallback, PATCH_JUMP);
- InjectHook(0x401800, &CAnimBlendAssociation::SetDeleteCallback, PATCH_JUMP);
- InjectHook(0x401700, &CAnimBlendAssociation::SetCurrentTime, PATCH_JUMP);
- InjectHook(0x401780, &CAnimBlendAssociation::SyncAnimation, PATCH_JUMP);
- InjectHook(0x4017D0, &CAnimBlendAssociation::Start, PATCH_JUMP);
- InjectHook(0x4031F0, &CAnimBlendAssociation::UpdateTime, PATCH_JUMP);
- InjectHook(0x4032B0, &CAnimBlendAssociation::UpdateBlend, PATCH_JUMP);
-
- InjectHook(0x401460, &CAnimBlendAssociation_::ctor1, PATCH_JUMP);
- InjectHook(0x4014C0, &CAnimBlendAssociation_::ctor2, PATCH_JUMP);
- InjectHook(0x401520, &CAnimBlendAssociation_::dtor, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp
index cc4281d6..d40e8357 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendClumpData.h"
#include "RwHelper.h"
@@ -35,20 +35,3 @@ CAnimBlendClumpData::ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *
for(i = 0; i < numFrames; i++)
cb(&frames[i], arg);
}
-
-#include <new>
-
-class CAnimBlendClumpData_ : public CAnimBlendClumpData
-{
-public:
- CAnimBlendClumpData *ctor(void) { return ::new (this) CAnimBlendClumpData(); }
- void dtor(void) { this->CAnimBlendClumpData::~CAnimBlendClumpData(); }
-};
-
-
-STARTPATCHES
- InjectHook(0x401880, &CAnimBlendClumpData_::ctor, PATCH_JUMP);
- InjectHook(0x4018B0, &CAnimBlendClumpData_::dtor, PATCH_JUMP);
- InjectHook(0x4018F0, &CAnimBlendClumpData::SetNumberOfFrames, PATCH_JUMP);
- InjectHook(0x401930, &CAnimBlendClumpData::ForAllFrames, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 1c8c391d..a537425a 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -18,7 +18,7 @@ struct AnimBlendFrameData
#ifdef PED_SKIN
union {
RwFrame *frame;
- RpHAnimStdKeyFrame *hanimframe;
+ RpHAnimStdKeyFrame *hanimFrame;
};
int32 nodeID;
#else
@@ -50,4 +50,6 @@ public:
#endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
};
+#ifndef PED_SKIN
static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error");
+#endif
diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp
index e4bcdc69..feeaca3d 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendSequence.h"
#include "AnimBlendHierarchy.h"
@@ -36,7 +36,7 @@ CAnimBlendHierarchy::CalcTotalTime(void)
float seqTime = 0.0f;
for(j = 0; j < sequences[i].numFrames; j++)
seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
- totalTime = max(totalTime, seqTime);
+ totalTime = Max(totalTime, seqTime);
}
totalLength = totalTime;
}
@@ -72,13 +72,3 @@ CAnimBlendHierarchy::RemoveUncompressedData(void)
// useless
compressed = 1;
}
-
-STARTPATCHES
- InjectHook(0x4019A0, &CAnimBlendHierarchy::Shutdown, PATCH_JUMP);
- InjectHook(0x4019C0, &CAnimBlendHierarchy::SetName, PATCH_JUMP);
- InjectHook(0x4019E0, &CAnimBlendHierarchy::CalcTotalTime, PATCH_JUMP);
- InjectHook(0x401A80, &CAnimBlendHierarchy::RemoveQuaternionFlips, PATCH_JUMP);
- InjectHook(0x401AB0, &CAnimBlendHierarchy::RemoveAnimSequences, PATCH_JUMP);
- InjectHook(0x401AD0, &CAnimBlendHierarchy::Uncompress, PATCH_JUMP);
- InjectHook(0x401B00, &CAnimBlendHierarchy::RemoveUncompressedData, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp
index be5fcc9c..193e9176 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendAssociation.h"
#include "AnimBlendNode.h"
@@ -158,13 +158,3 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
trans = kf->translation * blend;
}
}
-
-STARTPATCHES
- InjectHook(0x401B10, &CAnimBlendNode::Init, PATCH_JUMP);
- InjectHook(0x401B30, &CAnimBlendNode::Update, PATCH_JUMP);
- InjectHook(0x401DC0, &CAnimBlendNode::NextKeyFrame, PATCH_JUMP);
- InjectHook(0x4021B0, &CAnimBlendNode::FindKeyFrame, PATCH_JUMP);
- InjectHook(0x401E70, &CAnimBlendNode::CalcDeltas, PATCH_JUMP);
- InjectHook(0x401FE0, &CAnimBlendNode::GetCurrentTranslation, PATCH_JUMP);
- InjectHook(0x402110, &CAnimBlendNode::GetEndTranslation, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index 4b675774..4578ec50 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendSequence.h"
CAnimBlendSequence::CAnimBlendSequence(void)
@@ -60,9 +60,3 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
last = frame->rotation;
}
}
-
-STARTPATCHES
- InjectHook(0x402330, &CAnimBlendSequence::SetName, PATCH_JUMP);
- InjectHook(0x402350, &CAnimBlendSequence::SetNumFrames, PATCH_JUMP);
- InjectHook(0x4023A0, &CAnimBlendSequence::RemoveQuaternionFlips, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp
index e5721bdf..ebd2e1fb 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -1,6 +1,7 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
+#include "RwHelper.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
#include "FileMgr.h"
@@ -10,12 +11,12 @@
#include "AnimBlendAssocGroup.h"
#include "AnimManager.h"
-CAnimBlock *CAnimManager::ms_aAnimBlocks = (CAnimBlock*)0x6F01A0;
-CAnimBlendHierarchy *CAnimManager::ms_aAnimations = (CAnimBlendHierarchy*)0x70F430;
-int32 &CAnimManager::ms_numAnimBlocks = *(int32*)0x885AF8;
-int32 &CAnimManager::ms_numAnimations = *(int32*)0x8E2DD4;
-CAnimBlendAssocGroup *&CAnimManager::ms_aAnimAssocGroups = *(CAnimBlendAssocGroup**)0x8F583C;
-CLinkList<CAnimBlendHierarchy*> &CAnimManager::ms_animCache = *(CLinkList<CAnimBlendHierarchy*>*)0x9414DC;
+CAnimBlock CAnimManager::ms_aAnimBlocks[2];
+CAnimBlendHierarchy CAnimManager::ms_aAnimations[250];
+int32 CAnimManager::ms_numAnimBlocks;
+int32 CAnimManager::ms_numAnimations;
+CAnimBlendAssocGroup *CAnimManager::ms_aAnimAssocGroups;
+CLinkList<CAnimBlendHierarchy*> CAnimManager::ms_animCache;
AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_FLAG80 },
@@ -754,6 +755,11 @@ CAnimManager::LoadAnimFiles(void)
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++)
group->GetAnimation(j)->flags |= def->animDescs[j].flags;
+#ifdef PED_SKIN
+ // forgot on xbox/android
+ if(IsClumpSkinned(clump))
+ RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
+#endif
RpClumpDestroy(clump);
}
}
@@ -909,23 +915,3 @@ CAnimManager::RemoveLastAnimFile(void)
for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++)
ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences();
}
-
-
-STARTPATCHES
- InjectHook(0x403380, CAnimManager::Initialise, PATCH_JUMP);
- InjectHook(0x4033B0, CAnimManager::Shutdown, PATCH_JUMP);
- InjectHook(0x403410, CAnimManager::UncompressAnimation, PATCH_JUMP);
- InjectHook(0x4034A0, CAnimManager::GetAnimationBlock, PATCH_JUMP);
- InjectHook(0x4034F0, (CAnimBlendHierarchy *(*)(const char*, CAnimBlock*))CAnimManager::GetAnimation, PATCH_JUMP);
- InjectHook(0x4035B0, CAnimManager::GetAnimGroupName, PATCH_JUMP);
- InjectHook(0x4035C0, CAnimManager::CreateAnimAssociation, PATCH_JUMP);
- InjectHook(0x4035E0, (CAnimBlendAssociation *(*)(AssocGroupId, AnimationId))CAnimManager::GetAnimAssociation, PATCH_JUMP);
- InjectHook(0x403600, (CAnimBlendAssociation *(*)(AssocGroupId, const char*))CAnimManager::GetAnimAssociation, PATCH_JUMP);
- InjectHook(0x403620, CAnimManager::AddAnimation, PATCH_JUMP);
- InjectHook(0x4036A0, CAnimManager::AddAnimationAndSync, PATCH_JUMP);
- InjectHook(0x403710, CAnimManager::BlendAnimation, PATCH_JUMP);
- InjectHook(0x4038F0, CAnimManager::LoadAnimFiles, PATCH_JUMP);
- InjectHook(0x403A10, (void (*)(const char *))CAnimManager::LoadAnimFile, PATCH_JUMP);
- InjectHook(0x403A40, (void (*)(int, bool))CAnimManager::LoadAnimFile, PATCH_JUMP);
- InjectHook(0x404320, CAnimManager::RemoveLastAnimFile, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h
index 0d4e17fe..1b333b60 100644
--- a/src/animation/AnimManager.h
+++ b/src/animation/AnimManager.h
@@ -1,6 +1,7 @@
#pragma once
#include "AnimBlendHierarchy.h"
+#include "AnimationId.h"
enum AssocGroupId
{
@@ -33,185 +34,6 @@ enum AssocGroupId
NUM_ANIM_ASSOC_GROUPS
};
-enum AnimationId
-{
- ANIM_WALK,
- ANIM_RUN,
- ANIM_SPRINT,
- ANIM_IDLE_STANCE,
- ANIM_WALK_START,
- ANIM_RUN_STOP,
- ANIM_RUN_STOP_R,
- ANIM_IDLE_CAM,
- ANIM_IDLE_HBHB,
- ANIM_IDLE_TIRED,
- ANIM_IDLE_ARMED,
- ANIM_IDLE_CHAT,
- ANIM_IDLE_TAXI,
- ANIM_KO_SHOT_FRONT1,
- ANIM_KO_SHOT_FRONT2,
- ANIM_KO_SHOT_FRONT3,
- ANIM_KO_SHOT_FRONT4,
- ANIM_KO_SHOT_FACE,
- ANIM_KO_SHOT_STOM,
- ANIM_KO_SHOT_ARML,
- ANIM_KO_SHOT_ARMR,
- ANIM_KO_SHOT_LEGL,
- ANIM_KO_SHOT_LEGR,
- ANIM_KD_LEFT,
- ANIM_KD_RIGHT,
- ANIM_KO_SKID_FRONT,
- ANIM_KO_SPIN_R, // named left in VC
- ANIM_KO_SKID_BACK,
- ANIM_KO_SPIN_L, // named right in VC
- ANIM_SHOT_FRONT_PARTIAL,
- ANIM_SHOT_LEFT_PARTIAL,
- ANIM_SHOT_BACK_PARTIAL,
- ANIM_SHOT_RIGHT_PARTIAL,
- ANIM_HIT_FRONT,
- ANIM_HIT_LEFT,
- ANIM_HIT_BACK,
- ANIM_HIT_RIGHT,
- ANIM_FLOOR_HIT,
- ANIM_HIT_BODYBLOW,
- ANIM_HIT_CHEST,
- ANIM_HIT_HEAD,
- ANIM_HIT_WALK,
- ANIM_HIT_WALL,
- ANIM_FLOOR_HIT_F,
- ANIM_HIT_BEHIND,
- ANIM_PUNCH_R,
- ANIM_KICK_FLOOR,
- ANIM_WEAPON_BAT_H,
- ANIM_WEAPON_BAT_V,
- ANIM_WEAPON_HGUN_BODY,
- ANIM_WEAPON_AK_BODY,
- ANIM_WEAPON_PUMP,
- ANIM_WEAPON_SNIPER,
- ANIM_WEAPON_THROW,
- ANIM_WEAPON_THROWU,
- ANIM_WEAPON_START_THROW,
- ANIM_BOMBER,
- ANIM_HGUN_RELOAD,
- ANIM_AK_RELOAD,
- ANIM_FPS_PUNCH,
- ANIM_FPS_BAT,
- ANIM_FPS_UZI,
- ANIM_FPS_PUMP,
- ANIM_FPS_AK,
- ANIM_FPS_M16,
- ANIM_FPS_ROCKET,
- ANIM_FIGHT_IDLE,
- ANIM_FIGHT2_IDLE,
- ANIM_FIGHT_SH_F,
- ANIM_FIGHT_BODYBLOW,
- ANIM_FIGHT_HEAD,
- ANIM_FIGHT_KICK,
- ANIM_FIGHT_KNEE,
- ANIM_FIGHT_LHOOK,
- ANIM_FIGHT_PUNCH,
- ANIM_FIGHT_ROUNDHOUSE,
- ANIM_FIGHT_LONGKICK,
- ANIM_FIGHT_PPUNCH,
- ANIM_CAR_JACKED_RHS,
- ANIM_CAR_LJACKED_RHS,
- ANIM_CAR_JACKED_LHS,
- ANIM_CAR_LJACKED_LHS,
- ANIM_CAR_QJACK,
- ANIM_CAR_QJACKED,
- ANIM_CAR_ALIGN_LHS,
- ANIM_CAR_ALIGNHI_LHS,
- ANIM_CAR_OPEN_LHS,
- ANIM_CAR_DOORLOCKED_LHS,
- ANIM_CAR_PULLOUT_LHS,
- ANIM_CAR_PULLOUT_LOW_LHS,
- ANIM_CAR_GETIN_LHS,
- ANIM_CAR_GETIN_LOW_LHS,
- ANIM_CAR_CLOSEDOOR_LHS,
- ANIM_CAR_CLOSEDOOR_LOW_LHS,
- ANIM_CAR_ROLLDOOR,
- ANIM_CAR_ROLLDOOR_LOW,
- ANIM_CAR_GETOUT_LHS,
- ANIM_CAR_GETOUT_LOW_LHS,
- ANIM_CAR_CLOSE_LHS,
- ANIM_CAR_ALIGN_RHS,
- ANIM_CAR_ALIGNHI_RHS,
- ANIM_CAR_OPEN_RHS,
- ANIM_CAR_DOORLOCKED_RHS,
- ANIM_CAR_PULLOUT_RHS,
- ANIM_CAR_PULLOUT_LOW_RHS,
- ANIM_CAR_GETIN_RHS,
- ANIM_CAR_GETIN_LOW_RHS,
- ANIM_CAR_CLOSEDOOR_RHS,
- ANIM_CAR_CLOSEDOOR_LOW_RHS,
- ANIM_CAR_SHUFFLE_RHS,
- ANIM_CAR_LSHUFFLE_RHS,
- ANIM_CAR_SIT,
- ANIM_CAR_LSIT,
- ANIM_CAR_SITP,
- ANIM_CAR_SITPLO,
- ANIM_DRIVE_L,
- ANIM_DRIVE_R,
- ANIM_DRIVE_LOW_L,
- ANIM_DRIVE_LOW_R,
- ANIM_DRIVEBY_L,
- ANIM_DRIVEBY_R,
- ANIM_CAR_LB,
- ANIM_DRIVE_BOAT,
- ANIM_CAR_GETOUT_RHS,
- ANIM_CAR_GETOUT_LOW_RHS,
- ANIM_CAR_CLOSE_RHS,
- ANIM_CAR_HOOKERTALK,
- ANIM_COACH_OPEN_L,
- ANIM_COACH_OPEN_R,
- ANIM_COACH_IN_L,
- ANIM_COACH_IN_R,
- ANIM_COACH_OUT_L,
- ANIM_TRAIN_GETIN,
- ANIM_TRAIN_GETOUT,
- ANIM_CAR_CRAWLOUT_RHS,
- ANIM_CAR_CRAWLOUT_RHS2,
- ANIM_VAN_OPEN_L,
- ANIM_VAN_GETIN_L,
- ANIM_VAN_CLOSE_L,
- ANIM_VAN_GETOUT_L,
- ANIM_VAN_OPEN,
- ANIM_VAN_GETIN,
- ANIM_VAN_CLOSE,
- ANIM_VAN_GETOUT,
- ANIM_GETUP1,
- ANIM_GETUP2,
- ANIM_GETUP3,
- ANIM_GETUP_FRONT,
- ANIM_JUMP_LAUNCH,
- ANIM_JUMP_GLIDE,
- ANIM_JUMP_LAND,
- ANIM_FALL_FALL,
- ANIM_FALL_GLIDE,
- ANIM_FALL_LAND,
- ANIM_FALL_COLLAPSE,
- ANIM_EV_STEP,
- ANIM_EV_DIVE,
- ANIM_XPRESS_SCRATCH,
- ANIM_ROAD_CROSS,
- ANIM_TURN_180,
- ANIM_ARREST_GUN,
- ANIM_DROWN,
- ANIM_CPR,
- ANIM_DUCK_DOWN,
- ANIM_DUCK_LOW,
- ANIM_RBLOCK_CSHOOT,
- ANIM_WEAPON_THROWU2,
- ANIM_HANDSUP,
- ANIM_HANDSCOWER,
- ANIM_FUCKU,
- ANIM_PHONE_IN,
- ANIM_PHONE_OUT,
- ANIM_PHONE_TALK,
-
- NUM_ANIMS
-};
-
class CAnimBlendAssociation;
class CAnimBlendAssocGroup;
@@ -242,12 +64,12 @@ struct AnimAssocDefinition
class CAnimManager
{
static const AnimAssocDefinition ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS];
- static CAnimBlock *ms_aAnimBlocks; //[2]
- static CAnimBlendHierarchy *ms_aAnimations; //[250]
- static int32 &ms_numAnimBlocks;
- static int32 &ms_numAnimations;
- static CAnimBlendAssocGroup *&ms_aAnimAssocGroups;
- static CLinkList<CAnimBlendHierarchy*> &ms_animCache;
+ static CAnimBlock ms_aAnimBlocks[2];
+ static CAnimBlendHierarchy ms_aAnimations[250];
+ static int32 ms_numAnimBlocks;
+ static int32 ms_numAnimations;
+ static CAnimBlendAssocGroup *ms_aAnimAssocGroups;
+ static CLinkList<CAnimBlendHierarchy*> ms_animCache;
public:
static void Initialise(void);
diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h
new file mode 100644
index 00000000..82fed8bd
--- /dev/null
+++ b/src/animation/AnimationId.h
@@ -0,0 +1,180 @@
+#pragma once
+
+enum AnimationId
+{
+ ANIM_WALK,
+ ANIM_RUN,
+ ANIM_SPRINT,
+ ANIM_IDLE_STANCE,
+ ANIM_WALK_START,
+ ANIM_RUN_STOP,
+ ANIM_RUN_STOP_R,
+ ANIM_IDLE_CAM,
+ ANIM_IDLE_HBHB,
+ ANIM_IDLE_TIRED,
+ ANIM_IDLE_ARMED,
+ ANIM_IDLE_CHAT,
+ ANIM_IDLE_TAXI,
+ ANIM_KO_SHOT_FRONT1,
+ ANIM_KO_SHOT_FRONT2,
+ ANIM_KO_SHOT_FRONT3,
+ ANIM_KO_SHOT_FRONT4,
+ ANIM_KO_SHOT_FACE,
+ ANIM_KO_SHOT_STOM,
+ ANIM_KO_SHOT_ARML,
+ ANIM_KO_SHOT_ARMR,
+ ANIM_KO_SHOT_LEGL,
+ ANIM_KO_SHOT_LEGR,
+ ANIM_KD_LEFT,
+ ANIM_KD_RIGHT,
+ ANIM_KO_SKID_FRONT,
+ ANIM_KO_SPIN_R, // named left in VC
+ ANIM_KO_SKID_BACK,
+ ANIM_KO_SPIN_L, // named right in VC
+ ANIM_SHOT_FRONT_PARTIAL,
+ ANIM_SHOT_LEFT_PARTIAL,
+ ANIM_SHOT_BACK_PARTIAL,
+ ANIM_SHOT_RIGHT_PARTIAL,
+ ANIM_HIT_FRONT,
+ ANIM_HIT_LEFT,
+ ANIM_HIT_BACK,
+ ANIM_HIT_RIGHT,
+ ANIM_FLOOR_HIT,
+ ANIM_HIT_BODYBLOW,
+ ANIM_HIT_CHEST,
+ ANIM_HIT_HEAD,
+ ANIM_HIT_WALK,
+ ANIM_HIT_WALL,
+ ANIM_FLOOR_HIT_F,
+ ANIM_HIT_BEHIND,
+ ANIM_PUNCH_R,
+ ANIM_KICK_FLOOR,
+ ANIM_WEAPON_BAT_H,
+ ANIM_WEAPON_BAT_V,
+ ANIM_WEAPON_HGUN_BODY,
+ ANIM_WEAPON_AK_BODY,
+ ANIM_WEAPON_PUMP,
+ ANIM_WEAPON_SNIPER,
+ ANIM_WEAPON_THROW,
+ ANIM_WEAPON_THROWU,
+ ANIM_WEAPON_START_THROW,
+ ANIM_BOMBER,
+ ANIM_HGUN_RELOAD,
+ ANIM_AK_RELOAD,
+ ANIM_FPS_PUNCH,
+ ANIM_FPS_BAT,
+ ANIM_FPS_UZI,
+ ANIM_FPS_PUMP,
+ ANIM_FPS_AK,
+ ANIM_FPS_M16,
+ ANIM_FPS_ROCKET,
+ ANIM_FIGHT_IDLE,
+ ANIM_FIGHT2_IDLE,
+ ANIM_FIGHT_SH_F,
+ ANIM_FIGHT_BODYBLOW,
+ ANIM_FIGHT_HEAD,
+ ANIM_FIGHT_KICK,
+ ANIM_FIGHT_KNEE,
+ ANIM_FIGHT_LHOOK,
+ ANIM_FIGHT_PUNCH,
+ ANIM_FIGHT_ROUNDHOUSE,
+ ANIM_FIGHT_LONGKICK,
+ ANIM_FIGHT_PPUNCH,
+ ANIM_CAR_JACKED_RHS,
+ ANIM_CAR_LJACKED_RHS,
+ ANIM_CAR_JACKED_LHS,
+ ANIM_CAR_LJACKED_LHS,
+ ANIM_CAR_QJACK,
+ ANIM_CAR_QJACKED,
+ ANIM_CAR_ALIGN_LHS,
+ ANIM_CAR_ALIGNHI_LHS,
+ ANIM_CAR_OPEN_LHS,
+ ANIM_CAR_DOORLOCKED_LHS,
+ ANIM_CAR_PULLOUT_LHS,
+ ANIM_CAR_PULLOUT_LOW_LHS,
+ ANIM_CAR_GETIN_LHS,
+ ANIM_CAR_GETIN_LOW_LHS,
+ ANIM_CAR_CLOSEDOOR_LHS,
+ ANIM_CAR_CLOSEDOOR_LOW_LHS,
+ ANIM_CAR_ROLLDOOR,
+ ANIM_CAR_ROLLDOOR_LOW,
+ ANIM_CAR_GETOUT_LHS,
+ ANIM_CAR_GETOUT_LOW_LHS,
+ ANIM_CAR_CLOSE_LHS,
+ ANIM_CAR_ALIGN_RHS,
+ ANIM_CAR_ALIGNHI_RHS,
+ ANIM_CAR_OPEN_RHS,
+ ANIM_CAR_DOORLOCKED_RHS,
+ ANIM_CAR_PULLOUT_RHS,
+ ANIM_CAR_PULLOUT_LOW_RHS,
+ ANIM_CAR_GETIN_RHS,
+ ANIM_CAR_GETIN_LOW_RHS,
+ ANIM_CAR_CLOSEDOOR_RHS,
+ ANIM_CAR_CLOSEDOOR_LOW_RHS,
+ ANIM_CAR_SHUFFLE_RHS,
+ ANIM_CAR_LSHUFFLE_RHS,
+ ANIM_CAR_SIT,
+ ANIM_CAR_LSIT,
+ ANIM_CAR_SITP,
+ ANIM_CAR_SITPLO,
+ ANIM_DRIVE_L,
+ ANIM_DRIVE_R,
+ ANIM_DRIVE_LOW_L,
+ ANIM_DRIVE_LOW_R,
+ ANIM_DRIVEBY_L,
+ ANIM_DRIVEBY_R,
+ ANIM_CAR_LB,
+ ANIM_DRIVE_BOAT,
+ ANIM_CAR_GETOUT_RHS,
+ ANIM_CAR_GETOUT_LOW_RHS,
+ ANIM_CAR_CLOSE_RHS,
+ ANIM_CAR_HOOKERTALK,
+ ANIM_COACH_OPEN_L,
+ ANIM_COACH_OPEN_R,
+ ANIM_COACH_IN_L,
+ ANIM_COACH_IN_R,
+ ANIM_COACH_OUT_L,
+ ANIM_TRAIN_GETIN,
+ ANIM_TRAIN_GETOUT,
+ ANIM_CAR_CRAWLOUT_RHS,
+ ANIM_CAR_CRAWLOUT_RHS2,
+ ANIM_VAN_OPEN_L,
+ ANIM_VAN_GETIN_L,
+ ANIM_VAN_CLOSE_L,
+ ANIM_VAN_GETOUT_L,
+ ANIM_VAN_OPEN,
+ ANIM_VAN_GETIN,
+ ANIM_VAN_CLOSE,
+ ANIM_VAN_GETOUT,
+ ANIM_GETUP1,
+ ANIM_GETUP2,
+ ANIM_GETUP3,
+ ANIM_GETUP_FRONT,
+ ANIM_JUMP_LAUNCH,
+ ANIM_JUMP_GLIDE,
+ ANIM_JUMP_LAND,
+ ANIM_FALL_FALL,
+ ANIM_FALL_GLIDE,
+ ANIM_FALL_LAND,
+ ANIM_FALL_COLLAPSE,
+ ANIM_EV_STEP,
+ ANIM_EV_DIVE,
+ ANIM_XPRESS_SCRATCH,
+ ANIM_ROAD_CROSS,
+ ANIM_TURN_180,
+ ANIM_ARREST_GUN,
+ ANIM_DROWN,
+ ANIM_CPR,
+ ANIM_DUCK_DOWN,
+ ANIM_DUCK_LOW,
+ ANIM_RBLOCK_CSHOOT,
+ ANIM_WEAPON_THROWU2,
+ ANIM_HANDSUP,
+ ANIM_HANDSCOWER,
+ ANIM_FUCKU,
+ ANIM_PHONE_IN,
+ ANIM_PHONE_OUT,
+ ANIM_PHONE_TALK,
+
+ NUM_ANIMS
+}; \ No newline at end of file
diff --git a/src/animation/Bones.cpp b/src/animation/Bones.cpp
new file mode 100644
index 00000000..1608449d
--- /dev/null
+++ b/src/animation/Bones.cpp
@@ -0,0 +1,52 @@
+#include "common.h"
+#include "PedModelInfo.h"
+#include "Bones.h"
+
+#ifdef PED_SKIN
+
+int
+ConvertPedNode2BoneTag(int node)
+{
+ switch(node){
+ case PED_TORSO: return BONE_waist;
+ case PED_MID: return BONE_torso; // this is what Xbox/Mobile use
+ // return BONE_mid; // this is what PS2/PC use
+ case PED_HEAD: return BONE_head;
+ case PED_UPPERARML: return BONE_upperarml;
+ case PED_UPPERARMR: return BONE_upperarmr;
+ case PED_HANDL: return BONE_Lhand;
+ case PED_HANDR: return BONE_Rhand;
+ case PED_UPPERLEGL: return BONE_upperlegl;
+ case PED_UPPERLEGR: return BONE_upperlegr;
+ case PED_FOOTL: return BONE_footl;
+ case PED_FOOTR: return BONE_footr;
+ case PED_LOWERLEGR: return BONE_lowerlegl;
+ }
+ return -1;
+}
+
+const char*
+ConvertBoneTag2BoneName(int tag)
+{
+ switch(tag){
+ case BONE_waist: return "Swaist";
+ case BONE_upperlegr: return "Supperlegr";
+ case BONE_lowerlegr: return "Slowerlegr";
+ case BONE_footr: return "Sfootr";
+ case BONE_upperlegl: return "Supperlegl";
+ case BONE_lowerlegl: return "Slowerlegl";
+ case BONE_footl: return "Sfootl";
+ case BONE_mid: return "Smid";
+ case BONE_torso: return "Storso";
+ case BONE_head: return "Shead";
+ case BONE_upperarmr: return "Supperarmr";
+ case BONE_lowerarmr: return "Slowerarmr";
+ case BONE_Rhand: return "SRhand";
+ case BONE_upperarml: return "Supperarml";
+ case BONE_lowerarml: return "Slowerarml";
+ case BONE_Lhand: return "SLhand";
+ }
+ return nil;
+}
+
+#endif
diff --git a/src/animation/Bones.h b/src/animation/Bones.h
new file mode 100644
index 00000000..38d91ba3
--- /dev/null
+++ b/src/animation/Bones.h
@@ -0,0 +1,24 @@
+#pragma once
+
+enum BoneTag
+{
+ BONE_waist,
+ BONE_upperlegr,
+ BONE_lowerlegr,
+ BONE_footr,
+ BONE_upperlegl,
+ BONE_lowerlegl,
+ BONE_footl,
+ BONE_mid,
+ BONE_torso,
+ BONE_head,
+ BONE_upperarmr,
+ BONE_lowerarmr,
+ BONE_Rhand,
+ BONE_upperarml,
+ BONE_lowerarml,
+ BONE_Lhand,
+};
+
+int ConvertPedNode2BoneTag(int node);
+const char *ConvertBoneTag2BoneName(int tag);
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index 6f8e9790..334fe471 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -1,6 +1,5 @@
-#define WITHWINDOWS // just for VK_SPACE
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "CutsceneMgr.h"
#include "Directory.h"
@@ -117,19 +116,19 @@ FindCutsceneAudioTrackId(const char *szCutsceneName)
return -1;
}
-bool &CCutsceneMgr::ms_running = *(bool*)0x95CCF5;
-bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F;
-CDirectory *&CCutsceneMgr::ms_pCutsceneDir = *(CDirectory**)0x8F5F88;
-CCutsceneObject *(&CCutsceneMgr::ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS] = *(CCutsceneObject*(*)[NUMCUTSCENEOBJECTS]) *(uintptr*) 0x862170;
-int32 &CCutsceneMgr::ms_numCutsceneObjs = *(int32*)0x942FA4;
-bool &CCutsceneMgr::ms_loaded = *(bool*)0x95CD95;
-bool &CCutsceneMgr::ms_animLoaded = *(bool*)0x95CDA0;
-bool &CCutsceneMgr::ms_useLodMultiplier = *(bool*)0x95CD74;
-char(&CCutsceneMgr::ms_cutsceneName)[CUTSCENENAMESIZE] = *(char(*)[CUTSCENENAMESIZE]) *(uintptr*)0x70D9D0;
-CAnimBlendAssocGroup &CCutsceneMgr::ms_cutsceneAssociations = *(CAnimBlendAssocGroup*)0x709C58;
-CVector &CCutsceneMgr::ms_cutsceneOffset = *(CVector*)0x8F2C0C;
-float &CCutsceneMgr::ms_cutsceneTimer = *(float*)0x941548;
-uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
+bool CCutsceneMgr::ms_running;
+bool CCutsceneMgr::ms_cutsceneProcessing;
+CDirectory *CCutsceneMgr::ms_pCutsceneDir;
+CCutsceneObject *CCutsceneMgr::ms_pCutsceneObjects[NUMCUTSCENEOBJECTS];
+int32 CCutsceneMgr::ms_numCutsceneObjs;
+bool CCutsceneMgr::ms_loaded;
+bool CCutsceneMgr::ms_animLoaded;
+bool CCutsceneMgr::ms_useLodMultiplier;
+char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
+CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
+CVector CCutsceneMgr::ms_cutsceneOffset;
+float CCutsceneMgr::ms_cutsceneTimer;
+uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@@ -416,26 +415,10 @@ CCutsceneMgr::Update(void)
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|| CPad::GetPad(0)->GetEnterJustDown()
- || CPad::GetPad(0)->GetCharJustDown(VK_SPACE))
+ || CPad::GetPad(0)->GetCharJustDown(' '))
FinishCutscene();
}
}
bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; }
-STARTPATCHES
- InjectHook(0x4045D0, &CCutsceneMgr::Initialise, PATCH_JUMP);
- InjectHook(0x404630, &CCutsceneMgr::Shutdown, PATCH_JUMP);
- InjectHook(0x404650, &CCutsceneMgr::LoadCutsceneData, PATCH_JUMP);
- InjectHook(0x405140, &CCutsceneMgr::FinishCutscene, PATCH_JUMP);
- InjectHook(0x404D80, &CCutsceneMgr::SetHeadAnim, PATCH_JUMP);
- InjectHook(0x404DC0, &CCutsceneMgr::SetupCutsceneToStart, PATCH_JUMP);
- InjectHook(0x404D20, &CCutsceneMgr::SetCutsceneAnim, PATCH_JUMP);
- InjectHook(0x404CD0, &CCutsceneMgr::AddCutsceneHead, PATCH_JUMP);
- InjectHook(0x404BE0, &CCutsceneMgr::CreateCutsceneObject, PATCH_JUMP);
- InjectHook(0x4048E0, &CCutsceneMgr::DeleteCutsceneData, PATCH_JUMP);
- InjectHook(0x404EE0, &CCutsceneMgr::Update, PATCH_JUMP);
- InjectHook(0x4051B0, &CCutsceneMgr::GetCutsceneTimeInMilleseconds, PATCH_JUMP);
- InjectHook(0x4051F0, &CCutsceneMgr::HasCutsceneFinished, PATCH_JUMP);
- InjectHook(0x404B40, &CalculateBoundingSphereRadiusCB, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index 3c915eea..bfdcdb57 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -9,25 +9,26 @@ class CCutsceneHead;
class CCutsceneMgr
{
- static bool &ms_running;
- static CCutsceneObject *(&ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS];
+ static bool ms_running;
+ static CCutsceneObject *ms_pCutsceneObjects[NUMCUTSCENEOBJECTS];
- static int32 &ms_numCutsceneObjs;
- static bool &ms_loaded;
- static bool &ms_animLoaded;
- static bool &ms_useLodMultiplier;
+ static int32 ms_numCutsceneObjs;
+ static bool ms_loaded;
+ static bool ms_animLoaded;
+ static bool ms_useLodMultiplier;
- static char(&ms_cutsceneName)[CUTSCENENAMESIZE];
- static CAnimBlendAssocGroup &ms_cutsceneAssociations;
- static CVector &ms_cutsceneOffset;
- static float &ms_cutsceneTimer;
- static bool &ms_cutsceneProcessing;
+ static char ms_cutsceneName[CUTSCENENAMESIZE];
+ static CAnimBlendAssocGroup ms_cutsceneAssociations;
+ static CVector ms_cutsceneOffset;
+ static float ms_cutsceneTimer;
+ static bool ms_cutsceneProcessing;
public:
- static CDirectory *&ms_pCutsceneDir;
- static uint32 &ms_cutsceneLoadStatus;
+ static CDirectory *ms_pCutsceneDir;
+ static uint32 ms_cutsceneLoadStatus;
static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; }
+ static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index dcb71944..a1121282 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -1,19 +1,25 @@
#include "common.h"
-#include "patcher.h"
+
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "AnimBlendClumpData.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
-CAnimBlendClumpData *&gpAnimBlendClump = *(CAnimBlendClumpData**)0x621000;
+CAnimBlendClumpData *gpAnimBlendClump;
+
+// PS2 names without "NonSkinned"
+void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg);
+
+void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
-void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg);
-void FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg);
-void FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg);
void
-FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -25,9 +31,9 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
gpAnimBlendClump->velocity){
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
- FrameUpdateCallBackWith3dVelocityExtraction(frame, arg);
+ FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(frame, arg);
else
- FrameUpdateCallBackWithVelocityExtraction(frame, arg);
+ FrameUpdateCallBackWithVelocityExtractionNonSkinned(frame, arg);
return;
}
@@ -48,12 +54,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -69,7 +70,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
}
void
-FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackWithVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -122,12 +123,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -154,7 +150,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
// original code uses do loops?
void
-FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg)
+FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
@@ -201,12 +197,7 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
RwMatrixSetIdentity(mat);
-
- float norm = rot.MagnitudeSqr();
- if(norm == 0.0f)
- rot.w = 1.0f;
- else
- rot *= 1.0f/Sqrt(norm);
+ rot.Normalise();
rot.Get(mat);
}
@@ -221,8 +212,202 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
RwMatrixUpdate(mat);
}
-STARTPATCHES
- InjectHook(0x4025F0, FrameUpdateCallBack, PATCH_JUMP);
- InjectHook(0x4028B0, FrameUpdateCallBackWithVelocityExtraction, PATCH_JUMP);
- InjectHook(0x402D40, FrameUpdateCallBackWith3dVelocityExtraction, PATCH_JUMP);
-ENDPATCHES
+#ifdef PED_SKIN
+
+void
+FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity){
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
+ FrameUpdateCallBackWith3dVelocityExtractionSkinned(frame, arg);
+ else
+ FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
+ return;
+ }
+
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ (*node)->Update(vec, q, 1.0f-totalBlendAmount);
+ if((*node)->sequence->HasTranslation())
+ pos += vec;
+ rot += q;
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ xform->t.x = pos.x;
+ xform->t.y = pos.y;
+ xform->t.z = pos.z;
+ xform->t.x += frame->resetPos.x;
+ xform->t.y += frame->resetPos.y;
+ xform->t.z += frame->resetPos.z;
+ }
+}
+
+void
+FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ float transx = 0.0f, transy = 0.0f;
+ float curx = 0.0f, cury = 0.0f;
+ float endx = 0.0f, endy = 0.0f;
+ bool looped = false;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
+ cury += vec.y;
+ if((*node)->association->HasXTranslation())
+ curx += vec.x;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ transy += vec.y;
+ if((*node)->association->HasXTranslation())
+ transx += vec.x;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
+ endy += vec.y;
+ if((*node)->association->HasXTranslation())
+ endx += vec.x;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ gpAnimBlendClump->velocity->x = transx - curx;
+ gpAnimBlendClump->velocity->y = transy - cury;
+ if(looped){
+ gpAnimBlendClump->velocity->x += endx;
+ gpAnimBlendClump->velocity->y += endy;
+ }
+ xform->t.x = pos.x - transx;
+ xform->t.y = pos.y - transy;
+ xform->t.z = pos.z;
+ if(xform->t.z >= -0.8f)
+ if(xform->t.z < -0.4f)
+ xform->t.z += (2.5f * xform->t.z + 2.0f) * frame->resetPos.z;
+ else
+ xform->t.z += frame->resetPos.z;
+ xform->t.x += frame->resetPos.x;
+ xform->t.y += frame->resetPos.y;
+ }
+}
+
+void
+FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ CVector trans(0.0f, 0.0f, 0.0f);
+ CVector cur(0.0f, 0.0f, 0.0f);
+ CVector end(0.0f, 0.0f, 0.0f);
+ bool looped = false;
+ RpHAnimStdKeyFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslation(vec, 1.0f-totalBlendAmount);
+ cur += vec;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ trans += vec;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslation(vec, 1.0f-totalBlendAmount);
+ end += vec;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ *gpAnimBlendClump->velocity = trans - cur;
+ if(looped)
+ *gpAnimBlendClump->velocity += end;
+ xform->t.x = (pos - trans).x + frame->resetPos.x;
+ xform->t.y = (pos - trans).y + frame->resetPos.y;
+ xform->t.z = (pos - trans).z + frame->resetPos.z;
+ }
+}
+
+#endif
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index 9c847139..d3e10889 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -1,14 +1,19 @@
#include "common.h"
-#include "patcher.h"
+
+#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
+#include "Bones.h"
#include "AnimBlendClumpData.h"
#include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
+#ifdef PED_SKIN
+#include "PedModelInfo.h"
+#endif
-RwInt32 &ClumpOffset = *(RwInt32*)0x8F1B84;
+RwInt32 ClumpOffset;
enum
{
@@ -122,19 +127,59 @@ FrameForAllChildrenFillFrameArrayCallBack(RwFrame *frame, void *data)
return frame;
}
+// FrameInitCallBack on PS2
void
-FrameInitCallBack(AnimBlendFrameData *frameData, void*)
+FrameInitCBnonskin(AnimBlendFrameData *frameData, void*)
{
frameData->flag = 0;
frameData->resetPos = *RwMatrixGetPos(RwFrameGetMatrix(frameData->frame));
}
void
-RpAnimBlendClumpInit(RpClump *clump)
+FrameInitCBskin(AnimBlendFrameData *frameData, void*)
{
+ frameData->flag = 0;
+}
+
#ifdef PED_SKIN
- TODO
-#else
+void
+RpAnimBlendClumpInitSkinned(RpClump *clump)
+{
+ int i;
+ RwV3d boneTab[64];
+ CAnimBlendClumpData *clumpData;
+ RpAtomic *atomic;
+ RpSkin *skin;
+ RpHAnimHierarchy *hier;
+ int numBones;
+
+ RpAnimBlendAllocateData(clump);
+ clumpData = *RPANIMBLENDCLUMPDATA(clump);
+ atomic = IsClumpSkinned(clump);
+ assert(atomic);
+ skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
+ assert(skin);
+ numBones = RpSkinGetNumBones(skin);
+ clumpData->SetNumberOfBones(numBones);
+ hier = GetAnimHierarchyFromSkinClump(clump);
+ assert(hier);
+ memset(boneTab, 0, sizeof(boneTab));
+ SkinGetBonePositionsToTable(clump, boneTab);
+
+ AnimBlendFrameData *frames = clumpData->frames;
+ for(i = 0; i < numBones; i++){
+ frames[i].nodeID = HIERNODEID(hier, i);
+ frames[i].resetPos = boneTab[i];
+ frames[i].hanimFrame = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+ }
+ clumpData->ForAllFrames(FrameInitCBskin, nil);
+ clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
+}
+#endif
+
+void
+RpAnimBlendClumpInitNotSkinned(RpClump *clump)
+{
int numFrames = 0;
CAnimBlendClumpData *clumpData;
RwFrame *root;
@@ -147,9 +192,19 @@ RpAnimBlendClumpInit(RpClump *clump)
clumpData->SetNumberOfFrames(numFrames);
frames = clumpData->frames;
RwFrameForAllChildren(root, FrameForAllChildrenFillFrameArrayCallBack, &frames);
- clumpData->ForAllFrames(FrameInitCallBack, nil);
+ clumpData->ForAllFrames(FrameInitCBnonskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
+}
+
+void
+RpAnimBlendClumpInit(RpClump *clump)
+{
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump))
+ RpAnimBlendClumpInitSkinned(clump);
+ else
#endif
+ RpAnimBlendClumpInitNotSkinned(clump);
}
bool
@@ -298,42 +353,68 @@ RpAnimBlendClumpGetFirstAssociation(RpClump *clump)
return CAnimBlendAssociation::FromLink(clumpData->link.next);
}
+// FillFrameArrayCallBack on PS2
void
-FillFrameArrayCallBack(AnimBlendFrameData *frame, void *arg)
+FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
{
AnimBlendFrameData **frames = (AnimBlendFrameData**)arg;
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
}
+#ifdef PED_SKIN
+void
+RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
+{
+ int i;
+ CAnimBlendClumpData *clumpData = *RPANIMBLENDCLUMPDATA(clump);
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
+ for(i = PED_MID; i < PED_NODE_MAX; i++)
+ frames[i] = &clumpData->frames[RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(i))];
+}
+#endif
+
void
RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames)
{
#ifdef PED_SKIN
- TODO
-#else
- (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCallBack, frames);
+ if(IsClumpSkinned(clump))
+ RpAnimBlendClumpFillFrameArraySkin(clump, frames);
+ else
#endif
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCBnonskin, frames);
}
AnimBlendFrameData *pFrameDataFound;
+// FrameFindCallBack on PS2
void
-FrameFindCallBack(AnimBlendFrameData *frame, void *arg)
+FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
{
char *nodename = GetFrameNodeName(frame->frame);
if(!CGeneral::faststricmp(nodename, (char*)arg))
pFrameDataFound = frame;
}
+#ifdef PED_SKIN
+void
+FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
+{
+ const char *name = ConvertBoneTag2BoneName(frame->nodeID);
+ if(name && CGeneral::faststricmp(name, (char*)arg) == 0)
+ pFrameDataFound = frame;
+}
+#endif
+
AnimBlendFrameData*
RpAnimBlendClumpFindFrame(RpClump *clump, const char *name)
{
pFrameDataFound = nil;
#ifdef PED_SKIN
- TODO
-#else
- (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindCallBack, (void*)name);
+ if(IsClumpSkinned(clump))
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBskin, (void*)name);
+ else
#endif
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBnonskin, (void*)name);
return pFrameDataFound;
}
@@ -369,7 +450,12 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
}
updateData.nodes[i] = nil;
- clumpData->ForAllFrames(FrameUpdateCallBack, &updateData);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
+ else
+#endif
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
for(link = clumpData->link.next; link; link = link->next){
CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
@@ -378,26 +464,3 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
}
RwFrameUpdateObjects(RpClumpGetFrame(clump));
}
-
-
-STARTPATCHES
- InjectHook(0x4052D0, RpAnimBlendPluginAttach, PATCH_JUMP);
- InjectHook(0x4052A0, RpAnimBlendAllocateData, PATCH_JUMP);
- InjectHook(0x405780, (CAnimBlendAssociation *(*)(CAnimBlendAssociation*))RpAnimBlendGetNextAssociation, PATCH_JUMP);
- InjectHook(0x4057A0, (CAnimBlendAssociation *(*)(CAnimBlendAssociation*,uint32))RpAnimBlendGetNextAssociation, PATCH_JUMP);
-
- InjectHook(0x405520, RpAnimBlendClumpSetBlendDeltas, PATCH_JUMP);
- InjectHook(0x405560, RpAnimBlendClumpRemoveAllAssociations, PATCH_JUMP);
- InjectHook(0x405570, RpAnimBlendClumpRemoveAssociations, PATCH_JUMP);
- InjectHook(0x405480, RpAnimBlendClumpInit, PATCH_JUMP);
- InjectHook(0x405500, RpAnimBlendClumpIsInitialized, PATCH_JUMP);
- InjectHook(0x4055C0, RpAnimBlendClumpGetAssociation, PATCH_JUMP);
- InjectHook(0x4055F0, RpAnimBlendClumpGetMainAssociation, PATCH_JUMP);
- InjectHook(0x405680, RpAnimBlendClumpGetMainPartialAssociation, PATCH_JUMP);
- InjectHook(0x4056D0, RpAnimBlendClumpGetMainAssociation_N, PATCH_JUMP);
- InjectHook(0x405710, RpAnimBlendClumpGetMainPartialAssociation_N, PATCH_JUMP);
- InjectHook(0x405750, (CAnimBlendAssociation *(*)(RpClump*, uint32))RpAnimBlendClumpGetFirstAssociation, PATCH_JUMP);
- InjectHook(0x4031B0, (CAnimBlendAssociation *(*)(RpClump*))RpAnimBlendClumpGetFirstAssociation, PATCH_JUMP);
- InjectHook(0x405460, RpAnimBlendClumpFillFrameArray, PATCH_JUMP);
- InjectHook(0x4024B0, RpAnimBlendClumpUpdateAnimations, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h
index 55a4456b..838c8816 100644
--- a/src/animation/RpAnimBlend.h
+++ b/src/animation/RpAnimBlend.h
@@ -7,11 +7,11 @@ struct AnimBlendFrameData;
struct AnimBlendFrameUpdateData
{
- int foobar;
+ int foobar; // TODO: figure out what this actually means
CAnimBlendNode *nodes[16];
};
-extern RwInt32 &ClumpOffset;
+extern RwInt32 ClumpOffset;
#define RPANIMBLENDCLUMPDATA(o) (RWPLUGINOFFSET(CAnimBlendClumpData*, o, ClumpOffset))
bool RpAnimBlendPluginAttach(void);
@@ -37,5 +37,6 @@ CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump);
void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta);
-extern CAnimBlendClumpData *&gpAnimBlendClump;
-void FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg);
+extern CAnimBlendClumpData *gpAnimBlendClump;
+void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index fecd079e..a963b293 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "DMAudio.h"
#include "Entity.h"
#include "AudioCollision.h"
@@ -226,7 +226,7 @@ cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
s1 = SURFACE_BILLBOARD;
- ratio = min(1.f, 2.f * ratio);
+ ratio = Min(1.f, 2.f * ratio);
}
emittingVol = 40.f * ratio;
if(emittingVol) {
@@ -406,14 +406,3 @@ cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface
m_sCollisionManager.AddCollisionToRequestedQueue();
}
}
-
-STARTPATCHES
-InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
-InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
-InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
-InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
-InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
-InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
-InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
-InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index 1d2835cf..0c4b007f 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -1,5 +1,5 @@
-#include "common.h"
-#include "patcher.h"
+#include "common.h"
+
#include "audio_enums.h"
#include "AudioManager.h"
@@ -40,18 +40,18 @@
#include "sampman.h"
cAudioManager AudioManager;
-uint32 gPornNextTime; // = *(uint32*)0x6508A0;
-uint32 gSawMillNextTime; // = *(uint32*)0x6508A4;
-uint32 gShopNextTime; // = *(uint32*)0x6508A8;
-uint32 gAirportNextTime; // = *(uint32*)0x6508AC;
-uint32 gCinemaNextTime; //= *(uint32*)0x6508B0;
-uint32 gDocksNextTime; // = *(uint32*)0x6508B4;
-uint32 gHomeNextTime; // = *(uint32*)0x6508B8;
-uint32 gCellNextTime; // = *(uint32*)0x6508BC;
-uint32 gNextCryTime; // = *(uint32*)0x6508C0;
-uint8 gJumboVolOffsetPercentage; // = *(uint8 *)0x6508ED;
-bool bPlayerJustEnteredCar; // = *(bool *)0x6508C4;
-bool g_bMissionAudioLoadFailed; // = *(bool *)0x95CD8E;
+uint32 gPornNextTime;
+uint32 gSawMillNextTime;
+uint32 gShopNextTime;
+uint32 gAirportNextTime;
+uint32 gCinemaNextTime;
+uint32 gDocksNextTime;
+uint32 gHomeNextTime;
+uint32 gCellNextTime;
+uint32 gNextCryTime;
+uint8 gJumboVolOffsetPercentage;
+bool bPlayerJustEnteredCar;
+bool g_bMissionAudioLoadFailed;
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
const int policeChannel = channels + 1;
@@ -635,9 +635,9 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
float speedOfSource = (dist / m_bTimeSpent) * speedMultiplier;
if(m_fSpeedOfSound > Abs(speedOfSource)) {
if(speedOfSource < 0.0f) {
- speedOfSource = max(speedOfSource, -1.5f);
+ speedOfSource = Max(speedOfSource, -1.5f);
} else {
- speedOfSource = min(speedOfSource, 1.5f);
+ speedOfSource = Min(speedOfSource, 1.5f);
}
newFreq =
(oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound);
@@ -650,10 +650,10 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
int32
cAudioManager::ComputePan(float dist, CVector *vec)
{
- int32 index = min(63, Abs(vec->x / (dist / 64.f)));
+ int32 index = Min(63, Abs(vec->x / (dist / 64.f)));
- if(vec->x > 0.f) return max(20, 63 - panTable[index]);
- return min(107, panTable[index] + 63);
+ if(vec->x > 0.f) return Max(20, 63 - panTable[index]);
+ return Min(107, panTable[index] + 63);
}
uint8
@@ -2894,7 +2894,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
relativeVelChange = (gasPedalAudio - 0.4f) * 1.25f;
} else if(wheelState == WHEEL_STATE_SKIDDING) {
- relativeVelChange = min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
+ relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
} else if(wheelState == WHEEL_STATE_FIXED) {
modificator = 0.4f;
relativeVelChange = gasPedalAudio;
@@ -2905,7 +2905,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
velChange = Abs(velocityChange);
if(relativeVelChange > 0.4f) relativeVelChange = relativeVelChange * modificator;
if(velChange > 0.04f) {
- relativeVel = min(1.0f, velChange / transmission->fMaxVelocity);
+ relativeVel = Min(1.0f, velChange / transmission->fMaxVelocity);
} else {
relativeVel = 0.0f;
}
@@ -2914,7 +2914,7 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
relativeVelChange = 0.0f;
}
- return max(relativeVelChange, min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
+ return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
}
float
@@ -2924,12 +2924,12 @@ cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automo
float relativeVelChange;
if(automobile->m_aWheelState[wheel] == 2) {
- relativeVelChange = min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
+ relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
} else {
relativeVelChange = 0.0f;
}
- return max(relativeVelChange, min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
+ return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
}
bool
@@ -3326,7 +3326,7 @@ cAudioManager::ProcessActiveQueues()
if(field_4) {
emittingVol =
2 *
- min(63,
+ Min(63,
sample.m_bEmittingVolume);
} else {
emittingVol =
@@ -3353,13 +3353,13 @@ cAudioManager::ProcessActiveQueues()
if(sample.m_nFrequency <=
m_asActiveSamples[j]
.m_nFrequency) {
- freq = max(
+ freq = Max(
sample.m_nFrequency,
m_asActiveSamples[j]
.m_nFrequency -
6000);
} else {
- freq = min(
+ freq = Min(
sample.m_nFrequency,
m_asActiveSamples[j]
.m_nFrequency +
@@ -3376,14 +3376,14 @@ cAudioManager::ProcessActiveQueues()
if(sample.m_bEmittingVolume <=
m_asActiveSamples[j]
.m_bEmittingVolume) {
- vol = max(
+ vol = Max(
m_asActiveSamples[j]
.m_bEmittingVolume -
10,
sample
.m_bEmittingVolume);
} else {
- vol = min(
+ vol = Min(
m_asActiveSamples[j]
.m_bEmittingVolume +
10,
@@ -3394,7 +3394,7 @@ cAudioManager::ProcessActiveQueues()
uint8 emittingVol;
if(field_4) {
emittingVol =
- 2 * min(63, vol);
+ 2 * Min(63, vol);
} else {
emittingVol = vol;
}
@@ -3461,7 +3461,7 @@ cAudioManager::ProcessActiveQueues()
&position);
if(field_4) {
emittingVol =
- 2 * min(63, m_asActiveSamples[j]
+ 2 * Min(63, m_asActiveSamples[j]
.m_bEmittingVolume);
} else {
emittingVol =
@@ -3783,7 +3783,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params)
velocityChange = Abs(params->m_fVelocityChange);
if(velocityChange <= 0.0005f && params->m_pVehicle->GetPosition().y) return true;
- velocityChange = min(0.75f, velocityChange);
+ velocityChange = Min(0.75f, velocityChange);
multiplier = (velocityChange - 0.0005f) * 1.3342f;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
vol = (30.f * multiplier);
@@ -5044,7 +5044,7 @@ void
cAudioManager::ProcessJumboDecel(CPlane *plane)
{
if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) {
- const float modificator = min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
+ const float modificator = Min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000);
SetupJumboWhineSound(18, 29500);
}
@@ -6269,7 +6269,7 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
emittingVol = 10;
veh = (CAutomobile *)ped->m_pMyVehicle;
if(veh && veh->IsCar()) {
- for(int32 i = 2; i < ARRAYSIZE(veh->Doors); i++) {
+ for(int32 i = 2; i < ARRAY_SIZE(veh->Doors); i++) {
if(!veh->IsDoorClosed((eDoors)i) ||
veh->IsDoorMissing((eDoors)i)) {
emittingVol = 42;
@@ -7259,7 +7259,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
CurrentPretendGear = 1;
}
if(CReplay::IsPlayingBack()) {
- accelerateState = 255.f * max(0.0f, min(1.0f, automobile->m_fGasPedal));
+ accelerateState = 255.f * Max(0.0f, Min(1.0f, automobile->m_fGasPedal));
} else {
accelerateState = Pads->GetAccelerate();
}
@@ -7268,7 +7268,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
velocityChange = params->m_fVelocityChange;
relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity;
- accelerationMultipler = min(min(1.f, relativeVelocityChange), 0.f);
+ accelerationMultipler = Min(Min(1.f, relativeVelocityChange), 0.f);
gasPedalAudio = accelerationMultipler;
currentGear = params->m_pVehicle->m_nCurrentGear;
@@ -7290,9 +7290,9 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
if(0.0f != velocityChange) {
time = params->m_pVehicle->m_vecMoveSpeed.z / velocityChange;
if(time <= 0.0f) {
- freqModifier = max(-0.2f, time) * -15000.f;
+ freqModifier = Max(-0.2f, time) * -15000.f;
} else {
- freqModifier = -(min(0.2f, time) * 15000.f);
+ freqModifier = -(Min(0.2f, time) * 15000.f);
}
if(params->m_fVelocityChange < -0.001f) freqModifier = -freqModifier;
} else {
@@ -7311,10 +7311,10 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
gasPedalAudio = automobile->m_fGasPedalAudio;
} else {
gasPedalAudio =
- min(1.0f, params->m_fVelocityChange /
+ Min(1.0f, params->m_fVelocityChange /
params->m_pTransmission->fMaxReverseVelocity);
}
- gasPedalAudio = max(0.0f, gasPedalAudio);
+ gasPedalAudio = Max(0.0f, gasPedalAudio);
automobile->m_fGasPedalAudio = gasPedalAudio;
} else if(LastAccel > 0) {
if(channelUsed) {
@@ -7343,7 +7343,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq,
(engineSoundType + SFX_CAR_REV_10), 0, 52, 1);
- CurrentPretendGear = max(1, currentGear);
+ CurrentPretendGear = Max(1, currentGear);
LastAccel = accelerateState;
bHandbrakeOnLastFrame = automobile->bIsHandbrakeOn;
@@ -8005,7 +8005,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
if(params->m_fVelocityChange > 0.0f) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
train = (CTrain *)params->m_pVehicle;
- speedMultipler = min(1.0f, train->m_fSpeed * 250.f / 51.f);
+ speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f);
emittingVol = (75.f * speedMultipler);
if(train->m_fWagonPosition == 0.0f) {
m_sQueueSample.m_bVolume =
@@ -8176,7 +8176,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
if(automobile->Damage.GetDoorStatus(i) == 2) {
doorState = automobile->Doors[i].m_nDoorState;
if(doorState == 1 || doorState == 2) {
- velocity = min(0.3f, Abs(automobile->Doors[i].m_fAngVel));
+ velocity = Min(0.3f, Abs(automobile->Doors[i].m_fAngVel));
if(velocity > 0.0035f) {
emittingVol = (100.f * velocity * 10.f / 3.f);
m_sQueueSample.m_bVolume = ComputeVolume(
@@ -8599,7 +8599,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams *params)
m_sQueueSample.m_fSoundIntensity = 30.0f;
break;
case SOUND_CAR_JUMP:
- emittingVol = max(
+ emittingVol = Max(
80.f,
2 * (100.f *
m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
@@ -9081,7 +9081,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
params->m_fDistance);
emittingVol =
30.f *
- min(1.f,
+ Min(1.f,
velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
m_sQueueSample.m_bVolume =
ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
@@ -9132,6 +9132,9 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
CVehicle *veh = params->m_pVehicle;
if(veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) return;
+#ifdef FIX_BUGS
+ if (params->m_pVehicle->m_status == STATUS_WRECKED) return;
+#endif
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
@@ -9394,7 +9397,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated,
params->m_fDistance);
relativeVelocity =
- min(1.0f,
+ Min(1.0f,
velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads;
m_sQueueSample.m_bVolume =
@@ -9545,6 +9548,9 @@ cAudioManager::ResetTimers(uint32 time)
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
+#ifdef OPENAL
+ SampleManager.Service();
+#endif
}
}
@@ -9600,6 +9606,9 @@ cAudioManager::ServiceSoundEffects()
ProcessMissionAudio();
AdjustSamplesVolume();
ProcessActiveQueues();
+#ifdef OPENAL
+ SampleManager.Service();
+#endif
for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
cAudioScriptObject *object =
(cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]]
@@ -9980,7 +9989,7 @@ cAudioManager::Terminate()
m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
PreTerminateGameSpecificShutdown();
- for(uint32 i = 0; i < DIGITALCHANNELS; i++) {
+ for(uint32 i = 0; i < MAX_SAMPLEBANKS; i++) {
if(SampleManager.IsSampleBankLoaded(i)) SampleManager.UnloadSampleBank(i);
}
@@ -10032,7 +10041,7 @@ cAudioManager::UpdateReflections()
if(CWorld::ProcessVerticalLine(
camPos, m_avecReflectionsPos[4].z, colpoint,
ent, true, false, false, false, true, false,
- false)) {
+ nil)) {
m_afReflectionsDistances[4] =
colpoint.point.z - camPos.z;
} else {
@@ -10144,217 +10153,3 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa
quatIntensity;
return emittingVolume;
}
-
-// STARTPATCHES
-// InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
-// InjectHook(0x56AD30, &cAudioManager::AddPlayerCarSample, PATCH_JUMP);
-// InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
-// InjectHook(0x57B8D0, &cAudioManager::AddReleasingSounds, PATCH_JUMP);
-// InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
-// InjectHook(0x5697A0, &cAudioManager::CalculateDistance, PATCH_JUMP);
-// InjectHook(0x57AA10, &cAudioManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
-// InjectHook(0x57C160, &cAudioManager::ClearActiveSamples, PATCH_JUMP);
-// InjectHook(0x5796A0, &cAudioManager::ClearMissionAudio, PATCH_JUMP);
-// InjectHook(0x57C120, &cAudioManager::ClearRequestedQueue, PATCH_JUMP);
-// InjectHook(0x57AE00, &cAudioManager::ComputeDopplerEffectedFrequency, PATCH_JUMP);
-// InjectHook(0x57AD20, &cAudioManager::ComputePan, PATCH_JUMP);
-// InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
-// InjectHook(0x57A310, &cAudioManager::CreateEntity, PATCH_JUMP);
-// InjectHook(0x57A830, &cAudioManager::DestroyAllGameCreatedEntities, PATCH_JUMP);
-// InjectHook(0x57A400, &cAudioManager::DestroyEntity, PATCH_JUMP);
-// InjectHook(0x57C290, &cAudioManager::GenerateIntegerRandomNumberTable, PATCH_JUMP);
-// InjectHook(0x57A8C0, &cAudioManager::Get3DProviderName, PATCH_JUMP);
-// InjectHook(0x571110, &cAudioManager::GetArmyTalkSfx, PATCH_JUMP);
-// InjectHook(0x573AB0, &cAudioManager::GetBlackBusinessFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x572050, &cAudioManager::GetBlackCasualFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574380, &cAudioManager::GetBlackConstructionWorkerTalkSfx, PATCH_JUMP);
-// InjectHook(0x571D80, &cAudioManager::GetBlackCriminalTalkSfx, PATCH_JUMP);
-// InjectHook(0x5735E0, &cAudioManager::GetBlackDockerMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5724D0, &cAudioManager::GetBlackFatFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5726C0, &cAudioManager::GetBlackFatMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5728B0, &cAudioManager::GetBlackFemaleProstituteTalkSfx, PATCH_JUMP);
-// InjectHook(0x572C20, &cAudioManager::GetBlackProjectFemaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x572D20, &cAudioManager::GetBlackProjectFemaleYoungTalkSfx, PATCH_JUMP);
-// InjectHook(0x572AF0, &cAudioManager::GetBlackProjectMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5739C0, &cAudioManager::GetBlackWorkerMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574FF0, &cAudioManager::GetBomberTalkSfx, PATCH_JUMP);
-// InjectHook(0x5712C0, &cAudioManager::GetBusinessMaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x5713E0, &cAudioManager::GetBusinessMaleYoungTalkSfx, PATCH_JUMP);
-// InjectHook(0x572040, &cAudioManager::GetCasualMaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x574FE0, &cAudioManager::GetCatatalinaTalkSfx, PATCH_JUMP);
-// InjectHook(0x57AA30, &cAudioManager::GetCDAudioDriveLetter, PATCH_JUMP);
-// InjectHook(0x573010, &cAudioManager::GetChinatownFemaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x5730F0, &cAudioManager::GetChinatownFemaleYoungTalkSfx, PATCH_JUMP);
-// InjectHook(0x572E10, &cAudioManager::GetChinatownMaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x572F10, &cAudioManager::GetChinatownMaleYoungTalkSfx, PATCH_JUMP);
-// InjectHook(0x575120, &cAudioManager::GetChunkyTalkSfx, PATCH_JUMP);
-// InjectHook(0x571B00, &cAudioManager::GetColumbianTalkSfx, PATCH_JUMP);
-// InjectHook(0x570EA0, &cAudioManager::GetCopTalkSfx, PATCH_JUMP);
-// InjectHook(0x57A8F0, &cAudioManager::GetCurrent3DProviderIndex, PATCH_JUMP);
-// InjectHook(0x571770, &cAudioManager::GetDiabloTalkSfx, PATCH_JUMP);
-// InjectHook(0x569750, &cAudioManager::GetDistanceSquared, PATCH_JUMP);
-// InjectHook(0x574DA0, &cAudioManager::GetEightTalkSfx, PATCH_JUMP);
-// InjectHook(0x574040, &cAudioManager::GetFanFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x573F60, &cAudioManager::GetFanMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x571040, &cAudioManager::GetFBITalkSfx, PATCH_JUMP);
-// InjectHook(0x572280, &cAudioManager::GetFemaleNo3TalkSfx, PATCH_JUMP);
-// InjectHook(0x5712B0, &cAudioManager::GetFiremanTalkSfx, PATCH_JUMP);
-// InjectHook(0x574E50, &cAudioManager::GetFrankieTalkSfx, PATCH_JUMP);
-// InjectHook(0x575510, &cAudioManager::GetGenericFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x575460, &cAudioManager::GetGenericMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x571C30, &cAudioManager::GetHoodTalkSfx, PATCH_JUMP);
-// InjectHook(0x5741F0, &cAudioManager::GetHospitalFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574120, &cAudioManager::GetHospitalMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x56F410, &cAudioManager::GetJumboTaxiFreq, PATCH_JUMP);
-// InjectHook(0x573310, &cAudioManager::GetLittleItalyFemaleOldTalkSfx, PATCH_JUMP);
-// InjectHook(0x573400, &cAudioManager::GetLittleItalyFemaleYoungTalkSfx, PATCH_JUMP);
-// InjectHook(0x5731E0, &cAudioManager::GetLittleItalyMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x571510, &cAudioManager::GetMafiaTalkSfx, PATCH_JUMP);
-// InjectHook(0x571F40, &cAudioManager::GetMaleNo2TalkSfx, PATCH_JUMP);
-// InjectHook(0x5711C0, &cAudioManager::GetMedicTalkSfx, PATCH_JUMP);
-// InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP);
-// InjectHook(0x574F00, &cAudioManager::GetMistyTalkSfx, PATCH_JUMP);
-// InjectHook(0x575340, &cAudioManager::GetNormalMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x57A8A0, &cAudioManager::GetNum3DProvidersAvailable, PATCH_JUMP);
-// InjectHook(0x574FD0, &cAudioManager::GetOJGTalkSfx, PATCH_JUMP);
-// InjectHook(0x570960, &cAudioManager::GetPedCommentSfx, PATCH_JUMP);
-// InjectHook(0x570DB0, &cAudioManager::GetPhrase, PATCH_JUMP);
-// InjectHook(0x56BF80, &cAudioManager::GetVehicleDriveWheelSkidValue, PATCH_JUMP);
-// InjectHook(0x56C120, &cAudioManager::GetVehicleNonDriveWheelSkidValue, PATCH_JUMP);
-// InjectHook(0x575240, &cAudioManager::GetPimpTalkSfx, PATCH_JUMP);
-// InjectHook(0x570E00, &cAudioManager::GetPlayerTalkSfx, PATCH_JUMP);
-// InjectHook(0x5737E0, &cAudioManager::GetScumFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5736D0, &cAudioManager::GetScumMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x575060, &cAudioManager::GetSecurityGuardTalkSfx, PATCH_JUMP);
-// InjectHook(0x574480, &cAudioManager::GetShopperFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574790, &cAudioManager::GetSpecialCharacterTalkSfx, PATCH_JUMP);
-// InjectHook(0x573E90, &cAudioManager::GetStewardFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x573DC0, &cAudioManager::GetStewardMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574690, &cAudioManager::GetStudentFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574590, &cAudioManager::GetStudentMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x573CD0, &cAudioManager::GetSupermodelFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x573BD0, &cAudioManager::GetSupermodelMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x570F80, &cAudioManager::GetSwatTalkSfx, PATCH_JUMP);
-// InjectHook(0x575190, &cAudioManager::GetTaxiDriverTalkSfx, PATCH_JUMP);
-// InjectHook(0x571650, &cAudioManager::GetTriadTalkSfx, PATCH_JUMP);
-// InjectHook(0x5723A0, &cAudioManager::GetWhiteBusinessFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x572170, &cAudioManager::GetWhiteCasualFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x574290, &cAudioManager::GetWhiteConstructionWorkerTalkSfx, PATCH_JUMP);
-// InjectHook(0x571E60, &cAudioManager::GetWhiteCriminalTalkSfx, PATCH_JUMP);
-// InjectHook(0x5734F0, &cAudioManager::GetWhiteDockerMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5727B0, &cAudioManager::GetWhiteFatFemaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5725D0, &cAudioManager::GetWhiteFatMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5729D0, &cAudioManager::GetWhiteFemaleProstituteTalkSfx, PATCH_JUMP);
-// InjectHook(0x5738D0, &cAudioManager::GetWhiteWorkerMaleTalkSfx, PATCH_JUMP);
-// InjectHook(0x5718D0, &cAudioManager::GetYakuzaTalkSfx, PATCH_JUMP);
-// InjectHook(0x5719E0, &cAudioManager::GetYardieTalkSfx, PATCH_JUMP);
-// InjectHook(0x56CAB0, &cAudioManager::HasAirBrakes, PATCH_JUMP);
-// InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
-// InjectHook(0x57B030, &cAudioManager::InterrogateAudioEntities, PATCH_JUMP);
-// InjectHook(0x57AA50, &cAudioManager::IsAudioInitialised, PATCH_JUMP);
-// InjectHook(0x579650, &cAudioManager::IsMissionAudioSampleFinished, PATCH_JUMP);
-// InjectHook(0x57A9C0, &cAudioManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
-// InjectHook(0x579520, &cAudioManager::MissionScriptAudioUsesPoliceChannel, PATCH_JUMP);
-// InjectHook(0x56AD10, &cAudioManager::PlayerJustGotInCar, PATCH_JUMP);
-// InjectHook(0x56AD20, &cAudioManager::PlayerJustLeftCar, PATCH_JUMP);
-// InjectHook(0x579620, &cAudioManager::PlayLoadedMissionAudio, PATCH_JUMP);
-// InjectHook(0x57A500, &cAudioManager::PlayOneShot, PATCH_JUMP);
-// InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
-// InjectHook(0x569640, &cAudioManager::PostTerminateGameSpecificShutdown, PATCH_JUMP);
-// InjectHook(0x569400, &cAudioManager::PreInitialiseGameSpecificSetup, PATCH_JUMP);
-// InjectHook(0x579550, &cAudioManager::PreloadMissionAudio, PATCH_JUMP);
-// InjectHook(0x569570, &cAudioManager::PreTerminateGameSpecificShutdown, PATCH_JUMP);
-// InjectHook(0x57BA60, &cAudioManager::ProcessActiveQueues, PATCH_JUMP);
-// InjectHook(0x56C940, &cAudioManager::ProcessAirBrakes, PATCH_JUMP);
-// InjectHook(0x577B30, &cAudioManager::ProcessAirportScriptObject, PATCH_JUMP);
-// InjectHook(0x56DE80, &cAudioManager::ProcessBoatEngine, PATCH_JUMP);
-// InjectHook(0x56E500, &cAudioManager::ProcessBoatMovingOverWater, PATCH_JUMP);
-// InjectHook(0x5790D0, &cAudioManager::ProcessBridge, PATCH_JUMP);
-// InjectHook(0x579250, &cAudioManager::ProcessBridgeMotor, PATCH_JUMP);
-// InjectHook(0x579310, &cAudioManager::ProcessBridgeOneShots, PATCH_JUMP);
-// InjectHook(0x579170, &cAudioManager::ProcessBridgeWarning, PATCH_JUMP);
-// InjectHook(0x56CC20, &cAudioManager::ProcessCarBombTick, PATCH_JUMP);
-// InjectHook(0x577CA0, &cAudioManager::ProcessCinemaScriptObject, PATCH_JUMP);
-// InjectHook(0x577E50, &cAudioManager::ProcessDocksScriptObject, PATCH_JUMP);
-// InjectHook(0x56CAF0, &cAudioManager::ProcessEngineDamage, PATCH_JUMP);
-// InjectHook(0x569870, &cAudioManager::ProcessEntity, PATCH_JUMP);
-// InjectHook(0x575AC0, &cAudioManager::ProcessExplosions, PATCH_JUMP);
-// InjectHook(0x578FD0, &cAudioManager::ProcessFireHydrant, PATCH_JUMP);
-// InjectHook(0x5785E0, &cAudioManager::ProcessFrontEnd, PATCH_JUMP);
-// InjectHook(0x56E6A0, &cAudioManager::ProcessHelicopter, PATCH_JUMP);
-// InjectHook(0x577FE0, &cAudioManager::ProcessHomeScriptObject, PATCH_JUMP);
-// InjectHook(0x56E8F0, &cAudioManager::ProcessJumbo, PATCH_JUMP);
-// InjectHook(0x56EA40, &cAudioManager::ProcessJumboAccel, PATCH_JUMP);
-// InjectHook(0x56EE40, &cAudioManager::ProcessJumboDecel, PATCH_JUMP);
-// InjectHook(0x56ECF0, &cAudioManager::ProcessJumboFlying, PATCH_JUMP);
-// InjectHook(0x56ED10, &cAudioManager::ProcessJumboLanding, PATCH_JUMP);
-// InjectHook(0x56EC00, &cAudioManager::ProcessJumboTakeOff, PATCH_JUMP);
-// InjectHook(0x56EA10, &cAudioManager::ProcessJumboTaxi, PATCH_JUMP);
-// InjectHook(0x5777E0, &cAudioManager::ProcessLaunderetteScriptObject, PATCH_JUMP);
-// InjectHook(0x576770, &cAudioManager::ProcessLoopingScriptObject, PATCH_JUMP);
-// InjectHook(0x5796E0, &cAudioManager::ProcessMissionAudio, PATCH_JUMP);
-// InjectHook(0x56A050, &cAudioManager::ProcessModelCarEngine, PATCH_JUMP);
-// InjectHook(0x5760C0, &cAudioManager::ProcessOneShotScriptObject, PATCH_JUMP);
-// InjectHook(0x56F450, &cAudioManager::ProcessPed, PATCH_JUMP);
-// InjectHook(0x56F4D0, &cAudioManager::ProcessPedHeadphones, PATCH_JUMP);
-// InjectHook(0x56F650, &cAudioManager::ProcessPedOneShots, PATCH_JUMP);
-// InjectHook(0x5699C0, &cAudioManager::ProcessPhysical, PATCH_JUMP);
-// InjectHook(0x56E860, &cAudioManager::ProcessPlane, PATCH_JUMP);
-// InjectHook(0x56B0D0, &cAudioManager::ProcessPlayersVehicleEngine, PATCH_JUMP);
-// InjectHook(0x578190, &cAudioManager::ProcessPoliceCellBeatingScriptObject, PATCH_JUMP);
-// InjectHook(0x577280, &cAudioManager::ProcessPornCinema, PATCH_JUMP);
-// InjectHook(0x578A80, &cAudioManager::ProcessProjectiles, PATCH_JUMP);
-// InjectHook(0x569CC0, &cAudioManager::ProcessRainOnVehicle, PATCH_JUMP);
-// InjectHook(0x569700, &cAudioManager::ProcessReverb, PATCH_JUMP);
-// InjectHook(0x569E50, &cAudioManager::ProcessReverseGear, PATCH_JUMP);
-// InjectHook(0x577630, &cAudioManager::ProcessSawMillScriptObject, PATCH_JUMP);
-// InjectHook(0x576070, &cAudioManager::ProcessScriptObject, PATCH_JUMP);
-// InjectHook(0x577970, &cAudioManager::ProcessShopScriptObject, PATCH_JUMP);
-// InjectHook(0x5697D0, &cAudioManager::ProcessSpecial, PATCH_JUMP);
-// InjectHook(0x56DBF0, &cAudioManager::ProcessTrainNoise, PATCH_JUMP);
-// InjectHook(0x569A00, &cAudioManager::ProcessVehicle, PATCH_JUMP);
-// InjectHook(0x56C770, &cAudioManager::ProcessVehicleDoors, PATCH_JUMP);
-// InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
-// InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
-// InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
-// InjectHook(0x56C420, &cAudioManager::ProcessVehicleSirenOrAlarm, PATCH_JUMP);
-// InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
-// InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
-// InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
-// InjectHook(0x56A440, &cAudioManager::ProcessWetRoadNoise, PATCH_JUMP);
-// InjectHook(0x577530, &cAudioManager::ProcessWorkShopScriptObject, PATCH_JUMP);
-// InjectHook(0x57AF90, &cAudioManager::RandomDisplacement, PATCH_JUMP);
-// InjectHook(0x57A9F0, &cAudioManager::ReacquireDigitalHandle, PATCH_JUMP);
-// InjectHook(0x57A9E0, &cAudioManager::ReleaseDigitalHandle, PATCH_JUMP);
-// InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP);
-// InjectHook(0x57A7B0, &cAudioManager::ResetTimers, PATCH_JUMP);
-// InjectHook(0x57A2A0, &cAudioManager::Service, PATCH_JUMP);
-// InjectHook(0x57AA60, &cAudioManager::ServiceSoundEffects, PATCH_JUMP);
-// InjectHook(0x57A910, &cAudioManager::SetCurrent3DProvider, PATCH_JUMP);
-// InjectHook(0x57AA00, &cAudioManager::SetDynamicAcousticModelingStatus, PATCH_JUMP);
-// InjectHook(0x57A770, &cAudioManager::SetEffectsFadeVolume, PATCH_JUMP);
-// InjectHook(0x57A730, &cAudioManager::SetEffectsMasterVolume, PATCH_JUMP);
-// InjectHook(0x57A4C0, &cAudioManager::SetEntityStatus, PATCH_JUMP);
-// InjectHook(0x5795F0, &cAudioManager::SetMissionAudioLocation, PATCH_JUMP);
-// InjectHook(0x57A790, &cAudioManager::SetMusicFadeVolume, PATCH_JUMP);
-// InjectHook(0x57A750, &cAudioManager::SetMusicMasterVolume, PATCH_JUMP);
-// InjectHook(0x57A9A0, &cAudioManager::SetSpeakerConfig, PATCH_JUMP);
-// InjectHook(0x56F230, &cAudioManager::SetupJumboFlySound, PATCH_JUMP);
-// InjectHook(0x56F310, &cAudioManager::SetupJumboRumbleSound, PATCH_JUMP);
-// InjectHook(0x56EF20, &cAudioManager::SetupJumboTaxiSound, PATCH_JUMP);
-// InjectHook(0x56F070, &cAudioManager::SetupJumboWhineSound, PATCH_JUMP);
-// InjectHook(0x570690, &cAudioManager::SetupPedComments, PATCH_JUMP);
-// InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
-// InjectHook(0x57AC60, &cAudioManager::TranslateEntity, PATCH_JUMP);
-// InjectHook(0x56AC80, &cAudioManager::UpdateGasPedalAudio, PATCH_JUMP);
-// InjectHook(0x57B470, &cAudioManager::UpdateReflections, PATCH_JUMP);
-// InjectHook(0x56C600, &cAudioManager::UsesReverseWarning, PATCH_JUMP);
-// InjectHook(0x56C3C0, &cAudioManager::UsesSiren, PATCH_JUMP);
-// InjectHook(0x56C3F0, &cAudioManager::UsesSirenSwitching, PATCH_JUMP);
-
-// InjectHook(0x57C2B0, &cAudioManager::AdjustSamplesVolume, PATCH_JUMP);
-// InjectHook(0x57C320, &cAudioManager::ComputeEmittingVolume, PATCH_JUMP);
-
-// InjectHook(0x5755C0, &cPedComments::Add, PATCH_JUMP);
-// InjectHook(0x575730, &cPedComments::Process, PATCH_JUMP);
-// ENDPATCHES
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 31a07f9b..72d8ba41 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -118,7 +118,7 @@ enum eScriptSounds : int16 {
SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106,
SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107,
SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108,
- SCRIPT_SOUND_109 = 109,
+ SCRIPT_SOUND_BULLET_HIT_WATER = 109, //no sound
SCRIPT_SOUND_110 = 110,
SCRIPT_SOUND_111 = 111,
SCRIPT_SOUND_PAYPHONE_RINGING = 112,
@@ -143,28 +143,17 @@ public:
int32 m_nSampleIndex;
uint8 m_bBankIndex;
bool m_bIs2D;
- uint8 field_14; // unused
- uint8 field_15; // unused
int32 m_nReleasingVolumeModificator;
int32 m_nFrequency;
uint8 m_bVolume;
- uint8 field_25; // unused
- uint8 field_26; // unused
- uint8 field_27; // unused
float m_fDistance;
int32 m_nLoopCount;
int32 m_nLoopStart;
int32 m_nLoopEnd;
uint8 m_bEmittingVolume;
- uint8 field_45; // unused
- uint8 field_46; // unused
- uint8 field_47; // unused
float m_fSpeedMultiplier;
float m_fSoundIntensity;
bool m_bReleasingSoundFlag;
- uint8 field_57; // unused
- uint8 field_58; // unused
- uint8 field_59; // unused
CVector m_vecPos;
bool m_bReverbFlag;
uint8 m_bLoopsRemaining;
@@ -173,15 +162,8 @@ public:
int32 m_nReleasingVolumeDivider;
bool m_bIsProcessed;
bool m_bLoopEnded;
- uint8 field_82; // unused
- uint8 field_83; // unused
int32 m_nCalculatedVolume;
int8 m_nVolumeChange;
- uint8 field_89; // unused
- uint8 field_90; // unused
- uint8 field_91; // unused
-
- // no methods
};
static_assert(sizeof(tSound) == 92, "tSound: error");
@@ -197,12 +179,8 @@ public:
bool m_bIsUsed;
uint8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
- //uint8 gap_18[2];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents;
- uint8 field_25[3];
-
- // no methods
};
static_assert(sizeof(tAudioEntity) == 40, "tAudioEntity: error");
@@ -216,8 +194,6 @@ public:
float m_fDistance;
uint8 m_bVolume;
int8 m_nProcess;
-
- // no methods
};
static_assert(sizeof(tPedComment) == 28, "tPedComment: error");
@@ -244,18 +220,12 @@ class cMissionAudio
public:
CVector m_vecPos;
bool m_bPredefinedProperties;
- //uint8 gap_13[3];
int m_nSampleIndex;
uint8 m_bLoadingStatus;
uint8 m_bPlayStatus;
uint8 field_22; // todo find a name
- uint8 field_23; // unused
int32 m_nMissionAudioCounter;
bool m_bIsPlayed;
- uint8 field_29; // unused
- uint8 field_30; // unused
- uint8 field_31; // unused
- // no methods
};
static_assert(sizeof(cMissionAudio) == 32, "cMissionAudio: error");
@@ -305,17 +275,11 @@ public:
uint8 m_bActiveSamples;
uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus;
- uint8 field_6; // unused
- uint8 field_7; // unused
float m_fSpeedOfSound;
bool m_bTimerJustReset;
- uint8 field_13; // unused
- uint8 field_14; // unused
- uint8 field_15; // unused
int32 m_nTimer;
tSound m_sQueueSample;
bool m_bActiveSampleQueue;
- uint8 gap_109[3]; // unused
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_bSampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS];
@@ -341,7 +305,6 @@ public:
uint8 m_bTimeSpent;
uint8 m_bUserPause;
uint8 m_bPreviousUserPause;
- uint8 field_19195; // unused
uint32 m_FrameCounter;
cAudioManager();
@@ -618,6 +581,6 @@ public:
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
};
-static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
extern cAudioManager AudioManager;
diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp
index da9e1d2e..3d84006d 100644
--- a/src/audio/AudioScriptObject.cpp
+++ b/src/audio/AudioScriptObject.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AudioScriptObject.h"
#include "Pools.h"
#include "DMAudio.h"
@@ -86,10 +86,3 @@ PlayOneShotScriptObject(uint8 id, CVector const &pos)
audioScriptObject->AudioEntity = AEHANDLE_NONE;
DMAudio.CreateOneShotScriptObject(audioScriptObject);
}
-
-STARTPATCHES
-InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP);
-InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP);
-InjectHook(0x57C560, &cAudioScriptObject::LoadAllAudioScriptObjects, PATCH_JUMP);
-InjectHook(0x57c460, &cAudioScriptObject::SaveAllAudioScriptObjects, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index a01c85ae..11c85dbd 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -1,12 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "DMAudio.h"
#include "MusicManager.h"
#include "AudioManager.h"
#include "AudioScriptObject.h"
#include "sampman.h"
-cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
+cDMAudio DMAudio;
void
cDMAudio::Initialise(void)
@@ -318,57 +318,3 @@ cDMAudio::SetRadioChannel(int8 radio, int32 pos)
{
MusicManager.SetRadioChannelByScript(radio, pos);
}
-
-STARTPATCHES
- InjectHook(0x57C760, &cDMAudio::Initialise, PATCH_JUMP);
- InjectHook(0x57C780, &cDMAudio::Terminate, PATCH_JUMP);
- InjectHook(0x57C7A0, &cDMAudio::Service, PATCH_JUMP);
- InjectHook(0x57C7C0, &cDMAudio::CreateEntity, PATCH_JUMP);
- InjectHook(0x57C7F0, &cDMAudio::DestroyEntity, PATCH_JUMP);
- InjectHook(0x57C810, &cDMAudio::SetEntityStatus, PATCH_JUMP);
- InjectHook(0x57C840, &cDMAudio::PlayOneShot, PATCH_JUMP);
- InjectHook(0x57C870, &cDMAudio::DestroyAllGameCreatedEntities, PATCH_JUMP);
- InjectHook(0x57C890, &cDMAudio::SetEffectsMasterVolume, PATCH_JUMP);
- InjectHook(0x57C8C0, &cDMAudio::SetMusicMasterVolume, PATCH_JUMP);
- InjectHook(0x57C8F0, &cDMAudio::SetEffectsFadeVol, PATCH_JUMP);
- InjectHook(0x57C920, &cDMAudio::SetMusicFadeVol, PATCH_JUMP);
- InjectHook(0x57C950, &cDMAudio::GetNum3DProvidersAvailable, PATCH_JUMP);
- InjectHook(0x57C970, &cDMAudio::Get3DProviderName, PATCH_JUMP);
- InjectHook(0x57C990, &cDMAudio::GetCurrent3DProviderIndex, PATCH_JUMP);
- InjectHook(0x57C9B0, &cDMAudio::SetCurrent3DProvider, PATCH_JUMP);
- InjectHook(0x57C9D0, &cDMAudio::SetSpeakerConfig, PATCH_JUMP);
- InjectHook(0x57C9F0, &cDMAudio::IsMP3RadioChannelAvailable, PATCH_JUMP);
- InjectHook(0x57CA10, &cDMAudio::ReleaseDigitalHandle, PATCH_JUMP);
- InjectHook(0x57CA30, &cDMAudio::ReacquireDigitalHandle, PATCH_JUMP);
- InjectHook(0x57CA50, &cDMAudio::SetDynamicAcousticModelingStatus, PATCH_JUMP);
- InjectHook(0x57CA70, &cDMAudio::CheckForAnAudioFileOnCD, PATCH_JUMP);
- InjectHook(0x57CA90, &cDMAudio::GetCDAudioDriveLetter, PATCH_JUMP);
- InjectHook(0x57CAB0, &cDMAudio::IsAudioInitialised, PATCH_JUMP);
- InjectHook(0x57CAD0, &cDMAudio::ReportCrime, PATCH_JUMP);
- InjectHook(0x57CB00, &cDMAudio::CreateLoopingScriptObject, PATCH_JUMP);
- InjectHook(0x57CB40, &cDMAudio::DestroyLoopingScriptObject, PATCH_JUMP);
- InjectHook(0x57CB60, &cDMAudio::CreateOneShotScriptObject, PATCH_JUMP);
- InjectHook(0x57CBB0, &cDMAudio::PlaySuspectLastSeen, PATCH_JUMP);
- InjectHook(0x57CBE0, &cDMAudio::ReportCollision, PATCH_JUMP);
- InjectHook(0x57CC20, &cDMAudio::PlayFrontEndSound, PATCH_JUMP);
- InjectHook(0x57CC60, &cDMAudio::PlayRadioAnnouncement, PATCH_JUMP);
- InjectHook(0x57CC80, &cDMAudio::PlayFrontEndTrack, PATCH_JUMP);
- InjectHook(0x57CCB0, &cDMAudio::StopFrontEndTrack, PATCH_JUMP);
- InjectHook(0x57CCD0, &cDMAudio::ResetTimers, PATCH_JUMP);
- InjectHook(0x57CCF0, &cDMAudio::ChangeMusicMode, PATCH_JUMP);
- InjectHook(0x57CD10, &cDMAudio::PreloadCutSceneMusic, PATCH_JUMP);
- InjectHook(0x57CD30, &cDMAudio::PlayPreloadedCutSceneMusic, PATCH_JUMP);
- InjectHook(0x57CD50, &cDMAudio::StopCutSceneMusic, PATCH_JUMP);
- InjectHook(0x57CD70, &cDMAudio::PreloadMissionAudio, PATCH_JUMP);
- InjectHook(0x57CD90, &cDMAudio::GetMissionAudioLoadingStatus, PATCH_JUMP);
- InjectHook(0x57CDB0, &cDMAudio::SetMissionAudioLocation, PATCH_JUMP);
- InjectHook(0x57CDE0, &cDMAudio::PlayLoadedMissionAudio, PATCH_JUMP);
- InjectHook(0x57CE00, &cDMAudio::IsMissionAudioSampleFinished, PATCH_JUMP);
- InjectHook(0x57CE20, &cDMAudio::ClearMissionAudio, PATCH_JUMP);
- InjectHook(0x57CE40, &cDMAudio::GetRadioInCar, PATCH_JUMP);
- InjectHook(0x57CE60, &cDMAudio::SetRadioInCar, PATCH_JUMP);
- InjectHook(0x57CE80, &cDMAudio::SetRadioChannel, PATCH_JUMP);
-
- //InjectHook(0x57CEB0, `global constructor keyed to'dmaudio.cpp, PATCH_JUMP);
- //InjectHook(0x57CED0, cDMAudio::~cDMAudio, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index d2cdf466..42688fa6 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -1,6 +1,7 @@
#pragma once
#include "audio_enums.h"
+#include "Crime.h"
enum eSound : int16
{
@@ -179,7 +180,6 @@ enum eSound : int16
class cAudioScriptObject;
class CEntity;
-enum eCrimeType;
class cDMAudio
{
@@ -256,4 +256,4 @@ public:
void SetRadioInCar(uint32 radio);
void SetRadioChannel(int8 radio, int32 pos);
};
-extern cDMAudio &DMAudio;
+extern cDMAudio DMAudio;
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index d840c57b..efea6e45 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -13,12 +13,12 @@
#include "Timer.h"
#include "World.h"
#include "sampman.h"
-#include "patcher.h"
-cMusicManager &MusicManager = *(cMusicManager *)0x8F3964;
-int32 &gNumRetunePresses = *(int32 *)0x650B80;
-int32 &gRetuneCounter = *(int32*)0x650B84;
-bool& bHasStarted = *(bool*)0x650B7C;
+
+cMusicManager MusicManager;
+int32 gNumRetunePresses;
+int32 gRetuneCounter;
+bool bHasStarted;
const int maxVolume = 127;
@@ -51,6 +51,12 @@ cMusicManager::PlayerInCar()
if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
return false;
+ if (!FindPlayerVehicle())
+ return true;
+
+ if (FindPlayerVehicle()->m_status == STATUS_WRECKED)
+ return false;
+
switch(FindPlayerVehicle()->m_modelIndex) {
case MI_FIRETRUCK:
case MI_AMBULAN:
@@ -699,7 +705,7 @@ cMusicManager::GetTrackStartPos(uint8 track)
result = m_aTracks[track].m_nPosition;
m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
} else
- result = min(CTimer::GetTimeInMillisecondsPauseMode() - timer, 90000) + m_aTracks[track].m_nPosition;
+ result = Min(CTimer::GetTimeInMillisecondsPauseMode() - timer, 90000) + m_aTracks[track].m_nPosition;
if (result > m_aTracks[track].m_nLength) result %= m_aTracks[track].m_nLength;
return result;
@@ -904,34 +910,3 @@ cMusicManager::ChangeRadioChannel()
}
return true;
}
-
-STARTPATCHES
-InjectHook(0x57E4B0, &cMusicManager::PlayerInCar, PATCH_JUMP);
-InjectHook(0x57E6D0, &cMusicManager::DisplayRadioStationName, PATCH_JUMP);
-InjectHook(0x57CF70, &cMusicManager::Initialise, PATCH_JUMP);
-InjectHook(0x57D140, &cMusicManager::Terminate, PATCH_JUMP);
-InjectHook(0x57D1D0, &cMusicManager::GetRadioInCar, PATCH_JUMP);
-InjectHook(0x57D2C0, &cMusicManager::SetRadioInCar, PATCH_JUMP);
-InjectHook(0x57D180, &cMusicManager::SetRadioChannelByScript, PATCH_JUMP);
-InjectHook(0x57CF30, &cMusicManager::ResetMusicAfterReload, PATCH_JUMP);
-InjectHook(0x57E6A0, &cMusicManager::UsesPoliceRadio, PATCH_JUMP);
-InjectHook(0x57D310, &cMusicManager::ChangeMusicMode, PATCH_JUMP);
-InjectHook(0x57D420, &cMusicManager::ResetTimers, PATCH_JUMP);
-InjectHook(0x57D440, &cMusicManager::Service, PATCH_JUMP);
-InjectHook(0x57D530, &cMusicManager::ServiceFrontEndMode, PATCH_JUMP);
-InjectHook(0x57E3D0, &cMusicManager::StopFrontEndTrack, PATCH_JUMP);
-InjectHook(0x57E430, &cMusicManager::PlayAnnouncement, PATCH_JUMP);
-InjectHook(0x57E2E0, &cMusicManager::PlayFrontEndTrack, PATCH_JUMP);
-InjectHook(0x57E210, &cMusicManager::PreloadCutSceneMusic, PATCH_JUMP);
-InjectHook(0x57E290, &cMusicManager::PlayPreloadedCutSceneMusic, PATCH_JUMP);
-InjectHook(0x57E2B0, &cMusicManager::StopCutSceneMusic, PATCH_JUMP);
-InjectHook(0x57E450, &cMusicManager::GetTrackStartPos, PATCH_JUMP);
-InjectHook(0x57D690, &cMusicManager::ServiceGameMode, PATCH_JUMP);
-InjectHook(0x57DCB0, &cMusicManager::ServiceAmbience, PATCH_JUMP);
-InjectHook(0x57DEA0, &cMusicManager::ComputeAmbienceVol, PATCH_JUMP);
-InjectHook(0x57E100, &cMusicManager::ServiceTrack, PATCH_JUMP);
-InjectHook(0x57DFC0, &cMusicManager::ServiceAnnouncement, PATCH_JUMP);
-InjectHook(0x57E530, &cMusicManager::GetCarTuning, PATCH_JUMP);
-InjectHook(0x57E5A0, &cMusicManager::GetNextCarTuning, PATCH_JUMP);
-InjectHook(0x57E130, &cMusicManager::ChangeRadioChannel, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h
index 5c255069..5d6f41cf 100644
--- a/src/audio/MusicManager.h
+++ b/src/audio/MusicManager.h
@@ -86,4 +86,4 @@ public:
static_assert(sizeof(cMusicManager) == 0x95C, "cMusicManager: error");
-extern cMusicManager &MusicManager;
+extern cMusicManager MusicManager;
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 255d7026..c4946da6 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -1,15 +1,18 @@
#include "common.h"
-#include "patcher.h"
+
#include "DMAudio.h"
+
#include "AudioManager.h"
+
#include "AudioSamples.h"
#include "MusicManager.h"
-#include "PoliceRadio.h"
#include "PlayerPed.h"
-#include "sampman.h"
-#include "Zones.h"
+#include "PoliceRadio.h"
+#include "Replay.h"
#include "Vehicle.h"
#include "World.h"
+#include "Zones.h"
+#include "sampman.h"
const int maxVolume = 127;
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
@@ -21,14 +24,14 @@ struct tPoliceRadioZone {
int32 field_12;
};
-tPoliceRadioZone (&ZoneSfx)[NUMAUDIOZONES] = *(tPoliceRadioZone(*)[NUMAUDIOZONES])*(uintptr*)0x880240;
-char *SubZo2Label = (char*)0x6E9918;
-char *SubZo3Label = (char*)0x6E9870;
+tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
+char SubZo2Label[8];
+char SubZo3Label[8];
-int32 &g_nMissionAudioSfx = *(int32*)0x60ED84;
-int8 &g_nMissionAudioPlayingStatus = *(int8*)0x60ED88;
-uint8 &gSpecialSuspectLastSeenReport = *(uint8*)0x95CD4D;
-uint32 (&gMinTimeToNextReport)[NUM_CRIME_TYPES] = *(uint32(*)[NUM_CRIME_TYPES])*(uintptr*)0x8E2828;
+int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
+int8 g_nMissionAudioPlayingStatus = 2;
+uint8 gSpecialSuspectLastSeenReport;
+uint32 gMinTimeToNextReport[NUM_CRIME_TYPES];
void
cAudioManager::InitialisePoliceRadioZones()
@@ -155,7 +158,8 @@ cAudioManager::ServicePoliceRadio()
if(!m_bUserPause) {
bool crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef
- if(!FindPlayerPed() || !FindPlayerPed()->m_pWanted) return;
+ if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
+ return;
#endif
wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
if(!crimeReport) {
@@ -774,19 +778,3 @@ cAudioManager::AgeCrimes()
}
}
}
-
-STARTPATCHES
-InjectHook(0x580AF0, &cAudioManager::AgeCrimes, PATCH_JUMP);
-InjectHook(0x57F060, &cAudioManager::DoPoliceRadioCrackle, PATCH_JUMP);
-InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP);
-InjectHook(0x57EEC0, &cAudioManager::InitialisePoliceRadio, PATCH_JUMP);
-InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);
-InjectHook(0x580500, &cAudioManager::PlaySuspectLastSeen, PATCH_JUMP);
-InjectHook(0x5803D0, &cAudioManager::ReportCrime, PATCH_JUMP);
-InjectHook(0x57EFF0, &cAudioManager::ResetPoliceRadio, PATCH_JUMP);
-InjectHook(0x57F110, &cAudioManager::ServicePoliceRadio, PATCH_JUMP);
-InjectHook(0x57F1B0, &cAudioManager::ServicePoliceRadioChannel, PATCH_JUMP);
-InjectHook(0x57F020, &cAudioManager::SetMissionScriptPoliceAudio, PATCH_JUMP);
-InjectHook(0x57F5B0, &cAudioManager::SetupCrimeReport, PATCH_JUMP);
-InjectHook(0x57FCC0, &cAudioManager::SetupSuspectLastSeenReport, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/miles/sampman_mss.cpp
new file mode 100644
index 00000000..f3a6ba80
--- /dev/null
+++ b/src/audio/miles/sampman_mss.cpp
@@ -0,0 +1,2257 @@
+#include <windows.h>
+#include <shobjidl.h>
+#include <shlguid.h>
+
+#include <time.h>
+
+#include "eax.h"
+#include "eax-util.h"
+#include "mss.h"
+
+#include "sampman_mss.h"
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+
+#pragma comment( lib, "mss32.lib" )
+
+cSampleManager SampleManager;
+int32 BankStartOffset[MAX_SAMPLEBANKS];
+///////////////////////////////////////////////////////////////
+
+char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
+char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
+
+FILE *fpSampleDescHandle;
+FILE *fpSampleDataHandle;
+bool bSampleBankLoaded [MAX_SAMPLEBANKS];
+int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
+int32 nSampleBankSize [MAX_SAMPLEBANKS];
+int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
+int32 _nSampleDataEndOffset;
+
+int32 nPedSlotSfx [MAX_PEDSFX];
+int32 nPedSlotSfxAddr[MAX_PEDSFX];
+uint8 nCurrentPedSlot;
+
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+
+///////////////////////////////////////////////////////////////
+struct tMP3Entry
+{
+ char aFilename[MAX_PATH];
+
+ uint32 nTrackLength;
+ uint32 nTrackStreamPos;
+
+ tMP3Entry *pNext;
+ char *pLinkPath;
+};
+
+uint32 nNumMP3s;
+tMP3Entry *_pMP3List;
+char _mp3DirectoryPath[MAX_PATH];
+HSTREAM mp3Stream [MAX_MP3STREAMS];
+int8 nStreamPan [MAX_MP3STREAMS];
+int8 nStreamVolume[MAX_MP3STREAMS];
+uint32 _CurMP3Index;
+int32 _CurMP3Pos;
+bool _bIsMp3Active;
+
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+bool _bUseHDDAudio;
+char _aHDDPath[MAX_PATH];
+#endif
+///////////////////////////////////////////////////////////////
+
+
+bool _bSampmanInitialised = false;
+
+//
+// Miscellaneous globals / defines
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+
+EAXLISTENERPROPERTIES StartEAX3 =
+ {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f };
+
+EAXLISTENERPROPERTIES FinishEAX3 =
+ {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f };
+
+EAXLISTENERPROPERTIES EAX3Params;
+
+S32 prevprovider=-1;
+S32 curprovider=-1;
+S32 usingEAX=0;
+S32 usingEAX3=0;
+HPROVIDER opened_provider=0;
+H3DSAMPLE opened_samples[MAXCHANNELS] = {0};
+HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
+HDIGDRIVER DIG;
+S32 speaker_type=0;
+
+U32 _maxSamples;
+float _fPrevEaxRatioDestination;
+bool _usingMilesFast2D;
+float _fEffectsLevel;
+
+
+struct
+{
+ HPROVIDER id;
+ char name[80];
+}providers[MAXPROVIDERS];
+
+typedef struct provider_stuff
+{
+ char* name;
+ HPROVIDER id;
+} provider_stuff;
+
+
+static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
+{
+ return( _stricmp(s1->name,s2->name) );
+}
+
+static void
+add_providers()
+{
+ provider_stuff pi[MAXPROVIDERS];
+ U32 n,i,j;
+
+ SampleManager.SetNum3DProvidersAvailable(0);
+
+ HPROENUM next = HPROENUM_FIRST;
+
+ n=0;
+ while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n<MAXPROVIDERS))
+ {
+ ++n;
+ }
+
+ qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp);
+
+ for(i=0;i<n;i++)
+ {
+ providers[i].id=pi[i].id;
+ strcpy(providers[i].name, pi[i].name);
+ SampleManager.Set3DProviderName(i, providers[i].name);
+ }
+
+ SampleManager.SetNum3DProvidersAvailable(n);
+
+ for(j=n;j<MAXPROVIDERS;j++)
+ SampleManager.Set3DProviderName(j, NULL);
+}
+
+static void
+release_existing()
+{
+ for ( U32 i = 0; i < _maxSamples; i++ )
+ {
+ if ( opened_samples[i] )
+ {
+ AIL_release_3D_sample_handle(opened_samples[i]);
+ opened_samples[i] = NULL;
+ }
+ }
+
+ if ( opened_provider )
+ {
+ AIL_close_3D_provider(opened_provider);
+ opened_provider = NULL;
+ }
+
+ _fPrevEaxRatioDestination = 0.0f;
+ _usingMilesFast2D = false;
+ _fEffectsLevel = 0.0f;
+}
+
+static bool
+set_new_provider(S32 index)
+{
+ DWORD result;
+
+ if ( curprovider == index )
+ return true;
+
+ //close the already opened provider
+ curprovider = index;
+
+ release_existing();
+
+ if ( curprovider != -1 )
+ {
+ if ( !strcmp(providers[index].name, "Dolby Surround") )
+ _maxSamples = MAXCHANNELS_SURROUND;
+ else
+ _maxSamples = MAXCHANNELS;
+
+ AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples);
+
+ //load the new provider
+ result = AIL_open_3D_provider(providers[index].id);
+
+ if (result != M3D_NOERR)
+ {
+ curprovider=-1;
+
+ OutputDebugStringA(AIL_last_error());
+
+ release_existing();
+
+ return false;
+ }
+ else
+ {
+ opened_provider=providers[index].id;
+
+ //see if we're running under an EAX compatible provider
+
+ if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") )
+ {
+ usingEAX = 1;
+ usingEAX3 = 1;
+ }
+ else
+ {
+ usingEAX3 = 0;
+
+ result=AIL_3D_room_type(opened_provider);
+ usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX
+ }
+
+ if ( usingEAX3 )
+ {
+ OutputDebugString("DOING SPECIAL EAX 3 STUFF!");
+ AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3);
+ }
+ else if ( usingEAX )
+ {
+ AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE);
+
+ if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") )
+ _usingMilesFast2D = true;
+ }
+
+ AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples);
+
+ if ( _maxSamples > MAXCHANNELS )
+ _maxSamples = MAXCHANNELS;
+
+ SampleManager.SetSpeakerConfig(speaker_type);
+
+ //obtain a 3D sample handles
+ for ( U32 i = 0; i < _maxSamples; ++i )
+ {
+ opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider);
+ if ( opened_samples[i] != NULL )
+ AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f);
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::SetSpeakerConfig(int32 which)
+{
+ switch ( which )
+ {
+ case 1:
+ speaker_type=AIL_3D_2_SPEAKER;
+ break;
+
+ case 2:
+ speaker_type=AIL_3D_HEADPHONE;
+ break;
+
+ case 3:
+ speaker_type=AIL_3D_4_SPEAKER;
+ break;
+
+ default:
+ return;
+ break;
+ }
+
+ if (opened_provider)
+ AIL_set_3D_speaker_type(opened_provider, speaker_type);
+}
+
+uint32
+cSampleManager::GetMaximumSupportedChannels(void)
+{
+ if ( _maxSamples > MAXCHANNELS )
+ return MAXCHANNELS;
+
+ return _maxSamples;
+}
+
+int8
+cSampleManager::GetCurrent3DProviderIndex(void)
+{
+ return curprovider;
+}
+
+int8
+cSampleManager::SetCurrent3DProvider(uint8 nProvider)
+{
+ S32 savedprovider = curprovider;
+
+ if ( nProvider < m_nNumberOfProviders )
+ {
+ if ( set_new_provider(nProvider) )
+ return curprovider;
+ else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
+ return curprovider;
+ else
+ return -1;
+ }
+ else
+ return curprovider;
+}
+
+static bool
+_ResolveLink(char const *path, char *out)
+{
+ IShellLink* psl;
+ WIN32_FIND_DATA fd;
+ char filepath[MAX_PATH];
+
+ CoInitialize(NULL);
+
+ if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) ))
+ {
+ IPersistFile *ppf;
+
+ if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
+ {
+ WCHAR wpath[MAX_PATH];
+
+ MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
+
+ if (SUCCEEDED(ppf->Load(wpath, STGM_READ)))
+ {
+ /* Resolve the link */
+ if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH)))
+ {
+ strcpy(filepath, path);
+
+ if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY)))
+ {
+ OutputDebugString(fd.cFileName);
+
+ strcpy(out, filepath);
+ // FIX: Release the objects. Taken from SA.
+#ifdef FIX_BUGS
+ ppf->Release();
+ psl->Release();
+#endif
+ return true;
+ }
+ }
+ }
+
+ ppf->Release();
+ }
+ psl->Release();
+ }
+
+ return false;
+}
+
+static void
+_FindMP3s(void)
+{
+ tMP3Entry *pList;
+ bool bShortcut;
+ bool bInitFirstEntry;
+ HANDLE hFind;
+ char path[MAX_PATH];
+ char filepath[MAX_PATH*2];
+ S32 total_ms;
+ WIN32_FIND_DATA fd;
+
+
+ if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 )
+ {
+ GetLastError();
+ return;
+ }
+
+ OutputDebugString("Finding MP3s...");
+ strcpy(path, _mp3DirectoryPath);
+ strcat(path, "\\MP3\\");
+
+ strcpy(_mp3DirectoryPath, path);
+ OutputDebugString(_mp3DirectoryPath);
+
+ strcat(path, "*");
+
+ hFind = FindFirstFile(path, &fd);
+
+ if ( hFind == INVALID_HANDLE_VALUE )
+ {
+ GetLastError();
+ return;
+ }
+
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( filepathlen <= 0)
+ {
+ FindClose(hFind);
+ return;
+ }
+
+ FILE *f = fopen("MP3\\MP3Report.txt", "w");
+
+ if ( f )
+ {
+ fprintf(f, "MP3 Report File\n\n");
+ fprintf(f, "\"%s\"", fd.cFileName);
+ }
+
+
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ bShortcut = false;
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ OutputDebugString(fd.cFileName);
+
+ _pMP3List = new tMP3Entry;
+
+ if ( _pMP3List == NULL )
+ {
+ FindClose(hFind);
+
+ if ( f )
+ fclose(f);
+
+ return;
+ }
+
+ nNumMP3s = 1;
+
+ strcpy(_pMP3List->aFilename, fd.cFileName);
+
+ _pMP3List->nTrackLength = total_ms;
+
+ _pMP3List->pNext = NULL;
+
+ pList = _pMP3List;
+
+ if ( bShortcut )
+ {
+ _pMP3List->pLinkPath = new char[MAX_PATH*2];
+ strcpy(_pMP3List->pLinkPath, filepath);
+ }
+ else
+ {
+ _pMP3List->pLinkPath = NULL;
+ }
+
+ if ( f ) fprintf(f, " - OK\n");
+
+ bInitFirstEntry = false;
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+
+ bInitFirstEntry = true;
+ }
+
+ while ( true )
+ {
+ if ( !FindNextFile(hFind, &fd) )
+ break;
+
+ if ( bInitFirstEntry )
+ {
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
+
+ if ( filepathlen > 0 )
+ {
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ {
+ bShortcut = false;
+
+ if ( filepathlen > MAX_PATH )
+ {
+ if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
+
+ continue;
+ }
+ }
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ OutputDebugString(fd.cFileName);
+
+ _pMP3List = new tMP3Entry;
+
+ if ( _pMP3List == NULL)
+ break;
+
+ nNumMP3s = 1;
+
+ strcpy(_pMP3List->aFilename, fd.cFileName);
+
+ _pMP3List->nTrackLength = total_ms;
+ _pMP3List->pNext = NULL;
+
+ if ( bShortcut )
+ {
+ _pMP3List->pLinkPath = new char [MAX_PATH*2];
+ strcpy(_pMP3List->pLinkPath, filepath);
+ }
+ else
+ {
+ _pMP3List->pLinkPath = NULL;
+ }
+
+ pList = _pMP3List;
+
+ if ( f ) fprintf(f, " - OK\n");
+
+ bInitFirstEntry = false;
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+ }
+ }
+ }
+ else
+ {
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( filepathlen > 0 )
+ {
+ if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
+
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ {
+ bShortcut = false;
+ }
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ pList->pNext = new tMP3Entry;
+
+ tMP3Entry *e = pList->pNext;
+
+ if ( e == NULL )
+ break;
+
+ pList = pList->pNext;
+
+ strcpy(e->aFilename, fd.cFileName);
+ e->nTrackLength = total_ms;
+ e->pNext = NULL;
+
+ if ( bShortcut )
+ {
+ e->pLinkPath = new char [MAX_PATH*2];
+ strcpy(e->pLinkPath, filepath);
+ }
+ else
+ {
+ e->pLinkPath = NULL;
+ }
+
+ nNumMP3s++;
+
+ OutputDebugString(fd.cFileName);
+
+ if ( f ) fprintf(f, " - OK\n");
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+ }
+ }
+ }
+ }
+
+ if ( f )
+ {
+ fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
+ fclose(f);
+ }
+
+ FindClose(hFind);
+}
+
+static void
+_DeleteMP3Entries(void)
+{
+ tMP3Entry *e = _pMP3List;
+
+ while ( e != NULL )
+ {
+ tMP3Entry *next = e->pNext;
+
+ if ( next == NULL )
+ next = NULL;
+
+ if ( e->pLinkPath != NULL )
+ {
+#ifndef FIX_BUGS
+ delete e->pLinkPath; // BUG: should be delete []
+#else
+ delete[] e->pLinkPath;
+#endif
+ e->pLinkPath = NULL;
+ }
+
+ delete e;
+
+ if ( next )
+ e = next;
+ else
+ e = NULL;
+
+ nNumMP3s--;
+ }
+
+
+ if ( nNumMP3s != 0 )
+ {
+ OutputDebugString("Not all MP3 entries were deleted");
+ nNumMP3s = 0;
+ }
+
+ _pMP3List = NULL;
+}
+
+static tMP3Entry *
+_GetMP3EntryByIndex(uint32 idx)
+{
+ uint32 n = ( idx < nNumMP3s ) ? idx : 0;
+
+ if ( _pMP3List != NULL )
+ {
+ tMP3Entry *e = _pMP3List;
+
+ for ( uint32 i = 0; i < n; i++ )
+ e = e->pNext;
+
+ return e;
+
+ }
+
+ return NULL;
+}
+
+static inline bool
+_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry)
+{
+ _CurMP3Index = 0;
+
+ for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext )
+ {
+ if ( *pPosition >= (*pEntry)->nTrackStreamPos
+ && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos )
+ {
+ *pPosition -= (*pEntry)->nTrackStreamPos;
+ _CurMP3Pos = *pPosition;
+
+ return true;
+ }
+
+ _CurMP3Index++;
+ }
+
+ *pPosition = 0;
+ *pEntry = _pMP3List;
+ _CurMP3Pos = 0;
+ _CurMP3Index = 0;
+
+ return false;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+ return nNumMP3s != 0;
+}
+
+void
+cSampleManager::ReleaseDigitalHandle(void)
+{
+ if ( DIG )
+ {
+ prevprovider = curprovider;
+ release_existing();
+ curprovider = -1;
+ AIL_digital_handle_release(DIG);
+ }
+}
+
+void
+cSampleManager::ReacquireDigitalHandle(void)
+{
+ if ( DIG )
+ {
+ AIL_digital_handle_reacquire(DIG);
+ if ( prevprovider != -1 )
+ set_new_provider(prevprovider);
+ }
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+ TRACE("start");
+
+ if ( _bSampmanInitialised )
+ return true;
+
+ {
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ m_aSamples[i].nOffset = 0;
+ m_aSamples[i].nSize = 0;
+ m_aSamples[i].nFrequency = 22050;
+ m_aSamples[i].nLoopStart = 0;
+ m_aSamples[i].nLoopEnd = -1;
+ }
+
+ m_nEffectsVolume = MAX_VOLUME;
+ m_nMusicVolume = MAX_VOLUME;
+ m_nEffectsFadeVolume = MAX_VOLUME;
+ m_nMusicFadeVolume = MAX_VOLUME;
+
+ m_nMonoMode = 0;
+ }
+
+ // miles
+ TRACE("MILES");
+ {
+ curprovider = -1;
+ prevprovider = -1;
+
+ _usingMilesFast2D = false;
+ usingEAX=0;
+ usingEAX3=0;
+
+ _fEffectsLevel = 0.0f;
+
+ _maxSamples = 0;
+
+ opened_provider = NULL;
+ DIG = NULL;
+
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ opened_samples[i] = NULL;
+ }
+
+ // banks
+ TRACE("banks");
+ {
+ fpSampleDescHandle = NULL;
+ fpSampleDataHandle = NULL;
+
+ _nSampleDataEndOffset = 0;
+
+ for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+ {
+ bSampleBankLoaded[i] = false;
+ nSampleBankDiscStartOffset[i] = 0;
+ nSampleBankSize[i] = 0;
+ nSampleBankMemoryStartAddress[i] = 0;
+ }
+ }
+
+ // pedsfx
+ TRACE("pedsfx");
+ {
+ for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+ {
+ nPedSlotSfx[i] = NO_SAMPLE;
+ nPedSlotSfxAddr[i] = 0;
+ }
+
+ nCurrentPedSlot = 0;
+ }
+
+ // channel volume
+ TRACE("vol");
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ nChannelVolume[i] = 0;
+ }
+
+ TRACE("mss");
+ {
+ AIL_set_redist_directory( "mss" );
+
+ AIL_startup();
+
+ AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS);
+
+ DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
+ if ( DIG == NULL )
+ {
+ OutputDebugString(AIL_last_error());
+ Terminate();
+ return false;
+ }
+
+ add_providers();
+
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]);
+ if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
+
+ }
+
+ TRACE("cdrom");
+
+ S32 tatalms;
+ char filepath[MAX_PATH];
+
+ {
+ m_bInitialised = false;
+
+ while (true)
+ {
+ int32 drive = 'C';
+
+ do
+ {
+ char latter[2];
+
+ latter[0] = drive;
+ latter[1] = '\0';
+
+ strcpy(m_szCDRomRootPath, latter);
+ strcat(m_szCDRomRootPath, ":\\");
+
+ if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[0]);
+
+ FILE *f = fopen(filepath, "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ bool bFileNotFound = false;
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ nStreamLength[i] = tatalms;
+ }
+ else
+ {
+ bFileNotFound = true;
+ break;
+ }
+ }
+
+ if ( !bFileNotFound )
+ {
+ m_bInitialised = true;
+ break;
+ }
+ else
+ {
+ m_bInitialised = false;
+ continue;
+ }
+ }
+ }
+
+ } while ( ++drive <= 'Z' );
+
+ if ( !m_bInitialised )
+ {
+#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+ FrontEndMenuManager.WaitForUserCD();
+ if ( FrontEndMenuManager.m_bQuitGameNoCD )
+ {
+ Terminate();
+ return false;
+ }
+ continue;
+#else
+ m_bInitialised = true;
+#endif
+ }
+
+ break;
+ }
+ }
+
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+ // hddaudio
+ /**
+ Option for user to play audio files directly from hard disk.
+ Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory.
+ Grand Theft Auto III still requires the presence of the PLAY disc when started.
+ This may give better performance on some machines (though worse on others).
+ **/
+ TRACE("hddaudio 1.1 patch");
+ {
+ int32 streamLength[TOTAL_STREAMED_SOUNDS];
+
+ bool bFileNotFound = false;
+ char rootpath[MAX_PATH];
+
+ strcpy(_aHDDPath, m_szCDRomRootPath);
+ rootpath[0] = '\0';
+
+ FILE *f = fopen(StreamedNameTable[0], "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ strcpy(filepath, rootpath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ streamLength[i] = tatalms;
+ }
+ else
+ {
+ bFileNotFound = true;
+ break;
+ }
+ }
+
+ }
+ else
+ bFileNotFound = true;
+
+ if ( !bFileNotFound )
+ {
+ strcpy(m_szCDRomRootPath, rootpath);
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = streamLength[i];
+
+ _bUseHDDAudio = true;
+ }
+ else
+ _bUseHDDAudio = false;
+ }
+#endif
+
+ TRACE("stream");
+ {
+ for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ {
+ mp3Stream [i] = NULL;
+ nStreamPan [i] = 63;
+ nStreamVolume[i] = 100;
+ }
+ }
+
+ for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
+ {
+ opened_2dsamples[i] = AIL_allocate_sample_handle(DIG);
+ if ( opened_2dsamples[i] )
+ {
+ AIL_init_sample(opened_2dsamples[i]);
+ AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN);
+ }
+ }
+
+ TRACE("providerset");
+ {
+ _bSampmanInitialised = true;
+
+ U32 n = 0;
+
+ while ( n < m_nNumberOfProviders )
+ {
+ if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") )
+ {
+ set_new_provider(n);
+ break;
+ }
+ n++;
+ }
+
+ if ( n == m_nNumberOfProviders )
+ {
+ Terminate();
+ return false;
+ }
+ }
+
+ TRACE("bank");
+
+ LoadSampleBank(SAMPLEBANK_MAIN);
+
+ // mp3
+ TRACE("mp3");
+ {
+ nNumMP3s = 0;
+
+ _pMP3List = NULL;
+
+ _FindMP3s();
+
+ if ( nNumMP3s != 0 )
+ {
+ nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0;
+
+ for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext )
+ {
+ e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER];
+ nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength;
+ }
+
+ time_t t = time(NULL);
+ tm *localtm;
+ bool bUseRandomTable;
+
+ if ( t == -1 )
+ bUseRandomTable = true;
+ else
+ {
+ bUseRandomTable = false;
+ localtm = localtime(&t);
+ }
+
+ int32 randval;
+ if ( bUseRandomTable )
+ randval = AudioManager.GetRandomNumber(1);
+ else
+ randval = localtm->tm_sec * localtm->tm_min;
+
+ _CurMP3Index = randval % nNumMP3s;
+
+ tMP3Entry *randmp3 = _pMP3List;
+ for ( int32 i = randval % nNumMP3s; i > 0; --i)
+ randmp3 = randmp3->pNext;
+
+ if ( bUseRandomTable )
+ _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ else
+ {
+ if ( localtm->tm_sec > 0 )
+ {
+ int32 s = localtm->tm_sec;
+ _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
+ }
+ else
+ _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ }
+ }
+ else
+ _CurMP3Pos = 0;
+
+ _bIsMp3Active = false;
+ }
+
+ TRACE("end");
+
+ return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+ for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ {
+ if ( mp3Stream[i] )
+ {
+ AIL_pause_stream(mp3Stream[i], 1);
+ AIL_close_stream(mp3Stream[i]);
+ mp3Stream[i] = NULL;
+ }
+ }
+
+ for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
+ {
+ if ( opened_2dsamples[i] )
+ {
+ AIL_release_sample_handle(opened_2dsamples[i]);
+ opened_2dsamples[i] = NULL;
+ }
+ }
+
+ release_existing();
+
+ _DeleteMP3Entries();
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
+ {
+ AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
+ }
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
+ {
+ AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
+ }
+
+ if ( DIG )
+ {
+ AIL_close_digital_driver(DIG);
+ DIG = NULL;
+ }
+
+ AIL_shutdown();
+
+ _bSampmanInitialised = false;
+}
+
+bool
+cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+ char filepath[MAX_PATH];
+
+#if defined(GTA3_1_1_PATCH)
+ if (_bUseHDDAudio)
+ strcpy(filepath, _aHDDPath);
+ else
+ strcpy(filepath, m_szCDRomRootPath);
+#else
+ strcpy(filepath, m_szCDRomRootPath);
+#endif // #if defined(GTA3_1_1_PATCH)
+
+ strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
+
+ FILE *f = fopen(filepath, "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ return true;
+ }
+
+ return false;
+
+#else
+ return true;
+#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+}
+
+char
+cSampleManager::GetCDAudioDriveLetter(void)
+{
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+ if (_bUseHDDAudio)
+ {
+ if ( strlen(_aHDDPath) != 0 )
+ return _aHDDPath[0];
+ else
+ return '\0';
+ }
+ else
+ {
+ if ( strlen(m_szCDRomRootPath) != 0 )
+ return m_szCDRomRootPath[0];
+ else
+ return '\0';
+ }
+#else
+ if ( strlen(m_szCDRomRootPath) != 0 )
+ return m_szCDRomRootPath[0];
+ else
+ return '\0';
+#endif
+}
+
+void
+cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ?
+{
+ if ( _bSampmanInitialised )
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ {
+ if ( i < MAXCHANNELS )
+ {
+ if ( opened_samples[i] && GetChannelUsedFlag(i) )
+ {
+ if ( nChannelVolume[i] )
+ {
+ AIL_set_3D_sample_volume(opened_samples[i],
+ m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
+ }
+ }
+ }
+ else
+ {
+ if ( opened_2dsamples[i - MAXCHANNELS] )
+ {
+ if ( GetChannelUsedFlag(i - MAXCHANNELS) )
+ {
+ if ( nChannelVolume[i - MAXCHANNELS] )
+ {
+ AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS],
+ m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
+{
+ m_nEffectsVolume = nVolume;
+ UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+ m_nMusicVolume = nVolume;
+}
+
+void
+cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
+{
+ m_nEffectsFadeVolume = nVolume;
+ UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicFadeVolume(uint8 nVolume)
+{
+ m_nMusicFadeVolume = nVolume;
+}
+
+bool
+cSampleManager::LoadSampleBank(uint8 nBank)
+{
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ if ( MusicManager.IsInitialised()
+ && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && nBank != SAMPLEBANK_MAIN )
+ {
+ return false;
+ }
+
+ if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] )
+ return false;
+
+ bSampleBankLoaded[nBank] = true;
+
+ return true;
+}
+
+void
+cSampleManager::UnloadSampleBank(uint8 nBank)
+{
+ bSampleBankLoaded[nBank] = false;
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+ return bSampleBankLoaded[nBank];
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return true;
+ }
+
+ return false;
+}
+
+int32
+cSampleManager::_GetPedCommentSlot(uint32 nComment)
+{
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return slot;
+ }
+
+ return -1;
+}
+
+bool
+cSampleManager::LoadPedComment(uint32 nComment)
+{
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ // no talking peds during cutsenes or the game end
+ if ( MusicManager.IsInitialised() )
+ {
+ switch ( MusicManager.GetMusicMode() )
+ {
+ case MUSICMODE_CUTSCENE:
+ {
+ return false;
+
+ break;
+ }
+
+ case MUSICMODE_FRONTEND:
+ {
+ if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
+ return false;
+
+ break;
+ }
+ }
+ }
+
+ if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+ return false;
+
+ nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot;
+ nPedSlotSfx [nCurrentPedSlot] = nComment;
+
+ if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+ nCurrentPedSlot = 0;
+
+ return true;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+ return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+ return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+ return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+ return m_aSamples[nSample].nSize >> 1;
+}
+
+bool
+cSampleManager::UpdateReverb(void)
+{
+ if ( !usingEAX )
+ return false;
+
+ if ( AudioManager.GetFrameCounter() & 15 )
+ return false;
+
+ float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
+ float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
+ float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
+
+ float normy = norm(y, 5.0f, 40.0f);
+ float normx = norm(x, 5.0f, 40.0f);
+ float normz = norm(z, 5.0f, 40.0f);
+
+ float fRatio;
+
+ if ( normy == 0.0f )
+ {
+ if ( normx == 0.0f )
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = 0.5f;
+ }
+ else
+ {
+ fRatio = 0.3f;
+ }
+ }
+ else
+ {
+ if ( normx == 0.0f )
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = 0.5f;
+ }
+ else
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = (normy+normx+normz) / 3.0f;
+ }
+ }
+
+ fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+
+ if ( fRatio == _fPrevEaxRatioDestination )
+ return false;
+
+ if ( usingEAX3 )
+ {
+ if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
+ {
+ AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params);
+ _fEffectsLevel = 1.0f - fRatio * 0.5f;
+ }
+ }
+ else
+ {
+ if ( _usingMilesFast2D )
+ _fEffectsLevel = (1.0f - fRatio) * 0.4f;
+ else
+ _fEffectsLevel = (1.0f - fRatio) * 0.7f;
+ }
+
+ _fPrevEaxRatioDestination = fRatio;
+
+ return true;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( usingEAX )
+ {
+ if ( nReverbFlag != 0 )
+ {
+ if ( !b2d )
+ AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel);
+ }
+ else
+ {
+ if ( !b2d )
+ AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f);
+ }
+ }
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ int32 addr;
+
+ if ( nSfx < SAMPLEBANK_MAX )
+ {
+ if ( !IsSampleBankLoaded(nBank) )
+ return false;
+
+ addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
+ }
+ else
+ {
+ if ( !IsPedCommentLoaded(nSfx) )
+ return false;
+
+ int32 slot = _GetPedCommentSlot(nSfx);
+
+ addr = nPedSlotSfxAddr[slot];
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ {
+ AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize);
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ AILSOUNDINFO info;
+
+ info.format = WAVE_FORMAT_PCM;
+ info.data_ptr = (void *)addr;
+ info.channels = 1;
+ info.data_len = m_aSamples[nSfx].nSize;
+ info.rate = m_aSamples[nSfx].nFrequency;
+ info.bits = 16;
+
+ if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 )
+ {
+ OutputDebugString(AIL_last_error());
+ return false;
+ }
+
+ return true;
+ }
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
+
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ);
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin);
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ {
+ AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS],
+ m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ }
+
+ break;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+#ifndef FIX_BUGS
+ if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG
+#else
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+#endif
+ AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan);
+
+ break;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq);
+ }
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd);
+ }
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount);
+ }
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING;
+ else
+ return false;
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING;
+ else
+ return false;
+ }
+
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_start_3D_sample(opened_samples[nChannel]);
+ }
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ {
+ if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING )
+ AIL_end_3D_sample(opened_samples[nChannel]);
+ }
+ }
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+ AIL_close_stream(mp3Stream[nStream]);
+ }
+
+ char filepath[MAX_PATH];
+
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_service_stream(mp3Stream[nStream], 1);
+ }
+ else
+ OutputDebugString(AIL_last_error());
+ }
+ }
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0);
+ }
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ AIL_start_stream(mp3Stream[nStream]);
+ }
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+ uint32 position = nPos;
+ char filename[MAX_PATH];
+
+ if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+ AIL_close_stream(mp3Stream[nStream]);
+ }
+
+ if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER )
+ {
+ uint32 i = 0;
+ do {
+ if(i != 0 || _bIsMp3Active) {
+ if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0;
+
+ _CurMP3Pos = 0;
+
+ tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
+
+ if(mp3) {
+ mp3 = _pMP3List;
+ if(mp3 == NULL) {
+ _bIsMp3Active = false;
+ nFile = 0;
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(
+ mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(
+ mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream],
+ 0);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ if(mp3->pLinkPath != NULL)
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, mp3->pLinkPath, 0);
+ else {
+ strcpy(filename, _mp3DirectoryPath);
+ strcat(filename, mp3->aFilename);
+
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ }
+
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], 0);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+
+ _bIsMp3Active = false;
+ continue;
+ }
+ if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
+ position = 0;
+
+ tMP3Entry *e;
+ if ( !_GetMP3PosFromStreamPos(&position, &e) )
+ {
+ if ( e == NULL )
+ {
+ nFile = 0;
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(
+ mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(
+ mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ if ( e->pLinkPath != NULL )
+ mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0);
+ else
+ {
+ strcpy(filename, _mp3DirectoryPath);
+ strcat(filename, e->aFilename);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ }
+
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+
+ _bIsMp3Active = true;
+
+ return true;
+ }
+
+ _bIsMp3Active = false;
+
+ } while(++i < nNumMP3s);
+
+ position = 0;
+ nFile = 0;
+ }
+
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+
+ AIL_close_stream(mp3Stream[nStream]);
+ mp3Stream[nStream] = NULL;
+
+ if ( nStream == 0 )
+ _bIsMp3Active = false;
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+ S32 currentms;
+
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ if ( _bIsMp3Active )
+ {
+ tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
+
+ if ( mp3 != NULL )
+ {
+ AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
+ return currentms + mp3->nTrackStreamPos;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
+ return currentms;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+ uint8 vol = nVolume;
+
+ if ( m_bInitialised )
+ {
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nStreamVolume[nStream] = vol;
+ nStreamPan[nStream] = nPan;
+
+ if ( mp3Stream[nStream] )
+ {
+ if ( nEffectFlag )
+ AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ else
+ AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);
+
+ AIL_set_stream_pan(mp3Stream[nStream], nPan);
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+ if ( m_bInitialised )
+ return nStreamLength[nStream];
+
+ return 0;
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING )
+ return true;
+ else
+ return false;
+ }
+ }
+
+ return false;
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+ int32 nBank = SAMPLEBANK_MAIN;
+
+ fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
+ if ( fpSampleDescHandle == NULL )
+ return false;
+
+ fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
+ if ( fpSampleDataHandle == NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ return false;
+ }
+
+ fseek(fpSampleDataHandle, 0, SEEK_END);
+ _nSampleDataEndOffset = ftell(fpSampleDataHandle);
+ rewind(fpSampleDataHandle);
+
+ fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
+
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+#ifdef FIX_BUGS
+ if (nBank >= MAX_SAMPLEBANKS) break;
+#endif
+ if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+ {
+ nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+ nBank++;
+ }
+ }
+
+ nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+ nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+
+ return true;
+}
diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h
new file mode 100644
index 00000000..ebedfb63
--- /dev/null
+++ b/src/audio/miles/sampman_mss.h
@@ -0,0 +1,339 @@
+#pragma once
+#include "common.h"
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+
+struct tSample {
+ int32 nOffset;
+ uint32 nSize;
+ int32 nFrequency;
+ int32 nLoopStart;
+ int32 nLoopEnd;
+};
+
+enum
+{
+ SAMPLEBANK_MAIN,
+ SAMPLEBANK_PED,
+ MAX_SAMPLEBANKS,
+ SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX 7
+#define PED_BLOCKSIZE 79000
+
+#define MAXPROVIDERS 64
+
+#define MAXCHANNELS 28
+#define MAXCHANNELS_SURROUND 24
+#define MAX2DCHANNELS 1
+#define CHANNEL2D MAXCHANNELS
+
+#define MAX_MP3STREAMS 2
+
+#define DIGITALRATE 32000
+#define DIGITALBITS 16
+#define DIGITALCHANNELS 2
+
+#define MAX_DIGITAL_MIXER_CHANNELS 32
+
+class cSampleManager
+{
+ uint8 m_nEffectsVolume;
+ uint8 m_nMusicVolume;
+ uint8 m_nEffectsFadeVolume;
+ uint8 m_nMusicFadeVolume;
+ uint8 m_nMonoMode;
+ char unk;
+ char m_szCDRomRootPath[80];
+ bool m_bInitialised;
+ uint8 m_nNumberOfProviders;
+ char *m_aAudioProviders[MAXPROVIDERS];
+ tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+
+
+
+ cSampleManager(void) :
+ m_nNumberOfProviders(0)
+ { }
+
+ ~cSampleManager(void)
+ { }
+
+ void SetSpeakerConfig(int32 nConfig);
+ uint32 GetMaximumSupportedChannels(void);
+
+ uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
+ void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
+
+ char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
+ void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
+
+ int8 GetCurrent3DProviderIndex(void);
+ int8 SetCurrent3DProvider(uint8 which);
+
+ bool IsMP3RadioChannelAvailable(void);
+
+ void ReleaseDigitalHandle (void);
+ void ReacquireDigitalHandle(void);
+
+ bool Initialise(void);
+ void Terminate (void);
+
+ bool CheckForAnAudioFileOnCD(void);
+ char GetCDAudioDriveLetter (void);
+
+ void UpdateEffectsVolume(void);
+
+ void SetEffectsMasterVolume(uint8 nVolume);
+ void SetMusicMasterVolume (uint8 nVolume);
+ void SetEffectsFadeVolume (uint8 nVolume);
+ void SetMusicFadeVolume (uint8 nVolume);
+
+ bool LoadSampleBank (uint8 nBank);
+ void UnloadSampleBank (uint8 nBank);
+ bool IsSampleBankLoaded(uint8 nBank);
+
+ bool IsPedCommentLoaded(uint32 nComment);
+ bool LoadPedComment (uint32 nComment);
+
+ int32 _GetPedCommentSlot(uint32 nComment);
+
+ int32 GetSampleBaseFrequency (uint32 nSample);
+ int32 GetSampleLoopStartOffset(uint32 nSample);
+ int32 GetSampleLoopEndOffset (uint32 nSample);
+ uint32 GetSampleLength (uint32 nSample);
+
+ bool UpdateReverb(void);
+
+ void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
+ bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
+ void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+ void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
+ void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
+ void SetChannelVolume (uint32 nChannel, uint32 nVolume);
+ void SetChannelPan (uint32 nChannel, uint32 nPan);
+ void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
+ void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
+ void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
+ bool GetChannelUsedFlag (uint32 nChannel);
+ void StartChannel (uint32 nChannel);
+ void StopChannel (uint32 nChannel);
+
+ void PreloadStreamedFile (uint8 nFile, uint8 nStream);
+ void PauseStream (uint8 nPauseFlag, uint8 nStream);
+ void StartPreloadedStreamedFile (uint8 nStream);
+ bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
+ void StopStreamedFile (uint8 nStream);
+ int32 GetStreamedFilePosition (uint8 nStream);
+ void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
+ int32 GetStreamedFileLength (uint8 nStream);
+ bool IsStreamPlaying (uint8 nStream);
+ bool InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\CLASS.WAV",
+ "AUDIO\\KJAH.WAV",
+ "AUDIO\\RISE.WAV",
+ "AUDIO\\LIPS.WAV",
+ "AUDIO\\GAME.WAV",
+ "AUDIO\\MSX.WAV",
+ "AUDIO\\FLASH.WAV",
+ "AUDIO\\CHAT.WAV",
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\POLICE.WAV",
+ "AUDIO\\CITY.WAV",
+ "AUDIO\\WATER.WAV",
+ "AUDIO\\COMOPEN.WAV",
+ "AUDIO\\SUBOPEN.WAV",
+ "AUDIO\\JB.MP3",
+ "AUDIO\\BET.MP3",
+ "AUDIO\\L1_LG.MP3",
+ "AUDIO\\L2_DSB.MP3",
+ "AUDIO\\L3_DM.MP3",
+ "AUDIO\\L4_PAP.MP3",
+ "AUDIO\\L5_TFB.MP3",
+ "AUDIO\\J0_DM2.MP3",
+ "AUDIO\\J1_LFL.MP3",
+ "AUDIO\\J2_KCL.MP3",
+ "AUDIO\\J3_VH.MP3",
+ "AUDIO\\J4_ETH.MP3",
+ "AUDIO\\J5_DST.MP3",
+ "AUDIO\\J6_TBJ.MP3",
+ "AUDIO\\T1_TOL.MP3",
+ "AUDIO\\T2_TPU.MP3",
+ "AUDIO\\T3_MAS.MP3",
+ "AUDIO\\T4_TAT.MP3",
+ "AUDIO\\T5_BF.MP3",
+ "AUDIO\\S0_MAS.MP3",
+ "AUDIO\\S1_PF.MP3",
+ "AUDIO\\S2_CTG.MP3",
+ "AUDIO\\S3_RTC.MP3",
+ "AUDIO\\S5_LRQ.MP3",
+ "AUDIO\\S4_BDBA.MP3",
+ "AUDIO\\S4_BDBB.MP3",
+ "AUDIO\\S2_CTG2.MP3",
+ "AUDIO\\S4_BDBD.MP3",
+ "AUDIO\\S5_LRQB.MP3",
+ "AUDIO\\S5_LRQC.MP3",
+ "AUDIO\\A1_SSO.WAV",
+ "AUDIO\\A2_PP.WAV",
+ "AUDIO\\A3_SS.WAV",
+ "AUDIO\\A4_PDR.WAV",
+ "AUDIO\\A5_K2FT.WAV",
+ "AUDIO\\K1_KBO.MP3",
+ "AUDIO\\K2_GIS.MP3",
+ "AUDIO\\K3_DS.MP3",
+ "AUDIO\\K4_SHI.MP3",
+ "AUDIO\\K5_SD.MP3",
+ "AUDIO\\R0_PDR2.MP3",
+ "AUDIO\\R1_SW.MP3",
+ "AUDIO\\R2_AP.MP3",
+ "AUDIO\\R3_ED.MP3",
+ "AUDIO\\R4_GF.MP3",
+ "AUDIO\\R5_PB.MP3",
+ "AUDIO\\R6_MM.MP3",
+ "AUDIO\\D1_STOG.MP3",
+ "AUDIO\\D2_KK.MP3",
+ "AUDIO\\D3_ADO.MP3",
+ "AUDIO\\D5_ES.MP3",
+ "AUDIO\\D7_MLD.MP3",
+ "AUDIO\\D4_GTA.MP3",
+ "AUDIO\\D4_GTA2.MP3",
+ "AUDIO\\D6_STS.MP3",
+ "AUDIO\\A6_BAIT.WAV",
+ "AUDIO\\A7_ETG.WAV",
+ "AUDIO\\A8_PS.WAV",
+ "AUDIO\\A9_ASD.WAV",
+ "AUDIO\\K4_SHI2.MP3",
+ "AUDIO\\C1_TEX.MP3",
+ "AUDIO\\EL_PH1.MP3",
+ "AUDIO\\EL_PH2.MP3",
+ "AUDIO\\EL_PH3.MP3",
+ "AUDIO\\EL_PH4.MP3",
+ "AUDIO\\YD_PH1.MP3",
+ "AUDIO\\YD_PH2.MP3",
+ "AUDIO\\YD_PH3.MP3",
+ "AUDIO\\YD_PH4.MP3",
+ "AUDIO\\HD_PH1.MP3",
+ "AUDIO\\HD_PH2.MP3",
+ "AUDIO\\HD_PH3.MP3",
+ "AUDIO\\HD_PH4.MP3",
+ "AUDIO\\HD_PH5.MP3",
+ "AUDIO\\MT_PH1.MP3",
+ "AUDIO\\MT_PH2.MP3",
+ "AUDIO\\MT_PH3.MP3",
+ "AUDIO\\MT_PH4.MP3",
+ "AUDIO\\MISCOM.WAV",
+ "AUDIO\\END.MP3",
+ "AUDIO\\lib_a1.WAV",
+ "AUDIO\\lib_a2.WAV",
+ "AUDIO\\lib_a.WAV",
+ "AUDIO\\lib_b.WAV",
+ "AUDIO\\lib_c.WAV",
+ "AUDIO\\lib_d.WAV",
+ "AUDIO\\l2_a.WAV",
+ "AUDIO\\j4t_1.WAV",
+ "AUDIO\\j4t_2.WAV",
+ "AUDIO\\j4t_3.WAV",
+ "AUDIO\\j4t_4.WAV",
+ "AUDIO\\j4_a.WAV",
+ "AUDIO\\j4_b.WAV",
+ "AUDIO\\j4_c.WAV",
+ "AUDIO\\j4_d.WAV",
+ "AUDIO\\j4_e.WAV",
+ "AUDIO\\j4_f.WAV",
+ "AUDIO\\j6_1.WAV",
+ "AUDIO\\j6_a.WAV",
+ "AUDIO\\j6_b.WAV",
+ "AUDIO\\j6_c.WAV",
+ "AUDIO\\j6_d.WAV",
+ "AUDIO\\t4_a.WAV",
+ "AUDIO\\s1_a.WAV",
+ "AUDIO\\s1_a1.WAV",
+ "AUDIO\\s1_b.WAV",
+ "AUDIO\\s1_c.WAV",
+ "AUDIO\\s1_c1.WAV",
+ "AUDIO\\s1_d.WAV",
+ "AUDIO\\s1_e.WAV",
+ "AUDIO\\s1_f.WAV",
+ "AUDIO\\s1_g.WAV",
+ "AUDIO\\s1_h.WAV",
+ "AUDIO\\s1_i.WAV",
+ "AUDIO\\s1_j.WAV",
+ "AUDIO\\s1_k.WAV",
+ "AUDIO\\s1_l.WAV",
+ "AUDIO\\s3_a.WAV",
+ "AUDIO\\s3_b.WAV",
+ "AUDIO\\el3_a.WAV",
+ "AUDIO\\mf1_a.WAV",
+ "AUDIO\\mf2_a.WAV",
+ "AUDIO\\mf3_a.WAV",
+ "AUDIO\\mf3_b.WAV",
+ "AUDIO\\mf3_b1.WAV",
+ "AUDIO\\mf3_c.WAV",
+ "AUDIO\\mf4_a.WAV",
+ "AUDIO\\mf4_b.WAV",
+ "AUDIO\\mf4_c.WAV",
+ "AUDIO\\a1_a.WAV",
+ "AUDIO\\a3_a.WAV",
+ "AUDIO\\a5_a.WAV",
+ "AUDIO\\a4_a.WAV",
+ "AUDIO\\a4_b.WAV",
+ "AUDIO\\a4_c.WAV",
+ "AUDIO\\a4_d.WAV",
+ "AUDIO\\k1_a.WAV",
+ "AUDIO\\k3_a.WAV",
+ "AUDIO\\r1_a.WAV",
+ "AUDIO\\r2_a.WAV",
+ "AUDIO\\r2_b.WAV",
+ "AUDIO\\r2_c.WAV",
+ "AUDIO\\r2_d.WAV",
+ "AUDIO\\r2_e.WAV",
+ "AUDIO\\r2_f.WAV",
+ "AUDIO\\r2_g.WAV",
+ "AUDIO\\r2_h.WAV",
+ "AUDIO\\r5_a.WAV",
+ "AUDIO\\r6_a.WAV",
+ "AUDIO\\r6_a1.WAV",
+ "AUDIO\\r6_b.WAV",
+ "AUDIO\\lo2_a.WAV",
+ "AUDIO\\lo6_a.WAV",
+ "AUDIO\\yd2_a.WAV",
+ "AUDIO\\yd2_b.WAV",
+ "AUDIO\\yd2_c.WAV",
+ "AUDIO\\yd2_c1.WAV",
+ "AUDIO\\yd2_d.WAV",
+ "AUDIO\\yd2_e.WAV",
+ "AUDIO\\yd2_f.WAV",
+ "AUDIO\\yd2_g.WAV",
+ "AUDIO\\yd2_h.WAV",
+ "AUDIO\\yd2_ass.WAV",
+ "AUDIO\\yd2_ok.WAV",
+ "AUDIO\\h5_a.WAV",
+ "AUDIO\\h5_b.WAV",
+ "AUDIO\\h5_c.WAV",
+ "AUDIO\\ammu_a.WAV",
+ "AUDIO\\ammu_b.WAV",
+ "AUDIO\\ammu_c.WAV",
+ "AUDIO\\door_1.WAV",
+ "AUDIO\\door_2.WAV",
+ "AUDIO\\door_3.WAV",
+ "AUDIO\\door_4.WAV",
+ "AUDIO\\door_5.WAV",
+ "AUDIO\\door_6.WAV",
+ "AUDIO\\t3_a.WAV",
+ "AUDIO\\t3_b.WAV",
+ "AUDIO\\t3_c.WAV",
+ "AUDIO\\k1_b.WAV",
+ "AUDIO\\cat1.WAV"
+};
diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp
new file mode 100644
index 00000000..e8213cd9
--- /dev/null
+++ b/src/audio/openal/samp_oal.cpp
@@ -0,0 +1,1404 @@
+#include <al.h>
+#include <alc.h>
+#include <mpg123_pre.h>
+//#include <mpg123.h>
+#include <time.h>
+#include <io.h>
+#include "samp_oal.h"
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+#pragma comment( lib, "libmpg123.lib" )
+#pragma comment( lib, "OpenAL32.lib" )
+
+cSampleManager SampleManager;
+int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+
+///////////////////////////////////////////////////////////////
+class MP3Stream
+{
+public:
+ mpg123_handle *m_pMPG;
+ FILE *m_fpFile;
+ unsigned char *m_pBuf;
+ char m_aFilename[128];
+ size_t m_nBufSize;
+ size_t m_nLengthInBytes;
+ long m_nRate;
+ int m_nBitRate;
+ int m_nChannels;
+ int m_nEncoding;
+ int m_nLength;
+ int m_nBlockSize;
+ int m_nNumBlocks;
+ ALuint m_alSource;
+ ALuint m_alBuffers[5];
+ unsigned char *m_pBlocks;
+ bool m_bIsFree;
+ bool m_bIsOpened;
+ bool m_bIsPaused;
+ int m_nVolume;
+
+ void Initialize(void);
+ bool FillBuffer(ALuint alBuffer);
+ void Update(void);
+ void SetPos(uint32 nPos);
+ int32 FillBuffers();
+ MP3Stream(char *filename, ALuint source, ALuint *buffers);
+ ~MP3Stream() { Delete(); }
+ void Delete();
+
+};
+///////////////////////////////////////////////////////////////
+
+char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
+char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
+
+FILE *fpSampleDescHandle;
+FILE *fpSampleDataHandle;
+bool bSampleBankLoaded [MAX_SAMPLEBANKS];
+int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
+int32 nSampleBankSize [MAX_SAMPLEBANKS];
+int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
+int32 _nSampleDataEndOffset;
+
+int32 nPedSlotSfx [MAX_PEDSFX];
+int32 nPedSlotSfxAddr[MAX_PEDSFX];
+uint8 nCurrentPedSlot;
+
+
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+
+///////////////////////////////////////////////////////////////
+ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS];
+ALuint ALStreamSources[MAX_STREAMS];
+ALuint ALStreamBuffers[MAX_STREAMS][5];
+struct
+{
+ ALuint buffer;
+ ALuint timer;
+}ALBuffers[SAMPLEBANK_MAX];
+
+ALuint pedBuffers[MAX_PEDSFX];
+//bank0Buffers
+
+uint32 nNumMP3s;
+
+MP3Stream *mp3Stream[MAX_STREAMS];
+int8 nStreamPan [MAX_STREAMS];
+int8 nStreamVolume[MAX_STREAMS];
+
+float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS];
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+
+cSampleManager::cSampleManager(void)
+{
+ ;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+ ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL);
+ free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+
+ if ( fpSampleDescHandle != NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+ }
+
+ if ( fpSampleDataHandle != NULL )
+ {
+ fclose(fpSampleDataHandle);
+ fpSampleDataHandle = NULL;
+ }
+}
+
+void cSampleManager::SetSpeakerConfig(int32 nConfig)
+{
+
+}
+
+uint32 cSampleManager::GetMaximumSupportedChannels(void)
+{
+ return 20;
+}
+
+uint32 cSampleManager::GetNum3DProvidersAvailable()
+{
+ return 1;
+}
+
+void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
+{
+ ;
+}
+
+char *cSampleManager::Get3DProviderName(uint8 id)
+{
+ static char PROVIDER[256] = "OpenAL";
+ return PROVIDER;
+}
+
+void cSampleManager::Set3DProviderName(uint8 id, char *name)
+{
+ ;
+}
+
+int8 cSampleManager::GetCurrent3DProviderIndex(void)
+{
+ return 0;
+}
+
+int8 cSampleManager::SetCurrent3DProvider(uint8 which)
+{
+ return 0;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+ return nNumMP3s != 0;
+}
+
+
+void cSampleManager::ReleaseDigitalHandle(void)
+{
+
+}
+
+void cSampleManager::ReacquireDigitalHandle(void)
+{
+
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+ ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
+
+ m_pDevice = alcOpenDevice(NULL);
+ ASSERT(m_pDevice != NULL);
+
+ m_pContext = alcCreateContext(m_pDevice, attr);
+ ASSERT(m_pContext != NULL);
+
+ alcMakeContextCurrent(m_pContext);
+
+ mpg123_init();
+
+
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ m_aSamples[i].nOffset = 0;
+ m_aSamples[i].nSize = 0;
+ m_aSamples[i].nFrequency = MAX_FREQ;
+ m_aSamples[i].nLoopStart = 0;
+ m_aSamples[i].nLoopEnd = -1;
+ }
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = 3600000;
+
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ mp3Stream[i] = NULL;
+ nStreamVolume[i] = 100;
+ nStreamPan[i] = 63;
+ }
+
+ alGenSources(MAX_STREAMS, (ALuint *)ALStreamSources);
+ alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers);
+
+ m_nMonoMode = 0;
+
+ m_nEffectsVolume = MAX_VOLUME;
+ m_nMusicVolume = MAX_VOLUME;
+ m_nEffectsFadeVolume = MAX_VOLUME;
+ m_nMusicFadeVolume = MAX_VOLUME;
+
+
+ memset(alChannel, 0, sizeof(alChannel));
+ memset(nChannelVolume, 0, sizeof(nChannelVolume));
+ memset(ChannelSample, 0, sizeof(ChannelSample));
+
+ for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ )
+ ChannelPitch[i] = 1.0f;
+
+
+ fpSampleDescHandle = NULL;
+ fpSampleDataHandle = NULL;
+
+ for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+ {
+ bSampleBankLoaded[i] = false;
+ nSampleBankDiscStartOffset[i] = 0;
+ nSampleBankSize[i] = 0;
+ nSampleBankMemoryStartAddress[i] = 0;
+ }
+
+ alGenBuffers(MAX_PEDSFX, pedBuffers);
+
+ for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+ {
+ nPedSlotSfx[i] = NO_SAMPLE;
+ nPedSlotSfxAddr[i] = 0;
+ }
+
+ nCurrentPedSlot = 0;
+
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ ALBuffers[i].buffer = 0;
+ ALBuffers[i].timer = 0;
+ }
+
+ alListenerf (AL_GAIN, 1.0f);
+ alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
+ ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
+ alListenerfv(AL_ORIENTATION, orientation);
+
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
+
+ alGenSources(MAXCHANNELS, alChannel);
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ {
+ if ( alChannel[i] )
+ alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE);
+ }
+
+ alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]);
+ if ( alChannel[CHANNEL2D] )
+ {
+ alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE);
+ alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f);
+ }
+
+ LoadSampleBank(SAMPLEBANK_MAIN);
+
+ return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+ mpg123_exit();
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(m_pContext);
+ alcCloseDevice(m_pDevice);
+}
+
+void
+cSampleManager::UpdateSoundBuffers(void)
+{
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ if ( ALBuffers[i].timer > 0 )
+ {
+ ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f);
+
+ if ( ALBuffers[i].timer <= 0 )
+ {
+ if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
+ {
+ alDeleteBuffers(1, &ALBuffers[i].buffer);
+
+ if ( alGetError() == AL_NO_ERROR )
+ ALBuffers[i].buffer = 0;
+ else
+ ALBuffers[i].buffer = 120000;
+ }
+ }
+ }
+ }
+}
+
+bool cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+ return true;
+}
+
+char cSampleManager::GetCDAudioDriveLetter(void)
+{
+ return '\0';
+}
+
+void
+cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
+{
+ m_nEffectsVolume = nVolume;
+}
+
+void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+ m_nMusicVolume = nVolume;
+}
+
+void
+cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
+{
+ m_nEffectsFadeVolume = nVolume;
+}
+
+void
+cSampleManager::SetMusicFadeVolume(uint8 nVolume)
+{
+ m_nMusicFadeVolume = nVolume;
+}
+
+void
+cSampleManager::SetMonoMode(uint8 nMode)
+{
+ m_nMonoMode = nMode;
+}
+
+bool
+cSampleManager::LoadSampleBank(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ if ( MusicManager.IsInitialised()
+ && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && nBank != SAMPLEBANK_MAIN )
+ {
+ return false;
+ }
+
+ if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] )
+ return false;
+
+ bSampleBankLoaded[nBank] = true;
+
+ return true;
+}
+
+void
+cSampleManager::UnloadSampleBank(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ ; // NOIMP
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+ return true;
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return true;
+ }
+
+ return false;
+}
+
+
+int32
+cSampleManager::_GetPedCommentSlot(uint32 nComment)
+{
+ uint8 slot;
+
+ for (int32 i = 0; i < _TODOCONST(3); i++)
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if (nComment == nPedSlotSfx[slot])
+ return slot;
+ }
+
+ return -1;
+}
+
+bool
+cSampleManager::LoadPedComment(uint32 nComment)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ // no talking peds during cutsenes or the game end
+ if ( MusicManager.IsInitialised() )
+ {
+ switch ( MusicManager.GetMusicMode() )
+ {
+ case MUSICMODE_CUTSCENE:
+ {
+ return false;
+
+ break;
+ }
+
+ case MUSICMODE_FRONTEND:
+ {
+ if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
+ return false;
+
+ break;
+ }
+ }
+ }
+
+ if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+ return false;
+
+ nPedSlotSfx[nCurrentPedSlot] = nComment;
+
+ alBufferData(pedBuffers[nCurrentPedSlot],
+ AL_FORMAT_MONO16,
+ (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
+ m_aSamples[nComment].nSize,
+ MAX_FREQ);
+
+ if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+ nCurrentPedSlot = 0;
+
+ return true;
+}
+
+int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+ if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+ return SAMPLEBANK_PED;
+
+ if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+ return SAMPLEBANK_MAIN;
+
+ return SAMPLEBANK_INVALID;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nSize >> 1;
+}
+
+bool cSampleManager::UpdateReverb(void)
+{
+ return false;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+ ; // NOIMP
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ ALuint buffer;
+
+ if ( nSfx < SAMPLEBANK_MAX )
+ {
+ int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset;
+ int32 size = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize;
+
+ void *data = malloc(size);
+ ASSERT(data != NULL);
+
+ if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ {
+ free(data);
+ return false;
+ }
+
+ if ( fread(data, 1, size, fpSampleDataHandle) != size )
+ {
+ free(data);
+ return false;
+ }
+
+ ALuint buf;
+ alGenBuffers(1, &buf);
+ alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ);
+ free(data);
+
+ if ( !IsSampleBankLoaded(nBank) )
+ return false;
+
+ ALBuffers[nSfx].buffer = buf;
+ ALBuffers[nSfx].timer = 120000;
+
+ buffer = ALBuffers[nSfx].buffer;
+
+ ChannelSample[nChannel] = nSfx;
+ }
+ else
+ {
+ if ( !IsPedCommentLoaded(nSfx) )
+ return false;
+
+ int32 slot = _GetPedCommentSlot(nSfx);
+
+ buffer = pedBuffers[slot];
+ }
+
+ if ( buffer == 0 )
+ {
+ TRACE("No buffer to play id %d", nSfx);
+ return false;
+ }
+
+ if ( GetChannelUsedFlag(nChannel) )
+ {
+ TRACE("Stopping channel %d - really!!!", nChannel);
+ StopChannel(nChannel);
+ }
+
+ alSourcei(alChannel[nChannel], AL_BUFFER, 0);
+ currentChannelVolume [nChannel] = -1;
+ currentChannelFrequency [nChannel] = -1;
+ currentChannelMaxFrontDistance[nChannel] = -1;
+
+ if ( alChannel[nChannel] )
+ {
+ alSourcei(alChannel[nChannel], AL_BUFFER, buffer);
+ alSourcef(alChannel[nChannel], AL_PITCH, 1.0f);
+ ChannelPitch[nChannel] = 1.0f;
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // reduce the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
+ if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack
+ channelVol >>= 1;
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelVolume[nChannel] != channelVol )
+ {
+ ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
+ alSourcef(alChannel[nChannel], AL_GAIN, gain);
+ currentChannelVolume[nChannel] = channelVol;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ);
+ }
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax )
+ {
+ alSourcef(alChannel[nChannel], AL_MAX_DISTANCE, fMax);
+ alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f);
+ alSourcef(alChannel[nChannel], AL_MAX_GAIN, 1.0f);
+ currentChannelMaxFrontDistance[nChannel] = int32(fMax);
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nChannel == CHANNEL2D )
+ {
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
+ if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack
+ channelVol >>= 1;
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelVolume[nChannel] != channelVol )
+ {
+ ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
+ alSourcef(alChannel[nChannel], AL_GAIN, gain);
+ currentChannelVolume[nChannel] = channelVol;
+ }
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+ ; // NOIMP
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelFrequency[nChannel] != nFreq )
+ {
+ ALfloat pitch = ALfloat(nFreq) / MAX_FREQ;
+ alSourcef(alChannel[nChannel], AL_PITCH, pitch);
+ currentChannelFrequency[nChannel] = nFreq;
+
+ if ( Abs(1.0f - pitch) < 0.01f )
+ ChannelPitch[nChannel] = 1.0f;
+ else
+ ChannelPitch[nChannel] = pitch;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ ; // NOIMP
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nLoopCount != 0 )
+ alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE);
+ else
+ alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE);
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ ALint sourceState;
+ alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState);
+ return sourceState == AL_PLAYING;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank
+ {
+ if ( ChannelPitch[nChannel] != 1.0f )
+ ChannelPitch[nChannel] = 1.0f;
+ }
+
+ alSourcef (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]);
+ alSourcePlay(alChannel[nChannel]);
+ }
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ alSourceStop(alChannel[nChannel]);
+
+ currentChannelVolume [nChannel] = -1;
+ currentChannelFrequency [nChannel] = -1;
+ currentChannelMaxFrontDistance[nChannel] = -1;
+ ChannelPitch [nChannel] = 1.0f;
+ }
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ delete mp3Stream[nStream];
+ mp3Stream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ mp3Stream[nStream] = stream;
+
+ if ( stream->m_bIsOpened )
+ {
+ ;
+ }
+ else
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+ }
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ if ( nPauseFlag != 0 )
+ {
+ if ( !stream->m_bIsPaused )
+ {
+ alSourcePause(stream->m_alSource);
+ stream->m_bIsPaused = true;
+ }
+ }
+ else
+ {
+ if ( stream->m_bIsPaused )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsPaused = false;
+ }
+ }
+ }
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ stream->Initialize();
+ if ( stream->m_bIsOpened )
+ {
+ //NOTE: set pos here on mobile
+
+ if ( stream->FillBuffers() != 0 )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsFree = false;
+ }
+ }
+ }
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ delete mp3Stream[nStream];
+ mp3Stream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ mp3Stream[nStream] = stream;
+
+ if ( stream->m_bIsOpened )
+ {
+ stream->Initialize();
+ nStreamLength[nFile] = stream->m_nLength;
+ //MusicManager.SetTrackInfoLength(nFile, stream->m_nLength);
+
+ if ( stream->m_bIsOpened )
+ {
+ if ( nPos != 0 )
+ {
+ stream->SetPos(nPos);
+ }
+
+ if ( stream->FillBuffers() != 0 )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsFree = false;
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate;
+ }
+
+ return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nVolume > MAX_VOLUME )
+ nVolume = MAX_VOLUME;
+
+ if ( nPan > MAX_VOLUME )
+ nPan = MAX_VOLUME;
+
+ nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
+ nStreamPan [nStream] = nPan;
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ uint32 vol;
+ if ( nEffectFlag )
+ vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14;
+ else
+ vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14;
+
+ if ( stream->m_nVolume != vol )
+ {
+ if ( stream->m_bIsOpened )
+ {
+ ALuint source = stream->m_alSource;
+ if ( source )
+ {
+ ALfloat gain = ALfloat(vol) / MAX_VOLUME;
+ alSourcef(source, AL_GAIN, gain);
+ stream = mp3Stream[nStream];
+ }
+ }
+
+ stream->m_nVolume = vol;
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+ ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
+
+ return nStreamLength[nStream];
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused )
+ {
+ ALint sourceState;
+ alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState);
+ if ( !stream->m_bIsFree || sourceState == AL_PLAYING )
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::Service(void)
+{
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ if ( mp3Stream[i] )
+ mp3Stream[i]->Update();
+ }
+
+ UpdateSoundBuffers();
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+ int32 nBank = SAMPLEBANK_MAIN;
+
+ fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
+ if ( fpSampleDescHandle == NULL )
+ return false;
+
+ fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
+ if ( fpSampleDataHandle == NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ return false;
+ }
+
+ fseek(fpSampleDataHandle, 0, SEEK_END);
+ int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle);
+ rewind(fpSampleDataHandle);
+
+ fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
+
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+ {
+ nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+ nBank++;
+ }
+ }
+
+ nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+ nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+
+ return true;
+}
+
+/*
+sub_1D8D40
+PreloadSoundBank(tSample *,uchar)
+CheckOpenALChannels(void)
+*/
+
+void MP3Stream::Initialize(void)
+{
+ if ( !m_bIsOpened )
+ return;
+
+ mpg123_format_none(m_pMPG);
+
+ mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+
+ if ( mpg123_open_feed(m_pMPG) != MPG123_OK )
+ return;
+
+ const uint32 CHUNK_SIZE = 1024*5;
+
+ if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE )
+ {
+ Delete();
+ return;
+ }
+
+ m_nBufSize -= CHUNK_SIZE;
+
+ mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE);
+
+ if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK )
+ {
+ Delete();
+ return;
+ }
+
+ mpg123_frameinfo info;
+ if ( mpg123_info(m_pMPG, &info) != MPG123_OK )
+ {
+ Delete();
+ return;
+ }
+
+ m_nBitRate = info.bitrate;
+ m_nLength = 8 * m_nLengthInBytes / info.bitrate;
+ m_nBlockSize = mpg123_outblock(m_pMPG);
+ m_nNumBlocks = 5;
+ m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize);
+}
+
+bool MP3Stream::FillBuffer(ALuint alBuffer)
+{
+ size_t done;
+
+ uint8 *pBlockBuff = (uint8 *)m_pBlocks;
+
+ bool fail = !(m_nBufSize > 1);
+
+ int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done);
+ if ( alBuffer == 0 )
+ {
+ if ( err == MPG123_OK )
+ {
+ while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK )
+ ;
+ }
+
+ return true;
+ }
+
+ int32 blocks = 0;
+ for ( blocks = 0; blocks < m_nNumBlocks; blocks++ )
+ {
+ if ( err == MPG123_NEED_MORE )
+ {
+ if ( fail )
+ break;
+
+ size_t readSize = m_nBufSize;
+ if ( readSize > 0x4000 )
+ {
+ if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 )
+ {
+ fail = true;
+ TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing");
+ break;
+ }
+
+ m_nBufSize -= 0x4000;
+ mpg123_feed(m_pMPG, m_pBuf, 0x4000);
+ }
+ else
+ {
+ if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize )
+ {
+ fail = true;
+ break;
+ }
+
+ m_nBufSize -= readSize;
+ mpg123_feed(m_pMPG, m_pBuf, readSize);
+ }
+ }
+ else if ( err == MPG123_OK )
+ {
+ pBlockBuff += m_nBlockSize;
+ }
+ else
+ {
+ fail = true;
+ break;
+ }
+
+ err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done);
+ }
+
+ if ( blocks != 0 )
+ {
+ if ( m_nChannels == 1 )
+ alBufferData(alBuffer, AL_FORMAT_MONO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
+ else
+ alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
+ }
+
+ if ( fail && blocks < m_nNumBlocks )
+ m_bIsFree = true;
+
+ return blocks != 0;
+}
+
+void MP3Stream::Update(void)
+{
+ if ( !m_bIsOpened )
+ return;
+
+ if ( m_bIsFree )
+ return;
+
+ if ( !m_bIsPaused )
+ {
+ ALint sourceState;
+ ALint buffersProcessed = 0;
+
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+
+ ALint looping = AL_FALSE;
+ alGetSourcei(m_alSource, AL_LOOPING, &looping);
+
+ if ( looping == AL_TRUE )
+ {
+ TRACE("stream set looping");
+ alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
+ }
+
+ while( buffersProcessed-- )
+ {
+ ALuint buffer;
+
+ alSourceUnqueueBuffers(m_alSource, 1, &buffer);
+
+ if ( !m_bIsFree && FillBuffer(buffer) )
+ alSourceQueueBuffers(m_alSource, 1, &buffer);
+ }
+
+ if ( sourceState != AL_PLAYING )
+ {
+ alSourcef(m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(m_alSource);
+ }
+ }
+}
+
+void MP3Stream::SetPos(uint32 nPos)
+{
+ uint32 pos = nPos;
+ if ( nPos > m_nLength )
+ pos %= m_nLength;
+
+ uint32 blockPos = m_nBitRate * pos / 8;
+ if ( blockPos > m_nLengthInBytes )
+ blockPos %= m_nLengthInBytes;
+
+ fseek(m_fpFile, blockPos, SEEK_SET);
+
+ size_t done;
+ while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK )
+ ;
+}
+
+int32 MP3Stream::FillBuffers()
+{
+ int32 i = 0;
+ for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ )
+ {
+ if ( !FillBuffer(m_alBuffers[i]) )
+ break;
+ alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
+ }
+
+ return i;
+}
+
+MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers)
+{
+ strcpy(m_aFilename, filename);
+ memset(m_alBuffers, 0, sizeof(m_alBuffers));
+ m_alSource = source;
+ memcpy(m_alBuffers, buffers, sizeof(m_alBuffers));
+ m_nVolume = -1;
+ m_pBlocks = NULL;
+ m_pBuf = NULL;
+ m_pMPG = NULL;
+ m_bIsPaused = false;
+ m_bIsOpened = true;
+ m_bIsFree = true;
+ m_fpFile = fopen(m_aFilename, "rb");
+
+ if ( m_fpFile )
+ {
+ m_nBufSize = filelength(fileno(m_fpFile));
+ m_nLengthInBytes = m_nBufSize;
+ m_pMPG = mpg123_new(NULL, NULL);
+ m_pBuf = (unsigned char *)malloc(0x4000);
+ }
+ else
+ {
+ m_bIsOpened = false;
+ Delete();
+ }
+}
+
+void MP3Stream::Delete()
+{
+ if ( m_pMPG )
+ {
+ mpg123_delete(m_pMPG);
+ m_pMPG = NULL;
+ }
+
+ if ( m_fpFile )
+ {
+ fclose(m_fpFile);
+ m_fpFile = NULL;
+ }
+
+ if ( m_alSource )
+ {
+ ALint sourceState = AL_STOPPED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_STOPPED )
+ alSourceStop(m_alSource);
+
+ ALint buffersQueued;
+ alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
+
+ ALuint value;
+ while (buffersQueued--)
+ alSourceUnqueueBuffers(m_alSource, 1, &value);
+
+ m_alSource = 0;
+ }
+
+ if ( m_pBlocks )
+ {
+ free(m_pBlocks);
+ m_pBlocks = NULL;
+ }
+
+ if ( m_pBuf )
+ {
+ free(m_pBuf);
+ m_pBuf = NULL;
+ }
+
+ m_bIsOpened = false;
+} \ No newline at end of file
diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h
new file mode 100644
index 00000000..8bbdbcc9
--- /dev/null
+++ b/src/audio/openal/samp_oal.h
@@ -0,0 +1,340 @@
+#pragma once
+#include "common.h"
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+//#define MAX_FREQ 22050
+#define MAX_FREQ 32000
+
+struct tSample {
+ int32 nOffset;
+ uint32 nSize;
+ int32 nFrequency;
+ int32 nLoopStart;
+ int32 nLoopEnd;
+};
+
+enum
+{
+ SAMPLEBANK_MAIN,
+ SAMPLEBANK_PED,
+ MAX_SAMPLEBANKS,
+ SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX 7
+#define PED_BLOCKSIZE 79000
+
+
+//#define MAXCHANNELS 21 android
+#define MAXCHANNELS 28
+#define MAX2DCHANNELS 1
+#define CHANNEL2D MAXCHANNELS
+
+#define MAX_STREAMS 2
+
+struct ALCdevice_struct;
+struct ALCcontext_struct;
+typedef struct ALCdevice_struct ALCdevice;
+typedef struct ALCcontext_struct ALCcontext;
+
+class cSampleManager
+{
+ int field_0;
+ ALCdevice *m_pDevice;
+ ALCcontext *m_pContext;
+
+ uint8 m_nEffectsVolume;
+ uint8 m_nMusicVolume;
+ uint8 m_nEffectsFadeVolume;
+ uint8 m_nMusicFadeVolume;
+ uint8 m_nMonoMode;
+ char _pad0[3];
+ tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+
+
+
+ cSampleManager(void);
+ ~cSampleManager(void);
+
+ void SetSpeakerConfig(int32 nConfig);
+ uint32 GetMaximumSupportedChannels(void);
+
+ uint32 GetNum3DProvidersAvailable();
+ void SetNum3DProvidersAvailable(uint32 num);
+
+ char *Get3DProviderName(uint8 id);
+ void Set3DProviderName(uint8 id, char *name);
+
+ int8 GetCurrent3DProviderIndex(void);
+ int8 SetCurrent3DProvider(uint8 which);
+
+ bool IsMP3RadioChannelAvailable(void);
+
+ void ReleaseDigitalHandle (void);
+ void ReacquireDigitalHandle(void);
+
+ bool Initialise(void);
+ void Terminate (void);
+
+ void UpdateSoundBuffers(void);
+
+ bool CheckForAnAudioFileOnCD(void);
+ char GetCDAudioDriveLetter (void);
+
+ void UpdateEffectsVolume(void);
+
+ void SetEffectsMasterVolume(uint8 nVolume);
+ void SetMusicMasterVolume (uint8 nVolume);
+ void SetEffectsFadeVolume (uint8 nVolume);
+ void SetMusicFadeVolume (uint8 nVolume);
+ void SetMonoMode (uint8 nMode);
+
+ bool LoadSampleBank (uint8 nBank);
+ void UnloadSampleBank (uint8 nBank);
+ bool IsSampleBankLoaded(uint8 nBank);
+
+ bool IsPedCommentLoaded(uint32 nComment);
+ bool LoadPedComment (uint32 nComment);
+ int32 GetBankContainingSound(uint32 offset);
+
+ int32 _GetPedCommentSlot(uint32 nComment);
+
+ int32 GetSampleBaseFrequency (uint32 nSample);
+ int32 GetSampleLoopStartOffset(uint32 nSample);
+ int32 GetSampleLoopEndOffset (uint32 nSample);
+ uint32 GetSampleLength (uint32 nSample);
+
+ bool UpdateReverb(void);
+
+ void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
+ bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
+ void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+ void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
+ void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
+ void SetChannelVolume (uint32 nChannel, uint32 nVolume);
+ void SetChannelPan (uint32 nChannel, uint32 nPan);
+ void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
+ void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
+ void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
+ bool GetChannelUsedFlag (uint32 nChannel);
+ void StartChannel (uint32 nChannel);
+ void StopChannel (uint32 nChannel);
+
+ void PreloadStreamedFile (uint8 nFile, uint8 nStream);
+ void PauseStream (uint8 nPauseFlag, uint8 nStream);
+ void StartPreloadedStreamedFile (uint8 nStream);
+ bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
+ void StopStreamedFile (uint8 nStream);
+ int32 GetStreamedFilePosition (uint8 nStream);
+ void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
+ int32 GetStreamedFileLength (uint8 nStream);
+ bool IsStreamPlaying (uint8 nStream);
+ void Service(void);
+ bool InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+ "AUDIO\\HEAD.MP3",
+ "AUDIO\\CLASS.MP3",
+ "AUDIO\\KJAH.MP3",
+ "AUDIO\\RISE.MP3",
+ "AUDIO\\LIPS.MP3",
+ "AUDIO\\GAME.MP3",
+ "AUDIO\\MSX.MP3",
+ "AUDIO\\FLASH.MP3",
+ "AUDIO\\CHAT.MP3",
+ "AUDIO\\HEAD.MP3",
+ "AUDIO\\POLICE.MP3",
+ "AUDIO\\CITY.MP3",
+ "AUDIO\\WATER.MP3",
+ "AUDIO\\COMOPEN.MP3",
+ "AUDIO\\SUBOPEN.MP3",
+ "AUDIO\\JB.MP3",
+ "AUDIO\\BET.MP3",
+ "AUDIO\\L1_LG.MP3",
+ "AUDIO\\L2_DSB.MP3",
+ "AUDIO\\L3_DM.MP3",
+ "AUDIO\\L4_PAP.MP3",
+ "AUDIO\\L5_TFB.MP3",
+ "AUDIO\\J0_DM2.MP3",
+ "AUDIO\\J1_LFL.MP3",
+ "AUDIO\\J2_KCL.MP3",
+ "AUDIO\\J3_VH.MP3",
+ "AUDIO\\J4_ETH.MP3",
+ "AUDIO\\J5_DST.MP3",
+ "AUDIO\\J6_TBJ.MP3",
+ "AUDIO\\T1_TOL.MP3",
+ "AUDIO\\T2_TPU.MP3",
+ "AUDIO\\T3_MAS.MP3",
+ "AUDIO\\T4_TAT.MP3",
+ "AUDIO\\T5_BF.MP3",
+ "AUDIO\\S0_MAS.MP3",
+ "AUDIO\\S1_PF.MP3",
+ "AUDIO\\S2_CTG.MP3",
+ "AUDIO\\S3_RTC.MP3",
+ "AUDIO\\S5_LRQ.MP3",
+ "AUDIO\\S4_BDBA.MP3",
+ "AUDIO\\S4_BDBB.MP3",
+ "AUDIO\\S2_CTG2.MP3",
+ "AUDIO\\S4_BDBD.MP3",
+ "AUDIO\\S5_LRQB.MP3",
+ "AUDIO\\S5_LRQC.MP3",
+ "AUDIO\\A1_SSO.MP3",
+ "AUDIO\\A2_PP.MP3",
+ "AUDIO\\A3_SS.MP3",
+ "AUDIO\\A4_PDR.MP3",
+ "AUDIO\\A5_K2FT.MP3",
+ "AUDIO\\K1_KBO.MP3",
+ "AUDIO\\K2_GIS.MP3",
+ "AUDIO\\K3_DS.MP3",
+ "AUDIO\\K4_SHI.MP3",
+ "AUDIO\\K5_SD.MP3",
+ "AUDIO\\R0_PDR2.MP3",
+ "AUDIO\\R1_SW.MP3",
+ "AUDIO\\R2_AP.MP3",
+ "AUDIO\\R3_ED.MP3",
+ "AUDIO\\R4_GF.MP3",
+ "AUDIO\\R5_PB.MP3",
+ "AUDIO\\R6_MM.MP3",
+ "AUDIO\\D1_STOG.MP3",
+ "AUDIO\\D2_KK.MP3",
+ "AUDIO\\D3_ADO.MP3",
+ "AUDIO\\D5_ES.MP3",
+ "AUDIO\\D7_MLD.MP3",
+ "AUDIO\\D4_GTA.MP3",
+ "AUDIO\\D4_GTA2.MP3",
+ "AUDIO\\D6_STS.MP3",
+ "AUDIO\\A6_BAIT.MP3",
+ "AUDIO\\A7_ETG.MP3",
+ "AUDIO\\A8_PS.MP3",
+ "AUDIO\\A9_ASD.MP3",
+ "AUDIO\\K4_SHI2.MP3",
+ "AUDIO\\C1_TEX.MP3",
+ "AUDIO\\EL_PH1.MP3",
+ "AUDIO\\EL_PH2.MP3",
+ "AUDIO\\EL_PH3.MP3",
+ "AUDIO\\EL_PH4.MP3",
+ "AUDIO\\YD_PH1.MP3",
+ "AUDIO\\YD_PH2.MP3",
+ "AUDIO\\YD_PH3.MP3",
+ "AUDIO\\YD_PH4.MP3",
+ "AUDIO\\HD_PH1.MP3",
+ "AUDIO\\HD_PH2.MP3",
+ "AUDIO\\HD_PH3.MP3",
+ "AUDIO\\HD_PH4.MP3",
+ "AUDIO\\HD_PH5.MP3",
+ "AUDIO\\MT_PH1.MP3",
+ "AUDIO\\MT_PH2.MP3",
+ "AUDIO\\MT_PH3.MP3",
+ "AUDIO\\MT_PH4.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\END.MP3",
+ "AUDIO\\lib_a1.MP3",
+ "AUDIO\\lib_a2.MP3",
+ "AUDIO\\lib_a.MP3",
+ "AUDIO\\lib_b.MP3",
+ "AUDIO\\lib_c.MP3",
+ "AUDIO\\lib_d.MP3",
+ "AUDIO\\l2_a.MP3",
+ "AUDIO\\j4t_1.MP3",
+ "AUDIO\\j4t_2.MP3",
+ "AUDIO\\j4t_3.MP3",
+ "AUDIO\\j4t_4.MP3",
+ "AUDIO\\j4_a.MP3",
+ "AUDIO\\j4_b.MP3",
+ "AUDIO\\j4_c.MP3",
+ "AUDIO\\j4_d.MP3",
+ "AUDIO\\j4_e.MP3",
+ "AUDIO\\j4_f.MP3",
+ "AUDIO\\j6_1.MP3",
+ "AUDIO\\j6_a.MP3",
+ "AUDIO\\j6_b.MP3",
+ "AUDIO\\j6_c.MP3",
+ "AUDIO\\j6_d.MP3",
+ "AUDIO\\t4_a.MP3",
+ "AUDIO\\s1_a.MP3",
+ "AUDIO\\s1_a1.MP3",
+ "AUDIO\\s1_b.MP3",
+ "AUDIO\\s1_c.MP3",
+ "AUDIO\\s1_c1.MP3",
+ "AUDIO\\s1_d.MP3",
+ "AUDIO\\s1_e.MP3",
+ "AUDIO\\s1_f.MP3",
+ "AUDIO\\s1_g.MP3",
+ "AUDIO\\s1_h.MP3",
+ "AUDIO\\s1_i.MP3",
+ "AUDIO\\s1_j.MP3",
+ "AUDIO\\s1_k.MP3",
+ "AUDIO\\s1_l.MP3",
+ "AUDIO\\s3_a.MP3",
+ "AUDIO\\s3_b.MP3",
+ "AUDIO\\el3_a.MP3",
+ "AUDIO\\mf1_a.MP3",
+ "AUDIO\\mf2_a.MP3",
+ "AUDIO\\mf3_a.MP3",
+ "AUDIO\\mf3_b.MP3",
+ "AUDIO\\mf3_b1.MP3",
+ "AUDIO\\mf3_c.MP3",
+ "AUDIO\\mf4_a.MP3",
+ "AUDIO\\mf4_b.MP3",
+ "AUDIO\\mf4_c.MP3",
+ "AUDIO\\a1_a.MP3",
+ "AUDIO\\a3_a.MP3",
+ "AUDIO\\a5_a.MP3",
+ "AUDIO\\a4_a.MP3",
+ "AUDIO\\a4_b.MP3",
+ "AUDIO\\a4_c.MP3",
+ "AUDIO\\a4_d.MP3",
+ "AUDIO\\k1_a.MP3",
+ "AUDIO\\k3_a.MP3",
+ "AUDIO\\r1_a.MP3",
+ "AUDIO\\r2_a.MP3",
+ "AUDIO\\r2_b.MP3",
+ "AUDIO\\r2_c.MP3",
+ "AUDIO\\r2_d.MP3",
+ "AUDIO\\r2_e.MP3",
+ "AUDIO\\r2_f.MP3",
+ "AUDIO\\r2_g.MP3",
+ "AUDIO\\r2_h.MP3",
+ "AUDIO\\r5_a.MP3",
+ "AUDIO\\r6_a.MP3",
+ "AUDIO\\r6_a1.MP3",
+ "AUDIO\\r6_b.MP3",
+ "AUDIO\\lo2_a.MP3",
+ "AUDIO\\lo6_a.MP3",
+ "AUDIO\\yd2_a.MP3",
+ "AUDIO\\yd2_b.MP3",
+ "AUDIO\\yd2_c.MP3",
+ "AUDIO\\yd2_c1.MP3",
+ "AUDIO\\yd2_d.MP3",
+ "AUDIO\\yd2_e.MP3",
+ "AUDIO\\yd2_f.MP3",
+ "AUDIO\\yd2_g.MP3",
+ "AUDIO\\yd2_h.MP3",
+ "AUDIO\\yd2_ass.MP3",
+ "AUDIO\\yd2_ok.MP3",
+ "AUDIO\\h5_a.MP3",
+ "AUDIO\\h5_b.MP3",
+ "AUDIO\\h5_c.MP3",
+ "AUDIO\\ammu_a.MP3",
+ "AUDIO\\ammu_b.MP3",
+ "AUDIO\\ammu_c.MP3",
+ "AUDIO\\door_1.MP3",
+ "AUDIO\\door_2.MP3",
+ "AUDIO\\door_3.MP3",
+ "AUDIO\\door_4.MP3",
+ "AUDIO\\door_5.MP3",
+ "AUDIO\\door_6.MP3",
+ "AUDIO\\t3_a.MP3",
+ "AUDIO\\t3_b.MP3",
+ "AUDIO\\t3_c.MP3",
+ "AUDIO\\k1_b.MP3",
+ "AUDIO\\cat1.MP3"
+};
diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp
index 6edb6028..aa6b67dc 100644
--- a/src/audio/sampman.cpp
+++ b/src/audio/sampman.cpp
@@ -1,2334 +1,7 @@
-#include <windows.h>
-#include <shobjidl.h>
-#include <shlguid.h>
-
-#include <time.h>
-
-#include "eax.h"
-#include "eax-util.h"
-#include "mss.h"
-
-#include "sampman.h"
-#include "AudioManager.h"
-#include "MusicManager.h"
-#include "Frontend.h"
-#include "Timer.h"
-#include "patcher.h"
-
-#pragma comment( lib, "mss32.lib" )
-
-cSampleManager &SampleManager = *(cSampleManager *)0x7341E0;
-extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS] = *(int32 (*)[MAX_SAMPLEBANKS])*(int *)0x6FAB70;
-
-///////////////////////////////////////////////////////////////
-
-char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
-char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
-
-FILE *fpSampleDescHandle;
-FILE *fpSampleDataHandle;
-bool bSampleBankLoaded [MAX_SAMPLEBANKS];
-int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
-int32 nSampleBankSize [MAX_SAMPLEBANKS];
-int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
-int32 _nSampleDataEndOffset;
-
-int32 nPedSlotSfx [MAX_PEDSFX];
-int32 nPedSlotSfxAddr[MAX_PEDSFX];
-uint8 nCurrentPedSlot;
-
-uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-
-uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
-
-///////////////////////////////////////////////////////////////
-struct tMP3Entry
-{
- char aFilename[MAX_PATH];
-
- uint32 nTrackLength;
- uint32 nTrackStreamPos;
-
- tMP3Entry *pNext;
- char *pLinkPath;
-};
-
-uint32 nNumMP3s;
-tMP3Entry *_pMP3List;
-char _mp3DirectoryPath[MAX_PATH];
-HSTREAM mp3Stream [MAX_MP3STREAMS];
-int8 nStreamPan [MAX_MP3STREAMS];
-int8 nStreamVolume[MAX_MP3STREAMS];
-uint32 _CurMP3Index;
-int32 _CurMP3Pos;
-bool _bIsMp3Active;
-
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
-bool _bUseHDDAudio;
-char _aHDDPath[MAX_PATH];
-#endif
-///////////////////////////////////////////////////////////////
-
-
-bool _bSampmanInitialised = false;
-
-//
-// Miscellaneous globals / defines
-
-// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
-
-EAXLISTENERPROPERTIES StartEAX3 =
- {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f };
-
-EAXLISTENERPROPERTIES FinishEAX3 =
- {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f };
-
-EAXLISTENERPROPERTIES EAX3Params;
-
-S32 prevprovider=-1;
-S32 curprovider=-1;
-S32 usingEAX=0;
-S32 usingEAX3=0;
-HPROVIDER opened_provider=0;
-H3DSAMPLE opened_samples[MAXCHANNELS] = {0};
-HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
-HDIGDRIVER DIG;
-S32 speaker_type=0;
-
-U32 _maxSamples;
-float _fPrevEaxRatioDestination;
-bool _usingMilesFast2D;
-float _fEffectsLevel;
-
-
-struct
-{
- HPROVIDER id;
- char name[80];
-}providers[MAXPROVIDERS];
-
-typedef struct provider_stuff
-{
- char* name;
- HPROVIDER id;
-} provider_stuff;
-
-
-static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
-{
- return(strcasecmp(s1->name, s2->name));
-}
-
-static void
-add_providers()
-{
- provider_stuff pi[MAXPROVIDERS];
- U32 n,i,j;
-
- SampleManager.SetNum3DProvidersAvailable(0);
-
- HPROENUM next = HPROENUM_FIRST;
-
- n=0;
- while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n<MAXPROVIDERS))
- {
- ++n;
- }
-
- qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp);
-
- for(i=0;i<n;i++)
- {
- providers[i].id=pi[i].id;
- strcpy(providers[i].name, pi[i].name);
- SampleManager.Set3DProviderName(i, providers[i].name);
- }
-
- SampleManager.SetNum3DProvidersAvailable(n);
-
- for(j=n;j<MAXPROVIDERS;j++)
- SampleManager.Set3DProviderName(j, NULL);
-}
-
-static void
-release_existing()
-{
- for ( U32 i = 0; i < _maxSamples; i++ )
- {
- if ( opened_samples[i] )
- {
- AIL_release_3D_sample_handle(opened_samples[i]);
- opened_samples[i] = NULL;
- }
- }
-
- if ( opened_provider )
- {
- AIL_close_3D_provider(opened_provider);
- opened_provider = NULL;
- }
-
- _fPrevEaxRatioDestination = 0.0f;
- _usingMilesFast2D = false;
- _fEffectsLevel = 0.0f;
-}
-
-static bool
-set_new_provider(S32 index)
-{
- DWORD result;
-
- if ( curprovider == index )
- return true;
-
- //close the already opened provider
- curprovider = index;
-
- release_existing();
-
- if ( curprovider != -1 )
- {
- if ( !strcmp(providers[index].name, "Dolby Surround") )
- _maxSamples = MAXCHANNELS_SURROUND;
- else
- _maxSamples = MAXCHANNELS;
-
- AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples);
-
- //load the new provider
- result = AIL_open_3D_provider(providers[index].id);
-
- if (result != M3D_NOERR)
- {
- curprovider=-1;
-
- OutputDebugStringA(AIL_last_error());
-
- release_existing();
-
- return false;
- }
- else
- {
- opened_provider=providers[index].id;
-
- //see if we're running under an EAX compatible provider
-
- if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") )
- {
- usingEAX = 1;
- usingEAX3 = 1;
- }
- else
- {
- usingEAX3 = 0;
-
- result=AIL_3D_room_type(opened_provider);
- usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX
- }
-
- if ( usingEAX3 )
- {
- OutputDebugString("DOING SPECIAL EAX 3 STUFF!");
- AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3);
- }
- else if ( usingEAX )
- {
- AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE);
-
- if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") )
- _usingMilesFast2D = true;
- }
-
- AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples);
-
- if ( _maxSamples > MAXCHANNELS )
- _maxSamples = MAXCHANNELS;
-
- SampleManager.SetSpeakerConfig(speaker_type);
-
- //obtain a 3D sample handles
- for ( U32 i = 0; i < _maxSamples; ++i )
- {
- opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider);
- if ( opened_samples[i] != NULL )
- AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f);
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-void
-cSampleManager::SetSpeakerConfig(int32 which)
-{
- switch ( which )
- {
- case 1:
- speaker_type=AIL_3D_2_SPEAKER;
- break;
-
- case 2:
- speaker_type=AIL_3D_HEADPHONE;
- break;
-
- case 3:
- speaker_type=AIL_3D_4_SPEAKER;
- break;
-
- default:
- return;
- break;
- }
-
- if (opened_provider)
- AIL_set_3D_speaker_type(opened_provider, speaker_type);
-}
-
-uint32
-cSampleManager::GetMaximumSupportedChannels(void)
-{
- if ( _maxSamples > MAXCHANNELS )
- return MAXCHANNELS;
-
- return _maxSamples;
-}
-
-int8
-cSampleManager::GetCurrent3DProviderIndex(void)
-{
- return curprovider;
-}
-
-int8
-cSampleManager::SetCurrent3DProvider(uint8 nProvider)
-{
- S32 savedprovider = curprovider;
-
- if ( nProvider < m_nNumberOfProviders )
- {
- if ( set_new_provider(nProvider) )
- return curprovider;
- else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
- return curprovider;
- else
- return -1;
- }
- else
- return curprovider;
-}
-
-static bool
-_ResolveLink(char const *path, char *out)
-{
- IShellLink* psl;
- WIN32_FIND_DATA fd;
- char filepath[MAX_PATH];
-
- CoInitialize(NULL);
-
- if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) ))
- {
- IPersistFile *ppf;
-
- if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
- {
- WCHAR wpath[MAX_PATH];
-
- MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
-
- if (SUCCEEDED(ppf->Load(wpath, STGM_READ)))
- {
- /* Resolve the link */
- if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH)))
- {
- strcpy(filepath, path);
-
- if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY)))
- {
- OutputDebugString(fd.cFileName);
-
- strcpy(out, filepath);
- // FIX: Release the objects. Taken from SA.
-#ifdef FIX_BUGS
- ppf->Release();
- psl->Release();
-#endif
- return true;
- }
- }
- }
-
- ppf->Release();
- }
- psl->Release();
- }
-
- return false;
-}
-
-static void
-_FindMP3s(void)
-{
- tMP3Entry *pList;
- bool bShortcut;
- bool bInitFirstEntry;
- HANDLE hFind;
- char path[MAX_PATH];
- char filepath[MAX_PATH*2];
- S32 total_ms;
- WIN32_FIND_DATA fd;
-
-
- if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 )
- {
- GetLastError();
- return;
- }
-
- OutputDebugString("Finding MP3s...");
- strcpy(path, _mp3DirectoryPath);
- strcat(path, "\\MP3\\");
-
- strcpy(_mp3DirectoryPath, path);
- OutputDebugString(_mp3DirectoryPath);
-
- strcat(path, "*");
-
- hFind = FindFirstFile(path, &fd);
-
- if ( hFind == INVALID_HANDLE_VALUE )
- {
- GetLastError();
- return;
- }
-
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( filepathlen <= 0)
- {
- FindClose(hFind);
- return;
- }
-
- FILE *f = fopen("MP3\\MP3Report.txt", "w");
-
- if ( f )
- {
- fprintf(f, "MP3 Report File\n\n");
- fprintf(f, "\"%s\"", fd.cFileName);
- }
-
-
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f )
- fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- {
- bShortcut = false;
- }
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- OutputDebugString(fd.cFileName);
-
- _pMP3List = new tMP3Entry;
-
- if ( _pMP3List == NULL )
- {
- FindClose(hFind);
-
- if ( f )
- fclose(f);
-
- return;
- }
-
- nNumMP3s = 1;
-
- strcpy(_pMP3List->aFilename, fd.cFileName);
-
- _pMP3List->nTrackLength = total_ms;
-
- _pMP3List->pNext = NULL;
-
- pList = _pMP3List;
-
- if ( bShortcut )
- {
- _pMP3List->pLinkPath = new char[MAX_PATH*2];
- strcpy(_pMP3List->pLinkPath, filepath);
- }
- else
- {
- _pMP3List->pLinkPath = NULL;
- }
-
- if ( f )
- fprintf(f, " - OK\n");
-
- bInitFirstEntry = false;
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
-
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - not an MP3 or supported MP3 type\n");
-
- bInitFirstEntry = true;
- }
-
- while ( true )
- {
- if ( !FindNextFile(hFind, &fd) )
- {
- if ( f )
- {
- fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
- fclose(f);
- }
-
- FindClose(hFind);
-
- return;
- }
-
- if ( bInitFirstEntry )
- {
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( f )
- fprintf(f, "\"%s\"", fd.cFileName);
-
- if ( filepathlen > 0 )
- {
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f )
- fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- {
- bShortcut = false;
-
- if ( filepathlen > MAX_PATH )
- {
- if ( f )
- fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
-
- continue;
- }
- }
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- OutputDebugString(fd.cFileName);
-
- _pMP3List = new tMP3Entry;
-
- if ( _pMP3List == NULL)
- {
- if ( f )
- {
- fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
- fclose(f);
- }
- FindClose(hFind);
- return;
- }
-
- nNumMP3s = 1;
-
- strcpy(_pMP3List->aFilename, fd.cFileName);
-
- _pMP3List->nTrackLength = total_ms;
- _pMP3List->pNext = NULL;
-
- if ( bShortcut )
- {
- _pMP3List->pLinkPath = new char [MAX_PATH*2];
- strcpy(_pMP3List->pLinkPath, filepath);
- }
- else
- {
- _pMP3List->pLinkPath = NULL;
- }
-
- pList = _pMP3List;
-
- if ( f )
- fprintf(f, " - OK\n");
-
- bInitFirstEntry = false;
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - not an MP3 or supported MP3 type\n");
- }
- }
- }
- else
- {
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( filepathlen > 0 )
- {
- if ( f )
- fprintf(f, "\"%s\"", fd.cFileName);
-
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f )
- fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- {
- bShortcut = false;
- }
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- pList->pNext = new tMP3Entry;
-
- tMP3Entry *e = pList->pNext;
-
- if ( e == NULL)
- {
- if ( f )
- {
- fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
- fclose(f);
- }
- FindClose(hFind);
- return;
- }
-
- pList = pList->pNext;
-
- strcpy(e->aFilename, fd.cFileName);
- e->nTrackLength = total_ms;
- e->pNext = NULL;
-
- if ( bShortcut )
- {
- e->pLinkPath = new char [MAX_PATH*2];
- strcpy(e->pLinkPath, filepath);
- }
- else
- {
- e->pLinkPath = NULL;
- }
-
- nNumMP3s++;
-
- OutputDebugString(fd.cFileName);
-
- if ( f )
- fprintf(f, " - OK\n");
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
- OutputDebugString(filepath);
-
- if ( f )
- fprintf(f, " - not an MP3 or supported MP3 type\n");
- }
- }
- }
- }
-}
-
-static void
-_DeleteMP3Entries(void)
-{
- tMP3Entry *e = _pMP3List;
-
- while ( e != NULL )
- {
- tMP3Entry *next = e->pNext;
-
- if ( next == NULL )
- next = NULL;
-
- if ( e->pLinkPath != NULL )
- {
-#ifndef FIX_BUGS
- delete e->pLinkPath; // BUG: should be delete []
+#pragma once
+#include "common.h"
+#ifndef OPENAL
+#include "miles\sampman_mss.cpp"
#else
- delete[] e->pLinkPath;
-#endif
- e->pLinkPath = NULL;
- }
-
- delete e;
-
- if ( next )
- e = next;
- else
- e = NULL;
-
- nNumMP3s--;
- }
-
-
- if ( nNumMP3s != 0 )
- {
- OutputDebugString("Not all MP3 entries were deleted");
- nNumMP3s = 0;
- }
-
- _pMP3List = NULL;
-}
-
-static tMP3Entry *
-_GetMP3EntryByIndex(uint32 idx)
-{
- uint32 n = ( idx < nNumMP3s ) ? idx : 0;
-
- if ( _pMP3List != NULL )
- {
- tMP3Entry *e = _pMP3List;
-
- for ( uint32 i = 0; i < n; i++ )
- e = e->pNext;
-
- return e;
-
- }
-
- return NULL;
-}
-
-static inline bool
-_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry)
-{
- _CurMP3Index = 0;
-
- for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext )
- {
- if ( *pPosition >= (*pEntry)->nTrackStreamPos
- && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos )
- {
- *pPosition -= (*pEntry)->nTrackStreamPos;
- _CurMP3Pos = *pPosition;
-
- return true;
- }
-
- _CurMP3Index++;
- }
-
- *pPosition = 0;
- *pEntry = _pMP3List;
- _CurMP3Pos = 0;
- _CurMP3Index = 0;
-
- return false;
-}
-
-bool
-cSampleManager::IsMP3RadioChannelAvailable(void)
-{
- return nNumMP3s != 0;
-}
-
-void
-cSampleManager::ReleaseDigitalHandle(void)
-{
- if ( DIG )
- {
- prevprovider = curprovider;
- release_existing();
- curprovider = -1;
- AIL_digital_handle_release(DIG);
- }
-}
-
-void
-cSampleManager::ReacquireDigitalHandle(void)
-{
- if ( DIG )
- {
- AIL_digital_handle_reacquire(DIG);
- if ( prevprovider != -1 )
- set_new_provider(prevprovider);
- }
-}
-
-bool
-cSampleManager::Initialise(void)
-{
- TRACE("start");
-
- if ( _bSampmanInitialised )
- return true;
-
- {
- for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
- {
- m_aSamples[i].nOffset = 0;
- m_aSamples[i].nSize = 0;
- m_aSamples[i].nFrequency = 22050;
- m_aSamples[i].nLoopStart = 0;
- m_aSamples[i].nLoopEnd = -1;
- }
-
- m_nEffectsVolume = MAX_VOLUME;
- m_nMusicVolume = MAX_VOLUME;
- m_nEffectsFadeVolume = MAX_VOLUME;
- m_nMusicFadeVolume = MAX_VOLUME;
-
- m_nMonoMode = 0;
- }
-
- // miles
- TRACE("MILES");
- {
- curprovider = -1;
- prevprovider = -1;
-
- _usingMilesFast2D = false;
- usingEAX=0;
- usingEAX3=0;
-
- _fEffectsLevel = 0.0f;
-
- _maxSamples = 0;
-
- opened_provider = NULL;
- DIG = NULL;
-
- for ( int32 i = 0; i < MAXCHANNELS; i++ )
- opened_samples[i] = NULL;
- }
-
- // banks
- TRACE("banks");
- {
- fpSampleDescHandle = NULL;
- fpSampleDataHandle = NULL;
-
- _nSampleDataEndOffset = 0;
-
- for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
- {
- bSampleBankLoaded[i] = false;
- nSampleBankDiscStartOffset[i] = 0;
- nSampleBankSize[i] = 0;
- nSampleBankMemoryStartAddress[i] = 0;
- }
- }
-
- // pedsfx
- TRACE("pedsfx");
- {
- for ( int32 i = 0; i < MAX_PEDSFX; i++ )
- {
- nPedSlotSfx[i] = NO_SAMPLE;
- nPedSlotSfxAddr[i] = 0;
- }
-
- nCurrentPedSlot = 0;
- }
-
- // channel volume
- TRACE("vol");
- {
- for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
- nChannelVolume[i] = 0;
- }
-
- TRACE("mss");
- {
- AIL_set_redist_directory( "mss" );
-
- AIL_startup();
-
- AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS);
-
- DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
- if ( DIG == NULL )
- {
- OutputDebugString(AIL_last_error());
- Terminate();
- return false;
- }
-
- add_providers();
-
- if ( !InitialiseSampleBanks() )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]);
- if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
-
- }
-
- TRACE("cdrom");
-
- S32 tatalms;
- char filepath[MAX_PATH];
-
- {
- m_bInitialised = false;
-
- while (true)
- {
- int32 drive = 'C';
-
- do
- {
- char latter[2];
-
- latter[0] = drive;
- latter[1] = '\0';
-
- strcpy(m_szCDRomRootPath, latter);
- strcat(m_szCDRomRootPath, ":\\");
-
- if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
- {
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[0]);
-
- FILE *f = fopen(filepath, "rb");
-
- if ( f )
- {
- fclose(f);
-
- bool bFileNotFound = false;
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- nStreamLength[i] = tatalms;
- }
- else
- {
- bFileNotFound = true;
- break;
- }
- }
-
- if ( !bFileNotFound )
- {
- m_bInitialised = true;
- break;
- }
- else
- {
- m_bInitialised = false;
- continue;
- }
- }
- }
-
- } while ( ++drive <= 'Z' );
-
- if ( !m_bInitialised )
- {
-#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
- FrontEndMenuManager.WaitForUserCD();
- if ( FrontEndMenuManager.m_bQuitGameNoCD )
- {
- Terminate();
- return false;
- }
- continue;
-#else
- m_bInitialised = true;
-#endif
- }
-
- break;
- }
- }
-
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
- // hddaudio
- /**
- Option for user to play audio files directly from hard disk.
- Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory.
- Grand Theft Auto III still requires the presence of the PLAY disc when started.
- This may give better performance on some machines (though worse on others).
- **/
- TRACE("hddaudio 1.1 patch");
- {
- int32 streamLength[TOTAL_STREAMED_SOUNDS];
-
- bool bFileNotFound = false;
- char rootpath[MAX_PATH];
-
- strcpy(_aHDDPath, m_szCDRomRootPath);
- rootpath[0] = '\0';
-
- FILE *f = fopen(StreamedNameTable[0], "rb");
-
- if ( f )
- {
- fclose(f);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- strcpy(filepath, rootpath);
- strcat(filepath, StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- streamLength[i] = tatalms;
- }
- else
- {
- bFileNotFound = true;
- break;
- }
- }
-
- }
- else
- bFileNotFound = true;
-
- if ( !bFileNotFound )
- {
- strcpy(m_szCDRomRootPath, rootpath);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- nStreamLength[i] = streamLength[i];
-
- _bUseHDDAudio = true;
- }
- else
- _bUseHDDAudio = false;
- }
-#endif
-
- TRACE("stream");
- {
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
- {
- mp3Stream [i] = NULL;
- nStreamPan [i] = 63;
- nStreamVolume[i] = 100;
- }
- }
-
- for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
- {
- opened_2dsamples[i] = AIL_allocate_sample_handle(DIG);
- if ( opened_2dsamples[i] )
- {
- AIL_init_sample(opened_2dsamples[i]);
- AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN);
- }
- }
-
- TRACE("providerset");
- {
- _bSampmanInitialised = true;
-
- U32 n = 0;
-
- while ( n < m_nNumberOfProviders )
- {
- if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") )
- {
- set_new_provider(n);
- break;
- }
- n++;
- }
-
- if ( n == m_nNumberOfProviders )
- {
- Terminate();
- return false;
- }
- }
-
- TRACE("bank");
-
- LoadSampleBank(SAMPLEBANK_MAIN);
-
- // mp3
- TRACE("mp3");
- {
- nNumMP3s = 0;
-
- _pMP3List = NULL;
-
- _FindMP3s();
-
- if ( nNumMP3s != 0 )
- {
- nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0;
-
- for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext )
- {
- e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER];
- nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength;
- }
-
- time_t t = time(NULL);
- tm *localtm;
- bool bUseRandomTable;
-
- if ( t == -1 )
- bUseRandomTable = true;
- else
- {
- bUseRandomTable = false;
- localtm = localtime(&t);
- }
-
- int32 randval;
- if ( bUseRandomTable )
- randval = AudioManager.GetRandomNumber(1);
- else
- randval = localtm->tm_sec * localtm->tm_min;
-
- _CurMP3Index = randval % nNumMP3s;
-
- tMP3Entry *randmp3 = _pMP3List;
- for ( int32 i = randval % nNumMP3s; i > 0; --i)
- randmp3 = randmp3->pNext;
-
- if ( bUseRandomTable )
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
- else
- {
- if ( localtm->tm_sec > 0 )
- {
- int32 s = localtm->tm_sec;
- _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
- }
- else
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
- }
- }
- else
- _CurMP3Pos = 0;
-
- _bIsMp3Active = false;
- }
-
- TRACE("end");
-
- return true;
-}
-
-void
-cSampleManager::Terminate(void)
-{
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
- {
- if ( mp3Stream[i] )
- {
- AIL_pause_stream(mp3Stream[i], 1);
- AIL_close_stream(mp3Stream[i]);
- mp3Stream[i] = NULL;
- }
- }
-
- for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
- {
- if ( opened_2dsamples[i] )
- {
- AIL_release_sample_handle(opened_2dsamples[i]);
- opened_2dsamples[i] = NULL;
- }
- }
-
- release_existing();
-
- _DeleteMP3Entries();
-
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
- {
- AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
- nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
- }
-
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
- {
- AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
- nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
- }
-
- if ( DIG )
- {
- AIL_close_digital_driver(DIG);
- DIG = NULL;
- }
-
- AIL_shutdown();
-
- _bSampmanInitialised = false;
-}
-
-bool
-cSampleManager::CheckForAnAudioFileOnCD(void)
-{
-#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
- char filepath[MAX_PATH];
-
-#if defined(GTA3_1_1_PATCH)
- if (_bUseHDDAudio)
- strcpy(filepath, _aHDDPath);
- else
- strcpy(filepath, m_szCDRomRootPath);
-#else
- strcpy(filepath, m_szCDRomRootPath);
-#endif // #if defined(GTA3_1_1_PATCH)
-
- strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
-
- FILE *f = fopen(filepath, "rb");
-
- if ( f )
- {
- fclose(f);
-
- return true;
- }
-
- return false;
-
-#else
- return true;
-#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
-}
-
-char
-cSampleManager::GetCDAudioDriveLetter(void)
-{
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
- if (_bUseHDDAudio)
- {
- if ( strlen(_aHDDPath) != 0 )
- return _aHDDPath[0];
- else
- return '\0';
- }
- else
- {
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
- else
- return '\0';
- }
-#else
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
- else
- return '\0';
-#endif
-}
-
-void
-cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ?
-{
- if ( _bSampmanInitialised )
- {
- for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
- {
- if ( i < MAXCHANNELS )
- {
- if ( opened_samples[i] && GetChannelUsedFlag(i) )
- {
- if ( nChannelVolume[i] )
- {
- AIL_set_3D_sample_volume(opened_samples[i],
- m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
- }
- }
- }
- else
- {
- if ( opened_2dsamples[i - MAXCHANNELS] )
- {
- if ( GetChannelUsedFlag(i - MAXCHANNELS) )
- {
- if ( nChannelVolume[i - MAXCHANNELS] )
- {
- AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS],
- m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14);
- }
- }
- }
- }
- }
- }
-}
-
-void
-cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
-{
- m_nEffectsVolume = nVolume;
- UpdateEffectsVolume();
-}
-
-void
-cSampleManager::SetMusicMasterVolume(uint8 nVolume)
-{
- m_nMusicVolume = nVolume;
-}
-
-void
-cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
-{
- m_nEffectsFadeVolume = nVolume;
- UpdateEffectsVolume();
-}
-
-void
-cSampleManager::SetMusicFadeVolume(uint8 nVolume)
-{
- m_nMusicFadeVolume = nVolume;
-}
-
-bool
-cSampleManager::LoadSampleBank(uint8 nBank)
-{
- if ( CTimer::GetIsCodePaused() )
- return false;
-
- if ( MusicManager.IsInitialised()
- && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && nBank != SAMPLEBANK_MAIN )
- {
- return false;
- }
-
- if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
- return false;
-
- if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] )
- return false;
-
- bSampleBankLoaded[nBank] = true;
-
- return true;
-}
-
-void
-cSampleManager::UnloadSampleBank(uint8 nBank)
-{
- bSampleBankLoaded[nBank] = false;
-}
-
-bool
-cSampleManager::IsSampleBankLoaded(uint8 nBank)
-{
- return bSampleBankLoaded[nBank];
-}
-
-bool
-cSampleManager::IsPedCommentLoaded(uint32 nComment)
-{
- uint8 slot;
-
- for ( int32 i = 0; i < _TODOCONST(3); i++ )
- {
- slot = nCurrentPedSlot - i - 1;
- if ( nComment == nPedSlotSfx[slot] )
- return true;
- }
-
- return false;
-}
-
-int32
-cSampleManager::_GetPedCommentSlot(uint32 nComment)
-{
- uint8 slot;
-
- for ( int32 i = 0; i < _TODOCONST(3); i++ )
- {
- slot = nCurrentPedSlot - i - 1;
- if ( nComment == nPedSlotSfx[slot] )
- return slot;
- }
-
- return -1;
-}
-
-bool
-cSampleManager::LoadPedComment(uint32 nComment)
-{
- if ( CTimer::GetIsCodePaused() )
- return false;
-
- // no talking peds during cutsenes or the game end
- if ( MusicManager.IsInitialised() )
- {
- switch ( MusicManager.GetMusicMode() )
- {
- case MUSICMODE_CUTSCENE:
- {
- return false;
-
- break;
- }
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return false;
-
- break;
- }
- }
- }
-
- if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
- return false;
-
- if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
- return false;
-
- nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot;
- nPedSlotSfx [nCurrentPedSlot] = nComment;
-
- if ( ++nCurrentPedSlot >= MAX_PEDSFX )
- nCurrentPedSlot = 0;
-
- return true;
-}
-
-int32
-cSampleManager::GetSampleBaseFrequency(uint32 nSample)
-{
- return m_aSamples[nSample].nFrequency;
-}
-
-int32
-cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
-{
- return m_aSamples[nSample].nLoopStart;
-}
-
-int32
-cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
-{
- return m_aSamples[nSample].nLoopEnd;
-}
-
-uint32
-cSampleManager::GetSampleLength(uint32 nSample)
-{
- return m_aSamples[nSample].nSize >> 1;
-}
-
-bool
-cSampleManager::UpdateReverb(void)
-{
- if ( !usingEAX )
- return false;
-
- if ( AudioManager.GetFrameCounter() & 15 )
- return false;
-
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
-
- float normy = norm(y, 5.0f, 40.0f);
- float normx = norm(x, 5.0f, 40.0f);
- float normz = norm(z, 5.0f, 40.0f);
-
- float fRatio;
-
- if ( normy == 0.0f )
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- fRatio = 0.3f;
- }
- }
- else
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = (normy+normx+normz) / 3.0f;
- }
- }
-
- fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
-
- if ( fRatio == _fPrevEaxRatioDestination )
- return false;
-
- if ( usingEAX3 )
- {
- if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
- {
- AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params);
- _fEffectsLevel = 1.0f - fRatio * 0.5f;
- }
- }
- else
- {
- if ( _usingMilesFast2D )
- _fEffectsLevel = (1.0f - fRatio) * 0.4f;
- else
- _fEffectsLevel = (1.0f - fRatio) * 0.7f;
- }
-
- _fPrevEaxRatioDestination = fRatio;
-
- return true;
-}
-
-void
-cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( usingEAX )
- {
- if ( nReverbFlag != 0 )
- {
- if ( !b2d )
- AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel);
- }
- else
- {
- if ( !b2d )
- AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f);
- }
- }
-}
-
-bool
-cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- int32 addr;
-
- if ( nSfx < SAMPLEBANK_MAX )
- {
- if ( !IsSampleBankLoaded(nBank) )
- return false;
-
- addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
- }
- else
- {
- if ( !IsPedCommentLoaded(nSfx) )
- return false;
-
- int32 slot = _GetPedCommentSlot(nSfx);
-
- addr = nPedSlotSfxAddr[slot];
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- {
- AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize);
- return true;
- }
- else
- return false;
- }
- else
- {
- AILSOUNDINFO info;
-
- info.format = WAVE_FORMAT_PCM;
- info.data_ptr = (void *)addr;
- info.channels = 1;
- info.data_len = m_aSamples[nSfx].nSize;
- info.rate = m_aSamples[nSfx].nFrequency;
- info.bits = 16;
-
- if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 )
- {
- OutputDebugString(AIL_last_error());
- return false;
- }
-
- return true;
- }
-}
-
-void
-cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
-{
- uint32 vol = nVolume;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- nChannelVolume[nChannel] = vol;
-
- // increase the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
- }
-
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
-
-}
-
-void
-cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
-{
- if ( opened_samples[nChannel] )
- AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ);
-}
-
-void
-cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
-{
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin);
-}
-
-void
-cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
-{
- uint32 vol = nVolume;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- nChannelVolume[nChannel] = vol;
-
- // increase the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
- }
-
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- {
- AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS],
- m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
- }
-
- break;
- }
- }
-}
-
-void
-cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
-{
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
-#ifndef FIX_BUGS
- if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG
-#else
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
-#endif
- AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan);
-
- break;
- }
- }
-}
-
-void
-cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq);
- }
-}
-
-void
-cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd);
- }
-}
-
-void
-cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount);
- }
-}
-
-bool
-cSampleManager::GetChannelUsedFlag(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING;
- else
- return false;
- }
- else
- {
- if ( opened_samples[nChannel] )
- return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING;
- else
- return false;
- }
-
-}
-
-void
-cSampleManager::StartChannel(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_start_3D_sample(opened_samples[nChannel]);
- }
-}
-
-void
-cSampleManager::StopChannel(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
- }
- else
- {
- if ( opened_samples[nChannel] )
- {
- if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING )
- AIL_end_3D_sample(opened_samples[nChannel]);
- }
- }
-}
-
-void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
- AIL_close_stream(mp3Stream[nStream]);
- }
-
- char filepath[MAX_PATH];
-
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_service_stream(mp3Stream[nStream], 1);
- }
- else
- OutputDebugString(AIL_last_error());
- }
- }
-}
-
-void
-cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0);
- }
-}
-
-void
-cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- AIL_start_stream(mp3Stream[nStream]);
- }
-}
-
-bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
-{
- uint32 position = nPos;
- char filename[MAX_PATH];
-
- if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
- AIL_close_stream(mp3Stream[nStream]);
- }
-
- if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER )
- {
- uint32 i = 0;
-
- if ( !_bIsMp3Active ) goto FIND_MP3TRACK;
-
- do
- {
- if ( ++_CurMP3Index >= nNumMP3s )
- _CurMP3Index = 0;
-
- _CurMP3Pos = 0;
-
- tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
-
- if ( mp3 )
- {
- mp3 = _pMP3List;
- if ( mp3 == NULL )
- {
- _bIsMp3Active = false;
- nFile = 0;
- goto PLAY_STREAMEDTRACK;
- }
- }
-
- if ( mp3->pLinkPath != NULL )
- mp3Stream[nStream] = AIL_open_stream(DIG, mp3->pLinkPath, 0);
- else
- {
- strcpy(filename, _mp3DirectoryPath);
- strcat(filename, mp3->aFilename);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
- }
-
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], 0);
- AIL_pause_stream(mp3Stream[nStream], 0);
- return true;
- }
-
- goto NEXT_MP3TRACK;
-
-FIND_MP3TRACK:
- if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
- position = 0;
-
- tMP3Entry *e;
- if ( !_GetMP3PosFromStreamPos(&position, &e) )
- {
- if ( e == NULL )
- {
- nFile = 0;
- goto PLAY_STREAMEDTRACK;
- }
- }
-
- if ( e->pLinkPath != NULL )
- mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0);
- else
- {
- strcpy(filename, _mp3DirectoryPath);
- strcat(filename, e->aFilename);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
- }
-
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
-
- _bIsMp3Active = true;
-
- return true;
- }
-
-NEXT_MP3TRACK:
- _bIsMp3Active = false;
-
- } while ( ++i < nNumMP3s );
-
- position = 0;
- nFile = 0;
- goto PLAY_STREAMEDTRACK;
- }
-
-PLAY_STREAMEDTRACK:
- strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
- return true;
- }
- }
-
- return false;
-}
-
-void
-cSampleManager::StopStreamedFile(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
-
- AIL_close_stream(mp3Stream[nStream]);
- mp3Stream[nStream] = NULL;
-
- if ( nStream == 0 )
- _bIsMp3Active = false;
- }
- }
-}
-
-int32
-cSampleManager::GetStreamedFilePosition(uint8 nStream)
-{
- S32 currentms;
-
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- if ( _bIsMp3Active )
- {
- tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
-
- if ( mp3 != NULL )
- {
- AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
- return currentms + mp3->nTrackStreamPos;
- }
- else
- return 0;
- }
- else
- {
- AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
- return currentms;
- }
- }
- }
-
- return 0;
-}
-
-void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
-{
- uint8 vol = nVolume;
-
- if ( m_bInitialised )
- {
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- nStreamVolume[nStream] = vol;
- nStreamPan[nStream] = nPan;
-
- if ( mp3Stream[nStream] )
- {
- if ( nEffectFlag )
- AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
- else
- AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);
-
- AIL_set_stream_pan(mp3Stream[nStream], nPan);
- }
- }
-}
-
-int32
-cSampleManager::GetStreamedFileLength(uint8 nStream)
-{
- if ( m_bInitialised )
- return nStreamLength[nStream];
-
- return 0;
-}
-
-bool
-cSampleManager::IsStreamPlaying(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING )
- return true;
- else
- return false;
- }
- }
-
- return false;
-}
-
-bool
-cSampleManager::InitialiseSampleBanks(void)
-{
- int32 nBank = SAMPLEBANK_MAIN;
-
- fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
- if ( fpSampleDescHandle == NULL )
- return false;
-
- fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
- if ( fpSampleDataHandle == NULL )
- {
- fclose(fpSampleDescHandle);
- fpSampleDescHandle = NULL;
-
- return false;
- }
-
- fseek(fpSampleDataHandle, 0, SEEK_END);
- _nSampleDataEndOffset = ftell(fpSampleDataHandle);
- rewind(fpSampleDataHandle);
-
- fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
-
- fclose(fpSampleDescHandle);
- fpSampleDescHandle = NULL;
-
- for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
- {
- if ( BankStartOffset[nBank] == BankStartOffset[0] + i )
- {
- nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
- nBank++;
- }
- }
-
- nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
- nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
-
- return true;
-}
-
-STARTPATCHES
- //InjectHook(0x565500, cSampleManager::cSampleManager, PATCH_JUMP);
- //InjectHook(0x565510, cSampleManager::~cSampleManager, PATCH_JUMP);
- InjectHook(0x565520, comp, PATCH_JUMP);
- InjectHook(0x565540, add_providers, PATCH_JUMP);
- InjectHook(0x565680, release_existing, PATCH_JUMP);
- InjectHook(0x5656F0, set_new_provider, PATCH_JUMP);
- InjectHook(0x565900, &cSampleManager::SetSpeakerConfig, PATCH_JUMP);
- InjectHook(0x565970, &cSampleManager::GetMaximumSupportedChannels, PATCH_JUMP);
- InjectHook(0x565990, &cSampleManager::GetCurrent3DProviderIndex, PATCH_JUMP);
- InjectHook(0x5659A0, &cSampleManager::SetCurrent3DProvider, PATCH_JUMP);
- InjectHook(0x565A10, _ResolveLink, PATCH_JUMP);
- InjectHook(0x565B40, _FindMP3s, PATCH_JUMP);
- InjectHook(0x566380, _DeleteMP3Entries, PATCH_JUMP);
- InjectHook(0x566400, _GetMP3EntryByIndex, PATCH_JUMP);
- InjectHook(0x566490, &cSampleManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
- InjectHook(0x5664B0, &cSampleManager::ReleaseDigitalHandle, PATCH_JUMP);
- InjectHook(0x5664F0, &cSampleManager::ReacquireDigitalHandle, PATCH_JUMP);
- InjectHook(0x566530, &cSampleManager::Initialise, PATCH_JUMP);
- InjectHook(0x566DC0, &cSampleManager::Terminate, PATCH_JUMP);
- InjectHook(0x566EA0, &cSampleManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
- InjectHook(0x566F20, &cSampleManager::GetCDAudioDriveLetter, PATCH_JUMP);
- InjectHook(0x566F50, &cSampleManager::UpdateEffectsVolume, PATCH_JUMP);
- InjectHook(0x567010, &cSampleManager::SetEffectsMasterVolume, PATCH_JUMP);
- InjectHook(0x567020, &cSampleManager::SetMusicMasterVolume, PATCH_JUMP);
- InjectHook(0x567030, &cSampleManager::SetEffectsFadeVolume, PATCH_JUMP);
- InjectHook(0x567040, &cSampleManager::SetMusicFadeVolume, PATCH_JUMP);
- InjectHook(0x567050, &cSampleManager::LoadSampleBank, PATCH_JUMP);
- InjectHook(0x567110, &cSampleManager::UnloadSampleBank, PATCH_JUMP);
- InjectHook(0x567130, &cSampleManager::IsSampleBankLoaded, PATCH_JUMP);
- InjectHook(0x567150, &cSampleManager::IsPedCommentLoaded, PATCH_JUMP);
- InjectHook(0x5671A0, &cSampleManager::LoadPedComment, PATCH_JUMP);
- InjectHook(0x5672A0, &cSampleManager::GetSampleBaseFrequency, PATCH_JUMP);
- InjectHook(0x5672C0, &cSampleManager::GetSampleLoopStartOffset, PATCH_JUMP);
- InjectHook(0x5672E0, &cSampleManager::GetSampleLoopEndOffset, PATCH_JUMP);
- InjectHook(0x567300, &cSampleManager::GetSampleLength, PATCH_JUMP);
- InjectHook(0x567320, &cSampleManager::UpdateReverb, PATCH_JUMP);
- InjectHook(0x567630, &cSampleManager::SetChannelReverbFlag, PATCH_JUMP);
- InjectHook(0x5676A0, &cSampleManager::InitialiseChannel, PATCH_JUMP);
- InjectHook(0x567820, &cSampleManager::SetChannelEmittingVolume, PATCH_JUMP);
- InjectHook(0x567890, &cSampleManager::SetChannel3DPosition, PATCH_JUMP);
- InjectHook(0x5678D0, &cSampleManager::SetChannel3DDistances, PATCH_JUMP);
- InjectHook(0x567900, &cSampleManager::SetChannelVolume, PATCH_JUMP);
- InjectHook(0x567980, &cSampleManager::SetChannelPan, PATCH_JUMP);
- InjectHook(0x5679D0, &cSampleManager::SetChannelFrequency, PATCH_JUMP);
- InjectHook(0x567A30, &cSampleManager::SetChannelLoopPoints, PATCH_JUMP);
- InjectHook(0x567AA0, &cSampleManager::SetChannelLoopCount, PATCH_JUMP);
- InjectHook(0x567B00, &cSampleManager::GetChannelUsedFlag, PATCH_JUMP);
- InjectHook(0x567B80, &cSampleManager::StartChannel, PATCH_JUMP);
- InjectHook(0x567BE0, &cSampleManager::StopChannel, PATCH_JUMP);
- InjectHook(0x567C50, &cSampleManager::PreloadStreamedFile, PATCH_JUMP);
- InjectHook(0x567D30, &cSampleManager::PauseStream, PATCH_JUMP);
- InjectHook(0x567D60, &cSampleManager::StartPreloadedStreamedFile, PATCH_JUMP);
- InjectHook(0x567D80, &cSampleManager::StartStreamedFile, PATCH_JUMP);
- InjectHook(0x5680E0, &cSampleManager::StopStreamedFile, PATCH_JUMP);
- InjectHook(0x568130, &cSampleManager::GetStreamedFilePosition, PATCH_JUMP);
- InjectHook(0x5681D0, &cSampleManager::SetStreamedVolumeAndPan, PATCH_JUMP);
- InjectHook(0x568270, &cSampleManager::GetStreamedFileLength, PATCH_JUMP);
- InjectHook(0x568290, &cSampleManager::IsStreamPlaying, PATCH_JUMP);
- InjectHook(0x5682D0, &cSampleManager::InitialiseSampleBanks, PATCH_JUMP);
- //InjectHook(0x5683F0, `global constructor keyed to'sampman.cpp, PATCH_JUMP);
-ENDPATCHES
+#include "openal\samp_oal.cpp"
+#endif \ No newline at end of file
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index 4b546911..f454d236 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -1,339 +1,7 @@
#pragma once
#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-
-struct tSample {
- int32 nOffset;
- uint32 nSize;
- int32 nFrequency;
- int32 nLoopStart;
- int32 nLoopEnd;
-};
-
-enum
-{
- SAMPLEBANK_MAIN,
- SAMPLEBANK_PED,
- MAX_SAMPLEBANKS,
- SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX 7
-#define PED_BLOCKSIZE 79000
-
-#define MAXPROVIDERS 64
-
-#define MAXCHANNELS 28
-#define MAXCHANNELS_SURROUND 24
-#define MAX2DCHANNELS 1
-#define CHANNEL2D MAXCHANNELS
-
-#define MAX_MP3STREAMS 2
-
-#define DIGITALRATE 32000
-#define DIGITALBITS 16
-#define DIGITALCHANNELS 2
-
-#define MAX_DIGITAL_MIXER_CHANNELS 32
-
-class cSampleManager
-{
- uint8 m_nEffectsVolume;
- uint8 m_nMusicVolume;
- uint8 m_nEffectsFadeVolume;
- uint8 m_nMusicFadeVolume;
- uint8 m_nMonoMode;
- char _pad0[1];
- char m_szCDRomRootPath[80];
- bool m_bInitialised;
- uint8 m_nNumberOfProviders;
- char *m_aAudioProviders[MAXPROVIDERS];
- tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-
-
-
- cSampleManager(void) :
- m_nNumberOfProviders(0)
- { }
-
- ~cSampleManager(void)
- { }
-
- void SetSpeakerConfig(int32 nConfig);
- uint32 GetMaximumSupportedChannels(void);
-
- uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
- void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
-
- char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
- void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
-
- int8 GetCurrent3DProviderIndex(void);
- int8 SetCurrent3DProvider(uint8 which);
-
- bool IsMP3RadioChannelAvailable(void);
-
- void ReleaseDigitalHandle (void);
- void ReacquireDigitalHandle(void);
-
- bool Initialise(void);
- void Terminate (void);
-
- bool CheckForAnAudioFileOnCD(void);
- char GetCDAudioDriveLetter (void);
-
- void UpdateEffectsVolume(void);
-
- void SetEffectsMasterVolume(uint8 nVolume);
- void SetMusicMasterVolume (uint8 nVolume);
- void SetEffectsFadeVolume (uint8 nVolume);
- void SetMusicFadeVolume (uint8 nVolume);
-
- bool LoadSampleBank (uint8 nBank);
- void UnloadSampleBank (uint8 nBank);
- bool IsSampleBankLoaded(uint8 nBank);
-
- bool IsPedCommentLoaded(uint32 nComment);
- bool LoadPedComment (uint32 nComment);
-
- int32 _GetPedCommentSlot(uint32 nComment);
-
- int32 GetSampleBaseFrequency (uint32 nSample);
- int32 GetSampleLoopStartOffset(uint32 nSample);
- int32 GetSampleLoopEndOffset (uint32 nSample);
- uint32 GetSampleLength (uint32 nSample);
-
- bool UpdateReverb(void);
-
- void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
- bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
- void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
- void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
- void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
- void SetChannelVolume (uint32 nChannel, uint32 nVolume);
- void SetChannelPan (uint32 nChannel, uint32 nPan);
- void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
- void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
- void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
- bool GetChannelUsedFlag (uint32 nChannel);
- void StartChannel (uint32 nChannel);
- void StopChannel (uint32 nChannel);
-
- void PreloadStreamedFile (uint8 nFile, uint8 nStream);
- void PauseStream (uint8 nPauseFlag, uint8 nStream);
- void StartPreloadedStreamedFile (uint8 nStream);
- bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
- void StopStreamedFile (uint8 nStream);
- int32 GetStreamedFilePosition (uint8 nStream);
- void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
- int32 GetStreamedFileLength (uint8 nStream);
- bool IsStreamPlaying (uint8 nStream);
- bool InitialiseSampleBanks(void);
-};
-
-extern cSampleManager &SampleManager;
-extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
- "AUDIO\\HEAD.WAV",
- "AUDIO\\CLASS.WAV",
- "AUDIO\\KJAH.WAV",
- "AUDIO\\RISE.WAV",
- "AUDIO\\LIPS.WAV",
- "AUDIO\\GAME.WAV",
- "AUDIO\\MSX.WAV",
- "AUDIO\\FLASH.WAV",
- "AUDIO\\CHAT.WAV",
- "AUDIO\\HEAD.WAV",
- "AUDIO\\POLICE.WAV",
- "AUDIO\\CITY.WAV",
- "AUDIO\\WATER.WAV",
- "AUDIO\\COMOPEN.WAV",
- "AUDIO\\SUBOPEN.WAV",
- "AUDIO\\JB.MP3",
- "AUDIO\\BET.MP3",
- "AUDIO\\L1_LG.MP3",
- "AUDIO\\L2_DSB.MP3",
- "AUDIO\\L3_DM.MP3",
- "AUDIO\\L4_PAP.MP3",
- "AUDIO\\L5_TFB.MP3",
- "AUDIO\\J0_DM2.MP3",
- "AUDIO\\J1_LFL.MP3",
- "AUDIO\\J2_KCL.MP3",
- "AUDIO\\J3_VH.MP3",
- "AUDIO\\J4_ETH.MP3",
- "AUDIO\\J5_DST.MP3",
- "AUDIO\\J6_TBJ.MP3",
- "AUDIO\\T1_TOL.MP3",
- "AUDIO\\T2_TPU.MP3",
- "AUDIO\\T3_MAS.MP3",
- "AUDIO\\T4_TAT.MP3",
- "AUDIO\\T5_BF.MP3",
- "AUDIO\\S0_MAS.MP3",
- "AUDIO\\S1_PF.MP3",
- "AUDIO\\S2_CTG.MP3",
- "AUDIO\\S3_RTC.MP3",
- "AUDIO\\S5_LRQ.MP3",
- "AUDIO\\S4_BDBA.MP3",
- "AUDIO\\S4_BDBB.MP3",
- "AUDIO\\S2_CTG2.MP3",
- "AUDIO\\S4_BDBD.MP3",
- "AUDIO\\S5_LRQB.MP3",
- "AUDIO\\S5_LRQC.MP3",
- "AUDIO\\A1_SSO.WAV",
- "AUDIO\\A2_PP.WAV",
- "AUDIO\\A3_SS.WAV",
- "AUDIO\\A4_PDR.WAV",
- "AUDIO\\A5_K2FT.WAV",
- "AUDIO\\K1_KBO.MP3",
- "AUDIO\\K2_GIS.MP3",
- "AUDIO\\K3_DS.MP3",
- "AUDIO\\K4_SHI.MP3",
- "AUDIO\\K5_SD.MP3",
- "AUDIO\\R0_PDR2.MP3",
- "AUDIO\\R1_SW.MP3",
- "AUDIO\\R2_AP.MP3",
- "AUDIO\\R3_ED.MP3",
- "AUDIO\\R4_GF.MP3",
- "AUDIO\\R5_PB.MP3",
- "AUDIO\\R6_MM.MP3",
- "AUDIO\\D1_STOG.MP3",
- "AUDIO\\D2_KK.MP3",
- "AUDIO\\D3_ADO.MP3",
- "AUDIO\\D5_ES.MP3",
- "AUDIO\\D7_MLD.MP3",
- "AUDIO\\D4_GTA.MP3",
- "AUDIO\\D4_GTA2.MP3",
- "AUDIO\\D6_STS.MP3",
- "AUDIO\\A6_BAIT.WAV",
- "AUDIO\\A7_ETG.WAV",
- "AUDIO\\A8_PS.WAV",
- "AUDIO\\A9_ASD.WAV",
- "AUDIO\\K4_SHI2.MP3",
- "AUDIO\\C1_TEX.MP3",
- "AUDIO\\EL_PH1.MP3",
- "AUDIO\\EL_PH2.MP3",
- "AUDIO\\EL_PH3.MP3",
- "AUDIO\\EL_PH4.MP3",
- "AUDIO\\YD_PH1.MP3",
- "AUDIO\\YD_PH2.MP3",
- "AUDIO\\YD_PH3.MP3",
- "AUDIO\\YD_PH4.MP3",
- "AUDIO\\HD_PH1.MP3",
- "AUDIO\\HD_PH2.MP3",
- "AUDIO\\HD_PH3.MP3",
- "AUDIO\\HD_PH4.MP3",
- "AUDIO\\HD_PH5.MP3",
- "AUDIO\\MT_PH1.MP3",
- "AUDIO\\MT_PH2.MP3",
- "AUDIO\\MT_PH3.MP3",
- "AUDIO\\MT_PH4.MP3",
- "AUDIO\\MISCOM.WAV",
- "AUDIO\\END.MP3",
- "AUDIO\\lib_a1.WAV",
- "AUDIO\\lib_a2.WAV",
- "AUDIO\\lib_a.WAV",
- "AUDIO\\lib_b.WAV",
- "AUDIO\\lib_c.WAV",
- "AUDIO\\lib_d.WAV",
- "AUDIO\\l2_a.WAV",
- "AUDIO\\j4t_1.WAV",
- "AUDIO\\j4t_2.WAV",
- "AUDIO\\j4t_3.WAV",
- "AUDIO\\j4t_4.WAV",
- "AUDIO\\j4_a.WAV",
- "AUDIO\\j4_b.WAV",
- "AUDIO\\j4_c.WAV",
- "AUDIO\\j4_d.WAV",
- "AUDIO\\j4_e.WAV",
- "AUDIO\\j4_f.WAV",
- "AUDIO\\j6_1.WAV",
- "AUDIO\\j6_a.WAV",
- "AUDIO\\j6_b.WAV",
- "AUDIO\\j6_c.WAV",
- "AUDIO\\j6_d.WAV",
- "AUDIO\\t4_a.WAV",
- "AUDIO\\s1_a.WAV",
- "AUDIO\\s1_a1.WAV",
- "AUDIO\\s1_b.WAV",
- "AUDIO\\s1_c.WAV",
- "AUDIO\\s1_c1.WAV",
- "AUDIO\\s1_d.WAV",
- "AUDIO\\s1_e.WAV",
- "AUDIO\\s1_f.WAV",
- "AUDIO\\s1_g.WAV",
- "AUDIO\\s1_h.WAV",
- "AUDIO\\s1_i.WAV",
- "AUDIO\\s1_j.WAV",
- "AUDIO\\s1_k.WAV",
- "AUDIO\\s1_l.WAV",
- "AUDIO\\s3_a.WAV",
- "AUDIO\\s3_b.WAV",
- "AUDIO\\el3_a.WAV",
- "AUDIO\\mf1_a.WAV",
- "AUDIO\\mf2_a.WAV",
- "AUDIO\\mf3_a.WAV",
- "AUDIO\\mf3_b.WAV",
- "AUDIO\\mf3_b1.WAV",
- "AUDIO\\mf3_c.WAV",
- "AUDIO\\mf4_a.WAV",
- "AUDIO\\mf4_b.WAV",
- "AUDIO\\mf4_c.WAV",
- "AUDIO\\a1_a.WAV",
- "AUDIO\\a3_a.WAV",
- "AUDIO\\a5_a.WAV",
- "AUDIO\\a4_a.WAV",
- "AUDIO\\a4_b.WAV",
- "AUDIO\\a4_c.WAV",
- "AUDIO\\a4_d.WAV",
- "AUDIO\\k1_a.WAV",
- "AUDIO\\k3_a.WAV",
- "AUDIO\\r1_a.WAV",
- "AUDIO\\r2_a.WAV",
- "AUDIO\\r2_b.WAV",
- "AUDIO\\r2_c.WAV",
- "AUDIO\\r2_d.WAV",
- "AUDIO\\r2_e.WAV",
- "AUDIO\\r2_f.WAV",
- "AUDIO\\r2_g.WAV",
- "AUDIO\\r2_h.WAV",
- "AUDIO\\r5_a.WAV",
- "AUDIO\\r6_a.WAV",
- "AUDIO\\r6_a1.WAV",
- "AUDIO\\r6_b.WAV",
- "AUDIO\\lo2_a.WAV",
- "AUDIO\\lo6_a.WAV",
- "AUDIO\\yd2_a.WAV",
- "AUDIO\\yd2_b.WAV",
- "AUDIO\\yd2_c.WAV",
- "AUDIO\\yd2_c1.WAV",
- "AUDIO\\yd2_d.WAV",
- "AUDIO\\yd2_e.WAV",
- "AUDIO\\yd2_f.WAV",
- "AUDIO\\yd2_g.WAV",
- "AUDIO\\yd2_h.WAV",
- "AUDIO\\yd2_ass.WAV",
- "AUDIO\\yd2_ok.WAV",
- "AUDIO\\h5_a.WAV",
- "AUDIO\\h5_b.WAV",
- "AUDIO\\h5_c.WAV",
- "AUDIO\\ammu_a.WAV",
- "AUDIO\\ammu_b.WAV",
- "AUDIO\\ammu_c.WAV",
- "AUDIO\\door_1.WAV",
- "AUDIO\\door_2.WAV",
- "AUDIO\\door_3.WAV",
- "AUDIO\\door_4.WAV",
- "AUDIO\\door_5.WAV",
- "AUDIO\\door_6.WAV",
- "AUDIO\\t3_a.WAV",
- "AUDIO\\t3_b.WAV",
- "AUDIO\\t3_c.WAV",
- "AUDIO\\k1_b.WAV",
- "AUDIO\\cat1.WAV"
-};
+#ifndef OPENAL
+#include "miles\sampman_mss.h"
+#else
+#include "openal\samp_oal.h"
+#endif \ No newline at end of file
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index b5bca21d..69511bc8 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AutoPilot.h"
#include "CarCtrl.h"
@@ -8,7 +8,7 @@
void CAutoPilot::ModifySpeed(float speed)
{
- m_fMaxTrafficSpeed = max(0.01f, speed);
+ m_fMaxTrafficSpeed = Max(0.01f, speed);
float positionBetweenNodes = (float)(CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve) / m_nTimeToSpendOnCurrentCurve;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[m_nNextPathNodeInfo];
@@ -35,7 +35,7 @@ void CAutoPilot::ModifySpeed(float speed)
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
(uint32)(positionBetweenNodes * m_nTimeToSpendOnCurrentCurve);
#else
- m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nSpeedScaleFactor;
+ m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nTimeToSpendOnCurrentCurve;
#endif
}
diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp
index 6a577449..8514ef9e 100644
--- a/src/control/Bridge.cpp
+++ b/src/control/Bridge.cpp
@@ -1,25 +1,25 @@
#include "common.h"
-#include "patcher.h"
+
#include "Bridge.h"
#include "Pools.h"
#include "ModelIndices.h"
#include "PathFind.h"
#include "Stats.h"
-CEntity*& CBridge::pLiftRoad = *(CEntity**)0x8E2C8C;
-CEntity*& CBridge::pLiftPart = *(CEntity**)0x8E2C94;
-CEntity*& CBridge::pWeight = *(CEntity**)0x8E28BC;
+CEntity *CBridge::pLiftRoad;
+CEntity *CBridge::pLiftPart;
+CEntity *CBridge::pWeight;
-int& CBridge::State = *(int*)0x8F2A1C;
-int& CBridge::OldState = *(int*)0x8F2A20;
+int CBridge::State;
+int CBridge::OldState;
-float& CBridge::DefaultZLiftPart = *(float*)0x941430;
-float& CBridge::DefaultZLiftRoad = *(float*)0x941438;
-float& CBridge::DefaultZLiftWeight = *(float*)0x8F1A44;
+float CBridge::DefaultZLiftPart;
+float CBridge::DefaultZLiftRoad;
+float CBridge::DefaultZLiftWeight;
-float& CBridge::OldLift = *(float*)0x8F6254;
+float CBridge::OldLift;
-uint32& CBridge::TimeOfBridgeBecomingOperational = *(uint32*)0x8F2BC0;
+uint32 CBridge::TimeOfBridgeBecomingOperational;
void CBridge::Init()
{
@@ -144,11 +144,3 @@ bool CBridge::ThisIsABridgeObjectMovingUp(int index)
return State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP || State == STATE_LIFT_PART_MOVING_UP;
}
-
-STARTPATCHES
- InjectHook(0x413A30, &CBridge::Init, PATCH_JUMP);
- InjectHook(0x413AC0, &CBridge::Update, PATCH_JUMP);
- InjectHook(0x413D10, &CBridge::ShouldLightsBeFlashing, PATCH_JUMP);
- InjectHook(0x413D20, &CBridge::FindBridgeEntities, PATCH_JUMP);
- InjectHook(0x413DE0, &CBridge::ThisIsABridgeObjectMovingUp, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/control/Bridge.h b/src/control/Bridge.h
index 63f41578..c5702629 100644
--- a/src/control/Bridge.h
+++ b/src/control/Bridge.h
@@ -14,11 +14,11 @@ enum bridgeStates {
class CBridge
{
public:
- static CEntity *&pLiftRoad, *&pLiftPart, *&pWeight;
- static int &State, &OldState;
- static float &DefaultZLiftPart, &DefaultZLiftRoad, &DefaultZLiftWeight;
- static float &OldLift;
- static uint32 &TimeOfBridgeBecomingOperational;
+ static CEntity *pLiftRoad, *pLiftPart, *pWeight;
+ static int State, OldState;
+ static float DefaultZLiftPart, DefaultZLiftRoad, DefaultZLiftWeight;
+ static float OldLift;
+ static uint32 TimeOfBridgeBecomingOperational;
static void Init();
static void Update();
diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp
index e47e3d5e..a8e77fc2 100644
--- a/src/control/CarAI.cpp
+++ b/src/control/CarAI.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "CarAI.h"
#include "Accident.h"
@@ -33,7 +33,6 @@ float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle)
void CCarAI::UpdateCarAI(CVehicle* pVehicle)
{
- //((void(*)(CVehicle*))(0x413E50))(pVehicle);
//return;
if (pVehicle->bIsLawEnforcer){
if (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_FARAWAY ||
@@ -375,7 +374,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 750;
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
if (pVehicle->VehicleCreatedBy == RANDOM_VEHICLE)
- pVehicle->AutoPilot.m_nDrivingStyle = max(DRIVINGSTYLE_AVOID_CARS, pVehicle->AutoPilot.m_nDrivingStyle);
+ pVehicle->AutoPilot.m_nDrivingStyle = Max(DRIVINGSTYLE_AVOID_CARS, pVehicle->AutoPilot.m_nDrivingStyle);
pVehicle->PlayCarHorn();
}
}
@@ -511,7 +510,7 @@ void CCarAI::TellCarToRamOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_FARAWAY;
pVehicle->bEngineOn = true;
- pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
+ pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
}
void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
@@ -520,7 +519,7 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_FARAWAY;
pVehicle->bEngineOn = true;
- pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
+ pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
}
eCarMission CCarAI::FindPoliceCarMissionForWantedLevel()
{
@@ -637,6 +636,3 @@ void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
}
}
}
-
-STARTPATCHES
-ENDPATCHES
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index 264f1f3f..ae38b68f 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "CarCtrl.h"
#include "Accident.h"
@@ -67,25 +67,25 @@
#define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f
#define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f
-int &CCarCtrl::NumLawEnforcerCars = *(int*)0x8F1B38;
-int &CCarCtrl::NumAmbulancesOnDuty = *(int*)0x885BB0;
-int &CCarCtrl::NumFiretrucksOnDuty = *(int*)0x9411F0;
-bool &CCarCtrl::bCarsGeneratedAroundCamera = *(bool*)0x95CD8A;
-float& CCarCtrl::CarDensityMultiplier = *(float*)0x5EC8B4;
-int32 &CCarCtrl::NumMissionCars = *(int32*)0x8F1B54;
-int32 &CCarCtrl::NumRandomCars = *(int32*)0x943118;
-int32 &CCarCtrl::NumParkedCars = *(int32*)0x8F29E0;
-int32 &CCarCtrl::NumPermanentCars = *(int32*)0x8F29F0;
-int8 &CCarCtrl::CountDownToCarsAtStart = *(int8*)0x95CD63;
-int32 &CCarCtrl::MaxNumberOfCarsInUse = *(int32*)0x5EC8B8;
-uint32 &CCarCtrl::LastTimeLawEnforcerCreated = *(uint32*)0x8F5FF0;
-uint32 &CCarCtrl::LastTimeFireTruckCreated = *(uint32*)0x880F5C;
-uint32 &CCarCtrl::LastTimeAmbulanceCreated = *(uint32*)0x941450;
-int32 (&CCarCtrl::TotalNumOfCarsOfRating)[TOTAL_CUSTOM_CLASSES] = *(int32(*)[TOTAL_CUSTOM_CLASSES])*(uintptr*)0x8F1A60;
-int32 (&CCarCtrl::NextCarOfRating)[TOTAL_CUSTOM_CLASSES] = *(int32(*)[TOTAL_CUSTOM_CLASSES])*(uintptr*)0x9412AC;
-int32 (&CCarCtrl::CarArrays)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY] = *(int32(*)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY])*(uintptr*)0x6EB860;
-CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP] = *(CVehicle*(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x70D830;
-uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x87F9A8;
+int CCarCtrl::NumLawEnforcerCars;
+int CCarCtrl::NumAmbulancesOnDuty;
+int CCarCtrl::NumFiretrucksOnDuty;
+bool CCarCtrl::bCarsGeneratedAroundCamera;
+float CCarCtrl::CarDensityMultiplier = 1.0f;
+int32 CCarCtrl::NumMissionCars;
+int32 CCarCtrl::NumRandomCars;
+int32 CCarCtrl::NumParkedCars;
+int32 CCarCtrl::NumPermanentCars;
+int8 CCarCtrl::CountDownToCarsAtStart;
+int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
+uint32 CCarCtrl::LastTimeLawEnforcerCreated;
+uint32 CCarCtrl::LastTimeFireTruckCreated;
+uint32 CCarCtrl::LastTimeAmbulanceCreated;
+int32 CCarCtrl::TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
+int32 CCarCtrl::NextCarOfRating[TOTAL_CUSTOM_CLASSES];
+int32 CCarCtrl::CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP];
+uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP];
void
CCarCtrl::GenerateRandomCars()
@@ -362,7 +362,7 @@ CCarCtrl::GenerateOneRandomCar()
if (distanceBetweenNodes / 2 < carLength)
positionBetweenNodes = 0.5f;
else
- positionBetweenNodes = min(1.0f - carLength / distanceBetweenNodes, max(carLength / distanceBetweenNodes, positionBetweenNodes));
+ positionBetweenNodes = Min(1.0f - carLength / distanceBetweenNodes, Max(carLength / distanceBetweenNodes, positionBetweenNodes));
pCar->AutoPilot.m_nNextDirection = (curNodeId >= nextNodeId) ? 1 : -1;
if (pCurNode->numLinks == 1){
/* Do not create vehicle if there is nowhere to go. */
@@ -426,7 +426,7 @@ CCarCtrl::GenerateOneRandomCar()
(uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve);
#else
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
- (0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nSpeedScaleFactor;
+ (0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve;
#endif
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
CVector directionNextLink(directionNextLinkX, directionNextLinkY, 0.0f);
@@ -804,10 +804,10 @@ CCarCtrl::FindMaximumSpeedForThisCarInTraffic(CVehicle* pVehicle)
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
- int xstart = max(0, CWorld::GetSectorIndexX(left));
- int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
- int ystart = max(0, CWorld::GetSectorIndexY(top));
- int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
+ int xstart = Max(0, CWorld::GetSectorIndexX(left));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
+ int ystart = Max(0, CWorld::GetSectorIndexY(top));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -838,10 +838,10 @@ CCarCtrl::ScanForPedDanger(CVehicle* pVehicle)
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
- int xstart = max(0, CWorld::GetSectorIndexX(left));
- int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
- int ystart = max(0, CWorld::GetSectorIndexY(top));
- int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
+ int xstart = Max(0, CWorld::GetSectorIndexX(left));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
+ int ystart = Max(0, CWorld::GetSectorIndexY(top));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -873,12 +873,12 @@ CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
float curSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed;
if (maxSpeed >= curSpeed){
if (maxSpeed > curSpeed)
- pVehicle->AutoPilot.ModifySpeed(min(maxSpeed, curSpeed + 0.05f * CTimer::GetTimeStep()));
+ pVehicle->AutoPilot.ModifySpeed(Min(maxSpeed, curSpeed + 0.05f * CTimer::GetTimeStep()));
}else if (curSpeed != 0.0f) {
if (curSpeed < 0.1f)
pVehicle->AutoPilot.ModifySpeed(0.0f);
else
- pVehicle->AutoPilot.ModifySpeed(max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
+ pVehicle->AutoPilot.ModifySpeed(Max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
}
}
@@ -979,7 +979,7 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
if (distanceUntilHit < 10.0f){
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS ||
pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_SLOW_DOWN_FOR_CARS){
- *pSpeed = min(*pSpeed, ABS(distanceUntilHit - 1.0f) * 0.1f * curSpeed);
+ *pSpeed = Min(*pSpeed, ABS(distanceUntilHit - 1.0f) * 0.1f * curSpeed);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds = true;
if (distanceUntilHit < 2.0f){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
@@ -1028,11 +1028,11 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
float projectionY = speedOtherY - forwardA.y * curSpeed;
float proximityA = TestCollisionBetween2MovingRects(pOtherVehicle, pVehicle, projectionX, projectionY, &forwardA, &forwardB, 0);
float proximityB = TestCollisionBetween2MovingRects(pVehicle, pOtherVehicle, -projectionX, -projectionY, &forwardB, &forwardA, 1);
- float minProximity = min(proximityA, proximityB);
+ float minProximity = Min(proximityA, proximityB);
if (minProximity >= 0.0f && minProximity < 1.0f){
- minProximity = max(0.0f, (minProximity - 0.2f) * 1.25f);
+ minProximity = Max(0.0f, (minProximity - 0.2f) * 1.25f);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfCars = true;
- *pSpeed = min(*pSpeed, minProximity * curSpeed);
+ *pSpeed = Min(*pSpeed, minProximity * curSpeed);
}
if (minProximity >= 0.0f && minProximity < 0.5f && pOtherEntity->IsVehicle() &&
CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 15000 &&
@@ -1041,7 +1041,7 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
if (pOtherEntity != FindPlayerVehicle() &&
DotProduct2D(pVehicle->GetForward(), pOtherVehicle->GetForward()) < 0.5f &&
pVehicle < pOtherVehicle){ /* that comparasion though... */
- *pSpeed = max(curSpeed / 5, *pSpeed);
+ *pSpeed = Max(curSpeed / 5, *pSpeed);
if (pVehicle->m_status == STATUS_SIMPLE){
pVehicle->m_status = STATUS_PHYSICS;
SwitchVehicleToRealPhysics(pVehicle);
@@ -1097,7 +1097,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityWidth = -(widthDistance - widthB) / widthProjection;
if (proximityWidth < 1.0f){
baseWidthProximity = proximityWidth;
- fullWidthProximity = min(1.0f, proximityWidth - fullWidthB / widthProjection);
+ fullWidthProximity = Min(1.0f, proximityWidth - fullWidthB / widthProjection);
}else{
baseWidthProximity = 1.0f;
}
@@ -1110,7 +1110,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityWidth = -(widthDistance + widthB) / widthProjection;
if (proximityWidth < 1.0f) {
baseWidthProximity = proximityWidth;
- fullWidthProximity = min(1.0f, proximityWidth + fullWidthB / widthProjection);
+ fullWidthProximity = Min(1.0f, proximityWidth + fullWidthB / widthProjection);
}
else {
baseWidthProximity = 1.0f;
@@ -1135,7 +1135,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityLength = -(lenDistance - lenB) / lenProjection;
if (proximityLength < 1.0f) {
baseLengthProximity = proximityLength;
- fullLengthProximity = min(1.0f, proximityLength - fullLenB / lenProjection);
+ fullLengthProximity = Min(1.0f, proximityLength - fullLenB / lenProjection);
}
else {
baseLengthProximity = 1.0f;
@@ -1151,7 +1151,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float proximityLength = -(lenDistance + backLenB) / lenProjection;
if (proximityLength < 1.0f) {
baseLengthProximity = proximityLength;
- fullLengthProximity = min(1.0f, proximityLength + fullLenB / lenProjection);
+ fullLengthProximity = Min(1.0f, proximityLength + fullLenB / lenProjection);
}
else {
baseLengthProximity = 1.0f;
@@ -1168,24 +1168,24 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
else if (lenProjection < 0.0f) {
fullLengthProximity = -(backLenB + lenDistance) / lenProjection;
}
- float baseProximity = max(baseWidthProximity, baseLengthProximity);
+ float baseProximity = Max(baseWidthProximity, baseLengthProximity);
if (baseProximity < fullWidthProximity && baseProximity < fullLengthProximity)
- proximity = min(proximity, baseProximity);
+ proximity = Min(proximity, baseProximity);
}
return proximity;
}
float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward)
{
- float distanceToTest = min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() * 2.5f + 1.0f) * 12.0f;
+ float distanceToTest = Min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() * 2.5f + 1.0f) * 12.0f;
float left = pVehicle->GetPosition().x - distanceToTest;
float right = pVehicle->GetPosition().x + distanceToTest;
float top = pVehicle->GetPosition().y - distanceToTest;
float bottom = pVehicle->GetPosition().y + distanceToTest;
- int xstart = max(0, CWorld::GetSectorIndexX(left));
- int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
- int ystart = max(0, CWorld::GetSectorIndexY(top));
- int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
+ int xstart = Max(0, CWorld::GetSectorIndexX(left));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
+ int ystart = Max(0, CWorld::GetSectorIndexY(top));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -1566,8 +1566,8 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nNextLane -= 1;
}
}
- pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
- pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
}else{
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
}
@@ -1595,7 +1595,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve < 10)
/* Oh hey there Obbe */
printf("fout\n");
- pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
+ pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
}
uint8 CCarCtrl::FindPathDirection(int32 prevNode, int32 curNode, int32 nextNode)
@@ -1746,8 +1746,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
pVehicle->AutoPilot.m_nNextLane -= 1;
}
}
- pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
- pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
}
else {
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
@@ -1773,7 +1773,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
directionCurrentLinkX, directionCurrentLinkY,
directionNextLinkX, directionNextLinkY
) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed);
- pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
+ pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
}
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
@@ -1826,8 +1826,8 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
else
pVehicle->AutoPilot.m_nNextLane -= 1;
}
- pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
- pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
+ pVehicle->AutoPilot.m_nNextLane = Max(0, pVehicle->AutoPilot.m_nNextLane);
}
else {
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
@@ -1853,7 +1853,7 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
directionCurrentLinkX, directionCurrentLinkY,
directionNextLinkX, directionNextLinkY
) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed);
- pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
+ pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = Max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
return false;
}
@@ -1965,7 +1965,7 @@ float CCarCtrl::FindSpeedMultiplier(float angleChange, float minAngle, float max
{
float angle = Abs(LimitRadianAngle(angleChange));
float n = angle - minAngle;
- n = max(0.0f, n);
+ n = Max(0.0f, n);
float d = maxAngle - minAngle;
float mult = 1.0f - n / d * (1.0f - coef);
if (n > d)
@@ -2252,9 +2252,9 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
angleCurrentLink = FindAngleToWeaveThroughTraffic(pVehicle, nil, angleCurrentLink, angleForward);
float steerAngle = LimitRadianAngle(angleCurrentLink - angleForward);
float maxAngle = FindMaxSteerAngle(pVehicle);
- steerAngle = min(maxAngle, max(-maxAngle, steerAngle));
+ steerAngle = Min(maxAngle, Max(-maxAngle, steerAngle));
if (pVehicle->GetMoveSpeed().Magnitude() > MIN_SPEED_TO_START_LIMITING_STEER)
- steerAngle = min(MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, max(-MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, steerAngle));
+ steerAngle = Min(MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, Max(-MAX_ANGLE_TO_STEER_AT_HIGH_SPEED, steerAngle));
float currentForwardSpeed = DotProduct(pVehicle->GetMoveSpeed(), pVehicle->GetForward()) * GAME_SPEED_TO_CARAI_SPEED;
float speedStyleMultiplier;
switch (pVehicle->AutoPilot.m_nDrivingStyle) {
@@ -2298,21 +2298,21 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
speedNodesMultiplier = 1.0f -
(1.0f - scalarDistanceToNextNode / DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN) *
(1.0f - tmpWideMultiplier);
- float speedMultiplier = min(speedStyleMultiplier, min(speedAngleMultiplier, speedNodesMultiplier));
+ float speedMultiplier = Min(speedStyleMultiplier, Min(speedAngleMultiplier, speedNodesMultiplier));
float speed = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier;
float speedDifference = speed - currentForwardSpeed;
if (speed < 0.05f && speedDifference < 0.03f){
*pBrake = 1.0f;
*pAccel = 0.0f;
}else if (speedDifference <= 0.0f){
- *pBrake = min(0.5f, -speedDifference * 0.05f);
+ *pBrake = Min(0.5f, -speedDifference * 0.05f);
*pAccel = 0.0f;
}else if (currentForwardSpeed < 2.0f){
*pBrake = 0.0f;
- *pAccel = min(1.0f, speedDifference * 0.25f);
+ *pAccel = Min(1.0f, speedDifference * 0.25f);
}else{
*pBrake = 0.0f;
- *pAccel = min(1.0f, speedDifference * 0.125f);
+ *pAccel = Min(1.0f, speedDifference * 0.125f);
}
*pSwerve = steerAngle;
*pHandbrake = false;
@@ -2332,7 +2332,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
if (ABS(steerAngle) > MIN_ANGLE_TO_APPLY_HANDBRAKE)
*pHandbrake = true;
float maxAngle = FindMaxSteerAngle(pVehicle);
- steerAngle = min(maxAngle, max(-maxAngle, steerAngle));
+ steerAngle = Min(maxAngle, Max(-maxAngle, steerAngle));
float speedMultiplier = FindSpeedMultiplier(angleToTarget - angleForward,
MIN_ANGLE_FOR_SPEED_LIMITING, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT);
float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed * speedMultiplier;
@@ -2340,9 +2340,9 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
float speedDiff = speedTarget - currentSpeed;
if (speedDiff <= 0.0f){
*pAccel = 0.0f;
- *pBrake = min(0.5f, -speedDiff * 0.05f);
+ *pBrake = Min(0.5f, -speedDiff * 0.05f);
}else if (currentSpeed < 25.0f){
- *pAccel = min(1.0f, speedDiff * 0.1f);
+ *pAccel = Min(1.0f, speedDiff * 0.1f);
*pBrake = 0.0f;
}else{
*pAccel = 1.0f;
@@ -2414,7 +2414,7 @@ void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CBoat* pBoat, float target
float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y);
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
float angleDiff = LimitRadianAngle(angleToTarget - angleForward);
- angleDiff = min(DEFAULT_MAX_STEER_ANGLE, max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
+ angleDiff = Min(DEFAULT_MAX_STEER_ANGLE, Max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason
float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f;
if (speedDiff > 0.0f){
@@ -2736,20 +2736,3 @@ bool CCarCtrl::MapCouldMoveInThisArea(float x, float y)
return x > -342.0f && x < -219.0f &&
y > -677.0f && y < -580.0f;
}
-
-STARTPATCHES
-InjectHook(0x416580, &CCarCtrl::GenerateRandomCars, PATCH_JUMP);
-InjectHook(0x417EC0, &CCarCtrl::ChooseModel, PATCH_JUMP);
-InjectHook(0x418320, &CCarCtrl::RemoveDistantCars, PATCH_JUMP);
-InjectHook(0x418430, &CCarCtrl::PossiblyRemoveVehicle, PATCH_JUMP);
-InjectHook(0x41D280, &CCarCtrl::Init, PATCH_JUMP);
-InjectHook(0x41D3B0, &CCarCtrl::ReInit, PATCH_JUMP);
-InjectHook(0x41E250, &CCarCtrl::SteerAIBoatWithPhysics, PATCH_JUMP);
-InjectHook(0x41F6E0, &CCarCtrl::RegisterVehicleOfInterest, PATCH_JUMP);
-InjectHook(0x41F780, &CCarCtrl::IsThisVehicleInteresting, PATCH_JUMP);
-InjectHook(0x41F7A0, &CCarCtrl::RemoveFromInterestingVehicleList, PATCH_JUMP);
-InjectHook(0x41F7D0, &CCarCtrl::ClearInterestingVehicleList, PATCH_JUMP);
-InjectHook(0x41F7F0, &CCarCtrl::SwitchVehicleToRealPhysics, PATCH_JUMP);
-InjectHook(0x41F820, &CCarCtrl::JoinCarWithRoadSystem, PATCH_JUMP);
-InjectHook(0x41FA00, &CCarCtrl::JoinCarWithRoadSystemGotoCoors, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h
index 925552b5..44ef9ab6 100644
--- a/src/control/CarCtrl.h
+++ b/src/control/CarCtrl.h
@@ -120,23 +120,23 @@ public:
return angle;
}
- static int32 &NumLawEnforcerCars;
- static int32 &NumAmbulancesOnDuty;
- static int32 &NumFiretrucksOnDuty;
- static int32 &NumRandomCars;
- static int32 &NumMissionCars;
- static int32 &NumParkedCars;
- static int32 &NumPermanentCars;
- static bool &bCarsGeneratedAroundCamera;
- static float &CarDensityMultiplier;
- static int8 &CountDownToCarsAtStart;
- static int32 &MaxNumberOfCarsInUse;
- static uint32 &LastTimeLawEnforcerCreated;
- static uint32 &LastTimeFireTruckCreated;
- static uint32 &LastTimeAmbulanceCreated;
- static int32 (&TotalNumOfCarsOfRating)[TOTAL_CUSTOM_CLASSES];
- static int32 (&NextCarOfRating)[TOTAL_CUSTOM_CLASSES];
- static int32 (&CarArrays)[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+ static int32 NumLawEnforcerCars;
+ static int32 NumAmbulancesOnDuty;
+ static int32 NumFiretrucksOnDuty;
+ static int32 NumRandomCars;
+ static int32 NumMissionCars;
+ static int32 NumParkedCars;
+ static int32 NumPermanentCars;
+ static bool bCarsGeneratedAroundCamera;
+ static float CarDensityMultiplier;
+ static int8 CountDownToCarsAtStart;
+ static int32 MaxNumberOfCarsInUse;
+ static uint32 LastTimeLawEnforcerCreated;
+ static uint32 LastTimeFireTruckCreated;
+ static uint32 LastTimeAmbulanceCreated;
+ static int32 TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
+ static int32 NextCarOfRating[TOTAL_CUSTOM_CLASSES];
+ static int32 CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
};
-extern CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP]; \ No newline at end of file
+extern CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP]; \ No newline at end of file
diff --git a/src/control/Curves.cpp b/src/control/Curves.cpp
index 5c6ef06d..623ab040 100644
--- a/src/control/Curves.cpp
+++ b/src/control/Curves.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Curves.h"
float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index b4d15abf..cfd58340 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Darkel.h"
#include "PlayerPed.h"
@@ -17,29 +17,29 @@
#define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2
-int32 &CDarkel::TimeLimit = *(int32*)0x885BAC;
-int32 &CDarkel::PreviousTime = *(int32*)0x885B00;
-int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8;
-int32 &CDarkel::WeaponType = *(int32*)0x9430F0;
-int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8;
-int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8;
-int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60;
+int32 CDarkel::TimeLimit;
+int32 CDarkel::PreviousTime;
+int32 CDarkel::TimeOfFrenzyStart;
+int32 CDarkel::WeaponType;
+int32 CDarkel::AmmoInterruptedWeapon;
+int32 CDarkel::KillsNeeded;
+int8 CDarkel::InterruptedWeapon;
/*
* bStandardSoundAndMessages is a completely beta thing,
* makes game handle sounds & messages instead of SCM (just like in GTA2)
* but it's never been used in the game. Has unused sliding text when frenzy completed etc.
*/
-int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6;
-int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA;
-int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98;
-uint16 &CDarkel::Status = *(uint16*)0x95CCB4;
-uint16 (&CDarkel::RegisteredKills)[NUM_DEFAULT_MODELS] = *(uint16(*)[NUM_DEFAULT_MODELS]) * (uintptr*)0x6EDBE0;
-int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78;
-int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40;
-int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C;
-int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34;
-wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08;
+int8 CDarkel::bStandardSoundAndMessages;
+int8 CDarkel::bNeedHeadShot;
+int8 CDarkel::bProperKillFrenzy;
+uint16 CDarkel::Status;
+uint16 CDarkel::RegisteredKills[NUM_DEFAULT_MODELS];
+int32 CDarkel::ModelToKill;
+int32 CDarkel::ModelToKill2;
+int32 CDarkel::ModelToKill3;
+int32 CDarkel::ModelToKill4;
+wchar *CDarkel::pStartMessage;
uint8
CDarkel::CalcFade(uint32 time, uint32 start, uint32 end)
@@ -262,10 +262,10 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
pStartMessage = text;
if (text == TheText.Get("PAGE_00")) {
- CDarkel::bProperKillFrenzy = 1;
- CDarkel::pStartMessage = 0;
+ CDarkel::bProperKillFrenzy = true;
+ CDarkel::pStartMessage = nil;
} else
- bProperKillFrenzy = 0;
+ bProperKillFrenzy = false;
bStandardSoundAndMessages = standardSound;
bNeedHeadShot = needHeadShot;
@@ -284,7 +284,7 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
if (FindPlayerVehicle()) {
player->m_currentWeapon = player->m_nSelectedWepSlot;
- player->GetWeapon()->m_nAmmoInClip = min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
+ player->GetWeapon()->m_nAmmoInClip = Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
player->ClearWeaponTarget();
}
}
@@ -371,19 +371,3 @@ CDarkel::Update()
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0);
}
}
-
-STARTPATCHES
- InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP);
- InjectHook(0x420650, CDarkel::Init, PATCH_JUMP);
- InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);
- InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP);
- InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP);
- InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP);
- InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP);
- InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP);
- InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP);
- InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP);
- InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP);
- InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP);
- InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/Darkel.h b/src/control/Darkel.h
index 12ce4451..14529c63 100644
--- a/src/control/Darkel.h
+++ b/src/control/Darkel.h
@@ -1,9 +1,10 @@
#pragma once
+
#include "ModelIndices.h"
+#include "WeaponType.h"
class CVehicle;
class CPed;
-enum eWeaponType;
enum
{
@@ -16,22 +17,22 @@ enum
class CDarkel
{
private:
- static int32 &TimeLimit;
- static int32 &PreviousTime;
- static int32 &TimeOfFrenzyStart;
- static int32 &WeaponType;
- static int32 &AmmoInterruptedWeapon;
- static int32 &KillsNeeded;
- static int8 &InterruptedWeapon;
- static int8 &bStandardSoundAndMessages;
- static int8 &bNeedHeadShot;
- static int8 &bProperKillFrenzy;
- static uint16 &Status;
- static uint16 (&RegisteredKills)[NUM_DEFAULT_MODELS];
- static int32 &ModelToKill;
- static int32 &ModelToKill2;
- static int32 &ModelToKill3;
- static int32 &ModelToKill4;
+ static int32 TimeLimit;
+ static int32 PreviousTime;
+ static int32 TimeOfFrenzyStart;
+ static int32 WeaponType;
+ static int32 AmmoInterruptedWeapon;
+ static int32 KillsNeeded;
+ static int8 InterruptedWeapon;
+ static int8 bStandardSoundAndMessages;
+ static int8 bNeedHeadShot;
+ static int8 bProperKillFrenzy;
+ static uint16 Status;
+ static uint16 RegisteredKills[NUM_DEFAULT_MODELS];
+ static int32 ModelToKill;
+ static int32 ModelToKill2;
+ static int32 ModelToKill3;
+ static int32 ModelToKill4;
static wchar *pStartMessage;
public:
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index 8e0ea02d..f8c8fa69 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "GameLogic.h"
#include "Clock.h"
#include "Stats.h"
@@ -20,7 +20,7 @@
#include "Script.h"
#include "Garages.h"
-uint8 CGameLogic::ActivePlayers; // 0x95CD5E
+uint8 CGameLogic::ActivePlayers;
void
CGameLogic::InitAtStartOfGame()
@@ -93,7 +93,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfHospitalFree) {
pPlayerInfo.m_bGetOutOfHospitalFree = false;
} else {
- pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000);
+ pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 1000);
pPlayerInfo.m_pPed->ClearWeapons();
}
@@ -163,7 +163,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfJailFree) {
pPlayerInfo.m_bGetOutOfJailFree = false;
} else {
- pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney);
+ pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - takeMoney);
pPlayerInfo.m_pPed->ClearWeapons();
}
@@ -284,11 +284,3 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
CWorld::Remove(pPlayerPed);
CWorld::Add(pPlayerPed);
}
-
-STARTPATCHES
- InjectHook(0x4213F0, &CGameLogic::InitAtStartOfGame, PATCH_JUMP);
- InjectHook(0x421C00, &CGameLogic::PassTime, PATCH_JUMP);
- InjectHook(0x421A20, &CGameLogic::SortOutStreamingAndMemory, PATCH_JUMP);
- InjectHook(0x421400, &CGameLogic::Update, PATCH_JUMP);
- InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index e4b2aee3..53527503 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Garages.h"
#include "main.h"
@@ -111,27 +111,27 @@ const int32 gaCarsToCollectInCraigsGarages[TOTAL_COLLECTCARS_GARAGES][TOTAL_COLL
{ MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO }
};
-int32& CGarages::BankVansCollected = *(int32*)0x8F1B34;
-bool& CGarages::BombsAreFree = *(bool*)0x95CD7A;
-bool& CGarages::RespraysAreFree = *(bool*)0x95CD1D;
-int32& CGarages::CarsCollected = *(int32*)0x880E18;
-int32(&CGarages::CarTypesCollected)[TOTAL_COLLECTCARS_GARAGES] = *(int32(*)[TOTAL_COLLECTCARS_GARAGES]) * (uintptr*)0x8E286C;
-int32& CGarages::CrushedCarId = *(int32*)0x943060;
-uint32& CGarages::LastTimeHelpMessage = *(uint32*)0x8F1B58;
-int32& CGarages::MessageNumberInString = *(int32*)0x885BA8;
-char(&CGarages::MessageIDString)[MESSAGE_LENGTH] = *(char(*)[MESSAGE_LENGTH]) * (uintptr*)0x878358;
-int32& CGarages::MessageNumberInString2 = *(int32*)0x8E2C14;
-uint32& CGarages::MessageStartTime = *(uint32*)0x8F2530;
-uint32& CGarages::MessageEndTime = *(uint32*)0x8F597C;
-uint32& CGarages::NumGarages = *(uint32*)0x8F29F4;
-bool& CGarages::PlayerInGarage = *(bool*)0x95CD83;
-int32& CGarages::PoliceCarsCollected = *(int32*)0x941444;
-CStoredCar(&CGarages::aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA210;
-CStoredCar(&CGarages::aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA300;
-CStoredCar(&CGarages::aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA3F0;
-int32& CGarages::AudioEntity = *(int32*)0x5ECEA8;
-CGarage(&CGarages::aGarages)[NUM_GARAGES] = *(CGarage(*)[NUM_GARAGES]) * (uintptr*)0x72BCD0;
-bool& CGarages::bCamShouldBeOutisde = *(bool*)0x95CDB2;
+int32 CGarages::BankVansCollected;
+bool CGarages::BombsAreFree;
+bool CGarages::RespraysAreFree;
+int32 CGarages::CarsCollected;
+int32 CGarages::CarTypesCollected[TOTAL_COLLECTCARS_GARAGES];
+int32 CGarages::CrushedCarId;
+uint32 CGarages::LastTimeHelpMessage;
+int32 CGarages::MessageNumberInString;
+char CGarages::MessageIDString[MESSAGE_LENGTH];
+int32 CGarages::MessageNumberInString2;
+uint32 CGarages::MessageStartTime;
+uint32 CGarages::MessageEndTime;
+uint32 CGarages::NumGarages;
+bool CGarages::PlayerInGarage;
+int32 CGarages::PoliceCarsCollected;
+CStoredCar CGarages::aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
+CStoredCar CGarages::aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
+CStoredCar CGarages::aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
+int32 CGarages::AudioEntity = AEHANDLE_NONE;
+CGarage CGarages::aGarages[NUM_GARAGES];
+bool CGarages::bCamShouldBeOutisde;
void CGarages::Init(void)
{
@@ -206,12 +206,12 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z
return NumGarages++;
}
CGarage* pGarage = &aGarages[NumGarages];
- pGarage->m_fX1 = min(X1, X2);
- pGarage->m_fX2 = max(X1, X2);
- pGarage->m_fY1 = min(Y1, Y2);
- pGarage->m_fY2 = max(Y1, Y2);
- pGarage->m_fZ1 = min(Z1, Z2);
- pGarage->m_fZ2 = max(Z1, Z2);
+ pGarage->m_fX1 = Min(X1, X2);
+ pGarage->m_fX2 = Max(X1, X2);
+ pGarage->m_fY1 = Min(Y1, Y2);
+ pGarage->m_fY2 = Max(Y1, Y2);
+ pGarage->m_fZ1 = Min(Z1, Z2);
+ pGarage->m_fZ2 = Max(Z1, Z2);
pGarage->m_pDoor1 = nil;
pGarage->m_pDoor2 = nil;
pGarage->m_fDoor1Z = Z1;
@@ -307,13 +307,13 @@ void CGarage::Update()
CGarages::bCamShouldBeOutisde = true;
}
if (pVehicle) {
- if (IsEntityEntirelyOutside(pVehicle, 0.0f))
+ if (!IsEntityEntirelyOutside(pVehicle, 0.0f))
TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = this;
if (pVehicle->GetModelIndex() == MI_MRWHOOP) {
if (pVehicle->IsWithinArea(
m_fX1 - DISTANCE_FOR_MRWHOOP_HACK,
- m_fX2 + DISTANCE_FOR_MRWHOOP_HACK,
- m_fY1 - DISTANCE_FOR_MRWHOOP_HACK,
+ m_fY1 + DISTANCE_FOR_MRWHOOP_HACK,
+ m_fX2 - DISTANCE_FOR_MRWHOOP_HACK,
m_fY2 + DISTANCE_FOR_MRWHOOP_HACK)) {
TheCamera.pToGarageWeAreIn = this;
CGarages::bCamShouldBeOutisde = true;
@@ -361,7 +361,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY;
@@ -440,7 +440,7 @@ void CGarage::Update()
}
if (bTakeMoney) {
if (!CGarages::RespraysAreFree)
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - RESPRAY_PRICE);
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - RESPRAY_PRICE);
CGarages::TriggerMessage("GA_2", -1, 4000, -1); // New engine and paint job. The cops won't recognize you!
}
else if (bChangedColour) {
@@ -458,7 +458,7 @@ void CGarage::Update()
m_fY2 + DISTANCE_TO_CALL_OFF_CHASE);
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -503,7 +503,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB;
@@ -520,7 +520,7 @@ void CGarage::Update()
}
m_eGarageState = GS_OPENING;
if (!CGarages::BombsAreFree)
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) {
((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
@@ -562,7 +562,7 @@ void CGarage::Update()
}
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -597,7 +597,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
@@ -626,7 +626,7 @@ void CGarage::Update()
}
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -663,7 +663,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -710,7 +710,7 @@ void CGarage::Update()
m_pTarget = FindPlayerVehicle();
m_pTarget->RegisterReference((CEntity**)&m_pTarget);
}
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -759,7 +759,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -799,7 +799,7 @@ void CGarage::Update()
m_pTarget = FindPlayerVehicle();
m_pTarget->RegisterReference((CEntity**)&m_pTarget);
}
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -820,7 +820,7 @@ void CGarage::Update()
m_eGarageState = GS_CLOSING;
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -831,7 +831,7 @@ void CGarage::Update()
case GS_FULLYCLOSED:
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -865,7 +865,7 @@ void CGarage::Update()
}
case GS_CLOSING:
if (m_pTarget) {
- m_fDoorPos = max(0.0f, m_fDoorPos - CRUSHER_CRANE_SPEED * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - CRUSHER_CRANE_SPEED * CTimer::GetTimeStep());
if (m_fDoorPos < TWOPI / 5) {
m_pTarget->bUsesCollision = false;
m_pTarget->bAffectedByGravity = false;
@@ -876,7 +876,7 @@ void CGarage::Update()
}
if (m_fDoorPos == 0.0f) {
CGarages::CrushedCarId = CPools::GetVehiclePool()->GetIndex(m_pTarget);
- float reward = min(CRUSHER_MAX_REWARD, CRUSHER_MIN_REWARD + m_pTarget->pHandling->nMonetaryValue * m_pTarget->m_fHealth * CRUSHER_REWARD_COEFFICIENT);
+ float reward = Min(CRUSHER_MAX_REWARD, CRUSHER_MIN_REWARD + m_pTarget->pHandling->nMonetaryValue * m_pTarget->m_fHealth * CRUSHER_REWARD_COEFFICIENT);
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += reward;
DestroyVehicleAndDriverAndPassengers(m_pTarget);
++CStats::CarsCrushed;
@@ -900,7 +900,7 @@ void CGarage::Update()
}
break;
case GS_OPENING:
- m_fDoorPos = min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED);
+ m_fDoorPos = Min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED);
if (m_fDoorPos == HALFPI) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -933,7 +933,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
@@ -961,7 +961,7 @@ void CGarage::Update()
m_eGarageState = GS_OPENING;
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -981,7 +981,7 @@ void CGarage::Update()
case GARAGE_FOR_SCRIPT_TO_OPEN:
switch (m_eGarageState) {
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -1001,7 +1001,7 @@ void CGarage::Update()
case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE:
switch (m_eGarageState) {
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -1009,7 +1009,7 @@ void CGarage::Update()
UpdateDoorsHeight();
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -1050,7 +1050,7 @@ void CGarage::Update()
break;
}
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (!IsPlayerOutsideGarage())
m_eGarageState = GS_OPENING;
else if (m_fDoorPos == 0.0f) {
@@ -1082,7 +1082,7 @@ void CGarage::Update()
#ifdef FIX_BUGS
bool bCreatedAllCars = false;
#else
- bool bCraetedAllCars;
+ bool bCreatedAllCars;
#endif
switch (m_eGarageType) {
case GARAGE_HIDEOUT_ONE: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse1); break;
@@ -1096,7 +1096,7 @@ void CGarage::Update()
break;
}
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -1121,7 +1121,7 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
- m_fDoorPos = max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -1137,7 +1137,7 @@ void CGarage::Update()
m_eGarageState = GS_OPENING;
break;
case GS_OPENING:
- m_fDoorPos = min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
@@ -1695,17 +1695,17 @@ float CGarage::CalcSmallestDistToGarageDoorSquared(float X, float Y)
dist1 = SQR(m_fDoor1X - X) + SQR(m_fDoor1Y - Y);
if (m_pDoor2)
dist2 = SQR(m_fDoor2X - X) + SQR(m_fDoor2Y - Y);
- return min(dist1, dist2);
+ return Min(dist1, dist2);
}
void CGarage::FindDoorsEntities()
{
m_pDoor1 = nil;
m_pDoor2 = nil;
- int xstart = max(0, CWorld::GetSectorIndexX(m_fX1));
- int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2));
- int ystart = max(0, CWorld::GetSectorIndexY(m_fY1));
- int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fY2));
+ int xstart = Max(0, CWorld::GetSectorIndexX(m_fX1));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2));
+ int ystart = Max(0, CWorld::GetSectorIndexY(m_fY1));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fY2));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -1891,7 +1891,7 @@ void CGarage::StoreAndRemoveCarsForThisHideout(CStoredCar* aCars, int32 nMax)
pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE) {
- if (index < max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f))
+ if (index < Max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f))
aCars[index++].StoreCar(pVehicle);
CWorld::Players[CWorld::PlayerInFocus].CancelPlayerEnteringCars(pVehicle);
CWorld::Remove(pVehicle);
@@ -2256,7 +2256,7 @@ void CGarages::Save(uint8 * buf, uint32 * size)
#endif
}
-CStoredCar::CStoredCar(const CStoredCar & other)
+const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
{
m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos;
@@ -2272,6 +2272,7 @@ CStoredCar::CStoredCar(const CStoredCar & other)
m_nVariationA = other.m_nVariationA;
m_nVariationB = other.m_nVariationB;
m_nCarBombType = other.m_nCarBombType;
+ return *this;
}
void CGarages::Load(uint8* buf, uint32 size)
@@ -2313,6 +2314,10 @@ void CGarages::Load(uint8* buf, uint32 size)
#ifdef FIX_GARAGE_SIZE
VALIDATESAVEBUF(size);
#endif
+
+ MessageEndTime = 0;
+ bCamShouldBeOutisde = false;
+ MessageStartTime = 0;
}
bool
@@ -2352,10 +2357,3 @@ CGarages::IsModelIndexADoor(uint32 id)
id == MI_CRUSHERBODY ||
id == MI_CRUSHERLID;
}
-
-
-STARTPATCHES
- InjectHook(0x427AB0, CGarages::IsPointInAGarageCameraZone, PATCH_JUMP); // CCamera::CamControl
- InjectHook(0x427BC0, CGarages::CameraShouldBeOutside, PATCH_JUMP); // CCamera::CamControl
- InjectHook(0x428940, CGarages::Load, PATCH_JUMP); // GenericLoad
-ENDPATCHES
diff --git a/src/control/Garages.h b/src/control/Garages.h
index 26e7a89a..65193b32 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -70,7 +70,7 @@ public:
void Init() { m_nModelIndex = 0; }
void Clear() { m_nModelIndex = 0; }
bool HasCar() { return m_nModelIndex != 0; }
- CStoredCar(const CStoredCar& other);
+ const CStoredCar &operator=(const CStoredCar& other);
void StoreCar(CVehicle*);
CVehicle* RestoreCar();
};
@@ -179,27 +179,27 @@ class CGarages
enum {
MESSAGE_LENGTH = 8
};
- static int32 &BankVansCollected;
- static bool &BombsAreFree;
- static bool &RespraysAreFree;
- static int32 &CarsCollected;
- static int32 (&CarTypesCollected)[TOTAL_COLLECTCARS_GARAGES];
- static int32 &CrushedCarId;
- static uint32 &LastTimeHelpMessage;
- static int32 &MessageNumberInString;
- static char(&MessageIDString)[MESSAGE_LENGTH];
- static int32 &MessageNumberInString2;
- static uint32 &MessageStartTime;
- static uint32 &MessageEndTime;
- static uint32 &NumGarages;
- static bool &PlayerInGarage;
- static int32 &PoliceCarsCollected;
- static CGarage(&aGarages)[NUM_GARAGES];
- static CStoredCar(&aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS];
- static CStoredCar(&aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS];
- static CStoredCar(&aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS];
- static int32 &AudioEntity;
- static bool &bCamShouldBeOutisde;
+ static int32 BankVansCollected;
+ static bool BombsAreFree;
+ static bool RespraysAreFree;
+ static int32 CarsCollected;
+ static int32 CarTypesCollected[TOTAL_COLLECTCARS_GARAGES];
+ static int32 CrushedCarId;
+ static uint32 LastTimeHelpMessage;
+ static int32 MessageNumberInString;
+ static char MessageIDString[MESSAGE_LENGTH];
+ static int32 MessageNumberInString2;
+ static uint32 MessageStartTime;
+ static uint32 MessageEndTime;
+ static uint32 NumGarages;
+ static bool PlayerInGarage;
+ static int32 PoliceCarsCollected;
+ static CGarage aGarages[NUM_GARAGES];
+ static CStoredCar aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
+ static CStoredCar aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
+ static CStoredCar aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
+ static int32 AudioEntity;
+ static bool bCamShouldBeOutisde;
public:
static void Init(void);
diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp
index 5406522c..d128efeb 100644
--- a/src/control/OnscreenTimer.cpp
+++ b/src/control/OnscreenTimer.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "DMAudio.h"
#include "Hud.h"
@@ -153,18 +153,3 @@ void COnscreenTimerEntry::ProcessForDisplayCounter() {
uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset);
sprintf(m_bCounterBuffer, "%d", counter);
}
-
-STARTPATCHES
- InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP);
- InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP);
- InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayClock, PATCH_JUMP);
- InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP);
-
- InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP);
- InjectHook(0x429320, &COnscreenTimer::Process, PATCH_JUMP);
- InjectHook(0x4292E0, &COnscreenTimer::ProcessForDisplay, PATCH_JUMP);
- InjectHook(0x429450, &COnscreenTimer::ClearCounter, PATCH_JUMP);
- InjectHook(0x429410, &COnscreenTimer::ClearClock, PATCH_JUMP);
- InjectHook(0x4293B0, &COnscreenTimer::AddCounter, PATCH_JUMP);
- InjectHook(0x429350, &COnscreenTimer::AddClock, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index 61cd3d4e..44062b38 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "FileMgr.h" // only needed for empty function
#include "Camera.h"
@@ -12,21 +12,213 @@ bool gbShowPedPaths;
bool gbShowCarPaths;
bool gbShowCarPathsLinks;
-CPathFind &ThePaths = *(CPathFind*)0x8F6754;
-
-WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
+CPathFind ThePaths;
#define MAX_DIST INT16_MAX-1
+#define MIN_PED_ROUTE_DISTANCE 23.8f
// object flags:
// 1 UseInRoadBlock
// 2 east/west road(?)
-CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
-CPathInfoForObject *&InfoForTilePeds = *(CPathInfoForObject**)0x8F1AE4;
+CPathInfoForObject *InfoForTileCars;
+CPathInfoForObject *InfoForTilePeds;
// unused
-CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824;
-CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0;
+CTempDetachedNode *DetachedNodesCars;
+CTempDetachedNode *DetachedNodesPeds;
+
+bool
+CPedPath::CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints)
+{
+ *pointsFound = 0;
+ CVector vecDistance = destination - position;
+ if (Abs(vecDistance.x) > MIN_PED_ROUTE_DISTANCE || Abs(vecDistance.y) > MIN_PED_ROUTE_DISTANCE || Abs(vecDistance.z) > MIN_PED_ROUTE_DISTANCE)
+ return false;
+ CVector vecPos = (position + destination) * 0.5f;
+ CVector vecSectorStartPos (vecPos.x - 14.0f, vecPos.y - 14.0f, vecPos.z);
+ CVector2D vecSectorEndPos (vecPos.x + 28.0f, vecPos.x + 28.0f);
+ const int16 nodeStartX = (position.x - vecSectorStartPos.x) / 0.7f;
+ const int16 nodeStartY = (position.y - vecSectorStartPos.y) / 0.7f;
+ const int16 nodeEndX = (destination.x - vecSectorStartPos.x) / 0.7f;
+ const int16 nodeEndY = (destination.y - vecSectorStartPos.y) / 0.7f;
+ if (nodeStartX == nodeEndX && nodeStartY == nodeEndY)
+ return false;
+ CPedPathNode pathNodes[40][40];
+ CPedPathNode pathNodesList[416];
+ for (int32 x = 0; x < 40; x++) {
+ for (int32 y = 0; y < 40; y++) {
+ pathNodes[x][y].bBlockade = false;
+ pathNodes[x][y].id = INT16_MAX;
+ pathNodes[x][y].nodeIdX = x;
+ pathNodes[x][y].nodeIdY = y;
+ }
+ }
+ CWorld::AdvanceCurrentScanCode();
+ if (pathType != ROUTE_NO_BLOCKADE) {
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], pathNodes, &vecSectorStartPos);
+ AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], pathNodes, &vecSectorStartPos);
+ AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], pathNodes, &vecSectorStartPos);
+ AddBlockadeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], pathNodes, &vecSectorStartPos);
+ }
+ }
+ }
+ for (int32 i = 0; i < 416; i++) {
+ pathNodesList[i].prev = nil;
+ pathNodesList[i].next = nil;
+ }
+ CPedPathNode *pStartPathNode = &pathNodes[nodeStartX][nodeStartY];
+ CPedPathNode *pEndPathNode = &pathNodes[nodeEndX][nodeEndY];
+ pEndPathNode->bBlockade = false;
+ pEndPathNode->id = 0;
+ pEndPathNode->prev = nil;
+ pEndPathNode->next = pathNodesList;
+ pathNodesList[0].prev = pEndPathNode;
+ int32 pathNodeIndex = 0;
+ CPedPathNode *pPreviousNode = nil;
+ for (; pathNodeIndex < 414; pathNodeIndex++)
+ {
+ pPreviousNode = pathNodesList[pathNodeIndex].prev;
+ while (pPreviousNode && pPreviousNode != pStartPathNode) {
+ const uint8 nodeIdX = pPreviousNode->nodeIdX;
+ const uint8 nodeIdY = pPreviousNode->nodeIdY;
+ if (nodeIdX > 0) {
+ AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY], pathNodeIndex + 5, pathNodesList);
+ if (nodeIdY > 0)
+ AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY - 1], pathNodeIndex + 7, pathNodesList);
+ if (nodeIdY < 39)
+ AddNodeToPathList(&pathNodes[nodeIdX - 1][nodeIdY + 1], pathNodeIndex + 7, pathNodesList);
+ }
+ if (nodeIdX < 39) {
+ AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY], pathNodeIndex + 5, pathNodesList);
+ if (nodeIdY > 0)
+ AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY - 1], pathNodeIndex + 7, pathNodesList);
+ if (nodeIdY < 39)
+ AddNodeToPathList(&pathNodes[nodeIdX + 1][nodeIdY + 1], pathNodeIndex + 7, pathNodesList);
+ }
+ if (nodeIdY > 0)
+ AddNodeToPathList(&pathNodes[nodeIdX][nodeIdY - 1], pathNodeIndex + 5, pathNodesList);
+ if (nodeIdY < 39)
+ AddNodeToPathList(&pathNodes[nodeIdX][nodeIdY + 1], pathNodeIndex + 5, pathNodesList);
+ pPreviousNode = pPreviousNode->prev;
+ if (!pPreviousNode)
+ break;
+ }
+
+ if (pPreviousNode && pPreviousNode == pStartPathNode)
+ break;
+ }
+ if (pathNodeIndex == 414)
+ return false;
+ CPedPathNode *pPathNode = pStartPathNode;
+ for (*pointsFound = 0; pPathNode != pEndPathNode && *pointsFound < maxPoints; ++ *pointsFound) {
+ const uint8 nodeIdX = pPathNode->nodeIdX;
+ const uint8 nodeIdY = pPathNode->nodeIdY;
+ if (nodeIdX > 0 && pathNodes[nodeIdX - 1][nodeIdY].id + 5 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX - 1][nodeIdY];
+ else if (nodeIdX > 39 && pathNodes[nodeIdX + 1][nodeIdY].id + 5 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX + 1][nodeIdY];
+ else if (nodeIdY > 0 && pathNodes[nodeIdX][nodeIdY - 1].id + 5 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX][nodeIdY - 1];
+ else if (nodeIdY > 39 && pathNodes[nodeIdX][nodeIdY + 1].id + 5 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX][nodeIdY + 1];
+ else if (nodeIdX > 0 && nodeIdY > 0 && pathNodes[nodeIdX - 1][nodeIdY - 1].id + 7 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX - 1][nodeIdY - 1];
+ else if (nodeIdX > 0 && nodeIdY < 39 && pathNodes[nodeIdX - 1][nodeIdY + 1].id + 7 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX - 1][nodeIdY + 1];
+ else if (nodeIdX < 39 && nodeIdY > 0 && pathNodes[nodeIdX + 1][nodeIdY - 1].id + 7 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX + 1][nodeIdY - 1];
+ else if (nodeIdX < 39 && nodeIdY < 39 && pathNodes[nodeIdX + 1][nodeIdY + 1].id + 7 == pPathNode->id)
+ pPathNode = &pathNodes[nodeIdX + 1][nodeIdY + 1];
+ pointPoses[*pointsFound] = vecSectorStartPos;
+ pointPoses[*pointsFound].x += pPathNode->nodeIdX * 0.7f;
+ pointPoses[*pointsFound].y += pPathNode->nodeIdY * 0.7f;
+ }
+ return true;
+}
+
+
+void
+CPedPath::AddNodeToPathList(CPedPathNode *pNodeToAdd, int16 id, CPedPathNode *pNodeList)
+{
+ if (!pNodeToAdd->bBlockade && id < pNodeToAdd->id) {
+ if (pNodeToAdd->id != INT16_MAX)
+ RemoveNodeFromList(pNodeToAdd);
+ AddNodeToList(pNodeToAdd, id, pNodeList);
+ }
+}
+
+void
+CPedPath::RemoveNodeFromList(CPedPathNode *pNode)
+{
+ pNode->next->prev = pNode->prev;
+ if (pNode->prev)
+ pNode->prev->next = pNode->next;
+}
+
+void
+CPedPath::AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList)
+{
+ pNode->prev = pList[index].prev;
+ pNode->next = &pList[index];
+ if (pList[index].prev)
+ pList[index].prev->next = pNode;
+ pList[index].prev = pNode;
+ pNode->id = index;
+}
+
+void
+CPedPath::AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition)
+{
+ CPtrNode* listNode = list.first;
+ while (listNode) {
+ CEntity* pEntity = (CEntity*)listNode->item;
+ if (pEntity->m_scanCode != CWorld::GetCurrentScanCode() && pEntity->bUsesCollision) {
+ pEntity->m_scanCode = CWorld::GetCurrentScanCode();
+ AddBlockade(pEntity, pathNodes, pPosition);
+ }
+ listNode = listNode->next;
+ }
+}
+
+void
+CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition)
+{
+ const CColBox& boundingBox = pEntity->GetColModel()->boundingBox;
+ const float fBoundMaxY = boundingBox.max.y + 0.3f;
+ const float fBoundMinY = boundingBox.min.y - 0.3f;
+ const float fBoundMaxX = boundingBox.max.x + 0.3f;
+ const float fDistanceX = pPosition->x - pEntity->m_matrix.GetPosition().x;
+ const float fDistanceY = pPosition->y - pEntity->m_matrix.GetPosition().y;
+ const float fBoundRadius = pEntity->GetBoundRadius();
+ CVector vecBoundCentre;
+ pEntity->GetBoundCentre(vecBoundCentre);
+ if (vecBoundCentre.x + fBoundRadius >= pPosition->x &&
+ vecBoundCentre.y + fBoundRadius >= pPosition->y &&
+ vecBoundCentre.x - fBoundRadius <= pPosition->x + 28.0f &&
+ vecBoundCentre.y - fBoundRadius <= pPosition->y + 28.0f) {
+ for (int16 x = 0; x < 40; x++) {
+ const float pointX = x * 0.7f + fDistanceX;
+ for (int16 y = 0; y < 40; y++) {
+ if (!pathNodes[x][y].bBlockade) {
+ const float pointY = y * 0.7f + fDistanceY;
+ CVector2D point(pointX, pointY);
+ if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->m_matrix.GetRight()))) {
+ float fDotProduct = DotProduct2D(point, pEntity->m_matrix.GetForward());
+ if (fBoundMaxY > fDotProduct && fBoundMinY < fDotProduct)
+ pathNodes[x][y].bBlockade = true;
+ }
+ }
+ }
+ }
+ }
+}
void
CPathFind::Init(void)
@@ -205,8 +397,8 @@ CPathFind::PreparePathData(void)
numExtern++;
if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes)
numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes;
- maxX = max(maxX, Abs(InfoForTileCars[k].x));
- maxY = max(maxY, Abs(InfoForTileCars[k].y));
+ maxX = Max(maxX, Abs(InfoForTileCars[k].x));
+ maxY = Max(maxY, Abs(InfoForTileCars[k].y));
}else if(InfoForTileCars[k].type == NodeTypeIntern)
numIntern++;
}
@@ -390,7 +582,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
if(Abs(dx) < nearestDist){
dy = tempnodes[k].pos.y - CoorsXFormed.y;
if(Abs(dy) < nearestDist){
- nearestDist = max(Abs(dx), Abs(dy));
+ nearestDist = Max(Abs(dx), Abs(dy));
nearestId = k;
}
}
@@ -499,13 +691,13 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// Find i inside path segment
iseg = 0;
- for(j = max(oldNumPathNodes, i-12); j < i; j++)
+ for(j = Max(oldNumPathNodes, i-12); j < i; j++)
if(m_pathNodes[j].objectIndex == m_pathNodes[i].objectIndex)
iseg++;
istart = 12*m_mapObjects[m_pathNodes[i].objectIndex]->m_modelIndex;
// Add links to other internal nodes
- for(j = max(oldNumPathNodes, i-12); j < min(m_numPathNodes, i+12); j++){
+ for(j = Max(oldNumPathNodes, i-12); j < Min(m_numPathNodes, i+12); j++){
if(m_pathNodes[i].objectIndex != m_pathNodes[j].objectIndex || i == j)
continue;
// N.B.: in every path segment, the externals have to be at the end
@@ -1274,8 +1466,11 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
targetNode = FindNodeClosestToCoors(target, type, distLimit);
else
targetNode = forcedTargetNode;
- if(targetNode < 0)
- goto fail;
+ if(targetNode < 0) {
+ *pNumNodes = 0;
+ if(pDist) *pDist = 100000.0f;
+ return;
+ }
// Find start
int numPathsToTry;
@@ -1294,19 +1489,28 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
numPathsToTry = 1;
startObj = m_mapObjects[m_pathNodes[startNodeId].objectIndex];
}
- if(numPathsToTry == 0)
- goto fail;
+ if(numPathsToTry == 0) {
+ *pNumNodes = 0;
+ if(pDist) *pDist = 100000.0f;
+ return;
+ }
if(startNodeId < 0){
// why only check node 0?
- if(m_pathNodes[startObj->m_nodeIndices[type][0]].group != m_pathNodes[targetNode].group)
- goto fail;
+ if(m_pathNodes[startObj->m_nodeIndices[type][0]].group !=
+ m_pathNodes[targetNode].group) {
+ *pNumNodes = 0;
+ if(pDist) *pDist = 100000.0f;
+ return;
+ }
}else{
- if(m_pathNodes[startNodeId].group != m_pathNodes[targetNode].group)
- goto fail;
+ if(m_pathNodes[startNodeId].group != m_pathNodes[targetNode].group) {
+ *pNumNodes = 0;
+ if(pDist) *pDist = 100000.0f;
+ return;
+ }
}
-
for(i = 0; i < 512; i++)
m_searchNodes[i].next = nil;
AddNodeToList(&m_pathNodes[targetNode], 0);
@@ -1384,11 +1588,6 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
for(i = 0; i < numNodesToBeCleared; i++)
apNodesToBeCleared[i]->distance = MAX_DIST;
return;
-
-fail:
- *pNumNodes = 0;
- if(pDist)
- *pDist = 100000.0f;
}
static CPathNode *pNodeList[32];
@@ -1574,41 +1773,3 @@ CPathFind::DisplayPathData(void)
}
}
}
-
-STARTPATCHES
- InjectHook(0x4294A0, &CPathFind::Init, PATCH_JUMP);
- InjectHook(0x42D580, &CPathFind::AllocatePathFindInfoMem, PATCH_JUMP);
- InjectHook(0x429540, &CPathFind::RegisterMapObject, PATCH_JUMP);
- InjectHook(0x42D7E0, &CPathFind::StoreNodeInfoPed, PATCH_JUMP);
- InjectHook(0x42D690, &CPathFind::StoreNodeInfoCar, PATCH_JUMP);
- InjectHook(0x429610, &CPathFind::PreparePathData, PATCH_JUMP);
- InjectHook(0x42B810, &CPathFind::CountFloodFillGroups, PATCH_JUMP);
- InjectHook(0x429C20, &CPathFind::PreparePathDataForType, PATCH_JUMP);
-
- InjectHook(0x42C990, &CPathFind::CalcRoadDensity, PATCH_JUMP);
- InjectHook(0x42E1B0, &CPathFind::TestForPedTrafficLight, PATCH_JUMP);
- InjectHook(0x42E340, &CPathFind::TestCrossesRoad, PATCH_JUMP);
- InjectHook(0x42CBE0, &CPathFind::AddNodeToList, PATCH_JUMP);
- InjectHook(0x42CBB0, &CPathFind::RemoveNodeFromList, PATCH_JUMP);
- InjectHook(0x42B790, &CPathFind::RemoveBadStartNode, PATCH_JUMP);
- InjectHook(0x42E3B0, &CPathFind::SetLinksBridgeLights, PATCH_JUMP);
- InjectHook(0x42DED0, &CPathFind::SwitchOffNodeAndNeighbours, PATCH_JUMP);
- InjectHook(0x42D960, &CPathFind::SwitchRoadsOffInArea, PATCH_JUMP);
- InjectHook(0x42DA50, &CPathFind::SwitchPedRoadsOffInArea, PATCH_JUMP);
- InjectHook(0x42DB50, &CPathFind::SwitchRoadsInAngledArea, PATCH_JUMP);
- InjectHook(0x42E140, &CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours, PATCH_JUMP);
- InjectHook(0x42DF50, &CPathFind::MarkRoadsBetweenLevelsInArea, PATCH_JUMP);
- InjectHook(0x42E040, &CPathFind::PedMarkRoadsBetweenLevelsInArea, PATCH_JUMP);
- InjectHook(0x42CC30, &CPathFind::FindNodeClosestToCoors, PATCH_JUMP);
- InjectHook(0x42CDC0, &CPathFind::FindNodeClosestToCoorsFavourDirection, PATCH_JUMP);
- InjectHook(0x42CFC0, &CPathFind::FindNodeOrientationForCarPlacement, PATCH_JUMP);
- InjectHook(0x42D060, &CPathFind::FindNodeOrientationForCarPlacementFacingDestination, PATCH_JUMP);
- InjectHook(0x42BF10, &CPathFind::NewGenerateCarCreationCoors, PATCH_JUMP);
- InjectHook(0x42C1E0, &CPathFind::GeneratePedCreationCoors, PATCH_JUMP);
- InjectHook(0x42D2A0, &CPathFind::FindRoadObjectClosestToCoors, PATCH_JUMP);
- InjectHook(0x42B9F0, &CPathFind::FindNextNodeWandering, PATCH_JUMP);
- InjectHook(0x42B040, &CPathFind::DoPathSearch, PATCH_JUMP);
- InjectHook(0x42C8C0, &CPathFind::TestCoorsCloseness, PATCH_JUMP);
- InjectHook(0x42E450, &CPathFind::Save, PATCH_JUMP);
- InjectHook(0x42E550, &CPathFind::Load, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index 81467cdf..64c12d5b 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -3,11 +3,7 @@
#include "Treadable.h"
class CVehicle;
-
-class CPedPath {
-public:
- static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
-};
+class CPtrList;
enum
{
@@ -30,6 +26,33 @@ enum
SWITCH_ON = 1,
};
+enum
+{
+ ROUTE_ADD_BLOCKADE = 0,
+ ROUTE_NO_BLOCKADE = 1
+};
+
+struct CPedPathNode
+{
+ bool bBlockade;
+ uint8 nodeIdX;
+ uint8 nodeIdY;
+ int16 id;
+ CPedPathNode* prev;
+ CPedPathNode* next;
+};
+static_assert(sizeof(CPedPathNode) == 0x10, "CPedPathNode: error");
+
+class CPedPath {
+public:
+ static bool CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints);
+ static void AddNodeToPathList(CPedPathNode *pNodeToAdd, int16 id, CPedPathNode *pNodeList);
+ static void RemoveNodeFromList(CPedPathNode *pNode);
+ static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList);
+ static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition);
+ static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition);
+};
+
struct CPathNode
{
CVector pos;
@@ -115,8 +138,8 @@ struct CPathInfoForObject
int8 numRightLanes;
uint8 crossing : 1;
};
-extern CPathInfoForObject *&InfoForTileCars;
-extern CPathInfoForObject *&InfoForTilePeds;
+extern CPathInfoForObject *InfoForTileCars;
+extern CPathInfoForObject *InfoForTilePeds;
struct CTempNode
{
@@ -211,7 +234,7 @@ public:
};
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");
-extern CPathFind &ThePaths;
+extern CPathFind ThePaths;
extern bool gbShowPedPaths;
extern bool gbShowCarPaths;
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index 276f02b9..15e9f9f1 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Phones.h"
#include "Pools.h"
#include "ModelIndices.h"
@@ -12,14 +12,17 @@
#include "AudioScriptObject.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
+#ifdef FIX_BUGS
+#include "Replay.h"
+#endif
-CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;
+CPhoneInfo gPhoneInfo;
-bool &CPhoneInfo::bDisplayingPhoneMessage = *(bool*)0x6283AC; // is phone picked up
-uint32 &CPhoneInfo::PhoneEnableControlsTimer = *(uint32*)0x6283A8;
-CPhone *&CPhoneInfo::pPhoneDisplayingMessages = *(CPhone**)0x6283B0;
-bool &CPhoneInfo::bPickingUpPhone = *(bool*)0x6283B4;
-CPed *&CPhoneInfo::pCallBackPed = *(CPed**)0x6283B8; // ped who picking up the phone (reset after pickup cb)
+bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
+uint32 CPhoneInfo::PhoneEnableControlsTimer;
+CPhone *CPhoneInfo::pPhoneDisplayingMessages;
+bool CPhoneInfo::bPickingUpPhone;
+CPed *CPhoneInfo::pCallBackPed; // ped who picking up the phone (reset after pickup cb)
/*
Entering phonebooth cutscene, showing messages and triggering these things
@@ -45,6 +48,10 @@ isPhoneAvailable(int m_phoneId)
void
CPhoneInfo::Update(void)
{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return;
+#endif
CPlayerPed *player = FindPlayerPed();
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
if (bDisplayingPhoneMessage && CTimer::GetTimeInMilliseconds() > PhoneEnableControlsTimer) {
@@ -377,20 +384,3 @@ PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg)
CPhoneInfo::pCallBackPed = nil;
}
-
-STARTPATCHES
- InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP);
- InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP);
- InjectHook(0x42FFF0, &CPhoneInfo::HasMessageBeenDisplayed, PATCH_JUMP);
- InjectHook(0x430030, &CPhoneInfo::IsMessageBeingDisplayed, PATCH_JUMP);
- InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP);
- InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP);
- InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP);
- InjectHook(0x430060, &CPhoneInfo::Save, PATCH_JUMP);
- InjectHook(0x42F710, &CPhoneInfo::Shutdown, PATCH_JUMP);
- InjectHook(0x42F640, &CPhoneInfo::Initialise, PATCH_JUMP);
- InjectHook(0x42FDB0, &CPhoneInfo::GrabPhone, PATCH_JUMP);
- InjectHook(0x42F7A0, &CPhoneInfo::Update, PATCH_JUMP);
- InjectHook(0x42F570, &PhonePutDownCB, PATCH_JUMP);
- InjectHook(0x42F470, &PhonePickUpCB, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/Phones.h b/src/control/Phones.h
index e7e3c9a7..7fbf403f 100644
--- a/src/control/Phones.h
+++ b/src/control/Phones.h
@@ -36,11 +36,11 @@ static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
class CPhoneInfo {
public:
- static bool &bDisplayingPhoneMessage;
- static uint32 &PhoneEnableControlsTimer;
- static CPhone *&pPhoneDisplayingMessages;
- static bool &bPickingUpPhone;
- static CPed *&pCallBackPed;
+ static bool bDisplayingPhoneMessage;
+ static uint32 PhoneEnableControlsTimer;
+ static CPhone *pPhoneDisplayingMessages;
+ static bool bPickingUpPhone;
+ static CPed *pCallBackPed;
int32 m_nMax;
int32 m_nScriptPhonesMax;
@@ -63,7 +63,7 @@ public:
void Update(void);
};
-extern CPhoneInfo &gPhoneInfo;
+extern CPhoneInfo gPhoneInfo;
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index eb561670..d5db4ad8 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Camera.h"
@@ -31,16 +31,16 @@
#include "WaterLevel.h"
#include "World.h"
-CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98;
-int16 CPickups::NumMessages;// = *(int16*)0x95CC98;
-int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538;
-int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A;
+CPickup CPickups::aPickUps[NUMPICKUPS];
+int16 CPickups::NumMessages;
+int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
+int16 CPickups::CollectedPickUpIndex;
// unused
-bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71;
-CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8;
-CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8;
-uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C;
+bool CPickups::bPickUpcamActivated;
+CVehicle *CPickups::pPlayerVehicle;
+CVector CPickups::StaticCamCoors;
+uint32 CPickups::StaticCamStartTime;
tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
@@ -99,7 +99,7 @@ CPickup::GiveUsAPickUpObject(int32 handle)
switch (m_eType)
{
case PICKUP_IN_SHOP:
- object->m_obj_flag2 = true;
+ object->bPickupObjWithMessage = true;
object->bOutOfStock = false;
break;
case PICKUP_ON_STREET:
@@ -113,11 +113,11 @@ CPickup::GiveUsAPickUpObject(int32 handle)
case PICKUP_NAUTICAL_MINE_ARMED:
case PICKUP_FLOATINGPACKAGE:
case PICKUP_ON_STREET_SLOW:
- object->m_obj_flag2 = false;
+ object->bPickupObjWithMessage = false;
object->bOutOfStock = false;
break;
case PICKUP_IN_SHOP_OUT_OF_STOCK:
- object->m_obj_flag2 = false;
+ object->bPickupObjWithMessage = false;
object->bOutOfStock = true;
object->bRenderScorched = true;
break;
@@ -491,7 +491,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
int32 slot = 0;
if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) {
- for (slot = NUMPICKUPS; slot >= 0; slot--) {
+ for (slot = NUMPICKUPS-1; slot >= 0; slot--) {
if (aPickUps[slot].m_eType == PICKUP_NONE) {
bFreeFound = true;
break;
@@ -623,6 +623,34 @@ CPickups::Update()
if (CReplay::IsPlayingBack())
return;
#endif
+#ifdef CAMERA_PICKUP
+ if ( bPickUpcamActivated ) // taken from PS2
+ {
+ float dist = (FindPlayerCoors() - StaticCamCoors).Magnitude2D();
+ float mult;
+ if ( dist < 10.0f )
+ mult = 1.0f - (dist / 10.0f );
+ else
+ mult = 0.0f;
+
+ CVector pos = StaticCamCoors;
+ pos.z += (pPlayerVehicle->GetColModel()->boundingBox.GetSize().z + 2.0f) * mult;
+
+ if ( (CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 750 )
+ {
+ TheCamera.SetCamPositionForFixedMode(pos, CVector(0.0f, 0.0f, 0.0f));
+ TheCamera.TakeControl(FindPlayerVehicle(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_SCRIPT);
+ }
+
+ if ( FindPlayerVehicle() != pPlayerVehicle
+ || (FindPlayerCoors() - StaticCamCoors).Magnitude() > 40.0f
+ || ((CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 60000) )
+ {
+ TheCamera.RestoreWithJumpCut();
+ bPickUpcamActivated = false;
+ }
+ }
+#endif
#define PICKUPS_FRAME_SPAN (6)
#ifdef FIX_BUGS
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
@@ -690,7 +718,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CObject *object = (CObject*)entity;
- if (object->m_obj_flag2 || object->bOutOfStock || object->m_nBonusValue) {
+ if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) {
float dist = (TheCamera.GetPosition() - pos).Magnitude();
const float MAXDIST = 12.0f;
@@ -1406,47 +1434,3 @@ CPacManPickups::ResetPowerPillsCarriedByPlayer()
FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
}
}
-
-STARTPATCHES
- InjectHook(0x430220, CPickups::Init, PATCH_JUMP);
- InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP);
- InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP);
- InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP);
- InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP);
- InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP);
- InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP);
- InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP);
- InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP);
- InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP);
- InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP);
- InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP);
- InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP);
- InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP);
- InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP);
- InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/
- InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP);
- InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP);
- InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP);
- InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP);
- InjectHook(0x433F60, CPickups::Load, PATCH_JUMP);
- InjectHook(0x433E40, CPickups::Save, PATCH_JUMP);
- InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP);
- InjectHook(0x430860, &CPickup::Update, PATCH_JUMP);
- InjectHook(0x4331B0, &CPacManPickup::Update, PATCH_JUMP);
- InjectHook(0x432760, CPacManPickups::Init, PATCH_JUMP);
- InjectHook(0x432800, CPacManPickups::Update, PATCH_JUMP);
- InjectHook(0x432AE0, CPacManPickups::GeneratePMPickUps, PATCH_JUMP);
- InjectHook(0x432D50, CPacManPickups::GeneratePMPickUpsForRace, PATCH_JUMP);
- InjectHook(0x432F20, CPacManPickups::GenerateOnePMPickUp, PATCH_JUMP);
- InjectHook(0x432F60, CPacManPickups::Render, PATCH_JUMP);
- InjectHook(0x433150, CPacManPickups::ClearPMPickUps, PATCH_JUMP);
- InjectHook(0x433340, CPacManPickups::StartPacManRace, PATCH_JUMP);
- InjectHook(0x433360, CPacManPickups::StartPacManRecord, PATCH_JUMP);
- InjectHook(0x4333A0, CPacManPickups::QueryPowerPillsEatenInRace, PATCH_JUMP);
- InjectHook(0x4333B0, CPacManPickups::ResetPowerPillsEatenInRace, PATCH_JUMP);
- InjectHook(0x4333C0, CPacManPickups::CleanUpPacManStuff, PATCH_JUMP);
- InjectHook(0x4333D0, CPacManPickups::StartPacManScramble, PATCH_JUMP);
- InjectHook(0x4333F0, CPacManPickups::QueryPowerPillsCarriedByPlayer, PATCH_JUMP);
- InjectHook(0x433410, CPacManPickups::ResetPowerPillsCarriedByPlayer, PATCH_JUMP);
-
-ENDPATCHES
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index b5b4f396..11da5f54 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -89,13 +89,13 @@ public:
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size);
- static CPickup(&aPickUps)[NUMPICKUPS];
+ static CPickup aPickUps[NUMPICKUPS];
// unused
- static bool &bPickUpcamActivated;
- static CVehicle *&pPlayerVehicle;
- static CVector &StaticCamCoors;
- static uint32 &StaticCamStartTime;
+ static bool bPickUpcamActivated;
+ static CVehicle *pPlayerVehicle;
+ static CVector StaticCamCoors;
+ static uint32 StaticCamStartTime;
};
extern uint16 AmmoForWeapon[20];
diff --git a/src/control/Record.cpp b/src/control/Record.cpp
index ca4128e3..b9e8f8da 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Record.h"
#include "FileMgr.h"
@@ -10,11 +10,11 @@
#include "VehicleModelInfo.h"
#include "World.h"
-uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24;
-uint8*& CRecordDataForGame::pDataBuffer = *(uint8**)0x8F1B70;
-uint8*& CRecordDataForGame::pDataBufferPointer = *(uint8**)0x8F1AB0;
-int& CRecordDataForGame::FId = *(int*)0x885BA4;
-tGameBuffer& CRecordDataForGame::pDataBufferForFrame = *(tGameBuffer*)0x72CED0;
+uint16 CRecordDataForGame::RecordingState;
+uint8* CRecordDataForGame::pDataBuffer;
+uint8* CRecordDataForGame::pDataBufferPointer;
+int CRecordDataForGame::FId;
+tGameBuffer CRecordDataForGame::pDataBufferForFrame;
#define MEMORY_FOR_GAME_RECORD (150000)
@@ -176,15 +176,15 @@ uint16 CRecordDataForGame::CalcGameChecksum(void)
return checksum ^ checksum >> 16;
}
-uint8& CRecordDataForChase::Status = *(uint8*)0x95CDCE;
-int& CRecordDataForChase::PositionChanges = *(int*)0x8F59C8;
-uint8& CRecordDataForChase::CurrentCar = *(uint8*)0x95CDC9;
-CAutomobile* (&CRecordDataForChase::pChaseCars)[NUM_CHASE_CARS] = *(CAutomobile * (*)[NUM_CHASE_CARS])*(uintptr*)0x6F46A8;
-uint32& CRecordDataForChase::AnimStartTime = *(uint32*)0x8F1AEC;
-float& CRecordDataForChase::AnimTime = *(float*)0x880F88;
-CCarStateEachFrame* (&CRecordDataForChase::pBaseMemForCar)[NUM_CHASE_CARS] = *(CCarStateEachFrame * (*)[NUM_CHASE_CARS])*(uintptr*)0x70EA18;
-float& CRecordDataForChase::TimeMultiplier = *(float*)0x8E2A94;
-int& CRecordDataForChase::FId2 = *(int*)0x8E2C18;
+uint8 CRecordDataForChase::Status;
+int CRecordDataForChase::PositionChanges;
+uint8 CRecordDataForChase::CurrentCar;
+CAutomobile* CRecordDataForChase::pChaseCars[NUM_CHASE_CARS];
+uint32 CRecordDataForChase::AnimStartTime;
+float CRecordDataForChase::AnimTime;
+CCarStateEachFrame* CRecordDataForChase::pBaseMemForCar[NUM_CHASE_CARS];
+float CRecordDataForChase::TimeMultiplier;
+int CRecordDataForChase::FId2;
#define CHASE_SCENE_LENGTH_IN_SECONDS (80)
#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
@@ -296,7 +296,7 @@ void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
case STATE_PLAYBACK:
{
TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
- float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
+ float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * Min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (!pBaseMemForCar[i])
continue;
@@ -371,7 +371,7 @@ void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFram
else
pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
}
- pCar->m_fHealth = min(pCar->m_fHealth, 500.0f);
+ pCar->m_fHealth = Min(pCar->m_fHealth, 500.0f);
if (stop) {
pCar->m_fGasPedal = 0.0f;
pCar->m_fBrakePedal = 0.0f;
diff --git a/src/control/Record.h b/src/control/Record.h
index 4abeb68a..7af733ba 100644
--- a/src/control/Record.h
+++ b/src/control/Record.h
@@ -23,7 +23,7 @@ public:
CVector pos;
};
-extern char* gString;
+extern char gString[256];;
class CRecordDataForChase
{
@@ -37,15 +37,15 @@ class CRecordDataForChase
STATE_PLAYBACK = 3,
STATE_PLAYBACK_BEFORE_RECORDING = 4
};
- static uint8 &Status;
- static int &PositionChanges;
- static uint8 &CurrentCar;
- static CAutomobile*(&pChaseCars)[NUM_CHASE_CARS];
- static float &AnimTime;
- static uint32 &AnimStartTime;
- static CCarStateEachFrame* (&pBaseMemForCar)[NUM_CHASE_CARS];
- static float &TimeMultiplier;
- static int &FId2;
+ static uint8 Status;
+ static int PositionChanges;
+ static uint8 CurrentCar;
+ static CAutomobile*pChaseCars[NUM_CHASE_CARS];
+ static float AnimTime;
+ static uint32 AnimStartTime;
+ static CCarStateEachFrame* pBaseMemForCar[NUM_CHASE_CARS];
+ static float TimeMultiplier;
+ static int FId2;
public:
static bool IsRecording(void) { return Status == STATE_RECORD; }
@@ -86,11 +86,11 @@ class CRecordDataForGame
STATE_RECORD = 1,
STATE_PLAYBACK = 2,
};
- static uint16& RecordingState;
- static uint8* &pDataBuffer;
- static uint8* &pDataBufferPointer;
- static int &FId;
- static tGameBuffer &pDataBufferForFrame;
+ static uint16 RecordingState;
+ static uint8* pDataBuffer;
+ static uint8* pDataBufferPointer;
+ static int FId;
+ static tGameBuffer pDataBufferForFrame;
public:
static bool IsRecording() { return RecordingState == STATE_RECORD; }
diff --git a/src/control/Remote.cpp b/src/control/Remote.cpp
index f7d12702..9c749bd9 100644
--- a/src/control/Remote.cpp
+++ b/src/control/Remote.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Automobile.h"
#include "CarCtrl.h"
#include "Camera.h"
@@ -49,8 +49,3 @@ CRemote::TakeRemoteControlledCarFromPlayer(void)
CWorld::Players[CWorld::PlayerInFocus].m_bInRemoteMode = true;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
}
-
-STARTPATCHES
- InjectHook(0x435C30, &CRemote::GivePlayerRemoteControlledCar, PATCH_JUMP);
- InjectHook(0x435DA0, &CRemote::TakeRemoteControlledCarFromPlayer, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 0da32dd2..d37e98cf 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "AnimBlendAssociation.h"
#include "Boat.h"
#include "SpecialFX.h"
@@ -39,71 +39,73 @@
#include "Camera.h"
#include "Radar.h"
-uint8 &CReplay::Mode = *(uint8*)0x95CD5B;
-CAddressInReplayBuffer &CReplay::Record = *(CAddressInReplayBuffer*)0x942F7C;
-CAddressInReplayBuffer &CReplay::Playback = *(CAddressInReplayBuffer*)0x8F5F48;
-uint8 *&CReplay::pBuf0 = *(uint8**)0x8E2C64;
-CAutomobile *&CReplay::pBuf1 = *(CAutomobile**)0x8E2C68;
-uint8 *&CReplay::pBuf2 = *(uint8**)0x8E2C6C;
-CPlayerPed *&CReplay::pBuf3 = *(CPlayerPed**)0x8E2C70;
-uint8 *&CReplay::pBuf4 = *(uint8**)0x8E2C74;
-CCutsceneHead *&CReplay::pBuf5 = *(CCutsceneHead**)0x8E2C78;
-uint8 *&CReplay::pBuf6 = *(uint8**)0x8E2C80;
-CPtrNode *&CReplay::pBuf7 = *(CPtrNode**)0x8E2C84;
-uint8 *&CReplay::pBuf8 = *(uint8**)0x8E2C54;
-CEntryInfoNode *&CReplay::pBuf9 = *(CEntryInfoNode**)0x8E2C58;
-uint8 *&CReplay::pBuf10 = *(uint8**)0x8F2C28;
-CDummyPed *&CReplay::pBuf11 = *(CDummyPed**)0x8F2C2C;
-uint8 *&CReplay::pRadarBlips = *(uint8**)0x8F29F8;
-uint8 *&CReplay::pStoredCam = *(uint8**)0x8F2C34;
-uint8 *&CReplay::pWorld1 = *(uint8**)0x8E29C4;
-CReference *&CReplay::pEmptyReferences = *(CReference**)0x8F256C;
-CStoredDetailedAnimationState *&CReplay::pPedAnims = *(CStoredDetailedAnimationState**)0x8F6260;
-uint8 *&CReplay::pPickups = *(uint8**)0x8F1A48;
-uint8 *&CReplay::pReferences = *(uint8**)0x880FAC;
-uint8(&CReplay::BufferStatus)[NUM_REPLAYBUFFERS] = *(uint8(*)[NUM_REPLAYBUFFERS])*(uintptr*)0x8804D8;
-uint8(&CReplay::Buffers)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE] = *(uint8(*)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE])*(uintptr*)0x779958;
-bool &CReplay::bPlayingBackFromFile = *(bool*)0x95CD58;
-bool &CReplay::bReplayEnabled = *(bool*)0x617CAC;
-uint32 &CReplay::SlowMotion = *(uint32*)0x9414D4;
-uint32 &CReplay::FramesActiveLookAroundCam = *(uint32*)0x880F84;
-bool &CReplay::bDoLoadSceneWhenDone = *(bool*)0x95CD76;
-CPtrList &CReplay::WorldPtrList = *(CPtrList*)0x880F90;
-CPtrList &CReplay::BigBuildingPtrList = *(CPtrList*)0x941284;
-CWanted &CReplay::PlayerWanted = *(CWanted*)0x8F6278;
-CPlayerInfo &CReplay::PlayerInfo = *(CPlayerInfo*)0x8F5840;
-uint32 &CReplay::Time1 = *(uint32*)0x8F29DC;
-uint32 &CReplay::Time2 = *(uint32*)0x8F29D0;
-uint32 &CReplay::Time3 = *(uint32*)0x8F29D4;
-uint32 &CReplay::Time4 = *(uint32*)0x8F29C8;
-uint32 &CReplay::Frame = *(uint32*)0x8F2554;
-uint8 &CReplay::ClockHours = *(uint8*)0x95CDC5;
-uint8 &CReplay::ClockMinutes = *(uint8*)0x95CDA2;
-uint16 &CReplay::OldWeatherType = *(uint16*)0x95CCEA;
-uint16 &CReplay::NewWeatherType = *(uint16*)0x95CC6E;
-float &CReplay::WeatherInterpolationValue = *(float*)0x8F1A28;
-float &CReplay::TimeStepNonClipped = *(float*)0x8F5FF4;
-float &CReplay::TimeStep = *(float*)0x8F2C24;
-float &CReplay::TimeScale = *(float*)0x880E20;
-float &CReplay::CameraFixedX = *(float*)0x943054;
-float &CReplay::CameraFixedY = *(float*)0x943058;
-float &CReplay::CameraFixedZ = *(float*)0x94305C;
-int32 &CReplay::OldRadioStation = *(int32*)0x94151C;
-int8 &CReplay::CameraMode = *(int8*)0x95CD5F;
-bool &CReplay::bAllowLookAroundCam = *(bool*)0x95CDCD;
-float &CReplay::LoadSceneX = *(float*)0x880F9C;
-float &CReplay::LoadSceneY = *(float*)0x880F98;
-float &CReplay::LoadSceneZ = *(float*)0x880F94;
-float &CReplay::CameraFocusX = *(float*)0x942F5C;
-float &CReplay::CameraFocusY = *(float*)0x942F74;
-float &CReplay::CameraFocusZ = *(float*)0x942F58;
-bool &CReplay::bPlayerInRCBuggy = *(bool*)0x95CDC3;
-float &CReplay::fDistanceLookAroundCam = *(float*)0x885B44;
-float &CReplay::fBetaAngleLookAroundCam = *(float*)0x94072C;
-float &CReplay::fAlphaAngleLookAroundCam = *(float*)0x8F2A0C;
+uint8 CReplay::Mode;
+CAddressInReplayBuffer CReplay::Record;
+CAddressInReplayBuffer CReplay::Playback;
+uint8 *CReplay::pBuf0;
+CAutomobile *CReplay::pBuf1;
+uint8 *CReplay::pBuf2;
+CPlayerPed *CReplay::pBuf3;
+uint8 *CReplay::pBuf4;
+CCutsceneHead *CReplay::pBuf5;
+uint8 *CReplay::pBuf6;
+CPtrNode *CReplay::pBuf7;
+uint8 *CReplay::pBuf8;
+CEntryInfoNode *CReplay::pBuf9;
+uint8 *CReplay::pBuf10;
+CDummyPed *CReplay::pBuf11;
+uint8 *CReplay::pRadarBlips;
+uint8 *CReplay::pStoredCam;
+uint8 *CReplay::pWorld1;
+CReference *CReplay::pEmptyReferences;
+CStoredDetailedAnimationState *CReplay::pPedAnims;
+uint8 *CReplay::pPickups;
+uint8 *CReplay::pReferences;
+uint8 CReplay::BufferStatus[NUM_REPLAYBUFFERS];
+uint8 CReplay::Buffers[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
+bool CReplay::bPlayingBackFromFile;
+bool CReplay::bReplayEnabled = true;
+uint32 CReplay::SlowMotion;
+uint32 CReplay::FramesActiveLookAroundCam;
+bool CReplay::bDoLoadSceneWhenDone;
+CPtrNode* CReplay::WorldPtrList;
+CPtrNode* CReplay::BigBuildingPtrList;
+CWanted CReplay::PlayerWanted;
+CPlayerInfo CReplay::PlayerInfo;
+uint32 CReplay::Time1;
+uint32 CReplay::Time2;
+uint32 CReplay::Time3;
+uint32 CReplay::Time4;
+uint32 CReplay::Frame;
+uint8 CReplay::ClockHours;
+uint8 CReplay::ClockMinutes;
+uint16 CReplay::OldWeatherType;
+uint16 CReplay::NewWeatherType;
+float CReplay::WeatherInterpolationValue;
+float CReplay::TimeStepNonClipped;
+float CReplay::TimeStep;
+float CReplay::TimeScale;
+float CReplay::CameraFixedX;
+float CReplay::CameraFixedY;
+float CReplay::CameraFixedZ;
+int32 CReplay::OldRadioStation;
+int8 CReplay::CameraMode;
+bool CReplay::bAllowLookAroundCam;
+float CReplay::LoadSceneX;
+float CReplay::LoadSceneY;
+float CReplay::LoadSceneZ;
+float CReplay::CameraFocusX;
+float CReplay::CameraFocusY;
+float CReplay::CameraFocusZ;
+bool CReplay::bPlayerInRCBuggy;
+float CReplay::fDistanceLookAroundCam;
+float CReplay::fBetaAngleLookAroundCam;
+float CReplay::fAlphaAngleLookAroundCam;
+#ifdef FIX_BUGS
+int CReplay::nHandleOfPlayerPed[NUMPLAYERS];
+#endif
-static void(*(&CBArray)[30])(CAnimBlendAssociation*, void*) = *(void(*(*)[30])(CAnimBlendAssociation*, void*))*(uintptr*)0x61052C;
-static void(*CBArray_RE3[])(CAnimBlendAssociation*, void*) =
+static void(*CBArray[])(CAnimBlendAssociation*, void*) =
{
nil, &CPed::PedGetupCB, &CPed::PedStaggerCB, &CPed::PedEvadeCB, &CPed::FinishDieAnimCB,
&CPed::FinishedWaitCB, &CPed::FinishLaunchCB, &CPed::FinishHitHeadCB, &CPed::PedAnimGetInCB, &CPed::PedAnimDoorOpenCB,
@@ -119,16 +121,13 @@ static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*))
if (CBArray[i] == f)
return i;
}
- for (int i = 0; i < sizeof(CBArray_RE3) / sizeof(*CBArray_RE3); i++) {
- if (CBArray_RE3[i] == f)
- return i;
- }
+
return 0;
}
static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*)
{
- return CBArray_RE3[id];
+ return CBArray[id];
}
static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying)
@@ -279,7 +278,7 @@ void CReplay::RecordThisFrame(void)
continue;
memory_required += sizeof(tBulletTracePacket);
}
- memory_required += sizeof(tEndOfFramePacket);
+ memory_required += sizeof(tEndOfFramePacket) + 1; // 1 for Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
if (Record.m_nOffset + memory_required > REPLAYBUFFERSIZE) {
Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
BufferStatus[Record.m_bSlot] = REPLAYBUFFER_PLAYBACK;
@@ -682,9 +681,9 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id)
vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */
vp->acceleration = vehicle->m_fGasPedal * 100.0f;
vp->panels = vehicle->IsCar() ? ((CAutomobile*)vehicle)->Damage.m_panelStatus : 0;
- vp->velocityX = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */
- vp->velocityY = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().y));
- vp->velocityZ = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().z));
+ vp->velocityX = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */
+ vp->velocityY = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().y));
+ vp->velocityZ = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().z));
vp->mi = vehicle->GetModelIndex();
vp->primary_color = vehicle->m_currentColour1;
vp->secondary_color = vehicle->m_currentColour2;
@@ -1087,7 +1086,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
Playback.m_bSlot = first;
Playback.m_nOffset = 0;
Playback.m_pBase = Buffers[first];
- CObject::DeleteAllTempObjectInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f);
+ CObject::DeleteAllTempObjectsInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f);
StoreStuffInMem();
EmptyPedsAndVehiclePools();
SlowMotion = 1;
@@ -1112,6 +1111,10 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
void CReplay::StoreStuffInMem(void)
{
+#ifdef FIX_BUGS
+ for (int i = 0; i < NUMPLAYERS; i++)
+ nHandleOfPlayerPed[i] = CPools::GetPedPool()->GetIndex(CWorld::Players[i].m_pPed);
+#endif
CPools::GetVehiclePool()->Store(pBuf0, pBuf1);
CPools::GetPedPool()->Store(pBuf2, pBuf3);
CPools::GetObjectPool()->Store(pBuf4, pBuf5);
@@ -1120,8 +1123,8 @@ void CReplay::StoreStuffInMem(void)
CPools::GetDummyPool()->Store(pBuf10, pBuf11);
pWorld1 = new uint8[sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y];
memcpy(pWorld1, CWorld::GetSector(0, 0), NUMSECTORS_X * NUMSECTORS_Y * sizeof(CSector));
- WorldPtrList = CWorld::GetMovingEntityList();
- BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_NONE);
+ WorldPtrList = CWorld::GetMovingEntityList().first; // why
+ BigBuildingPtrList = CWorld::GetBigBuildingList(LEVEL_NONE).first;
pPickups = new uint8[sizeof(CPickup) * NUMPICKUPS];
memcpy(pPickups, CPickups::aPickUps, NUMPICKUPS * sizeof(CPickup));
pReferences = new uint8[(sizeof(CReference) * NUMREFERENCES)];
@@ -1166,8 +1169,8 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(CWorld::GetSector(0, 0), pWorld1, sizeof(CSector) * NUMSECTORS_X * NUMSECTORS_Y);
delete[] pWorld1;
pWorld1 = nil;
- CWorld::GetMovingEntityList() = WorldPtrList;
- CWorld::GetBigBuildingList(LEVEL_NONE) = BigBuildingPtrList;
+ CWorld::GetMovingEntityList().first = WorldPtrList;
+ CWorld::GetBigBuildingList(LEVEL_NONE).first = BigBuildingPtrList;
memcpy(CPickups::aPickUps, pPickups, sizeof(CPickup) * NUMPICKUPS);
delete[] pPickups;
pPickups = nil;
@@ -1182,6 +1185,14 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
delete[] pRadarBlips;
pRadarBlips = nil;
+#ifdef FIX_BUGS
+ for (int i = 0; i < NUMPLAYERS; i++) {
+ CPlayerPed* pPlayerPed = (CPlayerPed*)CPools::GetPedPool()->GetAt(nHandleOfPlayerPed[i]);
+ assert(pPlayerPed);
+ CWorld::Players[i].m_pPed = pPlayerPed;
+ pPlayerPed->RegisterReference((CEntity**)&CWorld::Players[i].m_pPed);
+ }
+#endif
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);
CWorld::Players[0] = PlayerInfo;
int i = CPools::GetPedPool()->GetSize();
@@ -1215,7 +1226,7 @@ void CReplay::RestoreStuffFromMem(void)
vehicle->SetModelIndex(mi);
if (mi == MI_DODO){
CAutomobile* dodo = (CAutomobile*)vehicle;
- RpAtomicSetFlags(GetFirstObject(dodo->m_aCarNodes[CAR_WHEEL_LF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(dodo->m_aCarNodes[CAR_WHEEL_LF]), 0);
CMatrix tmp1;
tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false);
CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false);
@@ -1243,7 +1254,7 @@ void CReplay::RestoreStuffFromMem(void)
vehicle->GetMatrix().Detach();
if (vehicle->m_rwObject){
if (RwObjectGetType(vehicle->m_rwObject) == rpATOMIC){
- RwFrame* frame = RpAtomicGetFrame(vehicle->m_rwObject);
+ RwFrame* frame = RpAtomicGetFrame((RpAtomic*)vehicle->m_rwObject);
RpAtomicDestroy((RpAtomic*)vehicle->m_rwObject);
RwFrameDestroy(frame);
}
@@ -1254,7 +1265,7 @@ void CReplay::RestoreStuffFromMem(void)
int model_id = info->m_wheelId;
if (model_id != -1){
if ((vehicle->m_rwObject = CModelInfo::GetModelInfo(model_id)->CreateInstance())){
- vehicle->GetMatrix().AttachRW(&((RwFrame*)vehicle->m_rwObject->parent)->modelling, false);
+ vehicle->GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)vehicle->m_rwObject)), false);
}
}
}
@@ -1274,7 +1285,7 @@ void CReplay::RestoreStuffFromMem(void)
object->SetModelIndex(mi);
object->GetMatrix().m_attachment = nil;
if (RwObjectGetType(object->m_rwObject) == rpATOMIC)
- object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(object->m_rwObject)), false);
+ object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)object->m_rwObject)), false);
}
i = CPools::GetDummyPool()->GetSize();
while (--i >= 0) {
@@ -1289,7 +1300,7 @@ void CReplay::RestoreStuffFromMem(void)
dummy->SetModelIndex(mi);
dummy->GetMatrix().m_attachment = nil;
if (RwObjectGetType(dummy->m_rwObject) == rpATOMIC)
- dummy->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(dummy->m_rwObject)), false);
+ dummy->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)dummy->m_rwObject)), false);
}
CTimer::SetTimeInMilliseconds(Time1);
CTimer::SetTimeInMillisecondsNonClipped(Time2);
@@ -1397,8 +1408,8 @@ void CReplay::SaveReplayToHD(void)
for (first = (current + 1) % NUM_REPLAYBUFFERS; ; first = (first + 1) % NUM_REPLAYBUFFERS)
if (BufferStatus[first] == REPLAYBUFFER_RECORD || BufferStatus[first] == REPLAYBUFFER_PLAYBACK)
break;
- for(int i = first;; i = (i + 1) % NUM_REPLAYBUFFERS){
- CFileMgr::Write(fw, (char*)Buffers[first], sizeof(Buffers[first]));
+ for(int i = first; ; i = (i + 1) % NUM_REPLAYBUFFERS){
+ CFileMgr::Write(fw, (char*)Buffers[i], sizeof(Buffers[i]));
if (BufferStatus[i] == REPLAYBUFFER_RECORD)
break;
}
@@ -1501,9 +1512,9 @@ void CReplay::ProcessLookAroundCam(void)
--FramesActiveLookAroundCam;
fBetaAngleLookAroundCam += x_moved;
if (CPad::NewMouseControllerState.LMB && CPad::NewMouseControllerState.RMB)
- fDistanceLookAroundCam = max(3.0f, min(15.0f, fDistanceLookAroundCam + 2.0f * y_moved));
+ fDistanceLookAroundCam = Max(3.0f, Min(15.0f, fDistanceLookAroundCam + 2.0f * y_moved));
else
- fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved));
+ fAlphaAngleLookAroundCam = Max(0.1f, Min(1.5f, fAlphaAngleLookAroundCam + y_moved));
CVector camera_pt(
fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
@@ -1574,16 +1585,3 @@ void CReplay::Display()
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
-
-STARTPATCHES
-InjectHook(0x592FE0, &CReplay::Init, PATCH_JUMP);
-InjectHook(0x593150, &CReplay::DisableReplays, PATCH_JUMP);
-InjectHook(0x593160, &CReplay::EnableReplays, PATCH_JUMP);
-InjectHook(0x593170, &CReplay::Update, PATCH_JUMP);
-InjectHook(0x595B20, &CReplay::FinishPlayback, PATCH_JUMP);
-InjectHook(0x595BD0, &CReplay::EmptyReplayBuffer, PATCH_JUMP);
-InjectHook(0x595EE0, &CReplay::Display, PATCH_JUMP);
-InjectHook(0x596030, &CReplay::TriggerPlayback, PATCH_JUMP);
-InjectHook(0x597560, &CReplay::StreamAllNecessaryCarsAndPeds, PATCH_JUMP);
-InjectHook(0x597680, &CReplay::ShouldStandardCameraBeProcessed, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/control/Replay.h b/src/control/Replay.h
index 56de52a3..bf70a28a 100644
--- a/src/control/Replay.h
+++ b/src/control/Replay.h
@@ -192,7 +192,7 @@ class CReplay
int8 velocityX;
int8 velocityY;
int8 velocityZ;
- union{
+ union {
int8 car_gun;
int8 wheel_state;
};
@@ -205,68 +205,71 @@ class CReplay
static_assert(sizeof(tVehicleUpdatePacket) == 48, "tVehicleUpdatePacket: error");
private:
- static uint8 &Mode;
- static CAddressInReplayBuffer &Record;
- static CAddressInReplayBuffer &Playback;
- static uint8 *&pBuf0;
- static CAutomobile *&pBuf1;
- static uint8 *&pBuf2;
- static CPlayerPed *&pBuf3;
- static uint8 *&pBuf4;
- static CCutsceneHead *&pBuf5;
- static uint8 *&pBuf6;
- static CPtrNode *&pBuf7;
- static uint8 *&pBuf8;
- static CEntryInfoNode *&pBuf9;
- static uint8 *&pBuf10;
- static CDummyPed *&pBuf11;
- static uint8 *&pRadarBlips;
- static uint8 *&pStoredCam;
- static uint8 *&pWorld1;
- static CReference *&pEmptyReferences;
- static CStoredDetailedAnimationState *&pPedAnims;
- static uint8 *&pPickups;
- static uint8 *&pReferences;
- static uint8 (&BufferStatus)[NUM_REPLAYBUFFERS];
- static uint8 (&Buffers)[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
- static bool &bPlayingBackFromFile;
- static bool &bReplayEnabled;
- static uint32 &SlowMotion;
- static uint32 &FramesActiveLookAroundCam;
- static bool &bDoLoadSceneWhenDone;
- static CPtrList &WorldPtrList;
- static CPtrList &BigBuildingPtrList;
- static CWanted &PlayerWanted;
- static CPlayerInfo &PlayerInfo;
- static uint32 &Time1;
- static uint32 &Time2;
- static uint32 &Time3;
- static uint32 &Time4;
- static uint32 &Frame;
- static uint8 &ClockHours;
- static uint8 &ClockMinutes;
- static uint16 &OldWeatherType;
- static uint16 &NewWeatherType;
- static float &WeatherInterpolationValue;
- static float &TimeStepNonClipped;
- static float &TimeStep;
- static float &TimeScale;
- static float &CameraFixedX;
- static float &CameraFixedY;
- static float &CameraFixedZ;
- static int32 &OldRadioStation;
- static int8 &CameraMode;
- static bool &bAllowLookAroundCam;
- static float &LoadSceneX;
- static float &LoadSceneY;
- static float &LoadSceneZ;
- static float &CameraFocusX;
- static float &CameraFocusY;
- static float &CameraFocusZ;
- static bool &bPlayerInRCBuggy;
- static float &fDistanceLookAroundCam;
- static float &fAlphaAngleLookAroundCam;
- static float &fBetaAngleLookAroundCam;
+ static uint8 Mode;
+ static CAddressInReplayBuffer Record;
+ static CAddressInReplayBuffer Playback;
+ static uint8* pBuf0;
+ static CAutomobile* pBuf1;
+ static uint8* pBuf2;
+ static CPlayerPed* pBuf3;
+ static uint8* pBuf4;
+ static CCutsceneHead* pBuf5;
+ static uint8* pBuf6;
+ static CPtrNode* pBuf7;
+ static uint8* pBuf8;
+ static CEntryInfoNode* pBuf9;
+ static uint8* pBuf10;
+ static CDummyPed* pBuf11;
+ static uint8* pRadarBlips;
+ static uint8* pStoredCam;
+ static uint8* pWorld1;
+ static CReference* pEmptyReferences;
+ static CStoredDetailedAnimationState* pPedAnims;
+ static uint8* pPickups;
+ static uint8* pReferences;
+ static uint8 BufferStatus[NUM_REPLAYBUFFERS];
+ static uint8 Buffers[NUM_REPLAYBUFFERS][REPLAYBUFFERSIZE];
+ static bool bPlayingBackFromFile;
+ static bool bReplayEnabled;
+ static uint32 SlowMotion;
+ static uint32 FramesActiveLookAroundCam;
+ static bool bDoLoadSceneWhenDone;
+ static CPtrNode* WorldPtrList;
+ static CPtrNode* BigBuildingPtrList;
+ static CWanted PlayerWanted;
+ static CPlayerInfo PlayerInfo;
+ static uint32 Time1;
+ static uint32 Time2;
+ static uint32 Time3;
+ static uint32 Time4;
+ static uint32 Frame;
+ static uint8 ClockHours;
+ static uint8 ClockMinutes;
+ static uint16 OldWeatherType;
+ static uint16 NewWeatherType;
+ static float WeatherInterpolationValue;
+ static float TimeStepNonClipped;
+ static float TimeStep;
+ static float TimeScale;
+ static float CameraFixedX;
+ static float CameraFixedY;
+ static float CameraFixedZ;
+ static int32 OldRadioStation;
+ static int8 CameraMode;
+ static bool bAllowLookAroundCam;
+ static float LoadSceneX;
+ static float LoadSceneY;
+ static float LoadSceneZ;
+ static float CameraFocusX;
+ static float CameraFocusY;
+ static float CameraFocusZ;
+ static bool bPlayerInRCBuggy;
+ static float fDistanceLookAroundCam;
+ static float fAlphaAngleLookAroundCam;
+ static float fBetaAngleLookAroundCam;
+#ifdef FIX_BUGS
+ static int nHandleOfPlayerPed[NUMPLAYERS];
+#endif
public:
static void Init(void);
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 788a054a..2a31f8f1 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -1,25 +1,25 @@
#include "common.h"
-#include "patcher.h"
+
#include "Restart.h"
#include "Zones.h"
#include "PathFind.h"
-uint8 &CRestart::OverrideHospitalLevel = *(uint8*)0x95CD4C;
-uint8 &CRestart::OverridePoliceStationLevel = *(uint8*)0x95CD50;
-bool &CRestart::bFadeInAfterNextArrest = *(bool*)0x95CD69;
-bool &CRestart::bFadeInAfterNextDeath = *(bool*)0x95CD9D;
+uint8 CRestart::OverrideHospitalLevel;
+uint8 CRestart::OverridePoliceStationLevel;
+bool CRestart::bFadeInAfterNextArrest;
+bool CRestart::bFadeInAfterNextDeath;
-bool &CRestart::bOverrideRestart = *(bool*)0x95CD5D;
-CVector &CRestart::OverridePosition = *(CVector*)0x8E2C00;
-float &CRestart::OverrideHeading = *(float*)0x8F2A18;
+bool CRestart::bOverrideRestart;
+CVector CRestart::OverridePosition;
+float CRestart::OverrideHeading;
-CVector(&CRestart::HospitalRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x87F9B0;
-float(&CRestart::HospitalRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D40;
-uint16 &CRestart::NumberOfHospitalRestarts = *(uint16*)0x95CC46;
+CVector CRestart::HospitalRestartPoints[NUM_RESTART_POINTS];
+float CRestart::HospitalRestartHeadings[NUM_RESTART_POINTS];
+uint16 CRestart::NumberOfHospitalRestarts;
-CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x846228;
-float(&CRestart::PoliceRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D20;
-uint16 &CRestart::NumberOfPoliceRestarts = *(uint16*)0x95CC44;
+CVector CRestart::PoliceRestartPoints[NUM_RESTART_POINTS];
+float CRestart::PoliceRestartHeadings[NUM_RESTART_POINTS];
+uint16 CRestart::NumberOfPoliceRestarts;
void
CRestart::Initialise()
@@ -247,16 +247,3 @@ INITSAVEBUF
WriteSaveBuf(buf, OverridePoliceStationLevel);
VALIDATESAVEBUF(*size);
}
-
-
-STARTPATCHES
- InjectHook(0x435E20, &CRestart::Initialise, PATCH_JUMP);
- InjectHook(0x436100, &CRestart::AddHospitalRestartPoint, PATCH_JUMP);
- InjectHook(0x436150, &CRestart::AddPoliceRestartPoint, PATCH_JUMP);
- InjectHook(0x4366C0, &CRestart::OverrideNextRestart, PATCH_JUMP);
- InjectHook(0x4366F0, &CRestart::CancelOverrideRestart, PATCH_JUMP);
- InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP);
- InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP);
- InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP);
- InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/Restart.h b/src/control/Restart.h
index fb7806db..5d84c723 100644
--- a/src/control/Restart.h
+++ b/src/control/Restart.h
@@ -17,20 +17,20 @@ public:
static void LoadAllRestartPoints(uint8 *buf, uint32 size);
static void SaveAllRestartPoints(uint8 *buf, uint32 *size);
- static uint8 &OverrideHospitalLevel;
- static uint8 &OverridePoliceStationLevel;
- static bool &bFadeInAfterNextArrest;
- static bool &bFadeInAfterNextDeath;
-
- static bool &bOverrideRestart;
- static CVector &OverridePosition;
- static float &OverrideHeading;
-
- static CVector(&HospitalRestartPoints)[NUM_RESTART_POINTS];
- static float (&HospitalRestartHeadings)[NUM_RESTART_POINTS];
- static uint16 &NumberOfHospitalRestarts;
-
- static CVector (&PoliceRestartPoints)[NUM_RESTART_POINTS];
- static float (&PoliceRestartHeadings)[NUM_RESTART_POINTS];
- static uint16 &NumberOfPoliceRestarts;
+ static uint8 OverrideHospitalLevel;
+ static uint8 OverridePoliceStationLevel;
+ static bool bFadeInAfterNextArrest;
+ static bool bFadeInAfterNextDeath;
+
+ static bool bOverrideRestart;
+ static CVector OverridePosition;
+ static float OverrideHeading;
+
+ static CVector HospitalRestartPoints[NUM_RESTART_POINTS];
+ static float HospitalRestartHeadings[NUM_RESTART_POINTS];
+ static uint16 NumberOfHospitalRestarts;
+
+ static CVector PoliceRestartPoints[NUM_RESTART_POINTS];
+ static float PoliceRestartHeadings[NUM_RESTART_POINTS];
+ static uint16 NumberOfPoliceRestarts;
};
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index 9548bc0a..7fb0c211 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "RoadBlocks.h"
#include "PathFind.h"
#include "ModelIndices.h"
@@ -15,9 +15,9 @@
#include "CarCtrl.h"
#include "General.h"
-int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34;
-int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8;
-bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810;
+int16 CRoadBlocks::NumRoadBlocks;
+int16 CRoadBlocks::RoadBlockObjects[NUMROADBLOCKS];
+bool CRoadBlocks::InOrOut[NUMROADBLOCKS];
void
CRoadBlocks::Init(void)
@@ -195,9 +195,3 @@ CRoadBlocks::GenerateRoadBlocks(void)
}
}
}
-
-STARTPATCHES
- InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP);
- InjectHook(0x4376A0, &CRoadBlocks::GenerateRoadBlockCopsForCar, PATCH_JUMP);
- InjectHook(0x436FA0, &CRoadBlocks::GenerateRoadBlocks, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h
index 16e3a362..0f0c1882 100644
--- a/src/control/RoadBlocks.h
+++ b/src/control/RoadBlocks.h
@@ -6,9 +6,9 @@ class CVehicle;
class CRoadBlocks
{
public:
- static int16 (&NumRoadBlocks);
- static int16 (&RoadBlockObjects)[NUMROADBLOCKS];
- static bool (&InOrOut)[NUMROADBLOCKS];
+ static int16 NumRoadBlocks;
+ static int16 RoadBlockObjects[NUMROADBLOCKS];
+ static bool InOrOut[NUMROADBLOCKS];
static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode);
diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp
index 3e55d431..7f914a76 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -1,12 +1,1097 @@
#include "common.h"
-#include "patcher.h"
+
#include "SceneEdit.h"
-bool &CSceneEdit::m_bEditOn = *(bool*)0x95CD77;
-int32 &CSceneEdit::m_bCameraFollowActor = *(int*)0x940590;
-bool &CSceneEdit::m_bRecording = *(bool*)0x95CD1F;
-CVector &CSceneEdit::m_vecCurrentPosition = *(CVector*)0x943064;
-CVector &CSceneEdit::m_vecCamHeading = *(CVector*)0x942F8C;
+#include "Automobile.h"
+#include "Camera.h"
+#include "CarCtrl.h"
+#include "CivilianPed.h"
+#include "FileMgr.h"
+#include "Font.h"
+#include "ModelIndices.h"
+#include "ModelInfo.h"
+#include "Pad.h"
+#include "Ped.h"
+#include "Population.h"
+#include "Text.h"
+#include "Timecycle.h"
+#include "Streaming.h"
+#include "Vehicle.h"
+#include "WeaponInfo.h"
+#include "World.h"
+
+bool CSceneEdit::m_bEditOn;
+int32 CSceneEdit::m_bCameraFollowActor;
+bool CSceneEdit::m_bRecording;
+CVector CSceneEdit::m_vecCurrentPosition;
+CVector CSceneEdit::m_vecCamHeading;
+CVector CSceneEdit::m_vecGotoPosition;
+int32 CSceneEdit::m_nVehicle;
+int32 CSceneEdit::m_nVehicle2;
+int32 CSceneEdit::m_nActor;
+int32 CSceneEdit::m_nActor2;
+int32 CSceneEdit::m_nVehiclemodelId;
+int32 CSceneEdit::m_nPedmodelId;
+int16 CSceneEdit::m_nCurrentMovieCommand;
+int16 CSceneEdit::m_nNumActors;
+int16 CSceneEdit::m_nNumMovieCommands;
+int16 CSceneEdit::m_nCurrentCommand;
+int16 CSceneEdit::m_nCurrentVehicle;
+int16 CSceneEdit::m_nCurrentActor;
+int16 CSceneEdit::m_nWeaponType;
+bool CSceneEdit::m_bCommandActive;
+bool CSceneEdit::m_bActorSelected;
+bool CSceneEdit::m_bActor2Selected;
+bool CSceneEdit::m_bVehicleSelected;
+int16 CSceneEdit::m_nNumVehicles;
+CPed* CSceneEdit::pActors[NUM_ACTORS_IN_MOVIE];
+CVehicle* CSceneEdit::pVehicles[NUM_VEHICLES_IN_MOVIE];
+bool CSceneEdit::m_bDrawGotoArrow;
+CMovieCommand CSceneEdit::Movie[NUM_COMMANDS_IN_MOVIE];
+
+#define SHADOW_OFFSET (2.0f)
+#define ACTION_MESSAGE_X_RIGHT (60.0f)
+#define ACTION_MESSAGE_Y (8.0f)
+#define SELECTED_MESSAGE_X_RIGHT (60.0f)
+#define SELECTED_MESSAGE_Y (248.0f)
+#define COMMAND_NAME_X_RIGHT (60.0f)
+#define COMMAND_NAME_Y (38.0f)
+#define COMMAND_NAME_HEIGHT (16.0f)
+
+#define NUM_COMMANDS_TO_DRAW (9)
+
+static const char* pCommandStrings[] = {
+ "do-nothing", "New Actor", "Move Actor", "Select Actor", "Delete Actor",
+ "New Vehicle", "Move Vehicle", "Select Vehicle", "Delete Vehicle", "Give Weapon",
+ "Goto", "Goto (wait)", "Get In Car", "Get Out Car", "Kill",
+ "Flee", "Wait", "Position Camera", "Set Camera Target", "Select Camera Mode",
+ "Save Movie", "Load Movie", "Play Movie", "END"
+};
+
+static_assert(ARRAY_SIZE(pCommandStrings) == CSceneEdit::MOVIE_TOTAL_COMMANDS, "Scene edit: not all commands have names");
+
+static int32 NextValidModelId(int32 mi, int32 step)
+{
+ int32 result = -1;
+ int32 i = mi;
+ while (result == -1) {
+ i += step;
+ if (i < 0 || i > 5500) {
+ step = -step;
+ continue;
+ }
+ CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(i);
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo;
+ if (!pInfo)
+ continue;
+ if (pInfo->m_type == MITYPE_PED
+#ifdef FIX_BUGS
+ && !(i >= MI_SPECIAL01 && i <= MI_SPECIAL04)
+#endif
+ ||
+ pInfo->m_type == MITYPE_VEHICLE &&
+#ifdef FIX_BUGS
+ (pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR || pVehicleInfo->m_vehicleType == VEHICLE_TYPE_BOAT))
+#else // && and || priority failure it seems, also crashes on special models
+ pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR || pVehicleInfo->m_vehicleType == VEHICLE_TYPE_BOAT)
+#endif
+ result = i;
+ }
+ return result;
+}
+
+void CSceneEdit::LoadMovie(void)
+{
+ ReInitialise();
+ CFileMgr::SetDir("DATA");
+ int fid = CFileMgr::OpenFile("movie.dat", "r");
+#ifdef FIX_BUGS
+ if (fid >= 0)
+#endif
+ {
+ CFileMgr::Read(fid, (char*)&Movie, sizeof(Movie));
+ CFileMgr::Read(fid, (char*)&m_nNumMovieCommands, sizeof(m_nNumMovieCommands));
+ CFileMgr::CloseFile(fid);
+ }
+ CFileMgr::SetDir("");
+ m_bCommandActive = false;
+}
+
+void CSceneEdit::SaveMovie(void)
+{
+ CFileMgr::SetDir("DATA");
+ int fid = CFileMgr::OpenFileForWriting("movie.dat");
+ if (fid >= 0) {
+ CFileMgr::Write(fid, (char*)&Movie, sizeof(Movie));
+ CFileMgr::Write(fid, (char*)&m_nNumMovieCommands, sizeof(m_nNumMovieCommands));
+ CFileMgr::CloseFile(fid);
+ }
+ CFileMgr::SetDir("");
+ m_bCommandActive = false;
+}
+
+void CSceneEdit::Initialise(void)
+{
+ m_nActor = -1;
+ m_nActor2 = -1;
+ m_nVehicle = -1;
+ m_nVehicle2 = -1;
+ m_nCurrentCommand = MOVIE_NEW_ACTOR;
+ m_nVehiclemodelId = MI_INFERNUS;
+ m_nPedmodelId = MI_MALE01;
+ m_nNumVehicles = 0;
+ m_nNumActors = 0;
+ m_nNumMovieCommands = 0;
+ m_bCommandActive = false;
+ m_bRecording = true;
+ m_bEditOn = false;
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++)
+ pActors[i] = nil;
+ for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++)
+ pVehicles[i] = nil;
+ m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
+ m_bCameraFollowActor = false;
+ TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
+ m_bDrawGotoArrow = false;
+}
+
+void CSceneEdit::InitPlayback(void)
+{
+ m_nVehiclemodelId = MI_INFERNUS;
+ m_nPedmodelId = MI_MALE01;
+ m_bCommandActive = false;
+ m_nNumActors = 0;
+ m_nNumVehicles = 0;
+ m_nActor = -1;
+ m_nActor2 = -1;
+ m_nVehicle = -1;
+ m_nVehicle2 = -1;
+ TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
+ m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i]) {
+ CPopulation::RemovePed(pActors[i]);
+ pActors[i] = nil;
+ }
+ }
+ m_nCurrentActor = 0;
+ for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
+ if (pVehicles[i]) {
+ CWorld::Remove(pVehicles[i]);
+ delete pVehicles[i];
+ pVehicles[i] = nil;
+ }
+ }
+ m_nCurrentVehicle = 0;
+ m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
+ m_nCurrentMovieCommand = MOVIE_DO_NOTHING;
+ m_bDrawGotoArrow = false;
+}
+
+void CSceneEdit::ReInitialise(void)
+{
+ m_nVehiclemodelId = MI_INFERNUS;
+ m_nPedmodelId = MI_MALE01;
+ m_nCurrentCommand = MOVIE_NEW_ACTOR;
+ m_bEditOn = true;
+ m_bRecording = true;
+ m_bCommandActive = false;
+#ifdef FIX_BUGS
+ m_bCameraFollowActor = false;
+ TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true; // not enough...
+#endif
+ m_nActor = -1;
+ m_nActor2 = -1;
+ m_nVehicle = -1;
+ m_nVehicle2 = -1;
+ m_nNumMovieCommands = 0;
+ m_nCurrentMovieCommand = MOVIE_DO_NOTHING;
+ m_nNumActors = 0;
+ m_nNumVehicles = 0;
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i]) {
+ CPopulation::RemovePed(pActors[i]);
+ pActors[i] = nil;
+ }
+ }
+ for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
+ if (pVehicles[i]) {
+ CWorld::Remove(pVehicles[i]);
+ delete pVehicles[i];
+ pVehicles[i] = nil;
+ }
+ }
+ for (int i = 0; i < NUM_COMMANDS_IN_MOVIE; i++) {
+ Movie[i].m_nCommandId = MOVIE_DO_NOTHING;
+ Movie[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
+ Movie[i].m_vecCamera = CVector(0.0f, 0.0f, 0.0f);
+ Movie[i].m_nActorId = -1;
+ Movie[i].m_nActor2Id = -1;
+ Movie[i].m_nVehicleId = -1;
+ Movie[i].m_nModelIndex = 0;
+ }
+ m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
+ m_bDrawGotoArrow = false;
+}
+
+void CSceneEdit::Update(void)
+{
+ if (!m_bEditOn)
+ return;
+ if (m_bRecording)
+ ProcessCommand();
+ else {
+ if (m_bCameraFollowActor && m_nActor != -1) {
+ if (pActors[m_nActor]->bInVehicle)
+ TheCamera.TakeControl(pActors[m_nActor]->m_pMyVehicle, CCam::MODE_BEHINDCAR, JUMP_CUT, CAMCONTROL_SCRIPT);
+ else
+ TheCamera.TakeControl(pActors[m_nActor], CCam::MODE_FOLLOWPED, JUMP_CUT, CAMCONTROL_SCRIPT);
+ }
+ PlayBack();
+ }
+}
+
+void CSceneEdit::Draw(void)
+{
+ char str[200];
+ wchar wstr[200];
+ if (TheCamera.m_WideScreenOn)
+ return;
+#ifndef FIX_BUGS
+ CFont::SetPropOff();
+#endif
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetCentreOn();
+ CFont::SetRightJustifyOn();
+ CFont::SetRightJustifyWrap(0.0f);
+ CFont::SetBackGroundOnlyTextOff();
+#ifdef FIX_BUGS
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetPropOn();
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetDropShadowPosition(1);
+#else
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetPropOff();
+#endif
+ sprintf(str, "Action");
+ AsciiToUnicode(str, wstr);
+ CFont::SetColor(CRGBA(0, 0, 0, 0));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(ACTION_MESSAGE_Y + SHADOW_OFFSET), wstr);
+ CFont::SetColor(CRGBA(193, 164, 120, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(ACTION_MESSAGE_Y), wstr);
+ sprintf(str, "Selected");
+ AsciiToUnicode(str, wstr);
+ CFont::SetColor(CRGBA(0, 0, 0, 0));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y + SHADOW_OFFSET), wstr);
+ CFont::SetColor(CRGBA(193, 164, 120, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y), wstr);
+ CFont::SetCentreOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.7f));
+#ifdef FIX_BUGS
+ CFont::SetFontStyle(FONT_BANK);
+#else
+ CFont::SetFontStyle(FONT_HEADING);
+#endif
+ CFont::SetColor(CRGBA(0, 0, 0, 0));
+ for (int i = 0; i < NUM_COMMANDS_TO_DRAW; i++) {
+ int16 nCommandDrawn = m_nCurrentCommand + i - NUM_COMMANDS_TO_DRAW / 2;
+ if (nCommandDrawn >= MOVIE_TOTAL_COMMANDS)
+ nCommandDrawn -= (MOVIE_TOTAL_COMMANDS - 1);
+ if (nCommandDrawn <= MOVIE_DO_NOTHING)
+ nCommandDrawn += (MOVIE_TOTAL_COMMANDS - 1);
+ sprintf(str, pCommandStrings[nCommandDrawn]);
+ AsciiToUnicode(str, wstr);
+ CFont::SetColor(CRGBA(0, 0, 0, 0));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(COMMAND_NAME_Y + SHADOW_OFFSET + i * COMMAND_NAME_HEIGHT), wstr);
+ if (nCommandDrawn == m_nCurrentCommand)
+ CFont::SetColor(CRGBA(156, 91, 40, 255));
+ else
+ CFont::SetColor(CRGBA(193, 164, 120, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT), SCREEN_SCALE_Y(COMMAND_NAME_Y + i * COMMAND_NAME_HEIGHT), wstr);
+ }
+}
+
+void CSceneEdit::ProcessCommand(void)
+{
+ if (!m_bCommandActive) {
+ ClearForNewCommand();
+ if (CPad::GetPad(1)->GetDPadUpJustDown()) {
+ if (--m_nCurrentCommand == MOVIE_DO_NOTHING)
+ m_nCurrentCommand = MOVIE_END;
+ }
+ if (CPad::GetPad(1)->GetDPadDownJustDown()) {
+ if (++m_nCurrentCommand == MOVIE_TOTAL_COMMANDS)
+ m_nCurrentCommand = MOVIE_NEW_ACTOR;
+ }
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ if (m_nCurrentCommand != MOVIE_DO_NOTHING)
+ m_bCommandActive = true;
+ }
+ return;
+ }
+ switch (m_nCurrentCommand) {
+ case MOVIE_DO_NOTHING:
+ m_bCommandActive = false;
+ break;
+ case MOVIE_NEW_ACTOR:
+ if (m_nActor == -1) {
+ if (m_nNumActors == NUM_ACTORS_IN_MOVIE)
+ break;
+ if (!CStreaming::HasModelLoaded(m_nPedmodelId)) {
+ CStreaming::RequestModel(m_nPedmodelId, 0);
+#ifdef FIX_BUGS
+ CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
+#endif
+ break;
+ }
+ CPed* pPed = new CCivilianPed(PEDTYPE_SPECIAL, m_nPedmodelId);
+ pPed->CharCreatedBy = MISSION_CHAR;
+ pPed->GetPosition() = m_vecCurrentPosition;
+ pPed->SetOrientation(0.0f, 0.0f, 0.0f);
+ CWorld::Add(pPed);
+ pPed->bUsesCollision = false;
+ pPed->bAffectedByGravity = false;
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i] == nil) {
+ m_nActor = i;
+ pActors[i] = pPed;
+ break;
+ }
+ }
+ }
+ else {
+ pActors[m_nActor]->GetPosition() = m_vecCurrentPosition;
+ pActors[m_nActor]->SetOrientation(0.0f, 0.0f, 0.0f);
+ int32 mi = m_nPedmodelId;
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown())
+ mi = NextValidModelId(m_nPedmodelId, -1);
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown())
+ mi = NextValidModelId(m_nPedmodelId, 1);
+ if (mi == m_nPedmodelId) {
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ pActors[m_nActor]->bUsesCollision = true;
+ pActors[m_nActor]->bAffectedByGravity = true;
+ ++m_nNumActors;
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_NEW_ACTOR;
+ Movie[m_nNumMovieCommands].m_vecPosition = m_vecCurrentPosition;
+ Movie[m_nNumMovieCommands].m_nModelIndex = m_nPedmodelId;
+ Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ CWorld::Remove(pActors[m_nActor]);
+ delete pActors[m_nActor];
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ }
+ else {
+ m_nPedmodelId = mi;
+ if (pActors[m_nActor]) {
+ CWorld::Remove(pActors[m_nActor]);
+ delete pActors[m_nActor];
+ }
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ }
+ }
+ break;
+ case MOVIE_MOVE_ACTOR:
+ SelectActor();
+ if (m_bCommandActive)
+ break;
+ pActors[m_nActor]->GetPosition() = m_vecCurrentPosition;
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bCommandActive = false;
+#ifndef FIX_BUGS // why? it crashes, also makes no sense
+ pActors[m_nActor] = nil;
+#endif
+ SelectActor();
+ }
+ break;
+ case MOVIE_SELECT_ACTOR:
+ SelectActor();
+ break;
+ case MOVIE_DELETE_ACTOR:
+ SelectActor();
+ if (m_bActorSelected) {
+ CPopulation::RemovePed(pActors[m_nActor]);
+ m_nCurrentActor = 0;
+ --m_nNumActors;
+#ifdef FIX_BUGS
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+#else
+ m_nActor = -1;
+ pActors[m_nActor] = nil;
+#endif
+ SelectActor();
+ m_bCommandActive = false;
+ }
+ else if (CPad::GetPad(1)->GetCircleJustDown()) {
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_NEW_VEHICLE:
+ if (m_nVehicle == -1) {
+ if (m_nNumVehicles == NUM_VEHICLES_IN_MOVIE)
+ break;
+ if (!CStreaming::HasModelLoaded(m_nVehiclemodelId)) {
+ CStreaming::RequestModel(m_nVehiclemodelId, 0);
+#ifdef FIX_BUGS
+ CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
+#endif
+ break;
+ }
+ CVehicle* pVehicle = new CAutomobile(m_nVehiclemodelId, MISSION_VEHICLE);
+ pVehicle->m_status = STATUS_PHYSICS;
+ pVehicle->GetPosition() = m_vecCurrentPosition;
+ pVehicle->SetOrientation(0.0f, 0.0f, 0.0f);
+ CWorld::Add(pVehicle);
+ pVehicle->bUsesCollision = false;
+ pVehicle->bAffectedByGravity = false;
+ for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
+ if (pVehicles[i] == nil) {
+ m_nVehicle = i;
+ pVehicles[i] = pVehicle;
+ break;
+ }
+ }
+ }
+ else {
+ pVehicles[m_nVehicle]->GetPosition() = m_vecCurrentPosition;
+ pVehicles[m_nVehicle]->SetOrientation(0.0f, 0.0f, 0.0f);
+ int32 mi = m_nVehiclemodelId;
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown())
+ mi = NextValidModelId(m_nVehiclemodelId, -1);
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown())
+ mi = NextValidModelId(m_nVehiclemodelId, 1);
+ if (mi == m_nVehiclemodelId) {
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ pVehicles[m_nVehicle]->bUsesCollision = true;
+ pVehicles[m_nVehicle]->bAffectedByGravity = true;
+ ++m_nNumVehicles;
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_NEW_VEHICLE;
+ Movie[m_nNumMovieCommands].m_vecPosition = m_vecCurrentPosition;
+ Movie[m_nNumMovieCommands].m_nModelIndex = m_nVehiclemodelId;
+ Movie[m_nNumMovieCommands++].m_nVehicleId = m_nVehicle;
+ m_nVehicle = -1;
+ m_bCommandActive = false;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ CWorld::Remove(pVehicles[m_nVehicle]);
+ delete pVehicles[m_nVehicle];
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ m_bCommandActive = false;
+ }
+ }
+ else {
+ m_nVehiclemodelId = mi;
+ if (pVehicles[m_nVehicle]) {
+ CWorld::Remove(pVehicles[m_nVehicle]);
+ delete pVehicles[m_nVehicle];
+ }
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ }
+ }
+ break;
+ case MOVIE_MOVE_VEHICLE:
+ SelectVehicle();
+ if (m_bCommandActive)
+ break;
+ pVehicles[m_nVehicle]->GetPosition() = m_vecCurrentPosition;
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bCommandActive = false;
+#ifndef FIX_BUGS // again, why? works wrong
+ pVehicles[m_nVehicle] = nil;
+#endif
+ m_nVehicle = -1;
+ }
+ break;
+ case MOVIE_SELECT_VEHICLE:
+ SelectVehicle();
+ break;
+ case MOVIE_DELETE_VEHICLE:
+ SelectVehicle();
+ if (m_bVehicleSelected) {
+ CWorld::Remove(pVehicles[m_nVehicle]);
+ delete pVehicles[m_nVehicle];
+ m_nCurrentVehicle = 0;
+ --m_nNumVehicles;
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ SelectVehicle();
+ m_bCommandActive = false;
+ }
+ else if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_GIVE_WEAPON:
+ if (m_bActorSelected) {
+ if (SelectWeapon()) {
+ m_bCommandActive = false;
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GIVE_WEAPON;
+ Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
+ Movie[m_nNumMovieCommands++].m_nModelIndex = m_nWeaponType;
+ }
+ }
+ else {
+ SelectActor();
+ m_bCommandActive = true;
+ }
+ break;
+ case MOVIE_GOTO:
+ case MOVIE_GOTO_WAIT:
+ if (!m_bActorSelected) {
+ m_bDrawGotoArrow = true;
+ SelectActor();
+ if (m_nActor == -1)
+ m_bCommandActive = true;
+ }
+ else {
+ m_vecGotoPosition = m_vecCurrentPosition;
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ if (pActors[m_nActor]->bInVehicle) {
+ if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pActors[m_nActor]->m_pMyVehicle, m_vecGotoPosition, false))
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
+ else
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
+ pActors[m_nActor]->m_pMyVehicle->m_status = STATUS_PHYSICS;
+ pActors[m_nActor]->m_pMyVehicle->bEngineOn = true;
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed = Max(16, pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed);
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
+ TheCamera.TakeControl(pActors[m_nActor]->m_pMyVehicle, CCam::MODE_BEHINDCAR, JUMP_CUT, CAMCONTROL_SCRIPT);
+ }
+ else {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_vecGotoPosition);
+ TheCamera.TakeControl(pActors[m_nActor], CCam::MODE_FOLLOWPED, JUMP_CUT, CAMCONTROL_SCRIPT);
+ }
+ m_bDrawGotoArrow = false;
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GOTO;
+ Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
+ Movie[m_nNumMovieCommands++].m_vecPosition = m_vecGotoPosition;
+ }
+ if (!m_bDrawGotoArrow) {
+ if (pActors[m_nActor]->bInVehicle && pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_NONE ||
+ !pActors[m_nActor]->bInVehicle && pActors[m_nActor]->m_objective == OBJECTIVE_NONE) {
+ if (pActors[m_nActor]) // if there is something that requires this check the least, it's this one
+ m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].Source;
+ m_bCommandActive = false;
+ TheCamera.Cams[TheCamera.ActiveCam].Mode = CCam::MODE_FIGHT_CAM_RUNABOUT;
+ m_vecCurrentPosition = pActors[m_nActor]->GetPosition();
+ pActors[m_nActor]->SetObjective(OBJECTIVE_NONE);
+ if (pActors[m_nActor]->bInVehicle)
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ }
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ }
+ break;
+ case MOVIE_GET_IN_CAR:
+ if (m_bActorSelected)
+ SelectVehicle();
+ else {
+ SelectActor();
+ if (m_nActor != -1)
+ m_bCommandActive = true;
+ }
+ if (m_bVehicleSelected) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicles[m_nVehicle]);
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GET_IN_CAR;
+ Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
+ Movie[m_nNumMovieCommands++].m_nVehicleId = m_nVehicle;
+ m_nVehicle = -1;
+ m_bCommandActive = false;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_GET_OUT_CAR:
+ SelectActor();
+ if (m_bActorSelected) {
+ if (pActors[m_nActor]->bInVehicle) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_LEAVE_VEHICLE);
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GET_OUT_CAR;
+ Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
+ }
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pVehicles[m_nVehicle] = nil;
+ m_nVehicle = -1;
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_KILL:
+ if (!m_bActorSelected) {
+ SelectActor();
+ m_bCommandActive = true;
+ }
+ else if (!m_bActor2Selected) {
+ SelectActor2();
+ if (m_bActorSelected && m_bActor2Selected && m_nActor != -1 && m_nActor2 != -1 && m_nActor != m_nActor2) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pActors[m_nActor2]);
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_KILL;
+ Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
+ Movie[m_nNumMovieCommands++].m_nActor2Id = m_nActor2;
+ m_bCommandActive = false;
+ }
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ pActors[m_nActor2] = nil;
+ m_nActor2 = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_FLEE:
+ if (!m_bActorSelected) {
+ SelectActor();
+ m_bCommandActive = true;
+ }
+ else if (!m_bActor2Selected) {
+ SelectActor2();
+ if (m_bActorSelected && m_bActor2Selected && m_nActor != -1 && m_nActor2 != -1 && m_nActor != m_nActor2) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pActors[m_nActor2]);
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_FLEE;
+ Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
+ Movie[m_nNumMovieCommands++].m_nActor2Id = m_nActor2;
+ m_bCommandActive = false;
+ }
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ pActors[m_nActor2] = nil;
+ m_nActor2 = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_WAIT:
+ SelectActor();
+ if (m_bActorSelected) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_IDLE);
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_WAIT;
+ Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pActors[m_nActor] = nil;
+ m_nActor = -1;
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_POSITION_CAMERA:
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_POSITION_CAMERA;
+ Movie[m_nNumMovieCommands].m_vecPosition = TheCamera.Cams[TheCamera.ActiveCam].Source;
+ Movie[m_nNumMovieCommands++].m_vecCamera = m_vecCamHeading;
+ m_bCommandActive = false;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ m_bCommandActive = false;
+ }
+ break;
+ case MOVIE_SET_CAMERA_TARGET:
+ if (!m_bActorSelected) {
+ SelectActor();
+ m_bCommandActive = true;
+ }
+ else {
+ TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity = pActors[m_nActor];
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_SET_CAMERA_TARGET;
+ Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
+ m_bCommandActive = false;
+ }
+ }
+ break;
+ case MOVIE_SELECT_CAMERA_MODE:
+ m_bCommandActive = false;
+ break;
+ case MOVIE_SAVE_MOVIE:
+ SaveMovie();
+ break;
+ case MOVIE_LOAD_MOVIE:
+ LoadMovie();
+ break;
+ case MOVIE_PLAY_MOVIE:
+ InitPlayback();
+ LoadMovie();
+ m_bRecording = false;
+ break;
+ case MOVIE_END:
+ m_bRecording = false;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+void CSceneEdit::PlayBack(void)
+{
+ m_nCurrentCommand = Movie[m_nCurrentMovieCommand].m_nCommandId;
+ if (m_nCurrentMovieCommand >= m_nNumMovieCommands) {
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_nCurrentCommand = MOVIE_DO_NOTHING;
+ m_bRecording = true;
+ ReInitialise();
+ }
+ return;
+ }
+ switch (m_nCurrentCommand) {
+ case MOVIE_DO_NOTHING:
+ case MOVIE_MOVE_ACTOR:
+ case MOVIE_SELECT_ACTOR:
+ case MOVIE_DELETE_ACTOR:
+ case MOVIE_MOVE_VEHICLE:
+ case MOVIE_SELECT_VEHICLE:
+ case MOVIE_DELETE_VEHICLE:
+ break;
+ case MOVIE_NEW_ACTOR:
+ {
+ m_nPedmodelId = Movie[m_nCurrentMovieCommand].m_nModelIndex;
+ m_vecCurrentPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
+ if (!CStreaming::HasModelLoaded(m_nPedmodelId)) {
+ CStreaming::RequestModel(m_nPedmodelId, 0);
+#ifdef FIX_BUGS
+ CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
+#endif
+ break;
+ }
+ CPed* pPed = new CCivilianPed(PEDTYPE_SPECIAL, m_nPedmodelId);
+ pPed->CharCreatedBy = MISSION_CHAR;
+ CWorld::Add(pPed);
+ pPed->GetPosition() = m_vecCurrentPosition;
+ pPed->SetOrientation(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i] == nil) {
+ m_nActor = i;
+ pActors[i] = pPed;
+ break;
+ }
+ }
+ m_nNumActors++;
+ m_nCurrentMovieCommand++;
+ break;
+ }
+ case MOVIE_NEW_VEHICLE:
+ {
+ m_nVehiclemodelId = Movie[m_nCurrentMovieCommand].m_nModelIndex;
+ m_vecCurrentPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
+ if (!CStreaming::HasModelLoaded(m_nVehiclemodelId)) {
+ CStreaming::RequestModel(m_nVehiclemodelId, 0);
+#ifdef FIX_BUGS
+ CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
+#endif
+ break;
+ }
+ CVehicle* pVehicle = new CAutomobile(m_nVehiclemodelId, MISSION_VEHICLE);
+ pVehicle->m_status = STATUS_PHYSICS;
+ pVehicle->GetPosition() = m_vecCurrentPosition;
+ pVehicle->SetOrientation(0.0f, 0.0f, 0.0f);
+ CWorld::Add(pVehicle);
+ for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
+ if (pVehicles[i] == nil) {
+ m_nVehicle = i;
+ pVehicles[i] = pVehicle;
+ break;
+ }
+ }
+ m_nNumVehicles++;
+ m_nCurrentMovieCommand++;
+ break;
+ }
+ case MOVIE_GIVE_WEAPON:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ m_nWeaponType = Movie[m_nCurrentMovieCommand].m_nModelIndex;
+ pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
+ pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
+ pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
+ m_nCurrentMovieCommand++;
+ break;
+ case MOVIE_GOTO:
+ case MOVIE_GOTO_WAIT:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ m_vecGotoPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
+ if (pActors[m_nActor]->bInVehicle) {
+ if (pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS &&
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS_STRAIGHT) {
+ if ((pActors[m_nActor]->m_pMyVehicle->GetPosition() - m_vecGotoPosition).Magnitude() < 5.0f) {
+ if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pActors[m_nActor]->m_pMyVehicle, m_vecGotoPosition, false))
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
+ else
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
+ pActors[m_nActor]->m_pMyVehicle->m_status = STATUS_PHYSICS;
+ pActors[m_nActor]->m_pMyVehicle->bEngineOn = true;
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed = Max(16, pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed);
+ pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
+ if (m_nCurrentCommand != MOVIE_GOTO_WAIT)
+ ++m_nCurrentMovieCommand;
+ }
+ else
+ ++m_nCurrentMovieCommand;
+ }
+ }
+ else {
+ if (pActors[m_nActor]->m_objective != OBJECTIVE_GOTO_AREA_ON_FOOT) {
+ pActors[m_nActor]->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_vecGotoPosition);
+ ++m_nCurrentMovieCommand;
+ }
+ }
+ break;
+ case MOVIE_GET_IN_CAR:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ if (!pActors[m_nActor]->bInVehicle){
+ m_nVehicle = Movie[m_nCurrentMovieCommand].m_nVehicleId;
+ pActors[m_nActor]->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicles[m_nVehicle]);
+ }
+ else
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_GET_OUT_CAR:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ if (pActors[m_nActor]->bInVehicle)
+ pActors[m_nActor]->SetObjective(OBJECTIVE_LEAVE_VEHICLE);
+ else
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_KILL:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ m_nActor2 = Movie[m_nCurrentMovieCommand].m_nActor2Id;
+ pActors[m_nActor]->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pActors[m_nActor2]);
+ if (pActors[m_nActor2]->GetPedState() == PED_DEAD)
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_FLEE:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ m_nActor2 = Movie[m_nCurrentMovieCommand].m_nActor2Id;
+ pActors[m_nActor]->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pActors[m_nActor2]);
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_WAIT:
+ m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
+ pActors[m_nActor]->SetObjective(OBJECTIVE_IDLE);
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_POSITION_CAMERA:
+ TheCamera.Cams[TheCamera.ActiveCam].Source = Movie[m_nCurrentMovieCommand].m_vecPosition;
+ m_vecCamHeading = Movie[m_nCurrentMovieCommand].m_vecCamera;
+ TheCamera.Cams[TheCamera.ActiveCam].Front = m_vecCamHeading;
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_SET_CAMERA_TARGET:
+ m_bCameraFollowActor = true;
+ TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity = pActors[Movie[m_nNumMovieCommands].m_nActorId];
+ TheCamera.pTargetEntity = pActors[Movie[m_nNumMovieCommands].m_nActorId];
+ TheCamera.m_bLookingAtPlayer = false;
+ ++m_nCurrentMovieCommand;
+ break;
+ case MOVIE_SELECT_CAMERA_MODE:
+ m_bCommandActive = false; // this is wrong
+ break;
+ }
+}
+
+void CSceneEdit::ClearForNewCommand(void)
+{
+ m_nActor = -1;
+ m_nActor2 = -1;
+ m_nVehicle = -1;
+ m_bActorSelected = false;
+ m_bActor2Selected = false;
+ m_bVehicleSelected = false;
+ m_bDrawGotoArrow = false;
+}
+void CSceneEdit::SelectActor(void)
+{
+ m_bActorSelected = false;
+ if (m_nActor != -1) {
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
+ CPed* pPed;
+ do {
+ if (--m_nActor < 0)
+ m_nActor = NUM_ACTORS_IN_MOVIE - 1;
+ pPed = pActors[m_nActor];
+ } while (pPed == nil);
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
+ }
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
+ CPed* pPed;
+ do {
+ if (++m_nActor == NUM_ACTORS_IN_MOVIE)
+ m_nActor = 0;
+ pPed = pActors[m_nActor];
+ } while (pPed == nil);
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
+ }
+ m_vecCurrentPosition = pActors[m_nActor]->GetPosition();
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bActorSelected = true;
+ m_bCommandActive = false;
+ }
+ else if (CPad::GetPad(1)->GetCircleJustDown()) {
+ m_nActor = -1;
+ }
+ }
+ else if (m_nNumActors != 0) {
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i] != nil) {
+ m_nActor = i;
+ break;
+ }
+ }
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pActors[m_nActor]->GetPosition() - m_vecCamHeading;
+ if (m_nNumActors == 1) {
+ m_bActorSelected = true;
+ m_bCommandActive = false;
+ }
+ }
+ else {
+ m_bCommandActive = false;
+ }
+}
+
+void CSceneEdit::SelectActor2(void)
+{
+ m_bActor2Selected = false;
+ if (m_nNumActors <= 1) {
+ m_bCommandActive = false;
+ return;
+ }
+ if (m_nActor2 != -1) {
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
+ CPed* pPed;
+ do {
+ if (--m_nActor2 < 0)
+ m_nActor2 = NUM_ACTORS_IN_MOVIE - 1;
+ pPed = pActors[m_nActor2];
+ } while (pPed == nil || pPed == pActors[m_nActor]);
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
+ }
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
+ CPed* pPed;
+ do {
+ if (++m_nActor2 == NUM_ACTORS_IN_MOVIE)
+ m_nActor2 = 0;
+ pPed = pActors[m_nActor2];
+ } while (pPed == nil || pPed == pActors[m_nActor]);
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
+ }
+ m_vecCurrentPosition = pActors[m_nActor2]->GetPosition();
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bActor2Selected = true;
+ m_bCommandActive = false;
+ }
+ else if (CPad::GetPad(1)->GetCircleJustDown()) {
+ m_nActor2 = -1;
+ }
+ }
+ else {
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pActors[i] != nil && pActors[m_nActor] != pActors[i] ) {
+ m_nActor2 = i;
+ break;
+ }
+ }
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pActors[m_nActor2]->GetPosition() - m_vecCamHeading;
+ }
+}
+
+void CSceneEdit::SelectVehicle(void)
+{
+ m_bVehicleSelected = false;
+ if (m_nVehicle != -1) {
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
+ CVehicle* pVehicle;
+ do {
+ if (--m_nVehicle < 0)
+ m_nVehicle = NUM_VEHICLES_IN_MOVIE - 1;
+ pVehicle = pVehicles[m_nVehicle];
+ } while (pVehicle == nil);
+ }
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
+ CVehicle* pVehicle;
+ do {
+ if (++m_nVehicle == NUM_VEHICLES_IN_MOVIE)
+ m_nVehicle = 0;
+ pVehicle = pVehicles[m_nVehicle];
+ } while (pVehicle == nil);
+ }
+ m_vecCurrentPosition = pVehicles[m_nVehicle]->GetPosition();
+ TheCamera.Cams[TheCamera.ActiveCam].Source = pVehicles[m_nVehicle]->GetPosition() - m_vecCamHeading;
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bVehicleSelected = true;
+ m_bCommandActive = false;
+ }
+ else if (CPad::GetPad(1)->GetCircleJustDown()) {
+ m_nVehicle = -1;
+ }
+ }
+ else if (m_nNumVehicles != 0) {
+ for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
+ if (pVehicles[i] != nil) {
+ m_nVehicle = i;
+ break;
+ }
+ }
+ }
+}
-WRAPPER void CSceneEdit::Update(void) { EAXJMP(0x585570); }
-WRAPPER void CSceneEdit::Init(void) { EAXJMP(0x585170); }
+bool CSceneEdit::SelectWeapon(void)
+{
+ if (m_nWeaponType == WEAPONTYPE_UNARMED) {
+ m_nWeaponType = WEAPONTYPE_COLT45;
+ return false;
+ }
+ if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
+ if (++m_nWeaponType >= WEAPONTYPE_DETONATOR)
+ m_nWeaponType = WEAPONTYPE_BASEBALLBAT;
+ pActors[m_nActor]->ClearWeapons();
+ pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
+ pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
+ pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
+ }
+ else if (CPad::GetPad(1)->GetRightShoulder1JustDown()){
+ if (--m_nWeaponType <= WEAPONTYPE_UNARMED)
+ m_nWeaponType = WEAPONTYPE_GRENADE;
+ pActors[m_nActor]->ClearWeapons();
+ pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
+ pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
+ pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
+ }
+ if (CPad::GetPad(1)->GetTriangleJustDown()) {
+ m_bCommandActive = false;
+ return true;
+ }
+ if (CPad::GetPad(1)->GetCircleJustDown()) {
+ pActors[m_nActor]->ClearWeapons();
+ m_nWeaponType = WEAPONTYPE_UNARMED;
+ m_bCommandActive = false;
+ return false;
+ }
+ return false;
+} \ No newline at end of file
diff --git a/src/control/SceneEdit.h b/src/control/SceneEdit.h
index 0de72c19..6dcefa31 100644
--- a/src/control/SceneEdit.h
+++ b/src/control/SceneEdit.h
@@ -1,14 +1,95 @@
#pragma once
+class CPed;
+class CVehicle;
+
+struct CMovieCommand
+{
+ int32 m_nCommandId;
+ CVector m_vecPosition;
+ CVector m_vecCamera;
+ int16 m_nActorId;
+ int16 m_nActor2Id;
+ int16 m_nVehicleId;
+ int16 m_nModelIndex;
+};
+
class CSceneEdit
{
public:
- static bool &m_bEditOn;
- static int32 &m_bCameraFollowActor;
- static bool &m_bRecording;
- static CVector &m_vecCurrentPosition;
- static CVector &m_vecCamHeading;
+ enum {
+ MOVIE_DO_NOTHING = 0,
+ MOVIE_NEW_ACTOR,
+ MOVIE_MOVE_ACTOR,
+ MOVIE_SELECT_ACTOR,
+ MOVIE_DELETE_ACTOR,
+ MOVIE_NEW_VEHICLE,
+ MOVIE_MOVE_VEHICLE,
+ MOVIE_SELECT_VEHICLE,
+ MOVIE_DELETE_VEHICLE,
+ MOVIE_GIVE_WEAPON,
+ MOVIE_GOTO,
+ MOVIE_GOTO_WAIT,
+ MOVIE_GET_IN_CAR,
+ MOVIE_GET_OUT_CAR,
+ MOVIE_KILL,
+ MOVIE_FLEE,
+ MOVIE_WAIT,
+ MOVIE_POSITION_CAMERA,
+ MOVIE_SET_CAMERA_TARGET,
+ MOVIE_SELECT_CAMERA_MODE,
+ MOVIE_SAVE_MOVIE,
+ MOVIE_LOAD_MOVIE,
+ MOVIE_PLAY_MOVIE,
+ MOVIE_END,
+ MOVIE_TOTAL_COMMANDS
+ };
+ enum {
+ NUM_ACTORS_IN_MOVIE = 5,
+ NUM_VEHICLES_IN_MOVIE = 5,
+ NUM_COMMANDS_IN_MOVIE = 20
+ };
+ static int32 m_bCameraFollowActor;
+ static CVector m_vecCurrentPosition;
+ static CVector m_vecCamHeading;
+ static CVector m_vecGotoPosition;
+ static int32 m_nVehicle;
+ static int32 m_nVehicle2;
+ static int32 m_nActor;
+ static int32 m_nActor2;
+ static int32 m_nVehiclemodelId;
+ static int32 m_nPedmodelId;
+ static int16 m_nCurrentMovieCommand;
+ static int16 m_nCurrentCommand;
+ static int16 m_nCurrentVehicle;
+ static int16 m_nCurrentActor;
+ static bool m_bEditOn;
+ static bool m_bRecording;
+ static bool m_bCommandActive;
+ static bool m_bActorSelected;
+ static bool m_bActor2Selected;
+ static bool m_bVehicleSelected;
+ static int16 m_nNumActors;
+ static int16 m_nNumVehicles;
+ static int16 m_nNumMovieCommands;
+ static int16 m_nWeaponType;
+ static CPed* pActors[NUM_ACTORS_IN_MOVIE];
+ static CVehicle* pVehicles[NUM_VEHICLES_IN_MOVIE];
+ static bool m_bDrawGotoArrow;
+ static CMovieCommand Movie[NUM_COMMANDS_IN_MOVIE];
+ static void LoadMovie(void);
+ static void SaveMovie(void);
+ static void Initialise(void);
+ static void InitPlayback(void);
+ static void ReInitialise(void);
static void Update(void);
- static void Init(void);
+ static void Draw(void);
+ static void ProcessCommand(void);
+ static void PlayBack(void);
+ static void ClearForNewCommand(void);
+ static void SelectActor(void);
+ static void SelectActor2(void);
+ static void SelectVehicle(void);
+ static bool SelectWeapon(void);
};
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 1f085d32..7ab40847 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -1,10 +1,10 @@
#define WITHWINDOWS // for our script loading hack
#include "common.h"
-#include "patcher.h"
#include "Script.h"
#include "ScriptCommands.h"
+#include "AnimBlendAssociation.h"
#include "Boat.h"
#include "BulletInfo.h"
#include "Camera.h"
@@ -18,11 +18,12 @@
#include "Cranes.h"
#include "Credits.h"
#include "CutsceneMgr.h"
-#include "Darkel.h"
#include "DMAudio.h"
+#include "Darkel.h"
#include "EmergencyPed.h"
#include "Explosion.h"
#include "FileMgr.h"
+#include "Fire.h"
#include "Frontend.h"
#include "Gangs.h"
#include "Garages.h"
@@ -31,7 +32,6 @@
#include "Heli.h"
#include "Hud.h"
#include "Lines.h"
-#include "main.h"
#include "Messages.h"
#include "ModelIndices.h"
#include "Pad.h"
@@ -48,13 +48,12 @@
#include "Population.h"
#include "PowerPoints.h"
#include "ProjectileInfo.h"
+#include "Radar.h"
#include "Record.h"
#include "Remote.h"
-#include "Restart.h"
#include "Replay.h"
+#include "Restart.h"
#include "RpAnimBlend.h"
-#include "AnimBlendAssociation.h"
-#include "Fire.h"
#include "Rubbish.h"
#include "Shadows.h"
#include "SpecialFX.h"
@@ -67,7 +66,7 @@
#include "Weather.h"
#include "World.h"
#include "Zones.h"
-#include "Radar.h"
+#include "main.h"
#define PICKUP_PLACEMENT_OFFSET 0.5f
#define PED_FIND_Z_OFFSET 5.0f
@@ -87,47 +86,47 @@
#define FEET_IN_METER 3.33f
#endif
-uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248;
-CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
-int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
-int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
-intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
-intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
-CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
-script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
-tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
-tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
-int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
-tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30;
-CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0;
-CStoredLine (&CTheScripts::aStoredLines)[MAX_NUM_STORED_LINES] = *(CStoredLine(*)[MAX_NUM_STORED_LINES])*(uintptr*)0x743018;
-bool &CTheScripts::DbgFlag = *(bool*)0x95CD87;
-uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F1B64;
-int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C;
-bool &CTheScripts::StoreVehicleWasRandom = *(bool*)0x95CDBC;
-CRunningScript *&CTheScripts::pIdleScripts = *(CRunningScript**)0x9430D4;
-CRunningScript *&CTheScripts::pActiveScripts = *(CRunningScript**)0x8E2BF4;
-uint32 &CTheScripts::NextFreeCollectiveIndex = *(uint32*)0x942F98;
-int32 &CTheScripts::LastRandomPedId = *(int32*)0x8F251C;
-uint16 &CTheScripts::NumberOfUsedObjects = *(uint16*)0x95CC72;
-bool &CTheScripts::bAlreadyRunningAMissionScript = *(bool*)0x95CDB3;
-bool &CTheScripts::bUsingAMultiScriptFile = *(bool*)0x95CD55;
-uint16 &CTheScripts::NumberOfMissionScripts = *(uint16*)0x95CC9A;
-uint32 &CTheScripts::LargestMissionScriptSize = *(uint32*)0x9414C8;
-uint32 &CTheScripts::MainScriptSize = *(uint32*)0x9405A4;
-uint8 &CTheScripts::FailCurrentMission = *(uint8*)0x95CD41;
-uint8 &CTheScripts::CountdownToMakePlayerUnsafe = *(uint8*)0x95CD51;
-uint8 &CTheScripts::DelayMakingPlayerUnsafeThisTime = *(uint8*)0x95CD88;
-uint16 &CTheScripts::NumScriptDebugLines = *(uint16*)0x95CC42;
-uint16 &CTheScripts::NumberOfIntroRectanglesThisFrame = *(uint16*)0x95CC88;
-uint16 &CTheScripts::NumberOfIntroTextLinesThisFrame = *(uint16*)0x95CC32;
-uint8 &CTheScripts::UseTextCommands = *(uint8*)0x95CD57;
-CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24;
-CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450;
-CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588;
-uint16 &CTheScripts::CommandsExecuted = *(uint16*)0x95CCA6;
-uint16 &CTheScripts::ScriptsUpdated = *(uint16*)0x95CC5E;
-int32(&ScriptParams)[32] = *(int32(*)[32])*(uintptr*)0x6ED460;
+uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE];
+CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS];
+int32 CTheScripts::BaseBriefIdForContact[MAX_NUM_CONTACTS];
+int32 CTheScripts::OnAMissionForContactFlag[MAX_NUM_CONTACTS];
+intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
+intro_script_rectangle CTheScripts::IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
+CSprite2d CTheScripts::ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
+script_sphere_struct CTheScripts::ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
+tCollectiveData CTheScripts::CollectiveArray[MAX_NUM_COLLECTIVES];
+tUsedObject CTheScripts::UsedObjectArray[MAX_NUM_USED_OBJECTS];
+int32 CTheScripts::MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
+tBuildingSwap CTheScripts::BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
+CEntity* CTheScripts::InvisibilitySettingArray[MAX_NUM_INVISIBILITY_SETTINGS];
+CStoredLine CTheScripts::aStoredLines[MAX_NUM_STORED_LINES];
+bool CTheScripts::DbgFlag;
+uint32 CTheScripts::OnAMissionFlag;
+int32 CTheScripts::StoreVehicleIndex;
+bool CTheScripts::StoreVehicleWasRandom;
+CRunningScript *CTheScripts::pIdleScripts;
+CRunningScript *CTheScripts::pActiveScripts;
+uint32 CTheScripts::NextFreeCollectiveIndex;
+int32 CTheScripts::LastRandomPedId;
+uint16 CTheScripts::NumberOfUsedObjects;
+bool CTheScripts::bAlreadyRunningAMissionScript;
+bool CTheScripts::bUsingAMultiScriptFile;
+uint16 CTheScripts::NumberOfMissionScripts;
+uint32 CTheScripts::LargestMissionScriptSize;
+uint32 CTheScripts::MainScriptSize;
+uint8 CTheScripts::FailCurrentMission;
+uint8 CTheScripts::CountdownToMakePlayerUnsafe;
+uint8 CTheScripts::DelayMakingPlayerUnsafeThisTime;
+uint16 CTheScripts::NumScriptDebugLines;
+uint16 CTheScripts::NumberOfIntroRectanglesThisFrame;
+uint16 CTheScripts::NumberOfIntroTextLinesThisFrame;
+uint8 CTheScripts::UseTextCommands;
+CMissionCleanup CTheScripts::MissionCleanup;
+CUpsideDownCarCheck CTheScripts::UpsideDownCars;
+CStuckCarCheck CTheScripts::StuckCars;
+uint16 CTheScripts::CommandsExecuted;
+uint16 CTheScripts::ScriptsUpdated;
+int32 ScriptParams[32];
CMissionCleanup::CMissionCleanup()
{
@@ -2010,7 +2009,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
car->m_status = STATUS_PHYSICS;
car->bEngineOn = true;
- car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6);
+ car->AutoPilot.m_nCruiseSpeed = Max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -2022,7 +2021,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CCarCtrl::JoinCarWithRoadSystem(car);
car->AutoPilot.m_nCarMission = MISSION_CRUISE;
car->bEngineOn = true;
- car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6);
+ car->AutoPilot.m_nCruiseSpeed = Max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -2106,7 +2105,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
- car->AutoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity);
+ car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity);
return 0;
}
case COMMAND_SET_CAR_DRIVING_STYLE:
@@ -3645,7 +3644,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = max(pos.x - infX, pos.y - infY);
+ float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos, radius);
return 0;
@@ -4151,7 +4150,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = max(pos.x - infX, pos.y - infY);
+ float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius);
return 0;
@@ -4947,7 +4946,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = max(pos.x - infX, pos.y - infY);
+ float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius);
return 0;
@@ -5369,7 +5368,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
pos.x = (infX + supX) / 2;
pos.y = (infY + supY) / 2;
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = max(pos.x - infX, pos.y - infY);
+ float radius = Max(pos.x - infX, pos.y - infY);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0;
@@ -5606,7 +5605,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE;
pVehicle->m_status = STATUS_PHYSICS;
pVehicle->bEngineOn = true;
- pVehicle->AutoPilot.m_nCruiseSpeed = max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
+ pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -5721,7 +5720,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->m_status = STATUS_PHYSICS;
- pBoat->AutoPilot.m_nCruiseSpeed = max(6, pBoat->AutoPilot.m_nCruiseSpeed);
+ pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed);
pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -6306,23 +6305,23 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
return 0;
case COMMAND_REGISTER_JUMP_DISTANCE:
CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpDistance = max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]);
+ CStats::MaximumJumpDistance = Max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]);
return 0;
case COMMAND_REGISTER_JUMP_HEIGHT:
CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpHeight = max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]);
+ CStats::MaximumJumpHeight = Max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]);
return 0;
case COMMAND_REGISTER_JUMP_FLIPS:
CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpFlips = max(CStats::MaximumJumpFlips, ScriptParams[0]);
+ CStats::MaximumJumpFlips = Max(CStats::MaximumJumpFlips, ScriptParams[0]);
return 0;
case COMMAND_REGISTER_JUMP_SPINS:
CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpSpins = max(CStats::MaximumJumpSpins, ScriptParams[0]);
+ CStats::MaximumJumpSpins = Max(CStats::MaximumJumpSpins, ScriptParams[0]);
return 0;
case COMMAND_REGISTER_JUMP_STUNT:
CollectParameters(&m_nIp, 1);
- CStats::BestStuntJump = max(CStats::BestStuntJump, ScriptParams[0]);
+ CStats::BestStuntJump = Max(CStats::BestStuntJump, ScriptParams[0]);
return 0;
case COMMAND_REGISTER_UNIQUE_JUMP_FOUND:
++CStats::NumberOfUniqueJumpsFound;
@@ -6436,9 +6435,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->FlagToDestroyWhenNextProcessed();
}
else if (CGame::nastyGame && pPed->IsPedInControl()) {
- RwMatrix tmp_rw;
- CPedIK::GetWorldMatrix(pPed->m_pFrames[PED_HEAD]->frame, &tmp_rw);
- pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, tmp_rw.pos, true);
+ pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true);
}
else {
pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
@@ -6451,9 +6448,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
assert(pPed);
if (CGame::nastyGame) {
- RwMatrix tmp_rw;
- CPedIK::GetWorldMatrix(pPed->m_pFrames[PED_HEAD]->frame, &tmp_rw);
- pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, tmp_rw.pos, true);
+ pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true);
}
else {
pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
@@ -6855,10 +6850,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
int16 collisions;
CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos,
- min(cp1.x, min(cp2.x, min(cp3.x, cp4.x))),
- min(cp1.y, min(cp2.y, min(cp3.y, cp4.y))),
- max(cp1.x, max(cp2.x, max(cp3.x, cp4.x))),
- max(cp1.y, max(cp2.y, max(cp3.y, cp4.y))),
+ Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
+ Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
+ Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
+ Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
&collisions, 2, nil, false, true, true, false, false);
if (collisions > 0)
obstacleInPath = true;
@@ -6909,11 +6904,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
int16 collisions;
- CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos,
- min(cp1.x, min(cp2.x, min(cp3.x, cp4.x))),
- min(cp1.y, min(cp2.y, min(cp3.y, cp4.y))),
- max(cp1.x, max(cp2.x, max(cp3.x, cp4.x))),
- max(cp1.y, max(cp2.y, max(cp3.y, cp4.y))),
+ CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, newPosition,
+ Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
+ Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
+ Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
+ Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
&collisions, 2, nil, false, true, true, false, false);
if (collisions > 0)
obstacleInPath = true;
@@ -7746,7 +7741,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float size = max(0.0f, *(float*)&ScriptParams[7]);
+ float size = Max(0.0f, *(float*)&ScriptParams[7]);
eParticleObjectType type = (eParticleObjectType)ScriptParams[0];
RwRGBA color;
if (type == POBJECT_SMOKE_TRAIL){
@@ -8931,7 +8926,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed);
if (ScriptParams[1])
- pPed->m_nZoneLevel = -1;
+ pPed->m_nZoneLevel = LEVEL_IGNORE;
else
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition());
return 0;
@@ -9130,7 +9125,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
if (ScriptParams[1])
- pVehicle->m_nZoneLevel = -1;
+ pVehicle->m_nZoneLevel = LEVEL_IGNORE;
else
pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(pVehicle->GetPosition());
return 0;
@@ -9147,7 +9142,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
{
- CollectParameters(&m_nIp, 2);
+ CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false);
@@ -10076,8 +10071,8 @@ void CRunningScript::LocatePlayerCarCommand(int32 command, uint32* pIp)
case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
result = !pPlayerInfo->m_pPed->bInVehicle;
break;
- case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
result = pPlayerInfo->m_pPed->bInVehicle;
break;
default:
@@ -11359,7 +11354,7 @@ VALIDATESAVEBUF(size)
void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity)
{
- static CColPoint aTempColPoints[32];
+ static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
int16 entities = 0;
CEntity* aEntities[16];
CWorld::FindObjectsKindaColliding(pos, pEntity->GetBoundRadius(), false, &entities, 16, aEntities, false, true, true, false, false);
@@ -11456,22 +11451,22 @@ void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, fl
supY = infY = Y;
X = (x2 + x3) / 2;
Y = (y2 + y3) / 2;
- infX = min(infX, X);
- supX = max(supX, X);
- infY = min(infY, Y);
- supY = max(supY, Y);
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
X = (x3 + x4) / 2;
Y = (y3 + y4) / 2;
- infX = min(infX, X);
- supX = max(supX, X);
- infY = min(infY, Y);
- supY = max(supY, Y);
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
X = (x4 + x1) / 2;
Y = (y4 + y1) / 2;
- infX = min(infX, X);
- supX = max(supX, X);
- infY = min(infY, Y);
- supY = max(supY, Y);
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
CVector center;
center.x = (infX + supX) / 2;
center.y = (infY + supY) / 2;
@@ -11626,17 +11621,3 @@ void CTheScripts::ReadMultiScriptFileOffsetsFromScript()
MultiScriptArray[i] = Read4BytesFromScript(&ip);
}
}
-
-STARTPATCHES
-InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
-InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
-InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
-InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
-InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
-InjectHook(0x44FD60, &CTheScripts::UndoEntityInvisibilitySettings, PATCH_JUMP);
-InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
-InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
-InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);
-InjectHook(0x453B30, &CTheScripts::LoadAllScripts, PATCH_JUMP);
-InjectHook(0x454060, &CTheScripts::ClearSpaceForMissionEntity, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/control/Script.h b/src/control/Script.h
index 4338bd18..2eed29fe 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -240,46 +240,46 @@ enum {
class CTheScripts
{
- static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE];
- static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
- static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
- static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
- static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
- static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
- static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
- static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
- static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
- static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
- static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
- static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS];
- static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS];
- static CStoredLine(&aStoredLines)[MAX_NUM_STORED_LINES];
- static bool &DbgFlag;
- static uint32 &OnAMissionFlag;
- static CMissionCleanup &MissionCleanup;
- static CStuckCarCheck &StuckCars;
- static CUpsideDownCarCheck &UpsideDownCars;
- static int32 &StoreVehicleIndex;
- static bool &StoreVehicleWasRandom;
- static CRunningScript *&pIdleScripts;
- static CRunningScript *&pActiveScripts;
- static uint32 &NextFreeCollectiveIndex;
- static int32 &LastRandomPedId;
- static uint16 &NumberOfUsedObjects;
- static bool &bAlreadyRunningAMissionScript;
- static bool &bUsingAMultiScriptFile;
- static uint16 &NumberOfMissionScripts;
- static uint32 &LargestMissionScriptSize;
- static uint32 &MainScriptSize;
- static uint8 &FailCurrentMission;
- static uint8 &CountdownToMakePlayerUnsafe;
- static uint8 &DelayMakingPlayerUnsafeThisTime;
- static uint16 &NumScriptDebugLines;
- static uint16 &NumberOfIntroRectanglesThisFrame;
- static uint16 &NumberOfIntroTextLinesThisFrame;
- static uint8 &UseTextCommands;
- static uint16 &CommandsExecuted;
- static uint16 &ScriptsUpdated;
+ static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
+ static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
+ static int32 BaseBriefIdForContact[MAX_NUM_CONTACTS];
+ static int32 OnAMissionForContactFlag[MAX_NUM_CONTACTS];
+ static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
+ static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
+ static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
+ static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
+ static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES];
+ static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS];
+ static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
+ static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
+ static CEntity* InvisibilitySettingArray[MAX_NUM_INVISIBILITY_SETTINGS];
+ static CStoredLine aStoredLines[MAX_NUM_STORED_LINES];
+ static bool DbgFlag;
+ static uint32 OnAMissionFlag;
+ static CMissionCleanup MissionCleanup;
+ static CStuckCarCheck StuckCars;
+ static CUpsideDownCarCheck UpsideDownCars;
+ static int32 StoreVehicleIndex;
+ static bool StoreVehicleWasRandom;
+ static CRunningScript *pIdleScripts;
+ static CRunningScript *pActiveScripts;
+ static uint32 NextFreeCollectiveIndex;
+ static int32 LastRandomPedId;
+ static uint16 NumberOfUsedObjects;
+ static bool bAlreadyRunningAMissionScript;
+ static bool bUsingAMultiScriptFile;
+ static uint16 NumberOfMissionScripts;
+ static uint32 LargestMissionScriptSize;
+ static uint32 MainScriptSize;
+ static uint8 FailCurrentMission;
+ static uint8 CountdownToMakePlayerUnsafe;
+ static uint8 DelayMakingPlayerUnsafeThisTime;
+ static uint16 NumScriptDebugLines;
+ static uint16 NumberOfIntroRectanglesThisFrame;
+ static uint16 NumberOfIntroTextLinesThisFrame;
+ static uint8 UseTextCommands;
+ static uint16 CommandsExecuted;
+ static uint16 ScriptsUpdated;
public:
static void Init();
diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp
index ab9cd92d..c8d3f79f 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -1,19 +1,19 @@
#include "common.h"
-#include "patcher.h"
-#include "General.h"
+
#include "Camera.h"
-#include "World.h"
-#include "PathFind.h"
-#include "Timer.h"
#include "Clock.h"
-#include "Weather.h"
-#include "Timecycle.h"
-#include "Pointlights.h"
-#include "Shadows.h"
#include "Coronas.h"
+#include "General.h"
+#include "PathFind.h"
+#include "PointLights.h"
+#include "Shadows.h"
#include "SpecialFX.h"
-#include "Vehicle.h"
+#include "Timecycle.h"
+#include "Timer.h"
#include "TrafficLights.h"
+#include "Vehicle.h"
+#include "Weather.h"
+#include "World.h"
// TODO: figure out the meaning of this
enum { SOME_FLAG = 0x80 };
@@ -39,10 +39,10 @@ CTrafficLights::DisplayActualLight(CEntity *ent)
float zMax = mi->Get2dEffect(0)->pos.z;
for(i = 1; i < 6; i++){
assert(mi->Get2dEffect(i));
- yMin = min(yMin, mi->Get2dEffect(i)->pos.y);
- yMax = max(yMax, mi->Get2dEffect(i)->pos.y);
- zMin = min(zMin, mi->Get2dEffect(i)->pos.z);
- zMax = max(zMax, mi->Get2dEffect(i)->pos.z);
+ yMin = Min(yMin, mi->Get2dEffect(i)->pos.y);
+ yMax = Max(yMax, mi->Get2dEffect(i)->pos.y);
+ zMin = Min(zMin, mi->Get2dEffect(i)->pos.z);
+ zMax = Max(zMax, mi->Get2dEffect(i)->pos.z);
}
CVector pos1, pos2;
@@ -327,9 +327,3 @@ CTrafficLights::LightForCars2(void)
else
return CAR_LIGHTS_RED;
}
-
-STARTPATCHES
- InjectHook(0x455760, &CTrafficLights::LightForCars1, PATCH_JUMP);
- InjectHook(0x455790, &CTrafficLights::LightForCars2, PATCH_JUMP);
- InjectHook(0x4557D0, &CTrafficLights::LightForPeds, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Accident.cpp b/src/core/Accident.cpp
index d8313ddc..1fd6c123 100644
--- a/src/core/Accident.cpp
+++ b/src/core/Accident.cpp
@@ -1,12 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "Accident.h"
#include "Ped.h"
#include "Pools.h"
#include "World.h"
-CAccidentManager& gAccidentManager = *(CAccidentManager*)0x87FD10;
+CAccidentManager gAccidentManager;
CAccident*
CAccidentManager::GetNextFreeAccident()
@@ -122,13 +122,3 @@ CAccidentManager::UnattendedAccidents()
}
return false;
}
-
-STARTPATCHES
- InjectHook(0x4565A0, &CAccidentManager::GetNextFreeAccident, PATCH_JUMP);
- InjectHook(0x4565D0, &CAccidentManager::ReportAccident, PATCH_JUMP);
- InjectHook(0x456710, &CAccidentManager::Update, PATCH_JUMP);
- InjectHook(0x456760, &CAccidentManager::FindNearestAccident, PATCH_JUMP);
- InjectHook(0x456880, &CAccidentManager::CountActiveAccidents, PATCH_JUMP);
- InjectHook(0x4568A0, &CAccidentManager::WorkToDoForMedics, PATCH_JUMP);
- InjectHook(0x4568D0, &CAccidentManager::UnattendedAccidents, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Accident.h b/src/core/Accident.h
index 69889645..949d5fb9 100644
--- a/src/core/Accident.h
+++ b/src/core/Accident.h
@@ -29,4 +29,4 @@ public:
bool WorkToDoForMedics();
};
-extern CAccidentManager& gAccidentManager; \ No newline at end of file
+extern CAccidentManager gAccidentManager; \ No newline at end of file
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index 1086db20..36ea20b7 100644
--- a/src/core/AnimViewer.cpp
+++ b/src/core/AnimViewer.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Font.h"
#include "Pad.h"
#include "Text.h"
@@ -37,6 +37,7 @@
#include "Shadows.h"
#include "Radar.h"
#include "Hud.h"
+#include "debugmenu.h"
int CAnimViewer::animTxdSlot = 0;
CEntity *CAnimViewer::pTarget = nil;
@@ -208,7 +209,6 @@ PlayAnimation(RpClump *clump, AssocGroupId animGroup, AnimationId anim)
animAssoc->SetRun();
}
-extern void (*DebugMenuProcess)(void);
void
CAnimViewer::Update(void)
{
@@ -367,7 +367,12 @@ CAnimViewer::Update(void)
} else {
// Originally it was GetPad(1)->LeftShoulder2
if (pad->NewState.Triangle) {
- CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump()));
+#ifdef PED_SKIN
+ if(IsClumpSkinned(pTarget->GetClump()))
+ ((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->AnimatePedColModelSkinned(pTarget->GetClump());
+ else
+#endif
+ CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump()));
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
CMessages::AddMessage(gUString, 100, 0);
}
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index cfdea46a..5cf1c8f3 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Draw.h"
#include "World.h"
@@ -28,7 +28,7 @@
const float DefaultFOV = 70.0f; // beta: 80.0f
bool PrintDebugCode = false;
-int16 &DebugCamMode = *(int16*)0x95CCF2;
+int16 DebugCamMode;
#ifdef FREE_CAM
bool CCamera::bFreeCam = false;
@@ -117,9 +117,9 @@ CCam::Process(void)
float FwdSpeedX = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().x * Fwd.x;
float FwdSpeedY = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().y * Fwd.y;
if(FwdSpeedX + FwdSpeedY > 0.0f)
- TargetSpeedVar = min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/0.9f, 1.0f);
+ TargetSpeedVar = Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/0.9f, 1.0f);
else
- TargetSpeedVar = -min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f);
+ TargetSpeedVar = -Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f);
SpeedVar = 0.895f*SpeedVar + 0.105*TargetSpeedVar;
}else{
CameraTarget = CamTargetEntity->GetPosition();
@@ -341,7 +341,7 @@ WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSp
else if(TargetSpeed > 0.0f && *CurrentSpeed > TargetSpeed)
*CurrentSpeed = TargetSpeed;
- *CurrentValue += *CurrentSpeed * min(10.0f, CTimer::GetTimeStep());
+ *CurrentValue += *CurrentSpeed * Min(10.0f, CTimer::GetTimeStep());
}
void
@@ -467,7 +467,7 @@ CCam::ProcessSpecialHeightRoutines(void)
vehicle->IsVehicle()){
float height = vehicle->GetColModel()->boundingBox.GetSize().z;
if(FoundCar){
- HighestCar = max(HighestCar, height);
+ HighestCar = Max(HighestCar, height);
}else{
FoundCar = true;
HighestCar = height;
@@ -481,7 +481,7 @@ CCam::ProcessSpecialHeightRoutines(void)
vehicle->IsVehicle()){
float height = vehicle->GetColModel()->boundingBox.GetSize().z;
if(FoundCar){
- HighestCar = max(HighestCar, height);
+ HighestCar = Max(HighestCar, height);
}else{
FoundCar = true;
HighestCar = height;
@@ -1323,7 +1323,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
else if(ReqSpeed > 0.0f && BetaSpeed > ReqSpeed)
BetaSpeed = ReqSpeed;
- Beta += BetaSpeed * min(10.0f, CTimer::GetTimeStep());
+ Beta += BetaSpeed * Min(10.0f, CTimer::GetTimeStep());
*/
WellBufferMe(FixedTargetOrientation, &Beta, &BetaSpeed, MaxSpeed, Acceleration, true);
@@ -1398,7 +1398,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
// Process height offset to avoid peds and cars
float TargetZOffSet = m_fRoadOffSet + m_fDimensionOfHighestNearCar;
- TargetZOffSet = max(TargetZOffSet, m_fPedBetweenCameraHeightOffset);
+ TargetZOffSet = Max(TargetZOffSet, m_fPedBetweenCameraHeightOffset);
float TargetHeight = CameraTarget.z + TargetZOffSet - Source.z;
if(TargetHeight > m_fCamBufferedHeight){
@@ -1454,7 +1454,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
}
}
- TargetCoors.z += min(1.0f, m_fCamBufferedHeight/2.0f);
+ TargetCoors.z += Min(1.0f, m_fCamBufferedHeight/2.0f);
m_cvecTargetCoorsForFudgeInter = TargetCoors;
Front = TargetCoors - Source;
@@ -1553,7 +1553,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
#else
if(Alpha > fBaseDist) // comparing an angle against a distance?
#endif
- CamDist = fBaseDist + Cos(min(Alpha*fFalloff, HALFPI))*fAngleDist;
+ CamDist = fBaseDist + Cos(Min(Alpha*fFalloff, HALFPI))*fAngleDist;
else
CamDist = fBaseDist + Cos(Alpha)*fAngleDist;
@@ -1585,14 +1585,14 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
PedColDist = (TargetCoors - colPoint.point).Magnitude();
Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f)
- RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f));
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}else{
- RwCameraSetNearClipPlane(Scene.camera, min(ColCamDist-0.35f, DEFAULT_NEAR));
+ 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));
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}
}
CWorld::pIgnoreEntity = nil;
@@ -1609,7 +1609,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
// Try to decrease near clip
- dist = max(min(Near, dist), 0.1f);
+ dist = Max(Min(Near, dist), 0.1f);
if(dist < Near)
RwCameraSetNearClipPlane(Scene.camera, dist);
@@ -1639,7 +1639,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
float PlayerDist = (Source - player->GetPosition()).Magnitude();
if(PlayerDist < 2.75f)
Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f;
- RwCameraSetNearClipPlane(Scene.camera, max(Near, 0.1f));
+ RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f));
}
}
@@ -1881,7 +1881,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
}
if(FoundCamRoof){
// Camera is under something
- float roof = FoundRoofCenter ? min(CamRoof, CarRoof) : CamRoof;
+ float roof = FoundRoofCenter ? Min(CamRoof, CarRoof) : CamRoof;
// Same weirdness again?
TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, roof - CamTargetZ - 1.5f);
CamClear = false;
@@ -2139,7 +2139,7 @@ void
CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist)
{
CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth;
- CA_MIN_DISTANCE = min(BaseDist*0.6f, 3.5f);
+ CA_MIN_DISTANCE = Min(BaseDist*0.6f, 3.5f);
CVector Dist = Source - TargetCoors;
@@ -2361,7 +2361,7 @@ CCam::Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, f
if(FindPlayerPed()->m_pPointGunAt){
Dist = (FindPlayerPed()->m_pPointGunAt->GetPosition() - CameraTarget).Magnitude2D();
if(Dist > 6.0f)
- HeightTarget = max(HeightTarget, Dist/22.0f*37.0f);
+ HeightTarget = Max(HeightTarget, Dist/22.0f*37.0f);
}
Source = TargetCoors + CVector(0.0f, -1.0f, 9.0f);
@@ -2776,17 +2776,20 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
if(CamTargetEntity->IsPed()){
// static bool FailedTestTwelveFramesAgo = false; // unused
- RwV3d HeadPos = vecHeadCamOffset;
+ CVector HeadPos = vecHeadCamOffset;
CVector TargetCoors;
- // needs fix for SKINNING
- RwFrame *frm = ((CPed*)CamTargetEntity)->GetNodeFrame(PED_HEAD);
+ ((CPed*)CamTargetEntity)->TransformToNode(HeadPos, PED_HEAD);
+ // This is done on PC, but checking for the clump frame is not necessary apparently
+/*
+ RwFrame *frm = ((CPed*)CamTargetEntity)->m_pFrames[PED_HEAD]->frame;
while(frm){
RwV3dTransformPoints(&HeadPos, &HeadPos, 1, RwFrameGetMatrix(frm));
frm = RwFrameGetParent(frm);
if(frm == RpClumpGetFrame(CamTargetEntity->GetClump()))
frm = nil;
}
+*/
if(ResetStatics){
Beta = TargetOrientation;
@@ -2813,13 +2816,13 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
m_vecBufferedPlayerBodyOffset.z =
TheCamera.m_fGaitSwayBuffer * m_vecBufferedPlayerBodyOffset.z +
(1.0f-TheCamera.m_fGaitSwayBuffer) * HeadPos.z;
- HeadPos = RwV3d(CamTargetEntity->GetMatrix() * m_vecBufferedPlayerBodyOffset);
+ HeadPos = (CamTargetEntity->GetMatrix() * m_vecBufferedPlayerBodyOffset);
}else{
float HeadDelta = (HeadPos - InitialHeadPos).Magnitude2D();
CVector Fwd = CamTargetEntity->GetForward();
Fwd.z = 0.0f;
Fwd.Normalise();
- HeadPos = RwV3d(HeadDelta*1.23f*Fwd + CamTargetEntity->GetPosition());
+ HeadPos = (HeadDelta*1.23f*Fwd + CamTargetEntity->GetPosition());
HeadPos.z += 0.59f;
}
Source = HeadPos;
@@ -3125,7 +3128,7 @@ CCam::Process_Syphon(const CVector &CameraTarget, float, float, float)
Front = TargetCoors - Source;
m_fMinDistAwayFromCamWhenInterPolating = Front.Magnitude2D();
if(m_fMinDistAwayFromCamWhenInterPolating < 1.1f)
- RwCameraSetNearClipPlane(Scene.camera, max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f));
+ RwCameraSetNearClipPlane(Scene.camera, Max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f));
Front.Normalise();
GetVectorsReadyForRW();
}
@@ -3382,7 +3385,7 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl
WellBufferMe(TargetOrientation, &m_fBufferedTargetOrientation, &m_fBufferedTargetOrientationSpeed, 0.07f, 0.004f, true);
TargetCoors = CameraTarget + 0.5f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f);
- TargetCamHeight = CameraTarget.z - Source.z + max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f;
+ TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f;
if(TargetCamHeight > m_fCamBufferedHeight)
WellBufferMe(TargetCamHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.15f, 0.04f, false);
else
@@ -4556,14 +4559,14 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
PedColDist = (TargetCoors - colPoint.point).Magnitude();
Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f)
- RwCameraSetNearClipPlane(Scene.camera, max(PedColDist-0.3f, 0.05f));
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}else{
- RwCameraSetNearClipPlane(Scene.camera, min(ColCamDist-0.35f, DEFAULT_NEAR));
+ 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));
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}
}
CWorld::pIgnoreEntity = nil;
@@ -4580,7 +4583,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
// Try to decrease near clip
- dist = max(min(Near, dist), 0.1f);
+ dist = Max(Min(Near, dist), 0.1f);
if(dist < Near)
RwCameraSetNearClipPlane(Scene.camera, dist);
@@ -4714,7 +4717,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
minDistForVehType = minDistForVehType * 0.65f;
}
- float nextDistance = max(newDistance, minDistForVehType);
+ float nextDistance = Max(newDistance, minDistForVehType);
CA_MAX_DISTANCE = newDistance;
CA_MIN_DISTANCE = 3.5f;
@@ -4811,7 +4814,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float betaChangeMult2 = (car->m_vecMoveSpeed - DotProduct(car->m_vecMoveSpeed, Front) * Front).Magnitude();
- float betaChange = min(1.0f, betaChangeMult1 * betaChangeMult2) * (velocityRightHeading - camRightHeading);
+ float betaChange = Min(1.0f, betaChangeMult1 * betaChangeMult2) * (velocityRightHeading - camRightHeading);
if (betaChange <= betaChangeLimit) {
if (betaChange < -betaChangeLimit)
betaChange = -betaChangeLimit;
@@ -4827,7 +4830,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float carPosChange = (TargetCoors - m_aTargetHistoryPosTwo).Magnitude();
if (carPosChange < newDistance && newDistance > minDistForThisCar) {
- newDistance = max(minDistForThisCar, carPosChange);
+ newDistance = Max(minDistForThisCar, carPosChange);
}
float maxAlphaAllowed = CARCAM_SET[camSetArrPos][13];
@@ -4851,7 +4854,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
v200 = (1.5f - carCol->boundingBox.min.y) / Cos(v88);
} else {
float a6g = 1.2f + carCol->boundingBox.max.x;
- v200 = a6g / Cos(max(0.0f, HALFPI - v88));
+ v200 = a6g / Cos(Max(0.0f, HALFPI - v88));
}
maxAlphaAllowed = Cos(Beta - (car->GetForward().Heading() - HALFPI)) * Atan2(car->GetForward().z, car->GetForward().Magnitude2D())
+ Atan2(TargetCoors.z - car->GetPosition().z + car->GetHeightAboveRoad(), v200 * 1.2f);
@@ -4944,7 +4947,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
yMovement = 0.0;
xMovement = 0.0;
targetAlpha = Alpha;
- stepsLeftToChangeBetaByMouse = max(0.0f, stepsLeftToChangeBetaByMouse - CTimer::GetTimeStep());
+ stepsLeftToChangeBetaByMouse = Max(0.0f, stepsLeftToChangeBetaByMouse - CTimer::GetTimeStep());
mouseChangesBeta = true;
}
}
@@ -4963,7 +4966,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9];
float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
- float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / max(CTimer::GetTimeStep(), 1.0f);
+ float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f);
if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount)
targetBetaWithStickBlendAmount = -newAngleSpeedMaxBlendAmount;
@@ -5088,7 +5091,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) {
Source = foundCol.point;
if (obstacleTargetDist < 1.2f) {
- RwCameraSetNearClipPlane(Scene.camera, max(0.05f, obstacleTargetDist - 0.3f));
+ 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)) {
@@ -5236,55 +5239,3 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
}
}
#endif
-
-STARTPATCHES
- InjectHook(0x456F40, WellBufferMe, PATCH_JUMP);
- InjectHook(0x458410, &CCam::Init, PATCH_JUMP);
- InjectHook(0x4582F0, &CCam::GetVectorsReadyForRW, PATCH_JUMP);
- InjectHook(0x457710, &CCam::DoAverageOnVector, PATCH_JUMP);
- InjectHook(0x458060, &CCam::GetPedBetaAngleForClearView, PATCH_JUMP);
- InjectHook(0x457210, &CCam::Cam_On_A_String_Unobscured, PATCH_JUMP);
- InjectHook(0x457A80, &CCam::FixCamWhenObscuredByVehicle, PATCH_JUMP);
- InjectHook(0x457B90, &CCam::FixCamIfObscured, PATCH_JUMP);
- InjectHook(0x465DA0, &CCam::RotCamIfInFrontCar, PATCH_JUMP);
- InjectHook(0x4662D0, &CCam::WorkOutCamHeightWeeCar, PATCH_JUMP);
- InjectHook(0x466650, &CCam::WorkOutCamHeight, PATCH_JUMP);
- InjectHook(0x458600, &CCam::LookBehind, PATCH_JUMP);
- InjectHook(0x458C40, &CCam::LookLeft, PATCH_JUMP);
- InjectHook(0x458FB0, &CCam::LookRight, PATCH_JUMP);
- InjectHook(0x4574C0, &CCam::ClipIfPedInFrontOfPlayer, PATCH_JUMP);
- InjectHook(0x459300, &CCam::KeepTrackOfTheSpeed, PATCH_JUMP);
- InjectHook(0x458580, &CCam::IsTargetInWater, PATCH_JUMP);
- InjectHook(0x4570C0, &CCam::AvoidWallsTopDownPed, PATCH_JUMP);
- InjectHook(0x4595B0, &CCam::PrintMode, PATCH_JUMP);
-
- InjectHook(0x467400, &CCam::ProcessSpecialHeightRoutines, PATCH_JUMP);
- InjectHook(0x4596A0, &CCam::Process, PATCH_JUMP);
- InjectHook(0x45E3A0, &CCam::Process_FollowPed, PATCH_JUMP);
- InjectHook(0x45FF70, &CCam::Process_FollowPedWithMouse, PATCH_JUMP);
- InjectHook(0x45BE60, &CCam::Process_BehindCar, PATCH_JUMP);
- InjectHook(0x45C090, &CCam::Process_Cam_On_A_String, PATCH_JUMP);
- InjectHook(0x463EB0, &CCam::Process_TopDown, PATCH_JUMP);
- InjectHook(0x464390, &CCam::Process_TopDownPed, PATCH_JUMP);
- InjectHook(0x461AF0, &CCam::Process_Rocket, PATCH_JUMP);
- InjectHook(0x460E00, &CCam::Process_M16_1stPerson, PATCH_JUMP);
- InjectHook(0x459FA0, &CCam::Process_1stPerson, PATCH_JUMP);
- InjectHook(0x462420, &CCam::Process_Sniper, PATCH_JUMP);
- InjectHook(0x463130, &CCam::Process_Syphon, PATCH_JUMP);
- InjectHook(0x463A70, &CCam::Process_Syphon_Crim_In_Front, PATCH_JUMP);
- InjectHook(0x45B470, &CCam::Process_BehindBoat, PATCH_JUMP);
- InjectHook(0x45D2F0, &CCam::Process_Fight_Cam, PATCH_JUMP);
- InjectHook(0x45DC20, &CCam::Process_FlyBy, PATCH_JUMP);
- InjectHook(0x464D10, &CCam::Process_WheelCam, PATCH_JUMP);
- InjectHook(0x45DA20, &CCam::Process_Fixed, PATCH_JUMP);
- InjectHook(0x461940, &CCam::Process_Player_Fallen_Water, PATCH_JUMP);
- InjectHook(0x45C400, &CCam::Process_Circle, PATCH_JUMP);
- InjectHook(0x462FC0, &CCam::Process_SpecialFixedForSyphon, PATCH_JUMP);
- InjectHook(0x45CCC0, &CCam::Process_Debug, PATCH_JUMP);
- InjectHook(0x4656C0, &CCam::ProcessPedsDeadBaby, PATCH_JUMP);
- InjectHook(0x465000, &CCam::ProcessArrestCamOne, PATCH_JUMP);
- InjectHook(0x4653C0, &CCam::ProcessArrestCamTwo, PATCH_JUMP);
-
- InjectHook(0x456CE0, &FindSplinePathPositionFloat, PATCH_JUMP);
- InjectHook(0x4569A0, &FindSplinePathPositionVector, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 91dd6573..c8eaaa56 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Draw.h"
#include "World.h"
@@ -29,6 +29,7 @@
#include "SceneEdit.h"
#include "Pools.h"
#include "Debug.h"
+#include "GenericGameStorage.h"
#include "Camera.h"
enum
@@ -57,9 +58,9 @@ enum
#define PLAYER (CWorld::Players[CWorld::PlayerInFocus].m_pPed)
// NB: removed explicit TheCamera from all functions
-CCamera &TheCamera = *(CCamera*)0x6FACF8;
-bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8;
-bool &bDidWeProcessAnyCinemaCam = *(bool*)0x95CD46;
+CCamera TheCamera;
+bool CCamera::m_bUseMouse3rdPerson = true;
+bool bDidWeProcessAnyCinemaCam;
#ifdef IMPROVED_CAMERA
#define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k)
@@ -466,7 +467,7 @@ CCamera::Process(void)
GetPosition().z += shakeOffset*(((shakeRand&0xF00)>>8)-7);
if(shakeOffset > 0.0f && m_BlurType != MBLUR_SNIPER)
- SetMotionBlurAlpha(min((int)(shakeStrength*255.0f) + 25, 150));
+ SetMotionBlurAlpha(Min((int)(shakeStrength*255.0f) + 25, 150));
if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON && FindPlayerVehicle() && FindPlayerVehicle()->GetUp().z < 0.2f)
SetMotionBlur(230, 230, 230, 215, MBLUR_NORMAL);
@@ -488,19 +489,19 @@ CCamera::Process(void)
CDraw::SetFOV(Cams[2].FOV);
m_vecGameCamPos = Cams[ActiveCam].Source;
- *RwMatrixGetPos(RwFrameGetMatrix(frame)) = (RwV3d)GetPosition();
- *RwMatrixGetAt(RwFrameGetMatrix(frame)) = (RwV3d)GetForward();
- *RwMatrixGetUp(RwFrameGetMatrix(frame)) = (RwV3d)GetUp();
- *RwMatrixGetRight(RwFrameGetMatrix(frame)) = (RwV3d)GetRight();
+ *RwMatrixGetPos(RwFrameGetMatrix(frame)) = GetPosition().toRwV3d();
+ *RwMatrixGetAt(RwFrameGetMatrix(frame)) = GetForward().toRwV3d();
+ *RwMatrixGetUp(RwFrameGetMatrix(frame)) = GetUp().toRwV3d();
+ *RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight().toRwV3d();
RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame);
}else{
RwFrame *frame = RwCameraGetFrame(m_pRwCamera);
m_vecGameCamPos = GetPosition();
- *RwMatrixGetPos(RwFrameGetMatrix(frame)) = (RwV3d)GetPosition();
- *RwMatrixGetAt(RwFrameGetMatrix(frame)) = (RwV3d)GetForward();
- *RwMatrixGetUp(RwFrameGetMatrix(frame)) = (RwV3d)GetUp();
- *RwMatrixGetRight(RwFrameGetMatrix(frame)) = (RwV3d)GetRight();
+ *RwMatrixGetPos(RwFrameGetMatrix(frame)) = GetPosition().toRwV3d();
+ *RwMatrixGetAt(RwFrameGetMatrix(frame)) = GetForward().toRwV3d();
+ *RwMatrixGetUp(RwFrameGetMatrix(frame)) = GetUp().toRwV3d();
+ *RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight().toRwV3d();
RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame);
}
@@ -767,27 +768,27 @@ CCamera::CamControl(void)
if(m_bUseScriptZoomValueCar){
if(CarZoomValueSmooth < m_fCarZoomValueScript){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = min(CarZoomValueSmooth, m_fCarZoomValueScript);
+ CarZoomValueSmooth = Min(CarZoomValueSmooth, m_fCarZoomValueScript);
}else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = max(CarZoomValueSmooth, m_fCarZoomValueScript);
+ CarZoomValueSmooth = Max(CarZoomValueSmooth, m_fCarZoomValueScript);
}
}else if(m_bFailedCullZoneTestPreviously){
CloseInCarHeightTarget = 0.65f;
if(CarZoomValueSmooth < -0.65f){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = min(CarZoomValueSmooth, -0.65f);
+ CarZoomValueSmooth = Min(CarZoomValueSmooth, -0.65f);
}else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = max(CarZoomValueSmooth, -0.65f);
+ CarZoomValueSmooth = Max(CarZoomValueSmooth, -0.65f);
}
}else{
if(CarZoomValueSmooth < CarZoomValue){
CarZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = min(CarZoomValueSmooth, CarZoomValue);
+ CarZoomValueSmooth = Min(CarZoomValueSmooth, CarZoomValue);
}else{
CarZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- CarZoomValueSmooth = max(CarZoomValueSmooth, CarZoomValue);
+ CarZoomValueSmooth = Max(CarZoomValueSmooth, CarZoomValue);
}
}
@@ -871,28 +872,28 @@ CCamera::CamControl(void)
if(m_bUseScriptZoomValuePed){
if(m_fPedZoomValueSmooth < m_fPedZoomValueScript){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
+ m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
}else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
+ m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, m_fPedZoomValueScript);
}
}else if(m_bFailedCullZoneTestPreviously){
static float PedZoomedInVal = 0.5f;
CloseInPedHeightTarget = 0.7f;
if(m_fPedZoomValueSmooth < PedZoomedInVal){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, PedZoomedInVal);
+ m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, PedZoomedInVal);
}else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, PedZoomedInVal);
+ m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, PedZoomedInVal);
}
}else{
if(m_fPedZoomValueSmooth < m_fPedZoomValue){
m_fPedZoomValueSmooth += 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = min(m_fPedZoomValueSmooth, m_fPedZoomValue);
+ m_fPedZoomValueSmooth = Min(m_fPedZoomValueSmooth, m_fPedZoomValue);
}else{
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
- m_fPedZoomValueSmooth = max(m_fPedZoomValueSmooth, m_fPedZoomValue);
+ m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, m_fPedZoomValue);
}
}
@@ -2183,13 +2184,21 @@ CCamera::DrawBordersForWideScreen(void)
SetMotionBlurAlpha(80);
CSprite2d::DrawRect(
+#ifdef FIX_BUGS
+ CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f),
+#else
CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f,
+#endif
SCREEN_WIDTH, 0.0f),
CRGBA(0, 0, 0, 255));
CSprite2d::DrawRect(
CRect(0.0f, SCREEN_HEIGHT,
+#ifdef FIX_BUGS
+ SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f)),
+#else
SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f),
+#endif
CRGBA(0, 0, 0, 255));
}
@@ -2247,7 +2256,7 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
if(fwd.Magnitude() < 2.0f)
// very close, fix near clip
- SetNearClipScript(max(fwd.Magnitude()*0.5f, 0.05f));
+ SetNearClipScript(Max(fwd.Magnitude()*0.5f, 0.05f));
// too far and driving away from cam
if(fwd.Magnitude() > 19.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true;
@@ -2481,6 +2490,10 @@ CCamera::TryToStartNewCamMode(int obbeMode)
TakeControl(FindPlayerEntity(), CCam::MODE_CAM_ON_A_STRING, JUMP_CUT, CAMCONTROL_OBBE);
return true;
case OBBE_COPCAR:
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return false;
+#endif
if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1)
return false;
if(FindPlayerVehicle() == nil)
@@ -2505,6 +2518,10 @@ CCamera::TryToStartNewCamMode(int obbeMode)
}
return false;
case OBBE_COPCAR_WHEEL:
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return false;
+#endif
if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1)
return false;
if(FindPlayerVehicle() == nil)
@@ -3377,58 +3394,3 @@ CCamPathSplines::CCamPathSplines(void)
for(i = 0; i < MAXPATHLENGTH; i++)
m_arr_PathData[i] = 0.0f;
}
-
-
-STARTPATCHES
- InjectHook(0x42C760, (bool (CCamera::*)(const CVector &center, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
- InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
-
- InjectHook(0x46FD40, &CCamera::SetMotionBlur, PATCH_JUMP);
- InjectHook(0x46FD80, &CCamera::SetMotionBlurAlpha, PATCH_JUMP);
- InjectHook(0x46F940, &CCamera::RenderMotionBlur, PATCH_JUMP);
-
- InjectHook(0x46FC90, &CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString, PATCH_JUMP);
-
- InjectHook(0x46FF00, &CCamera::SetWideScreenOn, PATCH_JUMP);
- InjectHook(0x46FF10, &CCamera::SetWideScreenOff, PATCH_JUMP);
-
- InjectHook(0x46FCC0, &CCamera::SetCamPositionForFixedMode, PATCH_JUMP);
- InjectHook(0x46FEC0, &CCamera::SetRwCamera, PATCH_JUMP);
- InjectHook(0x46B920, &CCamera::GetCutSceneFinishTime, PATCH_JUMP);
- InjectHook(0x46B560, &CCamera::FinishCutscene, PATCH_JUMP);
- InjectHook(0x46FF30, &CCamera::SetZoomValueFollowPedScript, PATCH_JUMP);
- InjectHook(0x46FF90, &CCamera::SetZoomValueCamStringScript, PATCH_JUMP);
-
-
- InjectHook(0x46F8E0, &CCamera::ProcessWideScreenOn, PATCH_JUMP);
- InjectHook(0x46FDE0, &CCamera::SetParametersForScriptInterpolation, PATCH_JUMP);
- InjectHook(0x46BA20, &CCamera::GetLookingLRBFirstPerson, PATCH_JUMP);
- InjectHook(0x470D80, &CCamera::StartTransitionWhenNotFinishedInter, PATCH_JUMP);
- InjectHook(0x46FFF0, &CCamera::StartTransition, PATCH_JUMP);
- InjectHook(0x46BEB0, &CCamera::InitialiseCameraForDebugMode, PATCH_JUMP);
- InjectHook(0x471500, &CCamera::TakeControl, PATCH_JUMP);
- InjectHook(0x4715B0, &CCamera::TakeControlNoEntity, PATCH_JUMP);
- InjectHook(0x46B3A0, &CCamera::Fade, PATCH_JUMP);
- InjectHook(0x46FE20, &CCamera::SetPercentAlongCutScene, PATCH_JUMP);
- InjectHook(0x46B100, &CamShakeNoPos, PATCH_JUMP);
- InjectHook(0x46B200, &CCamera::CamShake, PATCH_JUMP);
- InjectHook(0x46F520, &CCamera::ProcessObbeCinemaCameraPed, PATCH_JUMP);
- InjectHook(0x46F3E0, &CCamera::ProcessObbeCinemaCameraCar, PATCH_JUMP);
- InjectHook(0x470DA0, &CCamera::StoreValuesDuringInterPol, PATCH_JUMP);
- InjectHook(0x46B430, &CCamera::DrawBordersForWideScreen, PATCH_JUMP);
- InjectHook(0x46F990, &CCamera::Restore, PATCH_JUMP);
- InjectHook(0x46FAE0, &CCamera::RestoreWithJumpCut, PATCH_JUMP);
- InjectHook(0x46F080, &CCamera::ProcessFade, PATCH_JUMP);
- InjectHook(0x46EEA0, &CCamera::CalculateDerivedValues, PATCH_JUMP);
- InjectHook(0x46F1E0, &CCamera::ProcessMusicFade, PATCH_JUMP);
- InjectHook(0x46D1D0, &CCamera::LoadPathSplines, PATCH_JUMP);
- InjectHook(0x4712A0, &CCamera::UpdateTargetEntity, PATCH_JUMP);
- InjectHook(0x46B580, &CCamera::Find3rdPersonCamTargetVector, PATCH_JUMP);
- InjectHook(0x46BAD0, &CCamera::Init, PATCH_JUMP);
- InjectHook(0x46C9E0, &CCamera::LoadTrainCamNodes, PATCH_JUMP);
- InjectHook(0x46F600, &CCamera::Process_Train_Camera_Control, PATCH_JUMP);
- InjectHook(0x470EA0, &CCamera::UpdateSoundDistances, PATCH_JUMP);
- InjectHook(0x46BF10, &CCamera::IsItTimeForNewcam, PATCH_JUMP);
- InjectHook(0x471650, &CCamera::TryToStartNewCamMode, PATCH_JUMP);
-// InjectHook(0x46D3F0, &CCamera::Process, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Camera.h b/src/core/Camera.h
index eca4518a..d1c8ec03 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -6,7 +6,7 @@ class CPed;
class CAutomobile;
class CGarage;
-extern int16 &DebugCamMode;
+extern int16 DebugCamMode;
enum
{
@@ -415,7 +415,7 @@ uint32 unknown; // some counter having to do with music
float CamFrontXNorm;
float CamFrontYNorm;
-#if 0 // TODO: FIX_BUGS once GenericLoad is done
+#ifdef FIX_BUGS
int32 CarZoomIndicator;
#else
float CarZoomIndicator;
@@ -455,7 +455,7 @@ uint32 unknown; // some counter having to do with music
float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson;
float Orientation;
-#if 0 // TODO: FIX_BUGS once GenericLoad is done
+#ifdef FIX_BUGS
int32 PedZoomIndicator;
#else
float PedZoomIndicator;
@@ -540,7 +540,7 @@ uint32 unknown; // some counter having to do with music
uint32 m_uiFadeTimeStarted;
uint32 m_uiFadeTimeStartedMusic;
- static bool &m_bUseMouse3rdPerson;
+ static bool m_bUseMouse3rdPerson;
#ifdef FREE_CAM
static bool bFreeCam;
#endif
@@ -647,7 +647,7 @@ static_assert(offsetof(CCamera, m_vecCutSceneOffset) == 0x6F8, "CCamera: error")
static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error");
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
-extern CCamera &TheCamera;
+extern CCamera TheCamera;
void CamShakeNoPos(CCamera*, float);
void MakeAngleLessThan180(float &Angle);
diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp
index a400c039..ea79fb9a 100644
--- a/src/core/CdStream.cpp
+++ b/src/core/CdStream.cpp
@@ -1,6 +1,6 @@
-#include <windows.h>
+#define WITHWINDOWS
#include "common.h"
-#include "patcher.h"
+
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
@@ -507,24 +507,3 @@ CdStreamGetNumImages(void)
{
return gNumImages;
}
-
-
-STARTPATCHES
- InjectHook(0x405B50, CdStreamInitThread, PATCH_JUMP);
- InjectHook(0x405C80, CdStreamInit, PATCH_JUMP);
- //InjectHook(0x405DB0, debug, PATCH_JUMP);
- InjectHook(0x405DC0, GetGTA3ImgSize, PATCH_JUMP);
- InjectHook(0x405DD0, CdStreamShutdown, PATCH_JUMP);
- InjectHook(0x405E40, CdStreamRead, PATCH_JUMP);
- InjectHook(0x405F90, CdStreamGetStatus, PATCH_JUMP);
- InjectHook(0x406000, CdStreamGetLastPosn, PATCH_JUMP);
- InjectHook(0x406010, CdStreamSync, PATCH_JUMP);
- InjectHook(0x4060B0, AddToQueue, PATCH_JUMP);
- InjectHook(0x4060F0, GetFirstInQueue, PATCH_JUMP);
- InjectHook(0x406110, RemoveFirstInQueue, PATCH_JUMP);
- InjectHook(0x406140, CdStreamThread, PATCH_JUMP);
- InjectHook(0x406270, CdStreamAddImage, PATCH_JUMP);
- InjectHook(0x4062E0, CdStreamGetImageName, PATCH_JUMP);
- InjectHook(0x406300, CdStreamRemoveImages, PATCH_JUMP);
- InjectHook(0x406370, CdStreamGetNumImages, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp
index a97dcb5f..e4b908e0 100644
--- a/src/core/Clock.cpp
+++ b/src/core/Clock.cpp
@@ -1,22 +1,22 @@
#include "common.h"
-#include "patcher.h"
+
#include "Timer.h"
#include "Pad.h"
#include "Clock.h"
#include "Stats.h"
_TODO("gbFastTime");
-bool &gbFastTime = *(bool*)0x95CDBB;
+bool gbFastTime;
-uint8 &CClock::ms_nGameClockHours = *(uint8*)0x95CDA6;
-uint8 &CClock::ms_nGameClockMinutes = *(uint8*)0x95CDC8;
-uint16 &CClock::ms_nGameClockSeconds = *(uint16*)0x95CC7C;
-uint8 &CClock::ms_Stored_nGameClockHours = *(uint8*)0x95CD7B;
-uint8 &CClock::ms_Stored_nGameClockMinutes = *(uint8*)0x95CD9B;
-uint16 &CClock::ms_Stored_nGameClockSeconds = *(uint16*)0x95CC9C;
-uint32 &CClock::ms_nMillisecondsPerGameMinute = *(uint32*)0x8F2C64;
-uint32 &CClock::ms_nLastClockTick = *(uint32*)0x9430E4;
-bool &CClock::ms_bClockHasBeenStored = *(bool*)0x95CD82;
+uint8 CClock::ms_nGameClockHours;
+uint8 CClock::ms_nGameClockMinutes;
+uint16 CClock::ms_nGameClockSeconds;
+uint8 CClock::ms_Stored_nGameClockHours;
+uint8 CClock::ms_Stored_nGameClockMinutes;
+uint16 CClock::ms_Stored_nGameClockSeconds;
+uint32 CClock::ms_nMillisecondsPerGameMinute;
+uint32 CClock::ms_nLastClockTick;
+bool CClock::ms_bClockHasBeenStored;
void
CClock::Initialise(uint32 scale)
@@ -115,14 +115,3 @@ CClock::RestoreClock(void)
ms_nGameClockMinutes = ms_Stored_nGameClockMinutes;
ms_nGameClockSeconds = ms_Stored_nGameClockSeconds;
}
-
-
-STARTPATCHES
- InjectHook(0x473370, CClock::Initialise, PATCH_JUMP);
- InjectHook(0x473460, CClock::Update, PATCH_JUMP);
- InjectHook(0x4733C0, CClock::SetGameClock, PATCH_JUMP);
- InjectHook(0x4733F0, CClock::GetGameClockMinutesUntil, PATCH_JUMP);
- InjectHook(0x473420, CClock::GetIsTimeInRange, PATCH_JUMP);
- InjectHook(0x473540, CClock::StoreClock, PATCH_JUMP);
- InjectHook(0x473570, CClock::RestoreClock, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Clock.h b/src/core/Clock.h
index 6b9908ba..a611cd50 100644
--- a/src/core/Clock.h
+++ b/src/core/Clock.h
@@ -3,15 +3,15 @@
class CClock
{
public:
- static uint8 &ms_nGameClockHours;
- static uint8 &ms_nGameClockMinutes;
- static uint16 &ms_nGameClockSeconds;
- static uint8 &ms_Stored_nGameClockHours;
- static uint8 &ms_Stored_nGameClockMinutes;
- static uint16 &ms_Stored_nGameClockSeconds;
- static uint32 &ms_nMillisecondsPerGameMinute;
- static uint32 &ms_nLastClockTick;
- static bool &ms_bClockHasBeenStored;
+ static uint8 ms_nGameClockHours;
+ static uint8 ms_nGameClockMinutes;
+ static uint16 ms_nGameClockSeconds;
+ static uint8 ms_Stored_nGameClockHours;
+ static uint8 ms_Stored_nGameClockMinutes;
+ static uint16 ms_Stored_nGameClockSeconds;
+ static uint32 ms_nMillisecondsPerGameMinute;
+ static uint32 ms_nLastClockTick;
+ static bool ms_bClockHasBeenStored;
static void Initialise(uint32 scale);
static void Update(void);
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index c884f751..7dfe3651 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Lists.h"
#include "Game.h"
@@ -31,8 +31,8 @@ enum Direction
DIR_Z_NEG,
};
-eLevelName &CCollision::ms_collisionInMemory = *(eLevelName*)0x8F6250;
-CLinkList<CColModel*> &CCollision::ms_colModelCache = *(CLinkList<CColModel*>*)0x95CB58;
+eLevelName CCollision::ms_collisionInMemory;
+CLinkList<CColModel*> CCollision::ms_colModelCache;
void
CCollision::Init(void)
@@ -153,10 +153,10 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange)
// on water we expect to be between levels
multipleLevels = true;
}else{
- xmin = max(sx - 1, 0);
- xmax = min(sx + 1, NUMSECTORS_X-1);
- ymin = max(sy - 1, 0);
- ymax = min(sy + 1, NUMSECTORS_Y-1);
+ xmin = Max(sx - 1, 0);
+ xmax = Min(sx + 1, NUMSECTORS_X-1);
+ ymin = Max(sy - 1, 0);
+ ymax = Min(sy + 1, NUMSECTORS_Y-1);
for(x = xmin; x <= xmax; x++)
for(y = ymin; y <= ymax; y++){
@@ -1355,6 +1355,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
modelB.triangles[aTriangleIndicesB[j]],
modelB.trianglePlanes[aTriangleIndicesB[j]],
spherepoints[numCollisions], coldist);
+
if(hasCollided)
numCollisions++;
}
@@ -2139,70 +2140,3 @@ CColModel::operator=(const CColModel &other)
}
return *this;
}
-
-#include <new>
-struct CColLine_ : public CColLine
-{
- CColLine *ctor(CVector *p0, CVector *p1) { return ::new (this) CColLine(*p0, *p1); }
-};
-
-struct CColModel_ : public CColModel
-{
- CColModel *ctor(void) { return ::new (this) CColModel(); }
- void dtor(void) { this->CColModel::~CColModel(); }
-};
-
-
-STARTPATCHES
- InjectHook(0x4B9C30, (CMatrix& (*)(const CMatrix &src, CMatrix &dst))Invert, PATCH_JUMP);
-
- InjectHook(0x40B380, CCollision::Init, PATCH_JUMP);
- InjectHook(0x40B3A0, CCollision::Shutdown, PATCH_JUMP);
- InjectHook(0x40B3B0, CCollision::Update, PATCH_JUMP);
- InjectHook(0x40B5B0, CCollision::LoadCollisionWhenINeedIt, PATCH_JUMP);
- InjectHook(0x40B900, CCollision::SortOutCollisionAfterLoad, PATCH_JUMP);
-
- InjectHook(0x40BB70, CCollision::TestSphereBox, PATCH_JUMP);
- InjectHook(0x40E130, CCollision::TestLineBox, PATCH_JUMP);
- InjectHook(0x40E5C0, CCollision::TestVerticalLineBox, PATCH_JUMP);
- InjectHook(0x40EC10, CCollision::TestLineTriangle, PATCH_JUMP);
- InjectHook(0x40DAA0, CCollision::TestLineSphere, PATCH_JUMP);
- InjectHook(0x40C580, CCollision::TestSphereTriangle, PATCH_JUMP);
- InjectHook(0x40F720, CCollision::TestLineOfSight, PATCH_JUMP);
-
- InjectHook(0x40B9F0, CCollision::ProcessSphereSphere, PATCH_JUMP);
- InjectHook(0x40BC00, CCollision::ProcessSphereBox, PATCH_JUMP);
- InjectHook(0x40E670, CCollision::ProcessLineBox, PATCH_JUMP);
- InjectHook(0x40DE80, CCollision::ProcessLineSphere, PATCH_JUMP);
- InjectHook(0x40FB50, CCollision::ProcessVerticalLineTriangle, PATCH_JUMP);
- InjectHook(0x40F140, CCollision::ProcessLineTriangle, PATCH_JUMP);
- InjectHook(0x40CE30, CCollision::ProcessSphereTriangle, PATCH_JUMP);
-
- InjectHook(0x40F910, CCollision::ProcessLineOfSight, PATCH_JUMP);
- InjectHook(0x410120, CCollision::ProcessVerticalLine, PATCH_JUMP);
- InjectHook(0x410BE0, CCollision::ProcessColModels, PATCH_JUMP);
-
- InjectHook(0x40B960, CCollision::CalculateTrianglePlanes, PATCH_JUMP);
- InjectHook(0x411640, &CLink<CColModel*>::Remove, PATCH_JUMP);
- InjectHook(0x411620, &CLink<CColModel*>::Insert, PATCH_JUMP);
- InjectHook(0x4115C0, &CLinkList<CColModel*>::Insert, PATCH_JUMP);
- InjectHook(0x411600, &CLinkList<CColModel*>::Remove, PATCH_JUMP);
-// InjectHook(0x411530, &CLinkList<CColModel*>::Init, PATCH_JUMP);
-
- InjectHook(0x411E40, (void (CColSphere::*)(float, const CVector&, uint8, uint8))&CColSphere::Set, PATCH_JUMP);
- InjectHook(0x40B2A0, &CColBox::Set, PATCH_JUMP);
- InjectHook(0x40B320, &CColLine_::ctor, PATCH_JUMP);
- InjectHook(0x40B350, &CColLine::Set, PATCH_JUMP);
- InjectHook(0x411E70, &CColTriangle::Set, PATCH_JUMP);
-
- InjectHook(0x411EA0, &CColTrianglePlane::Set, PATCH_JUMP);
- InjectHook(0x412140, &CColTrianglePlane::GetNormal, PATCH_JUMP);
-
- InjectHook(0x411680, &CColModel_::ctor, PATCH_JUMP);
- InjectHook(0x4116E0, &CColModel_::dtor, PATCH_JUMP);
- InjectHook(0x411D80, &CColModel::RemoveCollisionVolumes, PATCH_JUMP);
- InjectHook(0x411CB0, &CColModel::CalculateTrianglePlanes, PATCH_JUMP);
- InjectHook(0x411D10, &CColModel::RemoveTrianglePlanes, PATCH_JUMP);
- InjectHook(0x411D40, &CColModel::SetLinkPtr, PATCH_JUMP);
- InjectHook(0x411D60, &CColModel::GetLinkPtr, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 1cbd1690..bdf51eb8 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -3,6 +3,13 @@
#include "templates.h"
#include "Game.h" // for eLevelName
+// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
+#ifdef FIX_BUGS
+#define MAX_COLLISION_POINTS 64
+#else
+#define MAX_COLLISION_POINTS 32
+#endif
+
struct CColSphere
{
CVector center;
@@ -110,8 +117,8 @@ struct CColModel
class CCollision
{
public:
- static eLevelName &ms_collisionInMemory;
- static CLinkList<CColModel*> &ms_colModelCache;
+ static eLevelName ms_collisionInMemory;
+ static CLinkList<CColModel*> ms_colModelCache;
static void Init(void);
static void Shutdown(void);
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index 541257c6..f55568be 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -1,7 +1,10 @@
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
+#endif
+
#include "common.h"
-#include "patcher.h"
+#include "crossplatform.h"
#include "ControllerConfig.h"
#include "Pad.h"
#include "FileMgr.h"
@@ -15,10 +18,9 @@
#include "World.h"
#include "ModelIndices.h"
#include "Camera.h"
-#include "win.h"
#include "GenericGameStorage.h"
-CControllerConfigManager &ControlsManager = *(CControllerConfigManager*)0x8F43A4;
+CControllerConfigManager ControlsManager;
CControllerConfigManager::CControllerConfigManager()
{
@@ -41,14 +43,72 @@ void CControllerConfigManager::MakeControllerActionsBlank()
}
}
+#ifdef RW_GL3
+int MapIdToButtonId(int mapId) {
+ switch (mapId) {
+ case GLFW_GAMEPAD_BUTTON_A: // Cross
+ return 2;
+ case GLFW_GAMEPAD_BUTTON_B: // Circle
+ return 1;
+ case GLFW_GAMEPAD_BUTTON_X: // Square
+ return 3;
+ case GLFW_GAMEPAD_BUTTON_Y: // Triangle
+ return 4;
+ case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
+ return 7;
+ case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
+ return 8;
+ case GLFW_GAMEPAD_BUTTON_BACK:
+ return 9;
+ case GLFW_GAMEPAD_BUTTON_START:
+ return 12;
+ case GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
+ return 10;
+ case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
+ return 11;
+ case GLFW_GAMEPAD_BUTTON_DPAD_UP:
+ return 13;
+ case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
+ return 14;
+ case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
+ return 15;
+ case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
+ return 16;
+ // GLFW sends those as axes, so I added them here manually.
+ case 15: // Left trigger
+ return 5;
+ case 16: // Right trigger
+ return 6;
+ default:
+ return 0;
+ }
+}
+#endif
+
int32 CControllerConfigManager::GetJoyButtonJustDown()
{
#ifdef __DINPUT_INCLUDED__
+#ifdef FIX_BUGS
+ for (int32 i = 0; i < MAX_BUTTONS; i++)
+#else
for (int32 i = 0; i < JOY_BUTTONS; i++)
+#endif
{
if (m_NewState.rgbButtons[i] & 0x80 && !(m_OldState.rgbButtons[i] & 0x80))
return i + 1;
}
+#elif defined RW_GL3
+ if (m_NewState.isGamepad) {
+ for (int32 i = 0; i < MAX_BUTTONS; i++) {
+ if (m_NewState.mappedButtons[i] && !(m_OldState.mappedButtons[i]))
+ return MapIdToButtonId(i);
+ }
+ } else {
+ for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
+ if (m_NewState.buttons[i] && !(m_OldState.buttons[i]))
+ return i + 1;
+ }
+ }
#endif
return 0;
}
@@ -249,8 +309,13 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
if (buttons > 16)
btn = 16;
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -445,8 +510,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
break;
}
- if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -872,8 +942,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
break;
}
- if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -1809,7 +1884,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextKeyBoard(e_ControllerAc
static wchar ActionText[50];
static wchar NewStringWithNumber[30];
- for (int32 i = 0; i < ARRAYSIZE(ActionText); i++)
+ for (int32 i = 0; i < ARRAY_SIZE(ActionText); i++)
ActionText[i] = '\0';
if (GetControllerKeyAssociatedWithAction(action, type) != rsNULL)
@@ -2266,6 +2341,19 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
else
m_aButtonStates[i] = false;
}
+#elif defined RW_GL3
+ if (m_NewState.isGamepad) {
+ for (int32 i = 0; i < MAX_BUTTONS; i++) {
+ if (i == GLFW_GAMEPAD_BUTTON_GUIDE)
+ continue;
+
+ m_aButtonStates[MapIdToButtonId(i)-1] = m_NewState.mappedButtons[i];
+ }
+ } else {
+ for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
+ m_aButtonStates[i] = m_NewState.buttons[i];
+ }
+ }
#endif
}
@@ -2362,57 +2450,3 @@ void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action)
}
}
}
-
-
-STARTPATCHES
- InjectHook(0x58B7A0, &CControllerConfigManager::MakeControllerActionsBlank, PATCH_JUMP);
- InjectHook(0x58B7D0, &CControllerConfigManager::GetJoyButtonJustDown, PATCH_JUMP);
- InjectHook(0x58B800, &CControllerConfigManager::SaveSettings, PATCH_JUMP);
- InjectHook(0x58B870, &CControllerConfigManager::LoadSettings, PATCH_JUMP);
- InjectHook(0x58B930, &CControllerConfigManager::InitDefaultControlConfiguration, PATCH_JUMP);
- InjectHook(0x58BD00, &CControllerConfigManager::InitDefaultControlConfigMouse, PATCH_JUMP);
- InjectHook(0x58BD90, &CControllerConfigManager::InitDefaultControlConfigJoyPad, PATCH_JUMP);
- InjectHook(0x58C060, &CControllerConfigManager::InitialiseControllerActionNameArray, PATCH_JUMP);
- InjectHook(0x58C5E0, &CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown, PATCH_JUMP);
- InjectHook(0x58C730, &CControllerConfigManager::AffectControllerStateOn_ButtonDown, PATCH_JUMP);
- InjectHook(0x58C880, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_Driving, PATCH_JUMP);
- InjectHook(0x58CAD0, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnly, PATCH_JUMP);
- InjectHook(0x58CB10, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly, PATCH_JUMP);
- InjectHook(0x58CBD0, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstAndThirdPersonOnly, PATCH_JUMP);
- InjectHook(0x58CD70, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_AllStates, PATCH_JUMP);
- InjectHook(0x58CE50, &CControllerConfigManager::AffectControllerStateOn_ButtonDown_VehicleAndThirdPersonOnly, PATCH_JUMP);
- InjectHook(0x58CE80, &CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp, PATCH_JUMP);
- InjectHook(0x58CFD0, &CControllerConfigManager::AffectControllerStateOn_ButtonUp, PATCH_JUMP);
- InjectHook(0x58D090, &CControllerConfigManager::AffectControllerStateOn_ButtonUp_All_Player_States, PATCH_JUMP);
- InjectHook(0x58D0C0, &CControllerConfigManager::AffectPadFromKeyBoard, PATCH_JUMP);
- InjectHook(0x58D1A0, &CControllerConfigManager::AffectPadFromMouse, PATCH_JUMP);
- InjectHook(0x58D220, &CControllerConfigManager::ClearSimButtonPressCheckers, PATCH_JUMP);
- InjectHook(0x58D2A0, &CControllerConfigManager::GetIsKeyboardKeyDown, PATCH_JUMP);
- InjectHook(0x58D8A0, &CControllerConfigManager::GetIsKeyboardKeyJustDown, PATCH_JUMP);
- InjectHook(0x58E280, &CControllerConfigManager::GetIsMouseButtonDown, PATCH_JUMP);
- InjectHook(0x58E360, &CControllerConfigManager::GetIsMouseButtonUp, PATCH_JUMP);
- InjectHook(0x58E440, &CControllerConfigManager::DeleteMatchingCommonControls, PATCH_JUMP);
- InjectHook(0x58E540, &CControllerConfigManager::DeleteMatching3rdPersonControls, PATCH_JUMP);
- InjectHook(0x58E630, &CControllerConfigManager::DeleteMatching1rst3rdPersonControls, PATCH_JUMP);
- InjectHook(0x58E710, &CControllerConfigManager::DeleteMatchingVehicleControls, PATCH_JUMP);
- InjectHook(0x58E890, &CControllerConfigManager::DeleteMatchingVehicle_3rdPersonControls, PATCH_JUMP);
- InjectHook(0x58E8D0, &CControllerConfigManager::DeleteMatching1rstPersonControls, PATCH_JUMP);
- InjectHook(0x58E920, &CControllerConfigManager::DeleteMatchingActionInitiators, PATCH_JUMP);
- InjectHook(0x58EA70, &CControllerConfigManager::GetIsKeyBlank, PATCH_JUMP);
- InjectHook(0x58EAD0, &CControllerConfigManager::GetActionType, PATCH_JUMP);
- InjectHook(0x58EB40, &CControllerConfigManager::ClearSettingsAssociatedWithAction, PATCH_JUMP);
- InjectHook(0x58EBF0, &CControllerConfigManager::GetControllerSettingTextWithOrderNumber, PATCH_JUMP);
- InjectHook(0x58EC50, &CControllerConfigManager::GetControllerSettingTextKeyBoard, PATCH_JUMP);
- InjectHook(0x58F320, &CControllerConfigManager::GetControllerSettingTextMouse, PATCH_JUMP);
- InjectHook(0x58F3D0, &CControllerConfigManager::GetControllerSettingTextJoystick, PATCH_JUMP);
- InjectHook(0x58F420, &CControllerConfigManager::GetNumOfSettingsForAction, PATCH_JUMP);
- InjectHook(0x58F460, &CControllerConfigManager::GetWideStringOfCommandKeys, PATCH_JUMP);
- InjectHook(0x58F590, &CControllerConfigManager::GetControllerKeyAssociatedWithAction, PATCH_JUMP);
- InjectHook(0x58F5B0, &CControllerConfigManager::UpdateJoyButtonState, PATCH_JUMP);
- InjectHook(0x58F660, &CControllerConfigManager::GetIsActionAButtonCombo, PATCH_JUMP);
- InjectHook(0x58F690, &CControllerConfigManager::GetButtonComboText, PATCH_JUMP);
- InjectHook(0x58F700, &CControllerConfigManager::SetControllerKeyAssociatedWithAction, PATCH_JUMP);
- InjectHook(0x58F740, &CControllerConfigManager::GetMouseButtonAssociatedWithAction, PATCH_JUMP);
- InjectHook(0x58F760, &CControllerConfigManager::SetMouseButtonAssociatedWithAction, PATCH_JUMP);
- InjectHook(0x58F790, &CControllerConfigManager::ResetSettingOrder, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 458e457c..7d0e1073 100644
--- a/src/core/ControllerConfig.h
+++ b/src/core/ControllerConfig.h
@@ -1,5 +1,9 @@
#pragma once
+#if defined RW_D3D9 || defined RWLIBS
+#define DIRECTINPUT_VERSION 0x0800
+#include <dinput.h>
+#endif
// based on x-gtasa
@@ -96,6 +100,16 @@ class CControllerState;
#define ACTIONNAME_LENGTH 40
+#ifdef RW_GL3
+struct GlfwJoyState {
+ int8 id;
+ bool isGamepad;
+ uint8 numButtons;
+ uint8* buttons;
+ bool mappedButtons[17];
+};
+#endif
+
class CControllerConfigManager
{
public:
@@ -112,20 +126,18 @@ public:
};
bool m_bFirstCapture;
- char _pad0[3];
-#ifdef __DINPUT_INCLUDED__
+#if defined RW_GL3
+ GlfwJoyState m_OldState;
+ GlfwJoyState m_NewState;
+#else
DIJOYSTATE2 m_OldState;
DIJOYSTATE2 m_NewState;
-#else
- uint8 ___padd[0x110 * 2];
#endif
wchar m_aActionNames[MAX_CONTROLLERACTIONS][ACTIONNAME_LENGTH];
bool m_aButtonStates[MAX_BUTTONS];
- char _pad1[3];
tControllerConfigBind m_aSettings[MAX_CONTROLLERACTIONS][MAX_CONTROLLERTYPES];
bool m_aSimCheckers[MAX_SIMS][MAX_CONTROLLERTYPES];
bool m_bMouseAssociated;
- char _pad2[3];
CControllerConfigManager();
@@ -196,6 +208,8 @@ public:
void ResetSettingOrder (e_ControllerAction action);
};
+#ifndef RW_GL3
VALIDATE_SIZE(CControllerConfigManager, 0x143C);
+#endif
-extern CControllerConfigManager &ControlsManager; \ No newline at end of file
+extern CControllerConfigManager ControlsManager; \ No newline at end of file
diff --git a/src/core/Crime.h b/src/core/Crime.h
new file mode 100644
index 00000000..8dfae5b8
--- /dev/null
+++ b/src/core/Crime.h
@@ -0,0 +1,36 @@
+#pragma once
+
+enum eCrimeType {
+ CRIME_NONE,
+ CRIME_POSSESSION_GUN,
+ CRIME_HIT_PED,
+ CRIME_HIT_COP,
+ CRIME_SHOOT_PED,
+ CRIME_SHOOT_COP,
+ CRIME_STEAL_CAR,
+ CRIME_RUN_REDLIGHT,
+ CRIME_RECKLESS_DRIVING,
+ CRIME_SPEEDING,
+ CRIME_RUNOVER_PED,
+ CRIME_RUNOVER_COP,
+ CRIME_SHOOT_HELI,
+ CRIME_PED_BURNED,
+ CRIME_COP_BURNED,
+ CRIME_VEHICLE_BURNED,
+ CRIME_DESTROYED_CESSNA,
+ NUM_CRIME_TYPES
+};
+
+class CCrimeBeingQd
+{
+public:
+ eCrimeType m_nType;
+ uint32 m_nId;
+ uint32 m_nTime;
+ CVector m_vecPosn;
+ bool m_bReported;
+ bool m_bPoliceDoesntCare;
+
+ CCrimeBeingQd() { };
+ ~CCrimeBeingQd() { };
+};
diff --git a/src/core/Debug.cpp b/src/core/Debug.cpp
index 917c99ab..e794dcaf 100644
--- a/src/core/Debug.cpp
+++ b/src/core/Debug.cpp
@@ -1,5 +1,7 @@
#include "common.h"
+#include "RwHelper.h"
#include "Debug.h"
+#include "Lines.h"
#include "Font.h"
#include "main.h"
#include "Text.h"
@@ -114,11 +116,14 @@ CDebug::DisplayScreenStrings()
CFont::SetFontStyle(FONT_BANK);
for(i = 0; i < ms_nScreenStrs; i++){
+/*
AsciiToUnicode(ms_aScreenStrs[i].str, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(ms_aScreenStrs[i].x, ms_aScreenStrs[i].y, gUString);
CFont::SetColor(CRGBA(255, 255, 255, 255));
CFont::PrintString(ms_aScreenStrs[i].x+1, ms_aScreenStrs[i].y+1, gUString);
+*/
+ ObrsPrintfString(ms_aScreenStrs[i].str, ms_aScreenStrs[i].x, ms_aScreenStrs[i].y);
}
CFont::DrawFonts();
@@ -131,7 +136,35 @@ CDebug::PrintAt(const char *str, int x, int y)
if(ms_nScreenStrs >= MAX_SCREEN_STRS)
return;
strncpy(ms_aScreenStrs[ms_nScreenStrs].str, str, 256);
- ms_aScreenStrs[ms_nScreenStrs].x = x*12;
- ms_aScreenStrs[ms_nScreenStrs].y = y*22;
+ ms_aScreenStrs[ms_nScreenStrs].x = x;//*12;
+ ms_aScreenStrs[ms_nScreenStrs].y = y;//*22;
ms_nScreenStrs++;
}
+
+CDebug::Line CDebug::ms_aLines[MAX_DEBUG_LINES];
+int CDebug::ms_nLines;
+
+void
+CDebug::AddLine(CVector p1, CVector p2, uint32 c1, uint32 c2)
+{
+ if(ms_nLines >= MAX_DEBUG_LINES)
+ return;
+ ms_aLines[ms_nLines].p1 = p1;
+ ms_aLines[ms_nLines].p2 = p2;
+ ms_aLines[ms_nLines].c1 = c1;
+ ms_aLines[ms_nLines].c2 = c2;
+ ms_nLines++;
+}
+
+void
+CDebug::DrawLines(void)
+{
+ int i;
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ for(i = 0; i < ms_nLines; i++){
+ Line *l = &ms_aLines[i];
+ CLines::RenderLineWithClipping(l->p1.x, l->p1.y, l->p1.z, l->p2.x, l->p2.y, l->p2.z, l->c1, l->c2);
+ }
+ ms_nLines = 0;
+}
diff --git a/src/core/Debug.h b/src/core/Debug.h
index d169a0b4..4a25bf41 100644
--- a/src/core/Debug.h
+++ b/src/core/Debug.h
@@ -8,6 +8,7 @@ class CDebug
MAX_STR_LEN = 80,
MAX_SCREEN_STRS = 100,
+ MAX_DEBUG_LINES = 100,
};
static int16 ms_nCurrentTextLine;
@@ -21,6 +22,13 @@ class CDebug
static ScreenStr ms_aScreenStrs[MAX_SCREEN_STRS];
static int ms_nScreenStrs;
+ struct Line {
+ CVector p1, p2;
+ uint32 c1, c2;
+ };
+ static Line ms_aLines[MAX_DEBUG_LINES];
+ static int ms_nLines;
+
public:
static void DebugInitTextBuffer();
static void DebugDisplayTextBuffer();
@@ -29,6 +37,9 @@ public:
// custom
static void PrintAt(const char *str, int x, int y);
static void DisplayScreenStrings();
+
+ static void AddLine(CVector p1, CVector p2, uint32 c1, uint32 c2);
+ static void DrawLines(void);
};
extern bool gbDebugStuffInRelease;
diff --git a/src/core/Directory.cpp b/src/core/Directory.cpp
index d4b4279d..cc4d65d8 100644
--- a/src/core/Directory.cpp
+++ b/src/core/Directory.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "FileMgr.h"
#include "Directory.h"
@@ -41,9 +41,23 @@ void
CDirectory::AddItem(const DirectoryInfo &dirinfo)
{
assert(numEntries < maxEntries);
+#ifdef FIX_BUGS
+ // don't add if already exists
+ uint32 offset, size;
+ if(FindItem(dirinfo.name, offset, size))
+ return;
+#endif
entries[numEntries++] = dirinfo;
}
+void
+CDirectory::AddItem(const DirectoryInfo &dirinfo, int32 imgId)
+{
+ DirectoryInfo di = dirinfo;
+ di.offset |= imgId<<24;
+ AddItem(di);
+}
+
bool
CDirectory::FindItem(const char *name, uint32 &offset, uint32 &size)
{
@@ -57,10 +71,3 @@ CDirectory::FindItem(const char *name, uint32 &offset, uint32 &size)
}
return false;
}
-
-STARTPATCHES
- InjectHook(0x473630, &CDirectory::ReadDirFile, PATCH_JUMP);
- InjectHook(0x473690, &CDirectory::WriteDirFile, PATCH_JUMP);
- InjectHook(0x473600, &CDirectory::AddItem, PATCH_JUMP);
- InjectHook(0x4736E0, &CDirectory::FindItem, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Directory.h b/src/core/Directory.h
index 06e6bba4..0fef080f 100644
--- a/src/core/Directory.h
+++ b/src/core/Directory.h
@@ -18,5 +18,6 @@ public:
void ReadDirFile(const char *filename);
bool WriteDirFile(const char *filename);
void AddItem(const DirectoryInfo &dirinfo);
+ void AddItem(const DirectoryInfo &dirinfo, int32 imgId);
bool FindItem(const char *name, uint32 &offset, uint32 &size);
};
diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp
index d1c76f33..675040ea 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Pools.h"
#include "ModelIndices.h"
#include "World.h"
@@ -11,7 +11,6 @@
int32 CEventList::ms_nFirstFreeSlotIndex;
CEvent gaEvent[NUMEVENTS];
-//CEvent *gaEvent = (CEvent*)0x6EF830;
enum
{
@@ -228,14 +227,3 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
FindPlayerPed()->SetWantedLevelNoDrop(2);
}
-
-STARTPATCHES
- InjectHook(0x475B60, CEventList::Initialise, PATCH_JUMP);
- InjectHook(0x475BE0, CEventList::Update, PATCH_JUMP);
- InjectHook(0x475C50, (void (*)(eEventType,eEventEntity,CEntity *,CPed *,int32))CEventList::RegisterEvent, PATCH_JUMP);
- InjectHook(0x475E10, (void (*)(eEventType,CVector,int32))CEventList::RegisterEvent, PATCH_JUMP);
- InjectHook(0x475F40, CEventList::GetEvent, PATCH_JUMP);
- InjectHook(0x475F70, CEventList::ClearEvent, PATCH_JUMP);
- InjectHook(0x475F90, CEventList::FindClosestEvent, PATCH_JUMP);
- InjectHook(0x476070, CEventList::ReportCrimeForEvent, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/EventList.h b/src/core/EventList.h
index 1c03c9d6..8840afc4 100644
--- a/src/core/EventList.h
+++ b/src/core/EventList.h
@@ -26,8 +26,7 @@ enum eEventType
EVENT_ICECREAM,
EVENT_ATM,
EVENT_SHOPSTALL, // used on graffitis
- EVENT_SHOPWINDOW,
- EVENT_LAST_EVENT // may be above one
+ EVENT_LAST_EVENT
};
enum eEventEntity
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index e0a0fafc..b7d82089 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "Quaternion.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
@@ -1355,43 +1355,3 @@ CFileLoader::ReLoadScene(const char *filename)
}
CFileMgr::CloseFile(fd);
}
-
-STARTPATCHES
- InjectHook(0x476290, CFileLoader::LoadLevel, PATCH_JUMP);
-
- InjectHook(0x476520, CFileLoader::LoadCollisionFromDatFile, PATCH_JUMP);
- InjectHook(0x4761D0, CFileLoader::LoadLine, PATCH_JUMP);
- InjectHook(0x4765B0, CFileLoader::LoadTexDictionary, PATCH_JUMP);
- InjectHook(0x478B20, CFileLoader::LoadCollisionFile, PATCH_JUMP);
- InjectHook(0x478C20, CFileLoader::LoadCollisionModel, PATCH_JUMP);
- InjectHook(0x476750, CFileLoader::LoadModelFile, PATCH_JUMP);
- InjectHook(0x476810, (void (*)(const char*))CFileLoader::LoadClumpFile, PATCH_JUMP);
- InjectHook(0x476990, (bool (*)(RwStream*,uint32))CFileLoader::LoadClumpFile, PATCH_JUMP);
- InjectHook(0x476A20, CFileLoader::StartLoadClumpFile, PATCH_JUMP);
- InjectHook(0x476A70, CFileLoader::FinishLoadClumpFile, PATCH_JUMP);
- InjectHook(0x476930, CFileLoader::LoadAtomicFile, PATCH_JUMP);
- InjectHook(0x4767C0, CFileLoader::LoadAtomicFile2Return, PATCH_JUMP);
- InjectHook(0x476630, CFileLoader::AddTexDictionaries, PATCH_JUMP);
-
- InjectHook(0x476AC0, CFileLoader::LoadObjectTypes, PATCH_JUMP);
- InjectHook(0x477040, CFileLoader::LoadObject, PATCH_JUMP);
- InjectHook(0x4774B0, CFileLoader::LoadTimeObject, PATCH_JUMP);
- InjectHook(0x477920, CFileLoader::LoadClumpObject, PATCH_JUMP);
- InjectHook(0x477990, CFileLoader::LoadVehicleObject, PATCH_JUMP);
- InjectHook(0x477DE0, CFileLoader::LoadPedObject, PATCH_JUMP);
- InjectHook(0x477ED0, CFileLoader::LoadPathHeader, PATCH_JUMP);
- InjectHook(0x477FF0, CFileLoader::LoadCarPathNode, PATCH_JUMP);
- InjectHook(0x477F00, CFileLoader::LoadPedPathNode, PATCH_JUMP);
- InjectHook(0x4780E0, CFileLoader::Load2dEffect, PATCH_JUMP);
-
- InjectHook(0x478370, CFileLoader::LoadScene, PATCH_JUMP);
- InjectHook(0x4786B0, CFileLoader::LoadObjectInstance, PATCH_JUMP);
- InjectHook(0x478A00, CFileLoader::LoadZone, PATCH_JUMP);
- InjectHook(0x478A90, CFileLoader::LoadCullZone, PATCH_JUMP);
-
- InjectHook(0x478550, CFileLoader::LoadMapZones, PATCH_JUMP);
-
- InjectHook(0x476DB0, CFileLoader::ReloadPaths, PATCH_JUMP);
- InjectHook(0x476F30, CFileLoader::ReloadObjectTypes, PATCH_JUMP);
- InjectHook(0x4772B0, CFileLoader::ReloadObject, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp
index 2a8628b0..46d725cd 100644
--- a/src/core/FileMgr.cpp
+++ b/src/core/FileMgr.cpp
@@ -2,7 +2,7 @@
#include <fcntl.h>
#include <direct.h>
#include "common.h"
-#include "patcher.h"
+
#include "FileMgr.h"
const char *_psGetUserFilesFolder();
@@ -168,8 +168,8 @@ myfeof(int fd)
}
-char *CFileMgr::ms_rootDirName = (char*)0x5F18F8;
-char *CFileMgr::ms_dirName = (char*)0x713CA8;
+char CFileMgr::ms_rootDirName[128] = {'\0'};
+char CFileMgr::ms_dirName[128];
void
CFileMgr::Initialise(void)
@@ -282,19 +282,3 @@ CFileMgr::GetErrorReadWrite(int fd)
{
return myfeof(fd);
}
-
-STARTPATCHES
- InjectHook(0x478F80, CFileMgr::Initialise, PATCH_JUMP);
- InjectHook(0x478FB0, CFileMgr::ChangeDir, PATCH_JUMP);
- InjectHook(0x479020, CFileMgr::SetDir, PATCH_JUMP);
- InjectHook(0x479080, CFileMgr::SetDirMyDocuments, PATCH_JUMP);
- InjectHook(0x479090, CFileMgr::LoadFile, PATCH_JUMP);
- InjectHook(0x479100, CFileMgr::OpenFile, PATCH_JUMP);
- InjectHook(0x479120, CFileMgr::OpenFileForWriting, PATCH_JUMP);
- InjectHook(0x479140, CFileMgr::Read, PATCH_JUMP);
- InjectHook(0x479160, CFileMgr::Write, PATCH_JUMP);
- InjectHook(0x479180, CFileMgr::Seek, PATCH_JUMP);
- InjectHook(0x4791D0, CFileMgr::ReadLine, PATCH_JUMP);
- InjectHook(0x479200, CFileMgr::CloseFile, PATCH_JUMP);
- InjectHook(0x479210, CFileMgr::GetErrorReadWrite, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h
index 3df0c7d8..a6e4b6e5 100644
--- a/src/core/FileMgr.h
+++ b/src/core/FileMgr.h
@@ -2,8 +2,8 @@
class CFileMgr
{
- static char *ms_rootDirName; //[128];
- static char *ms_dirName; //[128];
+ static char ms_rootDirName[128];
+ static char ms_dirName[128];
public:
static void Initialise(void);
static void ChangeDir(const char *dir);
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index cfa849e9..65b6deb2 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Vector.h"
#include "PlayerPed.h"
#include "Entity.h"
@@ -16,7 +16,7 @@
#include "Ped.h"
#include "Fire.h"
-CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
+CFireManager gFireManager;
CFire::CFire()
{
@@ -438,21 +438,3 @@ CFireManager::SetScriptFireAudio(int16 index, bool state)
{
m_aFires[index].m_bAudioSet = state;
}
-
-STARTPATCHES
- InjectHook(0x4798D0, &CFire::ProcessFire, PATCH_JUMP);
- InjectHook(0x4798B0, &CFire::ReportThisFire, PATCH_JUMP);
- InjectHook(0x479D40, &CFire::Extinguish, PATCH_JUMP);
- InjectHook(0x479500, (void(CFireManager::*)(CVector pos, float size, bool propagation))&CFireManager::StartFire, PATCH_JUMP);
- InjectHook(0x479590, (CFire *(CFireManager::*)(CEntity *, CEntity *, float, bool))&CFireManager::StartFire, PATCH_JUMP);
- InjectHook(0x479310, &CFireManager::Update, PATCH_JUMP);
- InjectHook(0x479430, &CFireManager::FindFurthestFire_NeverMindFireMen, PATCH_JUMP);
- InjectHook(0x479340, &CFireManager::FindNearestFire, PATCH_JUMP);
- InjectHook(0x4792E0, &CFireManager::GetNextFreeFire, PATCH_JUMP);
- InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP);
- InjectHook(0x479E60, &CFireManager::StartScriptFire, PATCH_JUMP);
- InjectHook(0x479FC0, &CFireManager::IsScriptFireExtinguish, PATCH_JUMP);
- InjectHook(0x47A000, &CFireManager::RemoveAllScriptFires, PATCH_JUMP);
- InjectHook(0x479FE0, &CFireManager::RemoveScriptFire, PATCH_JUMP);
- InjectHook(0x47A040, &CFireManager::SetScriptFireAudio, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Fire.h b/src/core/Fire.h
index a4599d11..85e53f61 100644
--- a/src/core/Fire.h
+++ b/src/core/Fire.h
@@ -48,4 +48,4 @@ public:
void RemoveScriptFire(int16 index);
void SetScriptFireAudio(int16 index, bool state);
};
-extern CFireManager &gFireManager;
+extern CFireManager gFireManager;
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 5d5d0af7..f3823f1d 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -1,8 +1,11 @@
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
+#endif
+
+#define WITHWINDOWS
#include "common.h"
-#include "patcher.h"
-#include "win.h"
+#include "crossplatform.h"
#include "Frontend.h"
#include "Font.h"
#include "Pad.h"
@@ -82,34 +85,34 @@ int curBottomBarOption = -1;
int hoveredBottomBarOption = -1;
#endif
-int32 CMenuManager::OS_Language = LANG_ENGLISH; // *(int32*)0x5F2F78;
-int8 CMenuManager::m_PrefsUseVibration; // = *(int8*)0x95CD92;
-int8 CMenuManager::m_DisplayControllerOnFoot; // = *(int8*)0x95CD8D;
-int8 CMenuManager::m_PrefsVsync = 1; // *(int8*)0x5F2E58;
-int8 CMenuManager::m_PrefsVsyncDisp = 1; // *(int8*)0x5F2E5C;
-int8 CMenuManager::m_PrefsFrameLimiter = 1; // *(int8*)0x5F2E60;
-int8 CMenuManager::m_PrefsShowSubtitles = 1; // *(int8*)0x5F2E54;
-int8 CMenuManager::m_PrefsSpeakers; // = *(int8*)0x95CD7E;
-int32 CMenuManager::m_ControlMethod; // = *(int32*)0x8F5F7C;
-int8 CMenuManager::m_PrefsDMA = 1; // *(int8*)0x5F2F74;
-int32 CMenuManager::m_PrefsLanguage; // = *(int32*)0x941238;
-uint8 CMenuManager::m_PrefsStereoMono; // *(bool*)0x95CDB5; // unused except restore settings
-
-bool CMenuManager::m_PrefsAllowNastyGame = true; // *(bool*)0x5F2E64;
-bool CMenuManager::m_bStartUpFrontEndRequested; // = *(bool*)0x95CCF4;
-bool CMenuManager::m_bShutDownFrontEndRequested; // = *(bool*)0x95CD6A;
-
-int8 CMenuManager::m_PrefsUseWideScreen; // = *(int8*)0x95CD23;
-int8 CMenuManager::m_PrefsRadioStation; // = *(int8*)0x95CDA4;
-int32 CMenuManager::m_PrefsBrightness = 256; // = *(int32*)0x5F2E50;
-float CMenuManager::m_PrefsLOD; // = *(float*)0x8F42C4;
-int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; // = *(int8*)0x628CFC;
-int32 CMenuManager::m_PrefsMusicVolume = 102; // = *(int32*)0x5F2E4C;
-int32 CMenuManager::m_PrefsSfxVolume = 102; // = *(int32*)0x5F2E48;
-
-char CMenuManager::m_PrefsSkinFile[256] = "$$\"\""; // = (char*)0x5F2E74;
-
-int32 CMenuManager::m_KeyPressedCode = -1; // = *(int32*)0x5F2E70;
+int32 CMenuManager::OS_Language = LANG_ENGLISH;
+int8 CMenuManager::m_PrefsUseVibration;
+int8 CMenuManager::m_DisplayControllerOnFoot;
+int8 CMenuManager::m_PrefsVsync = 1;
+int8 CMenuManager::m_PrefsVsyncDisp = 1;
+int8 CMenuManager::m_PrefsFrameLimiter = 1;
+int8 CMenuManager::m_PrefsShowSubtitles = 1;
+int8 CMenuManager::m_PrefsSpeakers;
+int32 CMenuManager::m_ControlMethod;
+int8 CMenuManager::m_PrefsDMA = 1;
+int32 CMenuManager::m_PrefsLanguage;
+uint8 CMenuManager::m_PrefsStereoMono; // unused except restore settings
+
+bool CMenuManager::m_PrefsAllowNastyGame = true;
+bool CMenuManager::m_bStartUpFrontEndRequested;
+bool CMenuManager::m_bShutDownFrontEndRequested;
+
+int8 CMenuManager::m_PrefsUseWideScreen;
+int8 CMenuManager::m_PrefsRadioStation;
+int32 CMenuManager::m_PrefsBrightness = 256;
+float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale;
+int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt;
+int32 CMenuManager::m_PrefsMusicVolume = 102;
+int32 CMenuManager::m_PrefsSfxVolume = 102;
+
+char CMenuManager::m_PrefsSkinFile[256] = "$$\"\"";
+
+int32 CMenuManager::m_KeyPressedCode = -1;
// 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
@@ -118,30 +121,26 @@ const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255);
const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color
#endif
-const float menuXYpadding = MENUACTION_POS_Y; // *(float*)0x5F355C; // not original name
-float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; //*(float*)0x5F2E40;
-float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; //*(float*)0x5F2E44;
+float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE;
+float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE;
bool holdingScrollBar; // *(bool*)0x628D59; // not original name
-int32 CMenuManager::m_SelectedMap; // *(int32*)0x8E2880;
-int32 CMenuManager::m_SelectedGameType; // *(int32*)0x942F88;
+int32 CMenuManager::m_SelectedMap;
+int32 CMenuManager::m_SelectedGameType;
// Used in a hidden menu
uint8 CMenuManager::m_PrefsPlayerRed = 255;
uint8 CMenuManager::m_PrefsPlayerGreen = 128;
uint8 CMenuManager::m_PrefsPlayerBlue; // why??
-CMenuManager FrontEndMenuManager; // = *(CMenuManager*)0x8F59D8;
+CMenuManager FrontEndMenuManager;
-// Move this somewhere else.
-float CRenderer::ms_lodDistScale = 1.2f; // *(float*)0x5F726C;
-
-uint32 TimeToStopPadShaking; // = *(uint32*)0x628CF8;
-char *pEditString; // = *(char**)0x628D00;
-int32 *pControlEdit; // = *(int32**)0x628D08;
-bool DisplayComboButtonErrMsg; // = *(bool*)0x628D14;
-int32 MouseButtonJustClicked; // = *(int32*)0x628D0C;
-int32 JoyButtonJustClicked; // = *(int32*)0x628D10;
+uint32 TimeToStopPadShaking;
+char *pEditString;
+int32 *pControlEdit;
+bool DisplayComboButtonErrMsg;
+int32 MouseButtonJustClicked;
+int32 JoyButtonJustClicked;
//int32 *pControlTemp = 0;
#ifndef MASTER
@@ -170,15 +169,15 @@ const char* FrontendFilenames[][2] = {
{"fe_arrows2", "" },
{"fe_arrows3", "" },
{"fe_arrows4", "" },
- {"fe_radio1", "" }, // HEAD_RADIO
- {"fe_radio2", "" }, // DOUBLE_CLEF
- {"fe_radio3", "" }, // JAH_RADIO
- {"fe_radio4", "" }, // RISE_FM
- {"fe_radio5", "" }, // LIPS_106
- {"fe_radio6", "" }, // GAME_FM
- {"fe_radio7", "" }, // MSX_FM
- {"fe_radio8", "" }, // FLASHBACK
- {"fe_radio9", "" }, // CHATTERBOX
+ {"fe_radio1", "" },
+ {"fe_radio2", "" },
+ {"fe_radio3", "" },
+ {"fe_radio4", "" },
+ {"fe_radio5", "" },
+ {"fe_radio6", "" },
+ {"fe_radio7", "" },
+ {"fe_radio8", "" },
+ {"fe_radio9", "" },
};
#ifdef MENU_MAP
@@ -283,9 +282,15 @@ ScaleAndCenterX(float x)
} while(0)
#endif
+#define PREPARE_MENU_HEADER \
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \
+ CFont::SetRightJustifyOn(); \
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \
+ CFont::SetFontStyle(FONT_HEADING);
+
#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
do { \
- lastActiveBarX = DisplaySlider(SCREEN_STRETCH_FROM_RIGHT(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
+ lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
if (i != m_nCurrOption || !itemsAreSelectable) \
break; \
\
@@ -296,10 +301,17 @@ ScaleAndCenterX(float x)
break; \
\
m_nHoverOption = increaseAction; \
- if (m_nMousePosX < SCREEN_STRETCH_FROM_RIGHT(MENUSLIDER_X + columnWidth)) \
+ if (m_nMousePosX < MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth)) \
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
} while(0)
+#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)); \
+ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \
+ m_nHoverOption = hoverOpt; \
+ } while (0)
+
// --- Functions not in the game/inlined starts
inline void
@@ -340,8 +352,8 @@ CMenuManager::PageUpList(bool playSoundOnSuccess)
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
- m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
- m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
+ m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
+ m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
} else {
m_nFirstVisibleRowOnList = 0;
m_nSelectedListRow = 0;
@@ -358,8 +370,8 @@ CMenuManager::PageDownList(bool playSoundOnSuccess)
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
- m_nFirstVisibleRowOnList = min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW);
- m_nSelectedListRow = max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
+ m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW);
+ m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
} else {
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
m_nSelectedListRow = m_nTotalListRow - 1;
@@ -421,13 +433,16 @@ CMenuManager::BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2)
void
CMenuManager::CentreMousePointer()
{
- tagPOINT Point;
-
if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) {
+#if defined RW_D3D9 || defined RWLIBS
+ tagPOINT Point;
Point.x = SCREEN_WIDTH / 2;
Point.y = SCREEN_HEIGHT / 2;
ClientToScreen(PSGLOBAL(window), &Point);
SetCursorPos(Point.x, Point.y);
+#elif defined RW_GL3
+ glfwSetCursorPos(PSGLOBAL(window), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
+#endif
PSGLOBAL(lastMousePos.x) = SCREEN_WIDTH / 2;
PSGLOBAL(lastMousePos.y) = SCREEN_HEIGHT / 2;
@@ -447,8 +462,8 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
if (typeOfControl == KEYBOARD) {
if (*pControlEdit == rsESC) {
escPressed = true;
- } else if (*pControlEdit > rsF3 && *pControlEdit != rsF9 && *pControlEdit != rsLWIN &&
- *pControlEdit != rsRWIN && *pControlEdit != rsRALT) {
+ } else if (*pControlEdit != rsF1 && *pControlEdit != rsF2 && *pControlEdit != rsF3 && *pControlEdit != rsF9 &&
+ *pControlEdit != rsLWIN && *pControlEdit != rsRWIN && *pControlEdit != rsRALT) {
typeToSave = KEYBOARD;
if (ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD) != rsNULL &&
*pControlEdit != ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD)) {
@@ -465,7 +480,10 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
DisplayComboButtonErrMsg = true;
}
- ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
+#ifdef FIX_BUGS
+ if(!escPressed && !invalidKey)
+#endif
+ ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
if (!DisplayComboButtonErrMsg && !escPressed && !invalidKey) {
if (typeOfControl == KEYBOARD) {
ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, KEYBOARD);
@@ -631,7 +649,7 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
} else
color = CRGBA(185, 120, 0, FadeIn(255));
- maxBarHeight = max(mostLeftBarSize, mostRightBarSize);
+ maxBarHeight = Max(mostLeftBarSize, mostRightBarSize);
float curBarFreeSpace = ((16 - i) * mostLeftBarSize + i * mostRightBarSize) / 16.0f;
float left = curBarX;
@@ -670,6 +688,17 @@ CMenuManager::Draw()
CFont::SetCentreOff();
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
+#ifdef GTA3_1_1_PATCH
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::SetRightJustifyOn();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f));
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::SetRightJustifyWrap(0.0f);
+ strcpy(gString, "V1.1");
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString);
+#endif
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
@@ -696,17 +725,9 @@ CMenuManager::Draw()
#endif
if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') {
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONTJAP(FONT_HEADING));
-#ifdef PS2_LIKE_MENU
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(1.3f));
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(75.0f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
-#else
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ PREPARE_MENU_HEADER
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
-#endif
+
// Weird place to put that.
nextYToUse += 24.0f + 10.0f;
}
@@ -745,9 +766,9 @@ CMenuManager::Draw()
#ifdef FIX_BUGS
// Label is wrapped from right by StretchX(40)px, but wrapped from left by 40px. And this is only place R* didn't use StretchX in here.
- CFont::PrintString(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN), MENU_Y(menuXYpadding), str);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN), MENU_Y(MENUACTION_POS_Y), str);
#else
- CFont::PrintString(MENU_X_MARGIN, menuXYpadding, str);
+ CFont::PrintString(MENU_X_MARGIN, MENUACTION_POS_Y, str);
#endif
}
@@ -1112,7 +1133,7 @@ CMenuManager::Draw()
int extraOffset = 0;
if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO)
- extraOffset = (int) 60.0f;
+ extraOffset = MENURADIO_ICON_SCALE;
// There were many unused codes in here to calculate how much space will texts gonna take.
@@ -1222,7 +1243,6 @@ CMenuManager::Draw()
}
// Sliders
- // We stretch slider start X here(like original code), because it will always be center of screen
int lastActiveBarX;
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
case MENUACTION_BRIGHTNESS:
@@ -1242,29 +1262,24 @@ CMenuManager::Draw()
break;
}
- nextYToUse += lineHeight * CFont::GetNumberLines(menuXYpadding, nextYToUse, leftText);
+ // 60.0 is silly
+ nextYToUse += lineHeight * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText);
- // TODO: This should be rewritten as multiple macro calls instead of loop, radio order is wrong.
- // And hover detection is missing.
- float fIconSpacing = 59.52f;
+ // Radio icons
if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) {
- for (int i = 0; i < POLICE_RADIO; i++) {
-#ifndef ASPECT_RATIO_SCALE
- if (i < USERTRACK)
- m_aFrontEndSprites[i + FE_RADIO1].Draw(SCREEN_STRETCH_X(MENURADIO_ICON_X + fIconSpacing * i), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(MENURADIO_ICON_Y), SCREEN_SCALE_X(MENURADIO_ICON_W), SCREEN_SCALE_Y(MENURADIO_ICON_H), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170));
- if (i > CHATTERBOX && DMAudio.IsMP3RadioChannelAvailable())
- m_aMenuSprites[MENUSPRITE_MP3LOGO].Draw(SCREEN_STRETCH_X(MENURADIO_ICON_X + fIconSpacing * i), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(MENURADIO_ICON_Y), SCREEN_SCALE_X(MENURADIO_ICON_W), SCREEN_SCALE_Y(MENURADIO_ICON_H), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170));
-#else
- float fMp3Pos = 0.0f;
- if (DMAudio.IsMP3RadioChannelAvailable())
- fMp3Pos = 34.0f;
-
- if (i < USERTRACK)
- m_aFrontEndSprites[i + FE_RADIO1].Draw((SCREEN_WIDTH * 0.5) + SCREEN_SCALE_X(-fMp3Pos + MENURADIO_ICON_X + (fIconSpacing * i)), MENU_Y(nextYToUse), MENU_X(menuXYpadding), MENU_Y(menuXYpadding), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170));
- if (i > CHATTERBOX && DMAudio.IsMP3RadioChannelAvailable())
- m_aMenuSprites[MENUSPRITE_MP3LOGO].Draw((SCREEN_WIDTH * 0.5) + SCREEN_SCALE_X(-fMp3Pos + MENURADIO_ICON_X + (fIconSpacing * i)), MENU_Y(nextYToUse), MENU_X(menuXYpadding), MENU_Y(menuXYpadding), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170));
-#endif
- }
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO1], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO2], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO5], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO7], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO8], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO3], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO4], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO6], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7);
+ ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO9], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8);
+
+ if (DMAudio.IsMP3RadioChannelAvailable())
+ ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9);
+
nextYToUse += 70.0f;
}
}
@@ -1735,11 +1750,8 @@ CMenuManager::DrawControllerSetupScreen()
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
- // Page header
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetRightJustifyOn();
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
- CFont::SetFontStyle(FONTJAP(FONT_HEADING));
+ PREPARE_MENU_HEADER
+
switch (m_ControlMethod) {
case CONTROL_STANDARD:
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
@@ -2417,10 +2429,8 @@ CMenuManager::DrawPlayerSetupScreen()
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONTJAP(FONT_HEADING));
+ PREPARE_MENU_HEADER
+
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
// lstrcpy's changed with strcpy
@@ -2488,7 +2498,7 @@ CMenuManager::DrawPlayerSetupScreen()
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1);
if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1))
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1);
- if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1))
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "�", 1))
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1);
}
@@ -2825,7 +2835,7 @@ CMenuManager::FadeIn(int alpha)
m_nCurrScreen == MENUPAGE_DELETING)
return alpha;
- return min(m_nMenuFadeAlpha, alpha);
+ return Min(m_nMenuFadeAlpha, alpha);
}
void
@@ -2889,6 +2899,9 @@ CMenuManager::InitialiseChangedLanguageSettings()
CGame::germanGame = false;
#ifdef MORE_LANGUAGES
switch (m_PrefsLanguage) {
+ case LANGUAGE_POLISH:
+ CFont::ReloadFonts(FONT_LANGSET_POLISH);
+ break;
case LANGUAGE_RUSSIAN:
CFont::ReloadFonts(FONT_LANGSET_RUSSIAN);
break;
@@ -2909,6 +2922,9 @@ CMenuManager::InitialiseChangedLanguageSettings()
CGame::germanGame = true;
break;
#ifdef MORE_LANGUAGES
+ case LANGUAGE_POLISH:
+ CGame::polishGame = true;
+ break;
case LANGUAGE_RUSSIAN:
CGame::russianGame = true;
break;
@@ -3180,7 +3196,7 @@ CMenuManager::PrintBriefs()
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
- float nextY = 40.0f;
+ float nextY = BRIEFS_TOP_MARGIN;
CRGBA newColor;
for (int i = 4; i >= 0; i--) {
tPreviousBrief &brief = CMessages::PreviousBriefs[i];
@@ -3213,8 +3229,8 @@ CMenuManager::PrintBriefs()
newColor.a = FadeIn(255);
CFont::SetColor(newColor);
#endif
- CFont::PrintString(MENU_X_LEFT_ALIGNED(50.0f), nextY, gUString);
- nextY += MENU_Y(menuXYpadding);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString);
+ nextY += MENU_Y(BRIEFS_LINE_HEIGHT);
}
}
@@ -3251,6 +3267,9 @@ void
CMenuManager::PrintStats()
{
int rowNum = ConstructStatLine(99999);
+#ifdef GTA3_1_1_PATCH
+ CFont::SetFontStyle(FONT_BANK);
+#endif
CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
float nextYChange, y, alphaMult;
@@ -3317,10 +3336,7 @@ CMenuManager::PrintStats()
// ::Draw already does that.
/*
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ PREPARE_MENU_HEADER
CFont::PrintString(MENU_X_RIGHT_ALIGNED(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));
@@ -3384,8 +3400,7 @@ CMenuManager::Process(void)
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
- }
- else
+ } else
SaveLoadFileError_SetUpErrorScreen();
}
@@ -4254,6 +4269,12 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
#ifdef MORE_LANGUAGES
+ case MENUACTION_LANG_PL:
+ m_PrefsLanguage = LANGUAGE_POLISH;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
case MENUACTION_LANG_RUS:
m_PrefsLanguage = LANGUAGE_RUSSIAN;
m_bFrontEnd_ReloadObrTxtGxt = true;
@@ -4468,12 +4489,20 @@ CMenuManager::ProcessButtonPresses(void)
ControlsManager.MakeControllerActionsBlank();
ControlsManager.InitDefaultControlConfiguration();
ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
- if (AllValidWinJoys.m_aJoys[0].m_bInitialised) {
+#if !defined RW_GL3
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_bInitialised) {
DIDEVCAPS devCaps;
devCaps.dwSize = sizeof(DIDEVCAPS);
PSGLOBAL(joy1)->GetCapabilities(&devCaps);
ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
}
+#else
+ if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ }
+#endif
m_ControlMethod = CONTROL_STANDARD;
MousePointerStateHelper.bInvertVertically = false;
TheCamera.m_fMouseAccelHorzntl = 0.0025f;
@@ -5254,6 +5283,7 @@ CMenuManager::PrintController(void)
void
CMenuManager::PrintMap(void)
{
+ CFont::SetJustifyOn();
bMenuMapActive = true;
CRadar::InitFrontEndMap();
@@ -5398,7 +5428,7 @@ CMenuManager::PrintMap(void)
if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f))
fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize;
- fMapCenterY = min(fMapCenterY, fMapSize); // To not show beyond north border
+ fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border
bMenuMapActive = false;
@@ -5460,7 +5490,7 @@ CMenuManager::ConstructStatLine(int rowIdx)
int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1));
- percentCompleted = min(percentCompleted, 100);
+ percentCompleted = Min(percentCompleted, 100);
STAT_LINE("PER_COM", &percentCompleted, false, nil);
STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil);
@@ -5474,7 +5504,8 @@ CMenuManager::ConstructStatLine(int rowIdx)
if (player.m_nTotalPackages != 0)
packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
- STAT_LINE("PERPIC", &packagesPercent, 0, &(nTemp = 100));
+ int nPackagesPercent = packagesPercent;
+ STAT_LINE("PERPIC", &nPackagesPercent, 0, &(nTemp = 100));
STAT_LINE("NOUNIF", &CStats::TotalNumberOfUniqueJumps, 0, &CStats::NumberOfUniqueJumpsFound);
STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil);
if (CGame::nastyGame) {
@@ -5554,6 +5585,7 @@ CMenuManager::ConstructStatLine(int rowIdx)
case LANGUAGE_ITALIAN:
case LANGUAGE_SPANISH:
#ifdef MORE_LANGUAGES
+ case LANGUAGE_POLISH:
case LANGUAGE_RUSSIAN:
#endif
STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil);
@@ -5631,21 +5663,3 @@ uint8 CMenuManager::GetNumberOfMenuOptions()
#undef GetBackJustUp
#undef GetBackJustDown
-
-STARTPATCHES
- for (int i = 1; i < ARRAY_SIZE(aScreens); i++)
- Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]);
- InjectHook(0x4856F0, &CMenuManager::ProcessButtonPresses, PATCH_JUMP);
- InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP);
- InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
- InjectHook(0x47A540, &CMenuManager::DrawFrontEnd, PATCH_JUMP);
-
- InjectHook(0x48ABE0, &CMenuManager::StretchX, PATCH_JUMP);
- InjectHook(0x48AC20, &CMenuManager::StretchY, PATCH_JUMP);
- InjectHook(0x488EE0, &CMenuManager::LoadSettings, PATCH_JUMP);
- InjectHook(0x488CC0, &CMenuManager::SaveSettings, PATCH_JUMP);
- InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP);
- InjectHook(0x48AB40, &CMenuManager::DoSettingsBeforeStartingAGame, PATCH_JUMP);
- InjectHook(0x48AE60, &CMenuManager::ProcessOnOffMenuOptions, PATCH_JUMP);
- InjectHook(0x489710, &CMenuManager::DrawControllerBound, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 792f0c45..6a18ce7a 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -1,25 +1,24 @@
-#pragma
+#pragma once
#include "Sprite2d.h"
+#ifdef PS2_LIKE_MENU
+#define MENUHEADER_POS_X 50.0f
+#define MENUHEADER_POS_Y 75.0f
+#define MENUHEADER_HEIGHT 1.3f
+#else
#define MENUHEADER_POS_X 35.0f
#define MENUHEADER_POS_Y 93.0f
-#define MENUHEADER_WIDTH 0.84f
#define MENUHEADER_HEIGHT 1.6f
+#endif
+#define MENUHEADER_WIDTH 0.84f
#define MENU_X_MARGIN 40.0f
#define MENUACTION_POS_Y 60.0f
#define MENUACTION_WIDTH 38.0f
#define MENUACTION_SCALE_MULT 0.9f
-#ifndef ASPECT_RATIO_SCALE
-#define MENURADIO_ICON_X 31.5f
-#else
-#define MENURADIO_ICON_X -262.0f
-#endif
-#define MENURADIO_ICON_Y 29.5f
-#define MENURADIO_ICON_W 60.0f
-#define MENURADIO_ICON_H 60.0f
+#define MENURADIO_ICON_SCALE 60.0f
#define MENUSLIDER_X 256.0f
#define MENUSLIDER_UNK 256.0f
@@ -62,6 +61,10 @@
#define STATS_RATING_X 24.0f
#define STATS_RATING_Y 20.0f
+#define BRIEFS_TOP_MARGIN 40.0f
+#define BRIEFS_LINE_X 50.0f
+#define BRIEFS_LINE_HEIGHT 60.0f
+
#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
#define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10
@@ -86,6 +89,7 @@ enum eLanguages
LANGUAGE_ITALIAN,
LANGUAGE_SPANISH,
#ifdef MORE_LANGUAGES
+ LANGUAGE_POLISH,
LANGUAGE_RUSSIAN,
LANGUAGE_JAPANESE,
#endif
@@ -363,6 +367,7 @@ enum eMenuAction
MENUACTION_UNK109,
MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
+ MENUACTION_LANG_PL,
MENUACTION_LANG_RUS,
MENUACTION_LANG_JAP,
#endif
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index daac3ec5..8633d222 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -1,11 +1,9 @@
#pragma warning( push )
#pragma warning( disable : 4005)
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
#pragma warning( pop )
#include "common.h"
-#include "win.h"
-#include "patcher.h"
+#include "crossplatform.h"
+
#include "Game.h"
#include "main.h"
#include "RwHelper.h"
@@ -72,7 +70,7 @@
#include "Streaming.h"
#include "SurfaceTable.h"
#include "TempColModels.h"
-#include "TimeCycle.h"
+#include "Timecycle.h"
#include "TrafficLights.h"
#include "Train.h"
#include "TxdStore.h"
@@ -86,22 +84,24 @@
#include "World.h"
#include "ZoneCull.h"
#include "Zones.h"
+#include "debugmenu.h"
-eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
-bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
-bool &CGame::nastyGame = *(bool*)0x5F4DD4;
-bool &CGame::frenchGame = *(bool*)0x95CDCB;
-bool &CGame::germanGame = *(bool*)0x95CD1E;
-bool &CGame::noProstitutes = *(bool*)0x95CDCF;
-bool &CGame::playingIntro = *(bool*)0x95CDC2;
-char *CGame::aDatFile = (char*)0x773A48;
+eLevelName CGame::currLevel;
+bool CGame::bDemoMode = true;
+bool CGame::nastyGame = true;
+bool CGame::frenchGame;
+bool CGame::germanGame;
+bool CGame::noProstitutes;
+bool CGame::playingIntro;
+char CGame::aDatFile[32];
#ifdef MORE_LANGUAGES
+bool CGame::polishGame = false;
bool CGame::russianGame = false;
#endif
-int &gameTxdSlot = *(int*)0x628D88;
+int gameTxdSlot;
bool
CGame::InitialiseOnceBeforeRW(void)
@@ -115,7 +115,9 @@ CGame::InitialiseOnceBeforeRW(void)
bool
CGame::InitialiseRenderWare(void)
{
+#ifdef USE_TEXTURE_POOL
_TexturePoolsInitialise();
+#endif
CTxdStore::Initialise();
CVisibilityPlugins::Initialise();
@@ -153,6 +155,14 @@ CGame::InitialiseRenderWare(void)
LightsCreate(Scene.world);
CreateDebugFont();
+
+#ifdef LIBRW
+#ifdef PS2_MATFX
+ rw::MatFX::modulateEnvMap = true;
+#else
+ rw::MatFX::modulateEnvMap = false;
+#endif
+#endif
CFont::Initialise();
CHud::Initialise();
@@ -188,7 +198,9 @@ void CGame::ShutdownRenderWare(void)
CVisibilityPlugins::Shutdown();
+#ifdef USE_TEXTURE_POOL
_TexturePoolsShutdown();
+#endif
}
bool CGame::InitialiseOnceAfterRW(void)
@@ -307,6 +319,7 @@ bool CGame::Initialise(const char* datFile)
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
+#ifdef USE_TXD_CDIMAGE
int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r");
if (txdHandle)
CFileMgr::CloseFile(txdHandle);
@@ -321,6 +334,9 @@ bool CGame::Initialise(const char* datFile)
CStreaming::Init();
}
}
+#else
+ CStreaming::Init();
+#endif
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
@@ -350,7 +366,7 @@ bool CGame::Initialise(const char* datFile)
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
- CSceneEdit::Init();
+ CSceneEdit::Initialise();
LoadingScreen("Loading the Game", "Load scripts", nil);
CTheScripts::Init();
CGangs::Initialise();
@@ -603,7 +619,6 @@ void CGame::InitialiseWhenRestarting(void)
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
-extern void (*DebugMenuProcess)(void);
void CGame::Process(void)
{
CPad::UpdatePads();
@@ -702,20 +717,3 @@ void CGame::ProcessTidyUpMemory(void)
// meow
#endif
}
-
-STARTPATCHES
- InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
- InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);
- InjectHook(0x48BCB0, CGame::ShutdownRenderWare, PATCH_JUMP);
- InjectHook(0x48BD50, CGame::InitialiseOnceAfterRW, PATCH_JUMP);
- InjectHook(0x48BEC0, CGame::FinalShutdown, PATCH_JUMP);
- InjectHook(0x48BED0, CGame::Initialise, PATCH_JUMP);
- InjectHook(0x48C3A0, CGame::ShutDown, PATCH_JUMP);
- InjectHook(0x48C4B0, CGame::ReInitGameObjectVariables, PATCH_JUMP);
- InjectHook(0x48C620, CGame::ReloadIPLs, PATCH_JUMP);
- InjectHook(0x48C6B0, CGame::ShutDownForRestart, PATCH_JUMP);
- InjectHook(0x48C740, CGame::InitialiseWhenRestarting, PATCH_JUMP);
- InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
- InjectHook(0x48CA10, CGame::DrasticTidyUpMemory, PATCH_JUMP);
- InjectHook(0x48CA20, CGame::TidyUpMemory, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Game.h b/src/core/Game.h
index 30581893..01f5f0e9 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -1,7 +1,7 @@
#pragma once
-enum eLevelName
-{
+enum eLevelName {
+ LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0,
LEVEL_INDUSTRIAL,
LEVEL_COMMERCIAL,
@@ -11,17 +11,18 @@ enum eLevelName
class CGame
{
public:
- static eLevelName &currLevel;
- static bool &bDemoMode;
- static bool &nastyGame;
- static bool &frenchGame;
- static bool &germanGame;
+ static eLevelName currLevel;
+ static bool bDemoMode;
+ static bool nastyGame;
+ static bool frenchGame;
+ static bool germanGame;
#ifdef MORE_LANGUAGES
+ static bool polishGame;
static bool russianGame;
#endif
- static bool &noProstitutes;
- static bool &playingIntro;
- static char *aDatFile; //[32];
+ static bool noProstitutes;
+ static bool playingIntro;
+ static char aDatFile[32];
static bool InitialiseOnceBeforeRW(void);
static bool InitialiseRenderWare(void);
diff --git a/src/core/General.h b/src/core/General.h
index f32846eb..7ffa99de 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -90,6 +90,11 @@ public:
return -Atan2(x / y, 1.0f);
}
}
+
+ static float GetAngleBetweenPoints(float x1, float y1, float x2, float y2)
+ {
+ return RADTODEG(GetRadianAngleBetweenPoints(x1, y1, x2, y2));
+ }
// should return direction in 0-8 range. fits perfectly to peds' path directions.
static int GetNodeHeadingFromVector(float x, float y)
@@ -119,7 +124,7 @@ public:
static bool faststricmp(const char *str1, const char *str2)
{
for (; *str1; str1++, str2++) {
-#if MUCH_SLOWER
+#if MUCH_SLOWER || !defined _WIN32 || defined __MINGW32__
if (toupper(*str1) != toupper(*str2))
#else
if (__ascii_toupper(*str1) != __ascii_toupper(*str2))
diff --git a/src/core/IniFile.cpp b/src/core/IniFile.cpp
index 08b30876..df01b440 100644
--- a/src/core/IniFile.cpp
+++ b/src/core/IniFile.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "IniFile.h"
#include "CarCtrl.h"
@@ -7,8 +7,8 @@
#include "main.h"
#include "Population.h"
-float &CIniFile::PedNumberMultiplier = *(float*)0x6182F4;
-float &CIniFile::CarNumberMultiplier = *(float*)0x6182F8;
+float CIniFile::PedNumberMultiplier = 1.0f;
+float CIniFile::CarNumberMultiplier = 1.0f;
void CIniFile::LoadIniFile()
{
@@ -17,10 +17,10 @@ void CIniFile::LoadIniFile()
if (f){
CFileMgr::ReadLine(f, gString, 200);
sscanf(gString, "%f", &PedNumberMultiplier);
- PedNumberMultiplier = min(3.0f, max(0.5f, PedNumberMultiplier));
+ PedNumberMultiplier = Min(3.0f, Max(0.5f, PedNumberMultiplier));
CFileMgr::ReadLine(f, gString, 200);
sscanf(gString, "%f", &CarNumberMultiplier);
- CarNumberMultiplier = min(3.0f, max(0.5f, CarNumberMultiplier));
+ CarNumberMultiplier = Min(3.0f, Max(0.5f, CarNumberMultiplier));
CFileMgr::CloseFile(f);
}
CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier;
diff --git a/src/core/IniFile.h b/src/core/IniFile.h
index 9a98151b..1e30c4de 100644
--- a/src/core/IniFile.h
+++ b/src/core/IniFile.h
@@ -5,6 +5,6 @@ class CIniFile
public:
static void LoadIniFile();
- static float& PedNumberMultiplier;
- static float& CarNumberMultiplier;
+ static float PedNumberMultiplier;
+ static float CarNumberMultiplier;
};
diff --git a/src/core/Instance.cpp b/src/core/Instance.cpp
deleted file mode 100644
index 775341be..00000000
--- a/src/core/Instance.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "common.h"
-#include "patcher.h"
-#include "Instance.h"
-
-void
-CInstance::Shutdown()
-{
- GetMatrix().Detach();
-}
-
-class CInstance_ : public CInstance
-{
-public:
- void dtor() { CInstance::~CInstance(); }
-};
-
-STARTPATCHES
- InjectHook(0x50BE90, &CInstance_::dtor, PATCH_JUMP);
- InjectHook(0x50B850, &CInstance::Shutdown, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h
index 8ce2d313..3c22283d 100644
--- a/src/core/MenuScreens.h
+++ b/src/core/MenuScreens.h
@@ -32,7 +32,7 @@ const CMenuScreen aScreens[] = {
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
- // MENU_CONTROLLER_SETTINGS = 4
+ // MENUPAGE_CONTROLLER_SETTINGS = 4
{ "FET_CON", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
MENUACTION_CTRLDISPLAY, "FEC_CDP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
@@ -72,9 +72,10 @@ const CMenuScreen aScreens[] = {
MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_NONE,
#ifdef MORE_LANGUAGES
- MENUACTION_LANG_RUS, "FEL_RUS", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_LANG_PL, "FEL_POL", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_LANG_RUS, "FEL_RUS", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_JAP, "FEL_JAP", SAVESLOT_NONE, MENUPAGE_NONE,
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index f83998b8..84bb1526 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -1,15 +1,18 @@
#pragma warning( push )
#pragma warning( disable : 4005)
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
+#endif
#pragma warning( pop )
#include "common.h"
+#include "crossplatform.h"
#ifdef XINPUT
-#include <Xinput.h>
+#include <xinput.h>
#pragma comment( lib, "Xinput9_1_0.lib" )
#endif
-#include "patcher.h"
+
#include "Pad.h"
#include "ControllerConfig.h"
#include "Timer.h"
@@ -29,32 +32,31 @@
#include "Record.h"
#include "Replay.h"
#include "Weather.h"
-#include "win.h"
#include "Streaming.h"
#include "PathFind.h"
#include "Wanted.h"
#include "General.h"
-CPad *Pads = (CPad*)0x6F0360; // [2]
-CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C;
+CPad Pads[MAX_PADS];
+CMousePointerStateHelper MousePointerStateHelper;
-bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
-bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
+bool CPad::bDisplayNoControllerMessage;
+bool CPad::bObsoleteControllerMessage;
bool CPad::bOldDisplayNoControllerMessage;
-bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
+bool CPad::m_bMapPadOneToPadTwo;
-CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
-CKeyboardState &CPad::NewKeyState = *(CKeyboardState*)0x6E60D0;
-CKeyboardState &CPad::TempKeyState = *(CKeyboardState*)0x774DE8;
+CKeyboardState CPad::OldKeyState;
+CKeyboardState CPad::NewKeyState;
+CKeyboardState CPad::TempKeyState;
char CPad::KeyBoardCheatString[20];
-CMouseControllerState &CPad::OldMouseControllerState = *(CMouseControllerState*)0x8472A0;
-CMouseControllerState &CPad::NewMouseControllerState = *(CMouseControllerState*)0x8809F0;
-CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerState*)0x6F1E60;
+CMouseControllerState CPad::OldMouseControllerState;
+CMouseControllerState CPad::NewMouseControllerState;
+CMouseControllerState CPad::PCTempMouseControllerState;
_TODO("gbFastTime");
-extern bool &gbFastTime;
+extern bool gbFastTime;
void WeaponCheat()
{
@@ -205,7 +207,7 @@ void ArmourCheat()
void WantedLevelUpCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
- FindPlayerPed()->SetWantedLevel(min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
+ FindPlayerPed()->SetWantedLevel(Min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
}
void WantedLevelDownCheat()
@@ -423,6 +425,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
{
CMouseControllerState state;
+#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
@@ -432,7 +435,6 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
devCaps.dwSize = sizeof(DIDEVCAPS);
PSGLOBAL(mouse)->GetCapabilities(&devCaps);
-
switch ( devCaps.dwButtons )
{
case 3:
@@ -456,6 +458,19 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
state.WHEELUP = true;
}
}
+#else
+ // It seems there is no way to get number of buttons on mouse, so assign all buttons if we have mouse.
+ double xpos = 1.0f, ypos;
+ glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
+
+ if (xpos != NULL) {
+ state.MMB = true;
+ state.RMB = true;
+ state.LMB = true;
+ state.WHEELDN = true;
+ state.WHEELUP = true;
+ }
+#endif
return state;
}
@@ -464,6 +479,7 @@ void CPad::UpdateMouse()
{
if ( IsForegroundApp() )
{
+#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
@@ -500,6 +516,44 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
}
+#else
+ double xpos = 1.0f, ypos;
+ glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
+ if (xpos == NULL)
+ return;
+
+ int32 signX = 1;
+ int32 signy = 1;
+
+ if (!FrontEndMenuManager.m_bMenuActive)
+ {
+ if (MousePointerStateHelper.bInvertVertically)
+ signy = -1;
+ if (MousePointerStateHelper.bInvertHorizontally)
+ signX = -1;
+ }
+
+ PCTempMouseControllerState.Clear();
+
+ PCTempMouseControllerState.x = (float)(signX * (xpos - PSGLOBAL(lastMousePos.x)));
+ PCTempMouseControllerState.y = (float)(signy * (ypos - PSGLOBAL(lastMousePos.y)));
+ PCTempMouseControllerState.LMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_LEFT);
+ PCTempMouseControllerState.RMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_RIGHT);
+ PCTempMouseControllerState.MMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_MIDDLE);
+ PCTempMouseControllerState.MXB1 = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_4);
+ PCTempMouseControllerState.MXB2 = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_5);
+
+ PSGLOBAL(lastMousePos.x) = xpos;
+ PSGLOBAL(lastMousePos.y) = ypos;
+
+ if (PSGLOBAL(mouseWheel) > 0)
+ PCTempMouseControllerState.WHEELUP = 1;
+ else if (PSGLOBAL(mouseWheel) < 0)
+ PCTempMouseControllerState.WHEELDN = 1;
+
+ OldMouseControllerState = NewMouseControllerState;
+ NewMouseControllerState = PCTempMouseControllerState;
+#endif
}
}
@@ -513,10 +567,10 @@ CControllerState CPad::ReconcileTwoControllersInput(CControllerState const &Stat
{ if ( State1.button || State2.button ) ReconState.button = 255; }
#define _RECONCILE_AXIS_POSITIVE(axis) \
- { if ( State1.axis >= 0 && State2.axis >= 0 ) ReconState.axis = max(State1.axis, State2.axis); }
+ { if ( State1.axis >= 0 && State2.axis >= 0 ) ReconState.axis = Max(State1.axis, State2.axis); }
#define _RECONCILE_AXIS_NEGATIVE(axis) \
- { if ( State1.axis <= 0 && State2.axis <= 0 ) ReconState.axis = min(State1.axis, State2.axis); }
+ { if ( State1.axis <= 0 && State2.axis <= 0 ) ReconState.axis = Min(State1.axis, State2.axis); }
#define _RECONCILE_AXIS(axis) \
{ _RECONCILE_AXIS_POSITIVE(axis); _RECONCILE_AXIS_NEGATIVE(axis); }
@@ -644,6 +698,8 @@ void CPad::AddToCheatString(char c)
{
for ( int32 i = ARRAY_SIZE(CheatString) - 2; i >= 0; i-- )
CheatString[i + 1] = CheatString[i];
+
+ CheatString[0] = c;
#define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1)
// "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
@@ -1283,7 +1339,7 @@ bool CPad::GetLookRight(void)
{
if ( ArePlayerControlsDisabled() )
return false;
-
+
return !!(NewState.RightShoulder2 && !NewState.LeftShoulder2);
}
@@ -1292,7 +1348,7 @@ bool CPad::GetLookBehindForCar(void)
{
if ( ArePlayerControlsDisabled() )
return false;
-
+
return !!(NewState.RightShoulder2 && NewState.LeftShoulder2);
}
@@ -1766,7 +1822,7 @@ bool CPad::CycleWeaponRightJustDown(void)
{
if ( ArePlayerControlsDisabled() )
return false;
-
+
return !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
}
@@ -1863,7 +1919,7 @@ bool CPad::ShiftTargetLeftJustDown(void)
{
if ( ArePlayerControlsDisabled() )
return false;
-
+
return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2);
}
@@ -1871,7 +1927,7 @@ bool CPad::ShiftTargetRightJustDown(void)
{
if ( ArePlayerControlsDisabled() )
return false;
-
+
return !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
}
@@ -2402,111 +2458,3 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
return pRsKeys;
}
-
-STARTPATCHES
- InjectHook(0x490D90, &WeaponCheat, PATCH_JUMP);
- InjectHook(0x490E70, &HealthCheat, PATCH_JUMP);
- InjectHook(0x490EE0, &TankCheat, PATCH_JUMP);
- InjectHook(0x491040, &BlowUpCarsCheat, PATCH_JUMP);
- InjectHook(0x4910B0, &ChangePlayerCheat, PATCH_JUMP);
- InjectHook(0x4911C0, &MayhemCheat, PATCH_JUMP);
- InjectHook(0x491270, &EverybodyAttacksPlayerCheat, PATCH_JUMP);
- InjectHook(0x491370, &WeaponsForAllCheat, PATCH_JUMP);
- InjectHook(0x4913A0, &FastTimeCheat, PATCH_JUMP);
- InjectHook(0x4913F0, &SlowTimeCheat, PATCH_JUMP);
- InjectHook(0x491430, &MoneyCheat, PATCH_JUMP);
- InjectHook(0x491460, &ArmourCheat, PATCH_JUMP);
- InjectHook(0x491490, &WantedLevelUpCheat, PATCH_JUMP);
- InjectHook(0x4914F0, &WantedLevelDownCheat, PATCH_JUMP);
- InjectHook(0x491520, &SunnyWeatherCheat, PATCH_JUMP);
- InjectHook(0x491550, &CloudyWeatherCheat, PATCH_JUMP);
- InjectHook(0x491580, &RainyWeatherCheat, PATCH_JUMP);
- InjectHook(0x4915B0, &FoggyWeatherCheat, PATCH_JUMP);
- InjectHook(0x4915E0, &FastWeatherCheat, PATCH_JUMP);
- InjectHook(0x491610, &OnlyRenderWheelsCheat, PATCH_JUMP);
- InjectHook(0x491640, &ChittyChittyBangBangCheat, PATCH_JUMP);
- InjectHook(0x491670, &StrongGripCheat, PATCH_JUMP);
- InjectHook(0x4916A0, &NastyLimbsCheat, PATCH_JUMP);
-
- InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP);
- InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP);
- InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP);
- InjectHook(0x491B50, &CPad::ClearMouseHistory, PATCH_JUMP);
- //InjectHook(0x491B80, &CMouseControllerState::CMouseControllerState, PATCH_JUMP);
- InjectHook(0x491BB0, &CMouseControllerState::Clear, PATCH_JUMP);
- InjectHook(0x491BD0, &CMousePointerStateHelper::GetMouseSetUp, PATCH_JUMP);
- InjectHook(0x491CA0, &CPad::UpdateMouse, PATCH_JUMP);
- InjectHook(0x491E60, &CPad::ReconcileTwoControllersInput, PATCH_JUMP);
- InjectHook(0x492230, &CPad::StartShake, PATCH_JUMP);
- InjectHook(0x492290, &CPad::StartShake_Distance, PATCH_JUMP);
- InjectHook(0x492360, &CPad::StartShake_Train, PATCH_JUMP);
- InjectHook(0x492450, &CPad::AddToPCCheatString, PATCH_JUMP);
- InjectHook(0x492720, CPad::UpdatePads, PATCH_JUMP);
- InjectHook(0x492C60, &CPad::ProcessPCSpecificStuff, PATCH_JUMP);
- InjectHook(0x492C70, &CPad::Update, PATCH_JUMP);
-#pragma warning( push )
-#pragma warning( disable : 4573)
- InjectHook(0x492F00, (void (*)())CPad::DoCheats, PATCH_JUMP);
-#pragma warning( pop )
- InjectHook(0x492F20, (void (CPad::*)(int16))&CPad::DoCheats, PATCH_JUMP);
- InjectHook(0x492F30, CPad::StopPadsShaking, PATCH_JUMP);
- InjectHook(0x492F50, &CPad::StopShaking, PATCH_JUMP);
- InjectHook(0x492F60, CPad::GetPad, PATCH_JUMP);
- InjectHook(0x492F70, &CPad::GetSteeringLeftRight, PATCH_JUMP);
- InjectHook(0x492FF0, &CPad::GetSteeringUpDown, PATCH_JUMP);
- InjectHook(0x493070, &CPad::GetCarGunUpDown, PATCH_JUMP);
- InjectHook(0x4930C0, &CPad::GetCarGunLeftRight, PATCH_JUMP);
- InjectHook(0x493110, &CPad::GetPedWalkLeftRight, PATCH_JUMP);
- InjectHook(0x493190, &CPad::GetPedWalkUpDown, PATCH_JUMP);
- InjectHook(0x493210, &CPad::GetAnalogueUpDown, PATCH_JUMP);
- InjectHook(0x493290, &CPad::GetLookLeft, PATCH_JUMP);
- InjectHook(0x4932C0, &CPad::GetLookRight, PATCH_JUMP);
- InjectHook(0x4932F0, &CPad::GetLookBehindForCar, PATCH_JUMP);
- InjectHook(0x493320, &CPad::GetLookBehindForPed, PATCH_JUMP);
- InjectHook(0x493350, &CPad::GetHorn, PATCH_JUMP);
- InjectHook(0x4933F0, &CPad::HornJustDown, PATCH_JUMP);
- InjectHook(0x493490, &CPad::GetCarGunFired, PATCH_JUMP);
- InjectHook(0x4934F0, &CPad::CarGunJustDown, PATCH_JUMP);
- InjectHook(0x493560, &CPad::GetHandBrake, PATCH_JUMP);
- InjectHook(0x4935A0, &CPad::GetBrake, PATCH_JUMP);
- InjectHook(0x4935F0, &CPad::GetExitVehicle, PATCH_JUMP);
- InjectHook(0x493650, &CPad::ExitVehicleJustDown, PATCH_JUMP);
- InjectHook(0x4936C0, &CPad::GetWeapon, PATCH_JUMP);
- InjectHook(0x493700, &CPad::WeaponJustDown, PATCH_JUMP);
- InjectHook(0x493780, &CPad::GetAccelerate, PATCH_JUMP);
- InjectHook(0x4937D0, &CPad::CycleCameraModeUpJustDown, PATCH_JUMP);
- InjectHook(0x493830, &CPad::CycleCameraModeDownJustDown, PATCH_JUMP);
- InjectHook(0x493870, &CPad::ChangeStationJustDown, PATCH_JUMP);
- InjectHook(0x493910, &CPad::CycleWeaponLeftJustDown, PATCH_JUMP);
- InjectHook(0x493940, &CPad::CycleWeaponRightJustDown, PATCH_JUMP);
- InjectHook(0x493970, &CPad::GetTarget, PATCH_JUMP);
- InjectHook(0x4939D0, &CPad::TargetJustDown, PATCH_JUMP);
- InjectHook(0x493A40, &CPad::JumpJustDown, PATCH_JUMP);
- InjectHook(0x493A70, &CPad::GetSprint, PATCH_JUMP);
- InjectHook(0x493AE0, &CPad::ShiftTargetLeftJustDown, PATCH_JUMP);
- InjectHook(0x493B10, &CPad::ShiftTargetRightJustDown, PATCH_JUMP);
- InjectHook(0x493B40, &CPad::GetAnaloguePadUp, PATCH_JUMP);
- InjectHook(0x493BA0, &CPad::GetAnaloguePadDown, PATCH_JUMP);
- InjectHook(0x493C00, &CPad::GetAnaloguePadLeft, PATCH_JUMP);
- InjectHook(0x493C60, &CPad::GetAnaloguePadRight, PATCH_JUMP);
- InjectHook(0x493CC0, &CPad::GetAnaloguePadLeftJustUp, PATCH_JUMP);
- InjectHook(0x493D20, &CPad::GetAnaloguePadRightJustUp, PATCH_JUMP);
- InjectHook(0x493D80, &CPad::ForceCameraBehindPlayer, PATCH_JUMP);
- InjectHook(0x493E00, &CPad::SniperZoomIn, PATCH_JUMP);
- InjectHook(0x493E70, &CPad::SniperZoomOut, PATCH_JUMP);
- InjectHook(0x493EE0, &CPad::SniperModeLookLeftRight, PATCH_JUMP);
- InjectHook(0x493F30, &CPad::SniperModeLookUpDown, PATCH_JUMP);
- InjectHook(0x493F80, &CPad::LookAroundLeftRight, PATCH_JUMP);
- InjectHook(0x494130, &CPad::LookAroundUpDown, PATCH_JUMP);
- InjectHook(0x494290, &CPad::ResetAverageWeapon, PATCH_JUMP);
- InjectHook(0x4942B0, CPad::PrintErrorMessage, PATCH_JUMP);
- InjectHook(0x494420, LittleTest, PATCH_JUMP);
- InjectHook(0x494450, CPad::ResetCheats, PATCH_JUMP);
- InjectHook(0x4944B0, CPad::EditString, PATCH_JUMP);
- InjectHook(0x494690, CPad::EditCodesForControls, PATCH_JUMP);
-
- //InjectHook(0x494E50, `global constructor keyed to'Pad.cpp, PATCH_JUMP);
- //InjectHook(0x494EB0, sub_494EB0, PATCH_JUMP);
- //InjectHook(0x494ED0, &CPad::~CPad, PATCH_JUMP);
- //InjectHook(0x494EE0, &CPad::CPad, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Pad.h b/src/core/Pad.h
index cb705c6b..b3b0849b 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -66,7 +66,7 @@ public:
VALIDATE_SIZE(CMousePointerStateHelper, 0x2);
-extern CMousePointerStateHelper &MousePointerStateHelper;
+extern CMousePointerStateHelper MousePointerStateHelper;
class CKeyboardState
@@ -155,7 +155,6 @@ public:
uint8 DisablePlayerControls;
int8 bApplyBrakes;
char CheatString[12];
- char _pad0[3];
int32 LastTimeTouched;
int32 AverageWeapon;
int32 AverageEntries;
@@ -163,18 +162,18 @@ public:
CPad() { }
~CPad() { }
- static bool &bDisplayNoControllerMessage;
- static bool &bObsoleteControllerMessage;
+ static bool bDisplayNoControllerMessage;
+ static bool bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
- static bool &m_bMapPadOneToPadTwo;
+ static bool m_bMapPadOneToPadTwo;
- static CKeyboardState &OldKeyState;
- static CKeyboardState &NewKeyState;
- static CKeyboardState &TempKeyState;
+ static CKeyboardState OldKeyState;
+ static CKeyboardState NewKeyState;
+ static CKeyboardState TempKeyState;
static char KeyBoardCheatString[20];
- static CMouseControllerState &OldMouseControllerState;
- static CMouseControllerState &NewMouseControllerState;
- static CMouseControllerState &PCTempMouseControllerState;
+ static CMouseControllerState OldMouseControllerState;
+ static CMouseControllerState NewMouseControllerState;
+ static CMouseControllerState PCTempMouseControllerState;
#ifdef GTA_PS2_STUFF
@@ -450,4 +449,4 @@ public:
};
VALIDATE_SIZE(CPad, 0xFC);
-extern CPad *Pads; //[2]
+extern CPad Pads[MAX_PADS];
diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp
index c882fc27..99ca5659 100644
--- a/src/core/Placeable.cpp
+++ b/src/core/Placeable.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "Placeable.h"
-#include "patcher.h"
+
CPlaceable::CPlaceable(void)
{
@@ -62,21 +62,3 @@ CPlaceable::IsWithinArea(float x1, float y1, float z1, float x2, float y2, float
y1 <= GetPosition().y && GetPosition().y <= y2 &&
z1 <= GetPosition().z && GetPosition().z <= z2;
}
-
-#include <new>
-
-class CPlaceable_ : public CPlaceable
-{
-public:
- CPlaceable *ctor(void) { return ::new (this) CPlaceable(); }
- void dtor(void) { CPlaceable::~CPlaceable(); }
-};
-
-STARTPATCHES
- InjectHook(0x49F9A0, &CPlaceable_::ctor, PATCH_JUMP);
- InjectHook(0x49F9E0, &CPlaceable_::dtor, PATCH_JUMP);
-
- InjectHook(0x49FA00, &CPlaceable::SetHeading, PATCH_JUMP);
- InjectHook(0x49FA50, (bool (CPlaceable::*)(float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP);
- InjectHook(0x49FAF0, (bool (CPlaceable::*)(float, float, float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 0043c2f4..e92f7568 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -1,35 +1,35 @@
#include "common.h"
-#include "patcher.h"
-#include "main.h"
-#include "PlayerPed.h"
-#include "Wanted.h"
-#include "PlayerInfo.h"
+
+#include "Automobile.h"
+#include "Bridge.h"
+#include "Camera.h"
+#include "Cranes.h"
+#include "Darkel.h"
+#include "Explosion.h"
#include "Fire.h"
#include "Frontend.h"
-#include "PlayerSkin.h"
-#include "Darkel.h"
+#include "General.h"
+#include "HandlingMgr.h"
#include "Messages.h"
-#include "Text.h"
-#include "Stats.h"
-#include "Remote.h"
-#include "World.h"
-#include "Replay.h"
-#include "Camera.h"
#include "Pad.h"
+#include "PathFind.h"
+#include "PlayerInfo.h"
+#include "PlayerPed.h"
+#include "PlayerSkin.h"
#include "ProjectileInfo.h"
-#include "Explosion.h"
+#include "Remote.h"
+#include "Renderer.h"
+#include "Replay.h"
#include "Script.h"
-#include "Automobile.h"
-#include "HandlingMgr.h"
-#include "General.h"
#include "SpecialFX.h"
-#include "Cranes.h"
-#include "Bridge.h"
+#include "Stats.h"
+#include "Streaming.h"
+#include "Text.h"
+#include "Wanted.h"
#include "WaterLevel.h"
-#include "PathFind.h"
+#include "World.h"
#include "ZoneCull.h"
-#include "Renderer.h"
-#include "Streaming.h"
+#include "main.h"
void
CPlayerInfo::SetPlayerSkin(char *skin)
@@ -41,6 +41,10 @@ CPlayerInfo::SetPlayerSkin(char *skin)
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();
@@ -180,7 +184,7 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
m_pPed->bExplosionProof = true;
m_pPed->m_bCanBeDamaged = false;
((CPlayerPed*)m_pPed)->ClearAdrenaline();
- CancelPlayerEnteringCars(false);
+ CancelPlayerEnteringCars(nil);
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
CProjectileInfo::RemoveAllProjectiles();
@@ -342,6 +346,10 @@ CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1,
void
CPlayerInfo::Process(void)
{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return;
+#endif
// Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
bool startTaxiTimer = true;
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
@@ -548,30 +556,13 @@ CPlayerInfo::Process(void)
}
if (FindPlayerVehicle()) {
CVehicle *veh = FindPlayerVehicle();
- veh->m_nZoneLevel = -1;
+ veh->m_nZoneLevel = LEVEL_IGNORE;
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
if (veh->pPassengers[i])
- veh->pPassengers[i]->m_nZoneLevel = 0;
+ veh->pPassengers[i]->m_nZoneLevel = LEVEL_NONE;
}
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
} else {
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
}
}
-
-STARTPATCHES
- InjectHook(0x4B5DC0, &CPlayerInfo::dtor, PATCH_JUMP);
- InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
- InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
- InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
- InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
- InjectHook(0x49FC10, &CPlayerInfo::Clear, PATCH_JUMP);
- InjectHook(0x4A15C0, &CPlayerInfo::BlowUpRCBuggy, PATCH_JUMP);
- InjectHook(0x4A13B0, &CPlayerInfo::CancelPlayerEnteringCars, PATCH_JUMP);
- InjectHook(0x4A1400, &CPlayerInfo::MakePlayerSafe, PATCH_JUMP);
- InjectHook(0x4A0EC0, &CPlayerInfo::EvaluateCarPosition, PATCH_JUMP);
- InjectHook(0x4A15F0, &CPlayerInfo::AwardMoneyForExplosion, PATCH_JUMP);
- InjectHook(0x4A0B20, &CPlayerInfo::LoadPlayerInfo, PATCH_JUMP);
- InjectHook(0x4A0960, &CPlayerInfo::SavePlayerInfo, PATCH_JUMP);
- InjectHook(0x49FD30, &CPlayerInfo::Process, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 19c5ce23..ff31418c 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -31,22 +31,13 @@ public:
uint32 m_nLastBumpPlayerCarTimer;
uint32 m_nUnusedTaxiTimer;
bool m_bUnusedTaxiThing;
- int8 field_197;
- int8 field_198;
- int8 field_199;
uint32 m_nNextSexFrequencyUpdateTime;
uint32 m_nNextSexMoneyUpdateTime;
int32 m_nSexFrequency;
CCivilianPed *m_pHooker;
int8 m_WBState; // eWastedBustedState
- int8 field_217;
- int8 field_218;
- int8 field_219;
uint32 m_nWBTime;
bool m_bInRemoteMode;
- int8 field_225;
- int8 field_226;
- int8 field_227;
uint32 m_nTimeLostRemoteCar;
uint32 m_nTimeLastHealthLoss;
uint32 m_nTimeLastArmourLoss;
@@ -54,8 +45,6 @@ public:
int32 m_nUpsideDownCounter;
int32 field_248;
int16 m_nTrafficMultiplier;
- int8 field_254;
- int8 field_255;
float m_fRoadDensity;
uint32 m_nPreviousTimeRewardedForExplosion;
int32 m_nExplosionsSinceLastReward;
@@ -90,7 +79,6 @@ public:
void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**);
~CPlayerInfo() { };
- void dtor(void) { this->CPlayerInfo::~CPlayerInfo(); }
};
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 6add9e0c..4f4588da 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Pools.h"
#include "Boat.h"
@@ -10,15 +10,15 @@
#include "Wanted.h"
#include "World.h"
-CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
-CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
-CPedPool *&CPools::ms_pPedPool = *(CPedPool**)0x8F2C60;
-CVehiclePool *&CPools::ms_pVehiclePool = *(CVehiclePool**)0x9430DC;
-CBuildingPool *&CPools::ms_pBuildingPool = *(CBuildingPool**)0x8F2C04;
-CTreadablePool *&CPools::ms_pTreadablePool = *(CTreadablePool**)0x8F2568;
-CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
-CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
-CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
+CCPtrNodePool *CPools::ms_pPtrNodePool;
+CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
+CPedPool *CPools::ms_pPedPool;
+CVehiclePool *CPools::ms_pVehiclePool;
+CBuildingPool *CPools::ms_pBuildingPool;
+CTreadablePool *CPools::ms_pTreadablePool;
+CObjectPool *CPools::ms_pObjectPool;
+CDummyPool *CPools::ms_pDummyPool;
+CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
void
CPools::Initialise(void)
@@ -110,7 +110,7 @@ INITSAVEBUF
CStreaming::LoadAllRequestedModels(false);
int32 slot = ReadSaveBuf<int32>(buf);
CVehicle* pVehicle;
- char* vbuf = new char[max(sizeof(CAutomobile), sizeof(CBoat))];
+ char* vbuf = new char[Max(sizeof(CAutomobile), sizeof(CBoat))];
if (type == VEHICLE_TYPE_BOAT) {
memcpy(vbuf, buf, sizeof(CBoat));
SkipSaveBuf(buf, sizeof(CBoat));
@@ -251,7 +251,7 @@ INITSAVEBUF
continue;
if (pObject->ObjectCreatedBy == MISSION_OBJECT) {
bool bIsPickup = pObject->bIsPickup;
- bool bFlag2 = pObject->m_obj_flag2;
+ bool bPickupObjWithMessage = pObject->bPickupObjWithMessage;
bool bOutOfStock = pObject->bOutOfStock;
bool bGlassCracked = pObject->bGlassCracked;
bool bGlassBroken = pObject->bGlassBroken;
@@ -269,7 +269,7 @@ INITSAVEBUF
WriteSaveBuf(buf, (uint32)0); // same
WriteSaveBuf(buf, pObject->ObjectCreatedBy);
WriteSaveBuf(buf, bIsPickup);
- WriteSaveBuf(buf, bFlag2);
+ WriteSaveBuf(buf, bPickupObjWithMessage);
WriteSaveBuf(buf, bOutOfStock);
WriteSaveBuf(buf, bGlassCracked);
WriteSaveBuf(buf, bGlassBroken);
@@ -305,7 +305,7 @@ INITSAVEBUF
ReadSaveBuf<uint32>(buf);
pBufferObject->ObjectCreatedBy = ReadSaveBuf<int8>(buf);
pBufferObject->bIsPickup = ReadSaveBuf<bool>(buf);
- pBufferObject->m_flagE2 = ReadSaveBuf<bool>(buf);
+ pBufferObject->bPickupObjWithMessage = ReadSaveBuf<bool>(buf);
pBufferObject->bOutOfStock = ReadSaveBuf<bool>(buf);
pBufferObject->bGlassCracked = ReadSaveBuf<bool>(buf);
pBufferObject->bGlassBroken = ReadSaveBuf<bool>(buf);
@@ -325,7 +325,7 @@ INITSAVEBUF
pObject->m_objectMatrix = pBufferObject->m_objectMatrix;
pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy;
pObject->bIsPickup = pBufferObject->bIsPickup;
- pObject->m_flagE2 = pBufferObject->m_flagE2;
+ pObject->bPickupObjWithMessage = pBufferObject->bPickupObjWithMessage;
pObject->bOutOfStock = pBufferObject->bOutOfStock;
pObject->bGlassCracked = pBufferObject->bGlassCracked;
pObject->bGlassBroken = pBufferObject->bGlassBroken;
@@ -425,19 +425,3 @@ INITSAVEBUF
}
VALIDATESAVEBUF(size)
}
-
-STARTPATCHES
- InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP);
- InjectHook(0x4A1880, CPools::ShutDown, PATCH_JUMP);
- InjectHook(0x4A1A50, CPools::CheckPoolsEmpty, PATCH_JUMP);
- InjectHook(0x4A1A80, CPools::GetPedRef, PATCH_JUMP);
- InjectHook(0x4A1AA0, CPools::GetPed, PATCH_JUMP);
- InjectHook(0x4A1AC0, CPools::GetVehicleRef, PATCH_JUMP);
- InjectHook(0x4A1AE0, CPools::GetVehicle, PATCH_JUMP);
- InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP);
- InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP);
- InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP);
- InjectHook(0x4A1B40, CPools::LoadVehiclePool, PATCH_JUMP);
- InjectHook(0x4A2550, CPools::LoadObjectPool, PATCH_JUMP);
- InjectHook(0x4A2B50, CPools::LoadPedPool, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Pools.h b/src/core/Pools.h
index 74b87585..b0ba6598 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -22,15 +22,15 @@ typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
class CPools
{
- static CCPtrNodePool *&ms_pPtrNodePool;
- static CEntryInfoNodePool *&ms_pEntryInfoNodePool;
- static CPedPool *&ms_pPedPool;
- static CVehiclePool *&ms_pVehiclePool;
- static CBuildingPool *&ms_pBuildingPool;
- static CTreadablePool *&ms_pTreadablePool;
- static CObjectPool *&ms_pObjectPool;
- static CDummyPool *&ms_pDummyPool;
- static CAudioScriptObjectPool *&ms_pAudioScriptObjectPool;
+ static CCPtrNodePool *ms_pPtrNodePool;
+ static CEntryInfoNodePool *ms_pEntryInfoNodePool;
+ static CPedPool *ms_pPedPool;
+ static CVehiclePool *ms_pVehiclePool;
+ static CBuildingPool *ms_pBuildingPool;
+ static CTreadablePool *ms_pTreadablePool;
+ static CObjectPool *ms_pObjectPool;
+ static CDummyPool *ms_pDummyPool;
+ static CAudioScriptObjectPool *ms_pAudioScriptObjectPool;
public:
static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; }
static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; }
diff --git a/src/core/Profile.cpp b/src/core/Profile.cpp
index 56584d12..05d54133 100644
--- a/src/core/Profile.cpp
+++ b/src/core/Profile.cpp
@@ -52,20 +52,20 @@ void CProfile::SuspendProfile(eProfile profile)
void CProfile::ShowResults()
{
- ms_afMaxEndTime[PROFILE_FRAME_RATE] = max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]);
- ms_afMaxEndTime[PROFILE_PHYSICS] = max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]);
- ms_afMaxEndTime[PROFILE_COLLISION] = max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]);
- ms_afMaxEndTime[PROFILE_PED_AI] = max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]);
- ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]);
- ms_afMaxEndTime[PROFILE_RENDERING_TIME] = max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]);
- ms_afMaxEndTime[PROFILE_TOTAL] = max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]);
+ ms_afMaxEndTime[PROFILE_FRAME_RATE] = Max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]);
+ ms_afMaxEndTime[PROFILE_PHYSICS] = Max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]);
+ ms_afMaxEndTime[PROFILE_COLLISION] = Max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]);
+ ms_afMaxEndTime[PROFILE_PED_AI] = Max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]);
+ ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = Max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxEndTime[PROFILE_RENDERING_TIME] = Max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxEndTime[PROFILE_TOTAL] = Max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]);
- ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]);
- ms_afMaxCumulativeTime[PROFILE_PHYSICS] = max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]);
- ms_afMaxCumulativeTime[PROFILE_COLLISION] = max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]);
- ms_afMaxCumulativeTime[PROFILE_PED_AI] = max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]);
- ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]);
- ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
- ms_afMaxCumulativeTime[PROFILE_TOTAL] = max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
+ ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = Max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]);
+ ms_afMaxCumulativeTime[PROFILE_PHYSICS] = Max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]);
+ ms_afMaxCumulativeTime[PROFILE_COLLISION] = Max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]);
+ ms_afMaxCumulativeTime[PROFILE_PED_AI] = Max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]);
+ ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = Max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = Max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_TOTAL] = Max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
}
#endif \ No newline at end of file
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index 154e7e9a..2b3e6f1e 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -1,6 +1,6 @@
#include "config.h"
#include "common.h"
-#include "patcher.h"
+
#include "RwHelper.h"
#include "Radar.h"
#include "Camera.h"
@@ -16,31 +16,31 @@
#include "Streaming.h"
#include "SpecialFX.h"
-float &CRadar::m_radarRange = *(float*)0x8E281C;
-sRadarTrace (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(sRadarTrace(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
-CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
-int32 gRadarTxdIds[64];// = (int*)0x6299C0;
-
-CSprite2d CRadar::AsukaSprite;// = *(CSprite2d*)0x8F1A40;
-CSprite2d CRadar::BombSprite;// = (CSprite2d*)0x8F5FB4;
-CSprite2d CRadar::CatSprite;// = (CSprite2d*)0x885B24;
-CSprite2d CRadar::CentreSprite;// = (CSprite2d*)0x8F6268;
-CSprite2d CRadar::CopcarSprite;// = (CSprite2d*)0x8F1A2C;
-CSprite2d CRadar::DonSprite;// = (CSprite2d*)0x8F2BE0;
-CSprite2d CRadar::EightSprite;// = (CSprite2d*)0x8F2BCC;
-CSprite2d CRadar::ElSprite;// = (CSprite2d*)0x8F1B80;
-CSprite2d CRadar::IceSprite;// = (CSprite2d*)0x9415FC;
-CSprite2d CRadar::JoeySprite;// = (CSprite2d*)0x8F2C00;
-CSprite2d CRadar::KenjiSprite;// = (CSprite2d*)0x8F2C68;
-CSprite2d CRadar::LizSprite;// = (CSprite2d*)0x8F5830;
-CSprite2d CRadar::LuigiSprite;// = (CSprite2d*)0x8F1A3C;
-CSprite2d CRadar::NorthSprite;// = (CSprite2d*)0x8F6274;
-CSprite2d CRadar::RaySprite;// = (CSprite2d*)0x8E2A7C;
-CSprite2d CRadar::SalSprite;// = (CSprite2d*)0x8F29EC;
-CSprite2d CRadar::SaveSprite;// = (CSprite2d*)0x8F5F74;
-CSprite2d CRadar::SpraySprite;// = (CSprite2d*)0x94307C;
-CSprite2d CRadar::TonySprite;// = (CSprite2d*)0x885B58;
-CSprite2d CRadar::WeaponSprite;// = (CSprite2d*)0x941534;
+float CRadar::m_radarRange;
+sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS];
+CVector2D vec2DRadarOrigin;
+int32 gRadarTxdIds[64];
+
+CSprite2d CRadar::AsukaSprite;
+CSprite2d CRadar::BombSprite;
+CSprite2d CRadar::CatSprite;
+CSprite2d CRadar::CentreSprite;
+CSprite2d CRadar::CopcarSprite;
+CSprite2d CRadar::DonSprite;
+CSprite2d CRadar::EightSprite;
+CSprite2d CRadar::ElSprite;
+CSprite2d CRadar::IceSprite;
+CSprite2d CRadar::JoeySprite;
+CSprite2d CRadar::KenjiSprite;
+CSprite2d CRadar::LizSprite;
+CSprite2d CRadar::LuigiSprite;
+CSprite2d CRadar::NorthSprite;
+CSprite2d CRadar::RaySprite;
+CSprite2d CRadar::SalSprite;
+CSprite2d CRadar::SaveSprite;
+CSprite2d CRadar::SpraySprite;
+CSprite2d CRadar::TonySprite;
+CSprite2d CRadar::WeaponSprite;
CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
nil,
@@ -81,6 +81,7 @@ CRGBA CRadar::ArrowBlipColour2;
uint16 CRadar::MapLegendCounter;
uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
int CRadar::TargetMarkerId = -1;
+CVector CRadar::TargetMarkerPos;
#endif
// taken from VC
@@ -1442,6 +1443,7 @@ CRadar::ToggleTargetMarker(float x, float y)
ms_RadarTrace[nextBlip].m_bInUse = 1;
ms_RadarTrace[nextBlip].m_Radius = 1.0f;
CVector pos(x, y, CWorld::FindGroundZForCoord(x,y));
+ TargetMarkerPos = pos;
ms_RadarTrace[nextBlip].m_vec2DPos = pos;
ms_RadarTrace[nextBlip].m_vecPos = pos;
ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
@@ -1456,51 +1458,3 @@ CRadar::ToggleTargetMarker(float x, float y)
}
#endif
-STARTPATCHES
- InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP);
- InjectHook(0x4A3F60, CRadar::Shutdown, PATCH_JUMP);
- InjectHook(0x4A4030, CRadar::LoadTextures, PATCH_JUMP);
- InjectHook(0x4A4180, CRadar::GetNewUniqueBlipIndex, PATCH_JUMP);
- InjectHook(0x4A41C0, CRadar::GetActualBlipArrayIndex, PATCH_JUMP);
- InjectHook(0x4A4200, CRadar::DrawMap, PATCH_JUMP);
- InjectHook(0x4A42F0, CRadar::DrawBlips, PATCH_JUMP);
- InjectHook(0x4A4C70, CRadar::Draw3dMarkers, PATCH_JUMP);
- InjectHook(0x4A4F30, CRadar::LimitRadarPoint, PATCH_JUMP);
- InjectHook(0x4A4F90, CRadar::CalculateBlipAlpha, PATCH_JUMP);
- InjectHook(0x4A5040, CRadar::TransformRadarPointToScreenSpace, PATCH_JUMP);
- InjectHook(0x4A50D0, CRadar::TransformRealWorldPointToRadarSpace, PATCH_JUMP);
- InjectHook(0x4A5300, CRadar::TransformRadarPointToRealWorldSpace, PATCH_JUMP);
- InjectHook(0x4A5530, CRadar::TransformRealWorldToTexCoordSpace, PATCH_JUMP);
- InjectHook(0x4A5590, CRadar::SetCoordBlip, PATCH_JUMP);
- InjectHook(0x4A5640, CRadar::SetEntityBlip, PATCH_JUMP);
- InjectHook(0x4A56C0, CRadar::ClearBlipForEntity, PATCH_JUMP);
- InjectHook(0x4A5720, CRadar::ClearBlip, PATCH_JUMP);
- InjectHook(0x4A5770, CRadar::ChangeBlipColour, PATCH_JUMP);
- InjectHook(0x4A57A0, CRadar::ChangeBlipBrightness, PATCH_JUMP);
- InjectHook(0x4A57E0, CRadar::ChangeBlipScale, PATCH_JUMP);
- InjectHook(0x4A5810, CRadar::ChangeBlipDisplay, PATCH_JUMP);
- InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
- InjectHook(0x4A5870, CRadar::ShowRadarTrace, PATCH_JUMP);
- InjectHook(0x4A59C0, CRadar::ShowRadarMarker, PATCH_JUMP);
- InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
- InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
- InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
- InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
- InjectHook(0x4A6020, ClipRadarTileCoords, PATCH_JUMP);
- InjectHook(0x4A6060, RequestMapSection, PATCH_JUMP);
- InjectHook(0x4A60A0, RemoveMapSection, PATCH_JUMP);
- InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
- InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, PATCH_JUMP);
- InjectHook(0x4A6160, IsPointInsideRadar, PATCH_JUMP);
- InjectHook(0x4A61C0, GetTextureCorners, PATCH_JUMP);
- InjectHook(0x4A6250, LineRadarBoxCollision, PATCH_JUMP);
- InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
- InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
- InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
- InjectHook(0x4A6B60, (void (*)(const CVector&))&CRadar::StreamRadarSections, PATCH_JUMP);
- InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
- InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
- InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
- //InjectHook(0x4A7000, `global constructor keyed to'Radar.cpp, PATCH_JUMP);
- //InjectHook(0x4A7260, sRadarTrace::sRadarTrace, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/core/Radar.h b/src/core/Radar.h
index 27f3a6f0..e39a17f0 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -82,8 +82,8 @@ static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
class CRadar
{
public:
- static float &m_radarRange;
- static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
+ static float m_radarRange;
+ static sRadarTrace ms_RadarTrace[NUMRADARBLIPS];
static CSprite2d AsukaSprite;
static CSprite2d BombSprite;
static CSprite2d CatSprite;
@@ -114,6 +114,7 @@ public:
static uint16 MapLegendList[NUM_MAP_LEGENDS];
static uint16 MapLegendCounter;
static int TargetMarkerId;
+ static CVector TargetMarkerPos;
static void InitFrontEndMap();
static void DrawYouAreHereSprite(float, float);
diff --git a/src/core/References.cpp b/src/core/References.cpp
index e87f0fd5..52abbc3e 100644
--- a/src/core/References.cpp
+++ b/src/core/References.cpp
@@ -1,13 +1,13 @@
#include "common.h"
-#include "patcher.h"
+
#include "World.h"
#include "Vehicle.h"
#include "PlayerPed.h"
#include "Pools.h"
#include "References.h"
-CReference *CReferences::aRefs = (CReference*)0x70BBE0; //[NUMREFERENCES];
-CReference *&CReferences::pEmptyList = *(CReference**)0x8F1AF8;
+CReference CReferences::aRefs[NUMREFERENCES];
+CReference *CReferences::pEmptyList;
void
CReferences::Init(void)
@@ -26,8 +26,17 @@ CReferences::RemoveReferencesToPlayer(void)
{
if(FindPlayerVehicle())
FindPlayerVehicle()->ResolveReferences();
+#ifdef FIX_BUGS
+ if (FindPlayerPed()) {
+ CPlayerPed* pPlayerPed = FindPlayerPed();
+ FindPlayerPed()->ResolveReferences();
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed = pPlayerPed;
+ pPlayerPed->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pPed);
+ }
+#else
if(FindPlayerPed())
FindPlayerPed()->ResolveReferences();
+#endif
}
void
@@ -57,9 +66,3 @@ CReferences::PruneAllReferencesInWorld(void)
e->PruneReferences();
}
}
-
-STARTPATCHES
- InjectHook(0x4A7350, CReferences::Init, PATCH_JUMP);
- InjectHook(0x4A7570, CReferences::RemoveReferencesToPlayer, PATCH_JUMP);
- InjectHook(0x4A75A0, CReferences::PruneAllReferencesInWorld, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/References.h b/src/core/References.h
index 6476e243..e7a64de7 100644
--- a/src/core/References.h
+++ b/src/core/References.h
@@ -11,8 +11,8 @@ struct CReference
class CReferences
{
public:
- static CReference *aRefs; //[NUMREFERENCES];
- static CReference *&pEmptyList;
+ static CReference aRefs[NUMREFERENCES];
+ static CReference *pEmptyList;
static void Init(void);
static void RemoveReferencesToPlayer(void);
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 02092a30..99274e04 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -1,62 +1,62 @@
#include "common.h"
-#include "patcher.h"
+
#include "Stats.h"
#include "Text.h"
#include "World.h"
-int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
-int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
-int32& CStats::CommercialPassed = *(int32*)0x8F4334;
-int32& CStats::IndustrialPassed = *(int32*)0x8E2A68;
-int32& CStats::SuburbanPassed = *(int32*)0x8F2740;
-int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
-int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
-int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
-int32(&CStats::PedsKilledOfThisType)[NUM_PEDTYPES] = *(int32(*)[NUM_PEDTYPES]) * (uintptr*)0x880DBC;
-int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
-int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
-int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
-int32& CStats::DistanceTravelledInVehicle = *(int32*)0x940574;
-int32& CStats::DistanceTravelledOnFoot = *(int32*)0x941518;
-int32 &CStats::ProgressMade = *(int32*)0x8F6224;
-int32 &CStats::TotalProgressInGame = *(int32*)0x885B2C;
-int32& CStats::CarsExploded = *(int32*)0x941288;
-int32& CStats::PeopleKilledByPlayer = *(int32*)0x8F1B7C;
-float &CStats::MaximumJumpDistance = *(float*)0x8F2BDC;
-float &CStats::MaximumJumpHeight = *(float*)0x940564;
-int32 &CStats::MaximumJumpFlips = *(int32*)0x8F2524;
-int32 &CStats::MaximumJumpSpins = *(int32*)0x8F29B0;
-int32 &CStats::BestStuntJump = *(int32*)0x885B50;
-int32 &CStats::NumberOfUniqueJumpsFound = *(int32*)0x885B74;
-int32 &CStats::TotalNumberOfUniqueJumps = *(int32*)0x8E2DC0;
-int32 &CStats::PassengersDroppedOffWithTaxi = *(int32*)0x940724;
-int32 &CStats::MoneyMadeWithTaxi = *(int32*)0x941544;
-int32 &CStats::MissionsGiven = *(int32*)0x9430E8;
-int32 &CStats::MissionsPassed = *(int32*)0x940768;
-char(&CStats::LastMissionPassedName)[8] = *(char(*)[8])*(uintptr*)0x70D828;
-int32 &CStats::TotalLegitimateKills = *(int32*)0x8F6004;
-int32 &CStats::ElBurroTime = *(int32*)0x8E2A6C;
-int32& CStats::Record4x4One = *(int32*)0x940570;
-int32& CStats::Record4x4Two = *(int32*)0x94058C;
-int32& CStats::Record4x4Three = *(int32*)0x880FA8;
-int32& CStats::Record4x4Mayhem = *(int32*)0x885B70;
-int32& CStats::LivesSavedWithAmbulance = *(int32*)0x8F57E0;
-int32& CStats::CriminalsCaught = *(int32*)0x8F2518;
-int32& CStats::HighestLevelAmbulanceMission = *(int32*)0x8F2A04;
-int32& CStats::FiresExtinguished = *(int32*)0x8F5FEC;
-int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
-int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
-int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
-int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
-int32& CStats::RoundsFiredByPlayer = *(int32*)0x8E2BE8;
-int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510;
-int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070;
-int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C;
-int32& CStats::BestTimeBombDefusal = *(int32*)0x880E24;
-int32& CStats::mmRain = *(int32*)0x8F2C98;
-int32& CStats::CarsCrushed = *(int32*)0x943050;
-int32(&CStats::FastestTimes)[CStats::TOTAL_FASTEST_TIMES] = *(int32(*)[CStats::TOTAL_FASTEST_TIMES])*(uintptr*)0x6E9128;
-int32(&CStats::HighestScores)[CStats::TOTAL_HIGHEST_SCORES] = *(int32(*)[CStats::TOTAL_HIGHEST_SCORES]) * (uintptr*)0x8622B0;
+int32 CStats::DaysPassed;
+int32 CStats::HeadsPopped;
+int32 CStats::CommercialPassed;
+int32 CStats::IndustrialPassed;
+int32 CStats::SuburbanPassed;
+int32 CStats::NumberKillFrenziesPassed;
+int32 CStats::PeopleKilledByOthers;
+int32 CStats::HelisDestroyed;
+int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
+int32 CStats::TimesDied;
+int32 CStats::TimesArrested;
+int32 CStats::KillsSinceLastCheckpoint;
+int32 CStats::DistanceTravelledInVehicle;
+int32 CStats::DistanceTravelledOnFoot;
+int32 CStats::ProgressMade;
+int32 CStats::TotalProgressInGame;
+int32 CStats::CarsExploded;
+int32 CStats::PeopleKilledByPlayer;
+float CStats::MaximumJumpDistance;
+float CStats::MaximumJumpHeight;
+int32 CStats::MaximumJumpFlips;
+int32 CStats::MaximumJumpSpins;
+int32 CStats::BestStuntJump;
+int32 CStats::NumberOfUniqueJumpsFound;
+int32 CStats::TotalNumberOfUniqueJumps;
+int32 CStats::PassengersDroppedOffWithTaxi;
+int32 CStats::MoneyMadeWithTaxi;
+int32 CStats::MissionsGiven;
+int32 CStats::MissionsPassed;
+char CStats::LastMissionPassedName[8];
+int32 CStats::TotalLegitimateKills;
+int32 CStats::ElBurroTime;
+int32 CStats::Record4x4One;
+int32 CStats::Record4x4Two;
+int32 CStats::Record4x4Three;
+int32 CStats::Record4x4Mayhem;
+int32 CStats::LivesSavedWithAmbulance;
+int32 CStats::CriminalsCaught;
+int32 CStats::HighestLevelAmbulanceMission;
+int32 CStats::FiresExtinguished;
+int32 CStats::LongestFlightInDodo;
+int32 CStats::TimeTakenDefuseMission;
+int32 CStats::TotalNumberKillFrenzies;
+int32 CStats::TotalNumberMissions;
+int32 CStats::RoundsFiredByPlayer;
+int32 CStats::KgsOfExplosivesUsed;
+int32 CStats::InstantHitsFiredByPlayer;
+int32 CStats::InstantHitsHitByPlayer;
+int32 CStats::BestTimeBombDefusal;
+int32 CStats::mmRain;
+int32 CStats::CarsCrushed;
+int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
+int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
void CStats::Init()
{
@@ -121,13 +121,13 @@ void CStats::RegisterFastestTime(int32 index, int32 time)
if (FastestTimes[index] == 0)
FastestTimes[index] = time;
else
- FastestTimes[index] = min(FastestTimes[index], time);
+ FastestTimes[index] = Min(FastestTimes[index], time);
}
void CStats::RegisterHighestScore(int32 index, int32 score)
{
assert(index >= 0 && index < TOTAL_HIGHEST_SCORES);
- HighestScores[index] = max(HighestScores[index], score);
+ HighestScores[index] = Max(HighestScores[index], score);
}
void CStats::RegisterElBurroTime(int32 time)
@@ -167,7 +167,7 @@ void CStats::AnotherCriminalCaught()
void CStats::RegisterLevelAmbulanceMission(int32 level)
{
- HighestLevelAmbulanceMission = max(HighestLevelAmbulanceMission, level);
+ HighestLevelAmbulanceMission = Max(HighestLevelAmbulanceMission, level);
}
void CStats::AnotherFireExtinguished()
@@ -177,7 +177,7 @@ void CStats::AnotherFireExtinguished()
void CStats::RegisterLongestFlightInDodo(int32 time)
{
- LongestFlightInDodo = max(LongestFlightInDodo, time);
+ LongestFlightInDodo = Max(LongestFlightInDodo, time);
}
void CStats::RegisterTimeTakenDefuseMission(int32 time)
@@ -418,11 +418,3 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
assert(buf - buf_start == size);
#undef CopyFromBuf
}
-
-STARTPATCHES
- InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables
- InjectHook(0x4AB3E0, CStats::SaveStats, PATCH_JUMP);
- InjectHook(0x4AB670, CStats::LoadStats, PATCH_JUMP);
- InjectHook(0x4AB090, CStats::FindCriminalRatingString, PATCH_JUMP);
- InjectHook(0x4AB2A0, CStats::FindCriminalRatingNumber, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/core/Stats.h b/src/core/Stats.h
index ac3259f9..4445ecf4 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -9,59 +9,59 @@ public:
TOTAL_FASTEST_TIMES = 16,
TOTAL_HIGHEST_SCORES = 16
};
- static int32 &DaysPassed;
- static int32 &HeadsPopped;
- static int32& CommercialPassed;
- static int32& IndustrialPassed;
- static int32& SuburbanPassed;
- static int32 &NumberKillFrenziesPassed;
- static int32 &PeopleKilledByOthers;
- static int32 &HelisDestroyed;
- static int32(&PedsKilledOfThisType)[ePedType::NUM_PEDTYPES];
- static int32 &TimesDied;
- static int32 &TimesArrested;
- static int32 &KillsSinceLastCheckpoint;
- static int32 &DistanceTravelledInVehicle;
- static int32 &DistanceTravelledOnFoot;
- static int32 &CarsExploded;
- static int32 &PeopleKilledByPlayer;
- static int32 &ProgressMade;
- static int32 &TotalProgressInGame;
- static float &MaximumJumpDistance;
- static float &MaximumJumpHeight;
- static int32 &MaximumJumpFlips;
- static int32 &MaximumJumpSpins;
- static int32 &BestStuntJump;
- static int32 &NumberOfUniqueJumpsFound;
- static int32 &TotalNumberOfUniqueJumps;
- static int32 &PassengersDroppedOffWithTaxi;
- static int32 &MoneyMadeWithTaxi;
- static int32 &MissionsGiven;
- static int32 &MissionsPassed;
- static char (&LastMissionPassedName)[8];
- static int32 &TotalLegitimateKills;
- static int32 &ElBurroTime;
- static int32 &Record4x4One;
- static int32 &Record4x4Two;
- static int32 &Record4x4Three;
- static int32 &Record4x4Mayhem;
- static int32 &LivesSavedWithAmbulance;
- static int32 &CriminalsCaught;
- static int32 &HighestLevelAmbulanceMission;
- static int32 &FiresExtinguished;
- static int32 &LongestFlightInDodo;
- static int32 &TimeTakenDefuseMission;
- static int32 &TotalNumberKillFrenzies;
- static int32 &TotalNumberMissions;
- static int32 &RoundsFiredByPlayer;
- static int32 &KgsOfExplosivesUsed;
- static int32 &InstantHitsFiredByPlayer;
- static int32 &InstantHitsHitByPlayer;
- static int32 &BestTimeBombDefusal;
- static int32 &mmRain;
- static int32 &CarsCrushed;
- static int32(&FastestTimes)[TOTAL_FASTEST_TIMES];
- static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
+ static int32 DaysPassed;
+ static int32 HeadsPopped;
+ static int32 CommercialPassed;
+ static int32 IndustrialPassed;
+ static int32 SuburbanPassed;
+ static int32 NumberKillFrenziesPassed;
+ static int32 PeopleKilledByOthers;
+ static int32 HelisDestroyed;
+ static int32 PedsKilledOfThisType[ePedType::NUM_PEDTYPES];
+ static int32 TimesDied;
+ static int32 TimesArrested;
+ static int32 KillsSinceLastCheckpoint;
+ static int32 DistanceTravelledInVehicle;
+ static int32 DistanceTravelledOnFoot;
+ static int32 CarsExploded;
+ static int32 PeopleKilledByPlayer;
+ static int32 ProgressMade;
+ static int32 TotalProgressInGame;
+ static float MaximumJumpDistance;
+ static float MaximumJumpHeight;
+ static int32 MaximumJumpFlips;
+ static int32 MaximumJumpSpins;
+ static int32 BestStuntJump;
+ static int32 NumberOfUniqueJumpsFound;
+ static int32 TotalNumberOfUniqueJumps;
+ static int32 PassengersDroppedOffWithTaxi;
+ static int32 MoneyMadeWithTaxi;
+ static int32 MissionsGiven;
+ static int32 MissionsPassed;
+ static char LastMissionPassedName[8];
+ static int32 TotalLegitimateKills;
+ static int32 ElBurroTime;
+ static int32 Record4x4One;
+ static int32 Record4x4Two;
+ static int32 Record4x4Three;
+ static int32 Record4x4Mayhem;
+ static int32 LivesSavedWithAmbulance;
+ static int32 CriminalsCaught;
+ static int32 HighestLevelAmbulanceMission;
+ static int32 FiresExtinguished;
+ static int32 LongestFlightInDodo;
+ static int32 TimeTakenDefuseMission;
+ static int32 TotalNumberKillFrenzies;
+ static int32 TotalNumberMissions;
+ static int32 RoundsFiredByPlayer;
+ static int32 KgsOfExplosivesUsed;
+ static int32 InstantHitsFiredByPlayer;
+ static int32 InstantHitsHitByPlayer;
+ static int32 BestTimeBombDefusal;
+ static int32 mmRain;
+ static int32 CarsCrushed;
+ static int32 FastestTimes[TOTAL_FASTEST_TIMES];
+ static int32 HighestScores[TOTAL_HIGHEST_SCORES];
public:
static void Init(void);
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index d00edf51..a76e9038 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "Pad.h"
#include "Hud.h"
@@ -28,51 +28,54 @@
#include "CutsceneMgr.h"
#include "CdStream.h"
#include "Streaming.h"
+#ifdef FIX_BUGS
+#include "Replay.h"
+#endif
#include "main.h"
-bool &CStreaming::ms_disableStreaming = *(bool*)0x95CD6E;
-bool &CStreaming::ms_bLoadingBigModel = *(bool*)0x95CDB0;
-int32 &CStreaming::ms_numModelsRequested = *(int32*)0x8E2C10;
-CStreamingInfo *CStreaming::ms_aInfoForModel = (CStreamingInfo*)0x6C7088;
-CStreamingInfo &CStreaming::ms_startLoadedList = *(CStreamingInfo*)0x942F60;
-CStreamingInfo &CStreaming::ms_endLoadedList = *(CStreamingInfo*)0x8F1AC0;
-CStreamingInfo &CStreaming::ms_startRequestedList = *(CStreamingInfo*)0x8F1B3C;
-CStreamingInfo &CStreaming::ms_endRequestedList = *(CStreamingInfo*)0x940738;
-int32 &CStreaming::ms_oldSectorX = *(int32*)0x8F2C84;
-int32 &CStreaming::ms_oldSectorY = *(int32*)0x8F2C88;
-int32 &CStreaming::ms_streamingBufferSize = *(int32*)0x942FB0;
-int8 **CStreaming::ms_pStreamingBuffer = (int8**)0x87F818;
-int32 &CStreaming::ms_memoryUsed = *(int32*)0x940568;
-CStreamingChannel *CStreaming::ms_channel = (CStreamingChannel*)0x727EE0;
-int32 &CStreaming::ms_channelError = *(int32*)0x880DB8;
-int32 &CStreaming::ms_numVehiclesLoaded = *(int32*)0x8F2C80;
-int32 *CStreaming::ms_vehiclesLoaded = (int32*)0x773560;
-int32 &CStreaming::ms_lastVehicleDeleted = *(int32*)0x95CBF8;
-CDirectory *&CStreaming::ms_pExtraObjectsDir = *(CDirectory**)0x95CB90;
-int32 &CStreaming::ms_numPriorityRequests = *(int32*)0x8F31C4;
-bool &CStreaming::ms_hasLoadedLODs = *(bool*)0x95CD47;
-int32 &CStreaming::ms_currentPedGrp = *(int32*)0x8F2BBC;
+bool CStreaming::ms_disableStreaming;
+bool CStreaming::ms_bLoadingBigModel;
+int32 CStreaming::ms_numModelsRequested;
+CStreamingInfo CStreaming::ms_aInfoForModel[NUMSTREAMINFO];
+CStreamingInfo CStreaming::ms_startLoadedList;
+CStreamingInfo CStreaming::ms_endLoadedList;
+CStreamingInfo CStreaming::ms_startRequestedList;
+CStreamingInfo CStreaming::ms_endRequestedList;
+int32 CStreaming::ms_oldSectorX;
+int32 CStreaming::ms_oldSectorY;
+int32 CStreaming::ms_streamingBufferSize;
+int8 *CStreaming::ms_pStreamingBuffer[2];
+int32 CStreaming::ms_memoryUsed;
+CStreamingChannel CStreaming::ms_channel[2];
+int32 CStreaming::ms_channelError;
+int32 CStreaming::ms_numVehiclesLoaded;
+int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
+int32 CStreaming::ms_lastVehicleDeleted;
+CDirectory *CStreaming::ms_pExtraObjectsDir;
+int32 CStreaming::ms_numPriorityRequests;
+bool CStreaming::ms_hasLoadedLODs;
+int32 CStreaming::ms_currentPedGrp;
int32 CStreaming::ms_currentPedLoading;
int32 CStreaming::ms_lastCullZone;
-uint16 &CStreaming::ms_loadedGangs = *(uint16*)0x95CC60;
-uint16 &CStreaming::ms_loadedGangCars = *(uint16*)0x95CC2E;
-int32 *CStreaming::ms_imageOffsets = (int32*)0x6E60A0;
-int32 &CStreaming::ms_lastImageRead = *(int32*)0x880E2C;
-int32 &CStreaming::ms_imageSize = *(int32*)0x8F1A34;
-uint32 &CStreaming::ms_memoryAvailable = *(uint32*)0x880F8C;
-
-int32 &desiredNumVehiclesLoaded = *(int32*)0x5EC194;
-
-CEntity *&pIslandLODindustEntity = *(CEntity**)0x6212DC;
-CEntity *&pIslandLODcomIndEntity = *(CEntity**)0x6212E0;
-CEntity *&pIslandLODcomSubEntity = *(CEntity**)0x6212E4;
-CEntity *&pIslandLODsubIndEntity = *(CEntity**)0x6212E8;
-CEntity *&pIslandLODsubComEntity = *(CEntity**)0x6212EC;
-int32 &islandLODindust = *(int32*)0x6212C8;
-int32 &islandLODcomInd = *(int32*)0x6212CC;
-int32 &islandLODcomSub = *(int32*)0x6212D0;
-int32 &islandLODsubInd = *(int32*)0x6212D4;
-int32 &islandLODsubCom = *(int32*)0x6212D8;
+uint16 CStreaming::ms_loadedGangs;
+uint16 CStreaming::ms_loadedGangCars;
+int32 CStreaming::ms_imageOffsets[NUMCDIMAGES];
+int32 CStreaming::ms_lastImageRead;
+int32 CStreaming::ms_imageSize;
+uint32 CStreaming::ms_memoryAvailable;
+
+int32 desiredNumVehiclesLoaded = 12;
+
+CEntity *pIslandLODindustEntity;
+CEntity *pIslandLODcomIndEntity;
+CEntity *pIslandLODcomSubEntity;
+CEntity *pIslandLODsubIndEntity;
+CEntity *pIslandLODsubComEntity;
+int32 islandLODindust;
+int32 islandLODcomInd;
+int32 islandLODcomSub;
+int32 islandLODsubInd;
+int32 islandLODsubCom;
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@@ -199,7 +202,7 @@ CStreaming::Init(void)
// PC only, figure out how much memory we got
#ifdef GTA_PC
#define MB (1024*1024)
- extern unsigned long &_dwMemAvailPhys;
+ extern unsigned long _dwMemAvailPhys;
ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
if(ms_memoryAvailable < 50*MB)
ms_memoryAvailable = 50*MB;
@@ -280,7 +283,11 @@ CStreaming::Update(void)
!requestedSubway &&
!CGame::playingIntro &&
ms_numModelsRequested < 5 &&
- !CRenderer::m_loadingPriority){
+ !CRenderer::m_loadingPriority
+#ifdef FIX_BUGS
+ && !CReplay::IsPlayingBack()
+#endif
+ ){
StreamVehiclesAndPeds();
StreamZoneModels(FindPlayerCoors());
}
@@ -362,8 +369,12 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
lastID = modelId;
}
}else{
- // BUG: doesn't remember which cdimage this was in
+#ifdef FIX_BUGS
+ // remember which cdimage this came from
+ ms_pExtraObjectsDir->AddItem(direntry, n);
+#else
ms_pExtraObjectsDir->AddItem(direntry);
+#endif
lastID = -1;
}
}else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
@@ -743,7 +754,8 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
}else
RemoveModel(modelId);
- ms_pExtraObjectsDir->FindItem(modelName, pos, size);
+ bool found = ms_pExtraObjectsDir->FindItem(modelName, pos, size);
+ assert(found);
mi->ClearTexDictionary();
if(CTxdStore::FindTxdSlot(modelName) == -1)
mi->SetTexDictionary("generic");
@@ -1248,7 +1260,11 @@ CStreaming::StreamVehiclesAndPeds(void)
static int modelQualityClass = 0;
if(CRecordDataForGame::IsRecording() ||
- CRecordDataForGame::IsPlayingBack())
+ CRecordDataForGame::IsPlayingBack()
+#ifdef FIX_BUGS
+ || CReplay::IsPlayingBack()
+#endif
+ )
return;
if(FindPlayerPed()->m_pWanted->AreSwatRequired()){
@@ -1939,7 +1955,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if(mi->m_type != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())){
lodDistSq = sq(mi->GetLargestLodDistance());
- lodDistSq = min(lodDistSq, sq(STREAM_DIST));
+ lodDistSq = Min(lodDistSq, sq(STREAM_DIST));
pos = CVector2D(e->GetPosition());
if(xmin < pos.x && pos.x < xmax &&
ymin < pos.y && pos.y < ymax &&
@@ -2159,20 +2175,20 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
if(Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y)){
// looking west/east
- ymin = max(iy - 10, 0);
- ymax = min(iy + 10, NUMSECTORS_Y - 1);
+ ymin = Max(iy - 10, 0);
+ ymax = Min(iy + 10, NUMSECTORS_Y - 1);
assert(ymin <= ymax);
// Delete a block of sectors that we know is behind the camera
if(TheCamera.GetForward().x > 0){
// looking east
- xmax = max(ix - 2, 0);
- xmin = max(ix - 10, 0);
+ xmax = Max(ix - 2, 0);
+ xmin = Max(ix - 10, 0);
inc = 1;
}else{
// looking west
- xmax = min(ix + 2, NUMSECTORS_X - 1);
- xmin = min(ix + 10, NUMSECTORS_X - 1);
+ xmax = Min(ix + 2, NUMSECTORS_X - 1);
+ xmin = Min(ix + 10, NUMSECTORS_X - 1);
inc = -1;
}
for(y = ymin; y <= ymax; y++){
@@ -2188,13 +2204,13 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
// Now a block that intersects with the camera's frustum
if(TheCamera.GetForward().x > 0){
// looking east
- xmax = max(ix + 10, 0);
- xmin = max(ix - 2, 0);
+ xmax = Max(ix + 10, 0);
+ xmin = Max(ix - 2, 0);
inc = 1;
}else{
// looking west
- xmax = min(ix - 10, NUMSECTORS_X - 1);
- xmin = min(ix + 2, NUMSECTORS_X - 1);
+ xmax = Min(ix - 10, NUMSECTORS_X - 1);
+ xmin = Min(ix + 2, NUMSECTORS_X - 1);
inc = -1;
}
for(y = ymin; y <= ymax; y++){
@@ -2223,20 +2239,20 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
}else{
// looking north/south
- xmin = max(ix - 10, 0);
- xmax = min(ix + 10, NUMSECTORS_X - 1);
+ xmin = Max(ix - 10, 0);
+ xmax = Min(ix + 10, NUMSECTORS_X - 1);
assert(xmin <= xmax);
// Delete a block of sectors that we know is behind the camera
if(TheCamera.GetForward().y > 0){
// looking north
- ymax = max(iy - 2, 0);
- ymin = max(iy - 10, 0);
+ ymax = Max(iy - 2, 0);
+ ymin = Max(iy - 10, 0);
inc = 1;
}else{
// looking south
- ymax = min(iy + 2, NUMSECTORS_Y - 1);
- ymin = min(iy + 10, NUMSECTORS_Y - 1);
+ ymax = Min(iy + 2, NUMSECTORS_Y - 1);
+ ymin = Min(iy + 10, NUMSECTORS_Y - 1);
inc = -1;
}
for(x = xmin; x <= xmax; x++){
@@ -2252,13 +2268,13 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
// Now a block that intersects with the camera's frustum
if(TheCamera.GetForward().y > 0){
// looking north
- ymax = max(iy + 10, 0);
- ymin = max(iy - 2, 0);
+ ymax = Max(iy + 10, 0);
+ ymin = Max(iy - 2, 0);
inc = 1;
}else{
// looking south
- ymax = min(iy - 10, NUMSECTORS_Y - 1);
- ymin = min(iy + 2, NUMSECTORS_Y - 1);
+ ymax = Min(iy - 10, NUMSECTORS_Y - 1);
+ ymin = Min(iy + 2, NUMSECTORS_Y - 1);
inc = -1;
}
for(x = xmin; x <= xmax; x++){
@@ -2439,82 +2455,3 @@ CStreaming::UpdateForAnimViewer(void)
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
}
}
-
-STARTPATCHES
- InjectHook(0x406430, CStreaming::Init, PATCH_JUMP);
- InjectHook(0x406C80, CStreaming::Shutdown, PATCH_JUMP);
- InjectHook(0x4076C0, CStreaming::Update, PATCH_JUMP);
- InjectHook(0x406CC0, (void (*)(void))CStreaming::LoadCdDirectory, PATCH_JUMP);
- InjectHook(0x406DA0, (void (*)(const char*, int))CStreaming::LoadCdDirectory, PATCH_JUMP);
- InjectHook(0x409740, CStreaming::ConvertBufferToObject, PATCH_JUMP);
- InjectHook(0x409580, CStreaming::FinishLoadingLargeFile, PATCH_JUMP);
- InjectHook(0x407EA0, CStreaming::RequestModel, PATCH_JUMP);
- InjectHook(0x407FD0, CStreaming::RequestSubway, PATCH_JUMP);
- InjectHook(0x408190, CStreaming::RequestBigBuildings, PATCH_JUMP);
- InjectHook(0x408210, CStreaming::RequestIslands, PATCH_JUMP);
- InjectHook(0x40A890, CStreaming::RequestSpecialModel, PATCH_JUMP);
- InjectHook(0x40ADA0, CStreaming::RequestSpecialChar, PATCH_JUMP);
- InjectHook(0x54A5F0, CStreaming::HasModelLoaded, PATCH_JUMP);
- InjectHook(0x40ADC0, CStreaming::HasSpecialCharLoaded, PATCH_JUMP);
- InjectHook(0x40ADE0, CStreaming::SetMissionDoesntRequireSpecialChar, PATCH_JUMP);
-
- InjectHook(0x408830, CStreaming::RemoveModel, PATCH_JUMP);
- InjectHook(0x4083A0, CStreaming::RemoveUnusedBuildings, PATCH_JUMP);
- InjectHook(0x4083D0, CStreaming::RemoveBuildings, PATCH_JUMP);
- InjectHook(0x408640, CStreaming::RemoveUnusedBigBuildings, PATCH_JUMP);
- InjectHook(0x408680, CStreaming::RemoveBigBuildings, PATCH_JUMP);
- InjectHook(0x408780, CStreaming::RemoveIslandsNotUsed, PATCH_JUMP);
- InjectHook(0x40B180, CStreaming::RemoveLoadedVehicle, PATCH_JUMP);
- InjectHook(0x4089B0, CStreaming::RemoveLeastUsedModel, PATCH_JUMP);
- InjectHook(0x408940, CStreaming::RemoveAllUnusedModels, PATCH_JUMP);
- InjectHook(0x409450, CStreaming::RemoveReferencedTxds, PATCH_JUMP);
-
- InjectHook(0x40B160, CStreaming::GetAvailableVehicleSlot, PATCH_JUMP);
- InjectHook(0x40B060, CStreaming::AddToLoadedVehiclesList, PATCH_JUMP);
- InjectHook(0x4094C0, CStreaming::IsTxdUsedByRequestedModels, PATCH_JUMP);
- InjectHook(0x407E70, CStreaming::IsObjectInCdImage, PATCH_JUMP);
- InjectHook(0x408280, CStreaming::HaveAllBigBuildingsLoaded, PATCH_JUMP);
- InjectHook(0x40A790, CStreaming::SetModelIsDeletable, PATCH_JUMP);
- InjectHook(0x40A800, CStreaming::SetModelTxdIsDeletable, PATCH_JUMP);
- InjectHook(0x40A820, CStreaming::SetMissionDoesntRequireModel, PATCH_JUMP);
-
- InjectHook(0x40AA00, CStreaming::LoadInitialPeds, PATCH_JUMP);
- InjectHook(0x40ADF0, CStreaming::LoadInitialVehicles, PATCH_JUMP);
- InjectHook(0x40AE60, CStreaming::StreamVehiclesAndPeds, PATCH_JUMP);
- InjectHook(0x40AA30, CStreaming::StreamZoneModels, PATCH_JUMP);
- InjectHook(0x40AD00, CStreaming::RemoveCurrentZonesModels, PATCH_JUMP);
-
- InjectHook(0x409BE0, CStreaming::ProcessLoadingChannel, PATCH_JUMP);
- InjectHook(0x40A610, CStreaming::FlushChannels, PATCH_JUMP);
- InjectHook(0x40A680, CStreaming::FlushRequestList, PATCH_JUMP);
- InjectHook(0x409FF0, CStreaming::GetCdImageOffset, PATCH_JUMP);
- InjectHook(0x409E50, CStreaming::GetNextFileOnCd, PATCH_JUMP);
- InjectHook(0x40A060, CStreaming::RequestModelStream, PATCH_JUMP);
- InjectHook(0x4077F0, CStreaming::RetryLoadFile, PATCH_JUMP);
- InjectHook(0x40A390, CStreaming::LoadRequestedModels, PATCH_JUMP);
- InjectHook(0x40A440, CStreaming::LoadAllRequestedModels, PATCH_JUMP);
-
- InjectHook(0x4078F0, CStreaming::AddModelsToRequestList, PATCH_JUMP);
- InjectHook(0x407C50, (void (*)(CPtrList&,float,float,float,float,float,float))CStreaming::ProcessEntitiesInSectorList, PATCH_JUMP);
- InjectHook(0x407DD0, (void (*)(CPtrList&))CStreaming::ProcessEntitiesInSectorList, PATCH_JUMP);
-
- InjectHook(0x407070, CStreaming::DeleteFarAwayRwObjects, PATCH_JUMP);
- InjectHook(0x407390, CStreaming::DeleteAllRwObjects, PATCH_JUMP);
- InjectHook(0x407400, CStreaming::DeleteRwObjectsAfterDeath, PATCH_JUMP);
- InjectHook(0x408A60, CStreaming::DeleteRwObjectsBehindCamera, PATCH_JUMP);
- InjectHook(0x407560, CStreaming::DeleteRwObjectsInSectorList, PATCH_JUMP);
- InjectHook(0x4075A0, CStreaming::DeleteRwObjectsInOverlapSectorList, PATCH_JUMP);
- InjectHook(0x409340, CStreaming::DeleteRwObjectsBehindCameraInSectorList, PATCH_JUMP);
- InjectHook(0x4093C0, CStreaming::DeleteRwObjectsNotInFrustumInSectorList, PATCH_JUMP);
- InjectHook(0x409B70, CStreaming::MakeSpaceFor, PATCH_JUMP);
- InjectHook(0x40A6D0, CStreaming::LoadScene, PATCH_JUMP);
-
- InjectHook(0x40B210, CStreaming::MemoryCardSave, PATCH_JUMP);
- InjectHook(0x40B250, CStreaming::MemoryCardLoad, PATCH_JUMP);
-
- InjectHook(0x4063E0, &CStreamingInfo::GetCdPosnAndSize, PATCH_JUMP);
- InjectHook(0x406410, &CStreamingInfo::SetCdPosnAndSize, PATCH_JUMP);
- InjectHook(0x4063D0, &CStreamingInfo::GetCdSize, PATCH_JUMP);
- InjectHook(0x406380, &CStreamingInfo::AddToList, PATCH_JUMP);
- InjectHook(0x4063A0, &CStreamingInfo::RemoveFromList, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 1100fd1b..cf8790e9 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -71,42 +71,41 @@ struct CStreamingChannel
};
class CDirectory;
-enum eLevelName;
class CPtrList;
class CStreaming
{
public:
- static bool &ms_disableStreaming;
- static bool &ms_bLoadingBigModel;
- static int32 &ms_numModelsRequested;
- static CStreamingInfo *ms_aInfoForModel; //[NUMSTREAMINFO]
- static CStreamingInfo &ms_startLoadedList;
- static CStreamingInfo &ms_endLoadedList;
- static CStreamingInfo &ms_startRequestedList;
- static CStreamingInfo &ms_endRequestedList;
- static int32 &ms_oldSectorX;
- static int32 &ms_oldSectorY;
- static int32 &ms_streamingBufferSize;
- static int8 **ms_pStreamingBuffer; //[2]
- static int32 &ms_memoryUsed;
- static CStreamingChannel *ms_channel; //[2]
- static int32 &ms_channelError;
- static int32 &ms_numVehiclesLoaded;
- static int32 *ms_vehiclesLoaded; //[MAXVEHICLESLOADED]
- static int32 &ms_lastVehicleDeleted;
- static CDirectory *&ms_pExtraObjectsDir;
- static int32 &ms_numPriorityRequests;
- static bool &ms_hasLoadedLODs;
- static int32 &ms_currentPedGrp;
+ static bool ms_disableStreaming;
+ static bool ms_bLoadingBigModel;
+ static int32 ms_numModelsRequested;
+ static CStreamingInfo ms_aInfoForModel[NUMSTREAMINFO];
+ static CStreamingInfo ms_startLoadedList;
+ static CStreamingInfo ms_endLoadedList;
+ static CStreamingInfo ms_startRequestedList;
+ static CStreamingInfo ms_endRequestedList;
+ static int32 ms_oldSectorX;
+ static int32 ms_oldSectorY;
+ static int32 ms_streamingBufferSize;
+ static int8 *ms_pStreamingBuffer[2];
+ static int32 ms_memoryUsed;
+ static CStreamingChannel ms_channel[2];
+ static int32 ms_channelError;
+ static int32 ms_numVehiclesLoaded;
+ static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED];
+ static int32 ms_lastVehicleDeleted;
+ static CDirectory *ms_pExtraObjectsDir;
+ static int32 ms_numPriorityRequests;
+ static bool ms_hasLoadedLODs;
+ static int32 ms_currentPedGrp;
static int32 ms_lastCullZone;
- static uint16 &ms_loadedGangs;
- static uint16 &ms_loadedGangCars;
+ static uint16 ms_loadedGangs;
+ static uint16 ms_loadedGangCars;
static int32 ms_currentPedLoading;
- static int32 *ms_imageOffsets; //[NUMCDIMAGES]
- static int32 &ms_lastImageRead;
- static int32 &ms_imageSize;
- static uint32 &ms_memoryAvailable;
+ static int32 ms_imageOffsets[NUMCDIMAGES];
+ static int32 ms_lastImageRead;
+ static int32 ms_imageSize;
+ static uint32 ms_memoryAvailable;
static void Init(void);
static void Shutdown(void);
diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp
index 2ba884b1..7212fc65 100644
--- a/src/core/SurfaceTable.cpp
+++ b/src/core/SurfaceTable.cpp
@@ -1,12 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "FileMgr.h"
#include "Weather.h"
#include "Collision.h"
#include "SurfaceTable.h"
-float (*CSurfaceTable::ms_aAdhesiveLimitTable)[NUMADHESIVEGROUPS] = (float (*)[NUMADHESIVEGROUPS])0x8E29D4;
+float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
void
CSurfaceTable::Initialise(char *filename)
@@ -141,10 +141,3 @@ CSurfaceTable::GetAdhesiveLimit(CColPoint &colpoint)
{
return ms_aAdhesiveLimitTable[GetAdhesionGroup(colpoint.surfaceB)][GetAdhesionGroup(colpoint.surfaceA)];
}
-
-STARTPATCHES
- InjectHook(0x4AB8F0, CSurfaceTable::Initialise, PATCH_JUMP);
- InjectHook(0x4ABA60, CSurfaceTable::GetAdhesionGroup, PATCH_JUMP);
- InjectHook(0x4ABAA0, CSurfaceTable::GetWetMultiplier, PATCH_JUMP);
- InjectHook(0x4ABA30, CSurfaceTable::GetAdhesiveLimit, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h
index 27f4ecca..4af6a265 100644
--- a/src/core/SurfaceTable.h
+++ b/src/core/SurfaceTable.h
@@ -98,8 +98,7 @@ struct CColPoint;
class CSurfaceTable
{
-// static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
- static float (*ms_aAdhesiveLimitTable)[NUMADHESIVEGROUPS];
+ static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
public:
static void Initialise(char *filename);
static int GetAdhesionGroup(uint8 surfaceType);
diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp
index f7cf035e..79d6252b 100644
--- a/src/core/TempColModels.cpp
+++ b/src/core/TempColModels.cpp
@@ -1,21 +1,21 @@
#include "common.h"
-#include "patcher.h"
+
#include "TempColModels.h"
#include "SurfaceTable.h"
-CColModel &CTempColModels::ms_colModelPed1 = *(CColModel*)0x726CB0;
-CColModel &CTempColModels::ms_colModelPed2 = *(CColModel*)0x726D08;
-CColModel &CTempColModels::ms_colModelBBox = *(CColModel*)0x727FE0;
-CColModel &CTempColModels::ms_colModelBumper1 = *(CColModel*)0x86BE88;
-CColModel &CTempColModels::ms_colModelWheel1 = *(CColModel*)0x878C40;
-CColModel &CTempColModels::ms_colModelPanel1 = *(CColModel*)0x87BDD8;
-CColModel &CTempColModels::ms_colModelBodyPart2 = *(CColModel*)0x87BE30;
-CColModel &CTempColModels::ms_colModelBodyPart1 = *(CColModel*)0x87BE88;
-CColModel (&CTempColModels::ms_colModelCutObj)[5] = *(CColModel(*)[5]) *(uintptr*)0x87C960;
-CColModel &CTempColModels::ms_colModelPedGroundHit = *(CColModel*)0x880480;
-CColModel &CTempColModels::ms_colModelBoot1 = *(CColModel*)0x880670;
-CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
-CColModel &CTempColModels::ms_colModelBonnet1 = *(CColModel*)0x8808A8;
+CColModel CTempColModels::ms_colModelPed1;
+CColModel CTempColModels::ms_colModelPed2;
+CColModel CTempColModels::ms_colModelBBox;
+CColModel CTempColModels::ms_colModelBumper1;
+CColModel CTempColModels::ms_colModelWheel1;
+CColModel CTempColModels::ms_colModelPanel1;
+CColModel CTempColModels::ms_colModelBodyPart2;
+CColModel CTempColModels::ms_colModelBodyPart1;
+CColModel CTempColModels::ms_colModelCutObj[5];
+CColModel CTempColModels::ms_colModelPedGroundHit;
+CColModel CTempColModels::ms_colModelBoot1;
+CColModel CTempColModels::ms_colModelDoor1;
+CColModel CTempColModels::ms_colModelBonnet1;
CColSphere s_aPedSpheres[3];
@@ -34,7 +34,7 @@ void
CTempColModels::Initialise(void)
{
#define SET_COLMODEL_SPHERES(colmodel, sphrs)\
- colmodel.numSpheres = ARRAYSIZE(sphrs);\
+ colmodel.numSpheres = ARRAY_SIZE(sphrs);\
colmodel.spheres = sphrs;\
colmodel.level = LEVEL_NONE;\
colmodel.ownsCollisionVolumes = false;\
@@ -45,7 +45,7 @@ CTempColModels::Initialise(void)
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
ms_colModelBBox.level = LEVEL_NONE;
- for (i = 0; i < ARRAYSIZE(ms_colModelCutObj); i++) {
+ for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
ms_colModelCutObj[i].level = LEVEL_NONE;
@@ -53,7 +53,7 @@ CTempColModels::Initialise(void)
// Ped Spheres
- for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++)
+ for (i = 0; i < ARRAY_SIZE(s_aPedSpheres); i++)
s_aPedSpheres[i].radius = 0.35f;
s_aPedSpheres[0].center = CVector(0.0f, 0.0f, -0.25f);
@@ -61,9 +61,9 @@ CTempColModels::Initialise(void)
s_aPedSpheres[2].center = CVector(0.0f, 0.0f, 0.55f);
#ifdef FIX_BUGS
- for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aPedSpheres); i++) {
#else
- for (i = 0; i < ARRAYSIZE(s_aPedGSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aPedGSpheres); i++) {
#endif
s_aPedSpheres[i].surface = SURFACE_FLESH;
s_aPedSpheres[i].piece = 0;
@@ -83,7 +83,7 @@ CTempColModels::Initialise(void)
s_aPed2Spheres[1].center = CVector(0.0f, 0.0f, -0.9f);
s_aPed2Spheres[2].center = CVector(0.0f, -0.35f, -0.9f);
- for (i = 0; i < ARRAYSIZE(s_aPed2Spheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aPed2Spheres); i++) {
s_aPed2Spheres[i].surface = SURFACE_FLESH;
s_aPed2Spheres[i].piece = 0;
}
@@ -129,7 +129,7 @@ CTempColModels::Initialise(void)
s_aDoorSpheres[1].center = CVector(0.0f, -0.95f, -0.35f);
s_aDoorSpheres[2].center = CVector(0.0f, -0.6f, 0.25f);
- for (i = 0; i < ARRAYSIZE(s_aDoorSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aDoorSpheres); i++) {
s_aDoorSpheres[i].surface = SURFACE_BILLBOARD;
s_aDoorSpheres[i].piece = 0;
}
@@ -141,7 +141,7 @@ CTempColModels::Initialise(void)
// Bumper Spheres
- for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++)
+ for (i = 0; i < ARRAY_SIZE(s_aBumperSpheres); i++)
s_aBumperSpheres[i].radius = 0.15f;
s_aBumperSpheres[0].center = CVector(0.85f, -0.05f, 0.0f);
@@ -149,7 +149,7 @@ CTempColModels::Initialise(void)
s_aBumperSpheres[2].center = CVector(-0.4f, 0.05f, 0.0f);
s_aBumperSpheres[3].center = CVector(-0.85f, -0.05f, 0.0f);
- for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBumperSpheres); i++) {
s_aBumperSpheres[i].surface = SURFACE_BILLBOARD;
s_aBumperSpheres[i].piece = 0;
}
@@ -161,7 +161,7 @@ CTempColModels::Initialise(void)
// Panel Spheres
- for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++)
+ for (i = 0; i < ARRAY_SIZE(s_aPanelSpheres); i++)
s_aPanelSpheres[i].radius = 0.15f;
s_aPanelSpheres[0].center = CVector(0.15f, 0.45f, 0.0f);
@@ -169,7 +169,7 @@ CTempColModels::Initialise(void)
s_aPanelSpheres[2].center = CVector(-0.15f, -0.45f, 0.0f);
s_aPanelSpheres[3].center = CVector(-0.15f, 0.45f, 0.0f);
- for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aPanelSpheres); i++) {
s_aPanelSpheres[i].surface = SURFACE_BILLBOARD;
s_aPanelSpheres[i].piece = 0;
}
@@ -181,7 +181,7 @@ CTempColModels::Initialise(void)
// Bonnet Spheres
- for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++)
+ for (i = 0; i < ARRAY_SIZE(s_aBonnetSpheres); i++)
s_aBonnetSpheres[i].radius = 0.2f;
s_aBonnetSpheres[0].center = CVector(-0.4f, 0.1f, 0.0f);
@@ -189,7 +189,7 @@ CTempColModels::Initialise(void)
s_aBonnetSpheres[2].center = CVector(0.4f, 0.1f, 0.0f);
s_aBonnetSpheres[3].center = CVector(0.4f, 0.9f, 0.0f);
- for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBonnetSpheres); i++) {
s_aBonnetSpheres[i].surface = SURFACE_BILLBOARD;
s_aBonnetSpheres[i].piece = 0;
}
@@ -201,7 +201,7 @@ CTempColModels::Initialise(void)
// Boot Spheres
- for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++)
+ for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++)
s_aBootSpheres[i].radius = 0.2f;
s_aBootSpheres[0].center = CVector(-0.4f, -0.1f, 0.0f);
@@ -209,7 +209,7 @@ CTempColModels::Initialise(void)
s_aBootSpheres[2].center = CVector(0.4f, -0.1f, 0.0f);
s_aBootSpheres[3].center = CVector(0.4f, -0.6f, 0.0f);
- for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) {
s_aBootSpheres[i].surface = SURFACE_BILLBOARD;
s_aBootSpheres[i].piece = 0;
}
@@ -228,9 +228,9 @@ CTempColModels::Initialise(void)
s_aWheelSpheres[1].center = CVector(0.3f, 0.0f, 0.0f);
#ifdef FIX_BUGS
- for (i = 0; i < ARRAYSIZE(s_aWheelSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aWheelSpheres); i++) {
#else
- for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) {
#endif
s_aWheelSpheres[i].surface = SURFACE_RUBBER29;
s_aWheelSpheres[i].piece = 0;
@@ -250,9 +250,9 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres1[1].center = CVector(0.8f, 0.0f, 0.0f);
#ifdef FIX_BUGS
- for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres1); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBodyPartSpheres1); i++) {
#else
- for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) {
#endif
s_aBodyPartSpheres1[i].surface = SURFACE_FLESH;
s_aBodyPartSpheres1[i].piece = 0;
@@ -272,9 +272,9 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres2[1].center = CVector(0.5f, 0.0f, 0.0f);
#ifdef FIX_BUGS
- for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres2); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBodyPartSpheres2); i++) {
#else
- for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+ for (i = 0; i < ARRAY_SIZE(s_aBootSpheres); i++) {
#endif
s_aBodyPartSpheres2[i].surface = SURFACE_FLESH;
s_aBodyPartSpheres2[i].piece = 0;
@@ -287,7 +287,3 @@ CTempColModels::Initialise(void)
#undef SET_COLMODEL_SPHERES
}
-
-STARTPATCHES
- InjectHook(0x412160, CTempColModels::Initialise, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/TempColModels.h b/src/core/TempColModels.h
index 263904d3..3e1dd5e1 100644
--- a/src/core/TempColModels.h
+++ b/src/core/TempColModels.h
@@ -5,19 +5,19 @@
class CTempColModels
{
public:
- static CColModel &ms_colModelPed1;
- static CColModel &ms_colModelPed2;
- static CColModel &ms_colModelBBox;
- static CColModel &ms_colModelBumper1;
- static CColModel &ms_colModelWheel1;
- static CColModel &ms_colModelPanel1;
- static CColModel &ms_colModelBodyPart2;
- static CColModel &ms_colModelBodyPart1;
- static CColModel (&ms_colModelCutObj)[5];
- static CColModel &ms_colModelPedGroundHit;
- static CColModel &ms_colModelBoot1;
- static CColModel &ms_colModelDoor1;
- static CColModel &ms_colModelBonnet1;
+ static CColModel ms_colModelPed1;
+ static CColModel ms_colModelPed2;
+ static CColModel ms_colModelBBox;
+ static CColModel ms_colModelBumper1;
+ static CColModel ms_colModelWheel1;
+ static CColModel ms_colModelPanel1;
+ static CColModel ms_colModelBodyPart2;
+ static CColModel ms_colModelBodyPart1;
+ static CColModel ms_colModelCutObj[5];
+ static CColModel ms_colModelPedGroundHit;
+ static CColModel ms_colModelBoot1;
+ static CColModel ms_colModelDoor1;
+ static CColModel ms_colModelBonnet1;
static void Initialise(void);
};
diff --git a/src/core/TimeStep.cpp b/src/core/TimeStep.cpp
index 9ccf7200..09dae911 100644
--- a/src/core/TimeStep.cpp
+++ b/src/core/TimeStep.cpp
@@ -1,5 +1,5 @@
#include "TimeStep.h"
-float &CTimeStep::ms_fTimeScale = *(float*)0x5F76C8;
-float &CTimeStep::ms_fFramesPerUpdate = *(float*)0x5F76CC;
-float &CTimeStep::ms_fTimeStep = *(float*)0x5F76D0;
+float CTimeStep::ms_fTimeScale = 1.0f;
+float CTimeStep::ms_fFramesPerUpdate = 1.0f;
+float CTimeStep::ms_fTimeStep = 1.0f;
diff --git a/src/core/TimeStep.h b/src/core/TimeStep.h
index c74df02a..6101b4c2 100644
--- a/src/core/TimeStep.h
+++ b/src/core/TimeStep.h
@@ -4,7 +4,7 @@
class CTimeStep
{
public:
- static float &ms_fTimeScale;
- static float &ms_fFramesPerUpdate;
- static float &ms_fTimeStep;
+ static float ms_fTimeScale;
+ static float ms_fFramesPerUpdate;
+ static float ms_fTimeStep;
};
diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp
index fda862f1..aca7c1dc 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -1,38 +1,32 @@
-#include <windows.h>
+#define WITHWINDOWS
#include "common.h"
-#include "patcher.h"
+
#include "DMAudio.h"
#include "Record.h"
#include "Timer.h"
-uint32 &CTimer::m_snTimeInMilliseconds = *(uint32*)0x885B48;
-uint32 &CTimer::m_snTimeInMillisecondsPauseMode = *(uint32*)0x5F7614;
-uint32 &CTimer::m_snTimeInMillisecondsNonClipped = *(uint32*)0x9412E8;
-uint32 &CTimer::m_snPreviousTimeInMilliseconds = *(uint32*)0x8F29E4;
-uint32 &CTimer::m_FrameCounter = *(uint32*)0x9412EC;
-float &CTimer::ms_fTimeScale = *(float*)0x8F2C20;
-float &CTimer::ms_fTimeStep = *(float*)0x8E2CB4;
-float &CTimer::ms_fTimeStepNonClipped = *(float*)0x8E2C4C;
-bool &CTimer::m_UserPause = *(bool*)0x95CD7C;
-bool &CTimer::m_CodePause = *(bool*)0x95CDB1;
+uint32 CTimer::m_snTimeInMilliseconds;
+uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
+uint32 CTimer::m_snTimeInMillisecondsNonClipped;
+uint32 CTimer::m_snPreviousTimeInMilliseconds;
+uint32 CTimer::m_FrameCounter;
+float CTimer::ms_fTimeScale;
+float CTimer::ms_fTimeStep;
+float CTimer::ms_fTimeStepNonClipped;
+bool CTimer::m_UserPause;
+bool CTimer::m_CodePause;
-//UInt32 oldPcTimer;
-uint32 &oldPcTimer = *(uint32*)0x9434F4;
+uint32 oldPcTimer;
-//UInt32 suspendPcTimer;
-uint32 &suspendPcTimer = *(uint32*)0x62A308;
+uint32 suspendPcTimer;
-//UInt32 _nCyclesPerMS = 1;
-uint32 &_nCyclesPerMS = *(uint32*)0x5F7610;
+uint32 _nCyclesPerMS = 1;
-//LARGE_INTEGER _oldPerfCounter;
-LARGE_INTEGER &_oldPerfCounter = *(LARGE_INTEGER*)0x62A310;
+LARGE_INTEGER _oldPerfCounter;
-//LARGE_INTEGER perfSuspendCounter;
-LARGE_INTEGER &perfSuspendCounter = *(LARGE_INTEGER*)0x62A318;
+LARGE_INTEGER perfSuspendCounter;
-//UInt32 suspendDepth;
-uint32 &suspendDepth = *(uint32*)0x62A320;
+uint32 suspendDepth;
#ifdef FIX_BUGS
double frameTime;
@@ -144,7 +138,7 @@ void CTimer::Update(void)
if ( !CRecordDataForGame::IsPlayingBack() )
{
- ms_fTimeStep = min(3.0f, ms_fTimeStep);
+ ms_fTimeStep = Min(3.0f, ms_fTimeStep);
if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
@@ -231,18 +225,3 @@ uint32 CTimer::GetCyclesPerFrame()
return 20;
}
-#if 1
-STARTPATCHES
- InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP);
- InjectHook(0x4ACF60, CTimer::Shutdown, PATCH_JUMP);
- InjectHook(0x4ACF70, CTimer::Update, PATCH_JUMP);
- InjectHook(0x4AD310, CTimer::Suspend, PATCH_JUMP);
- InjectHook(0x4AD370, CTimer::Resume, PATCH_JUMP);
- InjectHook(0x4AD3F0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP);
- InjectHook(0x4AD410, CTimer::GetCurrentTimeInCycles, PATCH_JUMP);
- InjectHook(0x4AD450, CTimer::GetIsSlowMotionActive, PATCH_JUMP);
- InjectHook(0x4AD480, CTimer::Stop, PATCH_JUMP);
- InjectHook(0x4AD490, CTimer::StartUserPause, PATCH_JUMP);
- InjectHook(0x4AD4A0, CTimer::EndUserPause, PATCH_JUMP);
-ENDPATCHES
-#endif
diff --git a/src/core/Timer.h b/src/core/Timer.h
index a4d674da..00a11409 100644
--- a/src/core/Timer.h
+++ b/src/core/Timer.h
@@ -3,17 +3,17 @@
class CTimer
{
- static uint32 &m_snTimeInMilliseconds;
- static uint32 &m_snTimeInMillisecondsPauseMode;
- static uint32 &m_snTimeInMillisecondsNonClipped;
- static uint32 &m_snPreviousTimeInMilliseconds;
- static uint32 &m_FrameCounter;
- static float &ms_fTimeScale;
- static float &ms_fTimeStep;
- static float &ms_fTimeStepNonClipped;
+ static uint32 m_snTimeInMilliseconds;
+ static uint32 m_snTimeInMillisecondsPauseMode;
+ static uint32 m_snTimeInMillisecondsNonClipped;
+ static uint32 m_snPreviousTimeInMilliseconds;
+ static uint32 m_FrameCounter;
+ static float ms_fTimeScale;
+ static float ms_fTimeStep;
+ static float ms_fTimeStepNonClipped;
public:
- static bool &m_UserPause;
- static bool &m_CodePause;
+ static bool m_UserPause;
+ static bool m_CodePause;
static const float &GetTimeStep(void) { return ms_fTimeStep; }
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
diff --git a/src/core/User.cpp b/src/core/User.cpp
index d89d1cec..50eb7d9d 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -1,18 +1,19 @@
#include "common.h"
-#include "patcher.h"
+
#include "Hud.h"
#include "PlayerPed.h"
+#include "Replay.h"
#include "Text.h"
#include "User.h"
#include "Vehicle.h"
#include "World.h"
#include "Zones.h"
-CPlaceName& CUserDisplay::PlaceName = *(CPlaceName*)0x8F29BC;
-COnscreenTimer& CUserDisplay::OnscnTimer = *(COnscreenTimer*)0x862238;
-CPager& CUserDisplay::Pager = *(CPager*)0x8F2744;
-CCurrentVehicle& CUserDisplay::CurrentVehicle = *(CCurrentVehicle*)0x8F5FE8;
+CPlaceName CUserDisplay::PlaceName;
+COnscreenTimer CUserDisplay::OnscnTimer;
+CPager CUserDisplay::Pager;
+CCurrentVehicle CUserDisplay::CurrentVehicle;
CPlaceName::CPlaceName()
{
@@ -115,21 +116,12 @@ CUserDisplay::Init()
void
CUserDisplay::Process()
{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return;
+#endif
PlaceName.Process();
OnscnTimer.Process();
Pager.Process();
CurrentVehicle.Process();
}
-
-STARTPATCHES
- InjectHook(0x4AD4C0, &CPlaceName::Init, PATCH_JUMP);
- InjectHook(0x4AD4E0, &CPlaceName::Process, PATCH_JUMP);
- InjectHook(0x4AD5B0, &CPlaceName::Display, PATCH_JUMP);
-
- InjectHook(0x4AD5F0, &CCurrentVehicle::Init, PATCH_JUMP);
- InjectHook(0x4AD600, &CCurrentVehicle::Process, PATCH_JUMP);
- InjectHook(0x4AD630, &CCurrentVehicle::Display, PATCH_JUMP);
-
- InjectHook(0x4AD660, &CUserDisplay::Init, PATCH_JUMP);
- InjectHook(0x4AD690, &CUserDisplay::Process, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/core/User.h b/src/core/User.h
index 02d5f613..153ef57b 100644
--- a/src/core/User.h
+++ b/src/core/User.h
@@ -31,10 +31,10 @@ public:
class CUserDisplay
{
public:
- static CPlaceName &PlaceName;
- static COnscreenTimer &OnscnTimer;
- static CPager &Pager;
- static CCurrentVehicle &CurrentVehicle;
+ static CPlaceName PlaceName;
+ static COnscreenTimer OnscnTimer;
+ static CPager Pager;
+ static CCurrentVehicle CurrentVehicle;
static void Init();
static void Process();
diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp
index 29294a2b..6f5fdf06 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Pools.h"
#include "ModelIndices.h"
#include "Timer.h"
@@ -11,8 +11,8 @@
#include "Wanted.h"
#include "General.h"
-int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
-int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
+int32 CWanted::MaximumWantedLevel = 6;
+int32 CWanted::nMaximumWantedLevel = 6400;
void
CWanted::Initialise()
@@ -212,7 +212,7 @@ CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesnt
else
sensitivity = m_fCrimeSensitivity;
- wantedLevelDrop = min(CCullZones::GetWantedLevelDrop(), 100);
+ wantedLevelDrop = Min(CCullZones::GetWantedLevelDrop(), 100);
chaos = (1.0f - wantedLevelDrop/100.0f) * sensitivity;
if (policeDoesntCare)
@@ -371,7 +371,7 @@ CWanted::Update(void)
CVector playerPos = FindPlayerCoors();
if (WorkOutPolicePresence(playerPos, radius) == 0) {
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
- m_nChaos = max(0, m_nChaos - 1);
+ m_nChaos = Max(0, m_nChaos - 1);
UpdateWantedLevel();
}
}
@@ -456,25 +456,3 @@ CWanted::UpdateCrimesQ(void)
}
}
}
-
-STARTPATCHES
- InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
- InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
- InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
- InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
- InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
- InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
- InjectHook(0x4ADA50, &CWanted::SetWantedLevel, PATCH_JUMP);
- InjectHook(0x4ADAC0, &CWanted::SetWantedLevelNoDrop, PATCH_JUMP);
- InjectHook(0x4ADAE0, &CWanted::SetMaximumWantedLevel, PATCH_JUMP);
- InjectHook(0x4ADBA0, &CWanted::AreSwatRequired, PATCH_JUMP);
- InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
- InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
- InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, PATCH_JUMP);
- InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
- InjectHook(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
- InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
- InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, PATCH_JUMP);
- InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
- InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index 9823529c..e3e407b0 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -1,44 +1,10 @@
#pragma once
+#include "Crime.h"
+
class CEntity;
class CCopPed;
-enum eCrimeType
-{
- CRIME_NONE,
- CRIME_POSSESSION_GUN,
- CRIME_HIT_PED,
- CRIME_HIT_COP,
- CRIME_SHOOT_PED,
- CRIME_SHOOT_COP,
- CRIME_STEAL_CAR,
- CRIME_RUN_REDLIGHT,
- CRIME_RECKLESS_DRIVING,
- CRIME_SPEEDING,
- CRIME_RUNOVER_PED,
- CRIME_RUNOVER_COP,
- CRIME_SHOOT_HELI,
- CRIME_PED_BURNED,
- CRIME_COP_BURNED,
- CRIME_VEHICLE_BURNED,
- CRIME_DESTROYED_CESSNA,
- NUM_CRIME_TYPES
-};
-
-class CCrimeBeingQd
-{
-public:
- eCrimeType m_nType;
- uint32 m_nId;
- uint32 m_nTime;
- CVector m_vecPosn;
- bool m_bReported;
- bool m_bPoliceDoesntCare;
-
- CCrimeBeingQd() { };
- ~CCrimeBeingQd() { };
-};
-
class CWanted
{
public:
@@ -60,8 +26,8 @@ public:
CCrimeBeingQd m_aCrimes[16];
CCopPed *m_pCops[10];
- static int32 &MaximumWantedLevel;
- static int32 &nMaximumWantedLevel;
+ static int32 MaximumWantedLevel;
+ static int32 nMaximumWantedLevel;
public:
void Initialise();
diff --git a/src/core/World.cpp b/src/core/World.cpp
index d64569b3..b2a01b80 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -1,63 +1,54 @@
-#include "common.h"
-#include "patcher.h"
-#include "Entity.h"
-#include "Ped.h"
-#include "PlayerPed.h"
-#include "Vehicle.h"
-#include "Object.h"
+#include "World.h"
#include "Camera.h"
-#include "DMAudio.h"
#include "CarCtrl.h"
+#include "CopPed.h"
+#include "CutsceneMgr.h"
+#include "DMAudio.h"
+#include "Entity.h"
+#include "EventList.h"
+#include "Explosion.h"
+#include "Fire.h"
#include "Garages.h"
-#include "TempColModels.h"
-#include "World.h"
+#include "Glass.h"
+#include "Messages.h"
#include "ModelIndices.h"
-#include "References.h"
-#include "CutsceneMgr.h"
+#include "Object.h"
+#include "ParticleObject.h"
+#include "Ped.h"
+#include "PlayerPed.h"
+#include "Population.h"
+#include "ProjectileInfo.h"
#include "Record.h"
-#include "RpAnimBlend.h"
-#include "Messages.h"
+#include "References.h"
#include "Replay.h"
-#include "Population.h"
-#include "Fire.h"
+#include "RpAnimBlend.h"
+#include "Shadows.h"
+#include "TempColModels.h"
+#include "Vehicle.h"
+#include "WaterLevel.h"
+#include "common.h"
+
+
+#define OBJECT_REPOSITION_OFFSET_Z 2.0f
+
+CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
+
+CPtrList CWorld::ms_bigBuildingsList[4];// = (CPtrList*)0x6FAB60;
+CPtrList CWorld::ms_listMovingEntityPtrs;// = *(CPtrList*)0x8F433C;
+CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];// = (CSector (*)[NUMSECTORS_Y])0x665608;
+uint16 CWorld::ms_nCurrentScanCode;// = *(uint16*)0x95CC64;
-CColPoint *gaTempSphereColPoints = (CColPoint*)0x6E64C0; // [32]
-
-CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
-CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
-CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
-uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
-
-uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61;
-CPlayerInfo (&CWorld::Players)[NUMPLAYERS] = *(CPlayerInfo (*)[NUMPLAYERS])*(uintptr*)0x9412F0;
-bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
-CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494;
-bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F;
-bool &CWorld::bSecondShift = *(bool*)0x95CD54;
-bool &CWorld::bForceProcessControl = *(bool*)0x95CD6C;
-bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
-
-bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C;
-bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
-
-WRAPPER void CWorld::ClearForRestart(void) { EAXJMP(0x4AE850); }
-WRAPPER void CWorld::AddParticles(void) { EAXJMP(0x4B4010); }
-WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
-WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); }
-WRAPPER void CWorld::RemoveStaticObjects() { EAXJMP(0x4B4D50); }
-WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
-WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
-WRAPPER void CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8) { EAXJMP(0x4B4E70) };
-WRAPPER void CWorld::FindObjectsIntersectingCube(const CVector &, const CVector &, int16*, int16, CEntity **, bool, bool, bool, bool, bool) { EAXJMP(0x4B2E70); }
-WRAPPER void CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool) { EAXJMP(0x4B3280); }
-WRAPPER void CWorld::FindObjectsOfTypeInRange(uint32, CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool) { EAXJMP(0x4B2600); }
-WRAPPER void CWorld::FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVector&, float, bool, short*, short, CEntity**) { EAXJMP(0x4B2960); }
-WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); }
-WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
-WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
-WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
-WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
-WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
+uint8 CWorld::PlayerInFocus;// = *(uint8 *)0x95CD61;
+CPlayerInfo CWorld::Players[NUMPLAYERS];
+bool CWorld::bNoMoreCollisionTorque;// = *(bool*)0x95CDCC;
+CEntity *CWorld::pIgnoreEntity;// = *(CEntity**)0x8F6494;
+bool CWorld::bIncludeDeadPeds;// = *(bool*)0x95CD8F;
+bool CWorld::bSecondShift;// = *(bool*)0x95CD54;
+bool CWorld::bForceProcessControl;// = *(bool*)0x95CD6C;
+bool CWorld::bProcessCutsceneOnly;// = *(bool*)0x95CD8B;
+
+bool CWorld::bDoingCarCollisions;// = *(bool*)0x95CD8C;
+bool CWorld::bIncludeCarTyres;// = *(bool*)0x95CDAA;
void
CWorld::Initialise()
@@ -75,37 +66,31 @@ CWorld::Initialise()
void
CWorld::Add(CEntity *ent)
{
- if(ent->IsVehicle() || ent->IsPed())
- DMAudio.SetEntityStatus(((CPhysical*)ent)->m_audioEntityId, true);
+ if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, true);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].InsertItem(ent);
else
ent->Add();
- if(ent->IsBuilding() || ent->IsDummy())
- return;
+ if(ent->IsBuilding() || ent->IsDummy()) return;
- if(!ent->bIsStatic)
- ((CPhysical*)ent)->AddToMovingList();
+ if(!ent->bIsStatic) ((CPhysical *)ent)->AddToMovingList();
}
void
CWorld::Remove(CEntity *ent)
{
- if(ent->IsVehicle() || ent->IsPed())
- DMAudio.SetEntityStatus(((CPhysical*)ent)->m_audioEntityId, false);
+ if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, false);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].RemoveItem(ent);
else
ent->Remove();
- if(ent->IsBuilding() || ent->IsDummy())
- return;
+ if(ent->IsBuilding() || ent->IsDummy()) return;
- if(!ent->bIsStatic)
- ((CPhysical*)ent)->RemoveFromMovingList();
+ if(!ent->bIsStatic) ((CPhysical *)ent)->RemoveFromMovingList();
}
void
@@ -113,31 +98,74 @@ CWorld::ClearScanCodes(void)
{
CPtrNode *node;
for(int i = 0; i < NUMSECTORS_Y; i++)
- for(int j = 0; j < NUMSECTORS_X; j++){
- CSector *s = &ms_aSectors[i][j];
- for(node = s->m_lists[ENTITYLIST_BUILDINGS].first; node; node = node->next)
- ((CEntity*)node->item)->m_scanCode = 0;
- for(node = s->m_lists[ENTITYLIST_VEHICLES].first; node; node = node->next)
- ((CEntity*)node->item)->m_scanCode = 0;
- for(node = s->m_lists[ENTITYLIST_PEDS].first; node; node = node->next)
- ((CEntity*)node->item)->m_scanCode = 0;
- for(node = s->m_lists[ENTITYLIST_OBJECTS].first; node; node = node->next)
- ((CEntity*)node->item)->m_scanCode = 0;
- for(node = s->m_lists[ENTITYLIST_DUMMIES].first; node; node = node->next)
- ((CEntity*)node->item)->m_scanCode = 0;
+ for(int j = 0; j < NUMSECTORS_X; j++) {
+ CSector *s = &ms_aSectors[i][j];
+ for(node = s->m_lists[ENTITYLIST_BUILDINGS].first; node; node = node->next)
+ ((CEntity *)node->item)->m_scanCode = 0;
+ for(node = s->m_lists[ENTITYLIST_VEHICLES].first; node; node = node->next)
+ ((CEntity *)node->item)->m_scanCode = 0;
+ for(node = s->m_lists[ENTITYLIST_PEDS].first; node; node = node->next)
+ ((CEntity *)node->item)->m_scanCode = 0;
+ for(node = s->m_lists[ENTITYLIST_OBJECTS].first; node; node = node->next)
+ ((CEntity *)node->item)->m_scanCode = 0;
+ for(node = s->m_lists[ENTITYLIST_DUMMIES].first; node; node = node->next)
+ ((CEntity *)node->item)->m_scanCode = 0;
+ }
+}
+
+void
+CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemoveProjectilesAndTidyUpShadows)
+{
+ CPedPool *pedPool = CPools::GetPedPool();
+ for(int32 i = 0; i < pedPool->GetSize(); i++) {
+ CPed *pPed = pedPool->GetSlot(i);
+ if(pPed && !pPed->IsPlayer() && pPed->CanBeDeleted() &&
+ CVector2D(pPed->GetPosition() - pos).MagnitudeSqr() < radius) {
+ CPopulation::RemovePed(pPed);
+ }
+ }
+ CVehiclePool *VehiclePool = CPools::GetVehiclePool();
+ for(int32 i = 0; i < VehiclePool->GetSize(); i++) {
+ CVehicle *pVehicle = VehiclePool->GetSlot(i);
+ if(pVehicle && CVector2D(pVehicle->GetPosition() - pos).MagnitudeSqr() < radius &&
+ !pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
+ if(pVehicle->pDriver) {
+ CPopulation::RemovePed(pVehicle->pDriver);
+ pVehicle->pDriver = nil;
+ }
+ for(int32 j = 0; j < pVehicle->m_nNumMaxPassengers; ++j) {
+ if(pVehicle->pPassengers[j]) {
+ CPopulation::RemovePed(pVehicle->pPassengers[j]);
+ pVehicle->pPassengers[j] = nil;
+ --pVehicle->m_nNumPassengers;
+ }
+ }
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ CObject::DeleteAllTempObjectsInArea(pos, radius);
+ gFireManager.ExtinguishPoint(pos, radius);
+ CWorld::ExtinguishAllCarFiresInArea(pos, radius);
+ CExplosion::RemoveAllExplosionsInArea(pos, radius);
+ if(bRemoveProjectilesAndTidyUpShadows) {
+ CProjectileInfo::RemoveAllProjectiles();
+ CShadows::TidyUpShadows();
}
}
bool
CWorld::CameraToIgnoreThisObject(CEntity *ent)
{
- if(CGarages::IsModelIndexADoor(ent->GetModelIndex()))
- return false;
- return ((CObject*)ent)->m_bCameraToAvoidThisObject != 1;
+ if(CGarages::IsModelIndexADoor(ent->GetModelIndex())) return false;
+ return ((CObject *)ent)->m_bCameraToAvoidThisObject != 1;
}
bool
-CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity,
+ bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects,
+ bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
int x, xstart, xend;
int y, ystart, yend;
@@ -154,94 +182,80 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
xend = GetSectorIndexX(point2.x);
yend = GetSectorIndexY(point2.y);
-#define LOSARGS CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
+#define LOSARGS \
+ CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, \
+ checkDummies, ignoreSeeThrough, ignoreSomeObjects
- if(xstart == xend && ystart == yend){
+ if(xstart == xend && ystart == yend) {
// Only one sector
return ProcessLineOfSightSector(*GetSector(xstart, ystart), LOSARGS);
- }else if(xstart == xend){
+ } else if(xstart == xend) {
// Only step in y
if(ystart < yend)
- for(y = ystart; y <= yend; y++)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = ystart; y <= yend; y++) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
- for(y = ystart; y >= yend; y--)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = ystart; y >= yend; y--) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
return dist < 1.0f;
- }else if(ystart == yend){
+ } else if(ystart == yend) {
// Only step in x
if(xstart < xend)
- for(x = xstart; x <= xend; x++)
- ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
+ for(x = xstart; x <= xend; x++) ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
else
- for(x = xstart; x >= xend; x--)
- ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
+ for(x = xstart; x >= xend; x--) ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
return dist < 1.0f;
- }else{
- if(point1.x < point2.x){
+ } else {
+ if(point1.x < point2.x) {
// Step from left to right
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
- y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
+ y2 = GetSectorIndexY((GetWorldX(xstart + 1) - point1.x) * m + point1.y);
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
- for(x = xstart+1; x < xend; x++){
+ for(x = xstart + 1; x < xend; x++) {
y1 = y2;
- y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
+ y2 = GetSectorIndexY((GetWorldX(x + 1) - point1.x) * m + point1.y);
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
}
y1 = y2;
y2 = yend;
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
- }else{
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ } else {
// Step from right to left
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
- y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
+ y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x) * m + point1.y);
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
- for(x = xstart-1; x > xend; x--){
+ for(x = xstart - 1; x > xend; x--) {
y1 = y2;
- y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
+ y2 = GetSectorIndexY((GetWorldX(x) - point1.x) * m + point1.y);
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
}
y1 = y2;
y2 = yend;
if(y1 < y2)
- for(y = y1; y <= y2; y++)
- ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ for(y = y1; y <= y2; y++) ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
else
- for(y = y1; y >= y2; y--)
- ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ for(y = y1; y >= y2; y--) ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
}
return dist < 1.0f;
}
@@ -250,51 +264,63 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
}
bool
-CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity,
+ bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects,
+ bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
float mindist = dist;
bool deadPeds = !!bIncludeDeadPeds;
bIncludeDeadPeds = false;
- if(checkBuildings){
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough);
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ if(checkBuildings) {
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity,
+ ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough);
}
- if(checkVehicles){
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough);
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ if(checkVehicles) {
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity,
+ ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough);
}
- if(checkPeds){
- if(deadPeds)
- bIncludeDeadPeds = true;
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough);
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ if(checkPeds) {
+ if(deadPeds) bIncludeDeadPeds = true;
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity,
+ ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough);
bIncludeDeadPeds = false;
}
- if(checkObjects){
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
+ if(checkObjects) {
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity,
+ ignoreSeeThrough, ignoreSomeObjects);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough, ignoreSomeObjects);
}
- if(checkDummies){
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough);
- ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ if(checkDummies) {
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity,
+ ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough);
}
bIncludeDeadPeds = deadPeds;
- if(mindist < dist){
+ if(mindist < dist) {
dist = mindist;
return true;
- }else
+ } else
return false;
}
bool
-CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist,
+ CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
bool deadPeds = false;
float mindist = dist;
@@ -302,119 +328,142 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
CEntity *e;
CColModel *colmodel;
- if(list.first && bIncludeDeadPeds && ((CEntity*)list.first->item)->IsPed())
- deadPeds = true;
+ if(list.first && bIncludeDeadPeds && ((CEntity *)list.first->item)->IsPed()) deadPeds = true;
- for(node = list.first; node; node = node->next){
- e = (CEntity*)node->item;
- if(e->m_scanCode != GetCurrentScanCode() &&
- e != pIgnoreEntity &&
- (e->bUsesCollision || deadPeds) &&
- !(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
+ for(node = list.first; node; node = node->next) {
+ e = (CEntity *)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds) &&
+ !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = nil;
e->m_scanCode = GetCurrentScanCode();
- if(e->IsPed()){
- if(e->bUsesCollision ||
- deadPeds && ((CPed*)e)->m_nPedState == PED_DEAD){
- if (((CPed*)e)->UseGroundColModel())
+ if(e->IsPed()) {
+ if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
+#ifdef PED_SKIN
+ if(IsClumpSkinned(e->GetClump()))
+ colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
+ else
+#endif
+ if(((CPed *)e)->UseGroundColModel())
colmodel = &CTempColModels::ms_colModelPedGroundHit;
else
#ifdef ANIMATE_PED_COL_MODEL
- colmodel = CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->GetHitColModel(), RpClumpGetFrame(e->GetClump()));
+ colmodel = CPedModelInfo::AnimatePedColModel(
+ ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
+ ->GetHitColModel(),
+ RpClumpGetFrame(e->GetClump()));
#else
- colmodel = ((CPedModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->GetHitColModel();
+ colmodel =
+ ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
+ ->GetHitColModel();
#endif
- }else
+ } else
colmodel = nil;
- }else if(e->bUsesCollision)
+ } else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
- if(colmodel &&
- CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough))
+ if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist,
+ ignoreSeeThrough))
entity = e;
}
}
- if(mindist < dist){
+ if(mindist < dist) {
dist = mindist;
return true;
- }else
+ } else
return false;
}
-bool
-CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
+bool
+CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings,
+ bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies,
+ bool ignoreSeeThrough, CStoredCollPoly *poly)
{
AdvanceCurrentScanCode();
CVector point2(point1.x, point1.y, z2);
return ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexX(point1.y)),
- CColLine(point1, point2), point, entity,
- checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
+ CColLine(point1, point2), point, entity, checkBuildings, checkVehicles,
+ checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
}
bool
-CWorld::ProcessVerticalLineSector(CSector &sector, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
+CWorld::ProcessVerticalLineSector(CSector &sector, const CColLine &line, CColPoint &point, CEntity *&entity,
+ bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects,
+ bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
float mindist = 1.0f;
- if(checkBuildings){
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough, poly);
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ if(checkBuildings) {
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist,
+ entity, ignoreSeeThrough, poly);
}
- if(checkVehicles){
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough, poly);
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ if(checkVehicles) {
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
}
- if(checkPeds){
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough, poly);
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ if(checkPeds) {
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
}
- if(checkObjects){
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, poly);
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ if(checkObjects) {
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
}
- if(checkDummies){
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough, poly);
- ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ if(checkDummies) {
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity,
+ ignoreSeeThrough, poly);
}
return mindist < 1.0f;
}
bool
-CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly)
+CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist,
+ CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
- for(node = list.first; node; node = node->next){
- e = (CEntity*)node->item;
- if(e->m_scanCode != GetCurrentScanCode() &&
- e->bUsesCollision){
+ for(node = list.first; node; node = node->next) {
+ e = (CEntity *)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() && e->bUsesCollision) {
e->m_scanCode = GetCurrentScanCode();
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
- if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough, poly))
+ if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist,
+ ignoreSeeThrough, poly))
entity = e;
}
}
- if(mindist < dist){
+ if(mindist < dist) {
dist = mindist;
return true;
- }else
+ } else
return false;
}
bool
-CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles,
+ bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough,
+ bool ignoreSomeObjects)
{
int x, xstart, xend;
int y, ystart, yend;
@@ -427,58 +476,54 @@ CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool
xend = GetSectorIndexX(point2.x);
yend = GetSectorIndexY(point2.y);
-#define LOSARGS CColLine(point1, point2), checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
+#define LOSARGS \
+ CColLine(point1, point2), checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, \
+ ignoreSeeThrough, ignoreSomeObjects
- if(xstart == xend && ystart == yend){
+ if(xstart == xend && ystart == yend) {
// Only one sector
return GetIsLineOfSightSectorClear(*GetSector(xstart, ystart), LOSARGS);
- }else if(xstart == xend){
+ } else if(xstart == xend) {
// Only step in y
- if(ystart < yend){
+ if(ystart < yend) {
for(y = ystart; y <= yend; y++)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
+ } else {
for(y = ystart; y >= yend; y--)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
}
- }else if(ystart == yend){
+ } else if(ystart == yend) {
// Only step in x
- if(xstart < xend){
+ if(xstart < xend) {
for(x = xstart; x <= xend; x++)
- if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS)) return false;
+ } else {
for(x = xstart; x >= xend; x--)
- if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS)) return false;
}
- }else{
- if(point1.x < point2.x){
+ } else {
+ if(point1.x < point2.x) {
// Step from left to right
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
- y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
- if(y1 < y2){
+ y2 = GetSectorIndexY((GetWorldX(xstart + 1) - point1.x) * m + point1.y);
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
+ } else {
for(y = y1; y >= y2; y--)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
}
- for(x = xstart+1; x < xend; x++){
+ for(x = xstart + 1; x < xend; x++) {
y1 = y2;
- y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
- if(y1 < y2){
+ y2 = GetSectorIndexY((GetWorldX(x + 1) - point1.x) * m + point1.y);
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
- }else{
+ } else {
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
@@ -487,39 +532,35 @@ CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool
y1 = y2;
y2 = yend;
- if(y1 < y2){
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
- if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS)) return false;
+ } else {
for(y = y1; y >= y2; y--)
- if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS)) return false;
}
- }else{
+ } else {
// Step from right to left
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
- y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
- if(y1 < y2){
+ y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x) * m + point1.y);
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
+ } else {
for(y = y1; y >= y2; y--)
- if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS)) return false;
}
- for(x = xstart-1; x > xend; x--){
+ for(x = xstart - 1; x > xend; x--) {
y1 = y2;
- y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
- if(y1 < y2){
+ y2 = GetSectorIndexY((GetWorldX(x) - point1.x) * m + point1.y);
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
- }else{
+ } else {
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
@@ -528,14 +569,12 @@ CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool
y1 = y2;
y2 = yend;
- if(y1 < y2){
+ if(y1 < y2) {
for(y = y1; y <= y2; y++)
- if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
- return false;
- }else{
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS)) return false;
+ } else {
for(y = y1; y >= y2; y--)
- if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
- return false;
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS)) return false;
}
}
}
@@ -546,37 +585,43 @@ CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool
}
bool
-CWorld::GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool checkBuildings, bool checkVehicles,
+ bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough,
+ bool ignoreSomeObjects)
{
- if(checkBuildings){
+ if(checkBuildings) {
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS], line, ignoreSeeThrough))
return false;
- if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, ignoreSeeThrough))
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line,
+ ignoreSeeThrough))
return false;
}
- if(checkVehicles){
+ if(checkVehicles) {
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES], line, ignoreSeeThrough))
return false;
- if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, ignoreSeeThrough))
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line,
+ ignoreSeeThrough))
return false;
}
- if(checkPeds){
+ if(checkPeds) {
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, ignoreSeeThrough))
return false;
}
- if(checkObjects){
- if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS], line, ignoreSeeThrough, ignoreSomeObjects))
+ if(checkObjects) {
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS], line, ignoreSeeThrough,
+ ignoreSomeObjects))
return false;
- if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, ignoreSeeThrough, ignoreSomeObjects))
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, ignoreSeeThrough,
+ ignoreSomeObjects))
return false;
}
- if(checkDummies){
+ if(checkDummies) {
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, ignoreSeeThrough))
@@ -587,21 +632,20 @@ CWorld::GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool
}
bool
-CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects)
+CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough,
+ bool ignoreSomeObjects)
{
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
- for(node = list.first; node; node = node->next){
- e = (CEntity*)node->item;
- if(e->m_scanCode != GetCurrentScanCode() &&
- e->bUsesCollision){
+ for(node = list.first; node; node = node->next) {
+ e = (CEntity *)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() && e->bUsesCollision) {
e->m_scanCode = GetCurrentScanCode();
- if(e != pIgnoreEntity &&
- !(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
+ if(e != pIgnoreEntity && !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
@@ -615,26 +659,25 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
}
void
-CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects)
+CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float radius, bool ignoreZ, short *nextObject,
+ short lastObject, CEntity **objects)
{
float radiusSqr = radius * radius;
float objDistSqr;
- for (CPtrNode *node = list.first; node; node = node->next) {
- CEntity *object = (CEntity*)node->item;
- if (object->m_scanCode != GetCurrentScanCode()) {
+ for(CPtrNode *node = list.first; node; node = node->next) {
+ CEntity *object = (CEntity *)node->item;
+ if(object->m_scanCode != GetCurrentScanCode()) {
object->m_scanCode = GetCurrentScanCode();
CVector diff = centre - object->GetPosition();
- if (ignoreZ)
+ if(ignoreZ)
objDistSqr = diff.MagnitudeSqr2D();
else
objDistSqr = diff.MagnitudeSqr();
- if (objDistSqr < radiusSqr && *nextObject < lastObject) {
- if (objects) {
- objects[*nextObject] = object;
- }
+ if(objDistSqr < radiusSqr && *nextObject < lastObject) {
+ if(objects) { objects[*nextObject] = object; }
(*nextObject)++;
}
}
@@ -642,140 +685,239 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float radi
}
void
-CWorld::FindObjectsInRange(CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
+CWorld::FindObjectsInRange(CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject,
+ CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds,
+ bool checkObjects, bool checkDummies)
{
int minX = GetSectorIndexX(centre.x - radius);
- if (minX <= 0) minX = 0;
+ if(minX <= 0) minX = 0;
int minY = GetSectorIndexY(centre.y - radius);
- if (minY <= 0) minY = 0;
+ if(minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + radius);
#ifdef FIX_BUGS
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif
int maxY = GetSectorIndexY(centre.y + radius);
#ifdef FIX_BUGS
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
#endif
-
+
AdvanceCurrentScanCode();
*nextObject = 0;
for(int curY = minY; curY <= maxY; curY++) {
for(int curX = minX; curX <= maxX; curX++) {
CSector *sector = GetSector(curX, curY);
- if (checkBuildings) {
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, ignoreZ, nextObject, lastObject, objects);
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
+ if(checkBuildings) {
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius,
+ ignoreZ, nextObject, lastObject, objects);
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre,
+ radius, ignoreZ, nextObject, lastObject, objects);
}
- if (checkVehicles) {
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, ignoreZ, nextObject, lastObject, objects);
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
+ if(checkVehicles) {
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius,
+ ignoreZ, nextObject, lastObject, objects);
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre,
+ radius, ignoreZ, nextObject, lastObject, objects);
}
- if (checkPeds) {
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ, nextObject, lastObject, objects);
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
+ if(checkPeds) {
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ,
+ nextObject, lastObject, objects);
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius,
+ ignoreZ, nextObject, lastObject, objects);
}
- if (checkObjects) {
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, ignoreZ, nextObject, lastObject, objects);
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
+ if(checkObjects) {
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius,
+ ignoreZ, nextObject, lastObject, objects);
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre,
+ radius, ignoreZ, nextObject, lastObject, objects);
}
- if (checkDummies) {
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, ignoreZ, nextObject, lastObject, objects);
- FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
+ if(checkDummies) {
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius,
+ ignoreZ, nextObject, lastObject, objects);
+ FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre,
+ radius, ignoreZ, nextObject, lastObject, objects);
}
}
}
}
-CEntity*
-CWorld::TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
+void
+CWorld::FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList &list, const CVector &position, float radius,
+ bool bCheck2DOnly, int16 *nEntitiesFound, int16 maxEntitiesToFind,
+ CEntity **aEntities)
{
- CEntity* foundE = nil;
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ if(pEntity->m_scanCode != GetCurrentScanCode()) {
+ pEntity->m_scanCode = GetCurrentScanCode();
+ if(modelId == pEntity->m_modelIndex) {
+ float fMagnitude = 0.0f;
+ if(bCheck2DOnly)
+ fMagnitude = (position - pEntity->GetPosition()).MagnitudeSqr2D();
+ else
+ fMagnitude = (position - pEntity->GetPosition()).MagnitudeSqr();
+ if(fMagnitude < radius * radius && *nEntitiesFound < maxEntitiesToFind) {
+ if(aEntities) aEntities[*nEntitiesFound] = pEntity;
+ ++*nEntitiesFound;
+ }
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float radius, bool bCheck2DOnly,
+ int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings,
+ bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nEntitiesFound = 0;
+ const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
+ const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ if(bBuildings) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius,
+ bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bVehicles) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius,
+ bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bPeds) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bObjects) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius,
+ bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bDummies) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(
+ modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius,
+ bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+CEntity *
+CWorld::TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings,
+ bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies,
+ bool ignoreSomeObjects)
+{
+ CEntity *foundE = nil;
int minX = GetSectorIndexX(centre.x - radius);
- if (minX <= 0) minX = 0;
+ if(minX <= 0) minX = 0;
int minY = GetSectorIndexY(centre.y - radius);
- if (minY <= 0) minY = 0;
+ if(minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + radius);
#ifdef FIX_BUGS
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif
int maxY = GetSectorIndexY(centre.y + radius);
#ifdef FIX_BUGS
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
#endif
AdvanceCurrentScanCode();
- for (int curY = minY; curY <= maxY; curY++) {
- for (int curX = minX; curX <= maxX; curX++) {
- CSector* sector = GetSector(curX, curY);
- if (checkBuildings) {
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
-
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
+ for(int curY = minY; curY <= maxY; curY++) {
+ for(int curX = minX; curX <= maxX; curX++) {
+ CSector *sector = GetSector(curX, curY);
+ if(checkBuildings) {
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre,
+ radius, entityToIgnore, false);
+ if(foundE) return foundE;
+
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP],
+ centre, radius, entityToIgnore, false);
+ if(foundE) return foundE;
}
- if (checkVehicles) {
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
-
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
+ if(checkVehicles) {
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre,
+ radius, entityToIgnore, false);
+ if(foundE) return foundE;
+
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP],
+ centre, radius, entityToIgnore, false);
+ if(foundE) return foundE;
}
- if (checkPeds) {
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
-
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
+ if(checkPeds) {
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius,
+ entityToIgnore, false);
+ if(foundE) return foundE;
+
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre,
+ radius, entityToIgnore, false);
+ if(foundE) return foundE;
}
- if (checkObjects) {
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, entityToIgnore, ignoreSomeObjects);
- if (foundE)
- return foundE;
-
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, radius, entityToIgnore, ignoreSomeObjects);
- if (foundE)
- return foundE;
+ if(checkObjects) {
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre,
+ radius, entityToIgnore, ignoreSomeObjects);
+ if(foundE) return foundE;
+
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP],
+ centre, radius, entityToIgnore, ignoreSomeObjects);
+ if(foundE) return foundE;
}
- if (checkDummies) {
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
-
- foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, radius, entityToIgnore, false);
- if (foundE)
- return foundE;
+ if(checkDummies) {
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre,
+ radius, entityToIgnore, false);
+ if(foundE) return foundE;
+
+ foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP],
+ centre, radius, entityToIgnore, false);
+ if(foundE) return foundE;
}
}
}
return foundE;
}
-CEntity*
-CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore, bool ignoreSomeObjects)
+CEntity *
+CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
+ bool ignoreSomeObjects)
{
static CColModel sphereCol;
@@ -799,24 +941,27 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
CMatrix sphereMat;
sphereMat.SetTranslate(spherePos);
- for(CPtrNode *node=list.first; node; node = node->next) {
- CEntity *e = (CEntity*)node->item;
+ for(CPtrNode *node = list.first; node; node = node->next) {
+ CEntity *e = (CEntity *)node->item;
- if (e->m_scanCode != GetCurrentScanCode()) {
+ if(e->m_scanCode != GetCurrentScanCode()) {
e->m_scanCode = GetCurrentScanCode();
- if (e != entityToIgnore && e->bUsesCollision && !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
+ if(e != entityToIgnore && e->bUsesCollision &&
+ !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
CVector diff = spherePos - e->GetPosition();
float distance = diff.Magnitude();
- if (e->GetBoundRadius() + radius > distance) {
+ if(e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->m_modelIndex)->GetColModel();
- int collidedSpheres = CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(),
- *eCol, gaTempSphereColPoints, nil, nil);
-
- if (collidedSpheres != 0 ||
- (e->IsVehicle() && ((CVehicle*)e)->m_vehType == VEHICLE_TYPE_CAR &&
- e->m_modelIndex != MI_DODO && radius + eCol->boundingBox.max.x > distance)) {
+ int collidedSpheres =
+ CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol,
+ gaTempSphereColPoints, nil, nil);
+
+ if(collidedSpheres != 0 ||
+ (e->IsVehicle() && ((CVehicle *)e)->m_vehType == VEHICLE_TYPE_CAR &&
+ e->m_modelIndex != MI_DODO &&
+ radius + eCol->boundingBox.max.x > distance)) {
return e;
}
}
@@ -832,7 +977,8 @@ CWorld::FindGroundZForCoord(float x, float y)
{
CColPoint point;
CEntity *ent;
- if(ProcessVerticalLine(CVector(x, y, 1000.0f), -1000.0f, point, ent, true, false, false, false, true, false, nil))
+ if(ProcessVerticalLine(CVector(x, y, 1000.0f), -1000.0f, point, ent, true, false, false, false, true, false,
+ nil))
return point.point.z;
else
return 20.0f;
@@ -843,13 +989,11 @@ CWorld::FindGroundZFor3DCoord(float x, float y, float z, bool *found)
{
CColPoint point;
CEntity *ent;
- if(ProcessVerticalLine(CVector(x, y, z), -1000.0f, point, ent, true, false, false, false, false, false, nil)){
- if(found)
- *found = true;
+ if(ProcessVerticalLine(CVector(x, y, z), -1000.0f, point, ent, true, false, false, false, false, false, nil)) {
+ if(found) *found = true;
return point.point.z;
- }else{
- if(found)
- *found = false;
+ } else {
+ if(found) *found = false;
return 0.0f;
}
}
@@ -859,35 +1003,373 @@ CWorld::FindRoofZFor3DCoord(float x, float y, float z, bool *found)
{
CColPoint point;
CEntity *ent;
- if(ProcessVerticalLine(CVector(x, y, z), 1000.0f, point, ent, true, false, false, false, true, false, nil)){
- if(found)
- *found = true;
+ if(ProcessVerticalLine(CVector(x, y, z), 1000.0f, point, ent, true, false, false, false, true, false, nil)) {
+ if(found) *found = true;
return point.point.z;
- }else{
+ } else {
if(found == nil)
- printf("THERE IS NO MAP BELOW THE FOLLOWING COORS:%f %f %f. (FindGroundZFor3DCoord)\n", x, y, z);
- if(found)
- *found = false;
+ printf("THERE IS NO MAP BELOW THE FOLLOWING COORS:%f %f %f. (FindGroundZFor3DCoord)\n", x, y,
+ z);
+ if(found) *found = false;
return 20.0f;
}
}
-CPlayerPed*
+void
+CWorld::RemoveReferencesToDeletedObject(CEntity *pDeletedObject)
+{
+ int32 i = CPools::GetPedPool()->GetSize();
+ while(--i >= 0) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if(pPed && pPed != pDeletedObject) {
+ pPed->RemoveRefsToEntity(pDeletedObject);
+ if(pPed->m_pCurrentPhysSurface == pDeletedObject) pPed->m_pCurrentPhysSurface = nil;
+ }
+ }
+ i = CPools::GetVehiclePool()->GetSize();
+ while(--i >= 0) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if(pVehicle && pVehicle != pDeletedObject) {
+ pVehicle->RemoveRefsToEntity(pDeletedObject);
+ pVehicle->RemoveRefsToVehicle(pDeletedObject);
+ }
+ }
+ i = CPools::GetObjectPool()->GetSize();
+ while(--i >= 0) {
+ CObject *pObject = CPools::GetObjectPool()->GetSlot(i);
+ if(pObject && pObject != pDeletedObject) { pObject->RemoveRefsToEntity(pDeletedObject); }
+ }
+}
+
+void
+CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bCheck2DOnly, int16 *nCollidingEntities,
+ int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
+ bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nCollidingEntities = 0;
+ const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
+ const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ if(bBuildings) {
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if(bVehicles) {
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if(bPeds) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position,
+ radius, bCheck2DOnly, nCollidingEntities,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if(bObjects) {
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if(bDummies) {
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly,
+ nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsKindaCollidingSectorList(CPtrList &list, const CVector &position, float radius, bool bCheck2DOnly,
+ int16 *nCollidingEntities, int16 maxEntitiesToFind, CEntity **aEntities)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ if(pEntity->m_scanCode != GetCurrentScanCode()) {
+ pEntity->m_scanCode = GetCurrentScanCode();
+ float fMagnitude = 0.0f;
+ if(bCheck2DOnly)
+ fMagnitude = (position - pEntity->GetPosition()).Magnitude2D();
+ else
+ fMagnitude = (position - pEntity->GetPosition()).Magnitude();
+ if(pEntity->GetBoundRadius() + radius > fMagnitude && *nCollidingEntities < maxEntitiesToFind) {
+ if(aEntities) aEntities[*nCollidingEntities] = pEntity;
+ ++*nCollidingEntities;
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &vecEndPos, int16 *nIntersecting,
+ int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
+ bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nIntersecting = 0;
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ if(bBuildings) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos,
+ nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if(bVehicles) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
+ nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if(bPeds) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ }
+ if(bObjects) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ }
+ if(bDummies) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES],
+ vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vecStartPos, const CVector &vecEndPos,
+ int16 *nIntersecting, int16 maxEntitiesToFind, CEntity **aEntities)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ if(pEntity->m_scanCode != GetCurrentScanCode()) {
+ pEntity->m_scanCode = GetCurrentScanCode();
+ float fRadius = pEntity->GetBoundRadius();
+ const CVector &entityPos = pEntity->GetPosition();
+ if(fRadius + entityPos.x >= vecStartPos.x && entityPos.x - fRadius <= vecEndPos.x &&
+ fRadius + entityPos.y >= vecStartPos.y && entityPos.y - fRadius <= vecEndPos.y &&
+ fRadius + entityPos.z >= vecStartPos.z && entityPos.z - fRadius <= vecEndPos.z &&
+ *nIntersecting < maxEntitiesToFind) {
+ if(aEntities) aEntities[*nIntersecting] = pEntity;
+ ++*nIntersecting;
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix,
+ const CVector &position, float fStartX, float fStartY, float fEndX,
+ float fEndY, int16 *nEntitiesFound, int16 maxEntitiesToFind,
+ CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds,
+ bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nEntitiesFound = 0;
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ if(bBuildings) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bVehicles) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bPeds) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bObjects) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if(bDummies) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound,
+ maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position,
+ nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox,
+ const CMatrix &matrix, const CVector &position,
+ int16 *nEntitiesFound, int16 maxEntitiesToFind,
+ CEntity **aEntities)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ if(pEntity->m_scanCode != GetCurrentScanCode()) {
+ pEntity->m_scanCode = GetCurrentScanCode();
+ CColSphere sphere;
+ CVector vecDistance = pEntity->GetPosition() - position;
+ sphere.radius = pEntity->GetBoundRadius();
+ sphere.center = Multiply3x3(vecDistance, matrix);
+ if(CCollision::TestSphereBox(sphere, boundingBox) && *nEntitiesFound < maxEntitiesToFind) {
+ if(aEntities) aEntities[*nEntitiesFound] = pEntity;
+ ++*nEntitiesFound;
+ }
+ }
+ }
+}
+
+void
+CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CVector &vecEndPos, int16 *nIntersecting,
+ int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds,
+ bool bObjects)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nIntersecting = 0;
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ if(bVehicles) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities, true, false);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
+ nIntersecting, maxEntitiesToFind, aEntities, true, false);
+ }
+ if(bPeds) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities, false, true);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities, false, true);
+ }
+ if(bObjects) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities, false, false);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
+ maxEntitiesToFind, aEntities, false, false);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVector &vecStartPos,
+ const CVector &vecEndPos, int16 *nIntersecting,
+ int16 maxEntitiesToFind, CEntity **aEntities, bool bIsVehicleList,
+ bool bIsPedList)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ if(pEntity->m_scanCode != GetCurrentScanCode()) {
+ pEntity->m_scanCode = GetCurrentScanCode();
+ bool bIsMissionEntity = false;
+ if(bIsVehicleList)
+ bIsMissionEntity = ((CVehicle *)pEntity)->VehicleCreatedBy == MISSION_VEHICLE;
+ else if(bIsPedList)
+ bIsMissionEntity = ((CPed *)pEntity)->CharCreatedBy == MISSION_CHAR;
+ else
+ bIsMissionEntity = ((CObject *)pEntity)->ObjectCreatedBy == MISSION_OBJECT;
+ float fRadius = pEntity->GetBoundRadius();
+ const CVector &entityPos = pEntity->GetPosition();
+ if(bIsMissionEntity && fRadius + entityPos.x >= vecStartPos.x &&
+ entityPos.x - fRadius <= vecEndPos.x && fRadius + entityPos.y >= vecStartPos.y &&
+ entityPos.y - fRadius <= vecEndPos.y && fRadius + entityPos.z >= vecStartPos.z &&
+ entityPos.z - fRadius <= vecEndPos.z && *nIntersecting < maxEntitiesToFind) {
+ if(aEntities) aEntities[*nIntersecting] = pEntity;
+ ++*nIntersecting;
+ }
+ }
+ }
+}
+
+CPlayerPed *
FindPlayerPed(void)
{
return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
}
-CVehicle*
+CVehicle *
FindPlayerVehicle(void)
{
CPlayerPed *ped = FindPlayerPed();
- if(ped && ped->InVehicle())
- return ped->m_pMyVehicle;
+ if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
return nil;
}
-CVehicle*
+CVehicle *
FindPlayerTrain(void)
{
if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
@@ -896,7 +1378,7 @@ FindPlayerTrain(void)
return nil;
}
-CEntity*
+CEntity *
FindPlayerEntity(void)
{
CPlayerPed *ped = FindPlayerPed();
@@ -909,6 +1391,10 @@ FindPlayerEntity(void)
CVector
FindPlayerCoors(void)
{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return TheCamera.GetPosition();
+#endif
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle->GetPosition();
@@ -916,9 +1402,14 @@ FindPlayerCoors(void)
return ped->GetPosition();
}
-CVector&
+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;
@@ -926,27 +1417,28 @@ FindPlayerSpeed(void)
return ped->m_vecMoveSpeed;
}
-CVector&
+CVector &
FindPlayerCentreOfWorld(int32 player)
{
- if(CCarCtrl::bCarsGeneratedAroundCamera)
- return TheCamera.GetPosition();
- if(CWorld::Players[player].m_pRemoteVehicle)
- return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
- if(FindPlayerVehicle())
- return FindPlayerVehicle()->GetPosition();
+#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();
}
-CVector&
+CVector &
FindPlayerCentreOfWorld_NoSniperShift(void)
{
- if(CCarCtrl::bCarsGeneratedAroundCamera)
- return TheCamera.GetPosition();
+#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();
+ if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
return FindPlayerPed()->GetPosition();
}
@@ -955,19 +1447,160 @@ FindPlayerHeading(void)
{
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
- if(FindPlayerVehicle())
- return FindPlayerVehicle()->GetForward().Heading();
+ if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
return FindPlayerPed()->GetForward().Heading();
}
void
-CWorld::RemoveEntityInsteadOfProcessingIt(CEntity* ent)
+CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ CVehiclePool *pVehiclePool = CPools::GetVehiclePool();
+ for(int32 i = 0; i < pVehiclePool->GetSize(); i++) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if(pVehicle) {
+ const CVector &position = pVehicle->GetPosition();
+ if(position.x >= x1 && position.x <= x2 && position.y >= y1 && position.y <= y2 &&
+ position.z >= z1 && position.z <= z2 && !pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
+ if(pVehicle->pDriver) {
+ CPopulation::RemovePed(pVehicle->pDriver);
+ pVehicle->pDriver = nil;
+ }
+ for(int32 j = 0; j < pVehicle->m_nNumMaxPassengers; ++j) {
+ if(pVehicle->pPassengers[j]) {
+ CPopulation::RemovePed(pVehicle->pPassengers[j]);
+ pVehicle->pPassengers[j] = nil;
+ --pVehicle->m_nNumPassengers;
+ }
+ }
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+}
+
+void
+CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ CPedPool *pPedPool = CPools::GetPedPool();
+ for(int32 i = 0; i < pPedPool->GetSize(); i++) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if(pPed) {
+ const CVector &position = pPed->GetPosition();
+ if(!pPed->IsPlayer() && pPed->CanBeDeleted() && position.x >= x1 && position.x <= x2 &&
+ position.y >= y1 && position.y <= y2 && position.z >= z1 && position.z <= z2) {
+ CPopulation::RemovePed(pPed);
+ }
+ }
+ }
+}
+
+void
+CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
+{
+ CWorld::AdvanceCurrentScanCode();
+ float fStartX = x1 - 10.0f;
+ float fStartY = y1 - 10.0f;
+ float fEndX = x2 + 10.0f;
+ float fEndY = y2 + 10.0f;
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
+ y2, fStartX, fStartY, fEndX, fEndY);
+ CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
+ y1, x2, y2, fStartX, fStartY, fEndX, fEndY);
+ CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
+ CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2,
+ y2);
+ }
+ }
+}
+
+void
+CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1, float x2, float y2, float fStartX,
+ float fStartY, float fEndX, float fEndY)
{
- if (ent->IsPed()) {
- if (FindPlayerPed() == ent)
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CVehicle *pVehicle = (CVehicle *)pNode->item;
+ if(pVehicle->m_scanCode != GetCurrentScanCode()) {
+ pVehicle->m_scanCode = GetCurrentScanCode();
+ const CVector &vehiclePos = pVehicle->GetPosition();
+ eCarMission 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 ||
+ carMission == MISSION_BLOCKPLAYER_FARAWAY || carMission == MISSION_BLOCKPLAYER_CLOSE)) {
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
+ CColModel *pColModel = pVehicle->GetColModel();
+ bool bInsideSphere = false;
+ for(int32 i = 0; i < pColModel->numSpheres; i++) {
+ CVector pos = pVehicle->m_matrix * pColModel->spheres[i].center;
+ float fRadius = pColModel->spheres[i].radius;
+ if(pos.x + fRadius > x1 && pos.x - fRadius < x2 && pos.y + fRadius > y1 &&
+ pos.y - fRadius < y2)
+ bInsideSphere = true;
+ // Maybe break the loop when bInsideSphere is set to true?
+ }
+ if(bInsideSphere) {
+ if(pVehicle->GetPosition().x <= (x1 + x2) * 0.5f)
+ pVehicle->m_vecMoveSpeed.x = Min(pVehicle->m_vecMoveSpeed.x, 0.0f);
+ else
+ pVehicle->m_vecMoveSpeed.x = Max(pVehicle->m_vecMoveSpeed.x, 0.0f);
+ if(pVehicle->GetPosition().y <= (y1 + y2) * 0.5f)
+ pVehicle->m_vecMoveSpeed.y = Min(pVehicle->m_vecMoveSpeed.y, 0.0f);
+ else
+ pVehicle->m_vecMoveSpeed.y = Max(pVehicle->m_vecMoveSpeed.y, 0.0f);
+ }
+ }
+ }
+ }
+}
+
+void
+CWorld::CallOffChaseForAreaSectorListPeds(CPtrList &list, float x1, float y1, float x2, float y2)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CPed *pPed = (CPed *)pNode->item;
+ const CVector &pedPos = pPed->GetPosition();
+ if(pPed->m_scanCode != GetCurrentScanCode()) {
+ pPed->m_scanCode = GetCurrentScanCode();
+ if(pPed != FindPlayerPed() && pPed->m_leader != FindPlayerPed() && pedPos.x > x1 &&
+ pedPos.x < x2 && pedPos.y > y1 && pedPos.y < y2 &&
+ (pPed->m_pedInObjective == FindPlayerPed() ||
+ pPed->m_carInObjective && pPed->m_carInObjective == FindPlayerVehicle()) &&
+ pPed->m_nPedState != PED_DEAD && pPed->m_nPedState != PED_DIE &&
+ (pPed->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT ||
+ pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER ||
+ pPed->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS)) {
+ if(pPed->IsPedInControl()) {
+ if(pPed->m_nPedType == PEDTYPE_COP)
+ ((CCopPed *)pPed)->ClearPursuit();
+ else
+ pPed->SetIdle();
+ pPed->SetObjective(OBJECTIVE_NONE);
+ } else {
+ pPed->m_prevObjective = OBJECTIVE_NONE;
+ pPed->m_nLastPedState = PED_IDLE;
+ }
+ }
+ }
+ }
+}
+
+void
+CWorld::RemoveEntityInsteadOfProcessingIt(CEntity *ent)
+{
+ if(ent->IsPed()) {
+ if(FindPlayerPed() == ent)
Remove(ent);
else
- CPopulation::RemovePed((CPed*)ent);
+ CPopulation::RemovePed((CPed *)ent);
} else {
Remove(ent);
delete ent;
@@ -978,12 +1611,13 @@ void
CWorld::RemoveFallenPeds(void)
{
int poolSize = CPools::GetPedPool()->GetSize();
- for(int poolIndex = poolSize-1; poolIndex >= 0; poolIndex--) {
+ for(int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
CPed *ped = CPools::GetPedPool()->GetSlot(poolIndex);
- if (ped) {
- if (ped->GetPosition().z < MAP_Z_LOW_LIMIT) {
- if (ped->CharCreatedBy != RANDOM_CHAR || ped->IsPlayer()) {
- int closestNode = ThePaths.FindNodeClosestToCoors(ped->GetPosition(), PATH_PED, 999999.9f, false, false);
+ if(ped) {
+ if(ped->GetPosition().z < MAP_Z_LOW_LIMIT) {
+ if(ped->CharCreatedBy != RANDOM_CHAR || ped->IsPlayer()) {
+ int closestNode = ThePaths.FindNodeClosestToCoors(ped->GetPosition(), PATH_PED,
+ 999999.9f, false, false);
CVector newPos = ThePaths.m_pathNodes[closestNode].pos;
newPos.z += 2.0f;
ped->Teleport(newPos);
@@ -1000,17 +1634,20 @@ void
CWorld::RemoveFallenCars(void)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
- CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh) {
- if (veh->GetPosition().z < MAP_Z_LOW_LIMIT) {
- if (veh->VehicleCreatedBy == MISSION_VEHICLE || veh == FindPlayerVehicle() || (veh->pDriver && veh->pDriver->IsPlayer())) {
- int closestNode = ThePaths.FindNodeClosestToCoors(veh->GetPosition(), PATH_CAR, 999999.9f, false, false);
+ for(int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
+ CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
+ if(veh) {
+ if(veh->GetPosition().z < MAP_Z_LOW_LIMIT) {
+ if(veh->VehicleCreatedBy == MISSION_VEHICLE || veh == FindPlayerVehicle() ||
+ (veh->pDriver && veh->pDriver->IsPlayer())) {
+ int closestNode = ThePaths.FindNodeClosestToCoors(veh->GetPosition(), PATH_CAR,
+ 999999.9f, false, false);
CVector newPos = ThePaths.m_pathNodes[closestNode].pos;
newPos.z += 3.0f;
veh->Teleport(newPos);
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- } else if (veh->VehicleCreatedBy == RANDOM_VEHICLE || veh->VehicleCreatedBy == PARKED_VEHICLE) {
+ } else if(veh->VehicleCreatedBy == RANDOM_VEHICLE ||
+ veh->VehicleCreatedBy == PARKED_VEHICLE) {
Remove(veh);
delete veh;
}
@@ -1023,11 +1660,10 @@ void
CWorld::StopAllLawEnforcersInTheirTracks(void)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
- CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh) {
- if (veh->bIsLawEnforcer)
- veh->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ for(int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
+ CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
+ if(veh) {
+ if(veh->bIsLawEnforcer) veh->SetMoveSpeed(0.0f, 0.0f, 0.0f);
}
}
}
@@ -1036,10 +1672,9 @@ void
CWorld::SetAllCarsCanBeDamaged(bool toggle)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
+ for(int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh)
- veh->bCanBeDamaged = toggle;
+ if(veh) veh->bCanBeDamaged = toggle;
}
}
@@ -1047,11 +1682,181 @@ void
CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
- CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh) {
- if ((point - veh->GetPosition()).MagnitudeSqr() < sq(range))
- veh->ExtinguishCarFire();
+ for(int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
+ CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
+ if(veh) {
+ if((point - veh->GetPosition()).MagnitudeSqr() < sq(range)) veh->ExtinguishCarFire();
+ }
+ }
+}
+
+void
+CWorld::AddParticles(void)
+{
+ for(int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for(int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector *pSector = GetSector(x, y);
+ CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
+ CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
+ }
+ }
+}
+
+void
+CWorld::ShutDown(void)
+{
+ for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
+ CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+ for(int32 i = 0; i < 4; i++) {
+ for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ // Maybe remove from world here?
+ delete pEntity;
+ }
+ GetBigBuildingList((eLevelName)i).Flush();
+ }
+ for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
+ CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) {
+ sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_DUMMIES].first) {
+ sprintf(gString, "Dummy list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first) {
+ sprintf(gString, "Building overlap list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP].first) {
+ sprintf(gString, "Vehicle overlap list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP].first) {
+ sprintf(gString, "Ped overlap list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_PEDS_OVERLAP].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP].first) {
+ sprintf(gString, "Object overlap list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP].Flush();
+ }
+ if(pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].first) {
+ sprintf(gString, "Dummy overlap list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+ }
+ ms_listMovingEntityPtrs.Flush();
+}
+
+void
+CWorld::ClearForRestart(void)
+{
+ if(CCutsceneMgr::HasLoaded()) CCutsceneMgr::DeleteCutsceneData();
+ CProjectileInfo::RemoveAllProjectiles();
+ CObject::DeleteAllTempObjects();
+ CObject::DeleteAllMissionObjects();
+ CPopulation::ConvertAllObjectsToDummyObjects();
+ for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
+ CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = GetBigBuildingList(LEVEL_NONE).first; pNode; pNode = pNode->next) {
+ CVehicle *pVehicle = (CVehicle *)pNode->item;
+ if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ }
+ CPools::CheckPoolsEmpty();
+}
+
+void
+CWorld::RepositionCertainDynamicObjects()
+{
+ int32 i = CPools::GetDummyPool()->GetSize();
+ while(--i >= 0) {
+ CDummy *dummy = CPools::GetDummyPool()->GetSlot(i);
+ if(dummy) { RepositionOneObject(dummy); }
+ }
+}
+
+void
+CWorld::RepositionOneObject(CEntity *pEntity)
+{
+ int16 modelId = pEntity->m_modelIndex;
+ if(modelId == MI_SINGLESTREETLIGHTS1 || modelId == MI_SINGLESTREETLIGHTS2 ||
+ modelId == MI_SINGLESTREETLIGHTS3 || modelId == MI_DOUBLESTREETLIGHTS || modelId == MI_TREE1 ||
+ modelId == MI_TREE2 || modelId == MI_TREE3 || modelId == MI_TREE4 || modelId == MI_TREE5 ||
+ modelId == MI_TREE6 || modelId == MI_TREE7 || modelId == MI_TREE8 || modelId == MI_TREE9 ||
+ modelId == MI_TREE10 || modelId == MI_TREE11 || modelId == MI_TREE12 || modelId == MI_TREE13 ||
+ modelId == MI_TREE14 || modelId == MI_TRAFFICLIGHTS || modelId == MI_PARKINGMETER ||
+ modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || modelId == MI_BIN || modelId == MI_POSTBOX1 ||
+ modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || modelId == MI_DUMP1 ||
+ modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 ||
+ modelId == MI_PHONESIGN || modelId == MI_TAXISIGN || modelId == MI_FISHSTALL01 ||
+ modelId == MI_FISHSTALL02 || modelId == MI_FISHSTALL03 || modelId == MI_FISHSTALL04 ||
+ modelId == MI_BAGELSTAND2 || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT ||
+ modelId == MI_PARKTABLE) {
+ CVector &position = pEntity->GetPosition();
+ float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z;
+ position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y,
+ position.z + OBJECT_REPOSITION_OFFSET_Z, nil) -
+ fBoundingBoxMinZ;
+ pEntity->m_matrix.UpdateRW();
+ pEntity->UpdateRwFrame();
+ } else if(modelId == MI_BUOY) {
+ float fWaterLevel = 0.0f;
+ bool bFound = true;
+ const CVector &position = pEntity->GetPosition();
+ float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y,
+ position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
+ if(CWaterLevel::GetWaterLevelNoWaves(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z,
+ &fWaterLevel)) {
+ if(!bFound || fWaterLevel > fGroundZ) {
+ CColModel *pColModel = pEntity->GetColModel();
+ float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
+ pEntity->GetPosition().z = 0.2f * fHeight + fWaterLevel - 0.5f * fHeight;
+ }
}
}
}
@@ -1060,28 +1865,72 @@ void
CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
+ for(int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh && veh->m_status != STATUS_WRECKED && !veh->m_pCarFire && !veh->bFireProof) {
- if (Abs(veh->GetPosition().z - z) < 5.0f && Abs(veh->GetPosition().x - x) < radius && Abs(veh->GetPosition().y - y) < radius)
- gFireManager.StartFire(veh, reason, 0.8f, true);
+ if(veh && veh->m_status != STATUS_WRECKED && !veh->m_pCarFire && !veh->bFireProof) {
+ if(Abs(veh->GetPosition().z - z) < 5.0f && Abs(veh->GetPosition().x - x) < radius &&
+ Abs(veh->GetPosition().y - y) < radius)
+ gFireManager.StartFire(veh, reason, 0.8f, true);
}
}
}
void
+CWorld::SetPedsOnFire(float x, float y, float z, float radius, CEntity *reason)
+{
+ int32 poolSize = CPools::GetPedPool()->GetSize();
+ for(int32 i = poolSize - 1; i >= 0; i--) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if(pPed && pPed->m_nPedState != PED_DEAD && !pPed->bInVehicle && !pPed->m_pFire && !pPed->bFireProof) {
+ if(Abs(pPed->GetPosition().z - z) < 5.0f && Abs(pPed->GetPosition().x - x) < radius &&
+ Abs(pPed->GetPosition().y - y) < radius)
+ gFireManager.StartFire(pPed, reason, 0.8f, true);
+ }
+ }
+}
+
+void
+CWorld::RemoveStaticObjects()
+{
+ for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
+ CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+}
+
+void
CWorld::Process(void)
{
- if (!(CTimer::GetFrameCounter() & 63))
- CReferences::PruneAllReferencesInWorld();
+ if(!(CTimer::GetFrameCounter() & 63)) CReferences::PruneAllReferencesInWorld();
- if (bProcessCutsceneOnly) {
- for (int i = 0; i < NUMCUTSCENEOBJECTS; i++) {
+ if(bProcessCutsceneOnly) {
+ for(int i = 0; i < NUMCUTSCENEOBJECTS; i++) {
CCutsceneObject *csObj = CCutsceneMgr::GetCutsceneObject(i);
- if (csObj && csObj->m_entryInfoList.first) {
- if (csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP
- && RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * (csObj->m_type == ENTITY_TYPE_OBJECT ? CTimer::GetTimeStepNonClipped() : CTimer::GetTimeStep()));
+ if(csObj && csObj->m_entryInfoList.first) {
+ if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP &&
+ RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(),
+ 0.02f * (csObj->m_type == ENTITY_TYPE_OBJECT
+ ? CTimer::GetTimeStepNonClipped()
+ : CTimer::GetTimeStep()));
}
csObj->ProcessControl();
csObj->ProcessCollision();
@@ -1092,102 +1941,98 @@ CWorld::Process(void)
CRecordDataForChase::ProcessControlCars();
CRecordDataForChase::SaveOrRetrieveCarPositions();
} else {
- for (CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity *movingEnt = (CEntity*)node->item;
- if (movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP
- && RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * (movingEnt->m_type == ENTITY_TYPE_OBJECT ? CTimer::GetTimeStepNonClipped() : CTimer::GetTimeStep()));
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
+ if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
+ RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(),
+ 0.02f * (movingEnt->m_type == ENTITY_TYPE_OBJECT
+ ? CTimer::GetTimeStepNonClipped()
+ : CTimer::GetTimeStep()));
}
}
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CPhysical* movingEnt = (CPhysical*)node->item;
- if (movingEnt->bRemoveFromWorld) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CPhysical *movingEnt = (CPhysical *)node->item;
+ if(movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else {
movingEnt->ProcessControl();
- if (movingEnt->bIsStatic) {
- movingEnt->RemoveFromMovingList();
- }
+ if(movingEnt->bIsStatic) { movingEnt->RemoveFromMovingList(); }
}
}
bForceProcessControl = true;
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CPhysical* movingEnt = (CPhysical*)node->item;
- if (movingEnt->bWasPostponed) {
- if (movingEnt->bRemoveFromWorld) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CPhysical *movingEnt = (CPhysical *)node->item;
+ if(movingEnt->bWasPostponed) {
+ if(movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else {
movingEnt->ProcessControl();
- if (movingEnt->bIsStatic) {
- movingEnt->RemoveFromMovingList();
- }
+ if(movingEnt->bIsStatic) { movingEnt->RemoveFromMovingList(); }
}
}
}
bForceProcessControl = false;
- if (CReplay::IsPlayingBack()) {
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity* movingEnt = (CEntity*)node->item;
+ if(CReplay::IsPlayingBack()) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
movingEnt->bIsInSafePosition = true;
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
}
} else {
bNoMoreCollisionTorque = false;
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity* movingEnt = (CEntity*)node->item;
- if (!movingEnt->bIsInSafePosition) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->ProcessCollision();
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
}
}
bNoMoreCollisionTorque = true;
- for (int i = 0; i < 4; i++) {
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity* movingEnt = (CEntity*)node->item;
- if (!movingEnt->bIsInSafePosition) {
+ for(int i = 0; i < 4; i++) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->ProcessCollision();
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
}
}
}
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity* movingEnt = (CEntity*)node->item;
- if (!movingEnt->bIsInSafePosition) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->bIsStuck = true;
movingEnt->ProcessCollision();
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
- if (!movingEnt->bIsInSafePosition) {
- movingEnt->bIsStuck = true;
- }
+ if(!movingEnt->bIsInSafePosition) { movingEnt->bIsStuck = true; }
}
}
bSecondShift = false;
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CEntity* movingEnt = (CEntity*)node->item;
- if (!movingEnt->bIsInSafePosition) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CEntity *movingEnt = (CEntity *)node->item;
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->ProcessShift();
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
- if (!movingEnt->bIsInSafePosition) {
- movingEnt->bIsStuck = true;
- }
+ if(!movingEnt->bIsInSafePosition) { movingEnt->bIsStuck = true; }
}
}
bSecondShift = true;
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CPhysical* movingEnt = (CPhysical*)node->item;
- if (!movingEnt->bIsInSafePosition) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CPhysical *movingEnt = (CPhysical *)node->item;
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->ProcessShift();
movingEnt->GetMatrix().UpdateRW();
movingEnt->UpdateRwFrame();
- if (!movingEnt->bIsInSafePosition) {
+ if(!movingEnt->bIsInSafePosition) {
movingEnt->bIsStuck = true;
- if (movingEnt->m_status == STATUS_PLAYER) {
- printf("STUCK: Final Step: Player Entity %d Is Stuck\n", movingEnt->m_modelIndex);
+ if(movingEnt->m_status == STATUS_PLAYER) {
+ printf("STUCK: Final Step: Player Entity %d Is Stuck\n",
+ movingEnt->m_modelIndex);
movingEnt->m_vecMoveSpeed *= 0.3f;
movingEnt->ApplyMoveSpeed();
movingEnt->ApplyTurnSpeed();
@@ -1196,35 +2041,28 @@ CWorld::Process(void)
}
}
}
- for (CPtrNode* node = ms_listMovingEntityPtrs.first; node; node = node->next) {
- CPed* movingPed = (CPed*)node->item;
- if (movingPed->IsPed()) {
- if (movingPed->bInVehicle && movingPed->m_nPedState != PED_EXIT_TRAIN || movingPed->EnteringCar()) {
+ for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
+ CPed *movingPed = (CPed *)node->item;
+ if(movingPed->IsPed()) {
+ if(movingPed->bInVehicle && movingPed->m_nPedState != PED_EXIT_TRAIN ||
+ movingPed->EnteringCar()) {
CVehicle *movingCar = movingPed->m_pMyVehicle;
- if (movingCar) {
- if (movingCar->IsTrain()) {
+ if(movingCar) {
+ if(movingCar->IsTrain()) {
movingPed->SetPedPositionInTrain();
} else {
- switch (movingPed->m_nPedState) {
- case PED_ENTER_CAR:
- case PED_CARJACK:
- movingPed->EnterCar();
- break;
- case PED_DRAG_FROM_CAR:
+ switch(movingPed->m_nPedState) {
+ case PED_ENTER_CAR:
+ case PED_CARJACK: movingPed->EnterCar(); break;
+ case PED_DRAG_FROM_CAR: movingPed->BeingDraggedFromCar(); break;
+ case PED_EXIT_CAR: movingPed->ExitCar(); break;
+ case PED_ARRESTED:
+ if(movingPed->m_nLastPedState == PED_DRAG_FROM_CAR) {
movingPed->BeingDraggedFromCar();
break;
- case PED_EXIT_CAR:
- movingPed->ExitCar();
- break;
- case PED_ARRESTED:
- if (movingPed->m_nLastPedState == PED_DRAG_FROM_CAR) {
- movingPed->BeingDraggedFromCar();
- break;
- }
- // fall through
- default:
- movingPed->SetPedPositionInCar();
- break;
+ }
+ // fall through
+ default: movingPed->SetPedPositionInCar(); break;
}
}
movingPed->GetMatrix().UpdateRW();
@@ -1239,39 +2077,161 @@ CWorld::Process(void)
CMessages::Process();
Players[PlayerInFocus].Process();
CRecordDataForChase::SaveOrRetrieveCarPositions();
- if ((CTimer::GetFrameCounter() & 7) == 1) {
+ if((CTimer::GetFrameCounter() & 7) == 1) {
RemoveFallenPeds();
- } else if ((CTimer::GetFrameCounter() & 7) == 5) {
+ } else if((CTimer::GetFrameCounter() & 7) == 5) {
RemoveFallenCars();
}
}
}
-STARTPATCHES
- InjectHook(0x4AE930, CWorld::Add, PATCH_JUMP);
- InjectHook(0x4AE9D0, CWorld::Remove, PATCH_JUMP);
- InjectHook(0x4B1F60, CWorld::ClearScanCodes, PATCH_JUMP);
- InjectHook(0x4AF970, CWorld::ProcessLineOfSight, PATCH_JUMP);
- InjectHook(0x4B0A80, CWorld::ProcessLineOfSightSector, PATCH_JUMP);
- InjectHook(0x4B0C70, CWorld::ProcessLineOfSightSectorList, PATCH_JUMP);
- InjectHook(0x4B0DE0, CWorld::ProcessVerticalLine, PATCH_JUMP);
- InjectHook(0x4B0EF0, CWorld::ProcessVerticalLineSector, PATCH_JUMP);
- InjectHook(0x4B1090, CWorld::ProcessVerticalLineSectorList, PATCH_JUMP);
- InjectHook(0x4AEAA0, CWorld::GetIsLineOfSightClear, PATCH_JUMP);
- InjectHook(0x4B2000, CWorld::GetIsLineOfSightSectorClear, PATCH_JUMP);
- InjectHook(0x4B2160, CWorld::GetIsLineOfSightSectorListClear, PATCH_JUMP);
-
- InjectHook(0x4B2200, CWorld::FindObjectsInRange, PATCH_JUMP);
- InjectHook(0x4B2540, CWorld::FindObjectsInRangeSectorList, PATCH_JUMP);
- InjectHook(0x4B4AC0, CWorld::TestSphereAgainstSectorList, PATCH_JUMP);
- InjectHook(0x4B4710, CWorld::TestSphereAgainstWorld, PATCH_JUMP);
- InjectHook(0x4B3A80, CWorld::FindGroundZForCoord, PATCH_JUMP);
- InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
- InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
-
- InjectHook(0x4B5BC0, CWorld::StopAllLawEnforcersInTheirTracks, PATCH_JUMP);
- InjectHook(0x4B53F0, CWorld::SetAllCarsCanBeDamaged, PATCH_JUMP);
- InjectHook(0x4B5460, CWorld::ExtinguishAllCarFiresInArea, PATCH_JUMP);
-
- InjectHook(0x4B1A60, CWorld::Process, PATCH_JUMP);
-ENDPATCHES
+void
+CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, CEntity *pCreator,
+ bool bProcessVehicleBombTimer)
+{
+ CVector2D vecStartPos(position.x - fRadius, position.y - fRadius);
+ CVector2D vecEndPos(position.x + fRadius, position.y + fRadius);
+ const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for(int32 y = nStartY; y <= nEndY; y++) {
+ for(int32 x = nStartX; x <= nEndX; x++) {
+ CSector *pSector = CWorld::GetSector(x, y);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
+ fPower, pCreator, bProcessVehicleBombTimer);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
+ pCreator, bProcessVehicleBombTimer);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius,
+ fPower, pCreator, bProcessVehicleBombTimer);
+ }
+ }
+}
+
+void
+CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, float fRadius, float fPower,
+ CEntity *pCreator, bool bProcessVehicleBombTimer)
+{
+ for(CPtrNode *pNode = list.first; pNode; pNode = pNode->next) {
+ CPhysical *pEntity = (CPhysical *)pNode->item;
+ CVector vecDistance = pEntity->GetPosition() - position;
+ float fMagnitude = vecDistance.Magnitude();
+ if(fRadius > fMagnitude) {
+ CWeapon::BlowUpExplosiveThings(pEntity);
+ CPed *pPed = (CPed *)pEntity;
+ CObject *pObject = (CObject *)pEntity;
+ CVehicle *pVehicle = (CVehicle *)pEntity;
+ if(!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) {
+ if(pEntity->bIsStatic) {
+ if(pEntity->IsObject()) {
+ if(fPower > pObject->m_fUprootLimit || IsFence(pObject->m_modelIndex)) {
+ if(IsGlass(pObject->m_modelIndex)) {
+ CGlass::WindowRespondsToExplosion(pObject, position);
+ } else {
+ pObject->bIsStatic = false;
+ pObject->AddToMovingList();
+ int16 modelId = pEntity->m_modelIndex;
+ if(modelId != MI_FIRE_HYDRANT ||
+ pObject->bHasBeenDamaged) {
+ if(pEntity->IsObject() &&
+ modelId != MI_EXPLODINGBARREL &&
+ modelId != MI_PETROLPUMP)
+ pObject->bHasBeenDamaged = true;
+ } else {
+ CVector pos = pEntity->GetPosition();
+ pos.z -= 0.5f;
+ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT,
+ pos, true);
+ pObject->bHasBeenDamaged = true;
+ }
+ }
+ }
+ if(pEntity->bIsStatic) {
+ float fDamageMultiplier =
+ (fRadius - fMagnitude) * 2.0f / fRadius;
+ float fDamage = 300.0f * Min(fDamageMultiplier, 1.0f);
+ pObject->ObjectDamage(fDamage);
+ }
+ } else {
+ pEntity->bIsStatic = false;
+ pEntity->AddToMovingList();
+ }
+ }
+ if(!pEntity->bIsStatic) {
+ float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
+ CVector vecForceDir =
+ vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier /
+ Max(fMagnitude, 0.01f));
+ vecForceDir.z = Max(vecForceDir.z, 0.0f);
+ if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f);
+ pEntity->ApplyMoveForce(vecForceDir);
+ if(!pEntity->bPedPhysics) {
+ float fBoundRadius = pEntity->GetBoundRadius();
+ float fDistanceZ = position.z - pEntity->GetPosition().z;
+ float fPointZ = fBoundRadius;
+ if(Max(fDistanceZ, -fBoundRadius) < fBoundRadius) {
+ if(fDistanceZ <= -fBoundRadius)
+ fPointZ = -fBoundRadius;
+ else
+ fPointZ = fDistanceZ;
+ }
+ pEntity->ApplyTurnForce(vecForceDir.x, vecForceDir.y, vecForceDir.z,
+ 0.0f, 0.0f, fPointZ);
+ }
+ switch(pEntity->m_type) {
+ case ENTITY_TYPE_VEHICLE:
+ if(pEntity->m_status == STATUS_SIMPLE) {
+ pEntity->m_status = STATUS_PHYSICS;
+ CCarCtrl::SwitchVehicleToRealPhysics(pVehicle);
+ }
+ pVehicle->InflictDamage(pCreator, WEAPONTYPE_EXPLOSION,
+ 1100.0f * fDamageMultiplier);
+ if(bProcessVehicleBombTimer) {
+ if(pVehicle->m_nBombTimer) pVehicle->m_nBombTimer /= 10;
+ }
+ break;
+ case ENTITY_TYPE_PED: {
+ int8 direction = pPed->GetLocalDirection(-vecForceDir);
+ pPed->bIsStanding = false;
+ pPed->ApplyMoveForce(0.0, 0.0, 2.0f);
+ float fDamage = 250.0f * fDamageMultiplier;
+ pPed->InflictDamage(pCreator, WEAPONTYPE_EXPLOSION, fDamage,
+ PEDPIECE_TORSO, direction);
+ if(pPed->m_nPedState != PED_DIE)
+ pPed->SetFall(2000,
+ (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0);
+ if(pCreator && pCreator->IsPed()) {
+ eEventType eventType = EVENT_SHOOT_PED;
+ if(pPed->m_nPedType == PEDTYPE_COP) eventType = EVENT_SHOOT_COP;
+ CEventList::RegisterEvent(eventType, EVENT_ENTITY_PED, pEntity,
+ (CPed *)pCreator, 10000);
+ pPed->RegisterThreatWithGangPeds(pCreator);
+ }
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ pObject->ObjectDamage(300.0f * fDamageMultiplier);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CWorld::UseDetonator(CEntity *pEntity)
+{
+ int32 i = CPools::GetVehiclePool()->GetSize();
+ while(--i >= 0) {
+ CAutomobile *pVehicle = (CAutomobile *)CPools::GetVehiclePool()->GetSlot(i);
+ if(pVehicle && !pVehicle->m_vehType && pVehicle->m_bombType == CARBOMB_REMOTE &&
+ pVehicle->m_pBombRigger == pEntity) {
+ pVehicle->m_bombType = CARBOMB_NONE;
+ pVehicle->m_nBombTimer = 500;
+ pVehicle->m_pBlowUpEntity = pVehicle->m_pBombRigger;
+ if(pVehicle->m_pBlowUpEntity)
+ pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity);
+ }
+ }
+}
diff --git a/src/core/World.h b/src/core/World.h
index 07e7889f..25c76531 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -54,22 +54,22 @@ struct CStoredCollPoly;
class CWorld
{
- static CPtrList *ms_bigBuildingsList; // [4];
- static CPtrList &ms_listMovingEntityPtrs;
- static CSector (*ms_aSectors)[NUMSECTORS_X]; // [NUMSECTORS_Y][NUMSECTORS_X];
- static uint16 &ms_nCurrentScanCode;
+ static CPtrList ms_bigBuildingsList[4];
+ static CPtrList ms_listMovingEntityPtrs;
+ static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
+ static uint16 ms_nCurrentScanCode;
public:
- static uint8 &PlayerInFocus;
- static CPlayerInfo (&Players)[NUMPLAYERS];
- static CEntity *&pIgnoreEntity;
- static bool &bIncludeDeadPeds;
- static bool &bNoMoreCollisionTorque;
- static bool &bSecondShift;
- static bool &bForceProcessControl;
- static bool &bProcessCutsceneOnly;
- static bool &bDoingCarCollisions;
- static bool &bIncludeCarTyres;
+ static uint8 PlayerInFocus;
+ static CPlayerInfo Players[NUMPLAYERS];
+ static CEntity *pIgnoreEntity;
+ static bool bIncludeDeadPeds;
+ static bool bNoMoreCollisionTorque;
+ static bool bSecondShift;
+ static bool bForceProcessControl;
+ static bool bProcessCutsceneOnly;
+ static bool bDoingCarCollisions;
+ static bool bIncludeCarTyres;
static void Remove(CEntity *entity);
static void Add(CEntity *entity);
@@ -85,7 +85,7 @@ public:
}
}
static void ClearScanCodes(void);
- static void ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8);
+ static void ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemoveProjectilesAndTidyUpShadows);
static bool CameraToIgnoreThisObject(CEntity *ent);
@@ -103,19 +103,26 @@ public:
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
- static void FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVector&, float, bool, short*, short, CEntity**);
- static void FindObjectsOfTypeInRange(uint32, CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
+ static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
static float FindGroundZForCoord(float x, float y);
static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
static void RemoveReferencesToDeletedObject(CEntity*);
- static void FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
- static void FindObjectsIntersectingCube(const CVector &, const CVector &, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
+ static void FindObjectsKindaColliding(const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
+ static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
+ static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities);
static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
- static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
- static void ClearCarsFromArea(float, float, float, float, float, float);
- static void ClearPedsFromArea(float, float, float, float, float, float);
- static void CallOffChaseForArea(float, float, float, float);
+ static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects);
+ static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList);
+
+ static void ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
+ static void ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
+ static void CallOffChaseForArea(float x1, float y1, float x2, float y2);
+ static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY);
+ static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2);
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
@@ -131,20 +138,23 @@ public:
static void StopAllLawEnforcersInTheirTracks();
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
- static void SetCarsOnFire(float, float, float, float, CEntity*);
- static void SetPedsOnFire(float, float, float, float, CEntity*);
+ static void SetCarsOnFire(float x, float y, float z, float radius, CEntity* reason);
+ static void SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason);
static void Initialise();
static void AddParticles();
static void ShutDown();
static void ClearForRestart(void);
static void RepositionCertainDynamicObjects();
+ static void RepositionOneObject(CEntity* pEntity);
static void RemoveStaticObjects();
static void Process();
- static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
+ static void TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
+ static void TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
+ static void UseDetonator(CEntity *pEntity);
};
-extern CColPoint *gaTempSphereColPoints;
+extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
class CPlayerPed;
class CVehicle;
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index 4a2bea4f..7a221f39 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Building.h"
#include "Treadable.h"
#include "Train.h"
@@ -11,21 +11,21 @@
#include "ZoneCull.h"
#include "Zones.h"
-int32 &CCullZones::NumCullZones = *(int*)0x8F2564;
-CCullZone(&CCullZones::aZones)[NUMCULLZONES] = *(CCullZone(*)[NUMCULLZONES])*(uintptr*)0x864750;
-int32 &CCullZones::NumAttributeZones = *(int*)0x8E29D0;
-CAttributeZone (&CCullZones::aAttributeZones)[NUMATTRIBZONES] = *(CAttributeZone(*)[NUMATTRIBZONES])*(uintptr*)0x709C60;
-uint16 (&CCullZones::aIndices)[NUMZONEINDICES] = *(uint16(*)[NUMZONEINDICES])*(uintptr*)0x847330;
-int16 (&CCullZones::aPointersToBigBuildingsForBuildings)[NUMBUILDINGS] = *(int16(*)[NUMBUILDINGS])*(uintptr*)0x86C9D0;
-int16 (&CCullZones::aPointersToBigBuildingsForTreadables)[NUMTREADABLES] = *(int16(*)[NUMTREADABLES])*(uintptr*)0x8F1B8C;
+int32 CCullZones::NumCullZones;
+CCullZone CCullZones::aZones[NUMCULLZONES];
+int32 CCullZones::NumAttributeZones;
+CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES];
+uint16 CCullZones::aIndices[NUMZONEINDICES];
+int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
+int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES];
-int32 &CCullZones::CurrentWantedLevelDrop_Player = *(int32*)0x880DA8;
-int32 &CCullZones::CurrentFlags_Camera = *(int32*)0x940718;
-int32 &CCullZones::CurrentFlags_Player = *(int32*)0x9415F0;
-int32 &CCullZones::OldCullZone = *(int32*)0x8E2C90;
-int32 &CCullZones::EntityIndicesUsed = *(int32*)0x8F2508;
-bool &CCullZones::bCurrentSubwayIsInvisible = *(bool*)0x95CDA5;
-bool &CCullZones::bCullZonesDisabled = *(bool*)0x95CD4A;
+int32 CCullZones::CurrentWantedLevelDrop_Player;
+int32 CCullZones::CurrentFlags_Camera;
+int32 CCullZones::CurrentFlags_Player;
+int32 CCullZones::OldCullZone;
+int32 CCullZones::EntityIndicesUsed;
+bool CCullZones::bCurrentSubwayIsInvisible;
+bool CCullZones::bCullZonesDisabled;
void
@@ -289,7 +289,7 @@ CCullZones::FindAttributesForCoors(CVector coors, int32 *wantedLevel)
coors.z >= aAttributeZones[i].minz && coors.z <= aAttributeZones[i].maxz){
attribs |= aAttributeZones[i].attributes;
if(wantedLevel)
- *wantedLevel = max(*wantedLevel, aAttributeZones[i].wantedLevel);
+ *wantedLevel = Max(*wantedLevel, aAttributeZones[i].wantedLevel);
}
return attribs;
}
@@ -562,17 +562,3 @@ CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set)
}
return false;
}
-
-STARTPATCHES
- InjectHook(0x524BC0, &CCullZones::Init, PATCH_JUMP);
- InjectHook(0x524EC0, &CCullZones::ResolveVisibilities, PATCH_JUMP);
- InjectHook(0x524F80, &CCullZones::Update, PATCH_JUMP);
- InjectHook(0x525370, &CCullZones::AddCullZone, PATCH_JUMP);
- InjectHook(0x5250D0, &CCullZones::ForceCullZoneCoors, PATCH_JUMP);
- InjectHook(0x525130, &CCullZones::FindCullZoneForCoors, PATCH_JUMP);
- InjectHook(0x5251C0, &CCullZones::FindAttributesForCoors, PATCH_JUMP);
- InjectHook(0x525290, &CCullZones::FindZoneWithStairsAttributeForPlayer, PATCH_JUMP);
-
- InjectHook(0x525610, &CCullZone::DoStuffLeavingZone, PATCH_JUMP);
- InjectHook(0x525810, &CCullZone::DoStuffEnteringZone, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index edaa7c4b..9bc07b8c 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -79,21 +79,21 @@ struct CAttributeZone
class CCullZones
{
public:
- static int32 &NumCullZones;
- static CCullZone (&aZones)[NUMCULLZONES];
- static int32 &NumAttributeZones;
- static CAttributeZone(&aAttributeZones)[NUMATTRIBZONES];
- static uint16 (&aIndices)[NUMZONEINDICES];
- static int16 (&aPointersToBigBuildingsForBuildings)[NUMBUILDINGS];
- static int16 (&aPointersToBigBuildingsForTreadables)[NUMTREADABLES];
+ static int32 NumCullZones;
+ static CCullZone aZones[NUMCULLZONES];
+ static int32 NumAttributeZones;
+ static CAttributeZone aAttributeZones[NUMATTRIBZONES];
+ static uint16 aIndices[NUMZONEINDICES];
+ static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
+ static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES];
- static int32 &CurrentWantedLevelDrop_Player;
- static int32 &CurrentFlags_Camera;
- static int32 &CurrentFlags_Player;
- static int32 &OldCullZone;
- static int32 &EntityIndicesUsed;
- static bool &bCurrentSubwayIsInvisible;
- static bool &bCullZonesDisabled;
+ static int32 CurrentWantedLevelDrop_Player;
+ static int32 CurrentFlags_Camera;
+ static int32 CurrentFlags_Player;
+ static int32 OldCullZone;
+ static int32 EntityIndicesUsed;
+ static bool bCurrentSubwayIsInvisible;
+ static bool bCullZonesDisabled;
static void Init(void);
static void ResolveVisibilities(void);
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 4bce3e79..804708b4 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include <ctype.h>
#include "Zones.h"
@@ -8,18 +8,18 @@
#include "Text.h"
#include "World.h"
-eLevelName &CTheZones::m_CurrLevel = *(eLevelName*)0x8F2BC8;
-CZone *&CTheZones::m_pPlayersZone = *(CZone**)0x8F254C;
-int16 &CTheZones::FindIndex = *(int16*)0x95CC40;
+eLevelName CTheZones::m_CurrLevel;
+CZone *CTheZones::m_pPlayersZone;
+int16 CTheZones::FindIndex;
-uint16 &CTheZones::NumberOfAudioZones = *(uint16*)0x95CC84;
-int16 *CTheZones::AudioZoneArray = (int16*)0x713BC0;
-uint16 &CTheZones::TotalNumberOfMapZones = *(uint16*)0x95CC74;
-uint16 &CTheZones::TotalNumberOfZones = *(uint16*)0x95CC36;
-CZone *CTheZones::ZoneArray = (CZone*)0x86BEE0;
-CZone *CTheZones::MapZoneArray = (CZone*)0x663EC0;
-uint16 &CTheZones::TotalNumberOfZoneInfos = *(uint16*)0x95CC3C;
-CZoneInfo *CTheZones::ZoneInfoArray = (CZoneInfo*)0x714400;
+uint16 CTheZones::NumberOfAudioZones;
+int16 CTheZones::AudioZoneArray[NUMAUDIOZONES];
+uint16 CTheZones::TotalNumberOfMapZones;
+uint16 CTheZones::TotalNumberOfZones;
+CZone CTheZones::ZoneArray[NUMZONES];
+CZone CTheZones::MapZoneArray[NUMMAPZONES];
+uint16 CTheZones::TotalNumberOfZoneInfos;
+CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES];
#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
@@ -625,251 +625,113 @@ CTheZones::InitialiseAudioZoneArray(void)
}
void
-CTheZones::SaveAllZones(uint8 *buffer, uint32 *length)
+CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
+ INITSAVEBUF
int i;
- *length = 8 + 12 +
- NUMZONES*56 + 2*NUMZONES*58 + 4 +
- NUMMAPZONES*56 + NUMAUDIOZONES*2 + 4;
-
- buffer[0] = 'Z';
- buffer[1] = 'N';
- buffer[2] = 'S';
- buffer[3] = '\0';
- *(uint32*)(buffer+4) = *length - 8;
- buffer += 8;
-
- *(int32*)(buffer) = GetIndexForZonePointer(m_pPlayersZone);
- *(int32*)(buffer+4) = m_CurrLevel;
- *(int16*)(buffer+8) = FindIndex;
- *(int16*)(buffer+10) = 0;
- buffer += 12;
-
- for(i = 0; i < NUMZONES; i++){
- memcpy(buffer, ZoneArray[i].name, 8);
- *(float*)(buffer+8) = ZoneArray[i].minx;
- *(float*)(buffer+12) = ZoneArray[i].miny;
- *(float*)(buffer+16) = ZoneArray[i].minz;
- *(float*)(buffer+20) = ZoneArray[i].maxx;
- *(float*)(buffer+24) = ZoneArray[i].maxy;
- *(float*)(buffer+28) = ZoneArray[i].maxz;
- *(int32*)(buffer+32) = ZoneArray[i].type;
- *(int32*)(buffer+36) = ZoneArray[i].level;
- *(int16*)(buffer+40) = ZoneArray[i].zoneinfoDay;
- *(int16*)(buffer+42) = ZoneArray[i].zoneinfoNight;
- *(int32*)(buffer+44) = GetIndexForZonePointer(ZoneArray[i].child);
- *(int32*)(buffer+48) = GetIndexForZonePointer(ZoneArray[i].parent);
- *(int32*)(buffer+52) = GetIndexForZonePointer(ZoneArray[i].next);
- buffer += 56;
+ *size = SAVE_HEADER_SIZE
+ + sizeof(int32) // GetIndexForZonePointer
+ + sizeof(m_CurrLevel) + sizeof(FindIndex)
+ + sizeof(int16) // padding
+ + sizeof(ZoneArray) + sizeof(ZoneInfoArray)
+ + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
+ + sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+ + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
+
+ WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
+
+ WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone));
+ WriteSaveBuf(buffer, m_CurrLevel);
+ WriteSaveBuf(buffer, FindIndex);
+ WriteSaveBuf(buffer, (int16)0); // padding
+
+ for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+ CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
+ zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
}
- for(i = 0; i < 2*NUMZONES; i++){
- *(int16*)(buffer) = ZoneInfoArray[i].carDensity;
- *(int16*)(buffer+2) = ZoneInfoArray[i].carThreshold[0];
- *(int16*)(buffer+4) = ZoneInfoArray[i].carThreshold[1];
- *(int16*)(buffer+6) = ZoneInfoArray[i].carThreshold[2];
- *(int16*)(buffer+8) = ZoneInfoArray[i].carThreshold[3];
- *(int16*)(buffer+10) = ZoneInfoArray[i].carThreshold[4];
- *(int16*)(buffer+12) = ZoneInfoArray[i].carThreshold[5];
- *(int16*)(buffer+14) = ZoneInfoArray[i].copThreshold;
- *(int16*)(buffer+16) = ZoneInfoArray[i].gangThreshold[0];
- *(int16*)(buffer+18) = ZoneInfoArray[i].gangThreshold[1];
- *(int16*)(buffer+20) = ZoneInfoArray[i].gangThreshold[2];
- *(int16*)(buffer+22) = ZoneInfoArray[i].gangThreshold[3];
- *(int16*)(buffer+24) = ZoneInfoArray[i].gangThreshold[4];
- *(int16*)(buffer+26) = ZoneInfoArray[i].gangThreshold[5];
- *(int16*)(buffer+28) = ZoneInfoArray[i].gangThreshold[6];
- *(int16*)(buffer+30) = ZoneInfoArray[i].gangThreshold[7];
- *(int16*)(buffer+32) = ZoneInfoArray[i].gangThreshold[8];
- *(uint16*)(buffer+34) = ZoneInfoArray[i].pedDensity;
- *(uint16*)(buffer+36) = ZoneInfoArray[i].copDensity;
- *(uint16*)(buffer+38) = ZoneInfoArray[i].gangDensity[0];
- *(uint16*)(buffer+40) = ZoneInfoArray[i].gangDensity[1];
- *(uint16*)(buffer+42) = ZoneInfoArray[i].gangDensity[2];
- *(uint16*)(buffer+44) = ZoneInfoArray[i].gangDensity[3];
- *(uint16*)(buffer+46) = ZoneInfoArray[i].gangDensity[4];
- *(uint16*)(buffer+48) = ZoneInfoArray[i].gangDensity[5];
- *(uint16*)(buffer+50) = ZoneInfoArray[i].gangDensity[6];
- *(uint16*)(buffer+52) = ZoneInfoArray[i].gangDensity[7];
- *(uint16*)(buffer+54) = ZoneInfoArray[i].gangDensity[8];
- *(uint16*)(buffer+56) = ZoneInfoArray[i].pedGroup;
- buffer += 58;
+ for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
+ WriteSaveBuf(buffer, ZoneInfoArray[i]);
+
+ WriteSaveBuf(buffer, TotalNumberOfZones);
+ WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
+
+ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
+ CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
+
+ /*
+ The call of GetIndexForZonePointer is wrong, as it is
+ meant for a different array, but the game doesn't brake
+ if those fields are nil. Let's make sure they are.
+ */
+ assert(MapZoneArray[i].child == nil);
+ assert(MapZoneArray[i].parent == nil);
+ assert(MapZoneArray[i].next == nil);
+ zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
}
- *(uint16*)(buffer) = TotalNumberOfZones;
- *(uint16*)(buffer+2) = TotalNumberOfZoneInfos;
- buffer += 4;
-
- for(i = 0; i < NUMMAPZONES; i++){
- memcpy(buffer, MapZoneArray[i].name, 8);
- *(float*)(buffer+8) = MapZoneArray[i].minx;
- *(float*)(buffer+12) = MapZoneArray[i].miny;
- *(float*)(buffer+16) = MapZoneArray[i].minz;
- *(float*)(buffer+20) = MapZoneArray[i].maxx;
- *(float*)(buffer+24) = MapZoneArray[i].maxy;
- *(float*)(buffer+28) = MapZoneArray[i].maxz;
- *(int32*)(buffer+32) = MapZoneArray[i].type;
- *(int32*)(buffer+36) = MapZoneArray[i].level;
- *(int16*)(buffer+40) = MapZoneArray[i].zoneinfoDay;
- *(int16*)(buffer+42) = MapZoneArray[i].zoneinfoNight;
-#ifdef STANDALONE
- // BUG: GetIndexForZonePointer uses ZoneArray
- // so indices will be unpredictable with different memory layout
- assert(0);
-#endif
- *(int32*)(buffer+44) = GetIndexForZonePointer(MapZoneArray[i].child);
- *(int32*)(buffer+48) = GetIndexForZonePointer(MapZoneArray[i].parent);
- *(int32*)(buffer+52) = GetIndexForZonePointer(MapZoneArray[i].next);
- buffer += 56;
- }
+ for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
+ WriteSaveBuf(buffer, AudioZoneArray[i]);
- for(i = 0; i < NUMAUDIOZONES; i++){
- *(int16*)buffer = AudioZoneArray[i];
- buffer += 2;
- }
+ WriteSaveBuf(buffer, TotalNumberOfMapZones);
+ WriteSaveBuf(buffer, NumberOfAudioZones);
- *(uint16*)(buffer) = TotalNumberOfMapZones;
- *(uint16*)(buffer+2) = NumberOfAudioZones;
+ VALIDATESAVEBUF(*size)
}
void
-CTheZones::LoadAllZones(uint8 *buffer, uint32 length)
+CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
+ INITSAVEBUF
int i;
- assert(length == 8 + 12 +
- NUMZONES*56 + 2*NUMZONES*58 + 4 +
- NUMMAPZONES*56 + NUMAUDIOZONES*2 + 4);
- assert(buffer[0] == 'Z');
- assert(buffer[1] == 'N');
- assert(buffer[2] == 'S');
- assert(buffer[3] == '\0');
- assert(*(uint32*)(buffer+4) == length - 8);
- buffer += 8;
-
- m_pPlayersZone = GetPointerForZoneIndex(*(int32*)(buffer));
- m_CurrLevel = (eLevelName)*(int32*)(buffer+4);
- FindIndex = *(int16*)(buffer+8);
- assert(*(int16*)(buffer+10) == 0);
- buffer += 12;
-
- for(i = 0; i < NUMZONES; i++){
- memcpy(ZoneArray[i].name, buffer, 8);
- ZoneArray[i].minx = *(float*)(buffer+8);
- ZoneArray[i].miny = *(float*)(buffer+12);
- ZoneArray[i].minz = *(float*)(buffer+16);
- ZoneArray[i].maxx = *(float*)(buffer+20);
- ZoneArray[i].maxy = *(float*)(buffer+24);
- ZoneArray[i].maxz = *(float*)(buffer+28);
- ZoneArray[i].type = (eZoneType)*(int32*)(buffer+32);
- ZoneArray[i].level = (eLevelName)*(int32*)(buffer+36);
- ZoneArray[i].zoneinfoDay = *(int16*)(buffer+40);
- ZoneArray[i].zoneinfoNight = *(int16*)(buffer+42);
- ZoneArray[i].child = GetPointerForZoneIndex(*(int32*)(buffer+44));
- ZoneArray[i].parent = GetPointerForZoneIndex(*(int32*)(buffer+48));
- ZoneArray[i].next = GetPointerForZoneIndex(*(int32*)(buffer+52));
- buffer += 56;
- }
+ CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
- for(i = 0; i < 2*NUMZONES; i++){
- ZoneInfoArray[i].carDensity = *(int16*)(buffer);
- ZoneInfoArray[i].carThreshold[0] = *(int16*)(buffer+2);
- ZoneInfoArray[i].carThreshold[1] = *(int16*)(buffer+4);
- ZoneInfoArray[i].carThreshold[2] = *(int16*)(buffer+6);
- ZoneInfoArray[i].carThreshold[3] = *(int16*)(buffer+8);
- ZoneInfoArray[i].carThreshold[4] = *(int16*)(buffer+10);
- ZoneInfoArray[i].carThreshold[5] = *(int16*)(buffer+12);
- ZoneInfoArray[i].copThreshold = *(int16*)(buffer+14);
- ZoneInfoArray[i].gangThreshold[0] = *(int16*)(buffer+16);
- ZoneInfoArray[i].gangThreshold[1] = *(int16*)(buffer+18);
- ZoneInfoArray[i].gangThreshold[2] = *(int16*)(buffer+20);
- ZoneInfoArray[i].gangThreshold[3] = *(int16*)(buffer+22);
- ZoneInfoArray[i].gangThreshold[4] = *(int16*)(buffer+24);
- ZoneInfoArray[i].gangThreshold[5] = *(int16*)(buffer+26);
- ZoneInfoArray[i].gangThreshold[6] = *(int16*)(buffer+28);
- ZoneInfoArray[i].gangThreshold[7] = *(int16*)(buffer+30);
- ZoneInfoArray[i].gangThreshold[8] = *(int16*)(buffer+32);
- ZoneInfoArray[i].pedDensity = *(uint16*)(buffer+34);
- ZoneInfoArray[i].copDensity = *(uint16*)(buffer+36);
- ZoneInfoArray[i].gangDensity[0] = *(uint16*)(buffer+38);
- ZoneInfoArray[i].gangDensity[1] = *(uint16*)(buffer+40);
- ZoneInfoArray[i].gangDensity[2] = *(uint16*)(buffer+42);
- ZoneInfoArray[i].gangDensity[3] = *(uint16*)(buffer+44);
- ZoneInfoArray[i].gangDensity[4] = *(uint16*)(buffer+46);
- ZoneInfoArray[i].gangDensity[5] = *(uint16*)(buffer+48);
- ZoneInfoArray[i].gangDensity[6] = *(uint16*)(buffer+50);
- ZoneInfoArray[i].gangDensity[7] = *(uint16*)(buffer+52);
- ZoneInfoArray[i].gangDensity[8] = *(uint16*)(buffer+54);
- ZoneInfoArray[i].pedGroup = *(uint16*)(buffer+56);
- buffer += 58;
- }
+ m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer));
+ m_CurrLevel = ReadSaveBuf<eLevelName>(buffer);
+ FindIndex = ReadSaveBuf<int16>(buffer);
+ ReadSaveBuf<int16>(buffer);
- TotalNumberOfZones = *(uint16*)(buffer);
- TotalNumberOfZoneInfos = *(uint16*)(buffer+2);
- buffer += 4;
+ for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+ ZoneArray[i] = ReadSaveBuf<CZone>(buffer);
- for(i = 0; i < NUMMAPZONES; i++){
- memcpy(MapZoneArray[i].name, buffer, 8);
- MapZoneArray[i].minx = *(float*)(buffer+8);
- MapZoneArray[i].miny = *(float*)(buffer+12);
- MapZoneArray[i].minz = *(float*)(buffer+16);
- MapZoneArray[i].maxx = *(float*)(buffer+20);
- MapZoneArray[i].maxy = *(float*)(buffer+24);
- MapZoneArray[i].maxz = *(float*)(buffer+28);
- MapZoneArray[i].type = (eZoneType)*(int32*)(buffer+32);
- MapZoneArray[i].level = (eLevelName)*(int32*)(buffer+36);
- MapZoneArray[i].zoneinfoDay = *(int16*)(buffer+40);
- MapZoneArray[i].zoneinfoNight = *(int16*)(buffer+42);
-#ifdef STANDALONE
- // BUG: GetPointerForZoneIndex uses ZoneArray
- // so pointers will be unpredictable with different memory layout
- assert(0);
-#endif
- MapZoneArray[i].child = GetPointerForZoneIndex(*(int32*)(buffer+44));
- MapZoneArray[i].parent = GetPointerForZoneIndex(*(int32*)(buffer+48));
- MapZoneArray[i].next = GetPointerForZoneIndex(*(int32*)(buffer+52));
- buffer += 56;
+ ZoneArray[i].child = GetPointerForZoneIndex((int32)ZoneArray[i].child);
+ ZoneArray[i].parent = GetPointerForZoneIndex((int32)ZoneArray[i].parent);
+ ZoneArray[i].next = GetPointerForZoneIndex((int32)ZoneArray[i].next);
}
- for(i = 0; i < NUMAUDIOZONES; i++){
- AudioZoneArray[i] = *(int16*)buffer;
- buffer += 2;
+ for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
+ ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer);
+
+ TotalNumberOfZones = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer);
+
+ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
+ MapZoneArray[i] = ReadSaveBuf<CZone>(buffer);
+
+ /*
+ The call of GetPointerForZoneIndex is wrong, as it is
+ meant for a different array, but the game doesn't brake
+ if save data stored is -1.
+ */
+ MapZoneArray[i].child = GetPointerForZoneIndex((int32)MapZoneArray[i].child);
+ MapZoneArray[i].parent = GetPointerForZoneIndex((int32)MapZoneArray[i].parent);
+ MapZoneArray[i].next = GetPointerForZoneIndex((int32)MapZoneArray[i].next);
+ assert(MapZoneArray[i].child == nil);
+ assert(MapZoneArray[i].parent == nil);
+ assert(MapZoneArray[i].next == nil);
}
- TotalNumberOfMapZones = *(uint16*)(buffer);
- NumberOfAudioZones = *(uint16*)(buffer+2);
-}
+ for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
+ AudioZoneArray[i] = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer);
+ NumberOfAudioZones = ReadSaveBuf<uint16>(buffer);
-STARTPATCHES
- InjectHook(0x4B5DD0, &CZone::GetTranslatedName, PATCH_JUMP);
- InjectHook(0x4B5DE0, CTheZones::Init, PATCH_JUMP);
- InjectHook(0x4B61D0, CTheZones::Update, PATCH_JUMP);
- InjectHook(0x4B6210, CTheZones::CreateZone, PATCH_JUMP);
- InjectHook(0x4B6380, CTheZones::CreateMapZone, PATCH_JUMP);
- InjectHook(0x4B64C0, CTheZones::PostZoneCreation, PATCH_JUMP);
- InjectHook(0x4B6500, CTheZones::InsertZoneIntoZoneHierarchy, PATCH_JUMP);
- InjectHook(0x4B6530, CTheZones::InsertZoneIntoZoneHierRecursive, PATCH_JUMP);
- InjectHook(0x4B65F0, CTheZones::ZoneIsEntirelyContainedWithinOtherZone, PATCH_JUMP);
- InjectHook(0x4B6710, CTheZones::PointLiesWithinZone, PATCH_JUMP);
- InjectHook(0x4B6910, CTheZones::GetLevelFromPosition, PATCH_JUMP);
- InjectHook(0x4B69B0, CTheZones::FindSmallestZonePosition, PATCH_JUMP);
- InjectHook(0x4B6790, CTheZones::FindSmallestZonePositionType, PATCH_JUMP);
- InjectHook(0x4B6890, CTheZones::FindSmallestZonePositionILN, PATCH_JUMP);
- InjectHook(0x4B6800, CTheZones::FindZoneByLabelAndReturnIndex, PATCH_JUMP);
- InjectHook(0x4B6FA0, CTheZones::GetZone, PATCH_JUMP);
- InjectHook(0x4B84F0, CTheZones::GetPointerForZoneIndex, PATCH_JUMP);
- InjectHook(0x4B6A10, CTheZones::GetZoneInfo, PATCH_JUMP);
- InjectHook(0x4B6FB0, CTheZones::GetZoneInfoForTimeOfDay, PATCH_JUMP);
- InjectHook(0x4B6A50, CTheZones::SetZoneCarInfo, PATCH_JUMP);
- InjectHook(0x4B6DC0, CTheZones::SetZonePedInfo, PATCH_JUMP);
- InjectHook(0x4B6EB0, CTheZones::SetCarDensity, PATCH_JUMP);
- InjectHook(0x4B6F00, CTheZones::SetPedDensity, PATCH_JUMP);
- InjectHook(0x4B6F50, CTheZones::SetPedGroup, PATCH_JUMP);
- InjectHook(0x4B83E0, CTheZones::FindAudioZone, PATCH_JUMP);
- InjectHook(0x4B8430, CTheZones::FindZoneForPoint, PATCH_JUMP);
- InjectHook(0x4B8340, CTheZones::AddZoneToAudioZoneArray, PATCH_JUMP);
- InjectHook(0x4B8510, CTheZones::SaveAllZones, PATCH_JUMP);
- InjectHook(0x4B8950, CTheZones::LoadAllZones, PATCH_JUMP);
-ENDPATCHES
+ VALIDATESAVEBUF(size)
+}
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 76855e8b..bb1585dc 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -52,18 +52,18 @@ public:
class CTheZones
{
public:
- static eLevelName &m_CurrLevel;
- static CZone *&m_pPlayersZone;
- static int16 &FindIndex;
+ static eLevelName m_CurrLevel;
+ static CZone *m_pPlayersZone;
+ static int16 FindIndex;
- static uint16 &NumberOfAudioZones;
- static int16 *AudioZoneArray; //[NUMAUDIOZONES];
- static uint16 &TotalNumberOfMapZones;
- static uint16 &TotalNumberOfZones;
- static CZone *ZoneArray; //[NUMZONES];
- static CZone *MapZoneArray; //[NUMMAPZONES];
- static uint16 &TotalNumberOfZoneInfos;
- static CZoneInfo *ZoneInfoArray; //[2*NUMZONES];
+ static uint16 NumberOfAudioZones;
+ static int16 AudioZoneArray[NUMAUDIOZONES];
+ static uint16 TotalNumberOfMapZones;
+ static uint16 TotalNumberOfZones;
+ static CZone ZoneArray[NUMZONES];
+ static CZone MapZoneArray[NUMMAPZONES];
+ static uint16 TotalNumberOfZoneInfos;
+ static CZoneInfo ZoneInfoArray[2*NUMZONES];
static void Init(void);
static void Update(void);
diff --git a/src/core/common.h b/src/core/common.h
index 7688b182..955225cc 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -11,11 +11,11 @@
#include <string.h>
#include <math.h>
-#ifdef WITHWINDOWS
-#include <Windows.h>
+#if defined _WIN32 && defined WITHWINDOWS
+#include <windows.h>
#endif
-#ifdef WITHD3D
+#if defined _WIN32 && defined WITHD3D
#include <windows.h>
#include <d3d8types.h>
#endif
@@ -23,6 +23,21 @@
#include <rwcore.h>
#include <rpworld.h>
+// gotta put this somewhere
+#ifdef LIBRW
+#define STREAMPOS(str) ((str)->tell())
+#define STREAMFILE(str) (((rw::StreamFile*)(str))->file)
+#define HIERNODEINFO(hier) ((hier)->nodeInfo)
+#define HIERNODEID(hier, i) ((hier)->nodeInfo[i].id)
+#define HANIMFRAMES(anim) ((anim)->keyframes)
+#else
+#define STREAMPOS(str) ((str)->Type.memory.position)
+#define STREAMFILE(str) ((str)->Type.file.fpFile)
+#define HIERNODEINFO(hier) ((hier)->pNodeInfo)
+#define HIERNODEID(hier, i) ((hier)->pNodeInfo[i].nodeID)
+#define HANIMFRAMES(anim) ((anim)->pFrames)
+#endif
+
#define rwVENDORID_ROCKSTAR 0x0253F2
// Get rid of bullshit windows definitions, we're not running on an 8086
@@ -33,15 +48,8 @@
#undef near
#endif
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef min
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
-#endif
+#define Max(a,b) ((a) > (b) ? (a) : (b))
+#define Min(a,b) ((a) < (b) ? (a) : (b))
typedef uint8_t uint8;
typedef int8_t int8;
@@ -55,10 +63,17 @@ typedef int64_t int64;
// hardcode ucs-2
typedef uint16_t wchar;
-#define nil nullptr
+#ifndef nil
+#define nil NULL
+#endif
#include "config.h"
+#ifdef PED_SKIN
+#include <rphanim.h>
+#include <rpskin.h>
+#endif
+
#define ALIGNPTR(p) (void*)((((uintptr)(void*)p) + sizeof(void*)-1) & ~(sizeof(void*)-1))
// PDP-10 like byte functions
@@ -73,13 +88,6 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
return w>>p & (1<<s)-1;
}
-
-#ifndef RWLIBS
-// little hack
-extern void **rwengine;
-#define RwEngineInstance (*rwengine)
-#endif
-
#include "skeleton.h"
#include "Draw.h"
@@ -268,7 +276,7 @@ class CTweakFunc : public CTweakVar
void (*m_pFunc)();
public:
CTweakFunc(void (*pFunc)(), const char *strName, const char *strPath) :
- m_pFunc(pFunc), m_pVarName(strName), m_pPath(strPath)
+ m_pPath(strPath), m_pVarName(strName), m_pFunc(pFunc)
{
CTweakVars::Add(this);
}
@@ -282,7 +290,7 @@ class CTweakBool : public CTweakVar
bool *m_pBoolVar;
public:
CTweakBool(bool *pBool, const char *strName, const char *strPath) :
- m_pBoolVar(pBool), m_pVarName(strName), m_pPath(strPath)
+ m_pPath(strPath), m_pVarName(strName), m_pBoolVar(pBool)
{
CTweakVars::Add(this);
}
@@ -298,9 +306,10 @@ class CTweakSwitch : public CTweakVar
const char **m_aStr;
void (*m_pFunc)();
public:
- CTweakSwitch(void *pInt, const char *strName, int32 nMin, int32 nMax, const char **aStr, void (*pFunc)(), const char *strPath) :
- m_pVarName(strName), m_pPath(strPath),
- m_aStr(aStr), m_pIntVar(pInt), m_nMin(nMin), m_nMax(nMax)
+ CTweakSwitch(void *pInt, const char *strName, int32 nMin, int32 nMax, const char **aStr,
+ void (*pFunc)(), const char *strPath)
+ : m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), m_nMin(nMin), m_nMax(nMax),
+ m_aStr(aStr)
{
CTweakVars::Add(this);
}
@@ -308,22 +317,24 @@ public:
void AddDBG(const char *path);
};
-#define _TWEEKCLASS(name, type) \
-class name : public CTweakVar \
-{ \
-public: \
- const char *m_pPath, *m_pVarName; \
- type *m_pIntVar, m_nLoawerBound, m_nUpperBound, m_nStep; \
- \
- name(type *pInt, const char *strName, type nLower, type nUpper, type nStep, const char *strPath) : \
- m_pIntVar(pInt), m_nLoawerBound(nLower), m_nUpperBound(nUpper), m_nStep(nStep), \
- m_pVarName(strName), m_pPath(strPath) \
- { \
- CTweakVars::Add(this); \
- } \
- \
- void AddDBG(const char *path); \
-};
+#define _TWEEKCLASS(name, type) \
+ class name : public CTweakVar \
+ { \
+ public: \
+ const char *m_pPath, *m_pVarName; \
+ type *m_pIntVar, m_nLoawerBound, m_nUpperBound, m_nStep; \
+ \
+ name(type *pInt, const char *strName, type nLower, type nUpper, type nStep, \
+ const char *strPath) \
+ : m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), \
+ m_nLoawerBound(nLower), m_nUpperBound(nUpper), m_nStep(nStep) \
+ \
+ { \
+ CTweakVars::Add(this); \
+ } \
+ \
+ void AddDBG(const char *path); \
+ };
_TWEEKCLASS(CTweakInt8, int8);
_TWEEKCLASS(CTweakUInt8, uint8);
diff --git a/src/core/config.h b/src/core/config.h
index f7fde579..2cf8ec88 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -47,7 +47,8 @@ enum Config {
NUM_PATHCONNECTIONS = 10260,
// Link list lengths
- // TODO: alpha list
+ NUMALPHALIST = 20,
+ NUMALPHAENTITYLIST = 150,
NUMCOLCACHELINKS = 200,
NUMREFERENCES = 800,
@@ -160,7 +161,7 @@ enum Config {
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
# ifdef GTA_PS2_STUFF
-//# define USE_PS2_RAND // this is unsafe until we have the game reversed
+# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
@@ -189,9 +190,19 @@ enum Config {
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
#define MORE_LANGUAGES // Add more translations to the game
+#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
+//#define USE_TXD_CDIMAGE // generate and load textures from txd.img
+//#define USE_TEXTURE_POOL
+//#define OPENAL
+
+// Particle
+//#define PC_PARTICLE
+//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// Pad
+#ifndef RW_GL3
#define XINPUT
+#endif
#define KANGAROO_CHEAT
#define REGISTER_START_BUTTON
@@ -204,6 +215,8 @@ enum Config {
#define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
#define TRIANGLE_BACK_BUTTON
// #define CIRCLE_BACK_BUTTON
+#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
+#define BETA_SLIDING_TEXT
// Script
#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default
@@ -220,8 +233,10 @@ enum Config {
// Pickups
//#define MONEY_MESSAGES
+#define CAMERA_PICKUP
// Peds
+#define PED_SKIN // support for skinned geometry on peds
#define ANIMATE_PED_COL_MODEL
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
diff --git a/src/core/debugmenu_public.h b/src/core/debugmenu_public.h
deleted file mode 100644
index 778e7afe..00000000
--- a/src/core/debugmenu_public.h
+++ /dev/null
@@ -1,154 +0,0 @@
-
-extern "C" {
-
-typedef void (*TriggerFunc)(void);
-
-struct DebugMenuEntry;
-
-typedef DebugMenuEntry *(*DebugMenuAddInt8_TYPE)(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc, int8_t step, int8_t lowerBound, int8_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddInt16_TYPE)(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc, int16_t step, int16_t lowerBound, int16_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddInt32_TYPE)(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc, int32_t step, int32_t lowerBound, int32_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddInt64_TYPE)(const char *path, const char *name, int64_t *ptr, TriggerFunc triggerFunc, int64_t step, int64_t lowerBound, int64_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddUInt8_TYPE)(const char *path, const char *name, uint8_t *ptr, TriggerFunc triggerFunc, uint8_t step, uint8_t lowerBound, uint8_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddUInt16_TYPE)(const char *path, const char *name, uint16_t *ptr, TriggerFunc triggerFunc, uint16_t step, uint16_t lowerBound, uint16_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddUInt32_TYPE)(const char *path, const char *name, uint32_t *ptr, TriggerFunc triggerFunc, uint32_t step, uint32_t lowerBound, uint32_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddUInt64_TYPE)(const char *path, const char *name, uint64_t *ptr, TriggerFunc triggerFunc, uint64_t step, uint64_t lowerBound, uint64_t upperBound, const char **strings);
-typedef DebugMenuEntry *(*DebugMenuAddFloat32_TYPE)(const char *path, const char *name, float *ptr, TriggerFunc triggerFunc, float step, float lowerBound, float upperBound);
-typedef DebugMenuEntry *(*DebugMenuAddFloat64_TYPE)(const char *path, const char *name, double *ptr, TriggerFunc triggerFunc, double step, double lowerBound, double upperBound);
-typedef DebugMenuEntry *(*DebugMenuAddCmd_TYPE)(const char *path, const char *name, TriggerFunc triggerFunc);
-typedef void (*DebugMenuEntrySetWrap_TYPE)(DebugMenuEntry *e, bool wrap);
-typedef void (*DebugMenuEntrySetStrings_TYPE)(DebugMenuEntry *e, const char **strings);
-typedef void (*DebugMenuEntrySetAddress_TYPE)(DebugMenuEntry *e, void *addr);
-
-struct DebugMenuAPI
-{
- bool isLoaded;
- HMODULE module;
- DebugMenuAddInt8_TYPE addint8;
- DebugMenuAddInt16_TYPE addint16;
- DebugMenuAddInt32_TYPE addint32;
- DebugMenuAddInt64_TYPE addint64;
- DebugMenuAddUInt8_TYPE adduint8;
- DebugMenuAddUInt16_TYPE adduint16;
- DebugMenuAddUInt32_TYPE adduint32;
- DebugMenuAddUInt64_TYPE adduint64;
- DebugMenuAddFloat32_TYPE addfloat32;
- DebugMenuAddFloat64_TYPE addfloat64;
- DebugMenuAddCmd_TYPE addcmd;
- DebugMenuEntrySetWrap_TYPE setwrap;
- DebugMenuEntrySetStrings_TYPE setstrings;
- DebugMenuEntrySetAddress_TYPE setaddress;
-};
-extern DebugMenuAPI gDebugMenuAPI;
-
-inline DebugMenuEntry *DebugMenuAddInt8(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc, int8_t step, int8_t lowerBound, int8_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddInt16(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc, int16_t step, int16_t lowerBound, int16_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddInt32(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc, int32_t step, int32_t lowerBound, int32_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddInt64(const char *path, const char *name, int64_t *ptr, TriggerFunc triggerFunc, int64_t step, int64_t lowerBound, int64_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddUInt8(const char *path, const char *name, uint8_t *ptr, TriggerFunc triggerFunc, uint8_t step, uint8_t lowerBound, uint8_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddUInt16(const char *path, const char *name, uint16_t *ptr, TriggerFunc triggerFunc, uint16_t step, uint16_t lowerBound, uint16_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddUInt32(const char *path, const char *name, uint32_t *ptr, TriggerFunc triggerFunc, uint32_t step, uint32_t lowerBound, uint32_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddUInt64(const char *path, const char *name, uint64_t *ptr, TriggerFunc triggerFunc, uint64_t step, uint64_t lowerBound, uint64_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddFloat32(const char *path, const char *name, float *ptr, TriggerFunc triggerFunc, float step, float lowerBound, float upperBound)
-{ return gDebugMenuAPI.addfloat32(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
-inline DebugMenuEntry *DebugMenuAddFloat64(const char *path, const char *name, double *ptr, TriggerFunc triggerFunc, double step, double lowerBound, double upperBound)
-{ return gDebugMenuAPI.addfloat64(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
-inline DebugMenuEntry *DebugMenuAddCmd(const char *path, const char *name, TriggerFunc triggerFunc)
-{ return gDebugMenuAPI.addcmd(path, name, triggerFunc); }
-inline void DebugMenuEntrySetWrap(DebugMenuEntry *e, bool wrap)
-{ gDebugMenuAPI.setwrap(e, wrap); }
-inline void DebugMenuEntrySetStrings(DebugMenuEntry *e, const char **strings)
-{ gDebugMenuAPI.setstrings(e, strings); }
-inline void DebugMenuEntrySetAddress(DebugMenuEntry *e, void *addr)
-{ gDebugMenuAPI.setaddress(e, addr); }
-
-inline bool DebugMenuLoad(void)
-{
- if(gDebugMenuAPI.isLoaded)
- return true;
- HMODULE mod = LoadLibraryA("debugmenu");
- if(mod == nil){
- char modulePath[MAX_PATH];
- HMODULE dllModule;
- GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)&gDebugMenuAPI, &dllModule);
- GetModuleFileNameA(dllModule, modulePath, MAX_PATH);
- char *p = strchr(modulePath, '\\');
- if(p) p[1] = '\0';
- strcat(modulePath, "debugmenu");
- mod = LoadLibraryA(modulePath);
- }
- if(mod == nil)
- return false;
- gDebugMenuAPI.addint8 = (DebugMenuAddInt8_TYPE)GetProcAddress(mod, "DebugMenuAddInt8");
- gDebugMenuAPI.addint16 = (DebugMenuAddInt16_TYPE)GetProcAddress(mod, "DebugMenuAddInt16");
- gDebugMenuAPI.addint32 = (DebugMenuAddInt32_TYPE)GetProcAddress(mod, "DebugMenuAddInt32");
- gDebugMenuAPI.addint64 = (DebugMenuAddInt64_TYPE)GetProcAddress(mod, "DebugMenuAddInt64");
- gDebugMenuAPI.adduint8 = (DebugMenuAddUInt8_TYPE)GetProcAddress(mod, "DebugMenuAddUInt8");
- gDebugMenuAPI.adduint16 = (DebugMenuAddUInt16_TYPE)GetProcAddress(mod, "DebugMenuAddUInt16");
- gDebugMenuAPI.adduint32 = (DebugMenuAddUInt32_TYPE)GetProcAddress(mod, "DebugMenuAddUInt32");
- gDebugMenuAPI.adduint64 = (DebugMenuAddUInt64_TYPE)GetProcAddress(mod, "DebugMenuAddUInt64");
- gDebugMenuAPI.addfloat32 = (DebugMenuAddFloat32_TYPE)GetProcAddress(mod, "DebugMenuAddFloat32");
- gDebugMenuAPI.addfloat64 = (DebugMenuAddFloat64_TYPE)GetProcAddress(mod, "DebugMenuAddFloat64");
- gDebugMenuAPI.addcmd = (DebugMenuAddCmd_TYPE)GetProcAddress(mod, "DebugMenuAddCmd");
- gDebugMenuAPI.setwrap = (DebugMenuEntrySetWrap_TYPE)GetProcAddress(mod, "DebugMenuEntrySetWrap");
- gDebugMenuAPI.setstrings = (DebugMenuEntrySetStrings_TYPE)GetProcAddress(mod, "DebugMenuEntrySetStrings");
- gDebugMenuAPI.setaddress = (DebugMenuEntrySetAddress_TYPE)GetProcAddress(mod, "DebugMenuEntrySetAddress");
- gDebugMenuAPI.isLoaded = true;
- gDebugMenuAPI.module = mod;
- return true;
-}
-
-}
-
-// Also overload them for simplicity
-
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc, int8_t step, int8_t lowerBound, int8_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc, int16_t step, int16_t lowerBound, int16_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc, int32_t step, int32_t lowerBound, int32_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int64_t *ptr, TriggerFunc triggerFunc, int64_t step, int64_t lowerBound, int64_t upperBound, const char **strings)
-{ return gDebugMenuAPI.addint64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint8_t *ptr, TriggerFunc triggerFunc, uint8_t step, uint8_t lowerBound, uint8_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint16_t *ptr, TriggerFunc triggerFunc, uint16_t step, uint16_t lowerBound, uint16_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint32_t *ptr, TriggerFunc triggerFunc, uint32_t step, uint32_t lowerBound, uint32_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint64_t *ptr, TriggerFunc triggerFunc, uint64_t step, uint64_t lowerBound, uint64_t upperBound, const char **strings)
-{ return gDebugMenuAPI.adduint64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, float *ptr, TriggerFunc triggerFunc, float step, float lowerBound, float upperBound)
-{ return gDebugMenuAPI.addfloat32(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
-inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, double *ptr, TriggerFunc triggerFunc, double step, double lowerBound, double upperBound)
-{ return gDebugMenuAPI.addfloat64(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
-
-inline DebugMenuEntry *DebugMenuAddVarBool32(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc)
-{
- static const char *boolstr[] = { "Off", "On" };
- DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
- DebugMenuEntrySetWrap(e, true);
- return e;
-}
-inline DebugMenuEntry *DebugMenuAddVarBool16(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc)
-{
- static const char *boolstr[] = { "Off", "On" };
- DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
- DebugMenuEntrySetWrap(e, true);
- return e;
-}
-inline DebugMenuEntry *DebugMenuAddVarBool8(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc)
-{
- static const char *boolstr[] = { "Off", "On" };
- DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
- DebugMenuEntrySetWrap(e, true);
- return e;
-}
diff --git a/src/core/main.cpp b/src/core/main.cpp
index f09c2e0a..ec37fa28 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -2,7 +2,7 @@
#include "rpmatfx.h"
#include "rphanim.h"
#include "rpskin.h"
-#include "patcher.h"
+
#include "main.h"
#include "CdStream.h"
#include "General.h"
@@ -58,24 +58,21 @@
#include "Console.h"
#include "timebars.h"
#include "GenericGameStorage.h"
+#include "SceneEdit.h"
+#include "debugmenu.h"
-GlobalScene &Scene = *(GlobalScene*)0x726768;
+GlobalScene Scene;
uint8 work_buff[55000];
-//char gString[256];
-//char gString2[512];
-//wchar gUString[256];
-//wchar gUString2[256];
-char *gString = (char*)0x711B40;
-char *gString2 = (char*)0x878A40;
-wchar *gUString = (wchar*)0x74B018;
-wchar *gUString2 = (wchar*)0x6EDD70;
-
+char gString[256];
+char gString2[512];
+wchar gUString[256];
+wchar gUString2[256];
float FramesPerSecond = 30.0f;
bool gbPrintShite = false;
-bool &gbModelViewer = *(bool*)0x95CD93;
+bool gbModelViewer;
int32 frameCount;
@@ -94,9 +91,6 @@ void GameInit(void);
void SystemInit(void);
void TheGame(void);
-extern void (*DebugMenuProcess)(void);
-extern void (*DebugMenuRender)(void);
-void DebugMenuInit(void);
void DebugMenuPopulate(void);
@@ -209,7 +203,7 @@ DoFade(void)
CRGBA fadeColor;
CRect rect;
int fadeValue = CDraw::FadeValue;
- float brightness = min(CMenuManager::m_PrefsBrightness, 256);
+ float brightness = Min(CMenuManager::m_PrefsBrightness, 256);
if(brightness <= 50)
brightness = 50;
if(FrontEndMenuManager.m_bMenuActive)
@@ -239,8 +233,13 @@ DoFade(void)
float y = SCREEN_HEIGHT/2 * TheCamera.m_ScreenReductionPercentage/100.0f;
rect.left = 0.0f;
rect.right = SCREEN_WIDTH;
+#ifdef FIX_BUGS
+ rect.top = y - SCREEN_SCALE_Y(8.0f);
+ rect.bottom = SCREEN_HEIGHT - y - SCREEN_SCALE_Y(8.0f);
+#else
rect.top = y - 8.0f;
rect.bottom = SCREEN_HEIGHT - y - 8.0f;
+#endif // FIX_BUGS
}else{
rect.left = 0.0f;
rect.right = SCREEN_WIDTH;
@@ -344,6 +343,8 @@ static void
Terminate3D(void)
{
CGame::ShutdownRenderWare();
+
+ DebugMenuShutdown();
RsRwTerminate();
@@ -690,14 +691,14 @@ DisplayGameDebugText()
CFont::SetPropOn();
CFont::SetBackgroundOff();
CFont::SetFontStyle(FONT_BANK);
- CFont::SetScale(SCREEN_STRETCH_X(0.5f), SCREEN_STRETCH_Y(0.5f));
+ CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.5f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetWrapx(SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetBackGroundOnlyTextOff();
CFont::SetColor(CRGBA(255, 108, 0, 255));
- CFont::PrintString(10.0f, 10.0f, ver);
+ CFont::PrintString(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(10.0f), ver);
FrameSamples++;
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
@@ -748,6 +749,7 @@ DisplayGameDebugText()
AsciiToUnicode(str, ustr);
+ // Let's not scale those numbers, they look better that way :eyes:
CFont::SetPropOff();
CFont::SetBackgroundOff();
CFont::SetScale(0.7f, 1.5f);
@@ -792,6 +794,8 @@ RenderDebugShit(void)
if(gbShowCollisionLines)
CRenderer::RenderCollisionLines();
ThePaths.DisplayPathData();
+ CDebug::DrawLines();
+ DefinedState();
#endif
}
@@ -863,11 +867,9 @@ Render2dStuff(void)
MusicManager.DisplayRadioStationName();
TheConsole.Display();
-/*
if(CSceneEdit::m_bEditOn)
CSceneEdit::Draw();
else
-*/
CHud::Draw();
CUserDisplay::OnscnTimer.ProcessForDisplay();
CMessages::Display();
@@ -1560,8 +1562,9 @@ void SystemInit()
//
#endif
-
+#ifdef GTA_PS2_STUFF
CPad::Initialise();
+#endif
CPad::GetPad(0)->Mode = 0;
CGame::frenchGame = false;
@@ -1837,28 +1840,3 @@ main(int argc, char *argv[])
return 0;
}
-
-STARTPATCHES
- InjectHook(0x48E480, Idle, PATCH_JUMP);
- InjectHook(0x48E700, FrontendIdle, PATCH_JUMP);
-
- InjectHook(0x48CF10, DoRWStuffStartOfFrame, PATCH_JUMP);
- InjectHook(0x48D040, DoRWStuffStartOfFrame_Horizon, PATCH_JUMP);
- InjectHook(0x48E030, RenderScene, PATCH_JUMP);
- InjectHook(0x48E080, RenderDebugShit, PATCH_JUMP);
- InjectHook(0x48E090, RenderEffects, PATCH_JUMP);
- InjectHook(0x48E0E0, Render2dStuff, PATCH_JUMP);
- InjectHook(0x48E450, RenderMenus, PATCH_JUMP);
- InjectHook(0x48D120, DoFade, PATCH_JUMP);
- InjectHook(0x48E470, Render2dStuffAfterFade, PATCH_JUMP);
-
- InjectHook(0x48D550, LoadSplash, PATCH_JUMP);
- InjectHook(0x48D670, DestroySplashScreen, PATCH_JUMP);
- InjectHook(0x48D770, LoadingScreen, PATCH_JUMP);
- InjectHook(0x48D760, ResetLoadingScreenBar, PATCH_JUMP);
-
- InjectHook(0x48D470, PluginAttach, PATCH_JUMP);
- InjectHook(0x48D520, Initialise3D, PATCH_JUMP);
- InjectHook(0x48D540, Terminate3D, PATCH_JUMP);
- InjectHook(0x48E800, AppEventHandler, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/main.h b/src/core/main.h
index 5e9401b9..90b13fbb 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -5,22 +5,15 @@ struct GlobalScene
RpWorld *world;
RwCamera *camera;
};
-extern GlobalScene &Scene;
+extern GlobalScene Scene;
extern uint8 work_buff[55000];
-//extern char gString[256];
-//extern char gString2[512];
-//extern wchar gUString[256];
-//extern wchar gUString2[256];
-extern char *gString;
-extern char *gString2;
-extern wchar *gUString;
-extern wchar *gUString2;
-extern bool &b_FoundRecentSavedGameWantToLoad;
+extern char gString[256];
+extern char gString2[512];
+extern wchar gUString[256];
+extern wchar gUString2[256];
extern bool gbPrintShite;
-extern bool &gbModelViewer;
-extern bool &StillToFadeOut;
-extern bool &JustLoadedDontFadeInYet;
+extern bool gbModelViewer;
class CSprite2d;
diff --git a/src/core/patcher.cpp b/src/core/patcher.cpp
index 19ca5f07..e5242e9d 100644
--- a/src/core/patcher.cpp
+++ b/src/core/patcher.cpp
@@ -1,11 +1,10 @@
+#define WITHWINDOWS
#include "common.h"
#include "patcher.h"
#include <algorithm>
#include <vector>
-#include <Windows.h>
-
StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func)
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 321ff172..2a9cbc77 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -1,6 +1,6 @@
#include <direct.h>
#include <csignal>
-#include <windows.h>
+#define WITHWINDOWS
#include "common.h"
#include "patcher.h"
#include "Renderer.h"
@@ -17,26 +17,22 @@
#include "Heli.h"
#include "Automobile.h"
#include "Ped.h"
-#include "debugmenu_public.h"
#include "Particle.h"
#include "Console.h"
#include "Debug.h"
#include "Hud.h"
+#include "SceneEdit.h"
+#include "Pad.h"
+#include "PlayerPed.h"
+#include "Radar.h"
+#include "debugmenu.h"
#include <list>
-#ifndef RWLIBS
-void **rwengine = *(void***)0x5A10E1;
-#else
+#ifdef RWLIBS
extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList);
#endif
-DebugMenuAPI gDebugMenuAPI;
-
-STARTPATCHES
- InjectHook(0x5A07E0, (void (*)(void*)) &operator delete, PATCH_JUMP);
- InjectHook(0x5A0690, (void* (*)(size_t)) &operator new, PATCH_JUMP);
-ENDPATCHES
#ifdef USE_PS2_RAND
unsigned __int64 myrand_seed = 1;
@@ -64,24 +60,6 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
-void (*DebugMenuProcess)(void);
-void (*DebugMenuRender)(void);
-static void stub(void) { }
-
-void
-DebugMenuInit(void)
-{
- if(DebugMenuLoad()){
- DebugMenuProcess = (void(*)(void))GetProcAddress(gDebugMenuAPI.module, "DebugMenuProcess");
- DebugMenuRender = (void(*)(void))GetProcAddress(gDebugMenuAPI.module, "DebugMenuRender");
- }
- if(DebugMenuProcess == nil || DebugMenuRender == nil){
- DebugMenuProcess = stub;
- DebugMenuRender = stub;
- }
-
-}
-
void WeaponCheat();
void HealthCheat();
void TankCheat();
@@ -162,6 +140,19 @@ FixCar(void)
((CAutomobile*)veh)->Fix();
}
+#ifdef MENU_MAP
+static void
+TeleportToWaypoint(void)
+{
+ if (FindPlayerVehicle()) {
+ if (CRadar::TargetMarkerId != -1)
+ FindPlayerVehicle()->Teleport(CRadar::TargetMarkerPos + CVector(0.0f, 0.0f, FindPlayerVehicle()->GetColModel()->boundingSphere.center.z));
+ } else
+ if(CRadar::TargetMarkerId != -1)
+ FindPlayerPed()->Teleport(CRadar::TargetMarkerPos + CVector(0.0f, 0.0f, FEET_OFFSET));
+}
+#endif
+
static int engineStatus;
static void
SetEngineStatus(void)
@@ -258,7 +249,7 @@ TWEAKSWITCH(CWeather::NewWeatherType, 0, 3, wt, NULL);
void
DebugMenuPopulate(void)
{
- if(DebugMenuLoad()){
+ if(1){
static const char *weathers[] = {
"Sunny", "Cloudy", "Rainy", "Foggy"
};
@@ -273,7 +264,7 @@ DebugMenuPopulate(void)
e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 3, weathers);
DebugMenuEntrySetWrap(e, true);
DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f);
- DebugMenuAddVar("Time & Weather", "Time scale", (float*)0x8F2C20, nil, 0.1f, 0.0f, 10.0f);
+ DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f);
DebugMenuAddCmd("Cheats", "Weapons", WeaponCheat);
DebugMenuAddCmd("Cheats", "Money", MoneyCheat);
@@ -331,47 +322,54 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); });
- DebugMenuAddVarBool8("Debug", "Draw hud", (int8*)&CHud::m_Wants_To_Draw_Hud, nil);
+#ifdef LIBRW
+ DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil);
+#endif
+
+ DebugMenuAddVarBool8("Debug", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil);
+ DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
+#ifdef MENU_MAP
+ DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
+#endif
DebugMenuAddVar("Debug", "Engine Status", &engineStatus, nil, 1, 0, 226, nil);
DebugMenuAddCmd("Debug", "Set Engine Status", SetEngineStatus);
DebugMenuAddCmd("Debug", "Fix Car", FixCar);
DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy);
DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad);
- DebugMenuAddVarBool8("Debug", "Catalina Heli On", (int8*)&CHeli::CatalinaHeliOn, nil);
+ DebugMenuAddVarBool8("Debug", "Catalina Heli On", &CHeli::CatalinaHeliOn, nil);
DebugMenuAddCmd("Debug", "Catalina Fly By", CHeli::StartCatalinaFlyBy);
DebugMenuAddCmd("Debug", "Catalina Take Off", CHeli::CatalinaTakeOff);
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
- DebugMenuAddVarBool8("Debug", "Script Heli On", (int8*)0x95CD43, nil);
-
- DebugMenuAddVarBool8("Debug", "Show Ped Paths", (int8*)&gbShowPedPaths, nil);
- DebugMenuAddVarBool8("Debug", "Show Car Paths", (int8*)&gbShowCarPaths, nil);
- DebugMenuAddVarBool8("Debug", "Show Car Path Links", (int8*)&gbShowCarPathsLinks, nil);
- DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
- DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
- DebugMenuAddVarBool8("Debug", "Show Collision Lines", (int8*)&gbShowCollisionLines, nil);
- DebugMenuAddVarBool8("Debug", "Show Collision Polys", (int8*)&gbShowCollisionPolys, nil);
- DebugMenuAddVarBool8("Debug", "Don't render Buildings", (int8*)&gbDontRenderBuildings, nil);
- DebugMenuAddVarBool8("Debug", "Don't render Big Buildings", (int8*)&gbDontRenderBigBuildings, nil);
- DebugMenuAddVarBool8("Debug", "Don't render Peds", (int8*)&gbDontRenderPeds, nil);
- DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
- DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
+ DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil);
+
+ DebugMenuAddVarBool8("Debug", "Show Ped Paths", &gbShowPedPaths, nil);
+ DebugMenuAddVarBool8("Debug", "Show Car Paths", &gbShowCarPaths, nil);
+ DebugMenuAddVarBool8("Debug", "Show Car Path Links", &gbShowCarPathsLinks, nil);
+ DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", &gbShowPedRoadGroups, nil);
+ DebugMenuAddVarBool8("Debug", "Show Car Road Groups", &gbShowCarRoadGroups, nil);
+ DebugMenuAddVarBool8("Debug", "Show Collision Lines", &gbShowCollisionLines, nil);
+ DebugMenuAddVarBool8("Debug", "Show Collision Polys", &gbShowCollisionPolys, nil);
+ DebugMenuAddVarBool8("Debug", "Don't render Buildings", &gbDontRenderBuildings, nil);
+ DebugMenuAddVarBool8("Debug", "Don't render Big Buildings", &gbDontRenderBigBuildings, nil);
+ DebugMenuAddVarBool8("Debug", "Don't render Peds", &gbDontRenderPeds, nil);
+ DebugMenuAddVarBool8("Debug", "Don't render Vehicles", &gbDontRenderVehicles, nil);
+ DebugMenuAddVarBool8("Debug", "Don't render Objects", &gbDontRenderObjects, nil);
#ifdef TOGGLEABLE_BETA_FEATURES
- DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
- DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
- DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil);
+ DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
+ DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", &CPed::bMakePedsRunToPhonesToReportCrimes, nil);
#endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
extern bool PrintDebugCode;
- extern int16 &DebugCamMode;
- DebugMenuAddVarBool8("Cam", "Use mouse Cam", (int8*)&CCamera::m_bUseMouse3rdPerson, nil);
+ extern int16 DebugCamMode;
+ DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil);
#ifdef FREE_CAM
- DebugMenuAddVarBool8("Cam", "Free Cam", (int8*)&CCamera::bFreeCam, nil);
+ DebugMenuAddVarBool8("Cam", "Free Cam", &CCamera::bFreeCam, nil);
#endif
- DebugMenuAddVarBool8("Cam", "Print Debug Code", (int8*)&PrintDebugCode, nil);
+ DebugMenuAddVarBool8("Cam", "Print Debug Code", &PrintDebugCode, nil);
DebugMenuAddVar("Cam", "Cam Mode", &DebugCamMode, nil, 1, 0, CCam::MODE_EDITOR, nil);
DebugMenuAddCmd("Cam", "Normal", []() { DebugCamMode = 0; });
DebugMenuAddCmd("Cam", "Follow Ped With Bind", []() { DebugCamMode = CCam::MODE_FOLLOW_PED_WITH_BIND; });
@@ -383,18 +381,6 @@ DebugMenuPopulate(void)
}
}
-/*
-int (*RsEventHandler_orig)(int a, int b);
-int
-delayedPatches10(int a, int b)
-{
- DebugMenuInit();
- DebugMenuPopulate();
-
- return RsEventHandler_orig(a, b);
-}
-*/
-
const int re3_buffsize = 1024;
static char re3_buff[re3_buffsize];
@@ -473,37 +459,3 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
#ifdef VALIDATE_SAVE_SIZE
int32 _saveBufCount;
#endif
-
-void
-patch()
-{
- StaticPatcher::Apply();
-
-// Patch<float>(0x46BC61+6, 1.0f); // car distance
- InjectHook(0x59E460, printf, PATCH_JUMP);
- InjectHook(0x475E00, printf, PATCH_JUMP); // _Error
-
-
-// InterceptCall(&open_script_orig, open_script, 0x438869);
-
-// InterceptCall(&RsEventHandler_orig, delayedPatches10, 0x58275E);
-}
-
-BOOL WINAPI
-DllMain(HINSTANCE hInst, DWORD reason, LPVOID)
-{
- if(reason == DLL_PROCESS_ATTACH){
-
- AllocConsole();
- freopen("CONIN$", "r", stdin);
- freopen("CONOUT$", "w", stdout);
- freopen("CONOUT$", "w", stderr);
-
- if (*(DWORD*)0x5C1E75 == 0xB85548EC) // 1.0
- patch();
- else
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/src/core/timebars.cpp b/src/core/timebars.cpp
index 93d85f8d..6b841a5c 100644
--- a/src/core/timebars.cpp
+++ b/src/core/timebars.cpp
@@ -1,5 +1,5 @@
-#ifndef MASTER
#include "common.h"
+#ifndef MASTER
#include "Font.h"
#include "Frontend.h"
#include "Timer.h"
@@ -102,14 +102,14 @@ void tbDisplay()
#ifndef FINAL
// Timers output (my own implementation)
for (uint32 i = 0; i < TimerBar.count; i++) {
- MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
+ MaxTimes[i] = Max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
AsciiToUnicode(temp, wtemp);
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
}
#ifdef FRAMETIME
- MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
+ MaxFrameTime = Max(MaxFrameTime, FrameEndTime - FrameInitTime);
sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
AsciiToUnicode(temp, wtemp);
diff --git a/src/entities/Building.cpp b/src/entities/Building.cpp
index 7813c87f..aad2d402 100644
--- a/src/entities/Building.cpp
+++ b/src/entities/Building.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Building.h"
#include "Streaming.h"
#include "Pools.h"
@@ -20,18 +20,3 @@ CBuilding::ReplaceWithNewModel(int32 id)
if(m_level == LEVEL_NONE || m_level == CGame::currLevel)
CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
}
-
-#include <new>
-
-class CBuilding_ : public CBuilding
-{
-public:
- CBuilding *ctor(void) { return ::new (this) CBuilding(); }
- void dtor(void) { CBuilding::~CBuilding(); }
-};
-
-STARTPATCHES
- InjectHook(0x4057D0, &CBuilding_::ctor, PATCH_JUMP);
- InjectHook(0x405800, &CBuilding_::dtor, PATCH_JUMP);
- InjectHook(0x405850, &CBuilding::ReplaceWithNewModel, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp
index 176e5682..8a4bfd5f 100644
--- a/src/entities/Dummy.cpp
+++ b/src/entities/Dummy.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Pools.h"
#include "World.h"
#include "Dummy.h"
@@ -50,17 +50,3 @@ CDummy::Remove(void)
m_entryInfoList.DeleteNode(node);
}
}
-
-class CDummy_ : public CDummy
-{
-public:
- void Add_(void) { CDummy::Add(); }
- void Remove_(void) { CDummy::Remove(); }
- void dtor(void) { CDummy::~CDummy(); }
-};
-
-STARTPATCHES
- InjectHook(0x473810, &CDummy_::dtor, PATCH_JUMP);
- InjectHook(0x473860, &CDummy_::Add_, PATCH_JUMP);
- InjectHook(0x473AD0, &CDummy_::Remove_, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 25e5db48..ee4faa82 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -1,6 +1,7 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
+#include "RwHelper.h"
#include "ModelIndices.h"
#include "Timer.h"
#include "Placeable.h"
@@ -24,6 +25,8 @@
#include "References.h"
#include "TxdStore.h"
#include "Zones.h"
+#include "Bones.h"
+#include "Debug.h"
int gBuildings;
@@ -293,8 +296,13 @@ CEntity::DeleteRwObject(void)
f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f);
- }else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ }else if(RwObjectGetType(m_rwObject) == rpCLUMP){
+#ifdef PED_SKIN
+ if(IsClumpSkinned((RpClump*)m_rwObject))
+ RpClumpForAllAtomics((RpClump*)m_rwObject, AtomicRemoveAnimFromSkinCB, nil);
+#endif
RpClumpDestroy((RpClump*)m_rwObject);
+ }
m_rwObject = nil;
CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
if(IsBuilding())
@@ -558,6 +566,44 @@ CEntity::PruneReferences(void)
}
}
+#ifdef PED_SKIN
+void
+CEntity::UpdateRpHAnim(void)
+{
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ RpHAnimHierarchyUpdateMatrices(hier);
+
+#if 0
+ int i;
+ char buf[256];
+ if(this == (CEntity*)FindPlayerPed())
+ for(i = 0; i < hier->numNodes; i++){
+ RpHAnimStdKeyFrame *kf = (RpHAnimStdKeyFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
+ kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
+ kf->t.x, kf->t.y, kf->t.z,
+ HIERNODEID(hier, i),
+ ConvertBoneTag2BoneName(HIERNODEID(hier, i)));
+ CDebug::PrintAt(buf, 10, 1+i*3);
+
+ RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i];
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.x, m->up.x, m->at.x, m->pos.x);
+ CDebug::PrintAt(buf, 80, 1+i*3+0);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.y, m->up.y, m->at.y, m->pos.y);
+ CDebug::PrintAt(buf, 80, 1+i*3+1);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.z, m->up.z, m->at.z, m->pos.z);
+ CDebug::PrintAt(buf, 80, 1+i*3+2);
+ }
+
+ void RenderSkeleton(RpHAnimHierarchy *hier);
+ RenderSkeleton(hier);
+#endif
+}
+#endif
+
void
CEntity::AddSteamsFromGround(CVector *unused)
{
@@ -865,55 +911,12 @@ CEntity::ModifyMatrixForBannerInWind(void)
UpdateRwFrame();
}
-#include <new>
-
-class CEntity_ : public CEntity
+void
+CEntity::AddSteamsFromGround(CPtrList& list)
{
-public:
- CEntity *ctor(void) { return ::new (this) CEntity(); }
- void dtor(void) { this->CEntity::~CEntity(); }
- void Add_(void) { CEntity::Add(); }
- void Remove_(void) { CEntity::Remove(); }
- void SetModelIndex_(uint32 i) { CEntity::SetModelIndex(i); }
- void CreateRwObject_(void) { CEntity::CreateRwObject(); }
- void DeleteRwObject_(void) { CEntity::DeleteRwObject(); }
- CRect GetBoundRect_(void) { return CEntity::GetBoundRect(); }
- void PreRender_(void) { CEntity::PreRender(); }
- void Render_(void) { CEntity::Render(); }
- bool SetupLighting_(void) { return CEntity::SetupLighting(); }
-};
-
-STARTPATCHES
- InjectHook(0x473C30, &CEntity_::ctor, PATCH_JUMP);
- InjectHook(0x473E40, &CEntity_::dtor, PATCH_JUMP);
- InjectHook(0x473E70, &CEntity_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x475080, &CEntity_::Add_, PATCH_JUMP);
- InjectHook(0x475310, &CEntity_::Remove_, PATCH_JUMP);
- InjectHook(0x473EA0, &CEntity_::CreateRwObject_, PATCH_JUMP);
- InjectHook(0x473F90, &CEntity_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x474000, &CEntity_::GetBoundRect_, PATCH_JUMP);
- InjectHook(0x474350, &CEntity_::PreRender_, PATCH_JUMP);
- InjectHook(0x474BD0, &CEntity_::Render_, PATCH_JUMP);
- InjectHook(0x4A7C60, &CEntity_::SetupLighting_, PATCH_JUMP);
-
- InjectHook(0x4742C0, (void (CEntity::*)(CVector&))&CEntity::GetBoundCentre, PATCH_JUMP);
- InjectHook(0x474310, &CEntity::GetBoundRadius, PATCH_JUMP);
- InjectHook(0x474C10, &CEntity::GetIsTouching, PATCH_JUMP);
- InjectHook(0x474CC0, &CEntity::GetIsOnScreen, PATCH_JUMP);
- InjectHook(0x474D20, &CEntity::GetIsOnScreenComplex, PATCH_JUMP);
- InjectHook(0x474CA0, &CEntity::IsVisible, PATCH_JUMP);
- InjectHook(0x474330, &CEntity::UpdateRwFrame, PATCH_JUMP);
- InjectHook(0x4755E0, &CEntity::SetupBigBuilding, PATCH_JUMP);
- InjectHook(0x4A7480, &CEntity::RegisterReference, PATCH_JUMP);
- InjectHook(0x4A74E0, &CEntity::ResolveReferences, PATCH_JUMP);
- InjectHook(0x4A7530, &CEntity::PruneReferences, PATCH_JUMP);
-
- InjectHook(0x473F10, &CEntity::AttachToRwObject, PATCH_JUMP);
- InjectHook(0x473F60, &CEntity::DetachFromRwObject, PATCH_JUMP);
-
- InjectHook(0x475A20, &CEntity::PreRenderForGlassWindow, PATCH_JUMP);
- InjectHook(0x50CE40, &CEntity::AddSteamsFromGround, PATCH_JUMP);
- InjectHook(0x475670, &CEntity::ModifyMatrixForTreeInWind, PATCH_JUMP);
- InjectHook(0x475830, &CEntity::ModifyMatrixForBannerInWind, PATCH_JUMP);
- InjectHook(0x4FA530, &CEntity::ProcessLightsForEntity, PATCH_JUMP);
-ENDPATCHES
+ CPtrNode *pNode = list.first;
+ while (pNode) {
+ ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
+ pNode = pNode->next;
+ }
+}
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index ca501ba4..ee9e6490 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -4,6 +4,7 @@
#include "Placeable.h"
struct CReference;
+class CPtrList;
enum eEntityType
{
@@ -39,25 +40,25 @@ public:
uint32 m_status : 5;
// flagsA
- uint32 bUsesCollision : 1;
- uint32 bCollisionProcessed : 1;
- uint32 bIsStatic : 1;
- uint32 bHasContacted : 1;
+ uint32 bUsesCollision : 1; // does entity use collision
+ uint32 bCollisionProcessed : 1; // has object been processed by a ProcessEntityCollision function
+ uint32 bIsStatic : 1; // is entity static
+ uint32 bHasContacted : 1; // has entity processed some contact forces
uint32 bPedPhysics : 1;
- uint32 bIsStuck : 1;
- uint32 bIsInSafePosition : 1;
+ uint32 bIsStuck : 1; // is entity stuck
+ uint32 bIsInSafePosition : 1; // is entity in a collision free safe position
uint32 bUseCollisionRecords : 1;
// flagsB
- uint32 bWasPostponed : 1;
+ uint32 bWasPostponed : 1; // was entity control processing postponed
uint32 bExplosionProof : 1;
- uint32 bIsVisible : 1;
- uint32 bHasCollided : 1; //
+ uint32 bIsVisible : 1; //is the entity visible
+ uint32 bHasCollided : 1;
uint32 bRenderScorched : 1;
uint32 bHasBlip : 1;
- uint32 bIsBIGBuilding : 1;
+ uint32 bIsBIGBuilding : 1; // Set if this entity is a big building
// VC inserts one more flag here: if drawdist <= 2000
- uint32 bRenderDamaged : 1;
+ uint32 bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage
// flagsC
uint32 bBulletProof : 1;
@@ -65,22 +66,22 @@ public:
uint32 bCollisionProof : 1;
uint32 bMeleeProof : 1;
uint32 bOnlyDamagedByPlayer : 1;
- uint32 bStreamingDontDelete : 1;
+ uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this
uint32 bZoneCulled : 1;
- uint32 bZoneCulled2 : 1; // only treadables+10m
+ uint32 bZoneCulled2 : 1; // only treadables+10m
// flagsD
- uint32 bRemoveFromWorld : 1;
- uint32 bHasHitWall : 1;
- uint32 bImBeingRendered : 1;
+ uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed
+ uint32 bHasHitWall : 1; // has collided with a building (changes subsequent collisions)
+ uint32 bImBeingRendered : 1; // don't delete me because I'm being rendered
uint32 bTouchingWater : 1; // used by cBuoyancy::ProcessBuoyancy
uint32 bIsSubway : 1; // set when subway, but maybe different meaning?
- uint32 bDrawLast : 1;
+ uint32 bDrawLast : 1; // draw object last
uint32 bNoBrightHeadLights : 1;
uint32 bDoNotRender : 1;
// flagsE
- uint32 bDistanceFade : 1;
+ uint32 bDistanceFade : 1; // Fade entity because it is far away
uint32 m_flagE2 : 1;
uint16 m_scanCode;
@@ -147,10 +148,16 @@ public:
void ResolveReferences(void);
void PruneReferences(void);
+#ifdef PED_SKIN
+ void UpdateRpHAnim(void);
+#endif
+
void PreRenderForGlassWindow(void);
void AddSteamsFromGround(CVector *unused);
void ModifyMatrixForTreeInWind(void);
void ModifyMatrixForBannerInWind(void);
void ProcessLightsForEntity(void);
+
+ static void AddSteamsFromGround(CPtrList& list);
};
static_assert(sizeof(CEntity) == 0x64, "CEntity: error");
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 9fc77a8c..a27e4d7b 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "World.h"
#include "Timer.h"
#include "ModelIndices.h"
@@ -36,7 +36,7 @@ CPhysical::CPhysical(void)
for(i = 0; i < 6; i++)
m_aCollisionRecords[i] = nil;
- field_EF = false;
+ m_bIsVehicleBeingShifted = false;
m_nDamagePieceType = 0;
m_fDamageImpulse = 0.0f;
@@ -63,7 +63,7 @@ CPhysical::CPhysical(void)
m_phy_flagA10 = false;
m_phy_flagA20 = false;
- m_nZoneLevel = 0;
+ m_nZoneLevel = LEVEL_NONE;
}
CPhysical::~CPhysical(void)
@@ -457,7 +457,7 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &
{
float compression = 1.0f - springRatio;
if(compression > 0.0f){
- float step = min(CTimer::GetTimeStep(), 3.0f);
+ float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -GRAVITY*m_fMass*step * springConst * compression * bias*2.0f;
ApplyMoveForce(springDir*impulse);
ApplyTurnForce(springDir*impulse, point);
@@ -471,12 +471,12 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
{
float speedA = DotProduct(speed, springDir);
float speedB = DotProduct(GetSpeed(point), springDir);
- float step = min(CTimer::GetTimeStep(), 3.0f);
+ float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f;
// what is this?
float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass);
- a = min(a, 1.0f);
+ a = Min(a, 1.0f);
float b = Abs(impulse / (speedB * m_fMass));
if(a < b)
impulse *= a/b;
@@ -612,7 +612,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){
CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true);
Bobj->bHasBeenDamaged = true;
- }else if(B->IsObject() && model != MI_EXPLODINGBARREL && model != MI_PETROLPUMP)
+ }else if(B->IsObject() && !IsExplosiveThingModel(model))
Bobj->bHasBeenDamaged = true;
}else{
if(IsGlass(B->GetModelIndex()))
@@ -646,7 +646,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
// positive if B is moving towards A
// not interested in how much B moves into A apparently?
// only interested in cases where A collided into B
- speedB = max(0.0f, DotProduct(B->m_vecMoveSpeed, colpoint.normal));
+ speedB = Max(0.0f, DotProduct(B->m_vecMoveSpeed, colpoint.normal));
// A has moved into B
if(speedA < speedB){
if(!A->bHasHitWall)
@@ -1037,7 +1037,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
int numCollisions;
int mostColliding;
- CColPoint colpoints[32];
+ CColPoint colpoints[MAX_COLLISION_POINTS];
CVector shift = { 0.0f, 0.0f, 0.0f };
bool doShift = false;
CEntity *boat = nil;
@@ -1147,18 +1147,18 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
CVector dir = A->GetPosition() - B->GetPosition();
dir.Normalise();
if(dir.z < 0.0f && dir.z < A->GetForward().z && dir.z < A->GetRight().z)
- dir.z = min(0.0f, min(A->GetForward().z, A->GetRight().z));
+ dir.z = Min(0.0f, Min(A->GetForward().z, A->GetRight().z));
shift += dir * colpoints[mostColliding].depth * 0.5f;
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
CVector dir = colpoints[mostColliding].normal;
- float f = min(Abs(dir.z), 0.9f);
+ float f = Min(Abs(dir.z), 0.9f);
dir.z = 0.0f;
dir.Normalise();
shift += dir * colpoints[mostColliding].depth / (1.0f - f);
boat = B;
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
CVector dir = colpoints[mostColliding].normal * -1.0f;
- float f = min(Abs(dir.z), 0.9f);
+ float f = Min(Abs(dir.z), 0.9f);
dir.z = 0.0f;
dir.Normalise();
B->GetPosition() += dir * colpoints[mostColliding].depth / (1.0f - f);
@@ -1187,7 +1187,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
bool
CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
{
- static CColPoint aColPoints[32];
+ static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius;
CVector center;
int listtype;
@@ -1246,7 +1246,7 @@ collision:
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
}
}else if(A->bHasContacted){
CVector savedMoveFriction = A->m_vecMoveFriction;
@@ -1268,7 +1268,7 @@ collision:
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1301,7 +1301,7 @@ collision:
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1328,7 +1328,7 @@ collision:
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1349,7 +1349,7 @@ collision:
bool
CPhysical::ProcessCollisionSectorList(CPtrList *lists)
{
- static CColPoint aColPoints[32];
+ static CColPoint aColPoints[MAX_COLLISION_POINTS];
float radius;
CVector center;
CPtrList *list;
@@ -1506,7 +1506,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff));
}
}else{
for(i = 0; i < numCollisions; i++){
@@ -1527,7 +1527,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff));
float adhesion = CSurfaceTable::GetAdhesiveLimit(aColPoints[i]) / numCollisions;
@@ -1545,7 +1545,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
else if(A->GetUp().z > 0.3f)
adhesion = 0.0f;
else
- adhesion *= min(5.0f, 0.03f*impulseA + 1.0f);
+ adhesion *= Min(5.0f, 0.03f*impulseA + 1.0f);
}
if(A->ApplyFriction(adhesion, aColPoints[i]))
@@ -1594,7 +1594,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
}
}else if(A->bHasContacted){
CVector savedMoveFriction = A->m_vecMoveFriction;
@@ -1619,7 +1619,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1655,7 +1655,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1685,7 +1685,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
A->bHasContacted = true;
@@ -1767,13 +1767,13 @@ CPhysical::ProcessShift(void)
CWorld::AdvanceCurrentScanCode();
if(IsVehicle())
- field_EF = true;
+ m_bIsVehicleBeingShifted = true;
CEntryInfoNode *node;
bool hasshifted = false; // whatever that means...
for(node = m_entryInfoList.first; node; node = node->next)
hasshifted |= ProcessShiftSectorList(node->sector->m_lists);
- field_EF = false;
+ m_bIsVehicleBeingShifted = false;
if(hasshifted){
CWorld::AdvanceCurrentScanCode();
for(node = m_entryInfoList.first; node; node = node->next)
@@ -1799,7 +1799,7 @@ CPhysical::ProcessCollision(void)
CPed *ped = (CPed*)this;
m_fDistanceTravelled = 0.0f;
- field_EF = 0;
+ m_bIsVehicleBeingShifted = false;
m_phy_flagA80 = false;
if(!bUsesCollision){
@@ -1831,7 +1831,7 @@ CPhysical::ProcessCollision(void)
if(IsPed() && (distSq >= sq(0.2f) || ped->IsPlayer())){
if(ped->IsPlayer())
- n = max(NUMSTEPS(0.2f), 2.0f);
+ n = Max(NUMSTEPS(0.2f), 2.0f);
else
n = NUMSTEPS(0.3f);
step = savedTimeStep / n;
@@ -1852,7 +1852,7 @@ CPhysical::ProcessCollision(void)
speedDown = Multiply3x3(GetMatrix(), speedDown);
speedUp = GetSpeed(speedUp);
speedDown = GetSpeed(speedDown);
- distSq = max(speedUp.MagnitudeSqr(), speedDown.MagnitudeSqr()) * sq(CTimer::GetTimeStep());
+ distSq = Max(speedUp.MagnitudeSqr(), speedDown.MagnitudeSqr()) * sq(CTimer::GetTimeStep());
if(distSq >= sq(0.3f)){
n = NUMSTEPS(0.3f);
step = savedTimeStep / n;
@@ -1912,7 +1912,7 @@ CPhysical::ProcessCollision(void)
ApplyMoveSpeed();
ApplyTurnSpeed();
GetMatrix().Reorthogonalise();
- field_EF = 0;
+ m_bIsVehicleBeingShifted = false;
m_phy_flagA80 = false;
if(!m_vecMoveSpeed.IsZero() ||
!m_vecTurnSpeed.IsZero() ||
@@ -1933,58 +1933,3 @@ CPhysical::ProcessCollision(void)
bIsInSafePosition = true;
RemoveAndAdd();
}
-
-class CPhysical_ : public CPhysical
-{
-public:
- void dtor(void) { CPhysical::~CPhysical(); }
- void Add_(void) { CPhysical::Add(); }
- void Remove_(void) { CPhysical::Remove(); }
- CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); }
- void ProcessControl_(void) { CPhysical::ProcessControl(); }
- void ProcessShift_(void) { CPhysical::ProcessShift(); }
- void ProcessCollision_(void) { CPhysical::ProcessCollision(); }
- int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); }
-};
-
-STARTPATCHES
- InjectHook(0x495130, &CPhysical_::dtor, PATCH_JUMP);
- InjectHook(0x4951F0, &CPhysical_::Add_, PATCH_JUMP);
- InjectHook(0x4954B0, &CPhysical_::Remove_, PATCH_JUMP);
- InjectHook(0x495540, &CPhysical_::RemoveAndAdd, PATCH_JUMP);
- InjectHook(0x495F10, &CPhysical_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x496F10, &CPhysical_::ProcessShift_, PATCH_JUMP);
- InjectHook(0x4961A0, &CPhysical_::ProcessCollision_, PATCH_JUMP);
- InjectHook(0x49F790, &CPhysical_::ProcessEntityCollision_, PATCH_JUMP);
- InjectHook(0x4958F0, &CPhysical::AddToMovingList, PATCH_JUMP);
- InjectHook(0x495940, &CPhysical::RemoveFromMovingList, PATCH_JUMP);
- InjectHook(0x497180, &CPhysical::AddCollisionRecord, PATCH_JUMP);
- InjectHook(0x4970C0, &CPhysical::AddCollisionRecord_Treadable, PATCH_JUMP);
- InjectHook(0x497240, &CPhysical::GetHasCollidedWith, PATCH_JUMP);
- InjectHook(0x49F820, &CPhysical::RemoveRefsToEntity, PATCH_JUMP);
- InjectHook(0x49F890, &CPhysical::PlacePhysicalRelativeToOtherPhysical, PATCH_JUMP);
-
-#define F3 float, float, float
- InjectHook(0x495B10, &CPhysical::ApplyMoveSpeed, PATCH_JUMP);
- InjectHook(0x497280, &CPhysical::ApplyTurnSpeed, PATCH_JUMP);
- InjectHook(0x4959A0, (void (CPhysical::*)(F3))&CPhysical::ApplyMoveForce, PATCH_JUMP);
- InjectHook(0x495A10, (void (CPhysical::*)(F3, F3))&CPhysical::ApplyTurnForce, PATCH_JUMP);
- InjectHook(0x495D90, (void (CPhysical::*)(F3))&CPhysical::ApplyFrictionMoveForce, PATCH_JUMP);
- InjectHook(0x495E10, (void (CPhysical::*)(F3, F3))&CPhysical::ApplyFrictionTurnForce, PATCH_JUMP);
- InjectHook(0x499890, &CPhysical::ApplySpringCollision, PATCH_JUMP);
- InjectHook(0x499990, &CPhysical::ApplySpringDampening, PATCH_JUMP);
- InjectHook(0x495B50, &CPhysical::ApplyGravity, PATCH_JUMP);
- InjectHook(0x495B80, (void (CPhysical::*)(void))&CPhysical::ApplyFriction, PATCH_JUMP);
- InjectHook(0x495C20, &CPhysical::ApplyAirResistance, PATCH_JUMP);
-
- InjectHook(0x4973A0, &CPhysical::ApplyCollision, PATCH_JUMP);
- InjectHook(0x4992A0, &CPhysical::ApplyCollisionAlt, PATCH_JUMP);
- InjectHook(0x499BE0, (bool (CPhysical::*)(float, CColPoint&))&CPhysical::ApplyFriction, PATCH_JUMP);
- InjectHook(0x49A180, (bool (CPhysical::*)(CPhysical*, float, CColPoint&))&CPhysical::ApplyFriction, PATCH_JUMP);
-
- InjectHook(0x49DA10, &CPhysical::ProcessShiftSectorList, PATCH_JUMP);
- InjectHook(0x49E790, &CPhysical::ProcessCollisionSectorList_SimpleCar, PATCH_JUMP);
- InjectHook(0x49B620, &CPhysical::ProcessCollisionSectorList, PATCH_JUMP);
- InjectHook(0x496E50, &CPhysical::CheckCollision, PATCH_JUMP);
- InjectHook(0x496EB0, &CPhysical::CheckCollision_SimpleCar, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/entities/Physical.h b/src/entities/Physical.h
index 6fbc3ffd..fa5ada05 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -40,7 +40,7 @@ public:
char field_EC;
uint8 m_nStaticFrames;
uint8 m_nCollisionRecords;
- bool field_EF;
+ bool m_bIsVehicleBeingShifted;
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
float m_fDistanceTravelled;
@@ -55,8 +55,8 @@ public:
uint8 bAffectedByGravity : 1;
uint8 bInfiniteMass : 1;
uint8 bIsInWater : 1;
- uint8 m_phy_flagA10 : 1;
- uint8 m_phy_flagA20 : 1;
+ uint8 m_phy_flagA10 : 1; // unused
+ uint8 m_phy_flagA20 : 1; // unused
uint8 bHitByTrain : 1;
uint8 m_phy_flagA80 : 1;
diff --git a/src/entities/Treadable.cpp b/src/entities/Treadable.cpp
index ea949f00..00abbe13 100644
--- a/src/entities/Treadable.cpp
+++ b/src/entities/Treadable.cpp
@@ -1,18 +1,8 @@
#include "common.h"
-#include "patcher.h"
+
#include "rpworld.h"
#include "Treadable.h"
#include "Pools.h"
void *CTreadable::operator new(size_t sz) { return CPools::GetTreadablePool()->New(); }
void CTreadable::operator delete(void *p, size_t sz) { CPools::GetTreadablePool()->Delete((CTreadable*)p); }
-
-class CTreadable_ : public CTreadable
-{
-public:
- void dtor(void) { CTreadable::~CTreadable(); }
-};
-
-STARTPATCHES
- InjectHook(0x405A10, &CTreadable_::dtor, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/extras/arrow.inc b/src/extras/arrow.inc
new file mode 100644
index 00000000..8ea78283
--- /dev/null
+++ b/src/extras/arrow.inc
@@ -0,0 +1,16 @@
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/src/extras/cursor.inc b/src/extras/cursor.inc
new file mode 100644
index 00000000..e8afd394
--- /dev/null
+++ b/src/extras/cursor.inc
@@ -0,0 +1,16 @@
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
+255, 255, 255, 255, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 255, 255, 255, 255, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0, 119, 119, 119, 0,
diff --git a/src/extras/debugmenu.cpp b/src/extras/debugmenu.cpp
new file mode 100644
index 00000000..f419e76f
--- /dev/null
+++ b/src/extras/debugmenu.cpp
@@ -0,0 +1,1294 @@
+#include "common.h"
+#include "RwHelper.h"
+#include "Pad.h"
+#include "ControllerConfig.h"
+#include "Timer.h"
+#include "rtcharse.h"
+#include "inttypes.h"
+#include "debugmenu.h"
+
+#define snprintf _snprintf
+
+#define strdup _strdup
+
+
+
+// Font stuff
+struct Pt
+{
+ int x, y;
+};
+
+enum MenuFontStyle
+{
+ MENUFONT_NORMAL,
+ MENUFONT_SEL_ACTIVE,
+ MENUFONT_SEL_INACTIVE,
+ MENUFONT_MOUSE
+};
+
+RtCharset *fontStyles[4];
+RtCharsetDesc fontDesc;
+int fontscale = 1; // not supported right now
+
+Pt
+fontGetStringSize(const char *s)
+{
+ Pt sz = { 0, 0 };
+ int x;
+ char c;
+ sz.y = fontDesc.height*fontscale; // always assume one line;
+ x = 0;
+ while(c = *s++){
+ if(c == '\n'){
+ sz.y += fontDesc.height*fontscale;
+ if(x > sz.x)
+ sz.x = x;
+ x = 0;
+ }else
+ x += fontDesc.width*fontscale;
+ }
+ if(x > sz.x)
+ sz.x = x;
+ return sz;
+}
+
+Pt
+fontPrint(const char *s, float x, float y, int style)
+{
+ RtCharsetPrintBuffered(fontStyles[style], s, x, y, false);
+ return fontGetStringSize(s);
+}
+
+int
+fontGetLen(int len)
+{
+ return len*fontDesc.width*fontscale;
+}
+
+
+void
+createMenuFont(void)
+{
+ OpenCharsetSafe();
+
+ RwRGBA fg_normal = { 255, 255, 255, 255 };
+ RwRGBA bg_normal = { 255, 255, 255, 0 };
+ fontStyles[MENUFONT_NORMAL] = RtCharsetCreate(&fg_normal, &bg_normal);
+ assert(fontStyles[MENUFONT_NORMAL]);
+
+ RwRGBA fg_sel_active = { 200, 200, 200, 255 };
+ RwRGBA bg_sel_active = { 132, 132, 132, 255 };
+ fontStyles[MENUFONT_SEL_ACTIVE] = RtCharsetCreate(&fg_sel_active, &bg_sel_active);
+ assert(fontStyles[MENUFONT_SEL_ACTIVE]);
+
+ RwRGBA fg_sel_inactive = { 200, 200, 200, 255 };
+ RwRGBA bg_sel_inactive = { 200, 200, 200, 0 };
+ fontStyles[MENUFONT_SEL_INACTIVE] = RtCharsetCreate(&fg_sel_inactive, &bg_sel_inactive);
+ assert(fontStyles[MENUFONT_SEL_INACTIVE]);
+
+ RwRGBA fg_mouse = { 255, 255, 255, 255 };
+ RwRGBA bg_mouse = { 132, 132, 132, 255 };
+ fontStyles[MENUFONT_MOUSE] = RtCharsetCreate(&fg_mouse, &bg_mouse);
+ assert(fontStyles[MENUFONT_MOUSE]);
+
+ RtCharsetGetDesc(fontStyles[MENUFONT_NORMAL], &fontDesc);
+}
+
+void
+destroyMenuFont(void)
+{
+ RtCharsetDestroy(fontStyles[MENUFONT_NORMAL]);
+ fontStyles[MENUFONT_NORMAL] = nil;
+ RtCharsetDestroy(fontStyles[MENUFONT_SEL_ACTIVE]);
+ fontStyles[MENUFONT_SEL_ACTIVE] = nil;
+ RtCharsetDestroy(fontStyles[MENUFONT_SEL_INACTIVE]);
+ fontStyles[MENUFONT_SEL_INACTIVE] = nil;
+ RtCharsetDestroy(fontStyles[MENUFONT_MOUSE]);
+ fontStyles[MENUFONT_MOUSE] = nil;
+}
+
+
+
+
+
+
+enum EntryType
+{
+ MENUEMPTY = 0,
+ MENUSUB,
+ MENUVAR,
+
+ MENUVAR_INT,
+ MENUVAR_FLOAT,
+ MENUVAR_CMD,
+
+ MENUSCROLL // dummy
+};
+
+struct Menu
+{
+ Menu *parent;
+ RwRect r;
+ MenuEntry *entries;
+ int numEntries;
+ int maxNameWidth, maxValWidth;
+
+ MenuEntry *findEntry(const char *entryname);
+ void insertEntrySorted(MenuEntry *entry);
+ void appendEntry(MenuEntry *entry);
+
+ bool isScrollingUp, isScrollingDown;
+ int scrollStart;
+ int numVisible;
+ RwRect scrollUpR, scrollDownR;
+ void scroll(int off);
+
+ int selection;
+ MenuEntry *selectedEntry; // updated by update
+ void changeSelection(int newsel);
+ void changeSelection(MenuEntry *e);
+
+ void update(void);
+ void draw(void);
+ Menu(void){ memset(this, 0, sizeof(Menu)); }
+};
+extern Menu toplevel;
+
+struct MenuEntry_Sub : MenuEntry
+{
+ Menu *submenu;
+
+ MenuEntry_Sub(const char *name, Menu *menu);
+};
+
+struct MenuEntry_Var : MenuEntry
+{
+ int maxvallen;
+ int vartype;
+ bool wrapAround;
+
+ virtual void processInput(bool mouseOver, bool selected) = 0;
+ int getValWidth(void) { return maxvallen; }
+ virtual void getValStr(char *str, int len) = 0;
+ MenuEntry_Var(const char *name, int type);
+};
+
+struct MenuEntry_Int : MenuEntry_Var
+{
+ virtual void setStrings(const char **strings) = 0;
+ virtual int findStringLen(void) = 0;
+ MenuEntry_Int(const char *name);
+};
+
+#define INTTYPES \
+ X(Int8, int8, 4, "%4" PRId8) \
+ X(Int16, int16, 6, "%6" PRId16) \
+ X(Int32, int32, 11, "%11" PRId32) \
+ X(Int64, int64, 21, "%21" PRId64) \
+ X(UInt8, uint8, 4, "%4" PRIu8) \
+ X(UInt16, uint16, 6, "%6" PRIu16) \
+ X(UInt32, uint32, 11, "%11" PRIu32) \
+ X(UInt64, uint64, 21, "%21" PRIu64)
+#define FLOATTYPES \
+ X(Float32, float, 11, "%11.3f") \
+ X(Float64, double, 11, "%11.3lf")
+
+#define X(NAME, TYPE, MAXLEN, FMT) \
+struct MenuEntry_##NAME : MenuEntry_Int \
+{ \
+ TYPE *variable; \
+ TYPE lowerBound, upperBound; \
+ TYPE step; \
+ TriggerFunc triggerFunc; \
+ const char *fmt; \
+ const char **strings; \
+ \
+ void processInput(bool mouseOver, bool selected); \
+ void getValStr(char *str, int len); \
+ \
+ void setStrings(const char **strings); \
+ int findStringLen(void); \
+ MenuEntry_##NAME(const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound, const char **strings); \
+};
+INTTYPES
+#undef X
+
+#define X(NAME, TYPE, MAXLEN, FMT) \
+struct MenuEntry_##NAME : MenuEntry_Var \
+{ \
+ TYPE *variable; \
+ TYPE lowerBound, upperBound; \
+ TYPE step; \
+ TriggerFunc triggerFunc; \
+ const char *fmt; \
+ \
+ void processInput(bool mouseOver, bool selected); \
+ void getValStr(char *str, int len); \
+ \
+ MenuEntry_##NAME(const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound); \
+};
+FLOATTYPES
+#undef X
+
+struct MenuEntry_Cmd : MenuEntry_Var
+{
+ TriggerFunc triggerFunc;
+
+ void processInput(bool mouseOver, bool selected);
+ void getValStr(char *str, int len);
+
+ MenuEntry_Cmd(const char *name, TriggerFunc triggerFunc);
+};
+
+
+Menu *findMenu(const char *name);
+
+
+
+#define MUHKEYS \
+ X(leftjustdown, rsLEFT) \
+ X(rightjustdown, rsRIGHT) \
+ X(upjustdown, rsUP) \
+ X(downjustdown, rsDOWN) \
+ X(pgupjustdown, rsPGUP) \
+ X(pgdnjustdown, rsPGDN)
+
+#define MUHBUTTONS \
+ X(button1justdown, 1) \
+ X(button2justdown, 2) \
+ X(button3justdown, 3)
+
+#define REPEATDELAY 700
+#define REPEATINTERVAL 50
+#define X(var, keycode) static int var;
+MUHKEYS
+#undef X
+static int downtime;
+static int repeattime;
+static int lastkeydown;
+static int *keyptr;
+
+static int buttondown[3];
+static int lastbuttondown;
+static int *buttonptr;
+static int button1justdown, button2justdown, button3justdown;
+static float mouseX, mouseY;
+
+static int menuOn;
+static int menuInitialized;
+static int screenWidth, screenHeight;
+static RwRaster *cursor, *arrow;
+
+static int firstBorder = 10;
+static int topBorder = 40; //10;
+static int leading = 4;
+static int gap = 10;
+static int minwidth = 100;
+
+void drawMouse(void);
+void drawArrow(RwRect r, int direction, int style);
+
+Menu toplevel;
+Menu *activeMenu = &toplevel;
+Menu *deepestMenu = &toplevel;
+Menu *mouseOverMenu;
+MenuEntry *mouseOverEntry;
+MenuEntry scrollUpEntry("SCROLLUP"), scrollDownEntry("SCROLLDOWN"); // dummies
+
+
+#define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k)
+#define KEYDOWN(k) ControlsManager.GetIsKeyboardKeyDown((RsKeyCodes)k)
+#define CTRLJUSTDOWN(key) \
+ ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYJUSTDOWN((RsKeyCodes)key) || \
+ (KEYJUSTDOWN(rsLCTRL) || KEYJUSTDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key))
+#define CTRLDOWN(key) ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key))
+
+
+bool
+isMouseInRect(RwRect r)
+{
+ return (mouseX >= r.x && mouseX < r.x+r.w &&
+ mouseY >= r.y && mouseY < r.y+r.h);
+}
+
+/*
+ * MenuEntry
+ */
+
+MenuEntry::MenuEntry(const char *name)
+{
+ this->type = MENUEMPTY;
+ this->name = strdup(name);
+ this->next = nil;
+ this->menu = nil;
+}
+
+MenuEntry_Sub::MenuEntry_Sub(const char *name, Menu *menu)
+: MenuEntry(name)
+{
+ this->type = MENUSUB;
+ this->submenu = menu;
+}
+
+MenuEntry_Var::MenuEntry_Var(const char *name, int vartype)
+: MenuEntry(name)
+{
+ this->type = MENUVAR;
+ this->vartype = vartype;
+ this->maxvallen = 0;
+ this->wrapAround = false;
+}
+
+/*
+ * *****************************
+ * MenuEntry_Int
+ * *****************************
+ */
+
+MenuEntry_Int::MenuEntry_Int(const char *name)
+: MenuEntry_Var(name, MENUVAR_INT)
+{
+}
+
+#define X(NAME, TYPE, MAXLEN, FMT) \
+int \
+MenuEntry_##NAME::findStringLen(void){ \
+ TYPE i; \
+ int len, maxlen = 0; \
+ for(i = this->lowerBound; i <= this->upperBound; i++){ \
+ len = strlen(this->strings[i-this->lowerBound]); \
+ if(len > maxlen) \
+ maxlen = len; \
+ } \
+ return maxlen; \
+} \
+void \
+MenuEntry_##NAME::processInput(bool mouseOver, bool selected) \
+{ \
+ TYPE v, oldv; \
+ int overflow = 0; \
+ int underflow = 0; \
+ \
+ v = *this->variable; \
+ oldv = v; \
+ \
+ if((selected && leftjustdown) || (mouseOver && button3justdown)){ \
+ v -= this->step; \
+ if(v > oldv) \
+ underflow = 1; \
+ } \
+ if((selected && rightjustdown) || (mouseOver && button1justdown)){ \
+ v += this->step; \
+ if(v < oldv) \
+ overflow = 1; \
+ } \
+ if(this->wrapAround){ \
+ if(v > this->upperBound || overflow) v = this->lowerBound; \
+ if(v < this->lowerBound || underflow) v = this->upperBound; \
+ }else{ \
+ if(v > this->upperBound || overflow) v = this->upperBound; \
+ if(v < this->lowerBound || underflow) v = this->lowerBound; \
+ } \
+ \
+ *this->variable = v; \
+ if(oldv != v && this->triggerFunc) \
+ this->triggerFunc(); \
+} \
+void \
+MenuEntry_##NAME::getValStr(char *str, int len) \
+{ \
+ static char tmp[20]; \
+ if(this->strings){ \
+ snprintf(tmp, 20, "%%%ds", this->maxvallen); \
+ if(*this->variable < this->lowerBound || *this->variable > this->upperBound){ \
+ snprintf(str, len, "ERROR"); \
+ return; \
+ } \
+ snprintf(str, len, tmp, this->strings[*this->variable-this->lowerBound]); \
+ }else \
+ snprintf(str, len, this->fmt, *this->variable); \
+} \
+void \
+MenuEntry_##NAME::setStrings(const char **strings) \
+{ \
+ this->strings = strings; \
+ if(this->strings) \
+ this->maxvallen = findStringLen(); \
+} \
+MenuEntry_##NAME::MenuEntry_##NAME(const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound, const char **strings) \
+: MenuEntry_Int(name) \
+{ \
+ this->variable = ptr; \
+ this->step = step; \
+ this->lowerBound = lowerBound; \
+ this->upperBound = upperBound; \
+ this->triggerFunc = triggerFunc; \
+ this->maxvallen = MAXLEN; \
+ this->fmt = FMT; \
+ this->setStrings(strings); \
+}
+INTTYPES
+#undef X
+
+/*
+ * *****************************
+ * MenuEntry_Float
+ * *****************************
+ */
+
+#define X(NAME, TYPE, MAXLEN, FMT) \
+MenuEntry_##NAME::MenuEntry_##NAME(const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound) \
+: MenuEntry_Var(name, MENUVAR_FLOAT) \
+{ \
+ this->variable = ptr; \
+ this->step = step; \
+ this->lowerBound = lowerBound; \
+ this->upperBound = upperBound; \
+ this->triggerFunc = triggerFunc; \
+ this->maxvallen = MAXLEN; \
+ this->fmt = FMT; \
+} \
+void \
+MenuEntry_##NAME::getValStr(char *str, int len) \
+{ \
+ snprintf(str, len, this->fmt, *this->variable); \
+} \
+void \
+MenuEntry_##NAME::processInput(bool mouseOver, bool selected) \
+{ \
+ float v, oldv; \
+ int overflow = 0; \
+ int underflow = 0; \
+ \
+ v = *this->variable; \
+ oldv = v; \
+ \
+ if((selected && leftjustdown) || (mouseOver && button3justdown)){ \
+ v -= this->step; \
+ if(v > oldv) \
+ underflow = 1; \
+ } \
+ if((selected && rightjustdown) || (mouseOver && button1justdown)){ \
+ v += this->step; \
+ if(v < oldv) \
+ overflow = 1; \
+ } \
+ if(this->wrapAround){ \
+ if(v > this->upperBound || overflow) v = this->lowerBound; \
+ if(v < this->lowerBound || underflow) v = this->upperBound; \
+ }else{ \
+ if(v > this->upperBound || overflow) v = this->upperBound; \
+ if(v < this->lowerBound || underflow) v = this->lowerBound; \
+ } \
+ \
+ *this->variable = v; \
+ if(oldv != v && this->triggerFunc) \
+ this->triggerFunc(); \
+}
+
+FLOATTYPES
+#undef X
+
+/*
+ * *****************************
+ * MenuEntry_Cmd
+ * *****************************
+ */
+
+void
+MenuEntry_Cmd::processInput(bool mouseOver, bool selected)
+{
+ // Don't execute on button3
+ if(this->triggerFunc && (selected && (leftjustdown || rightjustdown) || (mouseOver && button1justdown)))
+ this->triggerFunc();
+}
+
+void
+MenuEntry_Cmd::getValStr(char *str, int len)
+{
+ strncpy(str, "<", len);
+}
+
+MenuEntry_Cmd::MenuEntry_Cmd(const char *name, TriggerFunc triggerFunc)
+: MenuEntry_Var(name, MENUVAR_CMD)
+{
+ this->maxvallen = 1;
+ this->triggerFunc = triggerFunc;
+}
+
+
+/*
+ * *****************************
+ * Menu
+ * *****************************
+ */
+
+void
+Menu::scroll(int off) {
+ if(isScrollingUp && off < 0)
+ scrollStart += off;
+ if(isScrollingDown && off > 0)
+ scrollStart += off;
+ if(scrollStart < 0) scrollStart = 0;
+ if(scrollStart > numEntries-numVisible) scrollStart = numEntries-numVisible;
+}
+
+void
+Menu::changeSelection(int newsel){
+ selection = newsel;
+ if(selection < 0) selection = 0;
+ if(selection >= numEntries) selection = numEntries-1;
+ if(selection < scrollStart) scrollStart = selection;
+ if(selection >= scrollStart+numVisible) scrollStart = selection-numVisible+1;
+}
+
+void
+Menu::changeSelection(MenuEntry *sel)
+{
+ MenuEntry *e;
+ int i = 0;
+ for(e = this->entries; e; e = e->next){
+ if(e == sel){
+ this->selection = i;
+ this->selectedEntry = sel;
+ break;
+ }
+ i++;
+ }
+}
+
+
+
+MenuEntry*
+Menu::findEntry(const char *entryname)
+{
+ MenuEntry *m;
+ for(m = this->entries; m; m = m->next)
+ if(strcmp(entryname, m->name) == 0)
+ return m;
+ return nil;
+}
+
+void
+Menu::insertEntrySorted(MenuEntry *entry)
+{
+ MenuEntry **mp;
+ int cmp;
+ for(mp = &this->entries; *mp; mp = &(*mp)->next){
+ cmp = strcmp(entry->name, (*mp)->name);
+ if(cmp == 0)
+ return;
+ if(cmp < 0)
+ break;
+ }
+ entry->next = *mp;
+ *mp = entry;
+ entry->menu = this;
+ this->numEntries++;
+}
+
+void
+Menu::appendEntry(MenuEntry *entry)
+{
+ MenuEntry **mp;
+ for(mp = &this->entries; *mp; mp = &(*mp)->next);
+ entry->next = *mp;
+ *mp = entry;
+ entry->menu = this;
+ this->numEntries++;
+}
+
+void
+Menu::update(void)
+{
+ int i;
+ int x, y;
+ Pt sz;
+ MenuEntry *e;
+ int onscreen;
+ x = this->r.x;
+ y = this->r.y + 18;
+ int end = this->r.y+this->r.h - 18;
+ this->numVisible = 0;
+
+ deepestMenu = this;
+
+ int bottomy = end;
+ onscreen = 1;
+ i = 0;
+ this->maxNameWidth = 0;
+ this->maxValWidth = 0;
+ this->isScrollingUp = this->scrollStart > 0;
+ this->isScrollingDown = false;
+ this->selectedEntry = nil;
+ for(e = this->entries; e; e = e->next){
+ sz = fontGetStringSize(e->name);
+ e->r.x = x;
+ e->r.y = y;
+ e->r.w = sz.x;
+ e->r.h = sz.y;
+
+ if(i == this->selection)
+ this->selectedEntry = e;
+
+ if(i >= this->scrollStart)
+ y += sz.y + leading*fontscale;
+ if(y >= end){
+ this->isScrollingDown = true;
+ onscreen = 0;
+ }else
+ bottomy = y;
+ if(i >= this->scrollStart && onscreen)
+ this->numVisible++;
+
+ if(e->type == MENUVAR){
+ int valwidth = fontGetLen(((MenuEntry_Var*)e)->getValWidth());
+ if(valwidth > maxValWidth)
+ maxValWidth = valwidth;
+ }
+ if(e->r.w > maxNameWidth)
+ maxNameWidth = e->r.w;
+ i++;
+ }
+ if(this->r.w < maxNameWidth + maxValWidth + gap*fontscale)
+ this->r.w = maxNameWidth + maxValWidth + gap*fontscale;
+
+ this->scrollUpR = this->r;
+ this->scrollUpR.h = 16;
+ this->scrollDownR = this->scrollUpR;
+ this->scrollDownR.y = bottomy;
+
+ // Update active submenu
+ if(this->selectedEntry && this->selectedEntry->type == MENUSUB){
+ Menu *submenu = ((MenuEntry_Sub*)this->selectedEntry)->submenu;
+ submenu->r.x = this->r.x+this->r.w + 10;
+ submenu->r.y = this->r.y;
+ submenu->r.w = minwidth; // update menu will expand
+ submenu->r.h = this->r.h;
+ submenu->update();
+ }
+}
+
+void
+Menu::draw(void)
+{
+ static char val[100];
+ int i;
+ MenuEntry *e;
+ i = 0;
+ for(e = this->entries; e; e = e->next){
+ if(i >= this->scrollStart+this->numVisible)
+ break;
+ if(i >= this->scrollStart){
+ int style = MENUFONT_NORMAL;
+ if(i == this->selection)
+ style = this == activeMenu ? MENUFONT_SEL_ACTIVE : MENUFONT_SEL_INACTIVE;
+ if(style != MENUFONT_SEL_ACTIVE && e == mouseOverEntry)
+ style = MENUFONT_MOUSE;
+ fontPrint(e->name, e->r.x, e->r.y, style);
+ if(e->type == MENUVAR){
+ int valw = fontGetLen(((MenuEntry_Var*)e)->getValWidth());
+ ((MenuEntry_Var*)e)->getValStr(val, 100);
+ fontPrint(val, e->r.x+this->r.w-valw, e->r.y, style);
+ }
+ }
+ i++;
+ }
+
+ if(this->isScrollingUp)
+ drawArrow(this->scrollUpR, -1, isMouseInRect(this->scrollUpR));
+ if(this->isScrollingDown)
+ drawArrow(this->scrollDownR, 1, isMouseInRect(this->scrollDownR));
+
+ if(this->selectedEntry && this->selectedEntry->type == MENUSUB)
+ ((MenuEntry_Sub*)this->selectedEntry)->submenu->draw();
+}
+
+Menu*
+findMenu(const char *name)
+{
+ Menu *m;
+ MenuEntry *e;
+ char *tmppath = strdup(name);
+ char *next, *curname;
+
+ curname = tmppath;
+ next = curname;
+
+ m = &toplevel;
+ while(*next){
+ curname = next;
+ while(*next){
+ if(*next == '|'){
+ *next++ = '\0';
+ break;
+ }
+ next++;
+ }
+ e = m->findEntry(curname);
+ if(e){
+ // return an error if the entry exists but isn't a menu
+ if(e->type != MENUSUB){
+ free(tmppath);
+ return nil;
+ }
+ m = ((MenuEntry_Sub*)e)->submenu;
+ }else{
+ // Create submenus that don't exist yet
+ Menu *submenu = new Menu();
+ submenu->parent = m;
+ MenuEntry *me = new MenuEntry_Sub(curname, submenu);
+ // Don't sort submenus outside the toplevel menu
+ if(m == &toplevel)
+ m->insertEntrySorted(me);
+ else
+ m->appendEntry(me);
+ m = submenu;
+ }
+ }
+
+ free(tmppath);
+ return m;
+}
+
+/*
+ * ****************
+ * debug menu
+ * ****************
+ */
+
+static uint8 cursorPx[] = {
+#include "cursor.inc"
+};
+
+static uint8 arrowPx[] = {
+#include "arrow.inc"
+};
+
+void
+DebugMenuInit(void)
+{
+ createMenuFont();
+
+ RwInt32 w, h, d, flags;
+ RwImage *img = RwImageCreate(16, 16, 32);
+ assert(img);
+ RwImageSetPixels(img, cursorPx);
+ RwImageSetStride(img, RwImageGetWidth(img)*4);
+ RwImageFindRasterFormat(img, rwRASTERTYPETEXTURE, &w, &h, &d, &flags);
+ cursor = RwRasterCreate(w, h, d, flags);
+ cursor = RwRasterSetFromImage(cursor, img);
+ assert(cursor);
+ RwImageDestroy(img);
+
+ img = RwImageCreate(32, 16, 32);
+ assert(img);
+ RwImageSetPixels(img, arrowPx);
+ RwImageSetStride(img, RwImageGetWidth(img)*4);
+ RwImageFindRasterFormat(img, rwRASTERTYPETEXTURE, &w, &h, &d, &flags);
+ arrow = RwRasterCreate(w, h, d, flags);
+ arrow = RwRasterSetFromImage(arrow, img);
+ assert(arrow);
+ RwImageDestroy(img);
+
+ menuInitialized = true;
+}
+
+void
+DebugMenuShutdown(void)
+{
+ if(menuInitialized){
+ destroyMenuFont();
+ RwRasterDestroy(cursor);
+ cursor = nil;
+ RwRasterDestroy(arrow);
+ arrow = nil;
+ // TODO: the menus ...
+ }
+ menuInitialized = false;
+}
+
+void
+processInput(void)
+{
+ int shift = KEYDOWN(rsRSHIFT) || KEYDOWN(rsLSHIFT);
+#define X(var, keycode) var = KEYJUSTDOWN(keycode);
+ MUHKEYS
+#undef X
+
+ // Implement auto-repeat
+#define X(var, keycode) \
+ if(var){ \
+ repeattime = downtime = CTimer::GetTimeInMilliseconds(); \
+ lastkeydown = keycode; \
+ keyptr = &var; \
+ }
+ MUHKEYS
+#undef X
+ if(lastkeydown){
+ if(KEYDOWN(lastkeydown)){
+ int curtime = CTimer::GetTimeInMilliseconds();
+ if(curtime - downtime > REPEATDELAY){
+ if(curtime - repeattime > REPEATINTERVAL){
+ repeattime = curtime;
+ *keyptr = 1;
+ }
+ }
+ }else{
+ lastkeydown = 0;
+ }
+ }
+
+ // Also for mouse buttons
+#define X(var, num) \
+ if(var){ \
+ repeattime = downtime = CTimer::GetTimeInMilliseconds(); \
+ lastbuttondown = num; \
+ buttonptr = &var; \
+ }
+ MUHBUTTONS
+#undef X
+ if(lastbuttondown){
+ if(buttondown[lastbuttondown-1]){
+ int curtime = CTimer::GetTimeInMilliseconds();
+ if(curtime - downtime > REPEATDELAY){
+ if(curtime - repeattime > REPEATINTERVAL){
+ repeattime = curtime;
+ *buttonptr = 1;
+ }
+ }
+ }else{
+ lastbuttondown = 0;
+ }
+ }
+
+ // Walk through all visible menus and figure out which one the mouse is over
+ mouseOverMenu = nil;
+ mouseOverEntry = nil;
+ Menu *menu;
+ for(menu = deepestMenu; menu; menu = menu->parent)
+ if(isMouseInRect(menu->r)){
+ mouseOverMenu = menu;
+ break;
+ }
+ if(mouseOverMenu){
+ // Walk all visibile entries and figure out which one the mouse is over
+ MenuEntry *e;
+ int i = 0;
+ for(e = mouseOverMenu->entries; e; e = e->next){
+ if(i >= mouseOverMenu->scrollStart+mouseOverMenu->numVisible)
+ break;
+ if(i >= mouseOverMenu->scrollStart){
+ RwRect r = e->r;
+ r.w = mouseOverMenu->r.w; // span the whole menu
+ if(isMouseInRect(r)){
+ mouseOverEntry = e;
+ break;
+ }
+ }
+ i++;
+ }
+ if(mouseOverMenu->isScrollingUp && isMouseInRect(mouseOverMenu->scrollUpR)){
+ mouseOverEntry = &scrollUpEntry;
+ mouseOverEntry->r = mouseOverMenu->scrollUpR;
+ mouseOverEntry->menu = mouseOverMenu;
+ mouseOverEntry->type = MENUSCROLL;
+ }
+ if(mouseOverMenu->isScrollingDown && isMouseInRect(mouseOverMenu->scrollDownR)){
+ mouseOverEntry = &scrollDownEntry;
+ mouseOverEntry->r = mouseOverMenu->scrollDownR;
+ mouseOverEntry->menu = mouseOverMenu;
+ mouseOverEntry->type = MENUSCROLL;
+ }
+ }
+
+ if(pgupjustdown)
+ activeMenu->scroll(shift ? -5 : -1);
+ if(pgdnjustdown)
+ activeMenu->scroll(shift ? 5 : 1);
+ if(downjustdown)
+ activeMenu->changeSelection(activeMenu->selection + (shift ? 5 : 1));
+ if(upjustdown)
+ activeMenu->changeSelection(activeMenu->selection - (shift ? 5 : 1));
+
+ if(CPad::NewMouseControllerState.WHEELUP){
+ if(mouseOverMenu)
+ activeMenu = mouseOverMenu;
+ activeMenu->scroll(shift ? -5 : -1);
+ }
+ if(CPad::NewMouseControllerState.WHEELDN){
+ if(mouseOverMenu)
+ activeMenu = mouseOverMenu;
+ activeMenu->scroll(shift ? 5 : 1);
+ }
+
+ if(mouseOverEntry == &scrollUpEntry){
+ if(button1justdown){
+ activeMenu = mouseOverEntry->menu;
+ activeMenu->scroll(shift ? -5 : -1);
+ }
+ }
+ if(mouseOverEntry == &scrollDownEntry){
+ if(button1justdown){
+ activeMenu = mouseOverEntry->menu;
+ activeMenu->scroll(shift ? 5 : 1);
+ }
+ }
+
+ // Have to call this before processInput below because menu entry can change
+ if((button1justdown || button3justdown) && mouseOverEntry){
+ activeMenu = mouseOverEntry->menu;
+ activeMenu->changeSelection(mouseOverEntry);
+ }
+ if(KEYJUSTDOWN(rsENTER)){
+ if(activeMenu->selectedEntry && activeMenu->selectedEntry->type == MENUSUB)
+ activeMenu = ((MenuEntry_Sub*)activeMenu->selectedEntry)->submenu;
+ }else if(KEYJUSTDOWN(rsBACKSP)){
+ if(activeMenu->parent)
+ activeMenu = activeMenu->parent;
+ }else{
+ if(mouseOverEntry && mouseOverEntry->type == MENUVAR)
+ ((MenuEntry_Var*)mouseOverEntry)->processInput(true, mouseOverEntry == activeMenu->selectedEntry);
+ if(activeMenu->selectedEntry && activeMenu->selectedEntry->type == MENUVAR &&
+ mouseOverEntry != activeMenu->selectedEntry)
+ ((MenuEntry_Var*)activeMenu->selectedEntry)->processInput(false, true);
+ }
+}
+
+void
+updateMouse(void)
+{
+ CPad *pad = CPad::GetPad(0);
+ int dirX = 1;
+ int dirY = 1;
+
+ if(MousePointerStateHelper.bInvertHorizontally) dirX = -1;
+ if(MousePointerStateHelper.bInvertVertically) dirY = -1;
+
+ mouseX += pad->NewMouseControllerState.x*dirX;
+ mouseY += pad->NewMouseControllerState.y*dirY;
+
+ if(mouseX < 0.0f) mouseX = 0.0f;
+ if(mouseY < 0.0f) mouseY = 0.0f;
+ if(mouseX >= screenWidth) mouseX = screenWidth;
+ if(mouseY >= screenHeight) mouseY = screenHeight;
+
+ button1justdown = pad->NewMouseControllerState.LMB && !pad->OldMouseControllerState.LMB;
+ button2justdown = pad->NewMouseControllerState.MMB && !pad->OldMouseControllerState.MMB;
+ button3justdown = pad->NewMouseControllerState.RMB && !pad->OldMouseControllerState.RMB;
+ buttondown[0] = pad->NewMouseControllerState.LMB;
+ buttondown[1] = pad->NewMouseControllerState.MMB;
+ buttondown[2] = pad->NewMouseControllerState.RMB;
+
+ // Zero the mouse position so the camera won't move
+ pad->NewMouseControllerState.x = 0.0f;
+ pad->NewMouseControllerState.y = 0.0f;
+}
+
+void
+DebugMenuProcess(void)
+{
+ // We only process some input here
+
+ CPad *pad = CPad::GetPad(0);
+ if(CTRLJUSTDOWN('M'))
+ menuOn = !menuOn;
+ if(!menuOn)
+ return;
+
+ pad->DisablePlayerControls = 1;
+ // TODO: this could happen earlier
+ if(!menuInitialized)
+ DebugMenuInit();
+ updateMouse();
+
+}
+
+#ifdef LIBRW
+#define CURRENTCAM (rw::engine->currentCamera)
+#else
+#define CURRENTCAM ((RwCamera*)RWSRCGLOBAL(curCamera))
+#endif
+
+void
+DebugMenuRender(void)
+{
+ if(!menuOn)
+ return;
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, 0);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0);
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+
+ RwCamera *cam = CURRENTCAM;
+ screenWidth = RwRasterGetWidth(RwCameraGetRaster(cam));
+ screenHeight = RwRasterGetHeight(RwCameraGetRaster(cam));
+
+// if(screenHeight > 1080)
+// fontscale = 2;
+// else
+ fontscale = 1;
+
+ Pt sz;
+ sz = fontPrint("Debug Menu", firstBorder*fontscale+30, topBorder, 0);
+
+ toplevel.r.x = firstBorder*fontscale;
+ toplevel.r.y = topBorder + sz.y + 10;
+ toplevel.r.w = minwidth; // update menu will expand
+ toplevel.r.h = screenHeight - 10 - toplevel.r.y;
+ toplevel.update();
+ toplevel.draw();
+ processInput();
+ RtCharsetBufferFlush();
+
+ drawMouse();
+}
+
+
+
+void
+drawArrow(RwRect r, int direction, int style)
+{
+ static RwImVertexIndex indices[] = { 0, 1, 2, 2, 1, 3 };
+ static RwIm2DVertex arrowVerts[4];
+
+ RwCamera *cam = CURRENTCAM;
+ float recipz = 1.0f/RwCameraGetNearClipPlane(cam);
+
+ int width = RwRasterGetWidth(arrow);
+ int height = RwRasterGetHeight(arrow);
+
+ int left = r.x + (r.w - width)/2;
+ int right = left + width;
+ int top = r.y;
+ int bottom = r.y+r.h;
+
+ float umin = 0.5f / width;
+ float vmin = 0.5f / height;
+ float umax = (width + 0.5f) / width;
+ float vmax = (height + 0.5f) / height;
+ if(direction < 0){
+ vmin = (height - 0.5f) / height;
+ vmax = -0.5f / height;
+ }
+
+ if(style){
+ RwIm2DVertexSetScreenX(&arrowVerts[0], r.x);
+ RwIm2DVertexSetScreenY(&arrowVerts[0], r.y-1);
+ RwIm2DVertexSetScreenZ(&arrowVerts[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[0], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[0], 132, 132, 132, 255);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[1], r.x+r.w);
+ RwIm2DVertexSetScreenY(&arrowVerts[1], r.y-1);
+ RwIm2DVertexSetScreenZ(&arrowVerts[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[1], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[1], 132, 132, 132, 255);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[2], r.x);
+ RwIm2DVertexSetScreenY(&arrowVerts[2], r.y+r.h+1);
+ RwIm2DVertexSetScreenZ(&arrowVerts[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[2], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[2], 132, 132, 132, 255);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[3], r.x+r.w);
+ RwIm2DVertexSetScreenY(&arrowVerts[3], r.y+r.h+1);
+ RwIm2DVertexSetScreenZ(&arrowVerts[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[3], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[3], 132, 132, 132, 255);
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, arrowVerts, 4, indices, 6);
+ }
+
+
+ RwIm2DVertexSetScreenX(&arrowVerts[0], left);
+ RwIm2DVertexSetScreenY(&arrowVerts[0], top);
+ RwIm2DVertexSetScreenZ(&arrowVerts[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[0], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[0], 255, 255, 255, 255);
+ RwIm2DVertexSetU(&arrowVerts[0], umin, recipz);
+ RwIm2DVertexSetV(&arrowVerts[0], vmin, recipz);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[1], right);
+ RwIm2DVertexSetScreenY(&arrowVerts[1], top);
+ RwIm2DVertexSetScreenZ(&arrowVerts[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[1], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[1], 255, 255, 255, 255);
+ RwIm2DVertexSetU(&arrowVerts[1], umax, recipz);
+ RwIm2DVertexSetV(&arrowVerts[1], vmin, recipz);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[2], left);
+ RwIm2DVertexSetScreenY(&arrowVerts[2], bottom);
+ RwIm2DVertexSetScreenZ(&arrowVerts[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[2], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[2], 255, 255, 255, 255);
+ RwIm2DVertexSetU(&arrowVerts[2], umin, recipz);
+ RwIm2DVertexSetV(&arrowVerts[2], vmax, recipz);
+
+ RwIm2DVertexSetScreenX(&arrowVerts[3], right);
+ RwIm2DVertexSetScreenY(&arrowVerts[3], bottom);
+ RwIm2DVertexSetScreenZ(&arrowVerts[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&arrowVerts[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&arrowVerts[3], recipz);
+ RwIm2DVertexSetIntRGBA(&arrowVerts[3], 255, 255, 255, 255);
+ RwIm2DVertexSetU(&arrowVerts[3], umax, recipz);
+ RwIm2DVertexSetV(&arrowVerts[3], vmax, recipz);
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, arrow);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, arrowVerts, 4, indices, 6);
+}
+
+void
+drawMouse(void)
+{
+ static RwImVertexIndex indices[] = { 0, 1, 2, 2, 1, 3 };
+ static RwIm2DVertex vertices[4];
+ RwIm2DVertex *vert;
+ RwCamera *cam;
+ cam = CURRENTCAM;
+ float x = mouseX;
+ float y = mouseY;
+ float w = RwRasterGetWidth(cursor);
+ float h = RwRasterGetHeight(cursor);
+ float recipz = 1.0f/RwCameraGetNearClipPlane(cam);
+
+ float umin = 0.5f / w;
+ float vmin = 0.5f / h;
+ float umax = (w + 0.5f) / w;
+ float vmax = (h + 0.5f) / h;
+
+ vert = vertices;
+ RwIm2DVertexSetScreenX(vert, x);
+ RwIm2DVertexSetScreenY(vert, y);
+ RwIm2DVertexSetScreenZ(vert, RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(vert, RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(vert, recipz);
+ RwIm2DVertexSetIntRGBA(vert, 255, 255, 255, 255);
+ RwIm2DVertexSetU(vert, umin, recipz);
+ RwIm2DVertexSetV(vert, vmin, recipz);
+ vert++;
+
+ RwIm2DVertexSetScreenX(vert, x+w);
+ RwIm2DVertexSetScreenY(vert, y);
+ RwIm2DVertexSetScreenZ(vert, RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(vert, RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(vert, recipz);
+ RwIm2DVertexSetIntRGBA(vert, 255, 255, 255, 255);
+ RwIm2DVertexSetU(vert, umax, recipz);
+ RwIm2DVertexSetV(vert, vmin, recipz);
+ vert++;
+
+ RwIm2DVertexSetScreenX(vert, x);
+ RwIm2DVertexSetScreenY(vert, y+h);
+ RwIm2DVertexSetScreenZ(vert, RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(vert, RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(vert, recipz);
+ RwIm2DVertexSetIntRGBA(vert, 255, 255, 255, 255);
+ RwIm2DVertexSetU(vert, umin, recipz);
+ RwIm2DVertexSetV(vert, vmax, recipz);
+ vert++;
+
+ RwIm2DVertexSetScreenX(vert, x+w);
+ RwIm2DVertexSetScreenY(vert, y+h);
+ RwIm2DVertexSetScreenZ(vert, RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(vert, RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(vert, recipz);
+ RwIm2DVertexSetIntRGBA(vert, 255, 255, 255, 255);
+ RwIm2DVertexSetU(vert, umax, recipz);
+ RwIm2DVertexSetV(vert, vmax, recipz);
+ vert++;
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, cursor);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, vertices, 4, indices, 6);
+}
+
+
+
+
+/*
+ * Generate interfaces
+ */
+
+
+#define X(NAME, TYPE, unused1, unused2) \
+MenuEntry* \
+DebugMenuAdd##NAME(const char *path, const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound, const char **strings) \
+{ \
+ Menu *m = findMenu(path); \
+ if(m == nil) \
+ return nil; \
+ MenuEntry *e = new MenuEntry_##NAME(name, ptr, triggerFunc, step, lowerBound, upperBound, strings); \
+ m->appendEntry(e); \
+ return e; \
+}
+INTTYPES
+#undef X
+
+#define X(NAME, TYPE, unused1, unused2) \
+MenuEntry* \
+DebugMenuAdd##NAME(const char *path, const char *name, TYPE *ptr, TriggerFunc triggerFunc, TYPE step, TYPE lowerBound, TYPE upperBound) \
+{ \
+ Menu *m = findMenu(path); \
+ if(m == nil) \
+ return nil; \
+ MenuEntry *e = new MenuEntry_##NAME(name, ptr, triggerFunc, step, lowerBound, upperBound); \
+ m->appendEntry(e); \
+ return e; \
+}
+FLOATTYPES
+#undef X
+
+MenuEntry* \
+DebugMenuAddCmd(const char *path, const char *name, TriggerFunc triggerFunc)
+{
+ Menu *m = findMenu(path);
+ if(m == nil)
+ return nil;
+ MenuEntry *e = new MenuEntry_Cmd(name, triggerFunc);
+ m->appendEntry(e);
+ return e;
+}
+
+void
+DebugMenuEntrySetWrap(MenuEntry *e, bool wrap)
+{
+ if(e && e->type == MENUVAR)
+ ((MenuEntry_Var*)e)->wrapAround = wrap;
+}
+
+void
+DebugMenuEntrySetStrings(MenuEntry *e, const char **strings)
+{
+ if(e && e->type == MENUVAR_INT)
+ ((MenuEntry_Int*)e)->setStrings(strings);
+}
+
+void
+DebugMenuEntrySetAddress(MenuEntry *e, void *addr)
+{
+ if(e && e->type == MENUVAR){
+ MenuEntry_Var *ev = (MenuEntry_Var*)e;
+ // HACK - we know the variable field is at the same address
+ // for all int/float classes. let's hope it stays that way.
+ if(ev->vartype = MENUVAR_INT)
+ ((MenuEntry_Int32*)e)->variable = (int32*)addr;
+ else if(ev->vartype = MENUVAR_FLOAT)
+ ((MenuEntry_Float32*)e)->variable = (float*)addr;
+ }
+}
diff --git a/src/extras/debugmenu.h b/src/extras/debugmenu.h
new file mode 100644
index 00000000..462b59c4
--- /dev/null
+++ b/src/extras/debugmenu.h
@@ -0,0 +1,86 @@
+#pragma once
+
+typedef void (*TriggerFunc)(void);
+
+struct Menu;
+
+struct MenuEntry
+{
+ int type;
+ const char *name;
+ MenuEntry *next;
+ RwRect r;
+ Menu *menu;
+
+ MenuEntry(const char *name);
+};
+
+typedef MenuEntry DebugMenuEntry;
+
+MenuEntry *DebugMenuAddInt8(const char *path, const char *name, int8 *ptr, TriggerFunc triggerFunc, int8 step, int8 lowerBound, int8 upperBound, const char **strings);
+MenuEntry *DebugMenuAddInt16(const char *path, const char *name, int16 *ptr, TriggerFunc triggerFunc, int16 step, int16 lowerBound, int16 upperBound, const char **strings);
+MenuEntry *DebugMenuAddInt32(const char *path, const char *name, int32 *ptr, TriggerFunc triggerFunc, int32 step, int32 lowerBound, int32 upperBound, const char **strings);
+MenuEntry *DebugMenuAddInt64(const char *path, const char *name, int64 *ptr, TriggerFunc triggerFunc, int64 step, int64 lowerBound, int64 upperBound, const char **strings);
+MenuEntry *DebugMenuAddUInt8(const char *path, const char *name, uint8 *ptr, TriggerFunc triggerFunc, uint8 step, uint8 lowerBound, uint8 upperBound, const char **strings);
+MenuEntry *DebugMenuAddUInt16(const char *path, const char *name, uint16 *ptr, TriggerFunc triggerFunc, uint16 step, uint16 lowerBound, uint16 upperBound, const char **strings);
+MenuEntry *DebugMenuAddUInt32(const char *path, const char *name, uint32 *ptr, TriggerFunc triggerFunc, uint32 step, uint32 lowerBound, uint32 upperBound, const char **strings);
+MenuEntry *DebugMenuAddUInt64(const char *path, const char *name, uint64 *ptr, TriggerFunc triggerFunc, uint64 step, uint64 lowerBound, uint64 upperBound, const char **strings);
+MenuEntry *DebugMenuAddFloat32(const char *path, const char *name, float *ptr, TriggerFunc triggerFunc, float step, float lowerBound, float upperBound);
+MenuEntry *DebugMenuAddFloat64(const char *path, const char *name, double *ptr, TriggerFunc triggerFunc, double step, double lowerBound, double upperBound);
+MenuEntry *DebugMenuAddCmd(const char *path, const char *name, TriggerFunc triggerFunc);
+void DebugMenuEntrySetWrap(MenuEntry *e, bool wrap);
+void DebugMenuEntrySetStrings(MenuEntry *e, const char **strings);
+void DebugMenuEntrySetAddress(MenuEntry *e, void *addr);
+void DebugMenuInit(void);
+void DebugMenuShutdown(void);
+void DebugMenuProcess(void);
+void DebugMenuRender(void);
+
+
+// Some overloads for simplicity
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc, int8_t step, int8_t lowerBound, int8_t upperBound, const char **strings)
+{ return DebugMenuAddInt8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc, int16_t step, int16_t lowerBound, int16_t upperBound, const char **strings)
+{ return DebugMenuAddInt16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc, int32_t step, int32_t lowerBound, int32_t upperBound, const char **strings)
+{ return DebugMenuAddInt32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, int64_t *ptr, TriggerFunc triggerFunc, int64_t step, int64_t lowerBound, int64_t upperBound, const char **strings)
+{ return DebugMenuAddInt64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint8_t *ptr, TriggerFunc triggerFunc, uint8_t step, uint8_t lowerBound, uint8_t upperBound, const char **strings)
+{ return DebugMenuAddUInt8(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint16_t *ptr, TriggerFunc triggerFunc, uint16_t step, uint16_t lowerBound, uint16_t upperBound, const char **strings)
+{ return DebugMenuAddUInt16(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint32_t *ptr, TriggerFunc triggerFunc, uint32_t step, uint32_t lowerBound, uint32_t upperBound, const char **strings)
+{ return DebugMenuAddUInt32(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, uint64_t *ptr, TriggerFunc triggerFunc, uint64_t step, uint64_t lowerBound, uint64_t upperBound, const char **strings)
+{ return DebugMenuAddUInt64(path, name, ptr, triggerFunc, step, lowerBound, upperBound, strings); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, float *ptr, TriggerFunc triggerFunc, float step, float lowerBound, float upperBound)
+{ return DebugMenuAddFloat32(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
+inline DebugMenuEntry *DebugMenuAddVar(const char *path, const char *name, double *ptr, TriggerFunc triggerFunc, double step, double lowerBound, double upperBound)
+{ return DebugMenuAddFloat64(path, name, ptr, triggerFunc, step, lowerBound, upperBound); }
+
+inline DebugMenuEntry *DebugMenuAddVarBool32(const char *path, const char *name, int32_t *ptr, TriggerFunc triggerFunc)
+{
+ static const char *boolstr[] = { "Off", "On" };
+ DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
+ DebugMenuEntrySetWrap(e, true);
+ return e;
+}
+inline DebugMenuEntry *DebugMenuAddVarBool16(const char *path, const char *name, int16_t *ptr, TriggerFunc triggerFunc)
+{
+ static const char *boolstr[] = { "Off", "On" };
+ DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
+ DebugMenuEntrySetWrap(e, true);
+ return e;
+}
+inline DebugMenuEntry *DebugMenuAddVarBool8(const char *path, const char *name, int8_t *ptr, TriggerFunc triggerFunc)
+{
+ static const char *boolstr[] = { "Off", "On" };
+ DebugMenuEntry *e = DebugMenuAddVar(path, name, ptr, triggerFunc, 1, 0, 1, boolstr);
+ DebugMenuEntrySetWrap(e, true);
+ return e;
+}
+inline DebugMenuEntry *DebugMenuAddVarBool8(const char *path, const char *name, bool *ptr, TriggerFunc triggerFunc)
+{
+ return DebugMenuAddVarBool8(path, name, (int8_t*)ptr, triggerFunc);
+}
diff --git a/src/extras/inttypes.h b/src/extras/inttypes.h
new file mode 100644
index 00000000..bf0c53e2
--- /dev/null
+++ b/src/extras/inttypes.h
@@ -0,0 +1,216 @@
+#define PRId8 "hhd"
+#define PRId16 "hd"
+#define PRId32 "ld"
+#define PRId64 "lld"
+
+#define PRIdFAST8 "hhd"
+#define PRIdFAST16 "hd"
+#define PRIdFAST32 "ld"
+#define PRIdFAST64 "lld"
+
+#define PRIdLEAST8 "hhd"
+#define PRIdLEAST16 "hd"
+#define PRIdLEAST32 "ld"
+#define PRIdLEAST64 "lld"
+
+#define PRIdMAX "lld"
+#define PRIdPTR "lld"
+
+#define PRIi8 "hhi"
+#define PRIi16 "hi"
+#define PRIi32 "li"
+#define PRIi64 "lli"
+
+#define PRIiFAST8 "hhi"
+#define PRIiFAST16 "hi"
+#define PRIiFAST32 "li"
+#define PRIiFAST64 "lli"
+
+#define PRIiLEAST8 "hhi"
+#define PRIiLEAST16 "hi"
+#define PRIiLEAST32 "li"
+#define PRIiLEAST64 "lli"
+
+#define PRIiMAX "lli"
+#define PRIiPTR "lli"
+
+#define PRIo8 "hho"
+#define PRIo16 "ho"
+#define PRIo32 "lo"
+#define PRIo64 "llo"
+
+#define PRIoFAST8 "hho"
+#define PRIoFAST16 "ho"
+#define PRIoFAST32 "lo"
+#define PRIoFAST64 "llo"
+
+#define PRIoLEAST8 "hho"
+#define PRIoLEAST16 "ho"
+#define PRIoLEAST32 "lo"
+#define PRIoLEAST64 "llo"
+
+#define PRIoMAX "llo"
+#define PRIoPTR "llo"
+
+#define PRIu8 "hhu"
+#define PRIu16 "hu"
+#define PRIu32 "lu"
+#define PRIu64 "llu"
+
+#define PRIuFAST8 "hhu"
+#define PRIuFAST16 "hu"
+#define PRIuFAST32 "lu"
+#define PRIuFAST64 "llu"
+
+#define PRIuLEAST8 "hhu"
+#define PRIuLEAST16 "hu"
+#define PRIuLEAST32 "lu"
+#define PRIuLEAST64 "llu"
+
+#define PRIuMAX "llu"
+#define PRIuPTR "llu"
+
+#define PRIx8 "hhx"
+#define PRIx16 "hx"
+#define PRIx32 "lx"
+#define PRIx64 "llx"
+
+#define PRIxFAST8 "hhx"
+#define PRIxFAST16 "hx"
+#define PRIxFAST32 "lx"
+#define PRIxFAST64 "llx"
+
+#define PRIxLEAST8 "hhx"
+#define PRIxLEAST16 "hx"
+#define PRIxLEAST32 "lx"
+#define PRIxLEAST64 "llx"
+
+#define PRIxMAX "llx"
+#define PRIxPTR "llx"
+
+#define PRIX8 "hhX"
+#define PRIX16 "hX"
+#define PRIX32 "lX"
+#define PRIX64 "llX"
+
+#define PRIXFAST8 "hhX"
+#define PRIXFAST16 "hX"
+#define PRIXFAST32 "lX"
+#define PRIXFAST64 "llX"
+
+#define PRIXLEAST8 "hhX"
+#define PRIXLEAST16 "hX"
+#define PRIXLEAST32 "lX"
+#define PRIXLEAST64 "llX"
+
+#define PRIXMAX "llX"
+#define PRIXPTR "llX"
+
+ /* SCAN FORMAT MACROS */
+#define SCNd8 "hhd"
+#define SCNd16 "hd"
+#define SCNd32 "ld"
+#define SCNd64 "lld"
+
+#define SCNdFAST8 "hhd"
+#define SCNdFAST16 "hd"
+#define SCNdFAST32 "ld"
+#define SCNdFAST64 "lld"
+
+#define SCNdLEAST8 "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "ld"
+#define SCNdLEAST64 "lld"
+
+#define SCNdMAX "lld"
+#define SCNdPTR "lld"
+
+#define SCNi8 "hhi"
+#define SCNi16 "hi"
+#define SCNi32 "li"
+#define SCNi64 "lli"
+
+#define SCNiFAST8 "hhi"
+#define SCNiFAST16 "hi"
+#define SCNiFAST32 "li"
+#define SCNiFAST64 "lli"
+
+#define SCNiLEAST8 "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "li"
+#define SCNiLEAST64 "lli"
+
+#define SCNiMAX "lli"
+#define SCNiPTR "lli"
+
+#define SCNo8 "hho"
+#define SCNo16 "ho"
+#define SCNo32 "lo"
+#define SCNo64 "llo"
+
+#define SCNoFAST8 "hho"
+#define SCNoFAST16 "ho"
+#define SCNoFAST32 "lo"
+#define SCNoFAST64 "llo"
+
+#define SCNoLEAST8 "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "lo"
+#define SCNoLEAST64 "llo"
+
+#define SCNoMAX "llo"
+#define SCNoPTR "llo"
+
+#define SCNu8 "hhu"
+#define SCNu16 "hu"
+#define SCNu32 "lu"
+#define SCNu64 "llu"
+
+#define SCNuFAST8 "hhu"
+#define SCNuFAST16 "hu"
+#define SCNuFAST32 "lu"
+#define SCNuFAST64 "llu"
+
+#define SCNuLEAST8 "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "lu"
+#define SCNuLEAST64 "llu"
+
+#define SCNuMAX "llu"
+#define SCNuPTR "llu"
+
+#define SCNx8 "hhx"
+#define SCNx16 "hx"
+#define SCNx32 "lx"
+#define SCNx64 "llx"
+
+#define SCNxFAST8 "hhx"
+#define SCNxFAST16 "hx"
+#define SCNxFAST32 "lx"
+#define SCNxFAST64 "llx"
+
+#define SCNxLEAST8 "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "lx"
+#define SCNxLEAST64 "llx"
+
+#define SCNxMAX "llx"
+#define SCNxPTR "llx"
+
+#define SCNX8 "hhX"
+#define SCNX16 "hX"
+#define SCNX32 "lX"
+#define SCNX64 "llX"
+
+#define SCNXFAST8 "hhX"
+#define SCNXFAST16 "hX"
+#define SCNXFAST32 "lX"
+#define SCNXFAST64 "llX"
+
+#define SCNXLEAST8 "hhX"
+#define SCNXLEAST16 "hX"
+#define SCNXLEAST32 "lX"
+#define SCNXLEAST64 "llX"
+
+#define SCNXMAX "llX"
+#define SCNXPTR "llX" \ No newline at end of file
diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp
new file mode 100644
index 00000000..26b5ae3d
--- /dev/null
+++ b/src/fakerw/fake.cpp
@@ -0,0 +1,833 @@
+#define _CRT_SECURE_NO_WARNINGS
+#define WITH_D3D
+#include <rwcore.h>
+#include <rpworld.h>
+#include <rpmatfx.h>
+#include <rphanim.h>
+#include <rpskin.h>
+#include <assert.h>
+#include <string.h>
+
+using namespace rw;
+
+RwUInt8 RwObjectGetType(const RwObject *obj) { return obj->type; }
+
+
+void *RwMalloc(size_t size) { return malloc(size); }
+void *RwCalloc(size_t numObj, size_t sizeObj) { return calloc(numObj, sizeObj); }
+void RwFree(void *mem) { free(mem); }
+
+
+//RwReal RwV3dNormalize(RwV3d * out, const RwV3d * in);
+RwReal RwV3dLength(const RwV3d * in) { return length(*in); }
+//RwReal RwV2dLength(const RwV2d * in);
+//RwReal RwV2dNormalize(RwV2d * out, const RwV2d * in);
+//void RwV2dAssign(RwV2d * out, const RwV2d * ina);
+//void RwV2dAdd(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+//void RwV2dLineNormal(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+//void RwV2dSub(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+//void RwV2dPerp(RwV2d * out, const RwV2d * in);
+//void RwV2dScale(RwV2d * out, const RwV2d * in, RwReal scalar);
+//RwReal RwV2dDotProduct(const RwV2d * ina, const RwV2d * inb);
+//void RwV3dAssign(RwV3d * out, const RwV3d * ina);
+void RwV3dAdd(RwV3d * out, const RwV3d * ina, const RwV3d * inb) { *out = add(*ina, *inb); }
+void RwV3dSub(RwV3d * out, const RwV3d * ina, const RwV3d * inb) { *out = sub(*ina, *inb); }
+//void RwV3dScale(RwV3d * out, const RwV3d * in, RwReal scalar);
+//void RwV3dIncrementScaled(RwV3d * out, const RwV3d * in, RwReal scalar);
+//void RwV3dNegate(RwV3d * out, const RwV3d * in);
+RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb) { return dot(*ina, *inb); }
+//void RwV3dCrossProduct(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
+RwV3d *RwV3dTransformPoints(RwV3d * pointsOut, const RwV3d * pointsIn, RwInt32 numPoints, const RwMatrix * matrix)
+ { V3d::transformPoints(pointsOut, pointsIn, numPoints, matrix); return pointsOut; }
+//RwV3d *RwV3dTransformVectors(RwV3d * vectorsOut, const RwV3d * vectorsIn, RwInt32 numPoints, const RwMatrix * matrix);
+
+
+
+RwBool RwMatrixDestroy(RwMatrix *mpMat) { mpMat->destroy(); return true; }
+RwMatrix *RwMatrixCreate(void) { return Matrix::create(); }
+void RwMatrixCopy(RwMatrix * dstMatrix, const RwMatrix * srcMatrix) { *dstMatrix = *srcMatrix; }
+void RwMatrixSetIdentity(RwMatrix * matrix) { matrix->setIdentity(); }
+RwMatrix *RwMatrixMultiply(RwMatrix * matrixOut, const RwMatrix * MatrixIn1, const RwMatrix * matrixIn2);
+RwMatrix *RwMatrixTransform(RwMatrix * matrix, const RwMatrix * transform, RwOpCombineType combineOp)
+ { matrix->transform(transform, (rw::CombineOp)combineOp); return matrix; }
+//RwMatrix *RwMatrixOrthoNormalize(RwMatrix * matrixOut, const RwMatrix * matrixIn);
+RwMatrix *RwMatrixInvert(RwMatrix * matrixOut, const RwMatrix * matrixIn) { Matrix::invert(matrixOut, matrixIn); return matrixOut; }
+RwMatrix *RwMatrixScale(RwMatrix * matrix, const RwV3d * scale, RwOpCombineType combineOp)
+ { matrix->scale(scale, (rw::CombineOp)combineOp); return matrix; }
+RwMatrix *RwMatrixTranslate(RwMatrix * matrix, const RwV3d * translation, RwOpCombineType combineOp)
+ { matrix->translate(translation, (rw::CombineOp)combineOp); return matrix; }
+RwMatrix *RwMatrixRotate(RwMatrix * matrix, const RwV3d * axis, RwReal angle, RwOpCombineType combineOp)
+ { matrix->rotate(axis, angle, (rw::CombineOp)combineOp); return matrix; }
+//RwMatrix *RwMatrixRotateOneMinusCosineSine(RwMatrix * matrix, const RwV3d * unitAxis, RwReal oneMinusCosine, RwReal sine, RwOpCombineType combineOp);
+//const RwMatrix *RwMatrixQueryRotate(const RwMatrix * matrix, RwV3d * unitAxis, RwReal * angle, RwV3d * center);
+RwV3d *RwMatrixGetRight(RwMatrix * matrix) { return &matrix->right; }
+RwV3d *RwMatrixGetUp(RwMatrix * matrix) { return &matrix->up; }
+RwV3d *RwMatrixGetAt(RwMatrix * matrix) { return &matrix->at; }
+RwV3d *RwMatrixGetPos(RwMatrix * matrix) { return &matrix->pos; }
+RwMatrix *RwMatrixUpdate(RwMatrix * matrix) { matrix->update(); return matrix; }
+//RwMatrix *RwMatrixOptimize(RwMatrix * matrix, const RwMatrixTolerance *tolerance);
+
+
+
+
+RwFrame *RwFrameForAllObjects(RwFrame * frame, RwObjectCallBack callBack, void *data) {
+ FORLIST(lnk, frame->objectList)
+ if(callBack(&ObjectWithFrame::fromFrame(lnk)->object, data) == nil)
+ break;
+ return frame;
+}
+RwFrame *RwFrameTranslate(RwFrame * frame, const RwV3d * v, RwOpCombineType combine) { frame->translate(v, (CombineOp)combine); return frame; }
+RwFrame *RwFrameRotate(RwFrame * frame, const RwV3d * axis, RwReal angle, RwOpCombineType combine) { frame->rotate(axis, angle, (CombineOp)combine); return frame; }
+RwFrame *RwFrameScale(RwFrame * frame, const RwV3d * v, RwOpCombineType combine) { frame->scale(v, (CombineOp)combine); return frame; }
+RwFrame *RwFrameTransform(RwFrame * frame, const RwMatrix * m, RwOpCombineType combine) { frame->transform(m, (CombineOp)combine); return frame; }
+//RwFrame *RwFrameOrthoNormalize(RwFrame * frame);
+RwFrame *RwFrameSetIdentity(RwFrame * frame) { frame->matrix.setIdentity(); frame->updateObjects(); return frame; }
+//RwFrame *RwFrameCloneHierarchy(RwFrame * root);
+//RwBool RwFrameDestroyHierarchy(RwFrame * frame);
+RwFrame *RwFrameForAllChildren(RwFrame * frame, RwFrameCallBack callBack, void *data)
+ { return frame->forAllChildren(callBack, data); }
+RwFrame *RwFrameRemoveChild(RwFrame * child) { child->removeChild(); return child; }
+RwFrame *RwFrameAddChild(RwFrame * parent, RwFrame * child) { parent->addChild(child); return parent; }
+RwFrame *RwFrameGetParent(const RwFrame * frame) { return frame->getParent(); }
+//RwFrame *RwFrameGetRoot(const RwFrame * frame);
+RwMatrix *RwFrameGetLTM(RwFrame * frame) { return frame->getLTM(); }
+RwMatrix *RwFrameGetMatrix(RwFrame * frame) { return &frame->matrix; }
+RwFrame *RwFrameUpdateObjects(RwFrame * frame) { frame->updateObjects(); return frame; }
+RwFrame *RwFrameCreate(void) { return rw::Frame::create(); }
+//RwBool RwFrameInit(RwFrame *frame);
+//RwBool RwFrameDeInit(RwFrame *frame);
+RwBool RwFrameDestroy(RwFrame * frame) { frame->destroy(); return true; }
+//void _rwFrameInit(RwFrame *frame);
+//void _rwFrameDeInit(RwFrame *frame);
+//RwBool RwFrameDirty(const RwFrame * frame);
+//RwInt32 RwFrameCount(RwFrame * frame);
+//RwBool RwFrameSetStaticPluginsSize(RwInt32 size);
+RwInt32 RwFrameRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB)
+ { return Frame::registerPlugin(size, pluginID, constructCB, destructCB, (CopyConstructor)copyCB); }
+//RwInt32 RwFrameGetPluginOffset(RwUInt32 pluginID);
+//RwBool RwFrameValidatePlugins(const RwFrame * frame);
+//RwFrame *_rwFrameCloneAndLinkClones(RwFrame * root);
+//RwFrame *_rwFramePurgeClone(RwFrame *root);
+
+RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB)
+ { return Frame::registerPluginStream(pluginID, readCB, (StreamWrite)writeCB, (StreamGetSize)getSizeCB); }
+
+
+rwFrameList *rwFrameListDeinitialize(rwFrameList *frameList) {
+ rwFree(frameList->frames);
+ frameList->frames = nil;
+ return frameList;
+}
+rwFrameList *rwFrameListStreamRead(RwStream *stream, rwFrameList *fl) { return fl->streamRead(stream); }
+
+
+
+
+RwCamera *RwCameraBeginUpdate(RwCamera * camera) { camera->beginUpdate(); return camera; }
+RwCamera *RwCameraEndUpdate(RwCamera * camera) { camera->endUpdate(); return camera; }
+RwCamera *RwCameraClear(RwCamera * camera, RwRGBA * colour, RwInt32 clearMode) { camera->clear(colour, clearMode); return camera; }
+// WARNING: ignored arguments
+RwCamera *RwCameraShowRaster(RwCamera * camera, void *pDev, RwUInt32 flags) { camera->showRaster(); return camera; }
+RwBool RwCameraDestroy(RwCamera * camera) { camera->destroy(); return true; }
+RwCamera *RwCameraCreate(void) { return rw::Camera::create(); }
+RwCamera *RwCameraClone(RwCamera * camera) { return camera->clone(); }
+RwCamera *RwCameraSetViewOffset(RwCamera *camera, const RwV2d *offset) { camera->setViewOffset(offset); return camera; }
+RwCamera *RwCameraSetViewWindow(RwCamera *camera, const RwV2d *viewWindow) { camera->setViewWindow(viewWindow); return camera; }
+RwCamera *RwCameraSetProjection(RwCamera *camera, RwCameraProjection projection);
+RwCamera *RwCameraSetNearClipPlane(RwCamera *camera, RwReal nearClip) { camera->setNearPlane(nearClip); return camera; }
+RwCamera *RwCameraSetFarClipPlane(RwCamera *camera, RwReal farClip) { camera->setFarPlane(farClip); return camera; }
+RwInt32 RwCameraRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwCameraGetPluginOffset(RwUInt32 pluginID);
+RwBool RwCameraValidatePlugins(const RwCamera * camera);
+RwFrustumTestResult RwCameraFrustumTestSphere(const RwCamera * camera, const RwSphere * sphere) { return (RwFrustumTestResult)camera->frustumTestSphere(sphere); }
+const RwV2d *RwCameraGetViewOffset(const RwCamera *camera) { return &camera->viewOffset; }
+RwCamera *RwCameraSetRaster(RwCamera *camera, RwRaster *raster) { camera->frameBuffer = raster; return camera; }
+RwRaster *RwCameraGetRaster(const RwCamera *camera) { return camera->frameBuffer; }
+RwCamera *RwCameraSetZRaster(RwCamera *camera, RwRaster *zRaster) { camera->zBuffer = zRaster; return camera; }
+RwRaster *RwCameraGetZRaster(const RwCamera *camera) { return camera->zBuffer; }
+RwReal RwCameraGetNearClipPlane(const RwCamera *camera) { return camera->nearPlane; }
+RwReal RwCameraGetFarClipPlane(const RwCamera *camera) { return camera->farPlane; }
+RwCamera *RwCameraSetFogDistance(RwCamera *camera, RwReal fogDistance) { camera->fogPlane = fogDistance; return camera; }
+RwReal RwCameraGetFogDistance(const RwCamera *camera) { return camera->fogPlane; }
+RwCamera *RwCameraGetCurrentCamera(void);
+RwCameraProjection RwCameraGetProjection(const RwCamera *camera);
+const RwV2d *RwCameraGetViewWindow(const RwCamera *camera) { return &camera->viewWindow; }
+RwMatrix *RwCameraGetViewMatrix(RwCamera *camera) { return &camera->viewMatrix; }
+RwCamera *RwCameraSetFrame(RwCamera *camera, RwFrame *frame) { camera->setFrame(frame); return camera; }
+RwFrame *RwCameraGetFrame(const RwCamera *camera) { return camera->getFrame(); }
+
+
+
+
+
+RwImage *RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth) { return Image::create(width, height, depth); }
+RwBool RwImageDestroy(RwImage * image) { image->destroy(); return true; }
+RwImage *RwImageAllocatePixels(RwImage * image);
+RwImage *RwImageFreePixels(RwImage * image);
+RwImage *RwImageCopy(RwImage * destImage, const RwImage * sourceImage);
+RwImage *RwImageResize(RwImage * image, RwInt32 width, RwInt32 height);
+RwImage *RwImageApplyMask(RwImage * image, const RwImage * mask);
+RwImage *RwImageMakeMask(RwImage * image);
+RwImage *RwImageReadMaskedImage(const RwChar * imageName, const RwChar * maskname);
+RwImage *RwImageRead(const RwChar * imageName);
+RwImage *RwImageWrite(RwImage * image, const RwChar * imageName);
+RwChar *RwImageGetPath(void);
+const RwChar *RwImageSetPath(const RwChar * path) { Image::setSearchPath(path); return path; }
+RwImage *RwImageSetStride(RwImage * image, RwInt32 stride) { image->stride = stride; return image; }
+RwImage *RwImageSetPixels(RwImage * image, RwUInt8 * pixels) { image->pixels = pixels; return image; }
+RwImage *RwImageSetPalette(RwImage * image, RwRGBA * palette) { image->palette = (uint8*)palette; return image; }
+RwInt32 RwImageGetWidth(const RwImage * image) { return image->width; }
+RwInt32 RwImageGetHeight(const RwImage * image) { return image->height; }
+RwInt32 RwImageGetDepth(const RwImage * image);
+RwInt32 RwImageGetStride(const RwImage * image);
+RwUInt8 *RwImageGetPixels(const RwImage * image);
+RwRGBA *RwImageGetPalette(const RwImage * image);
+RwUInt32 RwRGBAToPixel(RwRGBA * rgbIn, RwInt32 rasterFormat);
+RwRGBA *RwRGBASetFromPixel(RwRGBA * rgbOut, RwUInt32 pixelValue, RwInt32 rasterFormat);
+RwBool RwImageSetGamma(RwReal gammaValue);
+RwReal RwImageGetGamma(void);
+RwImage *RwImageGammaCorrect(RwImage * image);
+RwRGBA *RwRGBAGammaCorrect(RwRGBA * rgb);
+RwInt32 RwImageRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwImageGetPluginOffset(RwUInt32 pluginID);
+RwBool RwImageValidatePlugins(const RwImage * image);
+//RwBool RwImageRegisterImageFormat(const RwChar * extension, RwImageCallBackRead imageRead, RwImageCallBackWrite imageWrite);
+const RwChar *RwImageFindFileType(const RwChar * imageName);
+RwInt32 RwImageStreamGetSize(const RwImage * image);
+RwImage *RwImageStreamRead(RwStream * stream);
+const RwImage *RwImageStreamWrite(const RwImage * image, RwStream * stream);
+
+RwImage *RwImageFindRasterFormat(RwImage *ipImage,RwInt32 nRasterType, RwInt32 *npWidth,RwInt32 *npHeight, RwInt32 *npDepth,RwInt32 *npFormat)
+{
+ return Raster::imageFindRasterFormat(ipImage, nRasterType, npWidth, npHeight, npDepth, npFormat) ? ipImage : nil;
+}
+
+
+
+
+RwRaster *RwRasterCreate(RwInt32 width, RwInt32 height, RwInt32 depth, RwInt32 flags) { return Raster::create(width, height, depth, flags); }
+RwBool RwRasterDestroy(RwRaster * raster) { raster->destroy(); return true; }
+RwInt32 RwRasterGetWidth(const RwRaster *raster) { return raster->width; }
+RwInt32 RwRasterGetHeight(const RwRaster *raster) { return raster->height; }
+RwInt32 RwRasterGetStride(const RwRaster *raster);
+RwInt32 RwRasterGetDepth(const RwRaster *raster) { return raster->depth; }
+RwInt32 RwRasterGetFormat(const RwRaster *raster);
+RwInt32 RwRasterGetType(const RwRaster *raster);
+RwRaster *RwRasterGetParent(const RwRaster *raster) { return raster->parent; }
+RwRaster *RwRasterGetOffset(RwRaster *raster, RwInt16 *xOffset, RwInt16 *yOffset);
+RwInt32 RwRasterGetNumLevels(RwRaster * raster);
+RwRaster *RwRasterSubRaster(RwRaster * subRaster, RwRaster * raster, RwRect * rect);
+RwRaster *RwRasterRenderFast(RwRaster * raster, RwInt32 x, RwInt32 y) { return raster->renderFast(x, y) ? raster : nil; }
+RwRaster *RwRasterRender(RwRaster * raster, RwInt32 x, RwInt32 y);
+RwRaster *RwRasterRenderScaled(RwRaster * raster, RwRect * rect);
+RwRaster *RwRasterPushContext(RwRaster * raster) { return Raster::pushContext(raster); }
+RwRaster *RwRasterPopContext(void) { return Raster::popContext(); }
+RwRaster *RwRasterGetCurrentContext(void) { return Raster::getCurrentContext(); }
+RwBool RwRasterClear(RwInt32 pixelValue);
+RwBool RwRasterClearRect(RwRect * rpRect, RwInt32 pixelValue);
+RwRaster *RwRasterShowRaster(RwRaster * raster, void *dev, RwUInt32 flags);
+RwUInt8 *RwRasterLock(RwRaster * raster, RwUInt8 level, RwInt32 lockMode);
+RwRaster *RwRasterUnlock(RwRaster * raster);
+RwUInt8 *RwRasterLockPalette(RwRaster * raster, RwInt32 lockMode);
+RwRaster *RwRasterUnlockPalette(RwRaster * raster);
+RwInt32 RwRasterRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwRasterGetPluginOffset(RwUInt32 pluginID);
+RwBool RwRasterValidatePlugins(const RwRaster * raster);
+
+RwRaster *RwRasterSetFromImage(RwRaster *raster, RwImage *image) { return raster->setFromImage(image); }
+
+
+
+
+RwTexture *RwTextureCreate(RwRaster * raster) { return Texture::create(raster); }
+RwBool RwTextureDestroy(RwTexture * texture) { texture->destroy(); return true; }
+RwTexture *RwTextureAddRef(RwTexture *texture) { texture->addRef(); return texture; }
+// TODO
+RwBool RwTextureSetMipmapping(RwBool enable) { return true; }
+RwBool RwTextureGetMipmapping(void);
+// TODO
+RwBool RwTextureSetAutoMipmapping(RwBool enable) { return true; }
+RwBool RwTextureGetAutoMipmapping(void);
+RwBool RwTextureSetMipmapGenerationCallBack(RwTextureCallBackMipmapGeneration callback);
+RwTextureCallBackMipmapGeneration RwTextureGetMipmapGenerationCallBack(void);
+RwBool RwTextureSetMipmapNameCallBack(RwTextureCallBackMipmapName callback);
+RwTextureCallBackMipmapName RwTextureGetMipmapNameCallBack(void);
+RwBool RwTextureGenerateMipmapName(RwChar * name, RwChar * maskName, RwUInt8 mipLevel, RwInt32 format);
+RwBool RwTextureRasterGenerateMipmaps(RwRaster * raster, RwImage * image);
+RwTextureCallBackRead RwTextureGetReadCallBack(void);
+RwBool RwTextureSetReadCallBack(RwTextureCallBackRead fpCallBack);
+RwTexture *RwTextureSetName(RwTexture * texture, const RwChar * name) { strncpy(texture->name, name, 32); return texture; }
+RwTexture *RwTextureSetMaskName(RwTexture * texture, const RwChar * maskName);
+RwChar *RwTextureGetName(RwTexture *texture) { return texture->name; }
+RwChar *RwTextureGetMaskName(RwTexture *texture);
+RwTexture *RwTextureSetRaster(RwTexture * texture, RwRaster * raster) { texture->raster = raster; return texture; }
+RwTexture *RwTextureRead(const RwChar * name, const RwChar * maskName) { return Texture::read(name, maskName); }
+RwRaster *RwTextureGetRaster(const RwTexture *texture) { return texture->raster; }
+RwInt32 RwTextureRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwTextureGetPluginOffset(RwUInt32 pluginID);
+RwBool RwTextureValidatePlugins(const RwTexture * texture);
+
+RwTexDictionary *RwTextureGetDictionary(RwTexture *texture);
+RwTexture *RwTextureSetFilterMode(RwTexture *texture, RwTextureFilterMode filtering) { texture->setFilter((Texture::FilterMode)filtering); return texture; }
+RwTextureFilterMode RwTextureGetFilterMode(const RwTexture *texture);
+RwTexture *RwTextureSetAddressing(RwTexture *texture, RwTextureAddressMode addressing) {
+ texture->setAddressU((Texture::Addressing)addressing);
+ texture->setAddressV((Texture::Addressing)addressing);
+ return texture;
+}
+RwTexture *RwTextureSetAddressingU(RwTexture *texture, RwTextureAddressMode addressing) {
+ texture->setAddressU((Texture::Addressing)addressing);
+ return texture;
+}
+RwTexture *RwTextureSetAddressingV(RwTexture *texture, RwTextureAddressMode addressing) {
+ texture->setAddressV((Texture::Addressing)addressing);
+ return texture;
+}
+RwTextureAddressMode RwTextureGetAddressing(const RwTexture *texture);
+RwTextureAddressMode RwTextureGetAddressingU(const RwTexture *texture);
+RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
+
+// TODO
+void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { }
+
+static rw::Raster*
+ConvertTexRaster(rw::Raster *ras)
+{
+ using namespace rw;
+ Image *img = ras->toImage();
+ ras->destroy();
+ img->unindex();
+ ras = Raster::createFromImage(img);
+ img->destroy();
+ return ras;
+}
+
+// hack for reading native textures
+RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size)
+{
+ *tex = Texture::streamReadNative(stream);
+#ifdef RW_GL3
+ if(strcmp((*tex)->name, "copnu") == 0)
+ tex = tex;
+ (*tex)->raster = ConvertTexRaster((*tex)->raster);
+#endif
+ return *tex != nil;
+}
+
+
+
+
+
+RwTexDictionary *RwTexDictionaryCreate(void) { return TexDictionary::create(); }
+RwBool RwTexDictionaryDestroy(RwTexDictionary * dict) { dict->destroy(); return true; }
+RwTexture *RwTexDictionaryAddTexture(RwTexDictionary * dict, RwTexture * texture) { dict->addFront(texture); return texture; }
+//RwTexture *RwTexDictionaryRemoveTexture(RwTexture * texture);
+RwTexture *RwTexDictionaryFindNamedTexture(RwTexDictionary * dict, const RwChar * name) { return dict->find(name); }
+RwTexDictionary *RwTexDictionaryGetCurrent(void) { return TexDictionary::getCurrent(); }
+RwTexDictionary *RwTexDictionarySetCurrent(RwTexDictionary * dict) { TexDictionary::setCurrent(dict); return dict; }
+const RwTexDictionary *RwTexDictionaryForAllTextures(const RwTexDictionary * dict, RwTextureCallBack fpCallBack, void *pData) {
+ FORLIST(lnk, ((RwTexDictionary*)dict)->textures)
+ if(fpCallBack(Texture::fromDict(lnk), pData) == nil)
+ break;
+ return dict;
+}
+RwBool RwTexDictionaryForAllTexDictionaries(RwTexDictionaryCallBack fpCallBack, void *pData);
+RwInt32 RwTexDictionaryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwTexDictionaryGetPluginOffset(RwUInt32 pluginID);
+RwBool RwTexDictionaryValidatePlugins(const RwTexDictionary * dict);
+RwUInt32 RwTexDictionaryStreamGetSize(const RwTexDictionary *texDict);
+RwTexDictionary *RwTexDictionaryStreamRead(RwStream *stream);
+const RwTexDictionary *RwTexDictionaryStreamWrite(const RwTexDictionary *texDict, RwStream *stream) {
+ ((RwTexDictionary*)texDict)->streamWrite(stream);
+ return texDict;
+}
+
+
+
+
+
+RwStream *RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, const void *pData) {
+ StreamFile *file;
+ StreamMemory *mem;
+ RwMemory *memargs;
+ const char *mode;
+
+ switch(accessType){
+ case rwSTREAMREAD: mode = "rb"; break;
+ case rwSTREAMWRITE: mode = "wb"; break;
+ case rwSTREAMAPPEND: mode = "ab"; break;
+ default: return nil;
+ }
+
+ // oh god this is horrible. librw streams really need fixing
+ switch(type){
+ case rwSTREAMFILENAME:{
+ StreamFile fakefile;
+ file = rwNewT(StreamFile, 1, 0);
+ memcpy(file, &fakefile, sizeof(StreamFile));
+ if(file->open((char*)pData, mode))
+ return file;
+ rwFree(file);
+ return nil;
+ }
+ case rwSTREAMMEMORY:{
+ StreamMemory fakemem;
+ memargs = (RwMemory*)pData;
+ mem = rwNewT(StreamMemory, 1, 0);
+ memcpy(mem, &fakemem, sizeof(StreamMemory));
+ if(mem->open(memargs->start, memargs->length))
+ return mem;
+ rwFree(mem);
+ return nil;
+ }
+ default:
+ assert(0 && "unknown type");
+ return nil;
+ }
+}
+RwBool RwStreamClose(RwStream * stream, void *pData) { stream->close(); rwFree(stream); return true; }
+RwUInt32 RwStreamRead(RwStream * stream, void *buffer, RwUInt32 length) { return stream->read(buffer, length); }
+RwStream *RwStreamWrite(RwStream * stream, const void *buffer, RwUInt32 length) { stream->write(buffer, length); return stream; }
+RwStream *RwStreamSkip(RwStream * stream, RwUInt32 offset) { stream->seek(offset); return stream; }
+
+RwBool RwStreamFindChunk(RwStream *stream, RwUInt32 type, RwUInt32 *lengthOut, RwUInt32 *versionOut)
+ { return findChunk(stream, type, lengthOut, versionOut); }
+
+
+
+void RwIm2DVertexSetCameraX(RwIm2DVertex *vert, RwReal camx) { }
+void RwIm2DVertexSetCameraY(RwIm2DVertex *vert, RwReal camy) { }
+void RwIm2DVertexSetCameraZ(RwIm2DVertex *vert, RwReal camz) { vert->setCameraZ(camz); }
+void RwIm2DVertexSetRecipCameraZ(RwIm2DVertex *vert, RwReal recipz) { vert->setRecipCameraZ(recipz); }
+void RwIm2DVertexSetScreenX(RwIm2DVertex *vert, RwReal scrnx) { vert->setScreenX(scrnx); }
+void RwIm2DVertexSetScreenY(RwIm2DVertex *vert, RwReal scrny) { vert->setScreenY(scrny); }
+void RwIm2DVertexSetScreenZ(RwIm2DVertex *vert, RwReal scrnz) { vert->setScreenZ(scrnz); }
+void RwIm2DVertexSetU(RwIm2DVertex *vert, RwReal texU, RwReal recipz) { vert->setU(texU, recipz); }
+void RwIm2DVertexSetV(RwIm2DVertex *vert, RwReal texV, RwReal recipz) { vert->setV(texV, recipz); }
+void RwIm2DVertexSetIntRGBA(RwIm2DVertex *vert, RwUInt8 red, RwUInt8 green, RwUInt8 blue, RwUInt8 alpha) { vert->setColor(red, green, blue, alpha); }
+
+RwReal RwIm2DGetNearScreenZ(void) { return im2d::GetNearZ(); }
+RwReal RwIm2DGetFarScreenZ(void) { return im2d::GetFarZ(); }
+RwBool RwIm2DRenderLine(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2)
+ { im2d::RenderLine(vertices, numVertices, vert1, vert2); return true; }
+RwBool RwIm2DRenderTriangle(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2, RwInt32 vert3 )
+ { im2d::RenderTriangle(vertices, numVertices, vert1, vert2, vert3); return true; }
+RwBool RwIm2DRenderPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices)
+ { im2d::RenderPrimitive((PrimitiveType)primType, vertices, numVertices); return true; }
+RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
+ { im2d::RenderIndexedPrimitive((PrimitiveType)primType, vertices, numVertices, indices, numIndices); return true; }
+
+
+void RwIm3DVertexSetPos(RwIm3DVertex *vert, RwReal x, RwReal y, RwReal z) { vert->setX(x); vert->setY(y); vert->setZ(z); }
+void RwIm3DVertexSetU(RwIm3DVertex *vert, RwReal u) { vert->setU(u); }
+void RwIm3DVertexSetV(RwIm3DVertex *vert, RwReal v) { vert->setV(v); }
+void RwIm3DVertexSetRGBA(RwIm3DVertex *vert, RwUInt8 r, RwUInt8 g, RwUInt8 b, RwUInt8 a) { vert->setColor(r, g, b, a); }
+
+// WARNING: ignoring flags
+void *RwIm3DTransform(RwIm3DVertex *pVerts, RwUInt32 numVerts, RwMatrix *ltm, RwUInt32 flags) { im3d::Transform(pVerts, numVerts, ltm); return pVerts; }
+RwBool RwIm3DEnd(void) { im3d::End(); return true; }
+RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2) {
+ RwImVertexIndex indices[2];
+ indices[0] = vert1;
+ indices[1] = vert2;
+ im3d::RenderIndexedPrimitive((PrimitiveType)PRIMTYPELINELIST, indices, 2);
+ return true;
+}
+RwBool RwIm3DRenderTriangle(RwInt32 vert1, RwInt32 vert2, RwInt32 vert3);
+RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType, RwImVertexIndex *indices, RwInt32 numIndices) { im3d::RenderIndexedPrimitive((PrimitiveType)primType, indices, numIndices); return true; }
+RwBool RwIm3DRenderPrimitive(RwPrimitiveType primType);
+
+
+
+
+
+RwBool RwRenderStateSet(RwRenderState state, void *value)
+{
+ uint32 uival = (uintptr)value;
+ switch(state){
+ case rwRENDERSTATETEXTURERASTER: SetRenderState(TEXTURERASTER, uival); return true;
+ case rwRENDERSTATETEXTUREADDRESS: SetRenderState(TEXTUREADDRESS, uival); return true;
+ case rwRENDERSTATETEXTUREADDRESSU: SetRenderState(TEXTUREADDRESSU, uival); return true;
+ case rwRENDERSTATETEXTUREADDRESSV: SetRenderState(TEXTUREADDRESSV, uival); return true;
+ case rwRENDERSTATETEXTUREPERSPECTIVE: return true;
+ case rwRENDERSTATEZTESTENABLE: SetRenderState(ZTESTENABLE, uival); return true;
+ case rwRENDERSTATESHADEMODE: return true;
+ case rwRENDERSTATEZWRITEENABLE: SetRenderState(ZWRITEENABLE, uival); return true;
+ case rwRENDERSTATETEXTUREFILTER: SetRenderState(TEXTUREFILTER, uival); return true;
+ case rwRENDERSTATESRCBLEND: SetRenderState(SRCBLEND, uival); return true;
+ case rwRENDERSTATEDESTBLEND: SetRenderState(DESTBLEND, uival); return true;
+ case rwRENDERSTATEVERTEXALPHAENABLE: SetRenderState(VERTEXALPHA, uival); return true;
+ case rwRENDERSTATEBORDERCOLOR: return true;
+ case rwRENDERSTATEFOGENABLE: SetRenderState(FOGENABLE, uival); return true;
+ case rwRENDERSTATEFOGCOLOR: SetRenderState(FOGCOLOR, uival); return true;
+ case rwRENDERSTATEFOGTYPE: return true;
+ case rwRENDERSTATEFOGDENSITY: return true;
+ case rwRENDERSTATEFOGTABLE: return true;
+ case rwRENDERSTATEALPHAPRIMITIVEBUFFER: return true;
+ case rwRENDERSTATECULLMODE: SetRenderState(CULLMODE, uival); return true;
+
+ // all unsupported
+ case rwRENDERSTATESTENCILENABLE:
+ case rwRENDERSTATESTENCILFAIL:
+ case rwRENDERSTATESTENCILZFAIL:
+ case rwRENDERSTATESTENCILPASS:
+ case rwRENDERSTATESTENCILFUNCTION:
+ case rwRENDERSTATESTENCILFUNCTIONREF:
+ case rwRENDERSTATESTENCILFUNCTIONMASK:
+ case rwRENDERSTATESTENCILFUNCTIONWRITEMASK:
+ default:
+ return true;
+ }
+}
+
+// WARNING: unused parameters
+RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { Engine::init(); return true; }
+// TODO: this is platform dependent
+RwBool RwEngineOpen(RwEngineOpenParams *initParams) {
+#if defined RW_D3D9 || defined RWLIBS
+ static EngineOpenParams openParams;
+ openParams.window = (HWND)initParams->displayID;
+#else
+ extern EngineOpenParams openParams;
+ openParams.window = (GLFWwindow**)initParams->displayID;
+#endif
+ return Engine::open(&openParams);
+}
+RwBool RwEngineStart(void) {
+ rw::d3d::isP8supported = false;
+ return Engine::start();
+}
+RwBool RwEngineStop(void) { Engine::stop(); return true; }
+RwBool RwEngineClose(void) { Engine::close(); return true; }
+RwBool RwEngineTerm(void) { Engine::term(); return true; }
+RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, RwPluginObjectDestructor termCB);
+RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID);
+RwInt32 RwEngineGetNumSubSystems(void) { return Engine::getNumSubSystems(); }
+RwSubSystemInfo *RwEngineGetSubSystemInfo(RwSubSystemInfo *subSystemInfo, RwInt32 subSystemIndex)
+ { return Engine::getSubSystemInfo(subSystemInfo, subSystemIndex); }
+RwInt32 RwEngineGetCurrentSubSystem(void) { return Engine::getCurrentSubSystem(); }
+RwBool RwEngineSetSubSystem(RwInt32 subSystemIndex) { return Engine::setSubSystem(subSystemIndex); }
+RwInt32 RwEngineGetNumVideoModes(void) { return Engine::getNumVideoModes(); }
+RwVideoMode *RwEngineGetVideoModeInfo(RwVideoMode *modeinfo, RwInt32 modeIndex)
+ { return Engine::getVideoModeInfo(modeinfo, modeIndex); }
+RwInt32 RwEngineGetCurrentVideoMode(void) { return Engine::getCurrentVideoMode(); }
+RwBool RwEngineSetVideoMode(RwInt32 modeIndex) { return Engine::setVideoMode(modeIndex); }
+RwInt32 RwEngineGetTextureMemorySize(void);
+RwInt32 RwEngineGetMaxTextureSize(void);
+
+
+
+// TODO
+void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) {}
+RwBool RwD3D8DeviceSupportsDXTTexture(void) { return true; }
+
+
+
+RpMaterial *RpMaterialCreate(void) { return Material::create(); }
+RwBool RpMaterialDestroy(RpMaterial *material) { material->destroy(); return true; }
+//RpMaterial *RpMaterialClone(RpMaterial *material);
+RpMaterial *RpMaterialSetTexture(RpMaterial *material, RwTexture *texture) { material->setTexture(texture); return material; }
+//RpMaterial *RpMaterialAddRef(RpMaterial *material);
+RwTexture *RpMaterialGetTexture(const RpMaterial *material) { return material->texture; }
+RpMaterial *RpMaterialSetColor(RpMaterial *material, const RwRGBA *color) { material->color = *color; return material; }
+const RwRGBA *RpMaterialGetColor(const RpMaterial *material) { return &material->color; }
+RpMaterial *RpMaterialSetSurfaceProperties(RpMaterial *material, const RwSurfaceProperties *surfaceProperties);
+const RwSurfaceProperties *RpMaterialGetSurfaceProperties(const RpMaterial *material) { return &material->surfaceProps; }
+//RwInt32 RpMaterialRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+//RwInt32 RpMaterialRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+//RwInt32 RpMaterialSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+//RwInt32 RpMaterialGetPluginOffset(RwUInt32 pluginID);
+//RwBool RpMaterialValidatePlugins(const RpMaterial *material);
+//RwUInt32 RpMaterialStreamGetSize(const RpMaterial *material);
+//RpMaterial *RpMaterialStreamRead(RwStream *stream);
+//const RpMaterial *RpMaterialStreamWrite(const RpMaterial *material, RwStream *stream);
+//RpMaterialChunkInfo *_rpMaterialChunkInfoRead(RwStream *stream, RpMaterialChunkInfo *materialChunkInfo, RwInt32 *bytesRead);
+
+
+
+
+
+RwReal RpLightGetRadius(const RpLight *light) { return light->radius; }
+//const RwRGBAReal *RpLightGetColor(const RpLight *light);
+RpLight *RpLightSetFrame(RpLight *light, RwFrame *frame) { light->setFrame(frame); return light; }
+RwFrame *RpLightGetFrame(const RpLight *light) { return light->getFrame(); }
+//RpLightType RpLightGetType(const RpLight *light);
+RpLight *RpLightSetFlags(RpLight *light, RwUInt32 flags) { light->setFlags(flags); return light; }
+//RwUInt32 RpLightGetFlags(const RpLight *light);
+RpLight *RpLightCreate(RwInt32 type) { return rw::Light::create(type); }
+RwBool RpLightDestroy(RpLight *light) { light->destroy(); return true; }
+RpLight *RpLightSetRadius(RpLight *light, RwReal radius) { light->radius = radius; return light; }
+RpLight *RpLightSetColor(RpLight *light, const RwRGBAReal *color) { light->setColor(color->red, color->green, color->blue); return light; }
+//RwReal RpLightGetConeAngle(const RpLight *light);
+//RpLight *RpLightSetConeAngle(RpLight * ight, RwReal angle);
+//RwUInt32 RpLightStreamGetSize(const RpLight *light);
+//RpLight *RpLightStreamRead(RwStream *stream);
+//const RpLight *RpLightStreamWrite(const RpLight *light, RwStream *stream);
+//RpLightChunkInfo *_rpLightChunkInfoRead(RwStream *stream, RpLightChunkInfo *lightChunkInfo, RwInt32 *bytesRead);
+//RwInt32 RpLightRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+//RwInt32 RpLightRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+//RwInt32 RpLightSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+//RwInt32 RpLightGetPluginOffset(RwUInt32 pluginID);
+//RwBool RpLightValidatePlugins(const RpLight * light);
+
+
+
+
+
+RpGeometry *RpGeometryCreate(RwInt32 numVert, RwInt32 numTriangles, RwUInt32 format) { return Geometry::create(numVert, numTriangles, format); }
+RwBool RpGeometryDestroy(RpGeometry *geometry) { geometry->destroy(); return true; }
+RpGeometry *_rpGeometryAddRef(RpGeometry *geometry);
+RpGeometry *RpGeometryLock(RpGeometry *geometry, RwInt32 lockMode) { geometry->lock(lockMode); return geometry; }
+RpGeometry *RpGeometryUnlock(RpGeometry *geometry) { geometry->unlock(); return geometry; }
+RpGeometry *RpGeometryTransform(RpGeometry *geometry, const RwMatrix *matrix);
+RpGeometry *RpGeometryCreateSpace(RwReal radius);
+RpMorphTarget *RpMorphTargetSetBoundingSphere(RpMorphTarget *morphTarget, const RwSphere *boundingSphere) { morphTarget->boundingSphere = *boundingSphere; return morphTarget; }
+RwSphere *RpMorphTargetGetBoundingSphere(RpMorphTarget *morphTarget) { return &morphTarget->boundingSphere; }
+const RpMorphTarget *RpMorphTargetCalcBoundingSphere(const RpMorphTarget *morphTarget, RwSphere *boundingSphere) { *boundingSphere = morphTarget->calculateBoundingSphere(); return morphTarget; }
+RwInt32 RpGeometryAddMorphTargets(RpGeometry *geometry, RwInt32 mtcount);
+RwInt32 RpGeometryAddMorphTarget(RpGeometry *geometry);
+RpGeometry *RpGeometryRemoveMorphTarget(RpGeometry *geometry, RwInt32 morphTarget);
+RwInt32 RpGeometryGetNumMorphTargets(const RpGeometry *geometry);
+RpMorphTarget *RpGeometryGetMorphTarget(const RpGeometry *geometry, RwInt32 morphTarget) { return &geometry->morphTargets[morphTarget]; }
+RwRGBA *RpGeometryGetPreLightColors(const RpGeometry *geometry) { return geometry->colors; }
+RwTexCoords *RpGeometryGetVertexTexCoords(const RpGeometry *geometry, RwTextureCoordinateIndex uvIndex) {
+ if(uvIndex == rwNARWTEXTURECOORDINATEINDEX)
+ return nil;
+ return geometry->texCoords[uvIndex-rwTEXTURECOORDINATEINDEX0];
+}
+RwInt32 RpGeometryGetNumTexCoordSets(const RpGeometry *geometry) { return geometry->numTexCoordSets; }
+RwInt32 RpGeometryGetNumVertices (const RpGeometry *geometry) { return geometry->numVertices; }
+RwV3d *RpMorphTargetGetVertices(const RpMorphTarget *morphTarget) { return morphTarget->vertices; }
+RwV3d *RpMorphTargetGetVertexNormals(const RpMorphTarget *morphTarget) { return morphTarget->normals; }
+RpTriangle *RpGeometryGetTriangles(const RpGeometry *geometry) { return geometry->triangles; }
+RwInt32 RpGeometryGetNumTriangles(const RpGeometry *geometry) { return geometry->numTriangles; }
+RpMaterial *RpGeometryGetMaterial(const RpGeometry *geometry, RwInt32 matNum) { return geometry->matList.materials[matNum]; }
+const RpGeometry *RpGeometryTriangleSetVertexIndices(const RpGeometry *geometry, RpTriangle *triangle, RwUInt16 vert1, RwUInt16 vert2, RwUInt16 vert3)
+ { triangle->v[0] = vert1; triangle->v[1] = vert2; triangle->v[2] = vert3; return geometry; }
+RpGeometry *RpGeometryTriangleSetMaterial(RpGeometry *geometry, RpTriangle *triangle, RpMaterial *material) {
+ int id = geometry->matList.findIndex(material);
+ if(id < 0)
+ id = geometry->matList.appendMaterial(material);
+ if(id < 0)
+ return nil;
+ triangle->matId = id;
+ return geometry;
+}
+const RpGeometry *RpGeometryTriangleGetVertexIndices(const RpGeometry *geometry, const RpTriangle *triangle, RwUInt16 *vert1, RwUInt16 *vert2, RwUInt16 *vert3);
+RpMaterial *RpGeometryTriangleGetMaterial(const RpGeometry *geometry, const RpTriangle *triangle);
+RwInt32 RpGeometryGetNumMaterials(const RpGeometry *geometry);
+RpGeometry *RpGeometryForAllMaterials(RpGeometry *geometry, RpMaterialCallBack fpCallBack, void *pData) {
+ int i;
+ for(i = 0; i < geometry->matList.numMaterials; i++)
+ if(fpCallBack(geometry->matList.materials[i], pData) == nil)
+ break;
+ return geometry;
+}
+//const RpGeometry *RpGeometryForAllMeshes(const RpGeometry *geometry, RpMeshCallBack fpCallBack, void *pData);
+RwInt32 RpGeometryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpGeometryRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpGeometrySetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpGeometryGetPluginOffset(RwUInt32 pluginID);
+RwBool RpGeometryValidatePlugins(const RpGeometry *geometry);
+RwUInt32 RpGeometryStreamGetSize(const RpGeometry *geometry);
+const RpGeometry *RpGeometryStreamWrite(const RpGeometry *geometry, RwStream *stream);
+RpGeometry *RpGeometryStreamRead(RwStream *stream) { return Geometry::streamRead(stream); }
+//RpGeometryChunkInfo *_rpGeometryChunkInfoRead(RwStream *stream, RpGeometryChunkInfo *geometryChunkInfo, RwInt32 *bytesRead);
+RwUInt32 RpGeometryGetFlags(const RpGeometry *geometry) { return geometry->flags; }
+RpGeometry *RpGeometrySetFlags(RpGeometry *geometry, RwUInt32 flags) { geometry->flags = flags; return geometry; }
+const RwSurfaceProperties *_rpGeometryGetSurfaceProperties(const RpGeometry *geometry);
+RpGeometry *_rpGeometrySetSurfaceProperties(RpGeometry *geometry, const RwSurfaceProperties *surfaceProperties);
+
+
+
+
+
+RwFrame *RpClumpGetFrame(const RpClump * clump) { return clump->getFrame(); }
+RpClump *RpClumpSetFrame(RpClump * clump, RwFrame * frame) { clump->setFrame(frame); return clump; }
+RpClump *RpClumpForAllAtomics(RpClump * clump, RpAtomicCallBack callback, void *pData) {
+ FORLIST(lnk, clump->atomics)
+ if(callback(Atomic::fromClump(lnk), pData) == nil)
+ break;
+ return clump;
+}
+RpClump *RpClumpForAllLights(RpClump * clump, RpLightCallBack callback, void *pData);
+RpClump *RpClumpForAllCameras(RpClump * clump, RwCameraCallBack callback, void *pData);
+//RpClump *RpClumpCreateSpace(const RwV3d * position, RwReal radius);
+RpClump *RpClumpRender(RpClump * clump) { clump->render(); return clump; }
+RpClump *RpClumpRemoveAtomic(RpClump * clump, RpAtomic * atomic) { clump->removeAtomic(atomic); return clump; }
+RpClump *RpClumpAddAtomic(RpClump * clump, RpAtomic * atomic) { clump->addAtomic(atomic); return clump; }
+//RpClump *RpClumpRemoveLight(RpClump * clump, RpLight * light);
+//RpClump *RpClumpAddLight(RpClump * clump, RpLight * light);
+//RpClump *RpClumpRemoveCamera(RpClump * clump, RwCamera * camera);
+//RpClump *RpClumpAddCamera(RpClump * clump, RwCamera * camera);
+RwBool RpClumpDestroy(RpClump * clump) { clump->destroy(); return true; }
+RpClump *RpClumpCreate(void) { return rw::Clump::create(); }
+RpClump *RpClumpClone(RpClump * clump) { return clump->clone(); }
+//RpClump *RpClumpSetCallBack(RpClump * clump, RpClumpCallBack callback);
+//RpClumpCallBack RpClumpGetCallBack(const RpClump * clump);
+RwInt32 RpClumpGetNumAtomics(RpClump * clump) { return clump->countAtomics(); }
+//RwInt32 RpClumpGetNumLights(RpClump * clump);
+//RwInt32 RpClumpGetNumCameras(RpClump * clump);
+RpClump *RpClumpStreamRead(RwStream * stream) { return rw::Clump::streamRead(stream); }
+//RpClump *RpClumpStreamWrite(RpClump * clump, RwStream * stream);
+RwInt32 RpClumpRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB)
+ { return Clump::registerPlugin(size, pluginID, constructCB, destructCB, (CopyConstructor)copyCB); }
+RwInt32 RpClumpRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB)
+ { return Clump::registerPluginStream(pluginID, readCB, (StreamWrite)writeCB, (StreamGetSize)getSizeCB); }
+//RwInt32 RpClumpSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+//RwInt32 RpClumpGetPluginOffset(RwUInt32 pluginID);
+//RwBool RpClumpValidatePlugins(const RpClump * clump);
+
+
+
+RpAtomic *RpAtomicCreate(void) { return rw::Atomic::create(); }
+RwBool RpAtomicDestroy(RpAtomic * atomic) { atomic->destroy(); return true; }
+RpAtomic *RpAtomicClone(RpAtomic * atomic) { return atomic->clone(); }
+RpAtomic *RpAtomicSetFrame(RpAtomic * atomic, RwFrame * frame) { atomic->setFrame(frame); return atomic; }
+RpAtomic *RpAtomicSetGeometry(RpAtomic * atomic, RpGeometry * geometry, RwUInt32 flags) { atomic->setGeometry(geometry, flags); return atomic; }
+
+RwFrame *RpAtomicGetFrame(const RpAtomic * atomic) { return atomic->getFrame(); }
+RpAtomic *RpAtomicSetFlags(RpAtomic * atomic, RwUInt32 flags) { atomic->setFlags(flags); return atomic; }
+RwUInt32 RpAtomicGetFlags(const RpAtomic * atomic) { return atomic->getFlags(); }
+RwSphere *RpAtomicGetBoundingSphere(RpAtomic * atomic) { return &atomic->boundingSphere; }
+RpAtomic *RpAtomicRender(RpAtomic * atomic) { atomic->render(); return atomic; }
+RpClump *RpAtomicGetClump(const RpAtomic * atomic) { return atomic->clump; }
+//RpInterpolator *RpAtomicGetInterpolator(RpAtomic * atomic);
+RpGeometry *RpAtomicGetGeometry(const RpAtomic * atomic) { return atomic->geometry; }
+// WARNING: illegal cast
+void RpAtomicSetRenderCallBack(RpAtomic * atomic, RpAtomicCallBackRender callback) { atomic->setRenderCB((Atomic::RenderCB)callback); }
+RpAtomicCallBackRender RpAtomicGetRenderCallBack(const RpAtomic * atomic) { return (RpAtomicCallBackRender)atomic->renderCB; }
+//RwBool RpAtomicInstance(RpAtomic *atomic);
+//RwUInt32 RpAtomicStreamGetSize(RpAtomic * atomic);
+//RpAtomic *RpAtomicStreamRead(RwStream * stream);
+//RpAtomic *RpAtomicStreamWrite(RpAtomic * atomic, RwStream * stream);
+RwInt32 RpAtomicRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB)
+ { return Atomic::registerPlugin(size, pluginID, constructCB, destructCB, (CopyConstructor)copyCB); }
+//RwInt32 RpAtomicRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+//RwInt32 RpAtomicSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+//RwInt32 RpAtomicSetStreamRightsCallBack(RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB);
+//RwInt32 RpAtomicGetPluginOffset(RwUInt32 pluginID);
+//RwBool RpAtomicValidatePlugins(const RpAtomic * atomic);
+
+RpAtomic *AtomicDefaultRenderCallBack(RpAtomic * atomic) { Atomic::defaultRenderCB(atomic); return atomic; }
+
+
+// TODO: this is extremely simplified
+RpWorld *RpWorldCreate(RwBBox * boundingBox) { return World::create(); }
+RwBool RpWorldDestroy(RpWorld * world) { world->destroy(); return true; }
+
+RwBool RpWorldPluginAttach(void) {
+ registerMeshPlugin();
+ registerNativeDataPlugin();
+ registerAtomicRightsPlugin();
+ registerMaterialRightsPlugin();
+ return true;
+}
+
+RpWorld *RpWorldRemoveCamera(RpWorld *world, RwCamera *camera) { world->removeCamera(camera); return world; }
+RpWorld *RpWorldAddCamera(RpWorld *world, RwCamera *camera) { world->addCamera(camera); return world; }
+RpWorld *RwCameraGetWorld(const RwCamera *camera);
+RpWorld *RpWorldRemoveAtomic(RpWorld *world, RpAtomic *atomic);
+RpWorld *RpWorldAddAtomic(RpWorld *world, RpAtomic *atomic);
+RpWorld *RpAtomicGetWorld(const RpAtomic *atomic);
+RpWorld *RpWorldAddClump(RpWorld *world, RpClump *clump);
+RpWorld *RpWorldRemoveClump(RpWorld *world, RpClump *clump);
+RpWorld *RpClumpGetWorld(const RpClump *clump);
+RpWorld *RpWorldAddLight(RpWorld *world, RpLight *light) { world->addLight(light); return world; }
+RpWorld *RpWorldRemoveLight(RpWorld *world, RpLight *light) { world->removeLight(light); return world; }
+RpWorld *RpLightGetWorld(const RpLight *light);
+RwCamera *RwCameraForAllClumpsInFrustum(RwCamera *camera, void *data);
+RwCamera *RwCameraForAllClumpsNotInFrustum(RwCamera *camera, RwInt32 numClumps, void *data);
+
+
+
+
+RwBool RpMatFXPluginAttach( void ) { registerMatFXPlugin(); return true; }
+RpAtomic *RpMatFXAtomicEnableEffects( RpAtomic *atomic ) { MatFX::enableEffects(atomic); return atomic; }
+RpMaterial *RpMatFXMaterialSetEffects( RpMaterial *material, RpMatFXMaterialFlags flags ) { MatFX::setEffects(material, (uint32)flags); return material; }
+RpMaterial *RpMatFXMaterialSetupEnvMap( RpMaterial *material, RwTexture *texture, RwFrame *frame, RwBool useFrameBufferAlpha, RwReal coef ) {
+ MatFX *mfx = MatFX::get(material);
+ mfx->setEnvTexture(texture);
+ mfx->setEnvFrame(frame);
+ mfx->setEnvCoefficient(coef);
+ return material;
+}
+
+
+
+
+
+RwBool RpHAnimPluginAttach(void) {
+ registerHAnimPlugin();
+ return true;
+}
+
+RwInt32 RpHAnimFrameGetID(RwFrame *frame) { return HAnimData::get(frame)->id; }
+
+RwInt32 RpHAnimIDGetIndex(RpHAnimHierarchy *hierarchy, RwInt32 ID) { return hierarchy->getIndex(ID); }
+
+RwBool RpHAnimFrameSetHierarchy(RwFrame *frame, RpHAnimHierarchy *hierarchy) { HAnimData::get(frame)->hierarchy = hierarchy; return true; }
+RpHAnimHierarchy *RpHAnimFrameGetHierarchy(RwFrame *frame) { return HAnimHierarchy::get(frame); }
+
+RpHAnimHierarchy *RpHAnimHierarchySetFlags(RpHAnimHierarchy *hierarchy, RpHAnimHierarchyFlag flags) { hierarchy->flags = flags; return hierarchy; }
+
+RwBool RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy *hierarchy, RpHAnimAnimation *anim) { hierarchy->interpolator->setCurrentAnim(anim); return true; }
+RwBool RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy *hierarchy, RwReal time) { hierarchy->interpolator->addTime(time); return true; }
+
+RwMatrix *RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy *hierarchy) { return hierarchy->matrices; }
+RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy *hierarchy) { hierarchy->updateMatrices(); return true; }
+
+RpHAnimAnimation *RpHAnimAnimationCreate(RwInt32 typeID, RwInt32 numFrames, RwInt32 flags, RwReal duration)
+ { return Animation::create(AnimInterpolatorInfo::find(typeID), numFrames, flags, duration); }
+RpHAnimAnimation *RpHAnimAnimationDestroy(RpHAnimAnimation *animation) { animation->destroy(); return animation; }
+RpHAnimAnimation *RpHAnimAnimationStreamRead(RwStream *stream) { return Animation::streamRead(stream); }
+
+
+
+
+
+
+RwBool RpSkinPluginAttach(void) {
+ registerSkinPlugin();
+ return true;
+}
+
+RwUInt32 RpSkinGetNumBones( RpSkin *skin ) { return skin->numBones; }
+const RwMatrixWeights *RpSkinGetVertexBoneWeights( RpSkin *skin ) { return (RwMatrixWeights*)skin->weights; }
+const RwUInt32 *RpSkinGetVertexBoneIndices( RpSkin *skin ) { return (RwUInt32*)skin->indices; }
+const RwMatrix *RpSkinGetSkinToBoneMatrices( RpSkin *skin ) { return (const RwMatrix*)skin->inverseMatrices; }
+
+RpSkin *RpSkinGeometryGetSkin( RpGeometry *geometry ) { return Skin::get(geometry); }
+
+RpAtomic *RpSkinAtomicSetHAnimHierarchy( RpAtomic *atomic, RpHAnimHierarchy *hierarchy ) { Skin::setHierarchy(atomic, hierarchy); return atomic; }
+RpHAnimHierarchy *RpSkinAtomicGetHAnimHierarchy( const RpAtomic *atomic ) { return Skin::getHierarchy(atomic); }
+
+
+
+
+
+RwImage *RtBMPImageWrite(RwImage * image, const RwChar * imageName) { rw::writeBMP(image, imageName); return image; }
+RwImage *RtBMPImageRead(const RwChar * imageName) { return rw::readBMP(imageName); }
+
+#include "rtquat.h"
+
+RtQuat *RtQuatRotate(RtQuat * quat, const RwV3d * axis, RwReal angle, RwOpCombineType combineOp) { return (RtQuat*)((rw::Quat*)quat)->rotate(axis, angle/180.0f*3.14159f, (CombineOp)combineOp); }
+void RtQuatConvertToMatrix(const RtQuat * const qpQuat, RwMatrix * const mpMatrix) { mpMatrix->rotate(*(rw::Quat*)qpQuat, COMBINEREPLACE); }
+
+
+#include "rtcharse.h"
+
+RwBool RtCharsetOpen(void) { return Charset::open(); }
+void RtCharsetClose(void) { return Charset::close(); }
+RtCharset *RtCharsetPrint(RtCharset * charSet, const RwChar * string, RwInt32 x, RwInt32 y) { charSet->print(string, x, y, true); return charSet; }
+RtCharset *RtCharsetPrintBuffered(RtCharset * charSet, const RwChar * string, RwInt32 x, RwInt32 y, RwBool hideSpaces) { charSet->printBuffered(string, x, y, hideSpaces); return charSet; }
+RwBool RtCharsetBufferFlush(void) { Charset::flushBuffer(); return true; }
+RtCharset *RtCharsetSetColors(RtCharset * charSet, const RwRGBA * foreGround, const RwRGBA * backGround) { return charSet->setColors(foreGround, backGround); }
+RtCharset *RtCharsetGetDesc(RtCharset * charset, RtCharsetDesc * desc) { *desc = charset->desc; return charset; }
+RtCharset *RtCharsetCreate(const RwRGBA * foreGround, const RwRGBA * backGround) { return Charset::create(foreGround, backGround); }
+RwBool RtCharsetDestroy(RtCharset * charSet) { charSet->destroy(); return true; }
+
+
+
+// fake shit
+RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { return 1; }
diff --git a/src/fakerw/rphanim.h b/src/fakerw/rphanim.h
new file mode 100644
index 00000000..6ece8306
--- /dev/null
+++ b/src/fakerw/rphanim.h
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "rtquat.h"
+
+//struct RpHAnimHierarchy;
+typedef rw::HAnimHierarchy RpHAnimHierarchy;
+//struct RpHAnimAnimation;
+typedef rw::Animation RpHAnimAnimation;
+
+#define rpHANIMSTDKEYFRAMETYPEID 0x1
+
+// same as rw::HAnimKeyFrame, but we need RtQuat in this one
+struct RpHAnimStdKeyFrame
+{
+ RpHAnimStdKeyFrame *prevFrame;
+ RwReal time;
+ RtQuat q;
+ RwV3d t;
+};
+
+
+enum RpHAnimHierarchyFlag
+{
+ rpHANIMHIERARCHYSUBHIERARCHY = rw::HAnimHierarchy::SUBHIERARCHY,
+ rpHANIMHIERARCHYNOMATRICES = rw::HAnimHierarchy::NOMATRICES,
+
+ rpHANIMHIERARCHYUPDATEMODELLINGMATRICES = rw::HAnimHierarchy::UPDATEMODELLINGMATRICES,
+ rpHANIMHIERARCHYUPDATELTMS = rw::HAnimHierarchy::UPDATELTMS,
+ rpHANIMHIERARCHYLOCALSPACEMATRICES = rw::HAnimHierarchy::LOCALSPACEMATRICES
+};
+
+#define rpHANIMPOPPARENTMATRIX rw::HAnimHierarchy::POP
+#define rpHANIMPUSHPARENTMATRIX rw::HAnimHierarchy::PUSH
+
+RwBool RpHAnimPluginAttach(void);
+
+RwBool RpHAnimFrameSetID(RwFrame *frame, RwInt32 id);
+RwInt32 RpHAnimFrameGetID(RwFrame *frame);
+
+RwInt32 RpHAnimIDGetIndex(RpHAnimHierarchy *hierarchy, RwInt32 ID);
+
+RwBool RpHAnimFrameSetHierarchy(RwFrame *frame, RpHAnimHierarchy *hierarchy);
+RpHAnimHierarchy *RpHAnimFrameGetHierarchy(RwFrame *frame);
+
+RpHAnimHierarchy *RpHAnimHierarchySetFlags(RpHAnimHierarchy *hierarchy, RpHAnimHierarchyFlag flags);
+RpHAnimHierarchyFlag RpHAnimHierarchyGetFlags(RpHAnimHierarchy *hierarchy);
+
+RwBool RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy *hierarchy, RpHAnimAnimation *anim);
+RwBool RpHAnimHierarchySetCurrentAnimTime(RpHAnimHierarchy *hierarchy, RwReal time);
+RwBool RpHAnimHierarchySubAnimTime(RpHAnimHierarchy *hierarchy, RwReal time);
+RwBool RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy *hierarchy, RwReal time);
+
+RwMatrix *RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy *hierarchy);
+RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy *hierarchy);
+
+#define rpHANIMHIERARCHYGETINTERPFRAME( hierarchy, nodeIndex ) \
+ ( (void *)( ( (RwUInt8 *)&(hierarchy->interpolator[1]) + \
+ ((nodeIndex) * \
+ hierarchy->interpolator->currentAnimKeyFrameSize) ) ) )
+
+
+RpHAnimAnimation *RpHAnimAnimationCreate(RwInt32 typeID, RwInt32 numFrames, RwInt32 flags, RwReal duration);
+RpHAnimAnimation *RpHAnimAnimationDestroy(RpHAnimAnimation *animation);
+RpHAnimAnimation *RpHAnimAnimationStreamRead(RwStream *stream);
diff --git a/src/fakerw/rpmatfx.h b/src/fakerw/rpmatfx.h
new file mode 100644
index 00000000..87c8fb2e
--- /dev/null
+++ b/src/fakerw/rpmatfx.h
@@ -0,0 +1,43 @@
+#pragma once
+
+enum RpMatFXMaterialFlags
+{
+ rpMATFXEFFECTNULL = rw::MatFX::NOTHING,
+ rpMATFXEFFECTBUMPMAP = rw::MatFX::BUMPMAP,
+ rpMATFXEFFECTENVMAP = rw::MatFX::ENVMAP,
+ rpMATFXEFFECTBUMPENVMAP = rw::MatFX::BUMPENVMAP,
+ rpMATFXEFFECTDUAL = rw::MatFX::DUAL,
+
+ rpMATFXEFFECTMAX,
+ rpMATFXNUMEFFECTS = rpMATFXEFFECTMAX - 1,
+};
+
+RwBool RpMatFXPluginAttach( void );
+RpAtomic *RpMatFXAtomicEnableEffects( RpAtomic *atomic );
+RwBool RpMatFXAtomicQueryEffects( RpAtomic *atomic );
+//RpWorldSector *RpMatFXWorldSectorEnableEffects( RpWorldSector *worldSector );
+//RwBool RpMatFXWorldSectorQueryEffects( RpWorldSector *worldSector );
+RpMaterial *RpMatFXMaterialSetEffects( RpMaterial *material, RpMatFXMaterialFlags flags );
+RpMaterial *RpMatFXMaterialSetupBumpMap( RpMaterial *material, RwTexture *texture, RwFrame *frame, RwReal coef );
+RpMaterial *RpMatFXMaterialSetupEnvMap( RpMaterial *material, RwTexture *texture, RwFrame *frame, RwBool useFrameBufferAlpha, RwReal coef );
+RpMaterial *RpMatFXMaterialSetupDualTexture( RpMaterial *material, RwTexture *texture, RwBlendFunction srcBlendMode, RwBlendFunction dstBlendMode );
+RpMatFXMaterialFlags RpMatFXMaterialGetEffects( const RpMaterial *material );
+RpMaterial *RpMatFXMaterialSetBumpMapTexture( RpMaterial *material, RwTexture *texture );
+RpMaterial *RpMatFXMaterialSetBumpMapFrame( RpMaterial *material, RwFrame *frame );
+RpMaterial *RpMatFXMaterialSetBumpMapCoefficient( RpMaterial *material, RwReal coef );
+RwTexture *RpMatFXMaterialGetBumpMapTexture( const RpMaterial *material );
+RwTexture *RpMatFXMaterialGetBumpMapBumpedTexture( const RpMaterial *material );
+RwFrame *RpMatFXMaterialGetBumpMapFrame( const RpMaterial *material );
+RwReal RpMatFXMaterialGetBumpMapCoefficient( const RpMaterial *material );
+RpMaterial *RpMatFXMaterialSetEnvMapTexture( RpMaterial *material, RwTexture *texture );
+RpMaterial *RpMatFXMaterialSetEnvMapFrame( RpMaterial *material, RwFrame *frame );
+RpMaterial *RpMatFXMaterialSetEnvMapFrameBufferAlpha( RpMaterial *material, RwBool useFrameBufferAlpha );
+RpMaterial *RpMatFXMaterialSetEnvMapCoefficient( RpMaterial *material, RwReal coef );
+RwTexture *RpMatFXMaterialGetEnvMapTexture( const RpMaterial *material );
+RwFrame *RpMatFXMaterialGetEnvMapFrame( const RpMaterial *material );
+RwBool RpMatFXMaterialGetEnvMapFrameBufferAlpha( const RpMaterial *material );
+RwReal RpMatFXMaterialGetEnvMapCoefficient( const RpMaterial *material );
+RpMaterial *RpMatFXMaterialSetDualTexture( RpMaterial *material, RwTexture *texture );
+RpMaterial *RpMatFXMaterialSetDualBlendModes( RpMaterial *material, RwBlendFunction srcBlendMode, RwBlendFunction dstBlendMode );
+RwTexture *RpMatFXMaterialGetDualTexture( const RpMaterial *material );
+const RpMaterial *RpMatFXMaterialGetDualBlendModes( const RpMaterial *material, RwBlendFunction *srcBlendMode, RwBlendFunction *dstBlendMode );
diff --git a/src/fakerw/rpskin.h b/src/fakerw/rpskin.h
new file mode 100644
index 00000000..1ffc9f27
--- /dev/null
+++ b/src/fakerw/rpskin.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <rphanim.h>
+
+//struct RpSkin;
+typedef rw::Skin RpSkin;
+
+struct RwMatrixWeights
+{
+ RwReal w0;
+ RwReal w1;
+ RwReal w2;
+ RwReal w3;
+};
+
+RwBool RpSkinPluginAttach(void);
+
+RwUInt32 RpSkinGetNumBones( RpSkin *skin );
+const RwMatrixWeights *RpSkinGetVertexBoneWeights( RpSkin *skin );
+const RwUInt32 *RpSkinGetVertexBoneIndices( RpSkin *skin );
+const RwMatrix *RpSkinGetSkinToBoneMatrices( RpSkin *skin );
+
+RpSkin *RpSkinGeometryGetSkin( RpGeometry *geometry );
+
+RpAtomic *RpSkinAtomicSetHAnimHierarchy( RpAtomic *atomic, RpHAnimHierarchy *hierarchy );
+RpHAnimHierarchy *RpSkinAtomicGetHAnimHierarchy( const RpAtomic *atomic );
diff --git a/src/fakerw/rpworld.h b/src/fakerw/rpworld.h
new file mode 100644
index 00000000..f10a3754
--- /dev/null
+++ b/src/fakerw/rpworld.h
@@ -0,0 +1,336 @@
+#pragma once
+
+#define rpATOMIC rw::Atomic::ID
+#define rpCLUMP rw::Clump::ID
+
+/*
+ ***********************************************
+ *
+ * RpMaterial
+ *
+ ***********************************************
+ */
+
+//struct RpMaterial;
+typedef rw::Material RpMaterial;
+
+typedef RpMaterial *(*RpMaterialCallBack)(RpMaterial *material, void *data);
+
+RpMaterial *RpMaterialCreate(void);
+RwBool RpMaterialDestroy(RpMaterial *material);
+RpMaterial *RpMaterialClone(RpMaterial *material);
+RpMaterial *RpMaterialSetTexture(RpMaterial *material, RwTexture *texture);
+RpMaterial *RpMaterialAddRef(RpMaterial *material);
+RwTexture *RpMaterialGetTexture(const RpMaterial *material);
+RpMaterial *RpMaterialSetColor(RpMaterial *material, const RwRGBA *color);
+const RwRGBA *RpMaterialGetColor(const RpMaterial *material);
+RpMaterial *RpMaterialSetSurfaceProperties(RpMaterial *material, const RwSurfaceProperties *surfaceProperties);
+const RwSurfaceProperties *RpMaterialGetSurfaceProperties(const RpMaterial *material);
+RwInt32 RpMaterialRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpMaterialRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpMaterialSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpMaterialGetPluginOffset(RwUInt32 pluginID);
+RwBool RpMaterialValidatePlugins(const RpMaterial *material);
+RwUInt32 RpMaterialStreamGetSize(const RpMaterial *material);
+RpMaterial *RpMaterialStreamRead(RwStream *stream);
+const RpMaterial *RpMaterialStreamWrite(const RpMaterial *material, RwStream *stream);
+//RpMaterialChunkInfo *_rpMaterialChunkInfoRead(RwStream *stream, RpMaterialChunkInfo *materialChunkInfo, RwInt32 *bytesRead);
+
+
+/*
+ ***********************************************
+ *
+ * RpLight
+ *
+ ***********************************************
+ */
+
+//struct RpLight;
+typedef rw::Light RpLight;
+
+enum RpLightType
+{
+ rpNALIGHTTYPE = 0,
+ rpLIGHTDIRECTIONAL,
+ rpLIGHTAMBIENT,
+ rpLIGHTPOINT = 0x80,
+ rpLIGHTSPOT,
+ rpLIGHTSPOTSOFT,
+};
+
+enum RpLightFlag
+{
+ rpLIGHTLIGHTATOMICS = 0x01,
+ rpLIGHTLIGHTWORLD = 0x02,
+};
+
+typedef RpLight *(*RpLightCallBack) (RpLight * light, void *data);
+
+RwReal RpLightGetRadius(const RpLight *light);
+const RwRGBAReal *RpLightGetColor(const RpLight *light);
+RpLight *RpLightSetFrame(RpLight *light, RwFrame *frame);
+RwFrame *RpLightGetFrame(const RpLight *light);
+RpLightType RpLightGetType(const RpLight *light);
+RpLight *RpLightSetFlags(RpLight *light, RwUInt32 flags);
+RwUInt32 RpLightGetFlags(const RpLight *light);
+RpLight *RpLightCreate(RwInt32 type);
+RwBool RpLightDestroy(RpLight *light);
+RpLight *RpLightSetRadius(RpLight *light, RwReal radius);
+RpLight *RpLightSetColor(RpLight *light, const RwRGBAReal *color);
+RwReal RpLightGetConeAngle(const RpLight *light);
+RpLight *RpLightSetConeAngle(RpLight * ight, RwReal angle);
+RwUInt32 RpLightStreamGetSize(const RpLight *light);
+RpLight *RpLightStreamRead(RwStream *stream);
+const RpLight *RpLightStreamWrite(const RpLight *light, RwStream *stream);
+//RpLightChunkInfo *_rpLightChunkInfoRead(RwStream *stream, RpLightChunkInfo *lightChunkInfo, RwInt32 *bytesRead);
+RwInt32 RpLightRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpLightRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpLightSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpLightGetPluginOffset(RwUInt32 pluginID);
+RwBool RpLightValidatePlugins(const RpLight * light);
+
+/*
+ ***********************************************
+ *
+ * RpGeometry
+ *
+ ***********************************************
+ */
+
+typedef rw::Triangle RpTriangle;
+
+//struct RpGeometry;
+typedef rw::Geometry RpGeometry;
+//struct RpMorphTarget;
+typedef rw::MorphTarget RpMorphTarget;
+
+enum RpGeometryFlag
+{
+ rpGEOMETRYTRISTRIP = rw::Geometry::TRISTRIP,
+ rpGEOMETRYPOSITIONS = rw::Geometry::POSITIONS,
+ rpGEOMETRYTEXTURED = rw::Geometry::TEXTURED,
+ rpGEOMETRYPRELIT = rw::Geometry::PRELIT,
+ rpGEOMETRYNORMALS = rw::Geometry::NORMALS,
+ rpGEOMETRYLIGHT = rw::Geometry::LIGHT,
+ rpGEOMETRYMODULATEMATERIALCOLOR = rw::Geometry::MODULATE,
+ rpGEOMETRYTEXTURED2 = rw::Geometry::TEXTURED2,
+ rpGEOMETRYNATIVE = rw::Geometry::NATIVE,
+ rpGEOMETRYNATIVEINSTANCE = rw::Geometry::NATIVEINSTANCE,
+ rpGEOMETRYFLAGSMASK = 0x000000FF,
+ rpGEOMETRYNATIVEFLAGSMASK = 0x0F000000,
+};
+
+enum RpGeometryLockMode
+{
+ rpGEOMETRYLOCKPOLYGONS = rw::Geometry::LOCKPOLYGONS,
+ rpGEOMETRYLOCKVERTICES = rw::Geometry::LOCKVERTICES,
+ rpGEOMETRYLOCKNORMALS = rw::Geometry::LOCKNORMALS,
+ rpGEOMETRYLOCKPRELIGHT = rw::Geometry::LOCKPRELIGHT,
+ rpGEOMETRYLOCKTEXCOORDS = rw::Geometry::LOCKTEXCOORDS,
+ rpGEOMETRYLOCKTEXCOORDS1 = rw::Geometry::LOCKTEXCOORDS1,
+ rpGEOMETRYLOCKTEXCOORDS2 = rw::Geometry::LOCKTEXCOORDS2,
+ rpGEOMETRYLOCKTEXCOORDS3 = rw::Geometry::LOCKTEXCOORDS3,
+ rpGEOMETRYLOCKTEXCOORDS4 = rw::Geometry::LOCKTEXCOORDS4,
+ rpGEOMETRYLOCKTEXCOORDS5 = rw::Geometry::LOCKTEXCOORDS5,
+ rpGEOMETRYLOCKTEXCOORDS6 = rw::Geometry::LOCKTEXCOORDS6,
+ rpGEOMETRYLOCKTEXCOORDS7 = rw::Geometry::LOCKTEXCOORDS7,
+ rpGEOMETRYLOCKTEXCOORDS8 = rw::Geometry::LOCKTEXCOORDS8,
+ rpGEOMETRYLOCKTEXCOORDSALL = rw::Geometry::LOCKTEXCOORDSALL,
+ rpGEOMETRYLOCKALL = rw::Geometry::LOCKALL
+};
+
+RpGeometry *RpGeometryCreate(RwInt32 numVert, RwInt32 numTriangles, RwUInt32 format);
+RwBool RpGeometryDestroy(RpGeometry *geometry);
+RpGeometry *_rpGeometryAddRef(RpGeometry *geometry);
+RpGeometry *RpGeometryLock(RpGeometry *geometry, RwInt32 lockMode);
+RpGeometry *RpGeometryUnlock(RpGeometry *geometry);
+RpGeometry *RpGeometryTransform(RpGeometry *geometry, const RwMatrix *matrix);
+RpGeometry *RpGeometryCreateSpace(RwReal radius);
+RpMorphTarget *RpMorphTargetSetBoundingSphere(RpMorphTarget *morphTarget, const RwSphere *boundingSphere);
+RwSphere *RpMorphTargetGetBoundingSphere(RpMorphTarget *morphTarget);
+const RpMorphTarget *RpMorphTargetCalcBoundingSphere(const RpMorphTarget *morphTarget, RwSphere *boundingSphere);
+RwInt32 RpGeometryAddMorphTargets(RpGeometry *geometry, RwInt32 mtcount);
+RwInt32 RpGeometryAddMorphTarget(RpGeometry *geometry);
+RpGeometry *RpGeometryRemoveMorphTarget(RpGeometry *geometry, RwInt32 morphTarget);
+RwInt32 RpGeometryGetNumMorphTargets(const RpGeometry *geometry);
+RpMorphTarget *RpGeometryGetMorphTarget(const RpGeometry *geometry, RwInt32 morphTarget);
+RwRGBA *RpGeometryGetPreLightColors(const RpGeometry *geometry);
+RwTexCoords *RpGeometryGetVertexTexCoords(const RpGeometry *geometry, RwTextureCoordinateIndex uvIndex);
+RwInt32 RpGeometryGetNumTexCoordSets(const RpGeometry *geometry);
+RwInt32 RpGeometryGetNumVertices (const RpGeometry *geometry);
+RwV3d *RpMorphTargetGetVertices(const RpMorphTarget *morphTarget);
+RwV3d *RpMorphTargetGetVertexNormals(const RpMorphTarget *morphTarget);
+RpTriangle *RpGeometryGetTriangles(const RpGeometry *geometry);
+RwInt32 RpGeometryGetNumTriangles(const RpGeometry *geometry);
+RpMaterial *RpGeometryGetMaterial(const RpGeometry *geometry, RwInt32 matNum);
+const RpGeometry *RpGeometryTriangleSetVertexIndices(const RpGeometry *geometry, RpTriangle *triangle, RwUInt16 vert1, RwUInt16 vert2, RwUInt16 vert3);
+RpGeometry *RpGeometryTriangleSetMaterial(RpGeometry *geometry, RpTriangle *triangle, RpMaterial *material);
+const RpGeometry *RpGeometryTriangleGetVertexIndices(const RpGeometry *geometry, const RpTriangle *triangle, RwUInt16 *vert1, RwUInt16 *vert2, RwUInt16 *vert3);
+RpMaterial *RpGeometryTriangleGetMaterial(const RpGeometry *geometry, const RpTriangle *triangle);
+RwInt32 RpGeometryGetNumMaterials(const RpGeometry *geometry);
+RpGeometry *RpGeometryForAllMaterials(RpGeometry *geometry, RpMaterialCallBack fpCallBack, void *pData);
+//const RpGeometry *RpGeometryForAllMeshes(const RpGeometry *geometry, RpMeshCallBack fpCallBack, void *pData);
+RwInt32 RpGeometryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpGeometryRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpGeometrySetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpGeometryGetPluginOffset(RwUInt32 pluginID);
+RwBool RpGeometryValidatePlugins(const RpGeometry *geometry);
+RwUInt32 RpGeometryStreamGetSize(const RpGeometry *geometry);
+const RpGeometry *RpGeometryStreamWrite(const RpGeometry *geometry, RwStream *stream);
+RpGeometry *RpGeometryStreamRead(RwStream *stream);
+//RpGeometryChunkInfo *_rpGeometryChunkInfoRead(RwStream *stream, RpGeometryChunkInfo *geometryChunkInfo, RwInt32 *bytesRead);
+RwUInt32 RpGeometryGetFlags(const RpGeometry *geometry);
+RpGeometry *RpGeometrySetFlags(RpGeometry *geometry, RwUInt32 flags);
+const RwSurfaceProperties *_rpGeometryGetSurfaceProperties(const RpGeometry *geometry);
+RpGeometry *_rpGeometrySetSurfaceProperties(RpGeometry *geometry, const RwSurfaceProperties *surfaceProperties);
+
+
+/*
+ ***********************************************
+ *
+ * RpAtomic and RpClump
+ *
+ ***********************************************
+ */
+
+//struct RpAtomic;
+typedef rw::Atomic RpAtomic;
+
+enum RpAtomicFlag
+{
+ rpATOMICCOLLISIONTEST = 0x01,
+ rpATOMICRENDER = 0x04,
+};
+
+enum RpAtomicSetGeomFlag
+{
+ rpATOMICSAMEBOUNDINGSPHERE = 0x01,
+};
+
+typedef RpAtomic *(*RpAtomicCallBack) (RpAtomic * atomic, void *data);
+typedef RpAtomic *(*RpAtomicCallBackRender) (RpAtomic * atomic);
+
+
+//struct RpClump;
+typedef rw::Clump RpClump;
+
+struct RpClumpChunkInfo
+{
+ RwInt32 numAtomics;
+ RwInt32 numLights;
+ RwInt32 numCameras;
+};
+
+typedef RpClump *(*RpClumpCallBack) (RpClump * clump, void *data);
+
+
+RpAtomic *AtomicDefaultRenderCallBack(RpAtomic * atomic);
+//void _rpAtomicResyncInterpolatedSphere(RpAtomic * atomic);
+//const RwSphere *RpAtomicGetWorldBoundingSphere(RpAtomic * atomic);
+
+RwFrame *RpClumpGetFrame(const RpClump * clump);
+RpClump *RpClumpSetFrame(RpClump * clump, RwFrame * frame);
+RpClump *RpClumpForAllAtomics(RpClump * clump, RpAtomicCallBack callback, void *pData);
+RpClump *RpClumpForAllLights(RpClump * clump, RpLightCallBack callback, void *pData);
+RpClump *RpClumpForAllCameras(RpClump * clump, RwCameraCallBack callback, void *pData);
+RpClump *RpClumpCreateSpace(const RwV3d * position, RwReal radius);
+RpClump *RpClumpRender(RpClump * clump);
+RpClump *RpClumpRemoveAtomic(RpClump * clump, RpAtomic * atomic);
+RpClump *RpClumpAddAtomic(RpClump * clump, RpAtomic * atomic);
+RpClump *RpClumpRemoveLight(RpClump * clump, RpLight * light);
+RpClump *RpClumpAddLight(RpClump * clump, RpLight * light);
+RpClump *RpClumpRemoveCamera(RpClump * clump, RwCamera * camera);
+RpClump *RpClumpAddCamera(RpClump * clump, RwCamera * camera);
+RwBool RpClumpDestroy(RpClump * clump);
+RpClump *RpClumpCreate(void);
+RpClump *RpClumpClone(RpClump * clump);
+RpClump *RpClumpSetCallBack(RpClump * clump, RpClumpCallBack callback);
+RpClumpCallBack RpClumpGetCallBack(const RpClump * clump);
+RwInt32 RpClumpGetNumAtomics(RpClump * clump);
+RwInt32 RpClumpGetNumLights(RpClump * clump);
+RwInt32 RpClumpGetNumCameras(RpClump * clump);
+RwUInt32 RpClumpStreamGetSize(RpClump * clump);
+RpClump *RpClumpStreamRead(RwStream * stream);
+RpClump *RpClumpStreamWrite(RpClump * clump, RwStream * stream);
+RwInt32 RpClumpRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpClumpRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpClumpSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpClumpGetPluginOffset(RwUInt32 pluginID);
+RwBool RpClumpValidatePlugins(const RpClump * clump);
+
+RpAtomic *RpAtomicCreate(void);
+RwBool RpAtomicDestroy(RpAtomic * atomic);
+RpAtomic *RpAtomicClone(RpAtomic * atomic);
+RpAtomic *RpAtomicSetFrame(RpAtomic * atomic, RwFrame * frame);
+RpAtomic *RpAtomicSetGeometry(RpAtomic * atomic, RpGeometry * geometry, RwUInt32 flags);
+
+RwFrame *RpAtomicGetFrame(const RpAtomic * atomic);
+RpAtomic *RpAtomicSetFlags(RpAtomic * atomic, RwUInt32 flags);
+RwUInt32 RpAtomicGetFlags(const RpAtomic * atomic);
+RwSphere *RpAtomicGetBoundingSphere(RpAtomic * atomic);
+RpAtomic *RpAtomicRender(RpAtomic * atomic);
+RpClump *RpAtomicGetClump(const RpAtomic * atomic);
+//RpInterpolator *RpAtomicGetInterpolator(RpAtomic * atomic);
+RpGeometry *RpAtomicGetGeometry(const RpAtomic * atomic);
+void RpAtomicSetRenderCallBack(RpAtomic * atomic, RpAtomicCallBackRender callback);
+RpAtomicCallBackRender RpAtomicGetRenderCallBack(const RpAtomic * atomic);
+RwBool RpAtomicInstance(RpAtomic *atomic);
+RwUInt32 RpAtomicStreamGetSize(RpAtomic * atomic);
+RpAtomic *RpAtomicStreamRead(RwStream * stream);
+RpAtomic *RpAtomicStreamWrite(RpAtomic * atomic, RwStream * stream);
+RwInt32 RpAtomicRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RpAtomicRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RpAtomicSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+RwInt32 RpAtomicSetStreamRightsCallBack(RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB);
+RwInt32 RpAtomicGetPluginOffset(RwUInt32 pluginID);
+RwBool RpAtomicValidatePlugins(const RpAtomic * atomic);
+
+//RwInt32 RpInterpolatorGetEndMorphTarget(const RpInterpolator * interpolator);
+//RwInt32 RpInterpolatorGetStartMorphTarget(const RpInterpolator * interpolator);
+//RwReal RpInterpolatorGetValue(const RpInterpolator * interpolator);
+//RwReal RpInterpolatorGetScale(const RpInterpolator * interpolator);
+//RpInterpolator *RpInterpolatorSetEndMorphTarget(RpInterpolator * interpolator, RwInt32 morphTarget, RpAtomic * atomic);
+//RpInterpolator *RpInterpolatorSetStartMorphTarget(RpInterpolator * interpolator, RwInt32 morphTarget, RpAtomic * atomic);
+//RpInterpolator *RpInterpolatorSetValue(RpInterpolator * interpolator, RwReal value, RpAtomic *atomic);
+//RpInterpolator *RpInterpolatorSetScale(RpInterpolator * interpolator, RwReal scale, RpAtomic *atomic);
+
+
+RpClump *RpLightGetClump(const RpLight *light);
+RpClump *RwCameraGetClump(const RwCamera *camera);
+
+/*
+ ***********************************************
+ *
+ * RpWorld
+ *
+ ***********************************************
+ */
+
+//struct RpWorld;
+typedef rw::World RpWorld;
+
+RwBool RpWorldDestroy(RpWorld * world);
+RpWorld *RpWorldCreate(RwBBox * boundingBox);
+
+RwBool RpWorldPluginAttach(void);
+
+RpWorld *RpWorldRemoveCamera(RpWorld *world, RwCamera *camera);
+RpWorld *RpWorldAddCamera(RpWorld *world, RwCamera *camera);
+RpWorld *RwCameraGetWorld(const RwCamera *camera);
+RpWorld *RpWorldRemoveAtomic(RpWorld *world, RpAtomic *atomic);
+RpWorld *RpWorldAddAtomic(RpWorld *world, RpAtomic *atomic);
+RpWorld *RpAtomicGetWorld(const RpAtomic *atomic);
+RpWorld *RpWorldAddClump(RpWorld *world, RpClump *clump);
+RpWorld *RpWorldRemoveClump(RpWorld *world, RpClump *clump);
+RpWorld *RpClumpGetWorld(const RpClump *clump);
+RpWorld *RpWorldAddLight(RpWorld *world, RpLight *light);
+RpWorld *RpWorldRemoveLight(RpWorld *world, RpLight *light);
+RpWorld *RpLightGetWorld(const RpLight *light);
+RwCamera *RwCameraForAllClumpsInFrustum(RwCamera *camera, void *data);
+RwCamera *RwCameraForAllClumpsNotInFrustum(RwCamera *camera, RwInt32 numClumps, void *data);
+//RwCamera *RwCameraForAllSectorsInFrustum(RwCamera *camera, RpWorldSectorCallBack callBack, void *pData);
+//RpLight *RpLightForAllWorldSectors(RpLight *light, RpWorldSectorCallBack callback, void *data);
+//RpAtomic *RpAtomicForAllWorldSectors(RpAtomic *atomic, RpWorldSectorCallBack callback, void *data);
+//RpWorldSector *RpWorldSectorForAllAtomics(RpWorldSector *sector, RpAtomicCallBack callback, void *data);
+//RpWorldSector *RpWorldSectorForAllCollisionAtomics(RpWorldSector *sector, RpAtomicCallBack callback, void *data);
+//RpWorldSector *RpWorldSectorForAllLights(RpWorldSector *sector, RpLightCallBack callback, void *data);
diff --git a/src/fakerw/rtbmp.h b/src/fakerw/rtbmp.h
new file mode 100644
index 00000000..896d276b
--- /dev/null
+++ b/src/fakerw/rtbmp.h
@@ -0,0 +1,4 @@
+#pragma once
+
+RwImage *RtBMPImageWrite(RwImage * image, const RwChar * imageName);
+RwImage *RtBMPImageRead(const RwChar * imageName);
diff --git a/src/fakerw/rtcharse.h b/src/fakerw/rtcharse.h
new file mode 100644
index 00000000..10eb1f32
--- /dev/null
+++ b/src/fakerw/rtcharse.h
@@ -0,0 +1,14 @@
+#pragma once
+
+typedef rw::Charset RtCharset;
+typedef rw::Charset::Desc RtCharsetDesc;
+
+RwBool RtCharsetOpen(void);
+void RtCharsetClose(void);
+RtCharset *RtCharsetPrint(RtCharset * charSet, const RwChar * string, RwInt32 x, RwInt32 y);
+RtCharset *RtCharsetPrintBuffered(RtCharset * charSet, const RwChar * string, RwInt32 x, RwInt32 y, RwBool hideSpaces);
+RwBool RtCharsetBufferFlush(void);
+RtCharset *RtCharsetSetColors(RtCharset * charSet, const RwRGBA * foreGround, const RwRGBA * backGround);
+RtCharset *RtCharsetGetDesc(RtCharset * charset, RtCharsetDesc * desc);
+RtCharset *RtCharsetCreate(const RwRGBA * foreGround, const RwRGBA * backGround);
+RwBool RtCharsetDestroy(RtCharset * charSet);
diff --git a/src/fakerw/rtquat.h b/src/fakerw/rtquat.h
new file mode 100644
index 00000000..450342b2
--- /dev/null
+++ b/src/fakerw/rtquat.h
@@ -0,0 +1,15 @@
+#pragma once
+
+// Same layout as rw::Quat but with ugly imag,real separation which i don't want in librw
+struct RtQuat
+{
+ rw::V3d imag;
+ rw::float32 real;
+};
+
+RwBool RtQuatConvertFromMatrix(RtQuat * const qpQuat, const RwMatrix * const mpMatrix);
+RtQuat *RtQuatRotate(RtQuat * quat, const RwV3d * axis, RwReal angle, RwOpCombineType combineOp);
+const RtQuat *RtQuatQueryRotate(const RtQuat *quat, RwV3d * unitAxis, RwReal * angle);
+RwV3d *RtQuatTransformVectors(RwV3d * vectorsOut, const RwV3d * vectorsIn, const RwInt32 numPoints, const RtQuat *quat);
+
+void RtQuatConvertToMatrix(const RtQuat * const qpQuat, RwMatrix * const mpMatrix);
diff --git a/src/fakerw/rwcore.h b/src/fakerw/rwcore.h
new file mode 100644
index 00000000..22e29737
--- /dev/null
+++ b/src/fakerw/rwcore.h
@@ -0,0 +1,413 @@
+#pragma once
+
+#define RWCORE_H // needed by CVector
+
+#include <rw.h>
+
+#include <rwplcore.h>
+
+/*
+ ***********************************************
+ *
+ * RwIm2D and RwIm3D
+ *
+ ***********************************************
+ */
+
+typedef rw::RWDEVICE::Im2DVertex RwIm2DVertex;
+typedef rw::RWDEVICE::Im3DVertex RwIm3DVertex;
+typedef RwUInt16 RwImVertexIndex;
+
+enum RwIm3DTransformFlags
+{
+ rwIM3D_VERTEXUV = 1,
+ rwIM3D_ALLOPAQUE = 2,
+ rwIM3D_NOCLIP = 4,
+ rwIM3D_VERTEXXYZ = 8,
+ rwIM3D_VERTEXRGBA = 16,
+};
+
+void RwIm2DVertexSetCameraX(RwIm2DVertex *vert, RwReal camx);
+void RwIm2DVertexSetCameraY(RwIm2DVertex *vert, RwReal camy);
+void RwIm2DVertexSetCameraZ(RwIm2DVertex *vert, RwReal camz);
+void RwIm2DVertexSetRecipCameraZ(RwIm2DVertex *vert, RwReal recipz);
+void RwIm2DVertexSetScreenX(RwIm2DVertex *vert, RwReal scrnx);
+void RwIm2DVertexSetScreenY(RwIm2DVertex *vert, RwReal scrny);
+void RwIm2DVertexSetScreenZ(RwIm2DVertex *vert, RwReal scrnz);
+void RwIm2DVertexSetU(RwIm2DVertex *vert, RwReal texU, RwReal recipz);
+void RwIm2DVertexSetV(RwIm2DVertex *vert, RwReal texV, RwReal recipz);
+void RwIm2DVertexSetIntRGBA(RwIm2DVertex *vert, RwUInt8 red, RwUInt8 green, RwUInt8 blue, RwUInt8 alpha);
+
+RwReal RwIm2DGetNearScreenZ(void);
+RwReal RwIm2DGetFarScreenZ(void);
+RwBool RwIm2DRenderLine(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2);
+RwBool RwIm2DRenderTriangle(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2, RwInt32 vert3 );
+RwBool RwIm2DRenderPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices);
+RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices);
+
+
+void RwIm3DVertexSetPos(RwIm3DVertex *vert, RwReal x, RwReal y, RwReal z);
+void RwIm3DVertexSetU(RwIm3DVertex *vert, RwReal u);
+void RwIm3DVertexSetV(RwIm3DVertex *vert, RwReal v);
+void RwIm3DVertexSetRGBA(RwIm3DVertex *vert, RwUInt8 r, RwUInt8 g, RwUInt8 b, RwUInt8 a);
+
+void *RwIm3DTransform(RwIm3DVertex *pVerts, RwUInt32 numVerts, RwMatrix *ltm, RwUInt32 flags);
+RwBool RwIm3DEnd(void);
+RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2);
+RwBool RwIm3DRenderTriangle(RwInt32 vert1, RwInt32 vert2, RwInt32 vert3);
+RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType, RwImVertexIndex *indices, RwInt32 numIndices);
+RwBool RwIm3DRenderPrimitive(RwPrimitiveType primType);
+
+
+/*
+ ***********************************************
+ *
+ * RwRaster
+ *
+ ***********************************************
+ */
+
+//struct RwRaster;
+typedef rw::Raster RwRaster;
+
+enum RwRasterType
+{
+ rwRASTERTYPENORMAL = rw::Raster::NORMAL,
+ rwRASTERTYPEZBUFFER = rw::Raster::ZBUFFER,
+ rwRASTERTYPECAMERA = rw::Raster::CAMERA,
+ rwRASTERTYPETEXTURE = rw::Raster::TEXTURE,
+ rwRASTERTYPECAMERATEXTURE = rw::Raster::CAMERATEXTURE,
+ rwRASTERTYPEMASK = 0x07,
+ rwRASTERDONTALLOCATE = rw::Raster::DONTALLOCATE,
+};
+
+enum RwRasterFormat
+{
+ rwRASTERFORMATDEFAULT = rw::Raster::DEFAULT,
+ rwRASTERFORMAT1555 = rw::Raster::C1555,
+ rwRASTERFORMAT565 = rw::Raster::C565,
+ rwRASTERFORMAT4444 = rw::Raster::C4444,
+ rwRASTERFORMATLUM8 = rw::Raster::LUM8,
+ rwRASTERFORMAT8888 = rw::Raster::C8888,
+ rwRASTERFORMAT888 = rw::Raster::C888,
+ rwRASTERFORMAT16 = rw::Raster::D16,
+ rwRASTERFORMAT24 = rw::Raster::D24,
+ rwRASTERFORMAT32 = rw::Raster::D32,
+ rwRASTERFORMAT555 = rw::Raster::C555,
+
+ rwRASTERFORMATAUTOMIPMAP = rw::Raster::AUTOMIPMAP,
+ rwRASTERFORMATPAL8 = rw::Raster::PAL8,
+ rwRASTERFORMATPAL4 = rw::Raster::PAL4,
+ rwRASTERFORMATMIPMAP = rw::Raster::MIPMAP,
+
+ rwRASTERFORMATPIXELFORMATMASK = 0x0f00,
+ rwRASTERFORMATMASK = 0xff00
+};
+
+enum RwRasterFlipMode
+{
+ rwRASTERFLIPDONTWAIT = 0,
+ rwRASTERFLIPWAITVSYNC = 1,
+};
+
+RwRaster *RwRasterCreate(RwInt32 width, RwInt32 height, RwInt32 depth, RwInt32 flags);
+RwBool RwRasterDestroy(RwRaster * raster);
+RwInt32 RwRasterGetWidth(const RwRaster *raster);
+RwInt32 RwRasterGetHeight(const RwRaster *raster);
+RwInt32 RwRasterGetStride(const RwRaster *raster);
+RwInt32 RwRasterGetDepth(const RwRaster *raster);
+RwInt32 RwRasterGetFormat(const RwRaster *raster);
+RwInt32 RwRasterGetType(const RwRaster *raster);
+RwRaster *RwRasterGetParent(const RwRaster *raster);
+RwRaster *RwRasterGetOffset(RwRaster *raster, RwInt16 *xOffset, RwInt16 *yOffset);
+RwInt32 RwRasterGetNumLevels(RwRaster * raster);
+RwRaster *RwRasterSubRaster(RwRaster * subRaster, RwRaster * raster, RwRect * rect);
+RwRaster *RwRasterRenderFast(RwRaster * raster, RwInt32 x, RwInt32 y);
+RwRaster *RwRasterRender(RwRaster * raster, RwInt32 x, RwInt32 y);
+RwRaster *RwRasterRenderScaled(RwRaster * raster, RwRect * rect);
+RwRaster *RwRasterPushContext(RwRaster * raster);
+RwRaster *RwRasterPopContext(void);
+RwRaster *RwRasterGetCurrentContext(void);
+RwBool RwRasterClear(RwInt32 pixelValue);
+RwBool RwRasterClearRect(RwRect * rpRect, RwInt32 pixelValue);
+RwRaster *RwRasterShowRaster(RwRaster * raster, void *dev, RwUInt32 flags);
+RwUInt8 *RwRasterLock(RwRaster * raster, RwUInt8 level, RwInt32 lockMode);
+RwRaster *RwRasterUnlock(RwRaster * raster);
+RwUInt8 *RwRasterLockPalette(RwRaster * raster, RwInt32 lockMode);
+RwRaster *RwRasterUnlockPalette(RwRaster * raster);
+RwInt32 RwRasterRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwRasterGetPluginOffset(RwUInt32 pluginID);
+RwBool RwRasterValidatePlugins(const RwRaster * raster);
+
+
+/*
+ ***********************************************
+ *
+ * RwImage
+ *
+ ***********************************************
+ */
+
+//struct RwImage;
+typedef rw::Image RwImage;
+
+RwImage *RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth);
+RwBool RwImageDestroy(RwImage * image);
+RwImage *RwImageAllocatePixels(RwImage * image);
+RwImage *RwImageFreePixels(RwImage * image);
+RwImage *RwImageCopy(RwImage * destImage, const RwImage * sourceImage);
+RwImage *RwImageResize(RwImage * image, RwInt32 width, RwInt32 height);
+RwImage *RwImageApplyMask(RwImage * image, const RwImage * mask);
+RwImage *RwImageMakeMask(RwImage * image);
+RwImage *RwImageReadMaskedImage(const RwChar * imageName, const RwChar * maskname);
+RwImage *RwImageRead(const RwChar * imageName);
+RwImage *RwImageWrite(RwImage * image, const RwChar * imageName);
+RwChar *RwImageGetPath(void);
+const RwChar *RwImageSetPath(const RwChar * path);
+RwImage *RwImageSetStride(RwImage * image, RwInt32 stride);
+RwImage *RwImageSetPixels(RwImage * image, RwUInt8 * pixels);
+RwImage *RwImageSetPalette(RwImage * image, RwRGBA * palette);
+RwInt32 RwImageGetWidth(const RwImage * image);
+RwInt32 RwImageGetHeight(const RwImage * image);
+RwInt32 RwImageGetDepth(const RwImage * image);
+RwInt32 RwImageGetStride(const RwImage * image);
+RwUInt8 *RwImageGetPixels(const RwImage * image);
+RwRGBA *RwImageGetPalette(const RwImage * image);
+RwUInt32 RwRGBAToPixel(RwRGBA * rgbIn, RwInt32 rasterFormat);
+RwRGBA *RwRGBASetFromPixel(RwRGBA * rgbOut, RwUInt32 pixelValue, RwInt32 rasterFormat);
+RwBool RwImageSetGamma(RwReal gammaValue);
+RwReal RwImageGetGamma(void);
+RwImage *RwImageGammaCorrect(RwImage * image);
+RwRGBA *RwRGBAGammaCorrect(RwRGBA * rgb);
+RwInt32 RwImageRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwImageGetPluginOffset(RwUInt32 pluginID);
+RwBool RwImageValidatePlugins(const RwImage * image);
+//RwBool RwImageRegisterImageFormat(const RwChar * extension, RwImageCallBackRead imageRead, RwImageCallBackWrite imageWrite);
+const RwChar *RwImageFindFileType(const RwChar * imageName);
+RwInt32 RwImageStreamGetSize(const RwImage * image);
+RwImage *RwImageStreamRead(RwStream * stream);
+const RwImage *RwImageStreamWrite(const RwImage * image, RwStream * stream);
+
+
+/*
+ ***********************************************
+ *
+ * RwTexture
+ *
+ ***********************************************
+ */
+
+//struct RwTexture;
+typedef rw::Texture RwTexture;
+//struct RwTexDictionary;
+typedef rw::TexDictionary RwTexDictionary;
+
+typedef RwTexture *(*RwTextureCallBackRead)(const RwChar *name, const RwChar *maskName);
+typedef RwTexture *(*RwTextureCallBack)(RwTexture *texture, void *pData);
+typedef RwTexDictionary *(*RwTexDictionaryCallBack)(RwTexDictionary *dict, void *data);
+typedef RwRaster *(*RwTextureCallBackMipmapGeneration)(RwRaster * raster, RwImage * image);
+typedef RwBool (*RwTextureCallBackMipmapName)(RwChar *name, RwChar *maskName, RwUInt8 mipLevel, RwInt32 format);
+
+RwTexture *RwTextureCreate(RwRaster * raster);
+RwBool RwTextureDestroy(RwTexture * texture);
+RwTexture *RwTextureAddRef(RwTexture *texture);
+RwBool RwTextureSetMipmapping(RwBool enable);
+RwBool RwTextureGetMipmapping(void);
+RwBool RwTextureSetAutoMipmapping(RwBool enable);
+RwBool RwTextureGetAutoMipmapping(void);
+RwBool RwTextureSetMipmapGenerationCallBack(RwTextureCallBackMipmapGeneration callback);
+RwTextureCallBackMipmapGeneration RwTextureGetMipmapGenerationCallBack(void);
+RwBool RwTextureSetMipmapNameCallBack(RwTextureCallBackMipmapName callback);
+RwTextureCallBackMipmapName RwTextureGetMipmapNameCallBack(void);
+RwBool RwTextureGenerateMipmapName(RwChar * name, RwChar * maskName, RwUInt8 mipLevel, RwInt32 format);
+RwBool RwTextureRasterGenerateMipmaps(RwRaster * raster, RwImage * image);
+RwTextureCallBackRead RwTextureGetReadCallBack(void);
+RwBool RwTextureSetReadCallBack(RwTextureCallBackRead fpCallBack);
+RwTexture *RwTextureSetName(RwTexture * texture, const RwChar * name);
+RwTexture *RwTextureSetMaskName(RwTexture * texture, const RwChar * maskName);
+RwChar *RwTextureGetName(RwTexture *texture);
+RwChar *RwTextureGetMaskName(RwTexture *texture);
+RwTexture *RwTextureSetRaster(RwTexture * texture, RwRaster * raster);
+RwTexture *RwTextureRead(const RwChar * name, const RwChar * maskName);
+RwRaster *RwTextureGetRaster(const RwTexture *texture);
+RwInt32 RwTextureRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwTextureGetPluginOffset(RwUInt32 pluginID);
+RwBool RwTextureValidatePlugins(const RwTexture * texture);
+
+RwTexDictionary *RwTextureGetDictionary(RwTexture *texture);
+RwTexture *RwTextureSetFilterMode(RwTexture *texture, RwTextureFilterMode filtering);
+RwTextureFilterMode RwTextureGetFilterMode(const RwTexture *texture);
+RwTexture *RwTextureSetAddressing(RwTexture *texture, RwTextureAddressMode addressing);
+RwTexture *RwTextureSetAddressingU(RwTexture *texture, RwTextureAddressMode addressing);
+RwTexture *RwTextureSetAddressingV(RwTexture *texture, RwTextureAddressMode addressing);
+RwTextureAddressMode RwTextureGetAddressing(const RwTexture *texture);
+RwTextureAddressMode RwTextureGetAddressingU(const RwTexture *texture);
+RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
+
+void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable);
+
+// hack for reading native textures
+RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size);
+
+
+RwTexDictionary *RwTexDictionaryCreate(void);
+RwBool RwTexDictionaryDestroy(RwTexDictionary * dict);
+RwTexture *RwTexDictionaryAddTexture(RwTexDictionary * dict, RwTexture * texture);
+RwTexture *RwTexDictionaryRemoveTexture(RwTexture * texture);
+RwTexture *RwTexDictionaryFindNamedTexture(RwTexDictionary * dict, const RwChar * name);
+RwTexDictionary *RwTexDictionaryGetCurrent(void);
+RwTexDictionary *RwTexDictionarySetCurrent(RwTexDictionary * dict);
+const RwTexDictionary *RwTexDictionaryForAllTextures(const RwTexDictionary * dict, RwTextureCallBack fpCallBack, void *pData);
+RwBool RwTexDictionaryForAllTexDictionaries(RwTexDictionaryCallBack fpCallBack, void *pData);
+RwInt32 RwTexDictionaryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwTexDictionaryGetPluginOffset(RwUInt32 pluginID);
+RwBool RwTexDictionaryValidatePlugins(const RwTexDictionary * dict);
+RwUInt32 RwTexDictionaryStreamGetSize(const RwTexDictionary *texDict);
+RwTexDictionary *RwTexDictionaryStreamRead(RwStream *stream);
+const RwTexDictionary *RwTexDictionaryStreamWrite(const RwTexDictionary *texDict, RwStream *stream);
+
+/* RwImage/RwRaster */
+
+RwImage *RwImageSetFromRaster(RwImage *image, RwRaster *raster);
+RwRaster *RwRasterSetFromImage(RwRaster *raster, RwImage *image);
+RwRGBA *RwRGBAGetRasterPixel(RwRGBA *rgbOut, RwRaster *raster, RwInt32 x, RwInt32 y);
+RwRaster *RwRasterRead(const RwChar *filename);
+RwRaster *RwRasterReadMaskedRaster(const RwChar *filename, const RwChar *maskname);
+RwImage *RwImageFindRasterFormat(RwImage *ipImage,RwInt32 nRasterType, RwInt32 *npWidth,RwInt32 *npHeight, RwInt32 *npDepth,RwInt32 *npFormat);
+
+
+/*
+ ***********************************************
+ *
+ * RwFrame
+ *
+ ***********************************************
+ */
+
+//struct RwFrame;
+typedef rw::Frame RwFrame;
+
+typedef RwFrame *(*RwFrameCallBack)(RwFrame *frame, void *data);
+
+
+RwFrame *RwFrameForAllObjects(RwFrame * frame, RwObjectCallBack callBack, void *data);
+RwFrame *RwFrameTranslate(RwFrame * frame, const RwV3d * v, RwOpCombineType combine);
+RwFrame *RwFrameRotate(RwFrame * frame, const RwV3d * axis, RwReal angle, RwOpCombineType combine);
+RwFrame *RwFrameScale(RwFrame * frame, const RwV3d * v, RwOpCombineType combine);
+RwFrame *RwFrameTransform(RwFrame * frame, const RwMatrix * m, RwOpCombineType combine);
+RwFrame *RwFrameOrthoNormalize(RwFrame * frame);
+RwFrame *RwFrameSetIdentity(RwFrame * frame);
+RwFrame *RwFrameCloneHierarchy(RwFrame * root);
+RwBool RwFrameDestroyHierarchy(RwFrame * frame);
+RwFrame *RwFrameForAllChildren(RwFrame * frame, RwFrameCallBack callBack, void *data);
+RwFrame *RwFrameRemoveChild(RwFrame * child);
+RwFrame *RwFrameAddChild(RwFrame * parent, RwFrame * child);
+RwFrame *RwFrameGetParent(const RwFrame * frame);
+RwFrame *RwFrameGetRoot(const RwFrame * frame);
+RwMatrix *RwFrameGetLTM(RwFrame * frame);
+RwMatrix *RwFrameGetMatrix(RwFrame * frame);
+RwFrame *RwFrameUpdateObjects(RwFrame * frame);
+RwFrame *RwFrameCreate(void);
+RwBool RwFrameInit(RwFrame *frame);
+RwBool RwFrameDeInit(RwFrame *frame);
+RwBool RwFrameDestroy(RwFrame * frame);
+void _rwFrameInit(RwFrame *frame);
+void _rwFrameDeInit(RwFrame *frame);
+RwBool RwFrameDirty(const RwFrame * frame);
+RwInt32 RwFrameCount(RwFrame * frame);
+RwBool RwFrameSetStaticPluginsSize(RwInt32 size);
+RwInt32 RwFrameRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwFrameGetPluginOffset(RwUInt32 pluginID);
+RwBool RwFrameValidatePlugins(const RwFrame * frame);
+RwFrame *_rwFrameCloneAndLinkClones(RwFrame * root);
+RwFrame *_rwFramePurgeClone(RwFrame *root);
+
+RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB);
+RwInt32 RwFrameSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB);
+
+typedef rw::FrameList_ rwFrameList;
+rwFrameList *rwFrameListInitialize(rwFrameList *frameList, RwFrame *frame);
+RwBool rwFrameListFindFrame(const rwFrameList *frameList, const RwFrame *frame, RwInt32 *npIndex);
+rwFrameList *rwFrameListDeinitialize(rwFrameList *frameList);
+RwUInt32 rwFrameListStreamGetSize(const rwFrameList *frameList);
+rwFrameList *rwFrameListStreamRead(RwStream *stream, rwFrameList *fl);
+const rwFrameList *rwFrameListStreamWrite(const rwFrameList *frameList, RwStream *stream);
+
+
+typedef rw::BBox RwBBox;
+
+/*
+ ***********************************************
+ *
+ * RwCamera
+ *
+ ***********************************************
+ */
+
+//struct RwCamera;
+typedef rw::Camera RwCamera;
+
+typedef RwCamera *(*RwCameraCallBack)(RwCamera *camera, void *data);
+
+enum RwCameraClearMode
+{
+ rwCAMERACLEARIMAGE = 0x1,
+ rwCAMERACLEARZ = 0x2,
+ rwCAMERACLEARSTENCIL = 0x4
+};
+
+enum RwCameraProjection
+{
+ rwNACAMERAPROJECTION = 0,
+ rwPERSPECTIVE = 1,
+ rwPARALLEL = 2
+};
+
+enum RwFrustumTestResult
+{
+ rwSPHEREOUTSIDE = 0,
+ rwSPHEREBOUNDARY = 1,
+ rwSPHEREINSIDE = 2
+};
+
+RwCamera *RwCameraBeginUpdate(RwCamera * camera);
+RwCamera *RwCameraEndUpdate(RwCamera * camera);
+RwCamera *RwCameraClear(RwCamera * camera, RwRGBA * colour, RwInt32 clearMode);
+RwCamera *RwCameraShowRaster(RwCamera * camera, void *pDev, RwUInt32 flags);
+RwBool RwCameraDestroy(RwCamera * camera);
+RwCamera *RwCameraCreate(void);
+RwCamera *RwCameraClone(RwCamera * camera);
+RwCamera *RwCameraSetViewOffset(RwCamera *camera, const RwV2d *offset);
+RwCamera *RwCameraSetViewWindow(RwCamera *camera, const RwV2d *viewWindow);
+RwCamera *RwCameraSetProjection(RwCamera *camera, RwCameraProjection projection);
+RwCamera *RwCameraSetNearClipPlane(RwCamera *camera, RwReal nearClip);
+RwCamera *RwCameraSetFarClipPlane(RwCamera *camera, RwReal farClip);
+RwInt32 RwCameraRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor constructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB);
+RwInt32 RwCameraGetPluginOffset(RwUInt32 pluginID);
+RwBool RwCameraValidatePlugins(const RwCamera * camera);
+RwFrustumTestResult RwCameraFrustumTestSphere(const RwCamera * camera, const RwSphere * sphere);
+const RwV2d *RwCameraGetViewOffset(const RwCamera *camera);
+RwCamera *RwCameraSetRaster(RwCamera *camera, RwRaster *raster);
+RwRaster *RwCameraGetRaster(const RwCamera *camera);
+RwCamera *RwCameraSetZRaster(RwCamera *camera, RwRaster *zRaster);
+RwRaster *RwCameraGetZRaster(const RwCamera *camera);
+RwReal RwCameraGetNearClipPlane(const RwCamera *camera);
+RwReal RwCameraGetFarClipPlane(const RwCamera *camera);
+RwCamera *RwCameraSetFogDistance(RwCamera *camera, RwReal fogDistance);
+RwReal RwCameraGetFogDistance(const RwCamera *camera);
+RwCamera *RwCameraGetCurrentCamera(void);
+RwCameraProjection RwCameraGetProjection(const RwCamera *camera);
+const RwV2d *RwCameraGetViewWindow(const RwCamera *camera);
+RwMatrix *RwCameraGetViewMatrix(RwCamera *camera);
+RwCamera *RwCameraSetFrame(RwCamera *camera, RwFrame *frame);
+RwFrame *RwCameraGetFrame(const RwCamera *camera);
+
+
+/*
+ *
+ * D3D-engine specific stuff
+ *
+ */
+
+void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate);
+RwBool RwD3D8DeviceSupportsDXTTexture(void);
diff --git a/src/fakerw/rwplcore.h b/src/fakerw/rwplcore.h
new file mode 100644
index 00000000..79c745b6
--- /dev/null
+++ b/src/fakerw/rwplcore.h
@@ -0,0 +1,498 @@
+#pragma once
+
+typedef rw::int8 RwInt8;
+typedef rw::int16 RwInt16;
+typedef rw::int32 RwInt32;
+typedef rw::uint8 RwUInt8;
+typedef rw::uint16 RwUInt16;
+typedef rw::uint32 RwUInt32;
+typedef rw::float32 RwReal;
+
+typedef char RwChar;
+typedef RwInt32 RwBool;
+
+#define __RWUNUSED__
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+// used for unicode
+#define RWSTRING(x) x
+
+typedef rw::V2d RwV2d;
+
+typedef rw::V3d RwV3d;
+
+typedef rw::Rect RwRect;
+
+typedef rw::Sphere RwSphere;
+
+enum RwTextureCoordinateIndex
+{
+ rwNARWTEXTURECOORDINATEINDEX = 0,
+ rwTEXTURECOORDINATEINDEX0,
+ rwTEXTURECOORDINATEINDEX1,
+ rwTEXTURECOORDINATEINDEX2,
+ rwTEXTURECOORDINATEINDEX3,
+ rwTEXTURECOORDINATEINDEX4,
+ rwTEXTURECOORDINATEINDEX5,
+ rwTEXTURECOORDINATEINDEX6,
+ rwTEXTURECOORDINATEINDEX7,
+};
+
+typedef rw::TexCoords RwTexCoords;
+
+typedef rw::SurfaceProperties RwSurfaceProperties;
+
+#define RWRGBALONG(r,g,b,a) \
+ ((RwUInt32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))
+
+
+#define MAKECHUNKID(vendorID, chunkID) (((vendorID & 0xFFFFFF) << 8) | (chunkID & 0xFF))
+
+enum RwCorePluginID
+{
+ rwID_NAOBJECT = 0x00,
+ rwID_STRUCT = 0x01,
+ rwID_STRING = 0x02,
+ rwID_EXTENSION = 0x03,
+ rwID_CAMERA = 0x05,
+ rwID_TEXTURE = 0x06,
+ rwID_MATERIAL = 0x07,
+ rwID_MATLIST = 0x08,
+ rwID_ATOMICSECT = 0x09,
+ rwID_PLANESECT = 0x0A,
+ rwID_WORLD = 0x0B,
+ rwID_SPLINE = 0x0C,
+ rwID_MATRIX = 0x0D,
+ rwID_FRAMELIST = 0x0E,
+ rwID_GEOMETRY = 0x0F,
+ rwID_CLUMP = 0x10,
+ rwID_LIGHT = 0x12,
+ rwID_UNICODESTRING = 0x13,
+ rwID_ATOMIC = 0x14,
+ rwID_TEXTURENATIVE = 0x15,
+ rwID_TEXDICTIONARY = 0x16,
+ rwID_ANIMDATABASE = 0x17,
+ rwID_IMAGE = 0x18,
+ rwID_SKINANIMATION = 0x19,
+ rwID_GEOMETRYLIST = 0x1A,
+ rwID_HANIMANIMATION = 0x1B,
+ rwID_TEAM = 0x1C,
+ rwID_CROWD = 0x1D,
+ rwID_DMORPHANIMATION = 0x1E,
+ rwID_RIGHTTORENDER = 0x1f,
+ rwID_MTEFFECTNATIVE = 0x20,
+ rwID_MTEFFECTDICT = 0x21,
+ rwID_TEAMDICTIONARY = 0x22,
+ rwID_PITEXDICTIONARY = 0x23,
+ rwID_TOC = 0x24,
+ rwID_PRTSTDGLOBALDATA = 0x25,
+ /* Insert before MAX and increment MAX */
+ rwID_COREPLUGINIDMAX = 0x26,
+};
+
+
+/*
+ ***********************************************
+ *
+ * RwObject
+ *
+ ***********************************************
+ */
+
+//struct RwObject;
+typedef rw::Object RwObject;
+
+typedef RwObject *(*RwObjectCallBack)(RwObject *object, void *data);
+
+RwUInt8 RwObjectGetType(const RwObject *obj);
+
+
+
+#define rwsprintf sprintf
+#define rwvsprintf vsprintf
+#define rwstrcpy strcpy
+#define rwstrncpy strncpy
+#define rwstrcat strcat
+#define rwstrncat strncat
+#define rwstrrchr strrchr
+#define rwstrchr strchr
+#define rwstrstr strstr
+#define rwstrcmp strcmp
+#define rwstricmp stricmp
+#define rwstrlen strlen
+#define rwstrupr strupr
+#define rwstrlwr strlwr
+#define rwstrtok strtok
+#define rwsscanf sscanf
+
+
+/*
+ ***********************************************
+ *
+ * Memory
+ *
+ ***********************************************
+ */
+
+struct RwMemoryFunctions;
+/*
+{
+ void *(*rwmalloc)(size_t size);
+ void (*rwfree)(void *mem);
+ void *(*rwrealloc)(void *mem, size_t newSize);
+ void *(*rwcalloc)(size_t numObj, size_t sizeObj);
+};
+*/
+
+void *RwMalloc(size_t size);
+void RwFree(void *mem);
+void *RwRealloc(void *mem, size_t newSize);
+void *RwCalloc(size_t numObj, size_t sizeObj);
+
+/*
+ ***********************************************
+ *
+ * RwStream
+ *
+ ***********************************************
+ */
+
+//struct RwStream;
+typedef rw::Stream RwStream;
+
+struct RwMemory
+{
+ RwUInt8 *start;
+ RwUInt32 length;
+};
+
+enum RwStreamType
+{
+ rwNASTREAM = 0,
+ rwSTREAMFILE,
+ rwSTREAMFILENAME,
+ rwSTREAMMEMORY,
+ rwSTREAMCUSTOM
+};
+
+enum RwStreamAccessType
+{
+ rwNASTREAMACCESS = 0,
+ rwSTREAMREAD,
+ rwSTREAMWRITE,
+ rwSTREAMAPPEND
+};
+
+RwStream *RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, const void *pData);
+RwBool RwStreamClose(RwStream * stream, void *pData);
+RwUInt32 RwStreamRead(RwStream * stream, void *buffer, RwUInt32 length);
+RwStream *RwStreamWrite(RwStream * stream, const void *buffer, RwUInt32 length);
+RwStream *RwStreamSkip(RwStream * stream, RwUInt32 offset);
+
+
+/*
+ ***********************************************
+ *
+ * Plugin Registry
+ *
+ ***********************************************
+ */
+
+#define RWPLUGINOFFSET(_type, _base, _offset) \
+ ((_type *)((RwUInt8 *)(_base) + (_offset)))
+
+typedef RwStream *(*RwPluginDataChunkWriteCallBack)(RwStream *stream, RwInt32 binaryLength, const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef RwStream *(*RwPluginDataChunkReadCallBack)(RwStream *stream, RwInt32 binaryLength, void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef RwInt32(*RwPluginDataChunkGetSizeCallBack)(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef RwBool(*RwPluginDataChunkAlwaysCallBack)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef RwBool(*RwPluginDataChunkRightsCallBack)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject, RwUInt32 extraData);
+typedef void *(*RwPluginObjectConstructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef void *(*RwPluginObjectCopy)(void *dstObject, const void *srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject);
+typedef void *(*RwPluginObjectDestructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
+
+/*
+ ***********************************************
+ *
+ * RwMatrix
+ *
+ ***********************************************
+ */
+
+typedef rw::Matrix RwMatrix;
+
+enum RwOpCombineType
+{
+ rwCOMBINEREPLACE = rw::COMBINEREPLACE,
+ rwCOMBINEPRECONCAT = rw::COMBINEPRECONCAT,
+ rwCOMBINEPOSTCONCAT = rw::COMBINEPOSTCONCAT
+};
+
+enum RwMatrixType
+{
+ rwMATRIXTYPENORMAL = rw::Matrix::TYPENORMAL,
+ rwMATRIXTYPEORTHOGANAL = rw::Matrix::TYPEORTHOGONAL,
+ rwMATRIXTYPEORTHONORMAL = rw::Matrix::TYPEORTHONORMAL,
+ rwMATRIXTYPEMASK = 0x00000003,
+};
+
+typedef rw::Matrix::Tolerance RwMatrixTolerance;
+
+RwBool RwMatrixDestroy(RwMatrix *mpMat);
+RwMatrix *RwMatrixCreate(void);
+void RwMatrixCopy(RwMatrix * dstMatrix, const RwMatrix * srcMatrix);
+void RwMatrixSetIdentity(RwMatrix * matrix);
+RwMatrix *RwMatrixMultiply(RwMatrix * matrixOut, const RwMatrix * MatrixIn1, const RwMatrix * matrixIn2);
+RwMatrix *RwMatrixTransform(RwMatrix * matrix, const RwMatrix * transform, RwOpCombineType combineOp);
+RwMatrix *RwMatrixOrthoNormalize(RwMatrix * matrixOut, const RwMatrix * matrixIn);
+RwMatrix *RwMatrixInvert(RwMatrix * matrixOut, const RwMatrix * matrixIn);
+RwMatrix *RwMatrixScale(RwMatrix * matrix, const RwV3d * scale, RwOpCombineType combineOp);
+RwMatrix *RwMatrixTranslate(RwMatrix * matrix, const RwV3d * translation, RwOpCombineType combineOp);
+RwMatrix *RwMatrixRotate(RwMatrix * matrix, const RwV3d * axis, RwReal angle, RwOpCombineType combineOp);
+RwMatrix *RwMatrixRotateOneMinusCosineSine(RwMatrix * matrix, const RwV3d * unitAxis, RwReal oneMinusCosine, RwReal sine, RwOpCombineType combineOp);
+const RwMatrix *RwMatrixQueryRotate(const RwMatrix * matrix, RwV3d * unitAxis, RwReal * angle, RwV3d * center);
+RwV3d *RwMatrixGetRight(RwMatrix * matrix);
+RwV3d *RwMatrixGetUp(RwMatrix * matrix);
+RwV3d *RwMatrixGetAt(RwMatrix * matrix);
+RwV3d *RwMatrixGetPos(RwMatrix * matrix);
+RwMatrix *RwMatrixUpdate(RwMatrix * matrix);
+RwMatrix *RwMatrixOptimize(RwMatrix * matrix, const RwMatrixTolerance *tolerance);
+
+/*
+ ***********************************************
+ *
+ * RwRGBA
+ *
+ ***********************************************
+ */
+
+typedef rw::RGBA RwRGBA;
+typedef rw::RGBAf RwRGBAReal;
+
+
+inline void RwRGBAAssign(RwRGBA *target, const RwRGBA *source) { *target = *source; }
+
+
+RwReal RwV3dNormalize(RwV3d * out, const RwV3d * in);
+RwReal RwV3dLength(const RwV3d * in);
+RwReal RwV2dLength(const RwV2d * in);
+RwReal RwV2dNormalize(RwV2d * out, const RwV2d * in);
+void RwV2dAssign(RwV2d * out, const RwV2d * ina);
+void RwV2dAdd(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+void RwV2dLineNormal(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+void RwV2dSub(RwV2d * out, const RwV2d * ina, const RwV2d * inb);
+void RwV2dPerp(RwV2d * out, const RwV2d * in);
+void RwV2dScale(RwV2d * out, const RwV2d * in, RwReal scalar);
+RwReal RwV2dDotProduct(const RwV2d * ina, const RwV2d * inb);
+void RwV3dAssign(RwV3d * out, const RwV3d * ina);
+void RwV3dAdd(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
+void RwV3dSub(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
+void RwV3dScale(RwV3d * out, const RwV3d * in, RwReal scalar);
+void RwV3dIncrementScaled(RwV3d * out, const RwV3d * in, RwReal scalar);
+void RwV3dNegate(RwV3d * out, const RwV3d * in);
+RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb);
+void RwV3dCrossProduct(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
+RwV3d *RwV3dTransformPoints(RwV3d * pointsOut, const RwV3d * pointsIn, RwInt32 numPoints, const RwMatrix * matrix);
+RwV3d *RwV3dTransformVectors(RwV3d * vectorsOut, const RwV3d * vectorsIn, RwInt32 numPoints, const RwMatrix * matrix);
+
+
+/*
+ ***********************************************
+ *
+ * Render States
+ *
+ ***********************************************
+ */
+
+// not librw because we don't support all of them (yet?) - mapping in wrapper functions
+enum RwRenderState
+{
+ rwRENDERSTATENARENDERSTATE = 0,
+ rwRENDERSTATETEXTURERASTER,
+ rwRENDERSTATETEXTUREADDRESS,
+ rwRENDERSTATETEXTUREADDRESSU,
+ rwRENDERSTATETEXTUREADDRESSV,
+ rwRENDERSTATETEXTUREPERSPECTIVE,
+ rwRENDERSTATEZTESTENABLE,
+ rwRENDERSTATESHADEMODE,
+ rwRENDERSTATEZWRITEENABLE,
+ rwRENDERSTATETEXTUREFILTER,
+ rwRENDERSTATESRCBLEND,
+ rwRENDERSTATEDESTBLEND,
+ rwRENDERSTATEVERTEXALPHAENABLE,
+ rwRENDERSTATEBORDERCOLOR,
+ rwRENDERSTATEFOGENABLE,
+ rwRENDERSTATEFOGCOLOR,
+ rwRENDERSTATEFOGTYPE,
+ rwRENDERSTATEFOGDENSITY,
+ rwRENDERSTATEFOGTABLE,
+ rwRENDERSTATEALPHAPRIMITIVEBUFFER,
+ rwRENDERSTATECULLMODE,
+ rwRENDERSTATESTENCILENABLE,
+ rwRENDERSTATESTENCILFAIL,
+ rwRENDERSTATESTENCILZFAIL,
+ rwRENDERSTATESTENCILPASS,
+ rwRENDERSTATESTENCILFUNCTION,
+ rwRENDERSTATESTENCILFUNCTIONREF,
+ rwRENDERSTATESTENCILFUNCTIONMASK,
+ rwRENDERSTATESTENCILFUNCTIONWRITEMASK
+};
+
+// not supported - we only do gouraud
+enum RwShadeMode
+{
+ rwSHADEMODENASHADEMODE = 0,
+ rwSHADEMODEFLAT,
+ rwSHADEMODEGOURAUD
+};
+
+enum RwBlendFunction
+{
+ rwBLENDNABLEND = 0,
+ rwBLENDZERO = rw::BLENDZERO,
+ rwBLENDONE = rw::BLENDONE,
+ rwBLENDSRCCOLOR = rw::BLENDSRCCOLOR,
+ rwBLENDINVSRCCOLOR = rw::BLENDINVSRCCOLOR,
+ rwBLENDSRCALPHA = rw::BLENDSRCALPHA,
+ rwBLENDINVSRCALPHA = rw::BLENDINVSRCALPHA,
+ rwBLENDDESTALPHA = rw::BLENDDESTALPHA,
+ rwBLENDINVDESTALPHA = rw::BLENDINVDESTALPHA,
+ rwBLENDDESTCOLOR = rw::BLENDDESTCOLOR,
+ rwBLENDINVDESTCOLOR = rw::BLENDINVDESTCOLOR,
+ rwBLENDSRCALPHASAT = rw::BLENDSRCALPHASAT
+};
+
+// unsupported - we only need linear
+enum RwFogType
+{
+ rwFOGTYPENAFOGTYPE = 0,
+ rwFOGTYPELINEAR,
+ rwFOGTYPEEXPONENTIAL,
+ rwFOGTYPEEXPONENTIAL2
+};
+
+enum RwTextureFilterMode
+{
+ rwFILTERNAFILTERMODE = 0,
+ rwFILTERNEAREST = rw::Texture::NEAREST,
+ rwFILTERLINEAR = rw::Texture::LINEAR,
+ rwFILTERMIPNEAREST = rw::Texture::MIPNEAREST,
+ rwFILTERMIPLINEAR = rw::Texture::MIPLINEAR,
+ rwFILTERLINEARMIPNEAREST = rw::Texture::LINEARMIPNEAREST,
+ rwFILTERLINEARMIPLINEAR = rw::Texture::LINEARMIPLINEAR
+};
+
+enum RwTextureAddressMode
+{
+ rwTEXTUREADDRESSNATEXTUREADDRESS = 0,
+ rwTEXTUREADDRESSWRAP = rw::Texture::WRAP,
+ rwTEXTUREADDRESSMIRROR = rw::Texture::MIRROR,
+ rwTEXTUREADDRESSCLAMP = rw::Texture::CLAMP,
+ rwTEXTUREADDRESSBORDER = rw::Texture::BORDER
+};
+
+enum RwCullMode
+{
+ rwCULLMODENACULLMODE = 0,
+ rwCULLMODECULLNONE = rw::CULLNONE,
+ rwCULLMODECULLBACK = rw::CULLBACK,
+ rwCULLMODECULLFRONT = rw::CULLFRONT
+};
+
+enum RwPrimitiveType
+{
+ rwPRIMTYPENAPRIMTYPE = rw::PRIMTYPENONE,
+ rwPRIMTYPELINELIST = rw::PRIMTYPELINELIST,
+ rwPRIMTYPEPOLYLINE = rw::PRIMTYPEPOLYLINE,
+ rwPRIMTYPETRILIST = rw::PRIMTYPETRILIST,
+ rwPRIMTYPETRISTRIP = rw::PRIMTYPETRISTRIP,
+ rwPRIMTYPETRIFAN = rw::PRIMTYPETRIFAN,
+ rwPRIMTYPEPOINTLIST = rw::PRIMTYPEPOINTLIST
+};
+
+
+RwBool RwRenderStateGet(RwRenderState state, void *value);
+RwBool RwRenderStateSet(RwRenderState state, void *value);
+
+
+/*
+ ***********************************************
+ *
+ * Engine
+ *
+ ***********************************************
+ */
+
+struct RwEngineOpenParams
+{
+ void *displayID;
+};
+
+typedef rw::SubSystemInfo RwSubSystemInfo;
+
+enum RwVideoModeFlag
+{
+ rwVIDEOMODEEXCLUSIVE = rw::VIDEOMODEEXCLUSIVE,
+/*
+ rwVIDEOMODEINTERLACE = 0x2,
+ rwVIDEOMODEFFINTERLACE = 0x4,
+ rwVIDEOMODEFSAA0 = 0x8,
+ rwVIDEOMODEFSAA1 = 0x10
+*/
+};
+
+typedef rw::VideoMode RwVideoMode;
+
+#if 0
+struct RwFileFunctions
+{
+ rwFnFexist rwfexist; /**< Pointer to fexist function */
+ rwFnFopen rwfopen; /**< Pointer to fopen function */
+ rwFnFclose rwfclose; /**< Pointer to fclose function */
+ rwFnFread rwfread; /**< Pointer to fread function */
+ rwFnFwrite rwfwrite; /**< Pointer to fwrite function */
+ rwFnFgets rwfgets; /**< Pointer to fgets function */
+ rwFnFputs rwfputs; /**< Pointer to puts function */
+ rwFnFeof rwfeof; /**< Pointer to feof function */
+ rwFnFseek rwfseek; /**< Pointer to fseek function */
+ rwFnFflush rwfflush; /**< Pointer to fflush function */
+ rwFnFtell rwftell; /**< Pointer to ftell function */
+};
+RwFileFunctions *RwOsGetFileInterface(void);
+#endif
+
+RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize);
+RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, RwPluginObjectDestructor termCB);
+RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID);
+RwBool RwEngineOpen(RwEngineOpenParams *initParams);
+RwBool RwEngineStart(void);
+RwBool RwEngineStop(void);
+RwBool RwEngineClose(void);
+RwBool RwEngineTerm(void);
+RwInt32 RwEngineGetNumSubSystems(void);
+RwSubSystemInfo *RwEngineGetSubSystemInfo(RwSubSystemInfo *subSystemInfo, RwInt32 subSystemIndex);
+RwInt32 RwEngineGetCurrentSubSystem(void);
+RwBool RwEngineSetSubSystem(RwInt32 subSystemIndex);
+RwInt32 RwEngineGetNumVideoModes(void);
+RwVideoMode *RwEngineGetVideoModeInfo(RwVideoMode *modeinfo, RwInt32 modeIndex);
+RwInt32 RwEngineGetCurrentVideoMode(void);
+RwBool RwEngineSetVideoMode(RwInt32 modeIndex);
+RwInt32 RwEngineGetTextureMemorySize(void);
+RwInt32 RwEngineGetMaxTextureSize(void);
+
+
+/*
+ ***********************************************
+ *
+ * Binary stream
+ *
+ ***********************************************
+ */
+
+RwBool RwStreamFindChunk(RwStream *stream, RwUInt32 type, RwUInt32 *lengthOut, RwUInt32 *versionOut);
diff --git a/src/math/Quaternion.h b/src/math/Quaternion.h
index fb37dc10..1d04bdff 100644
--- a/src/math/Quaternion.h
+++ b/src/math/Quaternion.h
@@ -10,6 +10,18 @@ public:
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z + w*w); }
float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; }
+ void Normalise(void) {
+ float sq = MagnitudeSqr();
+ if(sq == 0.0f)
+ w = 1.0f;
+ else{
+ float invsqrt = RecipSqrt(sq);
+ x *= invsqrt;
+ y *= invsqrt;
+ z *= invsqrt;
+ w *= invsqrt;
+ }
+ }
const CQuaternion &operator+=(CQuaternion const &right) {
x += right.x;
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 1274a4b2..44e646e9 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -9,6 +9,11 @@ public:
#ifdef RWCORE_H
CVector(const RwV3d &v) : x(v.x), y(v.y), z(v.z) {}
+ RwV3d toRwV3d(void) const {
+ RwV3d vecRw = { this->x, this->y, this->z };
+ return vecRw;
+ }
+
operator RwV3d (void) const {
RwV3d vecRw = { this->x, this->y, this->z };
return vecRw;
@@ -46,6 +51,13 @@ public:
y *= invsqrt;
z *= invsqrt;
}
+
+ void Normalise2D(void) {
+ float sq = MagnitudeSqr2D();
+ float invsqrt = RecipSqrt(sq);
+ x *= invsqrt;
+ y *= invsqrt;
+ }
const CVector &operator+=(CVector const &right) {
x += right.x;
diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h
index 1e4d698f..0885a5d2 100644
--- a/src/math/Vector2D.h
+++ b/src/math/Vector2D.h
@@ -11,15 +11,18 @@ public:
float Magnitude(void) const { return Sqrt(x*x + y*y); }
float MagnitudeSqr(void) const { return x*x + y*y; }
- void Normalise(void){
+ void Normalise(void);
+
+ void NormaliseSafe(void) {
float sq = MagnitudeSqr();
if(sq > 0.0f){
float invsqrt = RecipSqrt(sq);
x *= invsqrt;
y *= invsqrt;
}else
- x = 1.0f;
+ y = 1.0f;
}
+
const CVector2D &operator+=(CVector2D const &right) {
x += right.x;
y += right.y;
diff --git a/src/math/math.cpp b/src/math/math.cpp
index 4f74fac9..eeb9d3fa 100644
--- a/src/math/math.cpp
+++ b/src/math/math.cpp
@@ -1,10 +1,23 @@
#include "common.h"
-#include "patcher.h"
+
#include "Quaternion.h"
// TODO: move more stuff into here
void
+CVector2D::Normalise(void)
+{
+ float sq = MagnitudeSqr();
+ assert(sq != 0.0f); // just be safe here
+ //if(sq > 0.0f){
+ float invsqrt = RecipSqrt(sq);
+ x *= invsqrt;
+ y *= invsqrt;
+ //}else
+ // x = 1.0f;
+}
+
+void
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
{
float cX = Cos(xAngle);
@@ -191,8 +204,3 @@ CQuaternion::Get(RwMatrix *matrix)
matrix->up.z = y_2z + w_2x;
matrix->at.z = 1.0f - (x_2x + y_2y);
}
-
-STARTPATCHES
- InjectHook(0x4BA1C0, &CQuaternion::Slerp, PATCH_JUMP);
- InjectHook(0x4BA0D0, &CQuaternion::Get, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp
index 830ead51..e8d2601f 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "templates.h"
#include "TxdStore.h"
#include "2dEffect.h"
@@ -99,25 +99,3 @@ CBaseModelInfo::Get2dEffect(int n)
else
return nil;
}
-
-
-class CBaseModelInfo_ : public CBaseModelInfo
-{
-public:
- void Shutdown_(void) { CBaseModelInfo::Shutdown(); }
-};
-STARTPATCHES
- // can't easily replace ctor at 4F6A50
- InjectHook(0x4F6A90, &CBaseModelInfo_::Shutdown_, PATCH_JUMP);
-
- InjectHook(0x4F6AC0, &CBaseModelInfo::DeleteCollisionModel, PATCH_JUMP);
- InjectHook(0x4F6B70, &CBaseModelInfo::ClearTexDictionary, PATCH_JUMP);
- InjectHook(0x4F6BA0, &CBaseModelInfo::AddRef, PATCH_JUMP);
- InjectHook(0x4F6BB0, &CBaseModelInfo::RemoveRef, PATCH_JUMP);
- InjectHook(0x4F6B40, &CBaseModelInfo::SetTexDictionary, PATCH_JUMP);
- InjectHook(0x4F6B80, &CBaseModelInfo::AddTexDictionaryRef, PATCH_JUMP);
- InjectHook(0x4F6B90, &CBaseModelInfo::RemoveTexDictionaryRef, PATCH_JUMP);
- InjectHook(0x4F6B20, &CBaseModelInfo::Add2dEffect, PATCH_JUMP);
- InjectHook(0x4F6AF0, &CBaseModelInfo::Init2dEffects, PATCH_JUMP);
- InjectHook(0x4F6B00, &CBaseModelInfo::Get2dEffect, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp
index c6a6d5d0..44faf3c5 100644
--- a/src/modelinfo/ClumpModelInfo.cpp
+++ b/src/modelinfo/ClumpModelInfo.cpp
@@ -1,5 +1,6 @@
#include "common.h"
-#include "patcher.h"
+
+#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
@@ -15,12 +16,40 @@ CClumpModelInfo::DeleteRwObject(void)
}
}
+#ifdef PED_SKIN
+static RpAtomic*
+SetHierarchyForSkinAtomic(RpAtomic *atomic, void *data)
+{
+ RpSkinAtomicSetHAnimHierarchy(atomic, (RpHAnimHierarchy*)data);
+ return nil;
+}
+#endif
+
RwObject*
CClumpModelInfo::CreateInstance(void)
{
- if(m_clump)
- return (RwObject*)RpClumpClone(m_clump);
- return nil;
+ if(m_clump == nil)
+ return nil;
+ RpClump *clone = RpClumpClone(m_clump);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clone)){
+ RpHAnimHierarchy *hier;
+ RpHAnimAnimation *anim;
+
+ hier = GetAnimHierarchyFromClump(clone);
+ assert(hier);
+ // This seems dangerous as only the first atomic will get a hierarchy
+ // can we guarantee this if hands and head are also in the clump?
+ RpClumpForAllAtomics(clone, SetHierarchyForSkinAtomic, hier);
+ anim = HAnimAnimationCreateForHierarchy(hier);
+ RpHAnimHierarchySetCurrentAnim(hier, anim);
+// RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
+ // the rest is xbox only:
+ // RpSkinGetNumBones(RpSkinGeometryGetSkin(RpAtomicGetGeometry(IsClumpSkinned(clone))));
+ RpHAnimHierarchyUpdateMatrices(hier);
+ }
+#endif
+ return (RwObject*)clone;
}
RwObject*
@@ -48,8 +77,45 @@ CClumpModelInfo::SetClump(RpClump *clump)
CVisibilityPlugins::SetClumpModelInfo(m_clump, this);
AddTexDictionaryRef();
RpClumpForAllAtomics(clump, SetAtomicRendererCB, nil);
+
+ // TODO: also set for player?
if(strncmp(GetName(), "playerh", 8) == 0)
RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+
+#ifdef PED_SKIN
+ if(IsClumpSkinned(clump)){
+ int i;
+ RpHAnimHierarchy *hier;
+ RpAtomic *skinAtomic;
+ RpSkin *skin;
+
+ // mobile:
+// hier = nil;
+// RwFrameForAllChildren(RpClumpGetFrame(clump), GetHierarchyFromChildNodesCB, &hier);
+// assert(hier);
+// RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
+// skinAtomic = GetFirstAtomic(clump);
+
+ // xbox:
+ hier = GetAnimHierarchyFromClump(clump);
+ assert(hier);
+ RpSkinAtomicSetHAnimHierarchy(IsClumpSkinned(clump), hier);
+ skinAtomic = IsClumpSkinned(clump);
+
+ assert(skinAtomic);
+ skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(skinAtomic));
+ // ignore const
+ for(i = 0; i < RpGeometryGetNumVertices(RpAtomicGetGeometry(skinAtomic)); i++){
+ RwMatrixWeights *weights = (RwMatrixWeights*)&RpSkinGetVertexBoneWeights(skin)[i];
+ float sum = weights->w0 + weights->w1 + weights->w2 + weights->w3;
+ weights->w0 /= sum;
+ weights->w1 /= sum;
+ weights->w2 /= sum;
+ weights->w3 /= sum;
+ }
+// RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
+ }
+#endif
}
void
@@ -138,30 +204,3 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id)
RwFrameForAllChildren(RpClumpGetFrame(clump), FindFrameFromIdCB, &assoc);
return assoc.frame;
}
-
-
-class CClumpModelInfo_ : public CClumpModelInfo
-{
-public:
- void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); }
- RwObject *CreateInstance_1(void) { return CClumpModelInfo::CreateInstance(); }
- RwObject *CreateInstance_2(RwMatrix *m) { return CClumpModelInfo::CreateInstance(m); }
- RwObject *GetRwObject_(void) { return CClumpModelInfo::GetRwObject(); }
- void SetClump_(RpClump *clump) { CClumpModelInfo::SetClump(clump); }
-};
-
-STARTPATCHES
- InjectHook(0x4F8800, &CClumpModelInfo_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x4F8920, &CClumpModelInfo_::CreateInstance_1, PATCH_JUMP);
- InjectHook(0x4F88A0, &CClumpModelInfo_::CreateInstance_2, PATCH_JUMP);
- InjectHook(0x50C1C0, &CClumpModelInfo_::GetRwObject_, PATCH_JUMP);
- InjectHook(0x4F8830, &CClumpModelInfo_::SetClump_, PATCH_JUMP);
- InjectHook(0x4F8940, &CClumpModelInfo::SetAtomicRendererCB, PATCH_JUMP);
- InjectHook(0x4F8960, &CClumpModelInfo::FindFrameFromNameCB, PATCH_JUMP);
- InjectHook(0x4F8A10, &CClumpModelInfo::FindFrameFromNameWithoutIdCB, PATCH_JUMP);
- InjectHook(0x4F8AD0, &CClumpModelInfo::FindFrameFromIdCB, PATCH_JUMP);
- InjectHook(0x4F8BB0, &CClumpModelInfo::SetFrameIds, PATCH_JUMP);
- InjectHook(0x4F8B20, &CClumpModelInfo::FillFrameArrayCB, PATCH_JUMP);
- InjectHook(0x4F8B90, &CClumpModelInfo::FillFrameArray, PATCH_JUMP);
- InjectHook(0x4F8B50, &CClumpModelInfo::GetFrameFromId, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/MloModelInfo.cpp b/src/modelinfo/MloModelInfo.cpp
index 746d9db4..7535e6c5 100644
--- a/src/modelinfo/MloModelInfo.cpp
+++ b/src/modelinfo/MloModelInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
diff --git a/src/modelinfo/ModelIndices.cpp b/src/modelinfo/ModelIndices.cpp
index ec039a0b..9a6a74d0 100644
--- a/src/modelinfo/ModelIndices.cpp
+++ b/src/modelinfo/ModelIndices.cpp
@@ -1,9 +1,9 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "ModelIndices.h"
-#define X(name, var, addr) int16 &var = *(int16*)addr;
+#define X(name, var, addr) int16 var;
MODELINDICES
#undef X
@@ -32,8 +32,3 @@ TestModelIndices(void)
{
;
}
-
-STARTPATCHES
- InjectHook(0x48EB60, InitModelIndices, PATCH_JUMP);
- InjectHook(0x48F030, MatchModelString, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index 20d1b7f3..8e117882 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -158,7 +158,7 @@
X("subplatform_sub", MI_SUBPLATFORM_SUB2, 0x5F5BC0) \
X("files", MI_FILES, 0x5F5BC4)
-#define X(name, var, addr) extern int16 &var;
+#define X(name, var, addr) extern int16 var;
MODELINDICES
#undef X
@@ -490,3 +490,17 @@ IsPoliceVehicleModel(int16 id)
id == MI_POLICE ||
id == MI_ENFORCER;
}
+
+inline bool
+IsExplosiveThingModel(int16 id)
+{
+ return id == MI_EXPLODINGBARREL ||
+ id == MI_PETROLPUMP;
+}
+
+inline bool
+IsFence(int16 id)
+{
+ return id == MI_FENCE ||
+ id == MI_FENCE2;
+} \ No newline at end of file
diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp
index b6a95992..c1ae692f 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -1,15 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "TempColModels.h"
#include "ModelIndices.h"
#include "ModelInfo.h"
-CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408;
+CBaseModelInfo *CModelInfo::ms_modelInfoPtrs[MODELINFOSIZE];
-//CStore<CSimpleModelInfo, SIMPLEMODELSIZE> &CModelInfo::ms_simpleModelStore = *(CStore<CSimpleModelInfo, SIMPLEMODELSIZE>*)0x885BB4;
-//CStore<CTimeModelInfo, TIMEMODELSIZE> &CModelInfo::ms_timeModelStore = *(CStore<CTimeModelInfo, TIMEMODELSIZE>*)0x94076C;
-//CStore<C2dEffect, TWODFXSIZE> &CModelInfo::ms_2dEffectStore = *(CStore<C2dEffect, TWODFXSIZE>*)0x9434F8;
CStore<CSimpleModelInfo, SIMPLEMODELSIZE> CModelInfo::ms_simpleModelStore;
CStore<CMloModelInfo, MLOMODELSIZE> CModelInfo::ms_mloModelStore;
CStore<CInstance, MLOINSTANCESIZE> CModelInfo::ms_mloInstanceStore;
@@ -251,15 +248,3 @@ CModelInfo::ReInit2dEffects()
ms_modelInfoPtrs[i]->Init2dEffects();
}
}
-
-STARTPATCHES
- InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP);
- InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP);
- InjectHook(0x50B920, CModelInfo::AddSimpleModel, PATCH_JUMP);
- InjectHook(0x50B9C0, CModelInfo::AddTimeModel, PATCH_JUMP);
- InjectHook(0x50BA10, CModelInfo::AddClumpModel, PATCH_JUMP);
- InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
- InjectHook(0x50BA60, CModelInfo::AddVehicleModel, PATCH_JUMP);
- InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
- InjectHook(0x50BBC0, CModelInfo::RemoveColModelsFromOtherLevels, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index e6dec1d8..65cfa4e7 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -13,7 +13,7 @@
class CModelInfo
{
- static CBaseModelInfo **ms_modelInfoPtrs; //[MODELINFOSIZE];
+ static CBaseModelInfo *ms_modelInfoPtrs[MODELINFOSIZE];
static CStore<CSimpleModelInfo, SIMPLEMODELSIZE> ms_simpleModelStore;
static CStore<CMloModelInfo, MLOMODELSIZE> ms_mloModelStore;
static CStore<CInstance, MLOINSTANCESIZE> ms_mloInstanceStore;
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 015c6949..47080e23 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -1,6 +1,9 @@
#include "common.h"
-#include "patcher.h"
+
+#include "RwHelper.h"
#include "General.h"
+#include "Bones.h"
+#include "SurfaceTable.h"
#include "Ped.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
@@ -9,13 +12,31 @@
void
CPedModelInfo::DeleteRwObject(void)
{
- CClumpModelInfo::DeleteRwObject();
if(m_hitColModel)
delete m_hitColModel;
m_hitColModel = nil;
+#ifdef PED_SKIN
+ RwFrame *frame;
+ if(m_head){
+ frame = RpAtomicGetFrame(m_head);
+ RpAtomicDestroy(m_head);
+ RwFrameDestroy(frame);
+ }
+ if(m_lhand){
+ frame = RpAtomicGetFrame(m_lhand);
+ RpAtomicDestroy(m_lhand);
+ RwFrameDestroy(frame);
+ }
+ if(m_rhand){
+ frame = RpAtomicGetFrame(m_rhand);
+ RpAtomicDestroy(m_rhand);
+ RwFrameDestroy(frame);
+ }
+#endif
+ CClumpModelInfo::DeleteRwObject(); // PC calls this first
}
-RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[12] = {
+RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[PED_NODE_MAX] = {
{ "Smid", PED_MID, 0, }, // that is strange...
{ "Shead", PED_HEAD, 0, },
{ "Supperarml", PED_UPPERARML, 0, },
@@ -30,15 +51,70 @@ RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[12] = {
{ nil, 0, 0, },
};
+#ifdef PED_SKIN
+struct LimbCBarg
+{
+ CPedModelInfo *mi;
+ RpClump *clump;
+ int32 frameIDs[3];
+};
+
+RpAtomic*
+CPedModelInfo::findLimbsCb(RpAtomic *atomic, void *data)
+{
+ LimbCBarg *limbs = (LimbCBarg*)data;
+ RwFrame *frame = RpAtomicGetFrame(atomic);
+ const char *name = GetFrameNodeName(frame);
+ if(CGeneral::faststricmp(name, "Shead01") == 0){
+ limbs->frameIDs[0] = RpHAnimFrameGetID(frame);
+ limbs->mi->m_head = atomic;
+ RpClumpRemoveAtomic(limbs->clump, atomic);
+ RwFrameRemoveChild(frame);
+ }else if(CGeneral::faststricmp(name, "SLhand01") == 0){
+ limbs->frameIDs[1] = RpHAnimFrameGetID(frame);
+ limbs->mi->m_lhand = atomic;
+ RpClumpRemoveAtomic(limbs->clump, atomic);
+ RwFrameRemoveChild(frame);
+ }else if(CGeneral::faststricmp(name, "SRhand01") == 0){
+ limbs->frameIDs[2] = RpHAnimFrameGetID(frame);
+ limbs->mi->m_rhand = atomic;
+ RpClumpRemoveAtomic(limbs->clump, atomic);
+ RwFrameRemoveChild(frame);
+ }
+ return atomic;
+}
+#endif
+
void
CPedModelInfo::SetClump(RpClump *clump)
{
+#ifdef PED_SKIN
+
+ // CB has to be set here before atomics are detached from clump
+ if(strncmp(GetName(), "player", 7) == 0)
+ RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+ if(IsClumpSkinned(clump)){
+ LimbCBarg limbs = { this, clump, { 0, 0, 0 } };
+ RpClumpForAllAtomics(clump, findLimbsCb, &limbs);
+ }
+ CClumpModelInfo::SetClump(clump);
+ SetFrameIds(m_pPedIds);
+ if(m_hitColModel == nil && !IsClumpSkinned(clump))
+ CreateHitColModel();
+ // And again because CClumpModelInfo resets it
+ if(strncmp(GetName(), "player", 7) == 0)
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+ else if(IsClumpSkinned(clump))
+ // skinned peds have no low detail version, so they don't have the right render Cb
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
+#else
CClumpModelInfo::SetClump(clump);
SetFrameIds(m_pPedIds);
if(m_hitColModel == nil)
CreateHitColModel();
if(strncmp(GetName(), "player", 7) == 0)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+#endif
}
RpAtomic*
@@ -157,7 +233,7 @@ CPedModelInfo::CreateHitColModel(void)
}
if(nodeFrame){
float radius = m_pColNodeInfos[i].radius;
- if(m_pColNodeInfos[i].pieceType == 6)
+ if(m_pColNodeInfos[i].pieceType == PEDPIECE_HEAD)
RwFrameForAllObjects(nodeFrame, FindHeadRadiusCB, &radius);
RwMatrixTransform(mat, RwFrameGetMatrix(nodeFrame), rwCOMBINEREPLACE);
const char *name = GetFrameNodeName(nodeFrame);
@@ -172,7 +248,7 @@ CPedModelInfo::CreateHitColModel(void)
center.x = mat->pos.x + m_pColNodeInfos[i].x;
center.y = mat->pos.y + 0.0f;
center.z = mat->pos.z + m_pColNodeInfos[i].z;
- spheres[i].Set(radius, center, 17, m_pColNodeInfos[i].pieceType);
+ spheres[i].Set(radius, center, SURFACE_FLESH, m_pColNodeInfos[i].pieceType);
}
}
RwMatrixDestroy(mat);
@@ -186,7 +262,7 @@ CPedModelInfo::CreateHitColModel(void)
max.x = max.y = 0.5f;
max.z = 1.2f;
colmodel->boundingBox.Set(min, max, 0, 0);
- colmodel->level = 0;
+ colmodel->level = LEVEL_NONE;
m_hitColModel = colmodel;
}
@@ -230,16 +306,80 @@ CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
return colmodel;
}
-class CPedModelInfo_ : public CPedModelInfo
+#ifdef PED_SKIN
+void
+CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
{
-public:
- void DeleteRwObject_(void) { CPedModelInfo::DeleteRwObject(); }
- void SetClump_(RpClump *clump) { CPedModelInfo::SetClump(clump); }
-};
+ CVector center;
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
+ CColModel *colmodel = new CColModel;
+ CColSphere *spheres = (CColSphere*)RwMalloc(NUMPEDINFONODES*sizeof(CColSphere));
+ RwFrame *root = RpClumpGetFrame(m_clump);
+ RwMatrix *invmat = RwMatrixCreate();
+ RwMatrix *mat = RwMatrixCreate();
+ RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
+
+ for(int i = 0; i < NUMPEDINFONODES; i++){
+ *mat = *invmat;
+ int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode); // this is wrong, wtf R* ???
+ int idx = RpHAnimIDGetIndex(hier, id);
+
+ // This doesn't really work as the positions are not initialized yet
+ RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RwV3dTransformPoints(&pos, &pos, 1, mat);
+
+ center.x = pos.x + m_pColNodeInfos[i].x;
+ center.y = pos.y + 0.0f;
+ center.z = pos.z + m_pColNodeInfos[i].z;
+ spheres[i].Set(m_pColNodeInfos[i].radius, center, SURFACE_FLESH, m_pColNodeInfos[i].pieceType);
+ }
+ RwMatrixDestroy(invmat);
+ RwMatrixDestroy(mat);
+ colmodel->spheres = spheres;
+ colmodel->numSpheres = NUMPEDINFONODES;
+ center.x = center.y = center.z = 0.0f;
+ colmodel->boundingSphere.Set(2.0f, center, 0, 0);
+ CVector min, max;
+ min.x = min.y = -0.5f;
+ min.z = -1.2f;
+ max.x = max.y = 0.5f;
+ max.z = 1.2f;
+ colmodel->boundingBox.Set(min, max, 0, 0);
+ colmodel->level = LEVEL_NONE;
+ m_hitColModel = colmodel;
+}
+
+CColModel*
+CPedModelInfo::AnimatePedColModelSkinned(RpClump *clump)
+{
+ if(m_hitColModel == nil){
+ CreateHitColModelSkinned(clump);
+ return m_hitColModel;
+ }
+ RwMatrix *invmat, *mat;
+ CColSphere *spheres = m_hitColModel->spheres;
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
+ invmat = RwMatrixCreate();
+ mat = RwMatrixCreate();
+ RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
+
+ for(int i = 0; i < NUMPEDINFONODES; i++){
+ *mat = *invmat;
+ int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode);
+ int idx = RpHAnimIDGetIndex(hier, id);
+
+ RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RwV3dTransformPoints(&pos, &pos, 1, mat);
+
+ spheres[i].center.x = pos.x + m_pColNodeInfos[i].x;
+ spheres[i].center.y = pos.y + 0.0f;
+ spheres[i].center.z = pos.z + m_pColNodeInfos[i].z;
+ }
+ RwMatrixDestroy(invmat);
+ RwMatrixDestroy(mat);
+ return m_hitColModel;
+}
-STARTPATCHES
- InjectHook(0x510210, &CPedModelInfo_::SetClump_, PATCH_JUMP);
- InjectHook(0x510280, &CPedModelInfo_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x510390, &CPedModelInfo::SetLowDetailClump, PATCH_JUMP);
- InjectHook(0x5104D0, &CPedModelInfo::CreateHitColModel, PATCH_JUMP);
-ENDPATCHES
+#endif
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index 0336fa9b..a2bfd122 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -28,11 +28,13 @@ public:
ePedStats m_pedStatType;
uint32 m_carsCanDrive;
CColModel *m_hitColModel;
+#ifdef PED_SKIN
RpAtomic *m_head;
RpAtomic *m_lhand;
RpAtomic *m_rhand;
+#endif
- static RwObjectNameIdAssocation m_pPedIds[12];
+ static RwObjectNameIdAssocation m_pPedIds[PED_NODE_MAX];
CPedModelInfo(void) : CClumpModelInfo(MITYPE_PED) { }
void DeleteRwObject(void);
@@ -40,7 +42,18 @@ public:
void SetLowDetailClump(RpClump*);
void CreateHitColModel(void);
+ void CreateHitColModelSkinned(RpClump *clump);
CColModel *GetHitColModel(void) { return m_hitColModel; }
static CColModel *AnimatePedColModel(CColModel* colmodel, RwFrame* frame);
+ CColModel *AnimatePedColModelSkinned(RpClump *clump);
+
+#ifdef PED_SKIN
+ static RpAtomic *findLimbsCb(RpAtomic *atomic, void *data);
+ RpAtomic *getHead(void) { return m_head; }
+ RpAtomic *getLeftHand(void) { return m_lhand; }
+ RpAtomic *getRightHand(void) { return m_rhand; }
+#endif
};
-static_assert(sizeof(CPedModelInfo) == 0x54, "CPedModelInfo: error");
+#ifndef PED_SKIN
+static_assert(sizeof(CPedModelInfo) == 0x48, "CPedModelInfo: error");
+#endif \ No newline at end of file
diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp
index f8742f1e..2fb2adeb 100644
--- a/src/modelinfo/SimpleModelInfo.cpp
+++ b/src/modelinfo/SimpleModelInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "Camera.h"
#include "ModelInfo.h"
@@ -154,28 +154,3 @@ CSimpleModelInfo::SetupBigBuilding(void)
m_lodDistances[2] = 100.0f;
}
}
-
-class CSimpleModelInfo_ : public CSimpleModelInfo
-{
-public:
- void DeleteRwObject_(void) { CSimpleModelInfo::DeleteRwObject(); }
- RwObject *CreateInstance_1(void) { return CSimpleModelInfo::CreateInstance(); }
- RwObject *CreateInstance_2(RwMatrix *m) { return CSimpleModelInfo::CreateInstance(m); }
- RwObject *GetRwObject_(void) { return CSimpleModelInfo::GetRwObject(); }
-};
-
-STARTPATCHES
- InjectHook(0x5179B0, &CSimpleModelInfo_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x517B60, &CSimpleModelInfo_::CreateInstance_1, PATCH_JUMP);
- InjectHook(0x517AC0, &CSimpleModelInfo_::CreateInstance_2, PATCH_JUMP);
- InjectHook(0x4A9BA0, &CSimpleModelInfo_::GetRwObject_, PATCH_JUMP);
- InjectHook(0x517990, &CSimpleModelInfo::Init, PATCH_JUMP);
- InjectHook(0x517C60, &CSimpleModelInfo::IncreaseAlpha, PATCH_JUMP);
- InjectHook(0x517950, &CSimpleModelInfo::SetAtomic, PATCH_JUMP);
- InjectHook(0x517AA0, &CSimpleModelInfo::SetLodDistances, PATCH_JUMP);
- InjectHook(0x517A90, &CSimpleModelInfo::GetNearDistance, PATCH_JUMP);
- InjectHook(0x517A60, &CSimpleModelInfo::GetLargestLodDistance, PATCH_JUMP);
- InjectHook(0x517A00, &CSimpleModelInfo::GetAtomicFromDistance, PATCH_JUMP);
- InjectHook(0x517C00, &CSimpleModelInfo::FindRelatedModel, PATCH_JUMP);
- InjectHook(0x517B90, &CSimpleModelInfo::SetupBigBuilding, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/TimeModelInfo.cpp b/src/modelinfo/TimeModelInfo.cpp
index 3ab3e13a..fec3f6e5 100644
--- a/src/modelinfo/TimeModelInfo.cpp
+++ b/src/modelinfo/TimeModelInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Camera.h"
#include "ModelInfo.h"
@@ -30,7 +30,3 @@ CTimeModelInfo::FindOtherTimeModel(void)
}
return nil;
}
-
-STARTPATCHES
- InjectHook(0x517C80, &CTimeModelInfo::FindOtherTimeModel, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 0c45aa12..0c3a7720 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include <rpmatfx.h>
-#include "patcher.h"
+
#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
@@ -19,14 +19,14 @@
#include "ModelIndices.h"
#include "ModelInfo.h"
-int8 *CVehicleModelInfo::ms_compsToUse = (int8*)0x5FF2EC; // -2, -2
-int8 *CVehicleModelInfo::ms_compsUsed = (int8*)0x95CCB2;
-RwTexture **CVehicleModelInfo::ms_pEnvironmentMaps = (RwTexture **)0x8F1A30;
-RwRGBA *CVehicleModelInfo::ms_vehicleColourTable = (RwRGBA*)0x86BA88;
-RwTexture **CVehicleModelInfo::ms_colourTextureTable = (RwTexture**)0x711C40;
+int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
+int8 CVehicleModelInfo::ms_compsUsed[2];
+RwTexture *CVehicleModelInfo::ms_pEnvironmentMaps[NUM_VEHICLE_ENVMAPS];
+RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
+RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
-RwTexture *&gpWhiteTexture = *(RwTexture**)0x64C4F8;
-RwFrame *&pMatFxIdentityFrame = *(RwFrame**)0x64C510;
+RwTexture *gpWhiteTexture;
+RwFrame *pMatFxIdentityFrame;
enum {
VEHICLE_FLAG_COLLAPSE = 0x2,
@@ -1104,65 +1104,3 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
return n - 1;
}
-
-class CVehicleModelInfo_ : public CVehicleModelInfo
-{
-public:
- void DeleteRwObject_(void) { CVehicleModelInfo::DeleteRwObject(); }
- RwObject *CreateInstance_(void) { return CVehicleModelInfo::CreateInstance(); }
- void SetClump_(RpClump *clump) { CVehicleModelInfo::SetClump(clump); }
-};
-
-STARTPATCHES
- InjectHook(0x427820, &CVehicleModelInfo::SetComponentsToUse, PATCH_JUMP);
-
- InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP);
- InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP);
-
- InjectHook(0x51FE10, &CVehicleModelInfo::CollapseFramesCB, PATCH_JUMP);
- InjectHook(0x51FE50, &CVehicleModelInfo::MoveObjectsCB, PATCH_JUMP);
- InjectHook(0x51FE70, &CVehicleModelInfo::HideDamagedAtomicCB, PATCH_JUMP);
- InjectHook(0x51FED0, &CVehicleModelInfo::HideAllComponentsAtomicCB, PATCH_JUMP);
- InjectHook(0x51FEF0, &CVehicleModelInfo::HasAlphaMaterialCB, PATCH_JUMP);
-
- InjectHook(0x51FF10, &CVehicleModelInfo::SetAtomicRendererCB, PATCH_JUMP);
- InjectHook(0x520030, &CVehicleModelInfo::SetAtomicRendererCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x520230, &CVehicleModelInfo::SetAtomicRendererCB_Train, PATCH_JUMP);
- InjectHook(0x520120, &CVehicleModelInfo::SetAtomicRendererCB_Boat, PATCH_JUMP);
- InjectHook(0x520210, &CVehicleModelInfo::SetAtomicRendererCB_Heli, PATCH_JUMP);
- InjectHook(0x5202C0, &CVehicleModelInfo::SetAtomicRenderCallbacks, PATCH_JUMP);
-
- InjectHook(0x520340, &CVehicleModelInfo::SetAtomicFlagCB, PATCH_JUMP);
- InjectHook(0x520360, &CVehicleModelInfo::ClearAtomicFlagCB, PATCH_JUMP);
-
- InjectHook(0x5204D0, &CVehicleModelInfo::PreprocessHierarchy, PATCH_JUMP);
- InjectHook(0x5203C0, &CVehicleModelInfo::SetVehicleComponentFlags, PATCH_JUMP);
-
- InjectHook(0x520840, &CVehicleModelInfo::GetWheelPosn, PATCH_JUMP);
-
- InjectHook(0x520880, IsValidCompRule, PATCH_JUMP);
- InjectHook(0x520990, CountCompsInRule, PATCH_JUMP);
- InjectHook(0x5209C0, ChooseComponent, PATCH_JUMP);
- InjectHook(0x5208C0, GetListOfComponentsNotUsedByRules, PATCH_JUMP);
- InjectHook(0x520AB0, &CVehicleModelInfo::ChooseComponent, PATCH_JUMP);
- InjectHook(0x520BE0, &CVehicleModelInfo::ChooseSecondComponent, PATCH_JUMP);
-
- InjectHook(0x520DC0, (RpAtomic *(*)(RpAtomic*, void*))CVehicleModelInfo::GetEditableMaterialListCB, PATCH_JUMP);
- InjectHook(0x520D30, (RpMaterial *(*)(RpMaterial*, void*))CVehicleModelInfo::GetEditableMaterialListCB, PATCH_JUMP);
- InjectHook(0x520DE0, &CVehicleModelInfo::FindEditableMaterialList, PATCH_JUMP);
- InjectHook(0x520E70, &CVehicleModelInfo::SetVehicleColour, PATCH_JUMP);
- InjectHook(0x520FD0, &CVehicleModelInfo::ChooseVehicleColour, PATCH_JUMP);
- InjectHook(0x5210A0, &CVehicleModelInfo::AvoidSameVehicleColour, PATCH_JUMP);
- InjectHook(0x521260, &CVehicleModelInfo::LoadVehicleColours, PATCH_JUMP);
- InjectHook(0x521650, &CVehicleModelInfo::DeleteVehicleColourTextures, PATCH_JUMP);
-
- InjectHook(0x5219D0, &CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors, PATCH_JUMP);
-
- InjectHook(0x521820, (RpAtomic *(*)(RpAtomic*, void*))CVehicleModelInfo::SetEnvironmentMapCB, PATCH_JUMP);
- InjectHook(0x5217A0, (RpMaterial *(*)(RpMaterial*, void*))CVehicleModelInfo::SetEnvironmentMapCB, PATCH_JUMP);
- InjectHook(0x521770, CVehicleModelInfo::HasSpecularMaterialCB, PATCH_JUMP);
- InjectHook(0x521890, &CVehicleModelInfo::SetEnvironmentMap, PATCH_JUMP);
- InjectHook(0x521680, CVehicleModelInfo::LoadEnvironmentMaps, PATCH_JUMP);
- InjectHook(0x521720, CVehicleModelInfo::ShutdownEnvironmentMaps, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h
index 5969c4ca..9992ab98 100644
--- a/src/modelinfo/VehicleModelInfo.h
+++ b/src/modelinfo/VehicleModelInfo.h
@@ -81,11 +81,11 @@ public:
RpAtomic *m_comps[6];
int32 m_numComps;
- static int8 *ms_compsToUse; // [2];
- static int8 *ms_compsUsed; // [2];
- static RwTexture **ms_pEnvironmentMaps; // [NUM_VEHICLE_ENVMAPS]
- static RwRGBA *ms_vehicleColourTable; // [256]
- static RwTexture **ms_colourTextureTable; // [256]
+ static int8 ms_compsToUse[2];
+ static int8 ms_compsUsed[2];
+ static RwTexture *ms_pEnvironmentMaps[NUM_VEHICLE_ENVMAPS];
+ static RwRGBA ms_vehicleColourTable[256];
+ static RwTexture *ms_colourTextureTable[256];
static RwObjectNameIdAssocation *ms_vehicleDescs[NUM_VEHICLE_TYPES];
CVehicleModelInfo(void);
diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp
index a7722b8a..3ef257d2 100644
--- a/src/objects/CutsceneHead.cpp
+++ b/src/objects/CutsceneHead.cpp
@@ -1,10 +1,11 @@
#include "common.h"
#include <rpskin.h>
-#include "patcher.h"
+
#include "main.h"
#include "RwHelper.h"
#include "RpAnimBlend.h"
#include "AnimBlendClumpData.h"
+#include "Bones.h"
#include "Directory.h"
#include "CutsceneMgr.h"
#include "Streaming.h"
@@ -17,11 +18,23 @@ CCutsceneHead::CCutsceneHead(CObject *obj)
RpAtomic *atm;
assert(RwObjectGetType(obj->m_rwObject) == rpCLUMP);
- m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
- atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
- if(atm){
- assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
- RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
+#ifdef PED_SKIN
+ unk1 = 0;
+ bIsSkinned = false;
+ m_parentObject = (CCutsceneObject*)obj;
+ // Hide original head
+ if(IsClumpSkinned(obj->GetClump())){
+ m_parentObject->SetRenderHead(false);
+ bIsSkinned = true;
+ }else
+#endif
+ {
+ m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
+ atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
+ if(atm){
+ assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
+ RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
+ }
}
}
@@ -48,11 +61,28 @@ CCutsceneHead::ProcessControl(void)
RpAtomic *atm;
RpHAnimHierarchy *hier;
+ // android/xbox calls is at the end
CPhysical::ProcessControl();
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
- UpdateRwFrame();
+#ifdef PED_SKIN
+ if(bIsSkinned){
+ UpdateRpHAnim();
+ UpdateRwFrame();
+
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
+ int idx = RpHAnimIDGetIndex(hier, BONE_head);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ if(RwV3dLength(&mat->pos) > 100.0f){
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(mat) * m_matrix;
+ }
+ }else
+#endif
+ {
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
+ UpdateRwFrame(); // android/xbox don't call this
+ }
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
atm = GetFirstAtomic((RpClump*)m_rwObject);
@@ -65,8 +95,25 @@ CCutsceneHead::Render(void)
{
RpAtomic *atm;
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
+#ifdef PED_SKIN
+ if(bIsSkinned){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
+ RpHAnimHierarchyUpdateMatrices(hier);
+ int idx = RpHAnimIDGetIndex(hier, BONE_head);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ if(RwV3dLength(&mat->pos) > 100.0f){
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(mat) * m_matrix;
+ }
+ RenderLimb(BONE_Lhand);
+ RenderLimb(BONE_Rhand);
+ }else
+#endif
+ {
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
+ }
+
UpdateRwFrame();
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
@@ -76,6 +123,34 @@ CCutsceneHead::Render(void)
CObject::Render();
}
+#ifdef PED_SKIN
+void
+CCutsceneHead::RenderLimb(int32 bone)
+{
+ RpAtomic *atomic;
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
+ int idx = RpHAnimIDGetIndex(hier, bone);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
+ switch(bone){
+ case BONE_Lhand:
+ atomic = mi->getLeftHand();
+ break;
+ case BONE_Rhand:
+ atomic = mi->getRightHand();
+ break;
+ default:
+ return;
+ }
+ if(atomic){
+ RwFrame *frame = RpAtomicGetFrame(atomic);
+ RwMatrixTransform(RwFrameGetMatrix(frame), &mats[idx], rwCOMBINEREPLACE);
+ RwFrameUpdateObjects(frame);
+ RpAtomicRender(atomic);
+ }
+}
+#endif
+
void
CCutsceneHead::PlayAnimation(const char *animName)
{
@@ -109,20 +184,3 @@ CCutsceneHead::PlayAnimation(const char *animName)
RwStreamClose(stream, nil);
}
}
-
-class CCutsceneHead_ : public CCutsceneHead
-{
-public:
- void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); }
- void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); }
- void ProcessControl_(void) { CCutsceneHead::ProcessControl(); }
- void Render_(void) { CCutsceneHead::Render(); }
-};
-
-STARTPATCHES
- InjectHook(0x4BA650, &CCutsceneHead_::CreateRwObject_, PATCH_JUMP);
- InjectHook(0x4BA690, &CCutsceneHead_::DeleteRwObject_, PATCH_JUMP);
- InjectHook(0x4BA760, &CCutsceneHead_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4BA800, &CCutsceneHead_::Render_, PATCH_JUMP);
- InjectHook(0x4BA6A0, &CCutsceneHead::PlayAnimation, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/objects/CutsceneHead.h b/src/objects/CutsceneHead.h
index 52b66ede..0a70353d 100644
--- a/src/objects/CutsceneHead.h
+++ b/src/objects/CutsceneHead.h
@@ -6,6 +6,12 @@ class CCutsceneHead : public CCutsceneObject
{
public:
RwFrame *m_pHeadNode;
+#ifdef PED_SKIN
+ int32 unk1;
+ CCutsceneObject *m_parentObject;
+ int32 unk2;
+ int32 bIsSkinned;
+#endif
CCutsceneHead(CObject *obj);
@@ -13,7 +19,10 @@ public:
void DeleteRwObject(void);
void ProcessControl(void);
void Render(void);
+ void RenderLimb(int32 bone);
void PlayAnimation(const char *animName);
};
+#ifndef PED_SKIN
static_assert(sizeof(CCutsceneHead) == 0x19C, "CCutsceneHead: error");
+#endif
diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp
index 2f667a5d..7b4ae02b 100644
--- a/src/objects/CutsceneObject.cpp
+++ b/src/objects/CutsceneObject.cpp
@@ -1,10 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
+#include "RwHelper.h"
#include "Lights.h"
#include "PointLights.h"
#include "RpAnimBlend.h"
#include "AnimBlendClumpData.h"
+#include "Bones.h"
#include "Renderer.h"
#include "ModelIndices.h"
#include "Shadows.h"
@@ -19,6 +21,12 @@ CCutsceneObject::CCutsceneObject(void)
ObjectCreatedBy = CUTSCENE_OBJECT;
m_fMass = 1.0f;
m_fTurnMass = 1.0f;
+
+#ifdef PED_SKIN
+ bRenderHead = true;
+ bRenderRightHand = true;
+ bRenderLeftHand = true;
+#endif
}
void
@@ -42,12 +50,24 @@ CCutsceneObject::ProcessControl(void)
m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
ApplyMoveSpeed();
+
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump()))
+ UpdateRpHAnim();
+#endif
+}
+
+static RpMaterial*
+MaterialSetAlpha(RpMaterial *material, void *data)
+{
+ ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data;
+ return material;
}
void
CCutsceneObject::PreRender(void)
{
- if(IsPedModel(GetModelIndex()))
+ if(IsPedModel(GetModelIndex())){
CShadows::StoreShadowForPedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
@@ -55,14 +75,57 @@ CCutsceneObject::PreRender(void)
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ // For some reason xbox/android limbs are transparent here...
+ RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump()));
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geometry, MaterialSetAlpha, (void*)255);
+ }
}
void
CCutsceneObject::Render(void)
{
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ if(bRenderLeftHand) RenderLimb(BONE_Lhand);
+ if(bRenderRightHand) RenderLimb(BONE_Rhand);
+ if(bRenderHead) RenderLimb(BONE_head);
+ }
+#endif
CObject::Render();
}
+#ifdef PED_SKIN
+void
+CCutsceneObject::RenderLimb(int32 bone)
+{
+ RpAtomic *atomic;
+ CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
+ switch(bone){
+ case BONE_head:
+ atomic = mi->getHead();
+ break;
+ case BONE_Lhand:
+ atomic = mi->getLeftHand();
+ break;
+ case BONE_Rhand:
+ atomic = mi->getRightHand();
+ break;
+ default:
+ return;
+ }
+ if(atomic){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int idx = RpHAnimIDGetIndex(hier, bone);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwFrame *frame = RpAtomicGetFrame(atomic);
+ *RwFrameGetMatrix(frame) = *mat;
+ RwFrameUpdateObjects(frame);
+ RpAtomicRender(atomic);
+ }
+}
+#endif
+
bool
CCutsceneObject::SetupLighting(void)
{
@@ -88,25 +151,3 @@ CCutsceneObject::RemoveLighting(bool reset)
{
CRenderer::RemoveVehiclePedLights(this, reset);
}
-
-class CCutsceneObject_ : public CCutsceneObject
-{
-public:
- void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); }
- void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); }
- void ProcessControl_(void) { CCutsceneObject::ProcessControl(); }
- void PreRender_(void) { CCutsceneObject::PreRender(); }
- void Render_(void) { CCutsceneObject::Render(); }
- bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); }
- void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); }
-};
-
-STARTPATCHES
- InjectHook(0x4BA960, &CCutsceneObject_::dtor, PATCH_JUMP);
- InjectHook(0x4BA980, &CCutsceneObject_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x4BA9C0, &CCutsceneObject_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4BAA40, &CCutsceneObject_::PreRender_, PATCH_JUMP);
- InjectHook(0x4BAAA0, &CCutsceneObject_::Render_, PATCH_JUMP);
- InjectHook(0x4A7E70, &CCutsceneObject_::SetupLighting_, PATCH_JUMP);
- InjectHook(0x4A7F00, &CCutsceneObject_::RemoveLighting_, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h
index 31c3a528..9c4036bf 100644
--- a/src/objects/CutsceneObject.h
+++ b/src/objects/CutsceneObject.h
@@ -5,13 +5,29 @@
class CCutsceneObject : public CObject
{
public:
+#ifdef PED_SKIN
+ bool bRenderHead;
+ bool bRenderRightHand;
+ bool bRenderLeftHand;
+
+ bool GetRenderHead(void) { return bRenderHead; }
+ bool GetRenderRightHand(void) { return bRenderRightHand; }
+ bool GetRenderLeftHand(void) { return bRenderLeftHand; }
+ void SetRenderHead(bool render) { bRenderHead = render; }
+ void SetRenderRightHand(bool render) { bRenderRightHand = render; }
+ void SetRenderLeftHand(bool render) { bRenderLeftHand = render; }
+#endif
+
CCutsceneObject(void);
void SetModelIndex(uint32 id);
void ProcessControl(void);
void PreRender(void);
void Render(void);
+ void RenderLimb(int32 bone);
bool SetupLighting(void);
void RemoveLighting(bool reset);
};
+#ifndef PED_SKIN
static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error");
+#endif
diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp
index ba09ac3e..d5805073 100644
--- a/src/objects/DummyObject.cpp
+++ b/src/objects/DummyObject.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "DummyObject.h"
#include "Pools.h"
@@ -11,19 +11,3 @@ CDummyObject::CDummyObject(CObject *obj)
obj->DetachFromRwObject();
m_level = obj->m_level;
}
-
-#include <new>
-
-class CDummyObject_ : public CDummyObject
-{
-public:
- void dtor(void) { CDummyObject::~CDummyObject(); }
- CDummyObject *ctor(void) { return ::new (this) CDummyObject(); }
- CDummyObject *ctor(CObject *obj) { return ::new (this) CDummyObject(obj); }
-};
-
-STARTPATCHES
- InjectHook(0x4BAAF0, (CDummyObject* (CDummyObject::*)(void)) &CDummyObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BAB10, (CDummyObject* (CDummyObject::*)(CObject*)) &CDummyObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BAB70, &CDummyObject_::dtor, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index 867624c7..c0ce38f8 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Lights.h"
#include "Pools.h"
@@ -12,8 +12,8 @@
#include "World.h"
#include "Floater.h"
-int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2;
-int16 &CObject::nBodyCastHealth = *(int16*)0x5F7D4C; // 1000
+int16 CObject::nNoTempObjects;
+int16 CObject::nBodyCastHealth = 1000;
void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); }
void *CObject::operator new(size_t sz, int handle) { return CPools::GetObjectPool()->New(handle);};
@@ -35,7 +35,7 @@ CObject::CObject(void)
m_colour1 = m_colour2;
m_nBonusValue = 0;
bIsPickup = false;
- m_obj_flag2 = false;
+ bPickupObjWithMessage = false;
bOutOfStock = false;
bGlassCracked = false;
bGlassBroken = false;
@@ -214,7 +214,7 @@ CObject::ObjectDamage(float amount)
++nFrameGen;
int32 currentFrame = nFrameGen & 3;
float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
- RwRGBA randomColor = { color.red * fRandom, color.green * fRandom , color.blue, color.alpha };
+ 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);
CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
@@ -237,7 +237,7 @@ CObject::ObjectDamage(float amount)
++nFrameGen;
int32 currentFrame = nFrameGen & 3;
float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 0.5f);
- RwRGBA randomColor = { color.red * fRandom, color.green * fRandom , color.blue * fRandom, color.alpha };
+ 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);
CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
@@ -315,7 +315,7 @@ CObject::Init(void)
ObjectCreatedBy = GAME_OBJECT;
bIsStatic = true;
bIsPickup = false;
- m_obj_flag2 = false;
+ bPickupObjWithMessage = false;
bOutOfStock = false;
bGlassCracked = false;
bGlassBroken = false;
@@ -383,7 +383,7 @@ CObject::DeleteAllTempObjects()
}
void
-CObject::DeleteAllTempObjectInArea(CVector point, float fRadius)
+CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
{
CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
@@ -394,37 +394,3 @@ CObject::DeleteAllTempObjectInArea(CVector point, float fRadius)
}
}
}
-
-#include <new>
-
-class CObject_ : public CObject
-{
-public:
- CObject *ctor(void) { return ::new (this) CObject(); }
- CObject *ctor(int32 mi, bool createRW) { return ::new (this) CObject(mi, createRW); }
- CObject *ctor(CDummyObject *dummy) { return ::new (this) CObject(dummy); }
- void dtor(void) { CObject::~CObject(); }
- void Render_(void) { CObject::Render(); }
- void ProcessControl_(void) { CObject::ProcessControl(); }
- bool SetupLighting_(void) { return CObject::SetupLighting(); }
- void RemoveLighting_(bool reset) { CObject::RemoveLighting(reset); }
-};
-
-STARTPATCHES
- InjectHook(0x4BABD0, (CObject* (CObject::*)(void)) &CObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BACE0, (CObject* (CObject::*)(int32, bool)) &CObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BAD50, (CObject* (CObject::*)(CDummyObject*)) &CObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BAE00, &CObject_::dtor, PATCH_JUMP);
- InjectHook(0x4BB040, &CObject_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4BBDA0, &CObject::Teleport, PATCH_JUMP);
- InjectHook(0x4BB1E0, &CObject_::Render_, PATCH_JUMP);
- InjectHook(0x4A7C90, &CObject_::SetupLighting_, PATCH_JUMP);
- InjectHook(0x4A7CD0, &CObject_::RemoveLighting_, PATCH_JUMP);
- InjectHook(0x4BB240, &CObject::ObjectDamage, PATCH_JUMP);
- InjectHook(0x4BBD80, &CObject::RefModelInfo, PATCH_JUMP);
- InjectHook(0x4BAEC0, &CObject::Init, PATCH_JUMP);
- InjectHook(0x4BB010, &CObject::CanBeDeleted, PATCH_JUMP);
- InjectHook(0x4BBE60, &CObject::DeleteAllMissionObjects, PATCH_JUMP);
- InjectHook(0x4BBDF0, &CObject::DeleteAllTempObjects, PATCH_JUMP);
- InjectHook(0x4BBED0, &CObject::DeleteAllTempObjectInArea, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/objects/Object.h b/src/objects/Object.h
index 6d04c78a..319ec4bc 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -47,34 +47,33 @@ public:
float m_fUprootLimit;
int8 ObjectCreatedBy;
int8 bIsPickup : 1;
- int8 m_obj_flag2 : 1;
+ int8 bPickupObjWithMessage : 1;
int8 bOutOfStock : 1;
int8 bGlassCracked : 1;
int8 bGlassBroken : 1;
int8 bHasBeenDamaged : 1;
int8 bUseVehicleColours : 1;
- int8 m_obj_flag80 : 1;
int8 m_nBonusValue;
- int8 field_173;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
+
+ // this batch is unused
int8 field_17B;
int8 field_17C;
int8 field_17D;
int8 field_17E;
int8 field_17F;
+
uint32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
- int8 field_186;
- int8 field_187;
CEntity *m_pCurSurface;
CEntity *m_pCollidingEntity;
int8 m_colour1, m_colour2;
- static int16 &nNoTempObjects;
- static int16 &nBodyCastHealth;
+ static int16 nNoTempObjects;
+ static int16 nBodyCastHealth;
static void *operator new(size_t);
static void *operator new(size_t, int);
@@ -99,6 +98,6 @@ public:
static void DeleteAllMissionObjects();
static void DeleteAllTempObjects();
- static void DeleteAllTempObjectInArea(CVector point, float fRadius);
+ static void DeleteAllTempObjectsInArea(CVector point, float fRadius);
};
static_assert(sizeof(CObject) == 0x198, "CObject: error");
diff --git a/src/objects/ObjectData.cpp b/src/objects/ObjectData.cpp
index aa58a845..589cc3f7 100644
--- a/src/objects/ObjectData.cpp
+++ b/src/objects/ObjectData.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "ModelInfo.h"
#include "Object.h"
@@ -96,8 +96,3 @@ CObjectData::SetObjectData(int32 modelId, CObject &object)
object.bExplosionProof = true;
}
}
-
-STARTPATCHES
- InjectHook(0x4BC0E0, CObjectData::Initialise, PATCH_JUMP);
- InjectHook(0x4BC270, CObjectData::SetObjectData, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 60827411..932a0b8a 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "ParticleObject.h"
#include "Timer.h"
#include "General.h"
@@ -9,11 +9,11 @@
#include "Game.h"
-CParticleObject (&gPObjectArray)[MAX_PARTICLEOBJECTS] = *(CParticleObject(*)[MAX_PARTICLEOBJECTS])*(uintptr*)0x62A58C;
+CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
-CParticleObject *&CParticleObject::pCloseListHead = *(CParticleObject **)int(0x8F4340);
-CParticleObject *&CParticleObject::pFarListHead = *(CParticleObject **)int(0x942F78);
-CParticleObject *&CParticleObject::pUnusedListHead = *(CParticleObject **)int(0x94128C);
+CParticleObject *CParticleObject::pCloseListHead;
+CParticleObject *CParticleObject::pFarListHead;
+CParticleObject *CParticleObject::pUnusedListHead;
CAudioHydrant List[MAX_AUDIOHYDRANTS];
@@ -169,7 +169,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
break;
}
@@ -187,7 +191,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
break;
}
@@ -205,7 +213,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
pobj->m_Color = CRGBA(16, 16, 16, 255);
break;
@@ -228,7 +240,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
pobj->m_nNumEffectCycles = 0;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 1;
+#else
+ pobj->m_nSkipFrames = 3;
+#endif
pobj->m_nCreationChance = 0;
break;
}
@@ -236,7 +252,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
case POBJECT_SPLASHES_AROUND:
{
pobj->m_ParticleType = PARTICLE_SPLASH;
+#ifdef PC_PARTICLE
pobj->m_nNumEffectCycles = 15;
+#else
+ pobj->m_nNumEffectCycles = 30;
+#endif
pobj->m_nSkipFrames = 2;
pobj->m_nCreationChance = 0;
break;
@@ -246,7 +266,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_FLAME;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 2;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 2;
pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
break;
@@ -256,7 +280,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_FLAME;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 2;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 4;
pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
break;
@@ -286,7 +314,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 2;
pobj->m_fRandVal = 0.01f;
break;
@@ -598,6 +630,7 @@ void CParticleObject::UpdateClose(void)
case POBJECT_PED_WATER_SPLASH:
{
+#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -699,12 +732,69 @@ void CParticleObject::UpdateClose(void)
CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
}
+#else
+ CVector pos;
+ CVector vel;
+
+ for ( int32 i = -2; i < 2; i++ )
+ {
+ pos = this->GetPosition();
+ pos += CVector(-0.75f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += -1.5 * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+ pos = this->GetPosition();
+ pos += CVector(0.75f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), -0.75, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += -1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), 0.75, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+ }
+
+ for ( int32 i = 0; i < 4; i++ )
+ {
+ pos = this->GetPosition();
+
+ pos.x += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
+ pos.y += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
+ pos.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+
+ vel = this->m_vecTarget;
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+ }
+#endif
break;
}
case POBJECT_CAR_WATER_SPLASH:
{
+#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -799,7 +889,65 @@ void CParticleObject::UpdateClose(void)
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
}
+#else
+ CVector pos;
+ CVector vel;
+
+ for ( int32 i = -3; i < 4; i++ )
+ {
+ pos = this->GetPosition();
+ pos += CVector(-1.5f, 0.5f * float(i), 0.0f);
+
+
+ vel = this->m_vecTarget;
+ vel.x += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(1.5f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), -1.5f, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), 1.5f, 0.0f);
+
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+ }
+ for ( int32 i = 0; i < 8; i++ )
+ {
+ pos = this->GetPosition();
+ pos.x += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
+ pos.y += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
+
+ vel = this->m_vecTarget;
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+ }
+#endif
break;
}
@@ -1099,39 +1247,3 @@ CParticleObject::MoveToList(CParticleObject **from, CParticleObject **to, CParti
if ( obj->m_pNext )
obj->m_pNext->m_pPrev = obj;
}
-
-class CParticleObject_ : public CParticleObject
-{
-public:
- void ctor() { CParticleObject::CParticleObject(); }
- void dtor() { CParticleObject::~CParticleObject(); }
-};
-
-STARTPATCHES
- InjectHook(0x4BC330, CAudioHydrant::Add, PATCH_JUMP);
- InjectHook(0x4BC390, CAudioHydrant::Remove, PATCH_JUMP);
-
- InjectHook(0x4BC3E0, &CParticleObject_::ctor, PATCH_JUMP);
- InjectHook(0x4BC420, &CParticleObject_::dtor, PATCH_JUMP);
- InjectHook(0x4BC440, CParticleObject::Initialise, PATCH_JUMP);
-
- InjectHook(0x4BC4D0, (CParticleObject *(*)(uint16, CVector const &, uint8))CParticleObject::AddObject, PATCH_JUMP);
- InjectHook(0x4BC520, (CParticleObject *(*)(uint16, CVector const &, float, uint8))CParticleObject::AddObject, PATCH_JUMP);
- InjectHook(0x4BC570, (CParticleObject *(*)(uint16, CVector const &, CVector const &, float, uint8))CParticleObject::AddObject, PATCH_JUMP);
- InjectHook(0x4BC5B0, (CParticleObject *(*)(uint16, CVector const &, CVector const &, float, uint32, RwRGBA const &, uint8))CParticleObject::AddObject, PATCH_JUMP);
-
- InjectHook(0x4BC9F0, &CParticleObject::RemoveObject, PATCH_JUMP);
- InjectHook(0x4BCA30, CParticleObject::UpdateAll, PATCH_JUMP);
- InjectHook(0x4BCA80, &CParticleObject::UpdateClose, PATCH_JUMP);
- InjectHook(0x4BF9F0, &CParticleObject::UpdateFar, PATCH_JUMP);
- InjectHook(0x4BFA80, CParticleObject::SaveParticle, PATCH_JUMP);
- InjectHook(0x4BFB30, CParticleObject::LoadParticle, PATCH_JUMP);
- InjectHook(0x4BFC80, CParticleObject::RemoveAllParticleObjects, PATCH_JUMP);
- InjectHook(0x4BFD10, CParticleObject::MoveToList, PATCH_JUMP);
- //InjectHook(0x4BFD70, CParticleObject::~CParticleObject, PATCH_JUMP); // virtual
- //InjectHook(0x4BFDB0, `global constructor keyed to'ParticleObject.cpp, PATCH_JUMP);
- //InjectHook(0x4BFE00, CAudioHydrant::CAudioHydrant, PATCH_JUMP);
- //InjectHook(0x4BFE10, sub_4BFE10, PATCH_JUMP); // destroy gPObjectArray array
-
-
-ENDPATCHES
diff --git a/src/objects/ParticleObject.h b/src/objects/ParticleObject.h
index 45a3fa30..34a672bb 100644
--- a/src/objects/ParticleObject.h
+++ b/src/objects/ParticleObject.h
@@ -1,6 +1,8 @@
#pragma once
-#include "Placeable.h"
+
#include "AudioManager.h"
+#include "ParticleType.h"
+#include "Placeable.h"
#define MAX_PARTICLEOBJECTS 100
#define MAX_AUDIOHYDRANTS 8
@@ -37,7 +39,6 @@ enum eParticleObjectState
POBJECTSTATE_FREE,
};
-enum tParticleType;
class CParticle;
class CParticleObject : public CPlaceable
@@ -53,18 +54,16 @@ public:
uint8 m_nSkipFrames;
uint16 m_nFrameCounter;
uint16 m_nState;
- char _pad0[2];
CVector m_vecTarget;
float m_fRandVal;
float m_fSize;
CRGBA m_Color;
uint8 m_bRemove;
int8 m_nCreationChance;
- char _pad1[2];
- static CParticleObject *&pCloseListHead;
- static CParticleObject *&pFarListHead;
- static CParticleObject *&pUnusedListHead;
+ static CParticleObject *pCloseListHead;
+ static CParticleObject *pFarListHead;
+ static CParticleObject *pUnusedListHead;
CParticleObject();
~CParticleObject();
@@ -89,7 +88,7 @@ public:
static void MoveToList(CParticleObject **from, CParticleObject **to, CParticleObject *obj);
};
-extern CParticleObject (&gPObjectArray)[MAX_PARTICLEOBJECTS];
+extern CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
class CAudioHydrant
{
diff --git a/src/objects/Projectile.cpp b/src/objects/Projectile.cpp
index 32bc6bdb..fe8b0c68 100644
--- a/src/objects/Projectile.cpp
+++ b/src/objects/Projectile.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Projectile.h"
CProjectile::CProjectile(int32 model) : CObject()
@@ -13,17 +13,3 @@ CProjectile::CProjectile(int32 model) : CObject()
SetModelIndex(model);
ObjectCreatedBy = MISSION_OBJECT;
}
-
-#include <new>
-
-class CProjectile_ : public CProjectile
-{
-public:
- CProjectile* ctor(int32 model) { return ::new (this) CProjectile(model); }
- void dtor(void) { CProjectile::~CProjectile(); }
-};
-
-STARTPATCHES
- InjectHook(0x4BFE30, &CProjectile_::ctor, PATCH_JUMP);
- InjectHook(0x4BFED0, &CProjectile_::dtor, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index a9e0580e..2dee0397 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "CivilianPed.h"
#include "Phones.h"
#include "General.h"
@@ -318,12 +318,12 @@ CCivilianPed::ProcessControl(void)
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + playerSexFrequency;
if (playerSexFrequency >= 350) {
- CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 30);
+ CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = Max(250, playerSexFrequency - 30);
} else {
- CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 10);
+ CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = Max(250, playerSexFrequency - 10);
}
- m_pMyVehicle->pDriver->m_fHealth = min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
+ m_pMyVehicle->pDriver->m_fHealth = Min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
if (CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency == 250)
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
} else {
@@ -357,7 +357,7 @@ CCivilianPed::ProcessControl(void)
if (playerMoney <= 1) {
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 250;
} else {
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, playerMoney - 1);
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, playerMoney - 1);
}
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
}
@@ -376,21 +376,3 @@ CCivilianPed::ProcessControl(void)
if (m_moved.Magnitude() > 0.0f)
Avoid();
}
-
-#include <new>
-
-class CCivilianPed_ : public CCivilianPed
-{
-public:
- CCivilianPed *ctor(ePedType pedtype, uint32 mi) { return ::new (this) CCivilianPed(pedtype, mi); };
- void dtor(void) { CCivilianPed::~CCivilianPed(); }
- void ProcessControl_(void) { CCivilianPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
- InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
- InjectHook(0x4BFFE0, &CCivilianPed_::ProcessControl_, PATCH_JUMP);
-
- InjectHook(0x4C07A0, &CCivilianPed::CivilianAI, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h
index 6082c6ab..88d034c8 100644
--- a/src/peds/CivilianPed.h
+++ b/src/peds/CivilianPed.h
@@ -11,4 +11,6 @@ public:
void CivilianAI(void);
void ProcessControl(void);
};
+#ifndef PED_SKIN
static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
+#endif
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index b5812136..3fc8b8ca 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "World.h"
#include "PlayerPed.h"
#include "CopPed.h"
@@ -63,7 +63,7 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
m_bIsInPursuit = false;
field_1350 = 1;
m_bIsDisabledCop = false;
- field_1356 = 0;
+ m_fAbseilPos = 0.0f;
m_attackTimer = 0;
m_bBeatingSuspect = false;
m_bStopAndShootDisabledZone = false;
@@ -153,7 +153,7 @@ CCopPed::ClearPursuit(void)
return;
m_bIsInPursuit = false;
- for (int i = 0; i < max(wanted->m_MaxCops, wanted->m_CurrentCops); ++i) {
+ for (int i = 0; i < Max(wanted->m_MaxCops, wanted->m_CurrentCops); ++i) {
if (!foundMyself && wanted->m_pCops[i] == this) {
wanted->m_pCops[i] = nil;
--wanted->m_CurrentCops;
@@ -342,7 +342,7 @@ CCopPed::CopAI(void)
int oldCopNum = wanted->m_CurrentCops;
int maxCops = wanted->m_MaxCops;
- for (int i = 0; i < max(maxCops, oldCopNum); i++) {
+ for (int i = 0; i < Max(maxCops, oldCopNum); i++) {
CCopPed *cop = wanted->m_pCops[i];
if (cop && cop->m_fDistanceToTarget > copFarthestToTargetDist) {
copFarthestToTargetDist = cop->m_fDistanceToTarget;
@@ -465,8 +465,7 @@ CCopPed::CopAI(void)
if (m_fDistanceToTarget < weaponRange) {
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
CVector gunPos = weaponInfo->m_vecFireOffset;
- for (RwFrame *i = GetNodeFrame(PED_HANDR); i; i = RwFrameGetParent(i))
- RwV3dTransformPoints((RwV3d*)&gunPos, (RwV3d*)&gunPos, 1, RwFrameGetMatrix(i));
+ TransformToNode(gunPos, PED_HANDR);
CColPoint foundCol;
CEntity *foundEnt;
@@ -668,11 +667,13 @@ CCopPed::ProcessControl(void)
}
if (bDuckAndCover) {
+#if !defined(GTA3_1_1_PATCH) && !defined(VC_PED_PORTS)
if (!bNotAllowedToDuck && Seek()) {
SetMoveState(PEDMOVE_STILL);
SetMoveAnim();
SetPointGunAt(m_pedInObjective);
}
+#endif
} else if (Seek()) {
CVehicle *playerVeh = FindPlayerVehicle();
if (!playerVeh && player && player->EnteringCar()) {
@@ -736,25 +737,3 @@ CCopPed::ProcessControl(void)
SetAttack(m_pedInObjective);
}
}
-
-#include <new>
-
-class CCopPed_ : public CCopPed
-{
-public:
- CCopPed *ctor(eCopType type) { return ::new (this) CCopPed(type); };
- void dtor(void) { CCopPed::~CCopPed(); }
- void ProcessControl_(void) { CCopPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4C11B0, &CCopPed_::ctor, PATCH_JUMP);
- InjectHook(0x4C13E0, &CCopPed_::dtor, PATCH_JUMP);
- InjectHook(0x4C1400, &CCopPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4C28C0, &CCopPed::ClearPursuit, PATCH_JUMP);
- InjectHook(0x4C2B00, &CCopPed::SetArrestPlayer, PATCH_JUMP);
- InjectHook(0x4C27D0, &CCopPed::SetPursuit, PATCH_JUMP);
- InjectHook(0x4C2C90, &CCopPed::ArrestPlayer, PATCH_JUMP);
- InjectHook(0x4C26A0, &CCopPed::ScanForCrimes, PATCH_JUMP);
- InjectHook(0x4C1B50, &CCopPed::CopAI, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index 625cae49..e9780035 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -13,23 +13,16 @@ class CCopPed : public CPed
{
public:
int16 m_wRoadblockNode;
- int8 field_1342;
- int8 field_1343;
float m_fDistanceToTarget;
- int8 m_bIsInPursuit;
- int8 m_bIsDisabledCop;
+ bool m_bIsInPursuit;
+ bool m_bIsDisabledCop;
int8 field_1350;
bool m_bBeatingSuspect;
- int8 m_bStopAndShootDisabledZone;
- int8 m_bZoneDisabled;
- int8 field_1354;
- int8 field_1355;
- int32 field_1356;
+ bool m_bStopAndShootDisabledZone;
+ bool m_bZoneDisabled;
+ float m_fAbseilPos; // VC leftover, unused
eCopType m_nCopType;
int8 field_1364;
- int8 field_1365;
- int8 field_1366;
- int8 field_1367;
CCopPed(eCopType);
~CCopPed();
@@ -43,4 +36,6 @@ public:
void CopAI(void);
};
+#ifndef PED_SKIN
static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
+#endif
diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp
index 3a5067e7..7229ed3f 100644
--- a/src/peds/EmergencyPed.cpp
+++ b/src/peds/EmergencyPed.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "EmergencyPed.h"
#include "DMAudio.h"
#include "ModelIndices.h"
@@ -413,20 +413,3 @@ CEmergencyPed::MedicAI(void)
}
}
}
-
-#include <new>
-
-class CEmergencyPed_ : public CEmergencyPed
-{
-public:
- CEmergencyPed* ctor(int pedtype) { return ::new (this) CEmergencyPed(pedtype); };
- void dtor(void) { CEmergencyPed::~CEmergencyPed(); }
- void ProcessControl_(void) { CEmergencyPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4C2E40, &CEmergencyPed_::ctor, PATCH_JUMP);
- InjectHook(0x4C2EF0, &CEmergencyPed_::dtor, PATCH_JUMP);
- InjectHook(0x4C2F10, &CEmergencyPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4C3EC0, &CEmergencyPed::InRange, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/EmergencyPed.h b/src/peds/EmergencyPed.h
index 5693e908..6d3dac79 100644
--- a/src/peds/EmergencyPed.h
+++ b/src/peds/EmergencyPed.h
@@ -22,13 +22,12 @@ enum EmergencyPedState
class CEmergencyPed : public CPed
{
public:
- // 0x53C
CPed *m_pRevivedPed;
EmergencyPedState m_nEmergencyPedState;
CAccident *m_pAttendedAccident;
CFire *m_pAttendedFire;
- bool m_bStartedToCPR; // set but unused(?)
- int32 field_1360; // also something for medics, unused(?)
+ bool m_bStartedToCPR; // set but unused
+ int32 field_1360; // set to 0 but unused
CEmergencyPed(uint32);
~CEmergencyPed() { }
@@ -37,4 +36,6 @@ public:
void FiremanAI(void);
void MedicAI(void);
};
+#ifndef PED_SKIN
static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error");
+#endif
diff --git a/src/peds/Gangs.cpp b/src/peds/Gangs.cpp
index c67fe599..8859e61e 100644
--- a/src/peds/Gangs.cpp
+++ b/src/peds/Gangs.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "ModelIndices.h"
#include "Gangs.h"
#include "Weapon.h"
@@ -75,13 +75,3 @@ INITSAVEBUF
Gang[i] = ReadSaveBuf<CGangInfo>(buf);
VALIDATESAVEBUF(size);
}
-
-STARTPATCHES
- InjectHook(0x4C3FB0, CGangs::Initialise, PATCH_JUMP);
- InjectHook(0x4C4010, CGangs::SetGangVehicleModel, PATCH_JUMP);
- InjectHook(0x4C4030, CGangs::SetGangWeapons, PATCH_JUMP);
- InjectHook(0x4C4050, CGangs::SetGangPedModelOverride, PATCH_JUMP);
- InjectHook(0x4C4070, CGangs::GetGangPedModelOverride, PATCH_JUMP);
- InjectHook(0x4C4080, CGangs::SaveAllGangData, PATCH_JUMP);
- InjectHook(0x4C4100, CGangs::LoadAllGangData, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index cee2b323..dcb167f0 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -1,11 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Pools.h"
#include "Particle.h"
#include "Stats.h"
#include "World.h"
#include "RpAnimBlend.h"
+#include "Bones.h"
#include "Ped.h"
#include "Wanted.h"
#include "PlayerPed.h"
@@ -62,7 +63,7 @@
CPed *gapTempPedList[50];
uint16 gnNumTempPedList;
-CColPoint &aTempPedColPts = *(CColPoint*)0x62DB14;
+CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
// Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL)
PedAudioData CommentWaitTime[39] = {
@@ -106,8 +107,6 @@ PedAudioData CommentWaitTime[39] = {
{1000, 1000, 1000, 1000},
{1000, 1000, 5000, 5000},
};
-// *(CPedAudioData(*)[39]) * (uintptr*)0x5F94C4;
-
uint16 nPlayerInComboMove;
RpClump *flyingClumpTemp;
@@ -139,10 +138,9 @@ FightMove tFightMoves[NUM_FIGHTMOVES] = {
{ANIM_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
{ANIM_FIGHT2_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
};
-// *(FightMove(*)[NUM_FIGHTMOVES])* (uintptr*)0x5F9844;
-uint16 &CPed::nThreatReactionRangeMultiplier = *(uint16*)0x5F8C98;
-uint16 &CPed::nEnterCarRangeMultiplier = *(uint16*)0x5F8C94;
+uint16 CPed::nThreatReactionRangeMultiplier = 1;
+uint16 CPed::nEnterCarRangeMultiplier = 1;
CVector vecPedCarDoorAnimOffset;
CVector vecPedCarDoorLoAnimOffset;
@@ -151,9 +149,9 @@ CVector vecPedQuickDraggedOutCarAnimOffset;
CVector vecPedDraggedOutCarAnimOffset;
CVector vecPedTrainDoorAnimOffset;
-bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
-bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
-bool &CPed::bPedCheat3 = *(bool*)0x95CD59;
+bool CPed::bNastyLimbsCheat;
+bool CPed::bPedCheat2;
+bool CPed::bPedCheat3;
CVector2D CPed::ms_vec2DFleePosition;
void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); }
@@ -347,15 +345,15 @@ CPed::DebugRenderOnePedText(void)
bitAbove.z += 2.0f;
if (CSprite::CalcScreenCoors(bitAbove, &screenCoords, &width, &height, true)) {
- float lineHeight = SCREEN_SCALE_Y(min(height/100.0f, 0.7f) * 22.0f);
+ float lineHeight = SCREEN_SCALE_Y(Min(height/100.0f, 0.7f) * 22.0f);
DefinedState();
CFont::SetPropOn();
CFont::SetBackgroundOn();
// Originally both of them were being divided by 60.0f.
- float xScale = min(width / 240.0f, 0.7f);
- float yScale = min(height / 80.0f, 0.7f);
+ float xScale = Min(width / 240.0f, 0.7f);
+ float yScale = Min(height / 80.0f, 0.7f);
CFont::SetScale(SCREEN_SCALE_X(xScale), SCREEN_SCALE_Y(yScale));
CFont::SetCentreOn();
@@ -645,6 +643,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_collPoly.valid = false;
m_fCollisionSpeed = 0.0f;
m_wepModelID = -1;
+#ifdef PED_SKIN
+ m_pWeaponModel = nil;
+#endif
CPopulation::UpdatePedCount((ePedType)m_nPedType, false);
}
@@ -821,10 +822,17 @@ CPed::AddWeaponModel(int id)
RpAtomic *atm;
if (id != -1) {
- atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
- RwFrameDestroy(RpAtomicGetFrame(atm));
- RpAtomicSetFrame(atm, GetNodeFrame(PED_HANDR));
- RpClumpAddAtomic(GetClump(), atm);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump()))
+ m_pWeaponModel = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
+ else
+#endif
+ {
+ atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
+ RwFrameDestroy(RpAtomicGetFrame(atm));
+ RpAtomicSetFrame(atm, m_pFrames[PED_HANDR]->frame);
+ RpClumpAddAtomic(GetClump(), atm);
+ }
m_wepModelID = id;
}
}
@@ -918,25 +926,28 @@ void
CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
{
RwFrame *frame;
- RwV3d pos;
+ CVector pos;
- frame = GetNodeFrame(nodeId);
+ frame = m_pFrames[nodeId]->frame;
if (frame) {
if (CGame::nastyGame) {
+#ifdef PED_SKIN
+ if(!IsClumpSkinned(GetClump()))
+#endif
+ {
#ifdef TOGGLEABLE_BETA_FEATURES
- if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
+ if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
#else
- if (nodeId != PED_HEAD)
+ if (nodeId != PED_HEAD)
#endif
- SpawnFlyingComponent(nodeId, direction);
+ SpawnFlyingComponent(nodeId, direction);
- RecurseFrameChildrenVisibilityCB(frame, nil);
+ RecurseFrameChildrenVisibilityCB(frame, nil);
+ }
pos.x = 0.0f;
pos.y = 0.0f;
pos.z = 0.0f;
-
- for (; frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(frame));
+ TransformToNode(pos, PED_HEAD);
if (CEntity::GetIsOnScreen()) {
CParticle::AddParticle(PARTICLE_TEST, pos,
@@ -1105,10 +1116,7 @@ CPed::ClearLookFlag(void) {
bool
CPed::IsPedHeadAbovePos(float zOffset)
{
- RwMatrix mat;
-
- CPedIK::GetWorldMatrix(GetNodeFrame(PED_HEAD), &mat);
- return zOffset + GetPosition().z < RwMatrixGetPos(&mat)->z;
+ return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z;
}
void
@@ -1161,7 +1169,6 @@ CPed::Attack(void)
CAnimBlendAssociation *weaponAnimAssoc;
int32 weaponAnim;
float animStart;
- RwFrame *frame;
eWeaponType ourWeaponType;
float weaponAnimTime;
eWeaponFire ourWeaponFire;
@@ -1231,7 +1238,7 @@ CPed::Attack(void)
weaponAnimAssoc->SetCurrentTime(0.0f);
if (IsPlayer()) {
- ((CPlayerPed*)this)->field_1376 = 0.0f;
+ ((CPlayerPed*)this)->m_fAttackButtonCounter = 0.0f;
((CPlayerPed*)this)->m_bHaveTargetSelected = false;
}
}
@@ -1263,13 +1270,7 @@ CPed::Attack(void)
firePos = GetMatrix() * firePos;
} else if (ourWeaponType != WEAPONTYPE_UNARMED) {
- if (weaponAnimAssoc->animId == ANIM_KICK_FLOOR)
- frame = GetNodeFrame(PED_FOOTR);
- else
- frame = GetNodeFrame(PED_HANDR);
-
- for (; frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
+ TransformToNode(firePos, weaponAnimAssoc->animId == ANIM_KICK_FLOOR ? PED_FOOTR : PED_HANDR);
} else {
firePos = GetMatrix() * firePos;
}
@@ -1317,8 +1318,7 @@ CPed::Attack(void)
firePos = ourWeapon->m_vecFireOffset;
if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
- for (frame = GetNodeFrame(PED_HANDR); frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
+ TransformToNode(firePos, PED_HANDR);
CVector gunshellPos(
firePos.x - 0.6f * GetForward().x,
@@ -1418,7 +1418,17 @@ void
CPed::RemoveWeaponModel(int modelId)
{
// modelId is not used!! This function just removes the current weapon.
- RwFrameForAllObjects(GetNodeFrame(PED_HANDR),RemoveAllModelCB,nil);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ if(m_pWeaponModel){
+ RwFrame *frm = RpAtomicGetFrame(m_pWeaponModel);
+ RpAtomicDestroy(m_pWeaponModel);
+ RwFrameDestroy(frm);
+ m_pWeaponModel = nil;
+ }
+ }else
+#endif
+ RwFrameForAllObjects(m_pFrames[PED_HANDR]->frame,RemoveAllModelCB,nil);
m_wepModelID = -1;
}
@@ -1626,6 +1636,15 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
if (ped->IsPlayer())
AudioManager.PlayerJustLeftCar();
+#ifdef VC_PED_PORTS
+ if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
+ dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped);
+ ped->m_fHealth = 0.0f;
+ ped->SetDie(ANIM_FLOOR_HIT, 1000.0f, 0.5f);
+ return;
+ }
+#endif
+
if (quickJackedAssoc) {
dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
} else {
@@ -1831,7 +1850,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_VAN_GETIN:
#ifdef VC_PED_PORTS
multExtractedFromAnim = true;
- zBlend = max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.3f, 0.0f) / (1.0f - 0.3f);
+ zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.3f, 0.0f) / (1.0f - 0.3f);
// fall through
#endif
case ANIM_CAR_QJACKED:
@@ -1842,7 +1861,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
#ifdef VC_PED_PORTS
if (!multExtractedFromAnim) {
multExtractedFromAnim = true;
- zBlend = max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.5f, 0.0f) / (1.0f - 0.5f);
+ zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.5f, 0.0f) / (1.0f - 0.5f);
}
// fall through
#endif
@@ -1857,7 +1876,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
#ifdef VC_PED_PORTS
if (veh && veh->IsCar() && veh->bIsBus) {
multExtractedFromAnimBus = true;
- zBlend = min(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength, 0.5f) / 0.5f;
+ zBlend = Min(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength, 0.5f) / 0.5f;
}
// fall through
#endif
@@ -1937,7 +1956,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
neededPos.z = autoZPos.z;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
} else if (neededPos.z <= currentZ && m_pVehicleAnim && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE) {
- adjustedTimeStep = min(m_pVehicleAnim->timeStep, 0.1f);
+ adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
// Smoothly change ped position
neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep);
@@ -1959,12 +1978,12 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
if (m_pVehicleAnim &&
(vehAnim == ANIM_CAR_GETIN_RHS || vehAnim == ANIM_CAR_GETIN_LOW_RHS || vehAnim == ANIM_CAR_GETIN_LHS || vehAnim == ANIM_CAR_GETIN_LOW_LHS
|| vehAnim == ANIM_CAR_QJACK || vehAnim == ANIM_VAN_GETIN_L || vehAnim == ANIM_VAN_GETIN)) {
- adjustedTimeStep = min(m_pVehicleAnim->timeStep, 0.1f);
+ adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
// Smoothly change ped position
neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
} else if (EnteringCar()) {
- neededPos.z = max(currentZ, autoZPos.z);
+ neededPos.z = Max(currentZ, autoZPos.z);
}
#ifdef VC_PED_PORTS
}
@@ -2013,7 +2032,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
}
static void
-particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
+particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
{
switch (ped->m_nSurfaceTouched)
{
@@ -2022,7 +2041,7 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
case SURFACE_PAVEMENT:
case SURFACE_SAND:
for (int i = 0; i < times; ++i) {
- CVector adjustedPos = *pos;
+ CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
CParticle::AddParticle(PARTICLE_PEDFOOT_DUST, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, 0, 0);
@@ -2034,16 +2053,27 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
}
static void
-particleProduceFootSplash(CPed *ped, CVector *pos, float size, int times)
+particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
{
+#ifdef PC_PARTICLE
for (int i = 0; i < times; i++) {
- CVector adjustedPos = *pos;
+ CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
CVector direction = ped->GetForward() * -0.05f;
CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, direction, nil, size, CRGBA(32, 32, 32, 32), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
}
+#else
+ for ( int32 i = 0; i < times; i++ )
+ {
+ CVector adjustedPos = pos;
+ adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
+ }
+#endif
}
void
@@ -2074,6 +2104,40 @@ CPed::PlayFootSteps(void)
}
}
+#ifdef GTA_PS2_STUFF
+ CAnimBlendAssociation *runStopAsoc = NULL;
+
+ if ( IsPlayer() )
+ {
+ runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+
+ if ( runStopAsoc == NULL )
+ runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+ }
+
+ if ( runStopAsoc != NULL && runStopAsoc->blendAmount > 0.1f )
+ {
+ {
+ CVector pos(0.0f, 0.0f, 0.0f);
+ TransformToNode(pos, PED_FOOTL);
+
+ pos.z -= 0.1f;
+ pos += GetForward()*0.2f;
+ particleProduceFootDust(this, pos, 0.02f, 1);
+ }
+
+ {
+ CVector pos(0.0f, 0.0f, 0.0f);
+ TransformToNode(pos, PED_FOOTR);
+
+ pos.z -= 0.1f;
+ pos += GetForward()*0.2f;
+ particleProduceFootDust(this, pos, 0.02f, 1);
+ }
+ }
+#endif
+
+
if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) {
float stepStart = 1 / 15.0f;
float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart;
@@ -2088,9 +2152,7 @@ CPed::PlayFootSteps(void)
if (stepPart != 0) {
DMAudio.PlayOneShot(m_audioEntityId, stepPart == 1 ? SOUND_STEP_START : SOUND_STEP_END, 1.0f);
CVector footPos(0.0f, 0.0f, 0.0f);
-
- for (RwFrame *frame = GetNodeFrame(stepPart == 1 ? PED_FOOTL : PED_FOOTR); frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints(footPos, footPos, 1, RwFrameGetMatrix(frame));
+ TransformToNode(footPos, stepPart == 1 ? PED_FOOTL : PED_FOOTR);
CVector forward = GetForward();
@@ -2115,9 +2177,15 @@ CPed::PlayFootSteps(void)
}
if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
if(IsPlayer())
- particleProduceFootDust(this, &footPos, 0.0f, 4);
- } else if(stepPart == 2) {
- particleProduceFootSplash(this, &footPos, 0.15f, 4);
+ particleProduceFootDust(this, footPos, 0.0f, 4);
+ }
+#ifdef PC_PARTICLE
+ else if(stepPart == 2)
+#else
+ else
+#endif
+ {
+ particleProduceFootSplash(this, footPos, 0.15f, 4);
}
}
}
@@ -2125,6 +2193,7 @@ CPed::PlayFootSteps(void)
if (m_nSurfaceTouched == SURFACE_PUDDLE) {
float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude();
if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) {
+#ifdef PC_PARTICLE
float particleSize = pedSpeed * 2.0f;
if (particleSize < 0.25f)
@@ -2143,6 +2212,12 @@ CPed::PlayFootSteps(void)
particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, CRGBA(255,255,255,255), 0, 0, 0, 0);
+#else
+ CVector particlePos = (GetPosition() - 0.3f * GetUp()) + GetForward()*0.3f;
+ CVector particleDir = m_vecMoveSpeed * 0.45f;
+ particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos-CVector(0.0f, 0.0f, 1.2f), particleDir, nil, 0.0f, CRGBA(155, 185, 155, 255));
+#endif
}
}
}
@@ -2244,7 +2319,7 @@ CPed::BuildPedLists(void)
if (nThreatReactionRangeMultiplier * 30.0f > dist) {
gapTempPedList[gnNumTempPedList] = ped;
gnNumTempPedList++;
- assert(gnNumTempPedList < ARRAYSIZE(gapTempPedList));
+ assert(gnNumTempPedList < ARRAY_SIZE(gapTempPedList));
}
}
}
@@ -2284,6 +2359,11 @@ CPed::SetModelIndex(uint32 mi)
// This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D.
(*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta;
+
+#ifdef PED_SKIN
+ if(modelInfo->GetHitColModel() == nil)
+ modelInfo->CreateHitColModelSkinned(GetClump());
+#endif
}
void
@@ -2443,9 +2523,31 @@ CPed::CalculateNewVelocity(void)
}
if (newUpperLegs.phi > -DEGTORAD(50.0f) && newUpperLegs.phi < DEGTORAD(50.0f)) {
- newUpperLegs.theta = 0.0f;
- m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGL], &newUpperLegs, false);
- m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGR], &newUpperLegs, false);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+/*
+ // this looks shit
+ newUpperLegs.theta = 0.0f;
+ RwV3d axis = { -1.0f, 0.0f, 0.0f };
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.phi), rwCOMBINEPRECONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.phi), rwCOMBINEPRECONCAT);
+*/
+ newUpperLegs.theta = 0.1f;
+ RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+ RwV3d Zaxis = { 0.0f, 0.0f, 1.0f };
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.theta), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.phi), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.theta), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.phi), rwCOMBINEPOSTCONCAT);
+
+ bDontAcceptIKLookAts = true;
+ }else
+#endif
+ {
+ newUpperLegs.theta = 0.0f;
+ m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGL], &newUpperLegs, false);
+ m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGR], &newUpperLegs, false);
+ }
}
}
}
@@ -2505,7 +2607,7 @@ CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil)
CVector invDamageNormal(-damageNormal->x, -damageNormal->y, 0.0f);
invDamageNormal *= 1.0f / collPower;
CVector estimatedJumpDist = invDamageNormal + collPower * invDamageNormal * ourCol->spheres->radius;
- forwardOffset = estimatedJumpDist * min(2.0f / collPower, 4.0f);
+ forwardOffset = estimatedJumpDist * Min(2.0f / collPower, 4.0f);
}
} else {
pos.z -= 0.15f;
@@ -3032,7 +3134,6 @@ CPed::QuitEnteringCar(void)
if (animAssoc) {
animAssoc->blendDelta = -4.0f;
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc = m_pVehicleAnim;
animAssoc->flags &= ~ASSOC_RUNNING;
}
} else
@@ -3041,7 +3142,11 @@ CPed::QuitEnteringCar(void)
m_pVehicleAnim = nil;
if (veh) {
+#ifdef VC_PED_PORTS
+ if (veh->AutoPilot.m_nCruiseSpeed == 0 && veh->VehicleCreatedBy == RANDOM_VEHICLE)
+#else
if (veh->AutoPilot.m_nCruiseSpeed == 0)
+#endif
veh->AutoPilot.m_nCruiseSpeed = 17;
}
}
@@ -4140,10 +4245,10 @@ CPed::SetGetUp(void)
CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE ||
collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE
- && ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 5) % 8
+ && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8
|| CCollision::ProcessColModels(GetMatrix(), *CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(),
collidingVeh->GetMatrix(), *CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel(),
- &aTempPedColPts, nil, nil) > 0)) {
+ aTempPedColPts, nil, nil) > 0)) {
bGetUpAnimStarted = false;
if (IsPlayer())
@@ -5041,6 +5146,12 @@ CPed::FightStrike(CVector &touchedNodePos)
// He can beat us
if (sq(maxDistanceToBeBeaten) > potentialAttackDistance.MagnitudeSqr()) {
+#ifdef PED_SKIN
+ // Have to animate a skinned clump because the initial col model is useless
+ if(IsClumpSkinned(GetClump()))
+ ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->AnimatePedColModelSkinned(GetClump());
+ else
+#endif
if (nearPed->m_nPedState == PED_FALL
|| nearPed->m_nPedState == PED_DEAD || nearPed->m_nPedState == PED_DIE
|| !nearPed->IsPedHeadAbovePos(-0.3f)) {
@@ -5146,12 +5257,12 @@ CPed::FightStrike(CVector &touchedNodePos)
float moveMult;
if (m_lastFightMove == FIGHTMOVE_GROUNDKICK) {
- moveMult = min(damageMult * 0.6f, 4.0f);
+ moveMult = Min(damageMult * 0.6f, 4.0f);
} else {
if (nearPed->m_nPedState != PED_DIE || damageMult >= 20) {
moveMult = damageMult;
} else {
- moveMult = min(damageMult * 2.0f, 14.0f);
+ moveMult = Min(damageMult * 2.0f, 14.0f);
}
}
@@ -5189,7 +5300,7 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
}
if (extraTime == -1) {
- m_getUpTimer = -1;
+ m_getUpTimer = UINT32_MAX;
} else if (fallAssoc) {
if (IsPlayer()) {
m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
@@ -5875,7 +5986,7 @@ CPed::CreateDeadPedWeaponPickups(void)
pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
}
if (found)
- CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, min(weaponAmmo, AmmoForWeapon_OnStreet[weapon]));
+ CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon]));
}
ClearWeapons();
}
@@ -5884,7 +5995,7 @@ void
CPed::SetAttackTimer(uint32 time)
{
if (CTimer::GetTimeInMilliseconds() > m_attackTimer)
- m_attackTimer = max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time;
+ m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time;
}
void
@@ -6076,11 +6187,9 @@ CPed::Die(void)
uint8
CPed::DoesLOSBulletHitPed(CColPoint &colPoint)
{
- RwMatrix mat;
uint8 retVal = 2;
- CPedIK::GetWorldMatrix(GetNodeFrame(PED_HEAD), &mat);
- float headZ = RwMatrixGetPos(&mat)->z;
+ float headZ = GetNodePosition(PED_HEAD).z;
if (m_nPedState == PED_FALL)
retVal = 1;
@@ -6451,7 +6560,7 @@ CPed::ExitCar(void)
void
CPed::Fall(void)
{
- if (m_getUpTimer != -1 && CTimer::GetTimeInMilliseconds() > m_getUpTimer
+ if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer
#ifdef VC_PED_PORTS
&& bIsStanding
#endif
@@ -6502,37 +6611,32 @@ CPed::Fight(void)
if (curMove.hitLevel != HITLEVEL_NULL && animTime > curMove.startFireTime && animTime <= curMove.endFireTime && m_fightState >= FIGHTSTATE_NO_MOVE) {
CVector touchingNodePos(0.0f, 0.0f, 0.0f);
- RwFrame *touchingFrame = nil;
switch (m_lastFightMove) {
case FIGHTMOVE_STDPUNCH:
case FIGHTMOVE_PUNCHHOOK:
case FIGHTMOVE_BODYBLOW:
- touchingFrame = GetNodeFrame(PED_HANDR);
+ TransformToNode(touchingNodePos, PED_HANDR);
break;
case FIGHTMOVE_IDLE:
case FIGHTMOVE_SHUFFLE_F:
break;
case FIGHTMOVE_KNEE:
- touchingFrame = GetNodeFrame(PED_LOWERLEGR);
+ TransformToNode(touchingNodePos, PED_LOWERLEGR);
break;
case FIGHTMOVE_HEADBUTT:
- touchingFrame = GetNodeFrame(PED_HEAD);
+ TransformToNode(touchingNodePos, PED_HEAD);
break;
case FIGHTMOVE_PUNCHJAB:
- touchingFrame = GetNodeFrame(PED_HANDL);
+ TransformToNode(touchingNodePos, PED_HANDL);
break;
case FIGHTMOVE_KICK:
case FIGHTMOVE_LONGKICK:
case FIGHTMOVE_ROUNDHOUSE:
case FIGHTMOVE_GROUNDKICK:
- touchingFrame = GetNodeFrame(PED_FOOTR);
+ TransformToNode(touchingNodePos, PED_FOOTR);
break;
}
- while (touchingFrame) {
- RwV3dTransformPoints(touchingNodePos, touchingNodePos, 1, RwFrameGetMatrix(touchingFrame));
- touchingFrame = RwFrameGetParent(touchingFrame);
- }
if (m_lastFightMove == FIGHTMOVE_PUNCHJAB) {
touchingNodePos += 0.1f * GetForward();
@@ -7014,8 +7118,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
if (ped->bDoBloodyFootprints) {
CVector bloodPos(0.0f, 0.0f, 0.0f);
- for (RwFrame *i = ped->GetNodeFrame(PED_FOOTL); i; i = RwFrameGetParent(i))
- RwV3dTransformPoints(bloodPos, bloodPos, 1, RwFrameGetMatrix(i));
+ ped->TransformToNode(bloodPos, PED_FOOTL);
bloodPos.z -= 0.1f;
bloodPos += 0.2f * ped->GetForward();
@@ -7028,8 +7131,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
255, 255, 0, 0, 4.0f, 3000, 1.0f);
bloodPos = CVector(0.0f, 0.0f, 0.0f);
- for (RwFrame *j = ped->GetNodeFrame(PED_FOOTR); j; j = RwFrameGetParent(j))
- RwV3dTransformPoints(bloodPos, bloodPos, 1, RwFrameGetMatrix(j));
+ ped->TransformToNode(bloodPos, PED_FOOTR);
bloodPos.z -= 0.1f;
bloodPos += 0.2f * ped->GetForward();
@@ -8667,7 +8769,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
distVec.Normalise();
#ifdef VC_PED_PORTS
- distVec *= min(car->m_fMass / 1400.0f, 1.0f);
+ distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
#endif
car->ApplyMoveForce(distVec * -100.0f);
Say(SOUND_PED_DEFEND);
@@ -8700,7 +8802,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
m_vecMoveSpeed.z = 0.0f;
distVec.Normalise();
#ifdef VC_PED_PORTS
- distVec *= min(car->m_fMass / 1400.0f, 1.0f);
+ distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
#endif
car->ApplyMoveForce(distVec * -60.0f);
Say(SOUND_PED_DEFEND);
@@ -9182,8 +9284,11 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->QuitEnteringCar();
return;
}
- bool itsVan = veh->bIsVan;
- bool itsBus = veh->bIsBus;
+ bool itsVan = !!veh->bIsVan;
+ bool itsBus = !!veh->bIsBus;
+#ifdef FIX_BUGS
+ bool itsLow = !!veh->bLowVehicle;
+#endif
eDoors enterDoor;
AnimationId enterAnim;
@@ -9218,6 +9323,10 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
enterAnim = ANIM_VAN_GETIN;
} else if (itsBus) {
enterAnim = ANIM_COACH_IN_R;
+#ifdef FIX_BUGS
+ } else if (itsLow) {
+ enterAnim = ANIM_CAR_GETIN_LOW_RHS;
+#endif
} else {
enterAnim = ANIM_CAR_GETIN_RHS;
}
@@ -9225,6 +9334,10 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
enterAnim = ANIM_VAN_GETIN_L;
} else if (itsBus) {
enterAnim = ANIM_COACH_IN_L;
+#ifdef FIX_BUGS
+ } else if (itsLow) {
+ enterAnim = ANIM_CAR_GETIN_LOW_LHS;
+#endif
} else {
enterAnim = ANIM_CAR_GETIN_LHS;
}
@@ -10007,7 +10120,7 @@ CPed::ProcessControl(void)
CVector offsetToCheck;
m_nPedStateTimer++;
- float adjustedTs = max(CTimer::GetTimeStep(), 0.01f);
+ float adjustedTs = Max(CTimer::GetTimeStep(), 0.01f);
CPad *pad0 = CPad::GetPad(0);
if ((m_nPedStateTimer <= 50.0f / (4.0f * adjustedTs) || m_nPedStateTimer * 0.01f <= forceDir.MagnitudeSqr())
@@ -10031,7 +10144,7 @@ CPed::ProcessControl(void)
CColPoint obstacleForFlying, obstacleForFlyingOtherDir;
// Check is there any room for being knocked up in reverse direction of force
- if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlying, foundEnt, true, false, false, false, false, false, false)) {
+ if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlying, foundEnt, true, false, false, false, false, false, nil)) {
obstacleForFlyingZ = obstacleForFlying.point.z;
} else {
obstacleForFlyingZ = 500.0f;
@@ -10040,7 +10153,7 @@ CPed::ProcessControl(void)
posToCheck = GetPosition() - offsetToCheck;
// Now check for direction of force this time
- if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlyingOtherDir, foundEnt, true, false, false, false, false, false, false)) {
+ if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlyingOtherDir, foundEnt, true, false, false, false, false, false, nil)) {
obstacleForFlyingOtherDirZ = obstacleForFlyingOtherDir.point.z;
} else {
obstacleForFlyingOtherDirZ = 501.0f;
@@ -10160,7 +10273,7 @@ CPed::ProcessControl(void)
offsetToCheck = GetPosition();
offsetToCheck.z += 0.5f;
- if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, false)) {
+ if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, nil)) {
#ifdef VC_PED_PORTS
if (!bSomeVCflag1 || FEET_OFFSET + foundCol.point.z < GetPosition().z) {
GetPosition().z = FEET_OFFSET + foundCol.point.z;
@@ -10666,7 +10779,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (ped->EnteringCar()) {
- bool isLow = veh->bLowVehicle;
+ bool isLow = !!veh->bLowVehicle;
if (!veh->bIsBus)
veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_CLOSEDOOR_LHS, 1.0f);
@@ -10694,7 +10807,11 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
#endif
|| !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER
+#ifdef VC_PED_PORTS
+ || ped->m_nPedState == PED_CARJACK
+#endif
+ )
veh->bIsBeingCarJacked = false;
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
@@ -10719,7 +10836,10 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, ped);
}
} else {
- ped->QuitEnteringCar();
+#ifdef VC_PED_PORTS
+ if (ped->m_nPedState != PED_DRIVING)
+#endif
+ ped->QuitEnteringCar();
}
}
@@ -10790,6 +10910,11 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
}
}
}
+#ifdef CANCELLABLE_CAR_ENTER
+ if (!veh->IsDoorMissing(door) && veh->CanPedOpenLocks(ped) && veh->IsCar()) {
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
+ }
+#endif
ped->QuitEnteringCar();
ped->RestorePreviousObjective();
ped->bCancelEnteringCar = false;
@@ -11004,7 +11129,10 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (!ped->EnteringCar()) {
- ped->QuitEnteringCar();
+#ifdef VC_PED_PORTS
+ if(ped->m_nPedState != PED_DRIVING)
+#endif
+ ped->QuitEnteringCar();
return;
}
@@ -11030,9 +11158,9 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
PedSetInCarCB(nil, ped);
return;
}
- bool isVan = veh->bIsVan;
- bool isBus = veh->bIsBus;
- bool isLow = veh->bLowVehicle;
+ bool isVan = !!veh->bIsVan;
+ bool isBus = !!veh->bIsBus;
+ bool isLow = !!veh->bLowVehicle;
eDoors enterDoor;
switch (ped->m_vehEnterType) {
case CAR_DOOR_RF:
@@ -11147,7 +11275,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
if (!ped->IsNotInWreckedVehicle())
return;
- bool isLow = veh->bLowVehicle;
+ bool isLow = !!veh->bLowVehicle;
int padNo;
if (ped->IsPlayer()) {
@@ -11429,7 +11557,9 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
CMatrix pedMat(ped->GetMatrix());
CVector posAfterBeingDragged = Multiply3x3(pedMat, (itsRearDoor ? -vecPedDraggedOutCarAnimOffset : vecPedDraggedOutCarAnimOffset));
posAfterBeingDragged += ped->GetPosition();
+#ifndef VC_PED_PORTS
posAfterBeingDragged.z += 1.0f;
+#endif
CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
ped->GetPosition() = posAfterBeingDragged;
@@ -11479,17 +11609,26 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
&& ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && driver
&& driver->IsPlayer() && !CTheScripts::IsPlayerOnAMission()) {
+#ifndef VC_PED_PORTS
if (CGeneral::GetRandomNumber() & 1)
ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
else
+#endif
ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
} else {
- ped->m_nPedState = PED_NONE;
- ped->m_nLastPedState = PED_NONE;
- ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 10000);
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
+#ifdef VC_PED_PORTS
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
+ && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !driver
+ && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else
+#endif
+ {
+ ped->m_nPedState = PED_NONE;
+ ped->m_nLastPedState = PED_NONE;
+ ped->SetFindPathAndFlee(ped->m_pMyVehicle->GetPosition(), 10000);
+ }
}
ped->SetGetUp();
}
@@ -12199,7 +12338,7 @@ CPed::PlacePedOnDryLand(void)
CVector posToCheck = 0.5f * potentialGroundDist + gaTempSphereColPoints[0].point;
posToCheck.z = 3.0f + waterLevel;
- if (CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, false)) {
+ if (CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil)) {
foundColZ = foundCol.point.z;
if (foundColZ >= waterLevel) {
posToCheck.z = 0.8f + foundColZ;
@@ -12213,7 +12352,7 @@ CPed::PlacePedOnDryLand(void)
posToCheck = 5.0f * potentialGroundDist + GetPosition();
posToCheck.z = 3.0f + waterLevel;
- if (!CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, false))
+ if (!CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil))
return false;
foundColZ = foundCol.point.z;
@@ -12292,24 +12431,36 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void
ped->Say(SOUND_PED_FLEE_RUN);
}
} else {
- if (ped->m_pedStats->m_temper <= ped->m_pedStats->m_fear
- || ped->CharCreatedBy == MISSION_CHAR || veh->VehicleCreatedBy == MISSION_VEHICLE
- || !veh->pDriver || !veh->pDriver->IsPlayer()
- || CTheScripts::IsPlayerOnAMission()) {
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear
+ && ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
+ && veh->pDriver && veh->pDriver->IsPlayer()
+ && !CTheScripts::IsPlayerOnAMission()) {
- ped->SetFlee(veh->GetPosition(), 10000);
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
- if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
- ped->SetMoveState(PEDMOVE_SPRINT);
- ped->Say(SOUND_PED_FLEE_SPRINT);
- } else {
- ped->Say(SOUND_PED_FLEE_RUN);
+#ifndef VC_PED_PORTS
+ if (CGeneral::GetRandomNumber() < MYRAND_MAX / 2) {
+ ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, veh->pDriver);
+ } else
+#endif
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+
+ } else {
+#ifdef VC_PED_PORTS
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
+ && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !veh->pDriver
+ && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ else
+#endif
+ {
+ ped->SetFindPathAndFlee(veh->GetPosition(), 10000);
+ if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
+ ped->SetMoveState(PEDMOVE_SPRINT);
+ ped->Say(SOUND_PED_FLEE_SPRINT);
+ } else {
+ ped->Say(SOUND_PED_FLEE_RUN);
+ }
}
- } else if (CGeneral::GetRandomNumber() < 0x3FFF) {
- ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, veh->pDriver);
- } else
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ }
}
}
if (ped->m_nLastPedState == PED_IDLE)
@@ -12521,8 +12672,66 @@ CPed::Render(void)
if (!bInVehicle || m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR ||
bRenderPedInCar && sq(25.0f * TheCamera.LODDistMultiplier) >= (TheCamera.GetPosition() - GetPosition()).MagnitudeSqr()) {
CEntity::Render();
+
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ renderLimb(PED_HEAD);
+ renderLimb(PED_HANDL);
+ renderLimb(PED_HANDR);
+ }
+ if(m_pWeaponModel && IsClumpSkinned(GetClump())){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int idx = RpHAnimIDGetIndex(hier, m_pFrames[PED_HANDR]->nodeID);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwFrame *frame = RpAtomicGetFrame(m_pWeaponModel);
+ *RwFrameGetMatrix(frame) = *mat;
+ RwFrameUpdateObjects(frame);
+ RpAtomicRender(m_pWeaponModel);
+ }
+#endif
+ }
+}
+
+#ifdef PED_SKIN
+static RpMaterial*
+SetLimbAlphaCB(RpMaterial *material, void *data)
+{
+ ((RwRGBA*)RpMaterialGetColor(material))->alpha = *(uint8*)data;
+ return material;
+}
+
+void
+CPed::renderLimb(int node)
+{
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
+ RpAtomic *atomic;
+ switch(node){
+ case PED_HEAD:
+ atomic = mi->getHead();
+ break;
+ case PED_HANDL:
+ atomic = mi->getLeftHand();
+ break;
+ case PED_HANDR:
+ atomic = mi->getRightHand();
+ break;
+ default:
+ return;
}
+ if(atomic == nil)
+ return;
+
+ RwFrame *frame = RpAtomicGetFrame(atomic);
+ *RwFrameGetMatrix(frame) = *mat;
+ RwFrameUpdateObjects(frame);
+ int alpha = CVisibilityPlugins::GetClumpAlpha(GetClump());
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetLimbAlphaCB, &alpha);
+ RpAtomicRender(atomic);
}
+#endif
void
CPed::ProcessObjective(void)
@@ -13700,7 +13909,12 @@ CPed::ProcessObjective(void)
// fall through
case OBJECTIVE_LEAVE_VEHICLE:
if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- if (InVehicle()) {
+ if (InVehicle()
+#ifdef VC_PED_PORTS
+ && (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate()
+ || bBusJacked)
+#endif
+ ) {
if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN
&& (m_nPedType != PEDTYPE_COP
#ifdef VC_PED_PORTS
@@ -13912,9 +14126,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector2D adjustedColMin(objColMin.x - 0.35f, objColMin.y - 0.35f);
CVector2D adjustedColMax(objColMax.x + 0.35f, objColMax.y + 0.35f);
- checkIntervalInDist = max(checkIntervalInDist, 0.5f);
- checkIntervalInDist = min(checkIntervalInDist, (objColMax.z - objColMin.z) / 2.0f);
- checkIntervalInDist = min(checkIntervalInDist, (adjustedColMax.x - adjustedColMin.x) / 2.0f);
+ checkIntervalInDist = Max(checkIntervalInDist, 0.5f);
+ checkIntervalInDist = Min(checkIntervalInDist, (objColMax.z - objColMin.z) / 2.0f);
+ checkIntervalInDist = Min(checkIntervalInDist, (adjustedColMax.x - adjustedColMin.x) / 2.0f);
if (objMat.GetUp().z < 0.0f)
objUpsideDown = true;
@@ -14445,7 +14659,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat())
collidedWithBoat = true;
- if (!field_EF && !m_phy_flagA80
+ // ofc we're not vehicle
+ if (!m_bIsVehicleBeingShifted && !m_phy_flagA80
#ifdef VC_PED_PORTS
&& !collidingEnt->IsPed()
#endif
@@ -14585,7 +14800,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2);
}
} else {
- float damage = 100.0f * max(speed - 0.25f, 0.0f);
+ float damage = 100.0f * Max(speed - 0.25f, 0.0f);
float damage2 = damage;
if (m_vecMoveSpeed.z < -0.25f)
damage += (-0.25f - m_vecMoveSpeed.z) * 150.0f;
@@ -14663,8 +14878,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
#ifdef VC_PED_PORTS
} else {
float speed = m_vecMoveSpeed.Magnitude2D();
- sphereNormal.x = -m_vecMoveSpeed.x / max(0.001f, speed);
- sphereNormal.y = -m_vecMoveSpeed.y / max(0.001f, speed);
+ sphereNormal.x = -m_vecMoveSpeed.x / Max(0.001f, speed);
+ sphereNormal.y = -m_vecMoveSpeed.y / Max(0.001f, speed);
GetPosition().z -= 0.05f;
bSomeVCflag1 = true;
}
@@ -14933,12 +15148,26 @@ CPed::PreRender(void)
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ UpdateRpHAnim();
+
+ if(bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD){
+ // scale head to 0 if shot off
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix *head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwV3d zero = { 0.0f, 0.0f, 0.0f };
+ RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
+ }
+ }
+#endif
+
if (bBodyPartJustCameOff && bIsPedDieAnimPlaying && m_bodyPartBleeding != -1 && (CTimer::GetFrameCounter() & 7) > 3) {
CVector bloodDir(0.0f, 0.0f, 0.0f);
CVector bloodPos(0.0f, 0.0f, 0.0f);
- for (RwFrame *frame = GetNodeFrame(m_bodyPartBleeding); frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints(bloodPos, bloodPos, 1, RwFrameGetMatrix(frame));
+ TransformToNode(bloodPos, m_bodyPartBleeding);
switch (m_bodyPartBleeding) {
case PED_HEAD:
@@ -15029,7 +15258,7 @@ CPed::ProcessBuoyancy(void)
bTouchingWater = true;
CEntity *entity;
CColPoint point;
- if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, false)
+ if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, nil)
&& entity->IsVehicle() && ((CVehicle*)entity)->IsBoat()) {
bIsInWater = false;
return;
@@ -15050,7 +15279,11 @@ CPed::ProcessBuoyancy(void)
bIsInTheAir = false;
}
pos.z = pos.z - 0.8f;
+#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
+#else
+ 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;
return;
@@ -15079,6 +15312,7 @@ CPed::ProcessBuoyancy(void)
} else {
m_vecMoveSpeed.z = -0.01f;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
+#ifdef PC_PARTICLE
CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition();
float level = 0.0f;
if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
@@ -15087,6 +15321,18 @@ CPed::ProcessBuoyancy(void)
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true);
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100;
+#else
+ CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
+ aBitForward.z = level + 0.5f;
+
+ CVector vel = m_vecMoveSpeed * 0.1f;
+ vel.z = 0.18f;
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true);
+ nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
+ nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
+#endif
}
}
} else
@@ -15103,9 +15349,15 @@ CPed::ProcessBuoyancy(void)
if (pos.z != 0.0f) {
nGenerateWaterCircles = 0;
for(int i = 0; i < 4; i++) {
+#ifdef PC_PARTICLE
pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0);
+#else
+ pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
+ pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f));
+#endif
}
}
}
@@ -15117,9 +15369,17 @@ CPed::ProcessBuoyancy(void)
pos.z = level;
if (pos.z >= 0.0f) {
+#ifdef PC_PARTICLE
pos.z += 0.25f;
+#else
+ pos.z += 0.5f;
+#endif
nGenerateRaindrops = 0;
+#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true);
+#else
+ CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true);
+#endif
}
}
}
@@ -15212,7 +15472,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
{
uint32 optedDoorNode = wantedDoorNode;
bool teleportNeeded = false;
- bool isLow = veh->bLowVehicle;
+ bool isLow = !!veh->bLowVehicle;
if (!veh->CanPedExitCar()) {
if (veh->pDriver && !veh->pDriver->IsPlayer()) {
veh->AutoPilot.m_nCruiseSpeed = 0;
@@ -15406,7 +15666,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
if (CWorld::ProcessVerticalLine(vec, startZ, foundCol, foundEnt, true, true, false, false, true, false, nil))
foundColZ2 = foundCol.point.z;
- zForPed = max(foundColZ, foundColZ2);
+ zForPed = Max(foundColZ, foundColZ2);
if (zForPed > -99.0f)
GetPosition().z = FEET_OFFSET + zForPed;
@@ -16053,11 +16313,10 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
}
}
if (CGame::nastyGame) {
- RwMatrix headMat;
- CPedIK::GetWorldMatrix(GetNodeFrame(PED_HEAD), &headMat);
+ CVector headPos = GetNodePosition(PED_HEAD);
for(int i = 0; i < 4; ++i) {
CVector bloodDir(0.0f, 0.0f, 0.1f);
- CVector bloodPos = headMat.pos - 0.2f * GetForward();
+ CVector bloodPos = headPos - 0.2f * GetForward();
CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, bloodDir, nil, 0.0f, 0, 0, 0, 0);
}
}
@@ -16629,6 +16888,10 @@ CPed::SpawnFlyingComponent(int pedNode, int8 direction)
if (CObject::nNoTempObjects >= NUMTEMPOBJECTS)
return nil;
+#ifdef PED_SKIN
+ assert(!IsClumpSkinned(GetClump()));
+#endif
+
CObject *obj = new CObject();
if (!obj)
return nil;
@@ -16636,12 +16899,12 @@ CPed::SpawnFlyingComponent(int pedNode, int8 direction)
RwFrame *frame = RwFrameCreate();
RpClump *clump = RpClumpCreate();
RpClumpSetFrame(clump, frame);
- RwMatrix *matrix = RwFrameGetLTM(GetNodeFrame(pedNode));
+ RwMatrix *matrix = RwFrameGetLTM(m_pFrames[pedNode]->frame);
*RwFrameGetMatrix(frame) = *matrix;
flyingClumpTemp = clump;
- RwFrameForAllObjects(GetNodeFrame(pedNode), CloneAtomicToFrameCB, frame);
- RwFrameForAllChildren(GetNodeFrame(pedNode), RecurseFrameChildrenToCloneCB, frame);
+ RwFrameForAllObjects(m_pFrames[pedNode]->frame, CloneAtomicToFrameCB, frame);
+ RwFrameForAllChildren(m_pFrames[pedNode]->frame, RecurseFrameChildrenToCloneCB, frame);
flyingClumpTemp = nil;
switch (pedNode) {
case PED_HEAD:
@@ -17005,7 +17268,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
// Because buses have stairs
if (!m_pMyVehicle->bIsBus)
- zDiff = max(0.0f, doorOpenPos.z - GetPosition().z);
+ zDiff = Max(0.0f, doorOpenPos.z - GetPosition().z);
m_vecOffsetSeek = doorOpenPos - GetPosition();
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
@@ -17156,7 +17419,7 @@ CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo)
CVector appropriatePos = GetPosition();
CVector zCorrectedPos = appropriatePos;
- int tryCount = min(10, halfOfDist);
+ int tryCount = Min(10, halfOfDist);
for (int i = 0; i < tryCount; ++i) {
appropriatePos += halfNormalizedDist;
CPedPlacement::FindZCoorForPed(&zCorrectedPos);
@@ -17190,7 +17453,7 @@ CPed::WarpPedToNearLeaderOffScreen(void)
CVector appropriatePos = GetPosition();
CVector zCorrectedPos = appropriatePos;
- int tryCount = min(10, halfOfDist);
+ int tryCount = Min(10, halfOfDist);
for (int i = 0; i < tryCount; ++i) {
appropriatePos += halfNormalizedDist;
CPedPlacement::FindZCoorForPed(&zCorrectedPos);
@@ -17232,7 +17495,7 @@ CPed::SetCarJack_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
car->m_nGettingInFlags |= doorFlag;
m_vecOffsetSeek = carEnterPos - GetPosition();
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
- float zDiff = max(0.0f, carEnterPos.z - GetPosition().z);
+ float zDiff = Max(0.0f, carEnterPos.z - GetPosition().z);
bUsesCollision = false;
if (zDiff > 4.4f) {
@@ -17469,240 +17732,3 @@ CPed::SetExitBoat(CVehicle *boat)
// Not there in VC.
CWaterLevel::FreeBoatWakeArray();
}
-
-#include <new>
-
-class CPed_ : public CPed
-{
-public:
- CPed *ctor(uint32 pedType) { return ::new (this) CPed(pedType); }
- void dtor(void) { CPed::~CPed(); }
-
- void SetModelIndex_(uint32 mi) { CPed::SetModelIndex(mi); }
- void FlagToDestroyWhenNextProcessed_(void) { CPed::FlagToDestroyWhenNextProcessed(); }
- bool SetupLighting_(void) { return CPed::SetupLighting(); }
- void RemoveLighting_(bool reset) { CPed::RemoveLighting(reset); }
- void Teleport_(CVector pos) { CPed::Teleport(pos); }
- void ProcessControl_(void) { CPed::ProcessControl(); }
- void Render_(void) { CPed::Render(); }
- void PreRender_(void) { CPed::PreRender(); }
- int32 ProcessEntityCollision_(CEntity *collidingEnt, CColPoint *collidingPoints) { return CPed::ProcessEntityCollision(collidingEnt, collidingPoints); }
- void SetMoveAnim_(void) { CPed::SetMoveAnim(); }
-};
-
-STARTPATCHES
- InjectHook(0x4C41C0, &CPed_::ctor, PATCH_JUMP);
- InjectHook(0x4C50D0, &CPed_::dtor, PATCH_JUMP);
- InjectHook(0x4C52A0, &CPed_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x4D6570, &CPed_::FlagToDestroyWhenNextProcessed_, PATCH_JUMP);
- InjectHook(0x4A7D30, &CPed_::SetupLighting_, PATCH_JUMP);
- InjectHook(0x4A7DC0, &CPed_::RemoveLighting_, PATCH_JUMP);
- InjectHook(0x4D3E70, &CPed_::Teleport_, PATCH_JUMP);
- InjectHook(0x4C8910, &CPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4D03F0, &CPed_::Render_, PATCH_JUMP);
- InjectHook(0x4CBB30, &CPed_::ProcessEntityCollision_, PATCH_JUMP);
- InjectHook(0x4CFDD0, &CPed_::PreRender_, PATCH_JUMP);
- InjectHook(0x4C5A40, &CPed_::SetMoveAnim_, PATCH_JUMP);
-
- InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP);
- InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP);
- InjectHook(0x4EB470, &CPed::ApplyHeadShot, PATCH_JUMP);
- InjectHook(0x4EAEE0, &CPed::RemoveBodyPart, PATCH_JUMP);
- InjectHook(0x4C6460, (void (CPed::*)(CEntity*, bool)) &CPed::SetLookFlag, PATCH_JUMP);
- InjectHook(0x4C63E0, (void (CPed::*)(float, bool)) &CPed::SetLookFlag, PATCH_JUMP);
- InjectHook(0x4D12E0, &CPed::SetLookTimer, PATCH_JUMP);
- InjectHook(0x4C5700, &CPed::OurPedCanSeeThisOne, PATCH_JUMP);
- InjectHook(0x4D2BB0, &CPed::Avoid, PATCH_JUMP);
- InjectHook(0x4C6A50, &CPed::ClearAimFlag, PATCH_JUMP);
- InjectHook(0x4C64F0, &CPed::ClearLookFlag, PATCH_JUMP);
- InjectHook(0x4EB670, &CPed::IsPedHeadAbovePos, PATCH_JUMP);
- InjectHook(0x4E68A0, &CPed::FinishedAttackCB, PATCH_JUMP);
- InjectHook(0x4E5BD0, &CheckForPedsOnGroundToAttack, PATCH_JUMP);
- InjectHook(0x4E6BA0, &CPed::Attack, PATCH_JUMP);
- InjectHook(0x4CF980, &CPed::RemoveWeaponModel, PATCH_JUMP);
- InjectHook(0x4CFA60, &CPed::SetCurrentWeapon, PATCH_JUMP);
- InjectHook(0x4E4A10, &CPed::Duck, PATCH_JUMP);
- InjectHook(0x4E4A30, &CPed::ClearDuck, PATCH_JUMP);
- InjectHook(0x4E6180, &CPed::ClearPointGunAt, PATCH_JUMP);
- InjectHook(0x4E07D0, &CPed::BeingDraggedFromCar, PATCH_JUMP);
- InjectHook(0x4CF000, &CPed::PedSetDraggedOutCarCB, PATCH_JUMP);
- InjectHook(0x4C5D80, &CPed::RestartNonPartialAnims, PATCH_JUMP);
- InjectHook(0x4E4730, &CPed::GetLocalPositionToOpenCarDoor, PATCH_JUMP);
- InjectHook(0x4E4660, (CVector (*)(CVehicle*, uint32, float)) CPed::GetPositionToOpenCarDoor, PATCH_JUMP);
- InjectHook(0x4E1A30, (CVector (*)(CVehicle*, uint32)) CPed::GetPositionToOpenCarDoor, PATCH_JUMP);
- InjectHook(0x4DF940, &CPed::LineUpPedWithCar, PATCH_JUMP);
- InjectHook(0x4CC6C0, &CPed::PlayFootSteps, PATCH_JUMP);
- InjectHook(0x4C5350, &CPed::BuildPedLists, PATCH_JUMP);
- InjectHook(0x4CF9B0, &CPed::GiveWeapon, PATCH_JUMP);
- InjectHook(0x4C7EA0, &CPed::CalculateNewOrientation, PATCH_JUMP);
- InjectHook(0x4C78F0, &CPed::WorkOutHeadingForMovingFirstPerson, PATCH_JUMP);
- InjectHook(0x4C73F0, &CPed::CalculateNewVelocity, PATCH_JUMP);
- InjectHook(0x4DD820, &CPed::CanSeeEntity, PATCH_JUMP);
- InjectHook(0x4D9460, &CPed::RestorePreviousObjective, PATCH_JUMP);
- InjectHook(0x4D82C0, (void (CPed::*)(eObjective)) &CPed::SetObjective, PATCH_JUMP);
- InjectHook(0x4D83E0, (void (CPed::*)(eObjective, void*)) &CPed::SetObjective, PATCH_JUMP);
- InjectHook(0x4D89A0, (void (CPed::*)(eObjective, int16, int16)) &CPed::SetObjective, PATCH_JUMP);
- InjectHook(0x4D8A90, (void (CPed::*)(eObjective, CVector)) &CPed::SetObjective, PATCH_JUMP);
- InjectHook(0x4D8770, (void (CPed::*)(eObjective, CVector, float)) &CPed::SetObjective, PATCH_JUMP);
- InjectHook(0x4DDEC0, &CPed::ReactToAttack, PATCH_JUMP);
- InjectHook(0x4D0600, &CPed::SetIdle, PATCH_JUMP);
- InjectHook(0x4E0E00, &CPed::QuitEnteringCar, PATCH_JUMP);
- InjectHook(0x4E4AD0, &CPed::InformMyGangOfAttack, PATCH_JUMP);
- InjectHook(0x4D3C80, &CPed::ClearChat, PATCH_JUMP);
- InjectHook(0x4D1390, &CPed::TurnBody, PATCH_JUMP);
- InjectHook(0x4D3AC0, &CPed::Chat, PATCH_JUMP);
- InjectHook(0x4D0490, &CPed::CheckAroundForPossibleCollisions, PATCH_JUMP);
- InjectHook(0x4D3E20, &CPed::MakePhonecall, PATCH_JUMP);
- InjectHook(0x4D3CC0, &CPed::FacePhone, PATCH_JUMP);
- InjectHook(0x4D4860, &CPed::CheckForDeadPeds, PATCH_JUMP);
- InjectHook(0x4D4650, &CPed::CheckForExplosions, PATCH_JUMP);
- InjectHook(0x4D47D0, &CPed::CheckForGunShots, PATCH_JUMP);
- InjectHook(0x4E6990, &CPed::CheckForPointBlankPeds, PATCH_JUMP);
- InjectHook(0x4D0BE0, &CPed::CheckIfInTheAir, PATCH_JUMP);
- InjectHook(0x4C7F20, &CPed::ClearAll, PATCH_JUMP);
- InjectHook(0x4E6790, &CPed::ClearAttack, PATCH_JUMP);
- InjectHook(0x4E67F0, &CPed::ClearAttackByRemovingAnim, PATCH_JUMP);
- InjectHook(0x4D37D0, &CPed::SetDie, PATCH_JUMP);
- InjectHook(0x4C5D50, &CPed::StopNonPartialAnims, PATCH_JUMP);
- InjectHook(0x4C5DB0, &CPed::SetStoredState, PATCH_JUMP);
- InjectHook(0x4EA420, &CPed::InflictDamage, PATCH_JUMP);
- InjectHook(0x4D1EA0, &CPed::ClearFlee, PATCH_JUMP);
- InjectHook(0x4D0BB0, &CPed::ClearFall, PATCH_JUMP);
- InjectHook(0x4D0F20, &CPed::SetGetUp, PATCH_JUMP);
- InjectHook(0x4D6550, &CPed::RestoreHeadingRateCB, PATCH_JUMP);
- InjectHook(0x4C5E30, &CPed::RestorePreviousState, PATCH_JUMP);
- InjectHook(0x4E5F70, &CPed::SetPointGunAt, PATCH_JUMP);
- InjectHook(0x4D2750, &CPed::SetWanderPath, PATCH_JUMP);
- InjectHook(0x4D30C0, &CPed::SetEvasiveStep, PATCH_JUMP);
- InjectHook(0x4EA360, &CPed::ClearInvestigateEvent, PATCH_JUMP);
- InjectHook(0x4D8E80, &CPed::ClearLeader, PATCH_JUMP);
- InjectHook(0x4D1360, &CPed::ClearLook, PATCH_JUMP);
- InjectHook(0x4D8DF0, &CPed::ClearObjective, PATCH_JUMP);
- InjectHook(0x4D0970, &CPed::ClearPause, PATCH_JUMP);
- InjectHook(0x4D1620, &CPed::ClearSeek, PATCH_JUMP);
- InjectHook(0x4CFB70, &CPed::ClearWeapons, PATCH_JUMP);
- InjectHook(0x4C6BB0, &CPed::RestoreGunPosition, PATCH_JUMP);
- InjectHook(0x4D6540, &CPed::RestoreHeadingRate, PATCH_JUMP);
- InjectHook(0x4C69E0, (void (CPed::*)(CEntity*)) &CPed::SetAimFlag, PATCH_JUMP);
- InjectHook(0x4C6960, (void (CPed::*)(float)) &CPed::SetAimFlag, PATCH_JUMP);
- InjectHook(0x4CFAD0, &CPed::GrantAmmo, PATCH_JUMP);
- InjectHook(0x4CFB20, &CPed::SetAmmo, PATCH_JUMP);
- InjectHook(0x4D33A0, &CPed::SetEvasiveDive, PATCH_JUMP);
- InjectHook(0x4D09B0, &CPed::SetFall, PATCH_JUMP);
- InjectHook(0x4E6220, &CPed::SetAttack, PATCH_JUMP);
- InjectHook(0x4E7530, &CPed::StartFightAttack, PATCH_JUMP);
- InjectHook(0x4E8EC0, &CPed::FightStrike, PATCH_JUMP);
- InjectHook(0x4CCE20, &CPed::GetLocalDirection, PATCH_JUMP);
- InjectHook(0x4E8E20, &CPed::PlayHitSound, PATCH_JUMP);
- InjectHook(0x4E5A10, &CPed::Say, PATCH_JUMP);
- InjectHook(0x4D58D0, &CPed::SetWaitState, PATCH_JUMP);
- InjectHook(0x4D1D70, (void (CPed::*)(CEntity*, int)) &CPed::SetFlee, PATCH_JUMP);
- InjectHook(0x4D1C40, (void (CPed::*)(CVector2D const &, int)) &CPed::SetFlee, PATCH_JUMP);
- InjectHook(0x4EB9A0, &CPed::CollideWithPed, PATCH_JUMP);
- InjectHook(0x433490, &CPed::CreateDeadPedMoney, PATCH_JUMP);
- InjectHook(0x433660, &CPed::CreateDeadPedWeaponPickups, PATCH_JUMP);
- InjectHook(0x4D3970, &CPed::SetDead, PATCH_JUMP);
- InjectHook(0x53CDF0, &CPed::DeadPedMakesTyresBloody, PATCH_JUMP);
- InjectHook(0x4E0640, &CPed::SetBeingDraggedFromCar, PATCH_JUMP);
- InjectHook(0x4D1300, &CPed::SetAttackTimer, PATCH_JUMP);
- InjectHook(0x4D6950, &CPed::SetBuyIceCream, PATCH_JUMP);
- InjectHook(0x4D3A60, &CPed::SetChat, PATCH_JUMP);
- InjectHook(0x4D14B0, (void (CPed::*)(CVector, float)) &CPed::SetSeek, PATCH_JUMP);
- InjectHook(0x4D15A0, (void (CPed::*)(CEntity*, float)) &CPed::SetSeek, PATCH_JUMP);
- InjectHook(0x4EB5C0, &CPed::DoesLOSBulletHitPed, PATCH_JUMP);
- InjectHook(0x4E3EC0, &CPed::DuckAndCover, PATCH_JUMP);
- InjectHook(0x4E8D30, &CPed::EndFight, PATCH_JUMP);
- InjectHook(0x4E0D30, &CPed::EnterCar, PATCH_JUMP);
- InjectHook(0x4E2E50, &CPed::GetNearestTrainPedPosition, PATCH_JUMP);
- InjectHook(0x4E2D70, &CPed::GetNearestTrainDoor, PATCH_JUMP);
- InjectHook(0x4E33D0, &CPed::LineUpPedWithTrain, PATCH_JUMP);
- InjectHook(0x4E18D0, &CPed::ExitCar, PATCH_JUMP);
- InjectHook(0x4E7EE0, &CPed::Fight, PATCH_JUMP);
- InjectHook(0x4D3950, &CPed::FinishDieAnimCB, PATCH_JUMP);
- InjectHook(0x4E9830, &CPed::FinishFightMoveCB, PATCH_JUMP);
- InjectHook(0x4D7A80, &CPed::FinishHitHeadCB, PATCH_JUMP);
- InjectHook(0x4D7A50, &CPed::FinishJumpCB, PATCH_JUMP);
- InjectHook(0x4D7490, &CPed::FinishLaunchCB, PATCH_JUMP);
- InjectHook(0x4D6520, &CPed::FinishedWaitCB, PATCH_JUMP);
- InjectHook(0x4D5D80, &CPed::Wait, PATCH_JUMP);
- InjectHook(0x4E3A90, &CPed::FindBestCoordsFromNodes, PATCH_JUMP);
- InjectHook(0x4D2E70, &CPed::SeekFollowingPath, PATCH_JUMP);
- InjectHook(0x4D1640, &CPed::Seek, PATCH_JUMP);
- InjectHook(0x4D3020, &CPed::FollowPath, PATCH_JUMP);
- InjectHook(0x4D1ED0, &CPed::Flee, PATCH_JUMP);
- InjectHook(0x4E1CF0, &CPed::GetNearestDoor, PATCH_JUMP);
- InjectHook(0x4DF420, &CPed::GetFormationPosition, PATCH_JUMP);
- InjectHook(0x4E1F30, &CPed::GetNearestPassengerDoor, PATCH_JUMP);
- InjectHook(0x4D0690, &CPed::Idle, PATCH_JUMP);
- InjectHook(0x4DD720, &CPed::GetNextPointOnRoute, PATCH_JUMP);
- InjectHook(0x4D7B50, &CPed::GetPedRadioCategory, PATCH_JUMP);
- InjectHook(0x4CFA40, &CPed::GetWeaponSlot, PATCH_JUMP);
- InjectHook(0x4E2220, &CPed::GoToNearestDoor, PATCH_JUMP);
- InjectHook(0x4DD7B0, &CPed::HaveReachedNextPointOnRoute, PATCH_JUMP);
- InjectHook(0x4D0D10, &CPed::InTheAir, PATCH_JUMP);
- InjectHook(0x4C5270, &CPed::Initialise, PATCH_JUMP);
- InjectHook(0x4D0E40, &CPed::SetLanding, PATCH_JUMP);
- InjectHook(0x4E9B50, &CPed::InvestigateEvent, PATCH_JUMP);
- InjectHook(0x564BB0, &CPed::IsPedDoingDriveByShooting, PATCH_JUMP);
- InjectHook(0x4E4D90, &CPed::IsRoomToBeCarJacked, PATCH_JUMP);
- InjectHook(0x4EC430, &CPed::KillPedWithCar, PATCH_JUMP);
- InjectHook(0x4E9A80, &CPed::SetInvestigateEvent, PATCH_JUMP);
- InjectHook(0x4D5040, &CPed::LookForInterestingNodes, PATCH_JUMP);
- InjectHook(0x4D4F50, &CPed::LookForSexyCars, PATCH_JUMP);
- InjectHook(0x4D4DF0, &CPed::LookForSexyPeds, PATCH_JUMP);
- InjectHook(0x53CFD0, &CPed::MakeTyresMuddySectorList, PATCH_JUMP);
- InjectHook(0x4C6580, &FinishFuckUCB, PATCH_JUMP);
- InjectHook(0x4D11D0, &CPed::Mug, PATCH_JUMP);
- InjectHook(0x4DE130, &CPed::PedAnimAlignCB, PATCH_JUMP);
- InjectHook(0x4D0980, &CPed::Pause, PATCH_JUMP);
- InjectHook(0x4C65B0, &CPed::MoveHeadToLook, PATCH_JUMP);
- InjectHook(0x4DF1B0, &CPed::PedAnimDoorCloseCB, PATCH_JUMP);
- InjectHook(0x4E4B90, &CPed::PedAnimDoorCloseRollingCB, PATCH_JUMP);
- InjectHook(0x4DE500, &CPed::PedAnimDoorOpenCB, PATCH_JUMP);
- InjectHook(0x4D73D0, &CPed::SetJump, PATCH_JUMP);
- InjectHook(0x4E4E20, &CPed::RemoveInCarAnims, PATCH_JUMP);
- InjectHook(0x4DEC80, &CPed::PedAnimGetInCB, PATCH_JUMP);
- InjectHook(0x4DEAF0, &CPed::PedAnimPullPedOutCB, PATCH_JUMP);
- InjectHook(0x4DF5C0, &CPed::PedAnimStepOutCarCB, PATCH_JUMP);
- InjectHook(0x4D36E0, &CPed::PedEvadeCB, PATCH_JUMP);
- InjectHook(0x4CE810, &CPed::PedGetupCB, PATCH_JUMP);
- InjectHook(0x4CE8A0, &CPed::PedLandCB, PATCH_JUMP);
- InjectHook(0x4E2920, &CPed::PedSetDraggedOutCarPositionCB, PATCH_JUMP);
- InjectHook(0x4CF220, &CPed::PedSetInCarCB, PATCH_JUMP);
- InjectHook(0x4E3290, &CPed::PedSetInTrainCB, PATCH_JUMP);
- InjectHook(0x4C10C0, &CPed::RunToReportCrime, PATCH_JUMP);
- InjectHook(0x4E3870, &CPed::RegisterThreatWithGangPeds, PATCH_JUMP);
- InjectHook(0x4DD980, &CPed::ReactToPointGun, PATCH_JUMP);
- InjectHook(0x4CE8F0, &CPed::PedSetOutCarCB, PATCH_JUMP);
- InjectHook(0x4E36E0, &CPed::PedSetOutTrainCB, PATCH_JUMP);
- InjectHook(0x4EB6E0, &CPed::PlacePedOnDryLand, PATCH_JUMP);
- InjectHook(0x4E2480, &CPed::PedSetQuickDraggedOutCarPositionCB, PATCH_JUMP);
- InjectHook(0x4E4F30, &CPed::PositionPedOutOfCollision, PATCH_JUMP);
- InjectHook(0x4D6A00, &CPed::PossiblyFindBetterPosToSeekCar, PATCH_JUMP);
- InjectHook(0x4D94E0, &CPed::ProcessObjective, PATCH_JUMP);
- InjectHook(0x4CCEB0, &CPed::SetDirectionToWalkAroundObject, PATCH_JUMP);
- InjectHook(0x4DF3E0, &CPed::SetFormation, PATCH_JUMP);
- InjectHook(0x4C7340, &CPed::WillChat, PATCH_JUMP);
- InjectHook(0x4E32D0, &CPed::SetEnterTrain, PATCH_JUMP);
- InjectHook(0x4E4920, &CPed::SetDuck, PATCH_JUMP);
- InjectHook(0x4E0920, &CPed::SetEnterCar, PATCH_JUMP);
- InjectHook(0x4D7BC0, &CPed::SetRadioStation, PATCH_JUMP);
- InjectHook(0x4C7FF0, &CPed::ProcessBuoyancy, PATCH_JUMP);
- InjectHook(0x4D6620, &CPed::SetSolicit, PATCH_JUMP);
- InjectHook(0x4D2EA0, &CPed::SetFollowPath, PATCH_JUMP);
- InjectHook(0x4E1010, &CPed::SetExitCar, PATCH_JUMP);
- InjectHook(0x4C5FE0, &CPed::ScanForThreats, PATCH_JUMP);
- InjectHook(0x4C6C10, &CPed::ScanForInterestingStuff, PATCH_JUMP);
- InjectHook(0x4D3F90, &CPed::SeekCar, PATCH_JUMP);
- InjectHook(0x4E5870, &CPed::ServiceTalking, PATCH_JUMP);
- InjectHook(0x4E7780, &CPed::StartFightDefend, PATCH_JUMP);
- InjectHook(0x4D8F30, &CPed::UpdateFromLeader, PATCH_JUMP);
- InjectHook(0x4D4970, &CPed::SetPedPositionInCar, PATCH_JUMP);
- InjectHook(0x4D7D20, &CPed::WarpPedIntoCar, PATCH_JUMP);
- InjectHook(0x4E0A40, &CPed::SetEnterCar_AllClear, PATCH_JUMP);
- InjectHook(0x4D28D0, &CPed::WanderPath, PATCH_JUMP);
- InjectHook(0x4E5570, &CPed::WarpPedToNearEntityOffScreen, PATCH_JUMP);
- InjectHook(0x4E52A0, &CPed::WarpPedToNearLeaderOffScreen, PATCH_JUMP);
- InjectHook(0x4E0220, &CPed::SetCarJack, PATCH_JUMP);
- InjectHook(0x4D6780, &CPed::Solicit, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 2edd5d68..f4caafd8 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -1,12 +1,14 @@
#pragma once
+#include "RwHelper.h"
+#include "AnimManager.h"
+#include "Crime.h"
+#include "EventList.h"
+#include "PedIK.h"
+#include "PedStats.h"
#include "Physical.h"
#include "Weapon.h"
-#include "PedStats.h"
-#include "PedIK.h"
-#include "AnimManager.h"
#include "WeaponInfo.h"
-#include "EventList.h"
#define FEET_OFFSET 1.04f
#define CHECK_NEARBY_THINGS_MAX_DIST 15.0f
@@ -17,7 +19,6 @@ class CObject;
class CFire;
struct AnimBlendFrameData;
class CAnimBlendAssociation;
-enum eCrimeType;
struct PedAudioData
{
@@ -301,95 +302,94 @@ public:
float m_fCollisionSpeed;
// cf. https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CPed.h from R*
- uint8 bIsStanding : 1;
- uint8 m_ped_flagA2 : 1; // bWasStanding?
- uint8 bIsAttacking : 1; // doesn't reset after fist fight
- uint8 bIsPointingGunAt : 1;
- uint8 bIsLooking : 1;
- uint8 bKeepTryingToLook : 1; // if we can't look somewhere due to unreachable angles
- uint8 bIsRestoringLook : 1;
- uint8 bIsAimingGun : 1;
-
- uint8 bIsRestoringGun : 1;
- uint8 bCanPointGunAtTarget : 1;
- uint8 bIsTalking : 1;
- uint8 bIsInTheAir : 1;
- uint8 bIsLanding : 1;
- uint8 bIsRunning : 1; // on some conditions
- uint8 bHitSomethingLastFrame : 1;
- uint8 bVehEnterDoorIsBlocked : 1; // because someone else enters/exits from there
-
- uint8 bCanPedEnterSeekedCar : 1;
- uint8 bRespondsToThreats : 1;
- uint8 bRenderPedInCar : 1;
- uint8 bChangedSeat : 1;
- uint8 bUpdateAnimHeading : 1;
- uint8 bBodyPartJustCameOff : 1;
- uint8 bIsShooting : 1;
- uint8 bFindNewNodeAfterStateRestore : 1;
-
- uint8 bHasACamera : 1; // does ped possess a camera to document accidents involves fire/explosion
- uint8 bGonnaInvestigateEvent : 1;
- uint8 bPedIsBleeding : 1;
- uint8 bStopAndShoot : 1; // Ped cannot reach target to attack with fist, need to use gun
- uint8 bIsPedDieAnimPlaying : 1;
- uint8 bUsePedNodeSeek : 1;
- uint8 bObjectiveCompleted : 1;
- uint8 bScriptObjectiveCompleted : 1;
-
- uint8 bKindaStayInSamePlace : 1;
- uint8 bBeingChasedByPolice : 1; // Unused VC leftover. Should've been set for criminal/gang members
- uint8 bNotAllowedToDuck : 1;
- uint8 bCrouchWhenShooting : 1;
- uint8 bIsDucking : 1;
- uint8 bGetUpAnimStarted : 1;
- uint8 bDoBloodyFootprints : 1;
- uint8 bFleeAfterExitingCar : 1;
-
- uint8 bWanderPathAfterExitingCar : 1;
- uint8 bIsLeader : 1;
- uint8 bDontDragMeOutCar : 1; // unfinished feature
- uint8 m_ped_flagF8 : 1;
- uint8 bWillBeQuickJacked : 1;
- uint8 bCancelEnteringCar : 1; // after door is opened or couldn't be opened due to it's locked
- uint8 bObstacleShowedUpDuringKillObjective : 1;
- uint8 bDuckAndCover : 1;
-
- uint8 bStillOnValidPoly : 1; // set if the polygon the ped is on is still valid for collision
- uint8 bAllowMedicsToReviveMe : 1;
- uint8 bResetWalkAnims : 1;
- uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found
- uint8 bOnBoat : 1; // not just driver, may be just standing
- uint8 bBusJacked : 1;
- uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door and when arrested by police
- uint8 bFadeOut : 1;
-
- uint8 bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision
- uint8 bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type)
- uint8 bCullExtraFarAway : 1; // special ped only gets culled if it's extra far away (for roadblocks)
- uint8 bClearObjective : 1;
- uint8 bTryingToReachDryLand : 1; // has ped just exited boat and trying to get to dry land
- uint8 bCollidedWithMyVehicle : 1;
- uint8 bRichFromMugging : 1; // ped has lots of cash cause they've been mugging people
- uint8 bChrisCriminal : 1; // Is a criminal as killed during Chris' police mission (should be counted as such)
-
- uint8 bShakeFist : 1; // test shake hand at look entity
- uint8 bNoCriticalHits : 1; // if set, limbs won't came off
- uint8 bVehExitWillBeInstant : 1;
- uint8 bHasAlreadyBeenRecorded : 1;
- uint8 bFallenDown : 1;
+ uint32 bIsStanding : 1;
+ uint32 m_ped_flagA2 : 1; // bWasStanding?
+ uint32 bIsAttacking : 1; // doesn't reset after fist fight
+ uint32 bIsPointingGunAt : 1;
+ uint32 bIsLooking : 1;
+ uint32 bKeepTryingToLook : 1; // if we can't look somewhere due to unreachable angles
+ uint32 bIsRestoringLook : 1;
+ uint32 bIsAimingGun : 1;
+
+ uint32 bIsRestoringGun : 1;
+ uint32 bCanPointGunAtTarget : 1;
+ uint32 bIsTalking : 1;
+ uint32 bIsInTheAir : 1;
+ uint32 bIsLanding : 1;
+ uint32 bIsRunning : 1; // on some conditions
+ uint32 bHitSomethingLastFrame : 1;
+ uint32 bVehEnterDoorIsBlocked : 1; // because someone else enters/exits from there
+
+ uint32 bCanPedEnterSeekedCar : 1;
+ uint32 bRespondsToThreats : 1;
+ uint32 bRenderPedInCar : 1;
+ uint32 bChangedSeat : 1;
+ uint32 bUpdateAnimHeading : 1;
+ uint32 bBodyPartJustCameOff : 1;
+ uint32 bIsShooting : 1;
+ uint32 bFindNewNodeAfterStateRestore : 1;
+
+ uint32 bHasACamera : 1; // does ped possess a camera to document accidents involves fire/explosion
+ uint32 bGonnaInvestigateEvent : 1;
+ uint32 bPedIsBleeding : 1;
+ uint32 bStopAndShoot : 1; // Ped cannot reach target to attack with fist, need to use gun
+ uint32 bIsPedDieAnimPlaying : 1;
+ uint32 bUsePedNodeSeek : 1;
+ uint32 bObjectiveCompleted : 1;
+ uint32 bScriptObjectiveCompleted : 1;
+
+ uint32 bKindaStayInSamePlace : 1;
+ uint32 bBeingChasedByPolice : 1; // Unused VC leftover. Should've been set for criminal/gang members
+ uint32 bNotAllowedToDuck : 1;
+ uint32 bCrouchWhenShooting : 1;
+ uint32 bIsDucking : 1;
+ uint32 bGetUpAnimStarted : 1;
+ uint32 bDoBloodyFootprints : 1;
+ uint32 bFleeAfterExitingCar : 1;
+
+ uint32 bWanderPathAfterExitingCar : 1;
+ uint32 bIsLeader : 1;
+ uint32 bDontDragMeOutCar : 1; // unfinished feature
+ uint32 m_ped_flagF8 : 1;
+ uint32 bWillBeQuickJacked : 1;
+ uint32 bCancelEnteringCar : 1; // after door is opened or couldn't be opened due to it's locked
+ uint32 bObstacleShowedUpDuringKillObjective : 1;
+ uint32 bDuckAndCover : 1;
+
+ uint32 bStillOnValidPoly : 1; // set if the polygon the ped is on is still valid for collision
+ uint32 bAllowMedicsToReviveMe : 1;
+ uint32 bResetWalkAnims : 1;
+ uint32 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found
+ uint32 bOnBoat : 1; // not just driver, may be just standing
+ uint32 bBusJacked : 1;
+ uint32 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door and when arrested by police
+ uint32 bFadeOut : 1;
+
+ uint32 bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision
+ uint32 bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type)
+ uint32 bCullExtraFarAway : 1; // special ped only gets culled if it's extra far away (for roadblocks)
+ uint32 bClearObjective : 1;
+ uint32 bTryingToReachDryLand : 1; // has ped just exited boat and trying to get to dry land
+ uint32 bCollidedWithMyVehicle : 1;
+ uint32 bRichFromMugging : 1; // ped has lots of cash cause they've been mugging people
+ uint32 bChrisCriminal : 1; // Is a criminal as killed during Chris' police mission (should be counted as such)
+
+ uint32 bShakeFist : 1; // test shake hand at look entity
+ uint32 bNoCriticalHits : 1; // if set, limbs won't came off
+ uint32 bVehExitWillBeInstant : 1;
+ uint32 bHasAlreadyBeenRecorded : 1;
+ uint32 bFallenDown : 1;
#ifdef VC_PED_PORTS
- uint8 bSomeVCflag1 : 1;
-#else
- uint8 m_ped_flagI20 : 1;
+ uint32 bSomeVCflag1 : 1;
#endif
- uint8 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
- uint8 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
+#ifdef PED_SKIN
+ uint32 bDontAcceptIKLookAts : 1; // TODO: find uses of this
+#endif
+ // our own flags
+ uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
+ uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
- uint8 stuff10[3];
uint8 CharCreatedBy;
- uint8 field_161;
- uint8 pad_162[2];
eObjective m_objective;
eObjective m_prevObjective;
CPed *m_pedInObjective;
@@ -404,6 +404,10 @@ public:
CEntity* m_pEventEntity;
float m_fAngleToEvent;
AnimBlendFrameData *m_pFrames[PED_NODE_MAX];
+#ifdef PED_SKIN
+ // stored inside the clump with non-skin ped
+ RpAtomic *m_pWeaponModel;
+#endif
AssocGroupId m_animGroup;
CAnimBlendAssociation *m_pVehicleAnim;
CVector2D m_vecAnimMoveDelta;
@@ -424,8 +428,6 @@ public:
uint16 m_nPathNodes;
int16 m_nCurPathNode;
int8 m_nPathDir;
-private:
- int8 _pad2B5[3];
public:
CPathNode *m_pLastPathNode;
CPathNode *m_pNextPathNode;
@@ -436,12 +438,11 @@ public:
int16 m_routePointsPassed;
int16 m_routeType; // See PedRouteType
int16 m_routePointsBeingPassed;
- uint16 field_2D2;
CVector2D m_moved;
float m_fRotationCur;
float m_fRotationDest;
float m_headingRate;
- uint16 m_vehEnterType; // TODO: this is more like a door, not a type
+ uint16 m_vehEnterType;
int16 m_walkAroundType;
CPhysical *m_pCurrentPhysSurface;
CVector m_vecOffsetFromPhysSurface;
@@ -450,10 +451,8 @@ public:
CEntity *m_pSeekTarget;
CVehicle *m_pMyVehicle;
bool bInVehicle;
- uint8 pad_315[3];
float m_distanceToCountSeekDone;
bool bRunningToPhone;
- uint8 field_31D;
int16 m_phoneId;
eCrimeType m_crimeToReportOnPhone;
uint32 m_phoneTalkTimer;
@@ -468,7 +467,6 @@ public:
uint32 m_collidingThingTimer;
CEntity *m_pCollidingEntity;
uint8 m_stateUnused;
- uint8 pad_351[3];
uint32 m_timerUnused;
CVector2D *m_wanderRangeBounds; // array with 2 CVector2D (actually unused CRange2D class) - unused
CWeapon m_weapons[WEAPONTYPE_TOTAL_INVENTORY_WEAPONS];
@@ -483,7 +481,6 @@ public:
uint8 m_fightButtonPressure;
FightState m_fightState;
bool m_takeAStepAfterAttack;
- uint8 pad_4B3;
CFire *m_pFire;
CEntity *m_pLookTarget;
float m_fLookDirection;
@@ -502,11 +499,9 @@ public:
uint8 m_panicCounter;
bool m_deadBleeding;
int8 m_bodyPartBleeding; // PedNode, but -1 if there isn't
- uint8 m_field_4F3;
CPed *m_nearPeds[10];
uint16 m_numNearPeds;
int8 m_lastWepDam;
- uint8 pad_51F;
uint32 m_lastSoundStart;
uint32 m_soundStart;
uint16 m_lastQueuedSound;
@@ -742,7 +737,6 @@ public:
static void PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
- // functions that I see unnecessary to hook
bool IsPlayer(void);
bool UseGroundColModel(void);
bool CanSetPedState(void);
@@ -792,11 +786,15 @@ public:
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
- RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; }
PedState GetPedState(void) { return m_nPedState; }
void SetPedState(PedState state) { m_nPedState = state; }
+ bool Dead(void) { return m_nPedState == PED_DEAD; }
+ bool Dying(void) { return m_nPedState == PED_DIE; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
+ bool OnGround(void) { return m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
+
+ bool Driving(void) { return m_nPedState == PED_DRIVING; }
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
bool EnteringCar(void) { return m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK; }
@@ -822,15 +820,53 @@ public:
SetMoveState(PEDMOVE_WALK);
}
+ // Using this to abstract nodes of skinned and non-skinned meshes
+ CVector GetNodePosition(int32 node)
+ {
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ // this is just stupid
+ //RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
+ pos = mats[idx].pos;
+ return pos;
+ }else
+#endif
+ {
+ RwMatrix mat;
+ CPedIK::GetWorldMatrix(m_pFrames[node]->frame, &mat);
+ return mat.pos;
+ }
+ }
+ void TransformToNode(CVector &pos, int32 node)
+ {
+#ifdef PED_SKIN
+ if(IsClumpSkinned(GetClump())){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&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));
+ }
+ }
+
// set by 0482:set_threat_reaction_range_multiplier opcode
- static uint16 &nThreatReactionRangeMultiplier;
+ static uint16 nThreatReactionRangeMultiplier;
// set by 0481:set_enter_car_range_multiplier opcode
- static uint16 &nEnterCarRangeMultiplier;
+ static uint16 nEnterCarRangeMultiplier;
- static bool &bNastyLimbsCheat;
- static bool &bPedCheat2;
- static bool &bPedCheat3;
+ static bool bNastyLimbsCheat;
+ static bool bPedCheat2;
+ static bool bPedCheat3;
static CVector2D ms_vec2DFleePosition;
#ifdef TOGGLEABLE_BETA_FEATURES
@@ -843,6 +879,10 @@ public:
static void SwitchDebugDisplay(void);
void DebugRenderOnePedText(void);
#endif
+
+#ifdef PED_SKIN
+ void renderLimb(int node);
+#endif
};
class cPedParams
@@ -856,6 +896,7 @@ public:
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
+#ifndef PED_SKIN
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
@@ -868,3 +909,4 @@ static_assert(offsetof(CPed, m_bodyPartBleeding) == 0x4F2, "CPed: error");
static_assert(offsetof(CPed, m_pedInObjective) == 0x16C, "CPed: error");
static_assert(offsetof(CPed, m_pEventEntity) == 0x19C, "CPed: error");
static_assert(sizeof(CPed) == 0x53C, "CPed: error");
+#endif
diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp
index 8e450ee6..3db3dc0f 100644
--- a/src/peds/PedIK.cpp
+++ b/src/peds/PedIK.cpp
@@ -1,5 +1,6 @@
#include "common.h"
-#include "patcher.h"
+
+#include "Bones.h"
#include "Camera.h"
#include "PedIK.h"
#include "Ped.h"
@@ -12,6 +13,10 @@ LimbMovementInfo CPedIK::ms_headRestoreInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f
LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(20.0f), DEGTORAD(-100.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(10.0f) };
LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(80.0f), DEGTORAD(0.0f), DEGTORAD(20.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(5.0f) };
+const RwV3d XaxisIK = { 1.0f, 0.0f, 0.0f};
+const RwV3d YaxisIK = { 0.0f, 1.0f, 0.0f};
+const RwV3d ZaxisIK = { 0.0f, 0.0f, 1.0f};
+
CPedIK::CPedIK(CPed *ped)
{
m_ped = ped;
@@ -26,57 +31,104 @@ CPedIK::CPedIK(CPed *ped)
m_lowerArmOrient.theta = 0.0f;
}
+#ifdef PED_SKIN
+inline RwMatrix*
+GetComponentMatrix(CPed *ped, int32 node)
+{
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(ped->GetClump());
+ int idx = RpHAnimIDGetIndex(hier, ped->m_pFrames[node]->nodeID);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ return &mats[idx];
+}
+#endif
+
void
-CPedIK::RotateTorso(AnimBlendFrameData *animBlend, LimbOrientation *limb, bool changeRoll)
+CPedIK::RotateTorso(AnimBlendFrameData *node, LimbOrientation *limb, bool changeRoll)
{
- RwFrame *f = animBlend->frame;
- RwMatrix *mat = CPedIK::GetWorldMatrix(RwFrameGetParent(f), RwMatrixCreate());
-
- RwV3d upVector = { mat->right.z, mat->up.z, mat->at.z };
- RwV3d rightVector;
- RwV3d pos = RwFrameGetMatrix(f)->pos;
-
- // rotation == 0 -> looking in y direction
- // left? vector
- float c = Cos(m_ped->m_fRotationCur);
- float s = Sin(m_ped->m_fRotationCur);
- rightVector.x = -(c*mat->right.x + s*mat->right.y);
- rightVector.y = -(c*mat->up.x + s*mat->up.y);
- rightVector.z = -(c*mat->at.x + s*mat->at.y);
-
- if(changeRoll){
- // Used when aiming only involves over the legs.(canAimWithArm)
- // Automatically changes roll(forward rotation) axis of the parts above upper legs while moving, based on position of upper legs.
- // Not noticeable in normal conditions...
-
- RwV3d forwardVector;
- CVector inversedForward = CrossProduct(CVector(0.0f, 0.0f, 1.0f), mat->up);
- inversedForward.Normalise();
- float dotProduct = DotProduct(mat->at, inversedForward);
- if(dotProduct > 1.0f) dotProduct = 1.0f;
- if(dotProduct < -1.0f) dotProduct = -1.0f;
- float alpha = Acos(dotProduct);
-
- if(mat->at.z < 0.0f)
- alpha = -alpha;
-
- forwardVector.x = s * mat->right.x - c * mat->right.y;
- forwardVector.y = s * mat->up.x - c * mat->up.y;
- forwardVector.z = s * mat->at.x - c * mat->at.y;
-
- float curYaw, curPitch;
- CPedIK::ExtractYawAndPitchWorld(mat, &curYaw, &curPitch);
- RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi - (curYaw - m_ped->m_fRotationCur)), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(f), &forwardVector, RADTODEG(alpha), rwCOMBINEPOSTCONCAT);
- }else{
- // pitch
- RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
- // yaw
- RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi), rwCOMBINEPOSTCONCAT);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ RtQuat *q = &node->hanimFrame->q;
+#ifndef FIX_BUGS
+ // this is what the game does (also VC), but it does not look great
+ RtQuatRotate(q, &XaxisIK, RADTODEG(limb->phi), rwCOMBINEPRECONCAT);
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->theta), rwCOMBINEPRECONCAT); // pitch
+#else
+ // copied the code from the non-skinned case
+ // this seems to work ok
+
+ // We can't get the parent matrix of an hanim frame but
+ // this function is always called with PED_MID, so we know the parent frame.
+ // Trouble is that PED_MID is "Smid" on PS2/PC but BONE_torso on mobile/xbox...
+ // so this doesn't exactly do what we'd like anyway
+ RwMatrix *mat = GetComponentMatrix(m_ped, PED_MID);
+
+ RwV3d vec1, vec2;
+ vec1.x = mat->right.z;
+ vec1.y = mat->up.z;
+ vec1.z = mat->at.z;
+ float c = Cos(m_ped->m_fRotationCur);
+ float s = Sin(m_ped->m_fRotationCur);
+ vec2.x = -(c*mat->right.x + s*mat->right.y);
+ vec2.y = -(c*mat->up.x + s*mat->up.y);
+ vec2.z = -(c*mat->at.x + s*mat->at.y);
+
+ // Not sure what exactly to do here
+ RtQuatRotate(q, &vec1, RADTODEG(limb->phi), rwCOMBINEPRECONCAT);
+ RtQuatRotate(q, &vec2, RADTODEG(limb->theta), rwCOMBINEPRECONCAT);
+#endif
+ m_ped->bDontAcceptIKLookAts = true;
+ }else
+#endif
+ {
+ RwFrame *f = node->frame;
+ RwMatrix *mat = GetWorldMatrix(RwFrameGetParent(f), RwMatrixCreate());
+
+ RwV3d upVector = { mat->right.z, mat->up.z, mat->at.z };
+ RwV3d rightVector;
+ RwV3d pos = RwFrameGetMatrix(f)->pos;
+
+ // rotation == 0 -> looking in y direction
+ // left? vector
+ float c = Cos(m_ped->m_fRotationCur);
+ float s = Sin(m_ped->m_fRotationCur);
+ rightVector.x = -(c*mat->right.x + s*mat->right.y);
+ rightVector.y = -(c*mat->up.x + s*mat->up.y);
+ rightVector.z = -(c*mat->at.x + s*mat->at.y);
+
+ if(changeRoll){
+ // Used when aiming only involves over the legs.(canAimWithArm)
+ // Automatically changes roll(forward rotation) axis of the parts above upper legs while moving, based on position of upper legs.
+ // Not noticeable in normal conditions...
+
+ RwV3d forwardVector;
+ CVector inversedForward = CrossProduct(CVector(0.0f, 0.0f, 1.0f), mat->up);
+ inversedForward.Normalise();
+ float dotProduct = DotProduct(mat->at, inversedForward);
+ if(dotProduct > 1.0f) dotProduct = 1.0f;
+ if(dotProduct < -1.0f) dotProduct = -1.0f;
+ float alpha = Acos(dotProduct);
+
+ if(mat->at.z < 0.0f)
+ alpha = -alpha;
+
+ forwardVector.x = s * mat->right.x - c * mat->right.y;
+ forwardVector.y = s * mat->up.x - c * mat->up.y;
+ forwardVector.z = s * mat->at.x - c * mat->at.y;
+
+ float curYaw, curPitch;
+ ExtractYawAndPitchWorld(mat, &curYaw, &curPitch);
+ RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
+ RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi - (curYaw - m_ped->m_fRotationCur)), rwCOMBINEPOSTCONCAT);
+ RwMatrixRotate(RwFrameGetMatrix(f), &forwardVector, RADTODEG(alpha), rwCOMBINEPOSTCONCAT);
+ }else{
+ // pitch
+ RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->theta), rwCOMBINEPOSTCONCAT);
+ // yaw
+ RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->phi), rwCOMBINEPOSTCONCAT);
+ }
+ RwFrameGetMatrix(f)->pos = pos;
+ RwMatrixDestroy(mat);
}
- RwFrameGetMatrix(f)->pos = pos;
- RwMatrixDestroy(mat);
}
void
@@ -85,12 +137,24 @@ CPedIK::GetComponentPosition(RwV3d *pos, uint32 node)
RwFrame *f;
RwMatrix *mat;
- f = m_ped->GetNodeFrame(node);
- mat = RwFrameGetMatrix(f);
- *pos = mat->pos;
-
- for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
- RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(f));
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ 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);
+ }else
+#endif
+ {
+ f = m_ped->m_pFrames[node]->frame;
+ mat = RwFrameGetMatrix(f);
+ *pos = mat->pos;
+
+ for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
+ RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(f));
+ }
}
RwMatrix*
@@ -157,50 +221,94 @@ CPedIK::RestoreGunPosn(void)
return limbStatus == ANGLES_SET_EXACTLY;
}
+#ifdef PED_SKIN
+void
+CPedIK::RotateHead(void)
+{
+ RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.phi), rwCOMBINEREPLACE);
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.theta), rwCOMBINEPOSTCONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
+}
+#endif
+
bool
CPedIK::LookInDirection(float phi, float theta)
{
bool success = true;
- RwFrame *frame = m_ped->GetNodeFrame(PED_HEAD);
- RwMatrix *frameMat = RwFrameGetMatrix(frame);
+ float yaw, pitch;
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
+ m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
+ ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &m_headOrient.phi, &m_headOrient.theta);
+ }
- if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
- m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
- CPedIK::ExtractYawAndPitchLocal(frameMat, &m_headOrient.phi, &m_headOrient.theta);
- }
+ // parent of head is torso
+ RwMatrix worldMat = *GetComponentMatrix(m_ped, BONE_torso);
+ ExtractYawAndPitchWorld(&worldMat, &yaw, &pitch);
+
+ LimbMoveStatus headStatus = MoveLimb(m_headOrient, CGeneral::LimitRadianAngle(phi - yaw),
+ CGeneral::LimitRadianAngle(DEGTORAD(10.0f)), ms_headInfo);
+ if (headStatus == ANGLES_SET_TO_MAX)
+ success = false;
+
+ if (headStatus != ANGLES_SET_EXACTLY){
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
+ if (MoveLimb(m_torsoOrient, CGeneral::LimitRadianAngle(phi), theta, ms_torsoInfo))
+ success = true;
+ }else{
+ RotateHead();
+ return success;
+ }
+ }
- RwMatrix *worldMat = RwMatrixCreate();
- worldMat = CPedIK::GetWorldMatrix(RwFrameGetParent(frame), worldMat);
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+ RotateHead();
+ }else
+#endif
+ {
+ RwFrame *frame = m_ped->m_pFrames[PED_HEAD]->frame;
+ RwMatrix *frameMat = RwFrameGetMatrix(frame);
+
+ if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
+ m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
+ ExtractYawAndPitchLocal(frameMat, &m_headOrient.phi, &m_headOrient.theta);
+ }
- float alpha, beta;
- CPedIK::ExtractYawAndPitchWorld(worldMat, &alpha, &beta);
- RwMatrixDestroy(worldMat);
+ RwMatrix *worldMat = RwMatrixCreate();
+ worldMat = GetWorldMatrix(RwFrameGetParent(frame), worldMat);
- alpha += m_torsoOrient.phi;
- float neededPhiTurn = CGeneral::LimitRadianAngle(phi - alpha);
- beta *= cos(neededPhiTurn);
+ ExtractYawAndPitchWorld(worldMat, &yaw, &pitch);
+ RwMatrixDestroy(worldMat);
- float neededThetaTurn = CGeneral::LimitRadianAngle(theta - beta);
- LimbMoveStatus headStatus = CPedIK::MoveLimb(m_headOrient, neededPhiTurn, neededThetaTurn, ms_headInfo);
- if (headStatus == ANGLES_SET_TO_MAX)
- success = false;
+ yaw += m_torsoOrient.phi;
+ float neededPhiTurn = CGeneral::LimitRadianAngle(phi - yaw);
+ pitch *= Cos(neededPhiTurn);
- if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY)) {
- float remainingTurn = CGeneral::LimitRadianAngle(phi - m_ped->m_fRotationCur);
- if (CPedIK::MoveLimb(m_torsoOrient, remainingTurn, theta, ms_torsoInfo))
- success = true;
- }
- CMatrix nextFrame = CMatrix(frameMat);
- CVector framePos = nextFrame.GetPosition();
+ float neededThetaTurn = CGeneral::LimitRadianAngle(theta - pitch);
+ LimbMoveStatus headStatus = MoveLimb(m_headOrient, neededPhiTurn, neededThetaTurn, ms_headInfo);
+ if (headStatus == ANGLES_SET_TO_MAX)
+ success = false;
- nextFrame.SetRotateZ(m_headOrient.theta);
- nextFrame.RotateX(m_headOrient.phi);
- nextFrame.GetPosition() += framePos;
- nextFrame.UpdateRW();
+ if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY)) {
+ float remainingTurn = CGeneral::LimitRadianAngle(phi - m_ped->m_fRotationCur);
+ if (MoveLimb(m_torsoOrient, remainingTurn, theta, ms_torsoInfo))
+ success = true;
+ }
+ CMatrix nextFrame = CMatrix(frameMat);
+ CVector framePos = nextFrame.GetPosition();
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+ nextFrame.SetRotateZ(m_headOrient.theta);
+ nextFrame.RotateX(m_headOrient.phi);
+ nextFrame.GetPosition() += framePos;
+ nextFrame.UpdateRW();
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+
+ }
return success;
}
@@ -234,10 +342,24 @@ CPedIK::PointGunInDirection(float phi, float theta)
if (m_flags & AIMS_WITH_ARM && m_torsoOrient.phi * m_upperArmOrient.phi < 0.0f)
MoveLimb(m_torsoOrient, 0.0f, m_torsoOrient.theta, ms_torsoInfo);
} else {
- RwMatrix *matrix = GetWorldMatrix(RwFrameGetParent(m_ped->GetNodeFrame(PED_UPPERARMR)), RwMatrixCreate());
+ // Unused code
+ RwMatrix *matrix;
float yaw, pitch;
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ matrix = RwMatrixCreate();
+ *matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
+ ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
+ RwMatrixDestroy(matrix);
+ }else
+#endif
+ {
+ matrix = GetWorldMatrix(RwFrameGetParent(m_ped->m_pFrames[PED_UPPERARMR]->frame), RwMatrixCreate());
+ ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
+ RwMatrixDestroy(matrix);
+ }
+ //
+
LimbMoveStatus status = MoveLimb(m_torsoOrient, angle, theta, ms_torsoInfo);
if (status == ANGLES_SET_TO_MAX)
result = false;
@@ -255,24 +377,56 @@ bool
CPedIK::PointGunInDirectionUsingArm(float phi, float theta)
{
bool result = false;
- RwFrame *frame = m_ped->GetNodeFrame(PED_UPPERARMR);
- RwMatrix *matrix = GetWorldMatrix(RwFrameGetParent(frame), RwMatrixCreate());
-
- RwV3d upVector = { matrix->right.z, matrix->up.z, matrix->at.z };
+ RwV3d upVector; // only for non-skinned
+ RwMatrix *matrix;
float yaw, pitch;
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ matrix = RwMatrixCreate();
+ *matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
+ ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
+ RwMatrixDestroy(matrix);
+ }else
+#endif
+ {
+ RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
+ matrix = GetWorldMatrix(RwFrameGetParent(frame), RwMatrixCreate());
+
+ // with PED_SKIN this is actually done below (with a memory leak)
+ upVector.x = matrix->right.z;
+ upVector.y = matrix->up.z;
+ upVector.z = matrix->at.z;
+
+ ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
+ RwMatrixDestroy(matrix);
+ }
RwV3d rightVector = { 0.0f, 0.0f, 1.0f };
RwV3d forwardVector = { 1.0f, 0.0f, 0.0f };
- float uaPhi = phi - m_torsoOrient.phi - DEGTORAD(15.0f);
- LimbMoveStatus uaStatus = MoveLimb(m_upperArmOrient, uaPhi, CGeneral::LimitRadianAngle(theta - pitch), ms_upperArmInfo);
+ float uaPhi, uaTheta;
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ uaPhi = phi;
+ uaTheta = theta + DEGTORAD(10.0f);
+ }else
+#endif
+ {
+ uaPhi = phi - m_torsoOrient.phi - DEGTORAD(15.0f);
+ uaTheta = CGeneral::LimitRadianAngle(theta - pitch);
+ }
+ LimbMoveStatus uaStatus = MoveLimb(m_upperArmOrient, uaPhi, uaTheta, ms_upperArmInfo);
if (uaStatus == ANGLES_SET_EXACTLY) {
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
+
+#ifdef PED_SKIN
+ // this code is completely missing on xbox & android, but we can keep it with the check
+ // TODO? implement it for skinned geometry?
+ if(!IsClumpSkinned(m_ped->GetClump()))
+#endif
if (uaStatus == ANGLES_SET_TO_MAX) {
float laPhi = uaPhi - m_upperArmOrient.phi;
@@ -286,17 +440,29 @@ CPedIK::PointGunInDirectionUsingArm(float phi, float theta)
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
- RwFrame *child = GetFirstChild(frame);
+ RwFrame *child = GetFirstChild(m_ped->m_pFrames[PED_UPPERARMR]->frame);
RwV3d pos = RwFrameGetMatrix(child)->pos;
RwMatrixRotate(RwFrameGetMatrix(child), &forwardVector, RADTODEG(m_lowerArmOrient.theta), rwCOMBINEPOSTCONCAT);
RwMatrixRotate(RwFrameGetMatrix(child), &rightVector, RADTODEG(-m_lowerArmOrient.phi), rwCOMBINEPOSTCONCAT);
RwFrameGetMatrix(child)->pos = pos;
}
- RwV3d pos = RwFrameGetMatrix(frame)->pos;
- RwMatrixRotate(RwFrameGetMatrix(frame), &rightVector, RADTODEG(m_upperArmOrient.theta), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(frame), &upVector, RADTODEG(m_upperArmOrient.phi), rwCOMBINEPOSTCONCAT);
- RwFrameGetMatrix(frame)->pos = pos;
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ RtQuat *q = &m_ped->m_pFrames[PED_UPPERARMR]->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, RADTODEG(m_upperArmOrient.phi), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(m_upperArmOrient.theta), rwCOMBINEPOSTCONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
+ }else
+#endif
+ {
+ RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
+ // with PED_SKIN we're also getting upVector here
+ RwV3d pos = RwFrameGetMatrix(frame)->pos;
+ RwMatrixRotate(RwFrameGetMatrix(frame), &rightVector, RADTODEG(m_upperArmOrient.theta), rwCOMBINEPOSTCONCAT);
+ RwMatrixRotate(RwFrameGetMatrix(frame), &upVector, RADTODEG(m_upperArmOrient.phi), rwCOMBINEPOSTCONCAT);
+ RwFrameGetMatrix(frame)->pos = pos;
+ }
return result;
}
@@ -314,28 +480,42 @@ bool
CPedIK::RestoreLookAt(void)
{
bool result = false;
- RwMatrix *mat = RwFrameGetMatrix(m_ped->GetNodeFrame(PED_HEAD));
- if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
- m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
- } else {
- float yaw, pitch;
- ExtractYawAndPitchLocal(mat, &yaw, &pitch);
- if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
- result = true;
- }
+ float yaw, pitch;
- CMatrix matrix(mat);
- CVector pos = matrix.GetPosition();
- matrix.SetRotateZ(m_headOrient.theta);
- matrix.RotateX(m_headOrient.phi);
- matrix.Translate(pos);
- matrix.UpdateRW();
+#ifdef PED_SKIN
+ if(IsClumpSkinned(m_ped->GetClump())){
+ if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
+ m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
+ } else {
+ ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &yaw, &pitch);
+ if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
+ result = true;
+ }
+ RotateHead();
+ }else
+#endif
+ {
+ RwMatrix *mat = RwFrameGetMatrix(m_ped->m_pFrames[PED_HEAD]->frame);
+ if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
+ m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
+ } else {
+ ExtractYawAndPitchLocal(mat, &yaw, &pitch);
+ if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
+ result = true;
+ }
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ CMatrix matrix(mat);
+ CVector pos = matrix.GetPosition();
+ matrix.SetRotateZ(m_headOrient.theta);
+ matrix.RotateX(m_headOrient.phi);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
MoveLimb(m_torsoOrient, 0.0f, 0.0f, ms_torsoInfo);
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
-
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+ }
return result;
}
@@ -363,18 +543,13 @@ CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
if (mat->up.x > 0.0f) *pitch = -*pitch;
}
-STARTPATCHES
- InjectHook(0x4ED0F0, &CPedIK::GetComponentPosition, PATCH_JUMP);
- InjectHook(0x4ED060, &CPedIK::GetWorldMatrix, PATCH_JUMP);
- InjectHook(0x4EDDB0, &CPedIK::RotateTorso, PATCH_JUMP);
- InjectHook(0x4ED440, &CPedIK::MoveLimb, PATCH_JUMP);
- InjectHook(0x4EDD70, &CPedIK::RestoreGunPosn, PATCH_JUMP);
- InjectHook(0x4ED620, &CPedIK::LookInDirection, PATCH_JUMP);
- InjectHook(0x4ED590, &CPedIK::LookAtPosition, PATCH_JUMP);
- InjectHook(0x4ED9B0, &CPedIK::PointGunInDirection, PATCH_JUMP);
- InjectHook(0x4EDB20, &CPedIK::PointGunInDirectionUsingArm, PATCH_JUMP);
- InjectHook(0x4ED920, &CPedIK::PointGunAtPosition, PATCH_JUMP);
- InjectHook(0x4ED810, &CPedIK::RestoreLookAt, PATCH_JUMP);
- InjectHook(0x4ED140, &CPedIK::ExtractYawAndPitchWorld, PATCH_JUMP);
- InjectHook(0x4ED2C0, &CPedIK::ExtractYawAndPitchLocal, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+#ifdef PED_SKIN
+void
+CPedIK::ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch)
+{
+ RwMatrix *mat = RwMatrixCreate();
+ RtQuatConvertToMatrix(&node->hanimFrame->q, mat);
+ ExtractYawAndPitchLocal(mat, yaw, pitch);
+ RwMatrixDestroy(mat);
+}
+#endif
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index 7b82d1ac..fd9e4702 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -55,9 +55,11 @@ public:
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
+ void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
+ void RotateHead(void);
bool LookInDirection(float phi, float theta);
bool LookAtPosition(CVector const& pos);
bool RestoreLookAt(void);
diff --git a/src/peds/PedPlacement.cpp b/src/peds/PedPlacement.cpp
index e5f6a077..8b8b3dfa 100644
--- a/src/peds/PedPlacement.cpp
+++ b/src/peds/PedPlacement.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Ped.h"
#include "PedPlacement.h"
#include "World.h"
@@ -30,7 +30,7 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
if (CWorld::ProcessVerticalLine(vec, startZ, foundCol, foundEnt, true, false, false, false, true, false, nil))
foundColZ2 = foundCol.point.z;
- zForPed = max(foundColZ, foundColZ2);
+ zForPed = Max(foundColZ, foundColZ2);
if (zForPed > -99.0f)
pos->z = FEET_OFFSET + zForPed;
@@ -49,8 +49,3 @@ CPedPlacement::IsPositionClearForPed(CVector* pos)
CWorld::FindObjectsKindaColliding(*pos, 0.75f, true, &count, 2, nil, false, true, true, false, false);
return count == 0;
}
-
-STARTPATCHES
- InjectHook(0x4EE340, &CPedPlacement::FindZCoorForPed, PATCH_JUMP);
- InjectHook(0x4EE310, &CPedPlacement::IsPositionClearOfCars, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/PedRoutes.cpp b/src/peds/PedRoutes.cpp
index 3bc17002..3ff080e6 100644
--- a/src/peds/PedRoutes.cpp
+++ b/src/peds/PedRoutes.cpp
@@ -1,9 +1,9 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "PedRoutes.h"
-CRouteNode (&gaRoutes)[NUMPEDROUTES] = *(CRouteNode(*)[NUMPEDROUTES]) * (uintptr*)0x62E090;
+CRouteNode gaRoutes[NUMPEDROUTES];
void
CRouteNode::Initialise()
diff --git a/src/peds/PedStats.cpp b/src/peds/PedStats.cpp
index 147f11e2..06e39039 100644
--- a/src/peds/PedStats.cpp
+++ b/src/peds/PedStats.cpp
@@ -1,10 +1,9 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "FileMgr.h"
#include "PedStats.h"
-//CPedStats *(&CPedStats::ms_apPedStats)[NUM_PEDSTATS] = *(CPedStats *(*)[NUM_PEDSTATS]) *(uintptr*)0x9404D4;
CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];
void
@@ -117,10 +116,3 @@ CPedStats::GetPedStatType(char *name)
return NUM_PEDSTATS;
}
-
-STARTPATCHES
- InjectHook(0x4EF460, &CPedStats::Initialise, PATCH_JUMP);
- InjectHook(0x4EF540, &CPedStats::Shutdown, PATCH_JUMP);
- InjectHook(0x4EF580, &CPedStats::LoadPedStats, PATCH_JUMP);
- InjectHook(0x4EF780, &CPedStats::GetPedStatType, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp
index 4c9d6b3f..8bf4c6e1 100644
--- a/src/peds/PedType.cpp
+++ b/src/peds/PedType.cpp
@@ -1,9 +1,9 @@
#include "common.h"
-#include "patcher.h"
+
#include "FileMgr.h"
#include "PedType.h"
-CPedType *(&CPedType::ms_apPedType)[NUM_PEDTYPES] = *(CPedType *(*)[NUM_PEDTYPES]) *(uintptr*)0x941594;
+CPedType *CPedType::ms_apPedType[NUM_PEDTYPES];
void
CPedType::Initialise(void)
@@ -202,12 +202,3 @@ INITSAVEBUF
*ms_apPedType[i] = ReadSaveBuf<CPedType>(buf);
VALIDATESAVEBUF(size)
}
-
-STARTPATCHES
- InjectHook(0x4EE7E0, &CPedType::Initialise, PATCH_JUMP);
- InjectHook(0x4EE890, &CPedType::Shutdown, PATCH_JUMP);
- InjectHook(0x4EEC10, &CPedType::FindPedType, PATCH_JUMP);
- InjectHook(0x4EEF40, &CPedType::FindPedFlag, PATCH_JUMP);
- InjectHook(0x4EF320, &CPedType::Save, PATCH_JUMP);
- InjectHook(0x4EF3D0, &CPedType::Load, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index 3d927df5..c0c72550 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -71,7 +71,7 @@ class CPedType
uint32 m_threats;
uint32 m_avoid;
- static CPedType *(&ms_apPedType)[NUM_PEDTYPES];
+ static CPedType *ms_apPedType[NUM_PEDTYPES];
public:
static void Initialise(void);
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index ccc0a43a..664fff18 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -1,5 +1,6 @@
#include "common.h"
-#include "patcher.h"
+
+#include "RwHelper.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "Fire.h"
@@ -43,8 +44,8 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_fStaminaProgress = 0.0f;
m_nEvadeAmount = 0;
field_1367 = 0;
- m_nShotDelay = 0;
- field_1376 = 0.0f;
+ m_nHitAnimDelayTimer = 0;
+ m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bCanBeDamaged = true;
@@ -135,6 +136,9 @@ CPlayerPed::SetupPlayerPed(int32 index)
{
CPlayerPed *player = new CPlayerPed();
CWorld::Players[index].m_pPed = player;
+#ifdef FIX_BUGS
+ player->RegisterReference((CEntity**)&CWorld::Players[index].m_pPed);
+#endif
player->SetOrientation(0.0f, 0.0f, 0.0f);
@@ -179,7 +183,7 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
}
SetCurrentWeapon(weapon);
- GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
+ GetWeapon()->m_nAmmoInClip = Min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
ClearWeaponTarget();
@@ -696,7 +700,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
#else
m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
#endif
- m_fMoveSpeed = min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
+ m_fMoveSpeed = Min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
} else {
m_fMoveSpeed = 0.0f;
}
@@ -1024,10 +1028,10 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
if (padUsed->WeaponJustDown()) {
m_bHaveTargetSelected = true;
} else if (!m_bHaveTargetSelected) {
- field_1376 += CTimer::GetTimeStepNonClipped();
+ m_fAttackButtonCounter += CTimer::GetTimeStepNonClipped();
}
} else {
- field_1376 = 0.0f;
+ m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
}
SetAttack(nil);
@@ -1183,7 +1187,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
}
float maxAcc = 0.07f * CTimer::GetTimeStep();
- m_fMoveSpeed = min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
+ m_fMoveSpeed = Min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
} else {
m_fMoveSpeed = 0.0f;
@@ -1403,7 +1407,7 @@ CPlayerPed::ProcessControl(void)
if (bVehEnterDoorIsBlocked || bKindaStayInSamePlace) {
m_fMoveSpeed = 0.0f;
} else {
- m_fMoveSpeed = min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
+ m_fMoveSpeed = Min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
}
if (padUsed && !padUsed->ArePlayerControlsDisabled()) {
if (padUsed->GetTarget() || padUsed->GetLeftStickXJustDown() || padUsed->GetLeftStickYJustDown() ||
@@ -1494,42 +1498,9 @@ CPlayerPed::ProcessControl(void)
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
}
-}
-#include <new>
-
-class CPlayerPed_ : public CPlayerPed
-{
-public:
- CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
- void dtor(void) { CPlayerPed::~CPlayerPed(); }
- void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
- void ProcessControl_(void) { CPlayerPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
- InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
- InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
- InjectHook(0x4EFD90, &CPlayerPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
- InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
- InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
- InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
- InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
- InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
- InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP);
- InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP);
- InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP);
- InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP);
- InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP);
- InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP);
- InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP);
- InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP);
- InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP);
- InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP);
- InjectHook(0x4F3460, &CPlayerPed::KeepAreaAroundPlayerClear, PATCH_JUMP);
- InjectHook(0x4F1970, &CPlayerPed::PlayerControl1stPersonRunAround, PATCH_JUMP);
- InjectHook(0x4F1EF0, &CPlayerPed::ProcessPlayerWeapon, PATCH_JUMP);
- InjectHook(0x4F2640, &CPlayerPed::ProcessAnimGroups, PATCH_JUMP);
-ENDPATCHES
+#ifdef PED_SKIN
+ if (!bIsVisible && IsClumpSkinned(GetClump()))
+ UpdateRpHAnim();
+#endif
+}
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index c139bbbc..b8bd57e4 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -20,23 +20,16 @@ public:
uint8 m_nEvadeAmount;
int8 field_1367;
uint32 m_nSpeedTimer;
- int32 m_nShotDelay;
- float field_1376; // m_fAttackButtonCounter?
+ uint32 m_nHitAnimDelayTimer;
+ float m_fAttackButtonCounter;
bool m_bHaveTargetSelected; // may have better name
- int8 field_1381;
- int8 field_1382;
- int8 field_1383;
CEntity *m_pEvadingFrom; // is this CPhysical?
int32 m_nTargettableObjects[4];
bool m_bAdrenalineActive;
bool m_bHasLockOnTarget;
- int8 field_1406;
- int8 field_1407;
uint32 m_nAdrenalineTime;
bool m_bCanBeDamaged;
int8 field_1413;
- int8 field_1414;
- int8 field_1415;
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6];
float m_fWalkAngle;
@@ -84,4 +77,6 @@ public:
static void ReactivatePlayerPed(int32);
};
+#ifndef PED_SKIN
static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error");
+#endif
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index 6959487f..cd89a05d 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Game.h"
#include "General.h"
#include "World.h"
@@ -35,48 +35,48 @@ const RegenerationPoint aSafeZones[] = {
CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) },
{ LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f,
CVector(698.0f, 182.0f, -20.0f), CVector(681.0f, 178.0f, -20.0f), CVector(586.0f, 144.0f, -20.0f), CVector(577.0f, 135.0f, -20.0f) },
- { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 26.0f, 44.0f, 124.0f, 87.0f, 20.0f, 6.0f,
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 626.0f, 744.0f, -124.0f, -87.0f, -20.0f, -6.0f,
CVector(736.0f, -117.0f, -13.0f), CVector(730.0f, -115.0f, -13.0f), CVector(635.0f, -93.0f, -12.5f), CVector(650.0f, -89.0f, -12.5f) },
- { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 45.0f, 34.0f, 780.0f, 750.0f, 25.0f, 6.0f,
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 645.0f, 734.0f, -780.0f, -750.0f, -25.0f, -6.0f,
CVector(729.0f, -764.0f, -18.0f), CVector(720.0f, -769.0f, -17.0f), CVector(652.0f, -774.0f, -10.5f), CVector(659.0f, -770.0f, -10.5f) },
- { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 532.0f, 136.0f, 668.0f, 599.0f, 4.0f, 0.0f,
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -532.0f, -136.0f, -668.0f, -599.0f, 34.0f, 60.0f,
CVector(-172.0f, -619.0f, 44.0f), CVector(-183.0f, -623.0f, 44.0f), CVector(-511.0f, -645.0f, 41.0f), CVector(-493.0f, -639.0f, 41.5f) },
- { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 325.0f, 175.0f, 7.0f, 5.0f, 30.0f, 10.0f,
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -325.0f, -175.0f, 27.0f, 75.0f, -30.0f, -10.0f,
CVector(-185.0f, 40.8f, -20.5f), CVector(-202.0f, 37.0f, -20.5f), CVector(-315.0f, 65.5f, -20.5f), CVector(-306.0f, 62.4f, -20.5f) },
- { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 410.0f, 310.0f, 1055.0f, 1030.0f, 20.0f, 6.0f,
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -410.0f, -310.0f, -1055.0f, -1030.0f, -20.0f, -6.0f,
CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) },
- { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 425.0f, 280.0f, 471.0f, 447.0f, 20.0f, 5.0f,
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -425.0f, -280.0f, -471.0f, -447.0f, -20.0f, -5.0f,
CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) }
-}; // *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578;
-
-PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; // = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248;
-bool CPopulation::ms_bGivePedsWeapons; // = *(bool*)0x95CCF6;
-int32 CPopulation::m_AllRandomPedsThisType = -1; // = *(int32*)0x5FA570;
-float CPopulation::PedDensityMultiplier = 1.0f; // = *(float*)0x5FA56C;
-uint32 CPopulation::ms_nTotalMissionPeds; // = *(uint32*)0x8F5F70;
-int32 CPopulation::MaxNumberOfPedsInUse = 25; // *(int32*)0x5FA574;
-uint32 CPopulation::ms_nNumCivMale; // = *(uint32*)0x8F2548;
-uint32 CPopulation::ms_nNumCivFemale; // = *(uint32*)0x8F5F44;
-uint32 CPopulation::ms_nNumCop; // = *(uint32*)0x885AFC;
-bool CPopulation::bZoneChangeHasHappened; // = *(bool*)0x95CD79;
-uint32 CPopulation::ms_nNumEmergency; // = *(uint32*)0x94071C;
-int8 CPopulation::m_CountDownToPedsAtStart; // = *(int8*)0x95CD4F;
-uint32 CPopulation::ms_nNumGang1; // = *(uint32*)0x8F1B1C;
-uint32 CPopulation::ms_nNumGang2; // = *(uint32*)0x8F1B14;
-uint32 CPopulation::ms_nTotalPeds; // = *(uint32*)0x95CB50;
-uint32 CPopulation::ms_nNumGang3; // = *(uint32*)0x8F2548;
-uint32 CPopulation::ms_nTotalGangPeds; // = *(uint32*)0x885AF0;
-uint32 CPopulation::ms_nNumGang4; // = *(uint32*)0x8F1B2C;
-uint32 CPopulation::ms_nTotalCivPeds; // = *(uint32*)0x8F2C3C;
-uint32 CPopulation::ms_nNumGang5; // = *(uint32*)0x8F1B30;
-uint32 CPopulation::ms_nNumDummy; // = *(uint32*)0x8F1A98;
-uint32 CPopulation::ms_nNumGang6; // = *(uint32*)0x8F1B20;
-uint32 CPopulation::ms_nNumGang9; // = *(uint32*)0x8F1B10;
-uint32 CPopulation::ms_nNumGang7; // = *(uint32*)0x8F1B28;
-uint32 CPopulation::ms_nNumGang8; // = *(uint32*)0x8F1B0C;
-CVector CPopulation::RegenerationPoint_a; // = *(CVector*)0x8E2AA4;
-CVector CPopulation::RegenerationPoint_b; // = *(CVector*)0x8E2A98;
-CVector CPopulation::RegenerationForward; // = *(CVector*)0x8F1AD4;
+};
+
+PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
+bool CPopulation::ms_bGivePedsWeapons;
+int32 CPopulation::m_AllRandomPedsThisType = -1;
+float CPopulation::PedDensityMultiplier = 1.0f;
+uint32 CPopulation::ms_nTotalMissionPeds;
+int32 CPopulation::MaxNumberOfPedsInUse = 25;
+uint32 CPopulation::ms_nNumCivMale;
+uint32 CPopulation::ms_nNumCivFemale;
+uint32 CPopulation::ms_nNumCop;
+bool CPopulation::bZoneChangeHasHappened;
+uint32 CPopulation::ms_nNumEmergency;
+int8 CPopulation::m_CountDownToPedsAtStart;
+uint32 CPopulation::ms_nNumGang1;
+uint32 CPopulation::ms_nNumGang2;
+uint32 CPopulation::ms_nTotalPeds;
+uint32 CPopulation::ms_nNumGang3;
+uint32 CPopulation::ms_nTotalGangPeds;
+uint32 CPopulation::ms_nNumGang4;
+uint32 CPopulation::ms_nTotalCivPeds;
+uint32 CPopulation::ms_nNumGang5;
+uint32 CPopulation::ms_nNumDummy;
+uint32 CPopulation::ms_nNumGang6;
+uint32 CPopulation::ms_nNumGang9;
+uint32 CPopulation::ms_nNumGang7;
+uint32 CPopulation::ms_nNumGang8;
+CVector CPopulation::RegenerationPoint_a;
+CVector CPopulation::RegenerationPoint_b;
+CVector CPopulation::RegenerationForward;
void
CPopulation::Initialise()
@@ -595,7 +595,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
}
// Yeah, float
float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
- maxPossiblePedsForArea = min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
+ maxPossiblePedsForArea = Min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
if (ms_nTotalPeds < maxPossiblePedsForArea || addCop) {
int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
@@ -703,7 +703,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (!foundGround)
return;
- generatedCoors.z = max(generatedCoors.z, groundZ);
+ generatedCoors.z = Max(generatedCoors.z, groundZ);
}
bool farEnoughToAdd = true;
CMatrix mat(TheCamera.GetCameraMatrix());
@@ -1050,7 +1050,7 @@ CPopulation::TestSafeForRealObject(CDummyObject *dummy)
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
#endif
- static CColPoint aTempColPoints;
+ static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
for (int curY = minY; curY <= maxY; curY++) {
for (int curX = minX; curX <= maxX; curX++) {
@@ -1061,7 +1061,7 @@ CPopulation::TestSafeForRealObject(CDummyObject *dummy)
if (veh->m_scanCode != CWorld::GetCurrentScanCode()) {
if (veh->GetIsTouching(colCentre, colRadius)) {
veh->m_scanCode = CWorld::GetCurrentScanCode();
- if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), &aTempColPoints, nil, nil) > 0)
+ if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), aTempColPoints, nil, nil) > 0)
return false;
}
}
@@ -1072,7 +1072,7 @@ CPopulation::TestSafeForRealObject(CDummyObject *dummy)
if (veh->m_scanCode != CWorld::GetCurrentScanCode()) {
if (veh->GetIsTouching(colCentre, colRadius)) {
veh->m_scanCode = CWorld::GetCurrentScanCode();
- if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), &aTempColPoints, nil, nil) > 0)
+ if (CCollision::ProcessColModels(dummy->GetMatrix(), *dummyCol, veh->GetMatrix(), *veh->GetColModel(), aTempColPoints, nil, nil) > 0)
return false;
}
}
@@ -1180,16 +1180,3 @@ CPopulation::ManagePopulation(void)
}
}
}
-
-STARTPATCHES
- InjectHook(0x4F3770, &CPopulation::Initialise, PATCH_JUMP);
- InjectHook(0x4F5780, &CPopulation::ChooseGangOccupation, PATCH_JUMP);
- InjectHook(0x4F6200, &CPopulation::DealWithZoneChange, PATCH_JUMP);
- InjectHook(0x4F6010, &CPopulation::FindCollisionZoneForCoors, PATCH_JUMP);
- InjectHook(0x4F6410, &CPopulation::PedCreationDistMultiplier, PATCH_JUMP);
- InjectHook(0x4F5280, &CPopulation::AddPed, PATCH_JUMP);
- InjectHook(0x4F4470, &CPopulation::ConvertToRealObject, PATCH_JUMP);
- InjectHook(0x4F4690, &CPopulation::TestRoomForDummyObject, PATCH_JUMP);
- InjectHook(0x4F45A0, &CPopulation::ConvertToDummyObject, PATCH_JUMP);
- InjectHook(0x4F4410, &CPopulation::ConvertAllObjectsToDummyObjects, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Antennas.cpp b/src/render/Antennas.cpp
index d564c196..452069a0 100644
--- a/src/render/Antennas.cpp
+++ b/src/render/Antennas.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Antennas.h"
CAntenna CAntennas::aAntennas[NUMANTENNAS];
@@ -123,17 +123,3 @@ CAntenna::Update(CVector dir, CVector basepos)
pos[i] = newpos;
}
}
-
-STARTPATCHES
- InjectHook(0x4F64D0, &CAntennas::Init, PATCH_JUMP);
- InjectHook(0x4F6550, &CAntennas::Update, PATCH_JUMP);
- InjectHook(0x4F66C0, &CAntennas::RegisterOne, PATCH_JUMP);
- InjectHook(0x4F6590, &CAntennas::Render, PATCH_JUMP);
- InjectHook(0x4F6830, &CAntenna::Update, PATCH_JUMP);
-
- // give to cheetah for testing
-// Patch<int>(0x535B50+1, 105);
-// Patch<float>(0x535B57+7, -0.84);
-// Patch<float>(0x535B74+7, 0.78);
-// Patch<float>(0x535B69+7, 0.24);
-ENDPATCHES
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index 39866294..cb08a997 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Sprite.h"
#include "Sprite2d.h"
#include "General.h"
@@ -16,15 +16,15 @@
#define SMALLSTRIPHEIGHT 4.0f
#define HORIZSTRIPHEIGHT 48.0f
-RwTexture **gpCloudTex = (RwTexture**)0x9411C0; //[5];
+RwTexture *gpCloudTex[5];
-float &CClouds::CloudRotation = *(float*)0x8F5F40;
-uint32 &CClouds::IndividualRotation = *(uint32*)0x943078;
+float CClouds::CloudRotation;
+uint32 CClouds::IndividualRotation;
-float &CClouds::ms_cameraRoll = *(float*)0x8F29CC;
-float &CClouds::ms_horizonZ = *(float*)0x8F31C0;
-CRGBA &CClouds::ms_colourTop = *(CRGBA*)0x94143C;
-CRGBA &CClouds::ms_colourBottom = *(CRGBA*)0x8F2C38;
+float CClouds::ms_cameraRoll;
+float CClouds::ms_horizonZ;
+CRGBA CClouds::ms_colourTop;
+CRGBA CClouds::ms_colourBottom;
void
CClouds::Init(void)
@@ -233,7 +233,7 @@ CClouds::Render(void)
szx*55.0f, szy*55.0f,
tr, tg, tb, br, bg, bb, 0.0f, -1.0f,
1.0f/screenpos.z,
- IndividualRotation/65336.0f * 2*3.14f + ms_cameraRoll,
+ (uint16)IndividualRotation/65336.0f * 6.28f + ms_cameraRoll,
fluffyalpha);
bCloudOnScreen[i] = true;
}else
@@ -388,7 +388,7 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
ms_colourBottom.b = topblue;
ms_colourBottom.a = alpha;
- botpos = min(SCREEN_HEIGHT, topedge);
+ botpos = Min(SCREEN_HEIGHT, topedge);
CSprite2d::DrawRect(CRect(0, 0, SCREEN_WIDTH, botpos),
ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
}
@@ -415,27 +415,18 @@ CClouds::RenderHorizon(void)
if(ms_horizonZ > SCREEN_HEIGHT)
return;
- float z1 = min(ms_horizonZ + SMALLSTRIPHEIGHT, SCREEN_HEIGHT);
+ float z1 = Min(ms_horizonZ + SMALLSTRIPHEIGHT, SCREEN_HEIGHT);
CSprite2d::DrawRectXLU(CRect(0, ms_horizonZ, SCREEN_WIDTH, z1),
ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
// This is just weird
float a = SCREEN_HEIGHT/400.0f * HORIZSTRIPHEIGHT +
- SCREEN_HEIGHT/300.0f * max(TheCamera.GetPosition().z, 0.0f);
+ SCREEN_HEIGHT/300.0f * Max(TheCamera.GetPosition().z, 0.0f);
float b = TheCamera.GetUp().z < 0.0f ?
SCREEN_HEIGHT :
SCREEN_HEIGHT * Abs(TheCamera.GetRight().z);
float z2 = z1 + (a + b)*TheCamera.LODDistMultiplier;
- z2 = min(z2, SCREEN_HEIGHT);
+ z2 = Min(z2, SCREEN_HEIGHT);
CSprite2d::DrawRect(CRect(0, z1, SCREEN_WIDTH, z2),
ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
}
-
-STARTPATCHES
- InjectHook(0x4F6C10, CClouds::Init, PATCH_JUMP);
- InjectHook(0x4F6CA0, CClouds::Shutdown, PATCH_JUMP);
- InjectHook(0x4F6CE0, CClouds::Update, PATCH_JUMP);
- InjectHook(0x4F6D90, CClouds::Render, PATCH_JUMP);
- InjectHook(0x4F7F00, CClouds::RenderBackground, PATCH_JUMP);
- InjectHook(0x4F85F0, CClouds::RenderHorizon, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Clouds.h b/src/render/Clouds.h
index c8000569..4d8cd2c8 100644
--- a/src/render/Clouds.h
+++ b/src/render/Clouds.h
@@ -3,13 +3,13 @@
class CClouds
{
public:
- static float &CloudRotation;
- static uint32 &IndividualRotation;
+ static float CloudRotation;
+ static uint32 IndividualRotation;
- static float &ms_cameraRoll;
- static float &ms_horizonZ;
- static CRGBA &ms_colourTop;
- static CRGBA &ms_colourBottom;
+ static float ms_cameraRoll;
+ static float ms_horizonZ;
+ static CRGBA ms_colourTop;
+ static CRGBA ms_colourBottom;
static void Init(void);
static void Shutdown(void);
diff --git a/src/render/Console.cpp b/src/render/Console.cpp
index d4940955..5ae5d763 100644
--- a/src/render/Console.cpp
+++ b/src/render/Console.cpp
@@ -1,5 +1,6 @@
#include "common.h"
-#include "patcher.h"
+#include <stdarg.h>
+
#include "Console.h"
#include "Font.h"
#include "Timer.h"
@@ -8,7 +9,7 @@
#define CONSOLE_Y_POS (10.0f)
#define CONSOLE_LINE_HEIGHT (12.0f)
-CConsole &TheConsole = *(CConsole*)0x8F6498;
+CConsole TheConsole;
void
CConsole::AddLine(char *s, uint8 r, uint8 g, uint8 b)
diff --git a/src/render/Console.h b/src/render/Console.h
index c454d75e..b4fa60c4 100644
--- a/src/render/Console.h
+++ b/src/render/Console.h
@@ -22,4 +22,4 @@ public:
void Init() { m_nCurrentLine = 0; m_nLineCount = 0; }
};
-extern CConsole &TheConsole;
+extern CConsole TheConsole;
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index 68994b0b..de3b5c78 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "General.h"
#include "TxdStore.h"
@@ -48,16 +48,16 @@ FlareDef HeadLightsFlareDef[] = {
};
-RwTexture **gpCoronaTexture = (RwTexture**)0x5FAF44; //[9]
+RwTexture *gpCoronaTexture[9] = { nil, nil, nil, nil, nil, nil, nil, nil, nil };
-float &CCoronas::LightsMult = *(float*)0x5FB088; // 1.0
-float &CCoronas::SunScreenX = *(float*)0x8F4358;
-float &CCoronas::SunScreenY = *(float*)0x8F4354;
-bool &CCoronas::bSmallMoon = *(bool*)0x95CD49;
-bool &CCoronas::SunBlockedByClouds = *(bool*)0x95CD73;
-int &CCoronas::bChangeBrightnessImmediately = *(int*)0x8E2C30;
+float CCoronas::LightsMult = 1.0f;
+float CCoronas::SunScreenX;
+float CCoronas::SunScreenY;
+bool CCoronas::bSmallMoon;
+bool CCoronas::SunBlockedByClouds;
+int CCoronas::bChangeBrightnessImmediately;
-CRegisteredCorona *CCoronas::aCoronas = (CRegisteredCorona*)0x72E518;
+CRegisteredCorona CCoronas::aCoronas[NUMCORONAS];
const char aCoronaSpriteNames[][32] = {
"coronastar",
@@ -106,7 +106,7 @@ CCoronas::Update(void)
int i;
static int LastCamLook = 0;
- LightsMult = min(LightsMult + 0.03f * CTimer::GetTimeStep(), 1.0f);
+ LightsMult = Min(LightsMult + 0.03f * CTimer::GetTimeStep(), 1.0f);
int CamLook = 0;
if(TheCamera.Cams[TheCamera.ActiveCam].LookingLeft) CamLook |= 1;
@@ -118,7 +118,7 @@ CCoronas::Update(void)
if(LastCamLook != CamLook)
bChangeBrightnessImmediately = 3;
else
- bChangeBrightnessImmediately = max(bChangeBrightnessImmediately-1, 0);
+ bChangeBrightnessImmediately = Max(bChangeBrightnessImmediately-1, 0);
LastCamLook = CamLook;
for(i = 0; i < NUMCORONAS; i++)
@@ -305,7 +305,7 @@ CCoronas::Render(void)
// render corona itself
if(aCoronas[i].texture){
- float fogscale = CWeather::Foggyness*min(spriteCoors.z, 40.0f)/40.0f + 1.0f;
+ float fogscale = CWeather::Foggyness*Min(spriteCoors.z, 40.0f)/40.0f + 1.0f;
if(CCoronas::aCoronas[i].id == SUN_CORE)
spriteCoors.z = 0.95f * RwCameraGetFarClipPlane(Scene.camera);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(aCoronas[i].texture));
@@ -316,7 +316,7 @@ CCoronas::Render(void)
float f = 1.0f - aCoronas[i].someAngle*2.0f/PI;
float wscale = 6.0f*sq(sq(sq(f))) + 0.5f;
float hscale = 0.35f - (wscale - 0.5f) * 0.06f;
- hscale = max(hscale, 0.15f);
+ hscale = Max(hscale, 0.15f);
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * wscale,
@@ -466,7 +466,7 @@ CCoronas::RenderReflections(void)
float spritew, spriteh;
if(CSprite::CalcScreenCoors(coors, spriteCoors, &spritew, &spriteh, true)){
float drawDist = 0.75f * aCoronas[i].drawDist;
- drawDist = min(drawDist, 50.0f);
+ drawDist = Min(drawDist, 50.0f);
if(spriteCoors.z < drawDist){
float fadeDistance = drawDist / 2.0f;
float distanceFade = spriteCoors.z < fadeDistance ? 1.0f : 1.0f - (spriteCoors.z - fadeDistance)/fadeDistance;
@@ -545,25 +545,25 @@ CRegisteredCorona::Update(void)
(CCoronas::SunBlockedByClouds && id == CCoronas::SUN_CORONA ||
!CWorld::GetIsLineOfSightClear(coors, TheCamera.GetPosition(), true, false, false, false, false, false))){
// Corona is blocked, fade out
- fadeAlpha = max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), 0.0f);
+ fadeAlpha = Max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), 0.0f);
}else if(offScreen){
// Same when off screen
- fadeAlpha = max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), 0.0f);
+ fadeAlpha = Max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), 0.0f);
}else{
// Visible
if(alpha > fadeAlpha){
// fade in
- fadeAlpha = min(fadeAlpha + 15.0f*CTimer::GetTimeStep(), alpha);
+ fadeAlpha = Min(fadeAlpha + 15.0f*CTimer::GetTimeStep(), alpha);
if(CCoronas::bChangeBrightnessImmediately)
fadeAlpha = alpha;
}else if(alpha < fadeAlpha){
// too visible, decrease alpha but not below alpha
- fadeAlpha = max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), alpha);
+ fadeAlpha = Max(fadeAlpha - 15.0f*CTimer::GetTimeStep(), alpha);
}
// darken scene when the sun is visible
if(id == CCoronas::SUN_CORONA)
- CCoronas::LightsMult = max(CCoronas::LightsMult - CTimer::GetTimeStep()*0.06f, 0.6f);
+ CCoronas::LightsMult = Max(CCoronas::LightsMult - CTimer::GetTimeStep()*0.06f, 0.6f);
}
// remove if invisible
@@ -572,17 +572,3 @@ CRegisteredCorona::Update(void)
firstUpdate = false;
registeredThisFrame = false;
}
-
-STARTPATCHES
- InjectHook(0x4F9F90, CCoronas::Init, PATCH_JUMP);
- InjectHook(0x4FA050, CCoronas::Shutdown, PATCH_JUMP);
- InjectHook(0x4F8EC0, CCoronas::Update, PATCH_JUMP);
- InjectHook(0x4FA0E0, (void (*)(uint32, uint8, uint8, uint8, uint8, const CVector&, float, float, RwTexture*, int8, uint8, uint8, uint8, float))CCoronas::RegisterCorona, PATCH_JUMP);
- InjectHook(0x4FA080, (void (*)(uint32, uint8, uint8, uint8, uint8, const CVector&, float, float, uint8, int8, uint8, uint8, uint8, float))CCoronas::RegisterCorona, PATCH_JUMP);
- InjectHook(0x4FA2D0, CCoronas::UpdateCoronaCoors, PATCH_JUMP);
- InjectHook(0x4F8FB0, CCoronas::Render, PATCH_JUMP);
- InjectHook(0x4F9B40, CCoronas::RenderReflections, PATCH_JUMP);
- InjectHook(0x4FA380, CCoronas::DoSunAndMoon, PATCH_JUMP);
-
- InjectHook(0x4F8C40, &CRegisteredCorona::Update, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Coronas.h b/src/render/Coronas.h
index 359a34ed..4b49e40e 100644
--- a/src/render/Coronas.h
+++ b/src/render/Coronas.h
@@ -1,6 +1,6 @@
#pragma once
-extern RwTexture **gpCoronaTexture; //[9]
+extern RwTexture *gpCoronaTexture[9];
struct CRegisteredCorona
{
@@ -42,7 +42,7 @@ static_assert(sizeof(CRegisteredCorona) == 0x80, "CRegisteredCorona: error");
class CCoronas
{
- static CRegisteredCorona *aCoronas; //[NUMCORONAS];
+ static CRegisteredCorona aCoronas[NUMCORONAS];
public:
enum {
SUN_CORE = 1,
@@ -77,12 +77,12 @@ public:
STREAK_ON,
};
- static float &LightsMult;
- static float &SunScreenY;
- static float &SunScreenX;
- static bool &bSmallMoon;
- static bool &SunBlockedByClouds;
- static int &bChangeBrightnessImmediately;
+ static float LightsMult;
+ static float SunScreenY;
+ static float SunScreenX;
+ static bool bSmallMoon;
+ static bool SunBlockedByClouds;
+ static int bChangeBrightnessImmediately;
static void Init(void);
static void Shutdown(void);
diff --git a/src/render/Credits.cpp b/src/render/Credits.cpp
index b423fcc0..dc0b0252 100644
--- a/src/render/Credits.cpp
+++ b/src/render/Credits.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Timer.h"
#include "Font.h"
#include "Frontend.h"
@@ -8,8 +8,8 @@
#include "Text.h"
#include "Credits.h"
-bool &CCredits::bCreditsGoing = *(bool*)0x95CDD3;
-uint32 &CCredits::CreditsStartTime = *(uint32*)0x8F2528;
+bool CCredits::bCreditsGoing;
+uint32 CCredits::CreditsStartTime;
void
CCredits::Init(void)
@@ -497,13 +497,3 @@ bool CCredits::AreCreditsDone(void)
{
return !bCreditsGoing;
}
-
-STARTPATCHES
- InjectHook(0x4FE7A0, CCredits::Init, PATCH_JUMP);
- InjectHook(0x4FE760, CCredits::Start, PATCH_JUMP);
- InjectHook(0x4FE780, CCredits::Stop, PATCH_JUMP);
- InjectHook(0x4FE790, CCredits::AreCreditsDone, PATCH_JUMP);
- InjectHook(0x4FADF0, CCredits::Render, PATCH_JUMP);
- InjectHook(0x4FE710, CCredits::PrintCreditSpace, PATCH_JUMP);
- InjectHook(0x4FE620, CCredits::PrintCreditText, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Credits.h b/src/render/Credits.h
index c39fb035..e049ce76 100644
--- a/src/render/Credits.h
+++ b/src/render/Credits.h
@@ -2,8 +2,8 @@
class CCredits
{
- static bool &bCreditsGoing;
- static uint32 &CreditsStartTime;
+ static bool bCreditsGoing;
+ static uint32 CreditsStartTime;
public:
static void Init(void);
static void Start(void);
diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp
index 862fc024..b31cc624 100644
--- a/src/render/Draw.cpp
+++ b/src/render/Draw.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Draw.h"
#include "Frontend.h"
#include "Camera.h"
@@ -8,15 +8,15 @@
float CDraw::ms_fAspectRatio = DEFAULT_ASPECT_RATIO;
#endif
-float &CDraw::ms_fNearClipZ = *(float*)0x8E2DC4;
-float &CDraw::ms_fFarClipZ = *(float*)0x9434F0;
-float &CDraw::ms_fFOV = *(float*)0x5FBC6C;
-float &CDraw::ms_fLODDistance = *(float*)0x8F2C30;
+float CDraw::ms_fNearClipZ;
+float CDraw::ms_fFarClipZ;
+float CDraw::ms_fFOV = 45.0f;
+float CDraw::ms_fLODDistance;
-uint8 &CDraw::FadeValue = *(uint8*)0x95CD68;
-uint8 &CDraw::FadeRed = *(uint8*)0x95CD90;
-uint8 &CDraw::FadeGreen = *(uint8*)0x95CD71;
-uint8 &CDraw::FadeBlue = *(uint8*)0x95CD53;
+uint8 CDraw::FadeValue;
+uint8 CDraw::FadeRed;
+uint8 CDraw::FadeGreen;
+uint8 CDraw::FadeBlue;
float
CDraw::FindAspectRatio(void)
@@ -66,10 +66,3 @@ CDraw::SetFOV(float fov)
ms_fFOV = fov;
#endif
}
-
-STARTPATCHES
- InjectHook(0x4FE7B0, CDraw::SetFOV, PATCH_JUMP);
-
- Nop(0x46B618, 2);
- Patch<float>(0x5F0A64, 1.3333334f);
-ENDPATCHES
diff --git a/src/render/Draw.h b/src/render/Draw.h
index 50e1e294..55958a2a 100644
--- a/src/render/Draw.h
+++ b/src/render/Draw.h
@@ -13,11 +13,11 @@ enum eAspectRatio
class CDraw
{
private:
- static float &ms_fNearClipZ;
- static float &ms_fFarClipZ;
- static float &ms_fFOV;
+ static float ms_fNearClipZ;
+ static float ms_fFarClipZ;
+ static float ms_fFOV;
public:
- static float &ms_fLODDistance; // set but unused?
+ static float ms_fLODDistance; // set but unused?
#ifdef ASPECT_RATIO_SCALE
// we use this variable to scale a lot of 2D elements
@@ -25,10 +25,10 @@ public:
static float ms_fAspectRatio;
#endif
- static uint8 &FadeValue;
- static uint8 &FadeRed;
- static uint8 &FadeGreen;
- static uint8 &FadeBlue;
+ static uint8 FadeValue;
+ static uint8 FadeRed;
+ static uint8 FadeGreen;
+ static uint8 FadeBlue;
static void SetNearClipZ(float nearclip) { ms_fNearClipZ = nearclip; }
static float GetNearClipZ(void) { return ms_fNearClipZ; }
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index e2899532..9f3f6929 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "Entity.h"
#include "Fluff.h"
#include "Camera.h"
@@ -159,12 +159,12 @@ void CMovingThings::Update()
int block = CTimer::GetFrameCounter() % TIME_SPAN;
for (i = (block * NUMMOVINGTHINGS) / TIME_SPAN; i < ((block + 1) * NUMMOVINGTHINGS) / TIME_SPAN; i++) {
- if (aMovingThings[i].field_A == 1)
+ if (aMovingThings[i].m_nHidden == 1)
aMovingThings[i].Update();
}
for (i = 0; i < CMovingThings::Num; i++) {
- if (aMovingThings[i].field_A == 0)
+ if (aMovingThings[i].m_nHidden == 0)
aMovingThings[i].Update();
}
@@ -212,14 +212,14 @@ void CMovingThing::Update()
m_pEntity->UpdateRwFrame();
if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) < 40000.0f) {
- if (field_A == 1) {
+ if (m_nHidden == 1) {
AddToList(&CMovingThings::StartCloseList);
- field_A = 0;
+ m_nHidden = 0;
}
} else {
- if (field_A == 0) {
+ if (m_nHidden == 0) {
RemoveFromList();
- field_A = 1;
+ m_nHidden = 1;
}
}
}
@@ -864,31 +864,3 @@ void CDigitalClock::Render()
CSprite::FlushSpriteBuffer();
}
}
-
-STARTPATCHES
-InjectHook(0x4FF290, &CMovingThing::Update, PATCH_JUMP);
-InjectHook(0x4FF320, &CMovingThing::AddToList, PATCH_JUMP);
-InjectHook(0x4FF340, &CMovingThing::RemoveFromList, PATCH_JUMP);
-
-InjectHook(0x4FE7C0, &CMovingThings::Init, PATCH_JUMP);
-InjectHook(0x4FF020, &CMovingThings::Shutdown, PATCH_JUMP);
-InjectHook(0x4FF0D0, &CMovingThings::Update, PATCH_JUMP);
-InjectHook(0x4FF210, &CMovingThings::Render, PATCH_JUMP);
-
-InjectHook(0x4FF360, &FindTunnelMessage, PATCH_JUMP);
-InjectHook(0x4FF390, &FindBridgeMessage, PATCH_JUMP);
-InjectHook(0x4FF3C0, &FindTimeMessage, PATCH_JUMP);
-InjectHook(0x4FF450, &FindDigitalClockMessage, PATCH_JUMP);
-
-InjectHook(0x4FF610, &CScrollBar::Init, PATCH_JUMP);
-InjectHook(0x4FF6E0, &CScrollBar::Update, PATCH_JUMP);
-InjectHook(0x4FFCE0, &CScrollBar::Render, PATCH_JUMP);
-
-InjectHook(0x5000D0, &CTowerClock::Init, PATCH_JUMP);
-InjectHook(0x500130, &CTowerClock::Update, PATCH_JUMP);
-InjectHook(0x5001D0, &CTowerClock::Render, PATCH_JUMP);
-
-InjectHook(0x5004F0, &CDigitalClock::Init, PATCH_JUMP);
-InjectHook(0x500550, &CDigitalClock::Update, PATCH_JUMP);
-InjectHook(0x5005F0, &CDigitalClock::Render, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Fluff.h b/src/render/Fluff.h
index 7ab2d81d..fe3ab256 100644
--- a/src/render/Fluff.h
+++ b/src/render/Fluff.h
@@ -8,7 +8,7 @@ public:
CMovingThing *m_pNext;
CMovingThing *m_pPrev;
int16 m_nType;
- int16 field_A;
+ int16 m_nHidden;
CVector m_vecPosn;
CEntity* m_pEntity;
diff --git a/src/render/Font.cpp b/src/render/Font.cpp
index 6067a020..458974ae 100644
--- a/src/render/Font.cpp
+++ b/src/render/Font.cpp
@@ -1,26 +1,22 @@
#include "common.h"
-#include "patcher.h"
+
#include "Sprite2d.h"
#include "TxdStore.h"
#include "Font.h"
-CFontDetails &CFont::Details = *(CFontDetails*)0x8F317C;
-int16 &CFont::NewLine = *(int16*)0x95CC94;
-#ifdef MORE_LANGUAGES
-CSprite2d CFont::Sprite[4];
-#else
-CSprite2d *CFont::Sprite = (CSprite2d*)0x95CC04;
-#endif
+CFontDetails CFont::Details;
+int16 CFont::NewLine;
+CSprite2d CFont::Sprite[MAX_FONTS];
#ifdef MORE_LANGUAGES
uint8 CFont::LanguageSet = FONT_LANGSET_EFIGS;
int32 CFont::Slot = -1;
#define JAP_TERMINATION (0x8000 | '~')
-int16 CFont::Size[2][3][193] = {
+int16 CFont::Size[LANGSET_MAX][MAX_FONTS][193] = {
{
#else
-int16 CFont::Size[3][193] = {
+int16 CFont::Size[MAX_FONTS][193] = {
#endif
{
13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17, 13, 31,
@@ -117,6 +113,56 @@ int16 CFont::Size[3][193] = {
21, 32, 21, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 11, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19 },
+ },
+
+ {
+ {
+ 13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17, 13, 31,
+ 23, 16, 22, 21, 24, 23, 23, 20, 23, 22, 10, 35, 26, 26, 26, 26,
+ 30, 26, 24, 23, 24, 22, 21, 24, 26, 10, 20, 26, 22, 29, 26, 25,
+ 23, 25, 24, 24, 22, 25, 24, 29, 29, 23, 25, 37, 22, 37, 35, 37,
+ 35, 21, 22, 21, 21, 22, 13, 22, 21, 10, 16, 22, 11, 32, 21, 21,
+ 23, 22, 16, 20, 14, 21, 20, 30, 25, 21, 21, 33, 33, 33, 33, 35,
+ 27, 27, 27, 27, 32, 24, 23, 23, 23, 23, 11, 11, 11, 11, 26, 26,
+ 26, 26, 26, 26, 26, 25, 26, 21, 21, 21, 21, 32, 23, 22, 22, 22,
+ 22, 11, 11, 11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 26, 21, 24,
+ 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 18, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 20
+ },
+
+ {
+ 13, 9, 21, 35, 23, 35, 35, 11, 35, 35, 25, 35, 11, 17, 13, 33,
+ 28, 14, 22, 21, 24, 23, 23, 21, 23, 22, 10, 35, 13, 35, 13, 33,
+ 5, 25, 22, 23, 24, 21, 21, 24, 24, 9, 20, 24, 21, 27, 25, 25,
+ 22, 25, 23, 20, 23, 23, 23, 31, 23, 23, 23, 37, 33, 37, 35, 37,
+ 35, 21, 19, 19, 21, 19, 17, 21, 21, 8, 17, 18, 14, 24, 21, 21,
+ 20, 22, 19, 20, 20, 19, 20, 26, 21, 20, 21, 33, 33, 33, 33, 35,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 16
+ },
+
+ {
+ 15, 14, 16, 25, 19, 26, 22, 11, 18, 18, 27, 26, 13, 19, 9, 27,
+ 19, 18, 19, 19, 22, 19, 20, 18, 19, 20, 12, 32, 15, 32, 15, 35,
+ 15, 19, 19, 19, 19, 19, 16, 19, 20, 9, 19, 20, 14, 29, 19, 20,
+ 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19, 33, 31, 39, 37, 39,
+ 37, 21, 21, 21, 23, 21, 19, 23, 23, 10, 19, 20, 16, 26, 23, 23,
+ 20, 20, 20, 22, 21, 22, 22, 26, 22, 22, 23, 35, 35, 35, 35, 37,
+ 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, 9, 9, 9, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 30, 19, 19, 19, 19,
+ 19, 10, 10, 10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35,
+ 12, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19
+ }
}
#endif
};
@@ -164,6 +210,9 @@ CFont::Initialise(void)
default:
CTxdStore::LoadTxd(slot, "MODELS/FONTS.TXD");
break;
+ case FONT_LANGSET_POLISH:
+ CTxdStore::LoadTxd(slot, "MODELS/FONTS_P.TXD");
+ break;
case FONT_LANGSET_RUSSIAN:
CTxdStore::LoadTxd(slot, "MODELS/FONTS_R.TXD");
break;
@@ -222,6 +271,9 @@ CFont::ReloadFonts(uint8 set)
default:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS.TXD");
break;
+ case FONT_LANGSET_POLISH:
+ CTxdStore::LoadTxd(Slot, "MODELS/FONTS_P.TXD");
+ break;
case FONT_LANGSET_RUSSIAN:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS_R.TXD");
break;
@@ -1427,48 +1479,3 @@ CFont::SetDropColor(const CRGBA &col)
if (Details.alphaFade < 255.0f)
Details.dropColor.a *= Details.alphaFade / 255.0f;
}
-
-STARTPATCHES
-
- InjectHook(0x500A40, CFont::Initialise, PATCH_JUMP);
- InjectHook(0x500BA0, CFont::Shutdown, PATCH_JUMP);
- InjectHook(0x500BE0, CFont::InitPerFrame, PATCH_JUMP);
- InjectHook(0x500C30, CFont::PrintChar, PATCH_JUMP);
- InjectHook(0x500F50, (void (*)(float, float, wchar*))CFont::PrintString, PATCH_JUMP);
- InjectHook(0x501260, CFont::GetNumberLines, PATCH_JUMP);
- InjectHook(0x5013B0, CFont::GetTextRect, PATCH_JUMP);
- //InjectHook(0x501730, (void (*)(float, float, wchar*, wchar*, float))CFont::PrintString, PATCH_JUMP);
- InjectHook(0x5017E0, CFont::GetCharacterWidth, PATCH_JUMP);
- InjectHook(0x501840, CFont::GetCharacterSize, PATCH_JUMP);
- InjectHook(0x5018A0, CFont::GetStringWidth, PATCH_JUMP);
- InjectHook(0x501960, CFont::GetNextSpace, PATCH_JUMP);
- InjectHook(0x5019A0, CFont::ParseToken, PATCH_JUMP);
- InjectHook(0x501B50, CFont::DrawFonts, PATCH_JUMP);
- InjectHook(0x501E80, CFont::character_code, PATCH_JUMP);
-
- InjectHook(0x501B80, CFont::SetScale, PATCH_JUMP);
- InjectHook(0x501BA0, CFont::SetSlantRefPoint, PATCH_JUMP);
- InjectHook(0x501BC0, CFont::SetSlant, PATCH_JUMP);
- InjectHook(0x501BD0, CFont::SetColor, PATCH_JUMP);
- InjectHook(0x501C60, CFont::SetJustifyOn, PATCH_JUMP);
- InjectHook(0x501C80, CFont::SetJustifyOff, PATCH_JUMP);
- InjectHook(0x501C90, CFont::SetCentreOn, PATCH_JUMP);
- InjectHook(0x501CB0, CFont::SetCentreOff, PATCH_JUMP);
- InjectHook(0x501CC0, CFont::SetWrapx, PATCH_JUMP);
- InjectHook(0x501CD0, CFont::SetCentreSize, PATCH_JUMP);
- InjectHook(0x501CE0, CFont::SetBackgroundOn, PATCH_JUMP);
- InjectHook(0x501CF0, CFont::SetBackgroundOff, PATCH_JUMP);
- InjectHook(0x501D00, CFont::SetBackgroundColor, PATCH_JUMP);
- InjectHook(0x501D30, CFont::SetBackGroundOnlyTextOn, PATCH_JUMP);
- InjectHook(0x501D40, CFont::SetBackGroundOnlyTextOff, PATCH_JUMP);
- InjectHook(0x501D50, CFont::SetRightJustifyOn, PATCH_JUMP);
- InjectHook(0x501D70, CFont::SetRightJustifyOff, PATCH_JUMP);
- InjectHook(0x501D90, CFont::SetPropOff, PATCH_JUMP);
- InjectHook(0x501DA0, CFont::SetPropOn, PATCH_JUMP);
- InjectHook(0x501DB0, CFont::SetFontStyle, PATCH_JUMP);
- InjectHook(0x501DC0, CFont::SetRightJustifyWrap, PATCH_JUMP);
- InjectHook(0x501DD0, CFont::SetAlphaFade, PATCH_JUMP);
- InjectHook(0x501DE0, CFont::SetDropColor, PATCH_JUMP);
- InjectHook(0x501E70, CFont::SetDropShadowPosition, PATCH_JUMP);
-
-ENDPATCHES
diff --git a/src/render/Font.h b/src/render/Font.h
index 7c1d089f..73e9522a 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -34,6 +34,7 @@ enum {
#ifdef MORE_LANGUAGES
FONT_JAPANESE,
#endif
+ MAX_FONTS
};
enum {
@@ -47,7 +48,9 @@ enum
{
FONT_LANGSET_EFIGS,
FONT_LANGSET_RUSSIAN,
+ FONT_LANGSET_POLISH,
FONT_LANGSET_JAPANESE
+ LANGSET_MAX
};
#endif
@@ -56,19 +59,20 @@ enum
class CFont
{
#ifdef MORE_LANGUAGES
- static int16 Size[2][3][193];
+ static int16 Size[LANGSET_MAX][MAX_FONTS][193];
public:
static uint8 LanguageSet;
private:
static int32 Slot;
static CSprite2d Sprite[4];
#else
- static int16 Size[3][193];
+ static int16 Size[MAX_FONTS][193];
static CSprite2d* Sprite; //[3]
#endif
- static int16 &NewLine;
+ static int16 NewLine;
+ static CSprite2d Sprite[MAX_FONTS];
public:
- static CFontDetails& Details;
+ static CFontDetails Details;
static void Initialise(void);
static void Shutdown(void);
diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp
index 41d31985..9a4dbcfe 100644
--- a/src/render/Glass.cpp
+++ b/src/render/Glass.cpp
@@ -1,12 +1,12 @@
#include "common.h"
-#include "patcher.h"
+
#include "Glass.h"
#include "Timer.h"
#include "Object.h"
#include "General.h"
#include "AudioScriptObject.h"
#include "World.h"
-#include "TimeCycle.h"
+#include "Timecycle.h"
#include "Particle.h"
#include "Camera.h"
#include "RenderBuffer.h"
@@ -404,6 +404,7 @@ CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity)
void
CGlass::RenderEntityInGlass(CEntity *entity)
{
+ ASSERT(entity!=nil);
CObject *object = (CObject *)entity;
if ( object->bGlassBroken )
@@ -419,7 +420,7 @@ CGlass::RenderEntityInGlass(CEntity *entity)
uint8 alpha = CalcAlphaWithNormal(&fwdNorm);
CColModel *col = object->GetColModel();
-
+ ASSERT(col!=nil);
if ( col->numTriangles >= 2 )
{
CVector a = object->GetMatrix() * col->vertices[0];
@@ -523,6 +524,8 @@ CGlass::RenderEntityInGlass(CEntity *entity)
int32
CGlass::CalcAlphaWithNormal(CVector *normal)
{
+ ASSERT(normal!=nil);
+
float fwdDir = 2.0f * DotProduct(*normal, TheCamera.GetForward());
float fwdDot = DotProduct(TheCamera.GetForward()-fwdDir*(*normal), CVector(0.57f, 0.57f, -0.57f));
return int32(lerp(fwdDot*fwdDot*fwdDot*fwdDot*fwdDot*fwdDot, 20.0f, 255.0f));
@@ -597,6 +600,8 @@ CGlass::RenderReflectionPolys(void)
void
CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CVector point, bool explosion)
{
+ ASSERT(entity!=nil);
+
CObject *object = (CObject *)entity;
if ( object->bGlassBroken )
@@ -605,18 +610,19 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed,
object->bGlassCracked = true;
CColModel *col = object->GetColModel();
-
+ ASSERT(col!=nil);
+
CVector a = object->GetMatrix() * col->vertices[0];
CVector b = object->GetMatrix() * col->vertices[1];
CVector c = object->GetMatrix() * col->vertices[2];
CVector d = object->GetMatrix() * col->vertices[3];
- float minx = min(min(a.x, b.x), min(c.x, d.x));
- float maxx = max(max(a.x, b.x), max(c.x, d.x));
- float miny = min(min(a.y, b.y), min(c.y, d.y));
- float maxy = max(max(a.y, b.y), max(c.y, d.y));
- float minz = min(min(a.z, b.z), min(c.z, d.z));
- float maxz = max(max(a.z, b.z), max(c.z, d.z));
+ float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
+ float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
+ float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
+ float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
+ float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
+ float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
if ( amount > 300.0f )
@@ -647,6 +653,8 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed,
void
CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
{
+ ASSERT(entity!=nil);
+
CObject *object = (CObject *)entity;
if ( amount > 50.0f && !object->bGlassCracked )
@@ -659,6 +667,8 @@ CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
void
CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
{
+ ASSERT(entity!=nil);
+
CObject *object = (CObject *)entity;
if ( IsGlass(object->GetModelIndex()) )
@@ -679,6 +689,8 @@ CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
void
CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
{
+ ASSERT(entity!=nil);
+
CObject *object = (CObject *)entity;
CVector distToGlass = object->GetPosition() - point;
@@ -696,26 +708,3 @@ CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
object->bGlassCracked = true;
}
}
-
-STARTPATCHES
- InjectHook(0x501F20, CGlass::Init, PATCH_JUMP);
- InjectHook(0x502050, CGlass::Update, PATCH_JUMP);
- InjectHook(0x502080, &CFallingGlassPane::Update, PATCH_JUMP);
- InjectHook(0x502350, CGlass::Render, PATCH_JUMP);
- InjectHook(0x502490, CGlass::FindFreePane, PATCH_JUMP);
- InjectHook(0x5024C0, &CFallingGlassPane::Render, PATCH_JUMP);
- InjectHook(0x502AC0, CGlass::GeneratePanesForWindow, PATCH_JUMP);
- InjectHook(0x5033F0, CGlass::AskForObjectToBeRenderedInGlass, PATCH_JUMP);
- InjectHook(0x503420, CGlass::RenderEntityInGlass, PATCH_JUMP);
- InjectHook(0x503C90, CGlass::CalcAlphaWithNormal, PATCH_JUMP);
- InjectHook(0x503D60, CGlass::RenderHiLightPolys, PATCH_JUMP);
- InjectHook(0x503DE0, CGlass::RenderShatteredPolys, PATCH_JUMP);
- InjectHook(0x503E70, CGlass::RenderReflectionPolys, PATCH_JUMP);
- InjectHook(0x503F10, CGlass::WindowRespondsToCollision, PATCH_JUMP);
- InjectHook(0x504630, CGlass::WindowRespondsToSoftCollision, PATCH_JUMP);
- InjectHook(0x504670, CGlass::WasGlassHitByBullet, PATCH_JUMP);
- InjectHook(0x504790, CGlass::WindowRespondsToExplosion, PATCH_JUMP);
- //InjectHook(0x504880, `global constructor keyed to'glass.cpp, PATCH_JUMP);
- //InjectHook(0x5048D0, CFallingGlassPane::~CFallingGlassPane, PATCH_JUMP);
- //InjectHook(0x5048E0, CFallingGlassPane::CFallingGlassPane, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Glass.h b/src/render/Glass.h
index dccd9d3d..51c5aae9 100644
--- a/src/render/Glass.h
+++ b/src/render/Glass.h
@@ -13,7 +13,6 @@ public:
uint8 m_nTriIndex;
bool m_bActive;
bool m_bShattered;
- char _pad0[1];
CFallingGlassPane() { }
~CFallingGlassPane() { }
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index a2db6640..a2a74109 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Camera.h"
#include "DMAudio.h"
#include "Clock.h"
@@ -21,52 +21,52 @@
#include "User.h"
#include "World.h"
-wchar CHud::m_HelpMessage[256]; // = (wchar*)0x86B888;
-wchar CHud::m_LastHelpMessage[256]; // = (wchar*)0x6E8F28;
-uint32 CHud::m_HelpMessageState; // = *(int32*)0x880E1C;
-uint32 CHud::m_HelpMessageTimer; // = *(int32*)0x880FA4;
-int32 CHud::m_HelpMessageFadeTimer; // = *(int32*)0x8F6258;
-wchar CHud::m_HelpMessageToPrint[256]; // = (wchar*)0x664480;
-float CHud::m_fHelpMessageTime; // *(float *)0x8E2C28;
-bool CHud::m_HelpMessageQuick; // = *(bool*)0x95CCF7;
-uint32 CHud::m_ZoneState; // = *(int32*)0x8F29AC;
+wchar CHud::m_HelpMessage[256];
+wchar CHud::m_LastHelpMessage[256];
+uint32 CHud::m_HelpMessageState;
+uint32 CHud::m_HelpMessageTimer;
+int32 CHud::m_HelpMessageFadeTimer;
+wchar CHud::m_HelpMessageToPrint[256];
+float CHud::m_fHelpMessageTime;
+bool CHud::m_HelpMessageQuick;
+uint32 CHud::m_ZoneState;
int32 CHud::m_ZoneFadeTimer;
-uint32 CHud::m_ZoneNameTimer; // = *(int32*)0x8F1A50;
-wchar *CHud::m_pZoneName; // = *(wchar**)0x8E2C2C;
-wchar *CHud::m_pLastZoneName; // = (wchar*)0x8F432C;
+uint32 CHud::m_ZoneNameTimer;
+wchar *CHud::m_pZoneName;
+wchar *CHud::m_pLastZoneName;
wchar *CHud::m_ZoneToPrint;
-uint32 CHud::m_VehicleState; // = *(int32*)0x940560;
+uint32 CHud::m_VehicleState;
int32 CHud::m_VehicleFadeTimer;
-uint32 CHud::m_VehicleNameTimer; // = *(int32*)0x8F2A14;
-wchar *CHud::m_VehicleName; // = *(wchar**)0x942FB4;
-wchar *CHud::m_pLastVehicleName; // = *(wchar**)0x8E2DD8;
+uint32 CHud::m_VehicleNameTimer;
+wchar *CHud::m_VehicleName;
+wchar *CHud::m_pLastVehicleName;
wchar *CHud::m_pVehicleNameToPrint;
-wchar CHud::m_Message[256];// = (wchar*)0x72E318;
-wchar CHud::m_PagerMessage[256]; // = (wchar*)0x878840;
-bool CHud::m_Wants_To_Draw_Hud; // (bool*)0x95CD89;
-bool CHud::m_Wants_To_Draw_3dMarkers; // = *(bool*)0x95CD62;
-wchar CHud::m_BigMessage[6][128]; // = *(wchar(*)[6][128]) * (uintptr*)0x664CE0;
-int16 CHud::m_ItemToFlash; // = *(int16*)0x95CC82;
+wchar CHud::m_Message[256];
+wchar CHud::m_PagerMessage[256];
+bool CHud::m_Wants_To_Draw_Hud;
+bool CHud::m_Wants_To_Draw_3dMarkers;
+wchar CHud::m_BigMessage[6][128];
+int16 CHud::m_ItemToFlash;
// These aren't really in CHud
float CHud::BigMessageInUse[6];
float CHud::BigMessageAlpha[6];
float CHud::BigMessageX[6];
-float CHud::OddJob2OffTimer; // = *(float*)0x942FA0;
-bool CHud::CounterOnLastFrame; // = *(int8*)0x95CD67;
-float CHud::OddJob2XOffset; // = *(float*)0x8F1B5C;
-uint16 CHud::CounterFlashTimer; // = *(int16*)0x95CC20;
-uint16 CHud::OddJob2Timer; // = *(int16*)0x95CC52;
-bool CHud::TimerOnLastFrame; //= *(int8*)0x95CDA7;
-int16 CHud::OddJob2On; //= *(int16*)0x95CC78;
-uint16 CHud::TimerFlashTimer; //= *(int16*)0x95CC6C;
-int16 CHud::PagerSoundPlayed; //= *(int16*)0x95CC4A;
-int32 CHud::SpriteBrightness; //= *(int32*)0x95CC54;
-float CHud::PagerXOffset; //= *(float*)0x941590;
-int16 CHud::PagerTimer; //= *(int16*)0x95CC3A;
-int16 CHud::PagerOn; //= *(int16*)0x95CCA0;
-
-CSprite2d CHud::Sprites[NUM_HUD_SPRITES]; // = (CSprite2d*)0x95CB9C;
+float CHud::OddJob2OffTimer;
+bool CHud::CounterOnLastFrame;
+float CHud::OddJob2XOffset;
+uint16 CHud::CounterFlashTimer;
+uint16 CHud::OddJob2Timer;
+bool CHud::TimerOnLastFrame;
+int16 CHud::OddJob2On;
+uint16 CHud::TimerFlashTimer;
+int16 CHud::PagerSoundPlayed;
+int32 CHud::SpriteBrightness;
+float CHud::PagerXOffset;
+int16 CHud::PagerTimer;
+int16 CHud::PagerOn;
+
+CSprite2d CHud::Sprites[NUM_HUD_SPRITES];
struct
{
@@ -98,8 +98,8 @@ struct
{"siterocket", "siterocket"}
};
-RwTexture *&gpSniperSightTex = *(RwTexture**)0x8F5834;
-RwTexture *&gpRocketSightTex = *(RwTexture**)0x8E2C20;
+RwTexture *gpSniperSightTex;
+RwTexture *gpRocketSightTex;
void CHud::Draw()
{
@@ -136,7 +136,7 @@ void CHud::Draw()
if (DrawCrossHair || DrawCrossHairPC) {
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
- SpriteBrightness = min(SpriteBrightness+1, 30);
+ SpriteBrightness = Min(SpriteBrightness+1, 30);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -144,12 +144,10 @@ void CHud::Draw()
float fMultBright = SpriteBrightness * 0.03f * (0.25f * fStep + 0.75f);
CRect rect;
if (DrawCrossHairPC && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()) {
-#ifndef ASPECT_RATIO_SCALE
float f3rdX = SCREEN_WIDTH * TheCamera.m_f3rdPersonCHairMultX;
float f3rdY = SCREEN_HEIGHT * TheCamera.m_f3rdPersonCHairMultY;
-#else
- float f3rdX = (((TheCamera.m_f3rdPersonCHairMultX - 0.5f) / ((CDraw::GetAspectRatio()) / (DEFAULT_ASPECT_RATIO))) + 0.5f) * SCREEN_WIDTH;
- float f3rdY = SCREEN_HEIGHT * TheCamera.m_f3rdPersonCHairMultY + SCREEN_SCALE_Y(-2.0f);
+#ifdef ASPECT_RATIO_SCALE
+ f3rdY -= SCREEN_SCALE_Y(2.0f);
#endif
if (FindPlayerPed() && WeaponType == WEAPONTYPE_M16) {
rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.6f);
@@ -475,7 +473,12 @@ void CHud::Draw()
break;
}
+
+#ifndef HUD_ENHANCEMENTS
if (!m_Message[0]) {
+#else
+ if (!m_Message[0] && !m_BigMessage[2][0]) { // Hide zone name if wasted/busted text is displaying
+#endif
m_ZoneNameTimer += CTimer::GetTimeStepInMilliseconds();
CFont::SetJustifyOff();
CFont::SetPropOn();
@@ -565,7 +568,11 @@ void CHud::Draw()
break;
}
+#ifndef HUD_ENHANCEMENTS
if (!m_Message[0]) {
+#else
+ if (!m_Message[0] && !m_BigMessage[2][0]) { // Hide vehicle name if wasted/busted text is displaying
+#endif
m_VehicleNameTimer += CTimer::GetTimeStepInMilliseconds();
CFont::SetJustifyOff();
CFont::SetPropOn();
@@ -708,7 +715,7 @@ void CHud::Draw()
} else {
int counter = atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer);
#ifdef FIX_BUGS
- counter = min(counter, 100);
+ counter = Min(counter, 100);
#endif
CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 80));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(counter) / 2.0f + SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET + 50.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 255));
@@ -1204,7 +1211,7 @@ void CHud::DrawAfterFade()
OddJob2On = 2;
}
else {
- fStep = min(40.0f, OddJob2XOffset / 6.0f);
+ fStep = Min(40.0f, OddJob2XOffset / 6.0f);
OddJob2XOffset = OddJob2XOffset - fStep;
}
break;
@@ -1215,7 +1222,7 @@ void CHud::DrawAfterFade()
}
break;
case 3:
- fStep = max(30.0f, OddJob2XOffset / 5.0f);
+ fStep = Max(30.0f, OddJob2XOffset / 5.0f);
OddJob2XOffset = OddJob2XOffset - fStep;
@@ -1238,10 +1245,17 @@ void CHud::DrawAfterFade()
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::SetFontStyle(FONTJAP(FONT_BANK));
+#ifdef BETA_SLIDING_TEXT
+ CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f) - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[5]);
+
+ CFont::SetColor(CRGBA(156, 91, 40, 255));
+ CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f), m_BigMessage[5]);
+#else
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[5]);
CFont::SetColor(CRGBA(156, 91, 40, 255));
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f), m_BigMessage[5]);
+#endif
}
}
@@ -1490,18 +1504,3 @@ void CHud::Shutdown()
int HudTXD = CTxdStore::FindTxdSlot("hud");
CTxdStore::RemoveTxdSlot(HudTXD);
}
-
-STARTPATCHES
- InjectHook(0x5052A0, &CHud::Draw, PATCH_JUMP);
- InjectHook(0x509030, &CHud::DrawAfterFade, PATCH_JUMP);
- InjectHook(0x504F90, &CHud::GetRidOfAllHudMessages, PATCH_JUMP);
- InjectHook(0x5048F0, &CHud::Initialise, PATCH_JUMP);
- InjectHook(0x504CC0, &CHud::ReInitialise, PATCH_JUMP);
- InjectHook(0x50A250, &CHud::SetBigMessage, PATCH_JUMP);
- InjectHook(0x5051E0, &CHud::SetHelpMessage, PATCH_JUMP);
- InjectHook(0x50A210, &CHud::SetMessage, PATCH_JUMP);
- InjectHook(0x50A320, &CHud::SetPagerMessage, PATCH_JUMP);
- InjectHook(0x505290, &CHud::SetVehicleName, PATCH_JUMP);
- InjectHook(0x5051D0, &CHud::SetZoneName, PATCH_JUMP);
- InjectHook(0x504C50, &CHud::Shutdown, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Instance.cpp b/src/render/Instance.cpp
new file mode 100644
index 00000000..be6d73d6
--- /dev/null
+++ b/src/render/Instance.cpp
@@ -0,0 +1,9 @@
+#include "common.h"
+
+#include "Instance.h"
+
+void
+CInstance::Shutdown()
+{
+ GetMatrix().Detach();
+}
diff --git a/src/core/Instance.h b/src/render/Instance.h
index 01dfb6a2..01dfb6a2 100644
--- a/src/core/Instance.h
+++ b/src/render/Instance.h
diff --git a/src/render/Lines.cpp b/src/render/Lines.cpp
index ea433048..b5c85149 100644
--- a/src/render/Lines.cpp
+++ b/src/render/Lines.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Lines.h"
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index d28671fa..c3a25bce 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -1,14 +1,14 @@
#include "common.h"
-#include "patcher.h"
+
#include "RwHelper.h"
#include "Camera.h"
#include "MBlur.h"
// Originally taken from RW example 'mblur'
-RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
-bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
-bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
+RwRaster *CMBlur::pFrontBuffer;
+bool CMBlur::ms_bJustInitialised;
+bool CMBlur::BlurOn;
static RwIm2DVertex Vertex[4];
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
@@ -213,11 +213,3 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
-
-STARTPATCHES
- InjectHook(0x50AE40, CMBlur::MotionBlurOpen, PATCH_JUMP);
- InjectHook(0x50B170, CMBlur::MotionBlurClose, PATCH_JUMP);
- InjectHook(0x50A800, CMBlur::CreateImmediateModeData, PATCH_JUMP);
- InjectHook(0x50AD70, CMBlur::MotionBlurRender, PATCH_JUMP);
- InjectHook(0x50A9C0, CMBlur::OverlayRender, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/MBlur.h b/src/render/MBlur.h
index 42827f99..e8a5bef8 100644
--- a/src/render/MBlur.h
+++ b/src/render/MBlur.h
@@ -3,9 +3,9 @@
class CMBlur
{
public:
- static RwRaster *&pFrontBuffer;
- static bool &ms_bJustInitialised;
- static bool &BlurOn;
+ static RwRaster *pFrontBuffer;
+ static bool ms_bJustInitialised;
+ static bool BlurOn;
public:
static void MotionBlurOpen(RwCamera *cam);
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index 6956a887..c855c860 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "Timer.h"
#include "TxdStore.h"
@@ -12,9 +12,6 @@
#include "ParticleObject.h"
#include "Particle.h"
-#ifdef TOGGLEABLE_BETA_FEATURES
-bool CParticle::bEnableBannedParticles = false;
-#endif
#define MAX_PARTICLES_ON_SCREEN (1000)
@@ -204,26 +201,21 @@ RwRaster *gpGunShellRaster;
RwRaster *gpWakeOldRaster;
-//RwRaster *gpPointlightRaster; // CPointLights::RenderFogEffect
-RwRaster *&gpPointlightRaster = *(RwRaster **)0x8F5FE0;
+RwRaster *gpPointlightRaster; // CPointLights::RenderFogEffect
-//RwTexture *gpRainDropTex[MAX_RAINDROP_FILES]; // CWeather::RenderRainStreaks
-RwTexture * (&gpRainDropTex)[MAX_RAINDROP_FILES] = *(RwTexture * (*)[MAX_RAINDROP_FILES])*(int *)0x880660;
+RwTexture *gpRainDropTex[MAX_RAINDROP_FILES]; // CWeather::RenderRainStreaks
RwRaster *gpRainDropRaster[MAX_RAINDROP_FILES];
-//Float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE]; //
-float (&CParticle::ms_afRandTable)[CParticle::RAND_TABLE_SIZE] = *(float (*)[CParticle::RAND_TABLE_SIZE])*(int *)0x6E98C8;
+float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE];
CParticle *CParticle::m_pUnusedListHead;
-//Float CParticle::m_SinTable[CParticle::SIN_COS_TABLE_SIZE]; //
-//Float CParticle::m_CosTable[CParticle::SIN_COS_TABLE_SIZE]; /
-float (&CParticle::m_SinTable)[CParticle::SIN_COS_TABLE_SIZE] = *(float (*)[CParticle::SIN_COS_TABLE_SIZE])*(int *)0x877358;
-float (&CParticle::m_CosTable)[CParticle::SIN_COS_TABLE_SIZE] = *(float (*)[CParticle::SIN_COS_TABLE_SIZE])*(int *)0x70DA18;
+float CParticle::m_SinTable[CParticle::SIN_COS_TABLE_SIZE];
+float CParticle::m_CosTable[CParticle::SIN_COS_TABLE_SIZE];
int32 Randomizer;
@@ -393,8 +385,12 @@ void CParticle::Initialise()
gpFlame5Tex = RwTextureRead("flame5", nil);
+#ifdef FIX_BUGS
+ gpFlame5Raster = RwTextureGetRaster(gpFlame5Tex);
+#else
gpFlame5Raster = RwTextureGetRaster(gpFlame1Tex); // copy-paste bug ?
-
+#endif
+
gpRainDropSmallTex = RwTextureRead("rainsmall", nil);
gpRainDropSmallRaster = RwTextureGetRaster(gpRainDropSmallTex);
@@ -772,9 +768,8 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
if ( CTimer::GetIsPaused() )
return NULL;
-#ifdef TOGGLEABLE_BETA_FEATURES
- if(!bEnableBannedParticles)
-#endif
+
+#ifdef PC_PARTICLE
if ( ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@@ -787,6 +782,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
return nil;
}
+#endif
CParticle *pParticle = m_pUnusedListHead;
@@ -858,6 +854,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
pParticle->m_nRotation = nRotation;
+// PC only
if ( pParticle->m_nRotation >= 360 )
pParticle->m_nRotation -= 360;
else if ( pParticle->m_nRotation < 0 )
@@ -1353,12 +1350,13 @@ void CParticle::Update()
particle->m_nAlpha = clamp(particle->m_nAlpha - psystem->m_nFadeAlphaAmount,
0, 255);
-
+#ifdef PC_PARTICLE
if ( particle->m_nAlpha == 0 )
{
bRemoveParticle = true;
continue;
}
+#endif
}
else
++particle->m_nFadeAlphaTimer;
@@ -1453,18 +1451,15 @@ void CParticle::Render()
for ( int32 i = 0; i < MAX_PARTICLES; i++ )
{
tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[i];
-
+#ifdef PC_PARTICLE
bool particleBanned = false;
-
+#endif
CParticle *particle = psystem->m_pParticles;
RwRaster **frames = psystem->m_ppRaster;
-
+#ifdef PC_PARTICLE
tParticleType type = psystem->m_Type;
-#ifdef TOGGLEABLE_BETA_FEATURES
- if (!bEnableBannedParticles)
-#endif
if ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@@ -1476,7 +1471,8 @@ void CParticle::Render()
{
particleBanned = true;
}
-
+#endif
+
if ( particle )
{
if ( (flags & DRAW_OPAQUE) != (psystem->Flags & DRAW_OPAQUE)
@@ -1517,10 +1513,11 @@ void CParticle::Render()
while ( particle != nil )
{
bool canDraw = true;
+#ifdef PC_PARTICLE
if ( particle->m_nAlpha == 0 )
canDraw = false;
-
+#endif
if ( canDraw && psystem->m_nFinalAnimationFrame != 0 && frames != nil )
{
RwRaster *curFrame = frames[particle->m_nCurrentFrame];
@@ -1543,7 +1540,7 @@ void CParticle::Render()
particle->m_fSize * 63.0f,
particle->m_Color,
particle->m_nColorIntensity,
- (float)particle->m_nRotation,
+ (float)particle->m_nRotation, //DEGTORAD((float)particle->m_nRotation) ps2
particle->m_nAlpha);
}
else
@@ -1569,8 +1566,10 @@ void CParticle::Render()
if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) )
{
+#ifdef PC_PARTICLE
if ( (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w)
&& SCREEN_HEIGHT * fParticleScaleLimit >= h )
+#endif
{
if ( particle->m_nRotation != 0 )
{
@@ -1581,7 +1580,7 @@ void CParticle::Render()
particle->m_Color.blue,
particle->m_nColorIntensity,
1.0f / coors.z,
- float(particle->m_nRotation),
+ float(particle->m_nRotation), // DEGTORAD((float)particle->m_nRotation) ps2
particle->m_nAlpha);
}
else if ( psystem->Flags & SCREEN_TRAIL )
@@ -1606,7 +1605,6 @@ void CParticle::Render()
fTrailLength = fDist;
- //Float fRot = Atan2( vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)) );
float fRot = Asin(vecDist.x / fDist);
fRotation = fRot;
@@ -1658,7 +1656,6 @@ void CParticle::Render()
fTrailLength = fDist;
- //Float fRot = Atan2(vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)));
float fRot = Asin(vecDist.x / fDist);
fRotation = fRot;
@@ -1854,19 +1851,3 @@ void CParticle::AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatr
0.3f, color, 0, 0, 0, 0);
}
}
-
-STARTPATCHES
- //InjectHook(0x50C410, &CParticle::ctor, PATCH_JUMP);
- //InjectHook(0x50C420, &CParticle::dtor, PATCH_JUMP);
- InjectHook(0x50C430, CParticle::ReloadConfig, PATCH_JUMP);
- InjectHook(0x50C570, CParticle::Initialise, PATCH_JUMP);
- InjectHook(0x50CF40, CParticle::Shutdown, PATCH_JUMP);
- //InjectHook(0x50D140, CParticle::AddParticle, PATCH_JUMP);
- InjectHook(0x50D190, (CParticle *(*)(tParticleType, CVector const&, CVector const&, CEntity*, float, RwRGBA const&, int, int, int, int))CParticle::AddParticle, PATCH_JUMP);
- InjectHook(0x50DCF0, CParticle::Update, PATCH_JUMP);
- InjectHook(0x50EE20, CParticle::Render, PATCH_JUMP);
- InjectHook(0x50F6E0, CParticle::RemovePSystem, PATCH_JUMP);
- InjectHook(0x50F720, CParticle::RemoveParticle, PATCH_JUMP);
- InjectHook(0x50F760, CParticle::AddJetExplosion, PATCH_JUMP);
- InjectHook(0x50FAA0, CParticle::AddYardieDoorSmoke, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Particle.h b/src/render/Particle.h
index 310ef0d4..b71dc717 100644
--- a/src/render/Particle.h
+++ b/src/render/Particle.h
@@ -24,7 +24,6 @@ public:
uint16 m_nZRotationTimer;
float m_fCurrentZRadius;
uint16 m_nZRadiusTimer;
- char _pad0[2];
float m_fSize;
float m_fExpansionRate;
uint16 m_nFadeToBlackTimer;
@@ -36,7 +35,6 @@ public:
int16 m_nRotationStep;
int16 m_nRotation;
RwRGBA m_Color;
- char _pad1[2];
CParticle *m_pNext;
CParticle()
@@ -49,16 +47,11 @@ public:
;
}
- //static float ms_afRandTable[RAND_TABLE_SIZE];
- static float (&ms_afRandTable)[RAND_TABLE_SIZE];
+ static float ms_afRandTable[RAND_TABLE_SIZE];
static CParticle *m_pUnusedListHead;
- /*
static float m_SinTable[SIN_COS_TABLE_SIZE];
static float m_CosTable[SIN_COS_TABLE_SIZE];
- */
- static float (&m_SinTable)[SIN_COS_TABLE_SIZE];
- static float (&m_CosTable)[SIN_COS_TABLE_SIZE];
static float Sin(int32 value) { return m_SinTable[value]; }
static float Cos(int32 value) { return m_CosTable[value]; }
@@ -96,10 +89,6 @@ public:
static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize);
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
-
-#ifndef MASTER
- static bool bEnableBannedParticles;
-#endif
};
VALIDATE_SIZE(CParticle, 0x68); \ No newline at end of file
diff --git a/src/render/ParticleMgr.cpp b/src/render/ParticleMgr.cpp
index 7a1804de..3387d471 100644
--- a/src/render/ParticleMgr.cpp
+++ b/src/render/ParticleMgr.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "FileMgr.h"
#include "ParticleMgr.h"
@@ -8,8 +8,7 @@ cParticleSystemMgr mod_ParticleSystemManager;
const char *ParticleFilename = "PARTICLE.CFG";
-//cParticleSystemMgr::cParticleSystemMgr()
-void cParticleSystemMgr::ctor()
+cParticleSystemMgr::cParticleSystemMgr()
{
memset(this, 0, sizeof(*this));
}
@@ -91,7 +90,7 @@ void cParticleSystemMgr::LoadParticleData()
break;
case CFG_PARAM_INITIAL_COLOR_VARIATION:
- entry->m_InitialColorVariation = min(atoi(value), 100);
+ entry->m_InitialColorVariation = Min(atoi(value), 100);
break;
case CFG_PARAM_FADE_DESTINATION_COLOR_R:
@@ -242,9 +241,3 @@ void cParticleSystemMgr::LoadParticleData()
lineEnd++;
}
}
-
-STARTPATCHES
- InjectHook(0x50FCB0, &cParticleSystemMgr::ctor, PATCH_JUMP);
- InjectHook(0x50FCD0, &cParticleSystemMgr::Initialise, PATCH_JUMP);
- InjectHook(0x50FDF0, &cParticleSystemMgr::LoadParticleData, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/render/ParticleMgr.h b/src/render/ParticleMgr.h
index 5e8da1e4..70845a56 100644
--- a/src/render/ParticleMgr.h
+++ b/src/render/ParticleMgr.h
@@ -1,82 +1,8 @@
#pragma once
-class CParticle;
+#include "ParticleType.h"
-enum tParticleType
-{
- PARTICLE_SPARK = 0,
- PARTICLE_SPARK_SMALL,
- PARTICLE_WHEEL_DIRT,
- PARTICLE_WHEEL_WATER,
- PARTICLE_BLOOD,
- PARTICLE_BLOOD_SMALL,
- PARTICLE_BLOOD_SPURT,
- PARTICLE_DEBRIS,
- PARTICLE_DEBRIS2,
- PARTICLE_WATER,
- PARTICLE_FLAME,
- PARTICLE_FIREBALL,
- PARTICLE_GUNFLASH,
- PARTICLE_GUNFLASH_NOANIM,
- PARTICLE_GUNSMOKE,
- PARTICLE_GUNSMOKE2,
- PARTICLE_SMOKE,
- PARTICLE_SMOKE_SLOWMOTION,
- PARTICLE_GARAGEPAINT_SPRAY,
- PARTICLE_SHARD,
- PARTICLE_SPLASH,
- PARTICLE_CARFLAME,
- PARTICLE_STEAM,
- PARTICLE_STEAM2,
- PARTICLE_STEAM_NY,
- PARTICLE_STEAM_NY_SLOWMOTION,
- PARTICLE_ENGINE_STEAM,
- PARTICLE_RAINDROP,
- PARTICLE_RAINDROP_SMALL,
- PARTICLE_RAIN_SPLASH,
- PARTICLE_RAIN_SPLASH_BIGGROW,
- PARTICLE_RAIN_SPLASHUP,
- PARTICLE_WATERSPRAY,
- PARTICLE_EXPLOSION_MEDIUM,
- PARTICLE_EXPLOSION_LARGE,
- PARTICLE_EXPLOSION_MFAST,
- PARTICLE_EXPLOSION_LFAST,
- PARTICLE_CAR_SPLASH,
- PARTICLE_BOAT_SPLASH,
- PARTICLE_BOAT_THRUSTJET,
- PARTICLE_BOAT_WAKE,
- PARTICLE_WATER_HYDRANT,
- PARTICLE_WATER_CANNON,
- PARTICLE_EXTINGUISH_STEAM,
- PARTICLE_PED_SPLASH,
- PARTICLE_PEDFOOT_DUST,
- PARTICLE_HELI_DUST,
- PARTICLE_HELI_ATTACK,
- PARTICLE_ENGINE_SMOKE,
- PARTICLE_ENGINE_SMOKE2,
- PARTICLE_CARFLAME_SMOKE,
- PARTICLE_FIREBALL_SMOKE,
- PARTICLE_PAINT_SMOKE,
- PARTICLE_TREE_LEAVES,
- PARTICLE_CARCOLLISION_DUST,
- PARTICLE_CAR_DEBRIS,
- PARTICLE_HELI_DEBRIS,
- PARTICLE_EXHAUST_FUMES,
- PARTICLE_RUBBER_SMOKE,
- PARTICLE_BURNINGRUBBER_SMOKE,
- PARTICLE_BULLETHIT_SMOKE,
- PARTICLE_GUNSHELL_FIRST,
- PARTICLE_GUNSHELL,
- PARTICLE_GUNSHELL_BUMP1,
- PARTICLE_GUNSHELL_BUMP2,
- PARTICLE_TEST,
- PARTICLE_BIRD_FRONT,
- PARTICLE_RAINDROP_2D,
-
- MAX_PARTICLES,
- PARTICLE_FIRST = PARTICLE_SPARK,
- PARTICLE_LAST = PARTICLE_RAINDROP_2D
-};
+class CParticle;
enum
{
@@ -120,7 +46,6 @@ struct tParticleSystemData
uint16 m_nFinalAnimationFrame;
uint16 m_nAnimationSpeed;
uint16 m_nRotationSpeed;
- char _pad1[2];
float m_fGravitationalAcceleration;
int32 m_nFrictionDecceleration;
int32 m_nLifeSpan;
@@ -134,7 +59,6 @@ struct tParticleSystemData
RwRGBA m_RenderColouring;
uint8 m_InitialColorVariation;
RwRGBA m_FadeDestinationColor;
- char _pad2[3];
uint32 m_ColorFadeTime;
RwRaster **m_ppRaster;
@@ -194,11 +118,11 @@ class cParticleSystemMgr
public:
tParticleSystemData m_aParticles[MAX_PARTICLES];
- cParticleSystemMgr() { ctor(); } void ctor();
+ cParticleSystemMgr();
void Initialise();
void LoadParticleData();
- //void RangeCheck(tParticleSystemData *pData);
+ void RangeCheck(tParticleSystemData *pData) { }
};
VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
diff --git a/src/render/ParticleType.h b/src/render/ParticleType.h
new file mode 100644
index 00000000..8d352c44
--- /dev/null
+++ b/src/render/ParticleType.h
@@ -0,0 +1,77 @@
+#pragma once
+
+enum tParticleType
+{
+ PARTICLE_SPARK = 0,
+ PARTICLE_SPARK_SMALL,
+ PARTICLE_WHEEL_DIRT,
+ PARTICLE_WHEEL_WATER,
+ PARTICLE_BLOOD,
+ PARTICLE_BLOOD_SMALL,
+ PARTICLE_BLOOD_SPURT,
+ PARTICLE_DEBRIS,
+ PARTICLE_DEBRIS2,
+ PARTICLE_WATER,
+ PARTICLE_FLAME,
+ PARTICLE_FIREBALL,
+ PARTICLE_GUNFLASH,
+ PARTICLE_GUNFLASH_NOANIM,
+ PARTICLE_GUNSMOKE,
+ PARTICLE_GUNSMOKE2,
+ PARTICLE_SMOKE,
+ PARTICLE_SMOKE_SLOWMOTION,
+ PARTICLE_GARAGEPAINT_SPRAY,
+ PARTICLE_SHARD,
+ PARTICLE_SPLASH,
+ PARTICLE_CARFLAME,
+ PARTICLE_STEAM,
+ PARTICLE_STEAM2,
+ PARTICLE_STEAM_NY,
+ PARTICLE_STEAM_NY_SLOWMOTION,
+ PARTICLE_ENGINE_STEAM,
+ PARTICLE_RAINDROP,
+ PARTICLE_RAINDROP_SMALL,
+ PARTICLE_RAIN_SPLASH,
+ PARTICLE_RAIN_SPLASH_BIGGROW,
+ PARTICLE_RAIN_SPLASHUP,
+ PARTICLE_WATERSPRAY,
+ PARTICLE_EXPLOSION_MEDIUM,
+ PARTICLE_EXPLOSION_LARGE,
+ PARTICLE_EXPLOSION_MFAST,
+ PARTICLE_EXPLOSION_LFAST,
+ PARTICLE_CAR_SPLASH,
+ PARTICLE_BOAT_SPLASH,
+ PARTICLE_BOAT_THRUSTJET,
+ PARTICLE_BOAT_WAKE,
+ PARTICLE_WATER_HYDRANT,
+ PARTICLE_WATER_CANNON,
+ PARTICLE_EXTINGUISH_STEAM,
+ PARTICLE_PED_SPLASH,
+ PARTICLE_PEDFOOT_DUST,
+ PARTICLE_HELI_DUST,
+ PARTICLE_HELI_ATTACK,
+ PARTICLE_ENGINE_SMOKE,
+ PARTICLE_ENGINE_SMOKE2,
+ PARTICLE_CARFLAME_SMOKE,
+ PARTICLE_FIREBALL_SMOKE,
+ PARTICLE_PAINT_SMOKE,
+ PARTICLE_TREE_LEAVES,
+ PARTICLE_CARCOLLISION_DUST,
+ PARTICLE_CAR_DEBRIS,
+ PARTICLE_HELI_DEBRIS,
+ PARTICLE_EXHAUST_FUMES,
+ PARTICLE_RUBBER_SMOKE,
+ PARTICLE_BURNINGRUBBER_SMOKE,
+ PARTICLE_BULLETHIT_SMOKE,
+ PARTICLE_GUNSHELL_FIRST,
+ PARTICLE_GUNSHELL,
+ PARTICLE_GUNSHELL_BUMP1,
+ PARTICLE_GUNSHELL_BUMP2,
+ PARTICLE_TEST,
+ PARTICLE_BIRD_FRONT,
+ PARTICLE_RAINDROP_2D,
+
+ MAX_PARTICLES,
+ PARTICLE_FIRST = PARTICLE_SPARK,
+ PARTICLE_LAST = PARTICLE_RAINDROP_2D
+}; \ No newline at end of file
diff --git a/src/render/PlayerSkin.cpp b/src/render/PlayerSkin.cpp
index 2cba45fe..94af1fd1 100644
--- a/src/render/PlayerSkin.cpp
+++ b/src/render/PlayerSkin.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "PlayerSkin.h"
#include "TxdStore.h"
@@ -163,12 +163,3 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
SetAmbientColours(&AmbientColor);
RpClumpRender(gpPlayerClump);
}
-
-STARTPATCHES
-InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
-InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
-InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
-InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
-InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
-InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp
index a015ec54..b92e7e83 100644
--- a/src/render/PointLights.cpp
+++ b/src/render/PointLights.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Lights.h"
#include "Camera.h"
@@ -10,8 +10,8 @@
#include "Timer.h"
#include "PointLights.h"
-int16 &CPointLights::NumLights = *(int16*)0x95CC3E;
-CRegisteredPointLight *CPointLights::aLights = (CRegisteredPointLight*)0x7096D0;
+int16 CPointLights::NumLights;
+CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
void
CPointLights::InitPerFrame(void)
@@ -98,7 +98,7 @@ CPointLights::GenerateLightsAffectingObject(CVector *objCoors)
if(aLights[i].type == LIGHT_DIRECTIONAL){
float dot = -DotProduct(dir, aLights[i].dir);
- intensity *= max((dot-0.5f)*2.0f, 0.0f);
+ intensity *= Max((dot-0.5f)*2.0f, 0.0f);
}
if(intensity > 0.0f)
@@ -114,7 +114,7 @@ CPointLights::GenerateLightsAffectingObject(CVector *objCoors)
return ret;
}
-extern RwRaster *&gpPointlightRaster;
+extern RwRaster *gpPointlightRaster;
void
CPointLights::RemoveLightsAffectingObject(void)
@@ -284,10 +284,3 @@ CPointLights::RenderFogEffect(void)
}
}
}
-
-STARTPATCHES
- InjectHook(0x510790, CPointLights::AddLight, PATCH_JUMP);
- InjectHook(0x510960, CPointLights::GenerateLightsAffectingObject, PATCH_JUMP);
- InjectHook(0x510C20, CPointLights::RemoveLightsAffectingObject, PATCH_JUMP);
- InjectHook(0x510C30, CPointLights::RenderFogEffect, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/PointLights.h b/src/render/PointLights.h
index c1dad87f..215e1dc9 100644
--- a/src/render/PointLights.h
+++ b/src/render/PointLights.h
@@ -18,8 +18,8 @@ static_assert(sizeof(CRegisteredPointLight) == 0x2C, "CRegisteredPointLight: err
class CPointLights
{
public:
- static int16 &NumLights;
- static CRegisteredPointLight *aLights; //[NUMPOINTLIGHTS]
+ static int16 NumLights;
+ static CRegisteredPointLight aLights[NUMPOINTLIGHTS];
enum {
LIGHT_POINT,
diff --git a/src/render/RenderBuffer.cpp b/src/render/RenderBuffer.cpp
index f6499451..6120dfe2 100644
--- a/src/render/RenderBuffer.cpp
+++ b/src/render/RenderBuffer.cpp
@@ -1,15 +1,15 @@
#include "common.h"
-#include "patcher.h"
+
#include "RenderBuffer.h"
-int32 &TempBufferVerticesStored = *(int32*)0x8F5F78;
-int32 &TempBufferIndicesStored = *(int32*)0x8F1A4C;
+int32 TempBufferVerticesStored;
+int32 TempBufferIndicesStored;
-RwIm3DVertex *TempBufferRenderVertices = (RwIm3DVertex*)0x862330;
-RwImVertexIndex *TempBufferRenderIndexList = (RwImVertexIndex*)0x846288;
+RwIm3DVertex TempBufferRenderVertices[TEMPBUFFERVERTSIZE];
+RwImVertexIndex TempBufferRenderIndexList[TEMPBUFFERINDEXSIZE];
-int &RenderBuffer::VerticesToBeStored = *(int*)0x8F59C4;
-int &RenderBuffer::IndicesToBeStored = *(int*)0x8E28B0;
+int RenderBuffer::VerticesToBeStored;
+int RenderBuffer::IndicesToBeStored;
void
RenderBuffer::ClearRenderBuffer(void)
@@ -50,10 +50,3 @@ RenderBuffer::RenderStuffInBuffer(void)
}
ClearRenderBuffer();
}
-
-STARTPATCHES
- InjectHook(0x517620, RenderBuffer::ClearRenderBuffer, PATCH_JUMP);
- InjectHook(0x517640, RenderBuffer::StartStoring, PATCH_JUMP);
- InjectHook(0x5176B0, RenderBuffer::StopStoring, PATCH_JUMP);
- InjectHook(0x5177C0, RenderBuffer::RenderStuffInBuffer, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/RenderBuffer.h b/src/render/RenderBuffer.h
index 2b8a9f86..485d24e3 100644
--- a/src/render/RenderBuffer.h
+++ b/src/render/RenderBuffer.h
@@ -1,8 +1,8 @@
class RenderBuffer
{
public:
- static int &VerticesToBeStored;
- static int &IndicesToBeStored;
+ static int VerticesToBeStored;
+ static int IndicesToBeStored;
static void ClearRenderBuffer(void);
static void StartStoring(int numIndices, int numVertices, RwImVertexIndex **indexStart, RwIm3DVertex **vertexStart);
static void StopStoring(void);
@@ -12,7 +12,7 @@ public:
#define TEMPBUFFERVERTSIZE 256
#define TEMPBUFFERINDEXSIZE 1024
-extern int32 &TempBufferVerticesStored;
-extern int32 &TempBufferIndicesStored;
-extern RwIm3DVertex *TempBufferRenderVertices;
-extern RwImVertexIndex *TempBufferRenderIndexList; \ No newline at end of file
+extern int32 TempBufferVerticesStored;
+extern int32 TempBufferIndicesStored;
+extern RwIm3DVertex TempBufferRenderVertices[TEMPBUFFERVERTSIZE];
+extern RwImVertexIndex TempBufferRenderIndexList[TEMPBUFFERINDEXSIZE]; \ No newline at end of file
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index d7834065..3d308c52 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Lights.h"
#include "ModelInfo.h"
@@ -39,16 +39,17 @@ struct EntityInfo
float sort;
};
-CLinkList<EntityInfo> &gSortedVehiclesAndPeds = *(CLinkList<EntityInfo>*)0x629AC0;
+CLinkList<EntityInfo> gSortedVehiclesAndPeds;
-int32 &CRenderer::ms_nNoOfVisibleEntities = *(int32*)0x940730;
-CEntity *(&CRenderer::ms_aVisibleEntityPtrs)[NUMVISIBLEENTITIES] = *(CEntity * (*)[NUMVISIBLEENTITIES]) * (uintptr*)0x6E9920;
-CEntity *(&CRenderer::ms_aInVisibleEntityPtrs)[NUMINVISIBLEENTITIES] = *(CEntity * (*)[NUMINVISIBLEENTITIES]) * (uintptr*)0x880B50;
-int32 &CRenderer::ms_nNoOfInVisibleEntities = *(int32*)0x8F1B78;
+int32 CRenderer::ms_nNoOfVisibleEntities;
+CEntity *CRenderer::ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES];
+CEntity *CRenderer::ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES];
+int32 CRenderer::ms_nNoOfInVisibleEntities;
-CVector &CRenderer::ms_vecCameraPosition = *(CVector*)0x8E2C3C;
-CVehicle *&CRenderer::m_pFirstPersonVehicle = *(CVehicle**)0x885B80;
-bool &CRenderer::m_loadingPriority = *(bool*)0x95CD86;
+CVector CRenderer::ms_vecCameraPosition;
+CVehicle *CRenderer::m_pFirstPersonVehicle;
+bool CRenderer::m_loadingPriority;
+float CRenderer::ms_lodDistScale = 1.2f;
void
CRenderer::Init(void)
@@ -193,8 +194,6 @@ CRenderer::RenderRoads(void)
DeActivateDirectional();
SetAmbientColours();
- ThePaths.m_pathNodes[-1].group = 6;
-
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
t = (CTreadable*)ms_aVisibleEntityPtrs[i];
if(t->IsBuilding() && t->GetIsATreadable()){
@@ -1206,40 +1205,3 @@ CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset)
if(reset)
ReSetAmbientAndDirectionalColours();
}
-
-STARTPATCHES
- InjectHook(0x4A7680, CRenderer::Init, PATCH_JUMP);
- InjectHook(0x4A76A0, CRenderer::Shutdown, PATCH_JUMP);
-
- InjectHook(0x4A7B90, CRenderer::RenderOneRoad, PATCH_JUMP);
- InjectHook(0x4A7BA0, CRenderer::RenderOneNonRoad, PATCH_JUMP);
- InjectHook(0x4A7B20, CRenderer::RenderFirstPersonVehicle, PATCH_JUMP);
- InjectHook(0x4A78B0, CRenderer::RenderRoads, PATCH_JUMP);
- InjectHook(0x4A7930, CRenderer::RenderEverythingBarRoads, PATCH_JUMP);
- InjectHook(0x4A7AA0, CRenderer::RenderVehiclesButNotBoats, PATCH_JUMP);
- InjectHook(0x4A7AE0, CRenderer::RenderBoats, PATCH_JUMP);
- InjectHook(0x4A7910, CRenderer::RenderFadingInEntities, PATCH_JUMP);
-
- InjectHook(0x4A9350, CRenderer::SetupEntityVisibility, PATCH_JUMP);
- InjectHook(0x4A9920, CRenderer::SetupBigBuildingVisibility, PATCH_JUMP);
-
- InjectHook(0x4A76B0, CRenderer::ConstructRenderList, PATCH_JUMP);
- InjectHook(0x4A7840, CRenderer::PreRender, PATCH_JUMP);
- InjectHook(0x4A8970, CRenderer::ScanWorld, PATCH_JUMP);
- InjectHook(0x4AA240, CRenderer::RequestObjectsInFrustum, PATCH_JUMP);
- InjectHook(0x4A7F30, CRenderer::ScanSectorPoly, PATCH_JUMP);
- InjectHook(0x4A9300, CRenderer::ScanBigBuildingList, PATCH_JUMP);
- InjectHook(0x4A9BB0, CRenderer::ScanSectorList, PATCH_JUMP);
- InjectHook(0x4A9E30, CRenderer::ScanSectorList_Priority, PATCH_JUMP);
- InjectHook(0x4AA0A0, CRenderer::ScanSectorList_Subway, PATCH_JUMP);
- InjectHook(0x4AA1D0, CRenderer::ScanSectorList_RequestModels, PATCH_JUMP);
-
- InjectHook(0x4AA940, CRenderer::SortBIGBuildings, PATCH_JUMP);
- InjectHook(0x4AA990, CRenderer::SortBIGBuildingsForSectorList, PATCH_JUMP);
-
- InjectHook(0x4A9840, CRenderer::ShouldModelBeStreamed, PATCH_JUMP);
- InjectHook(0x4AAA00, CRenderer::IsEntityCullZoneVisible, PATCH_JUMP);
- InjectHook(0x4AAAA0, CRenderer::IsVehicleCullZoneVisible, PATCH_JUMP);
-
- InjectHook(0x4A7CF0, CRenderer::RemoveVehiclePedLights, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 42c154ec..362741e3 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -20,17 +20,17 @@ class CPtrList;
class CRenderer
{
- static int32 &ms_nNoOfVisibleEntities;
- static CEntity *(&ms_aVisibleEntityPtrs)[NUMVISIBLEENTITIES];
- static int32 &ms_nNoOfInVisibleEntities;
- static CEntity *(&ms_aInVisibleEntityPtrs)[NUMINVISIBLEENTITIES];
+ static int32 ms_nNoOfVisibleEntities;
+ static CEntity *ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES];
+ static int32 ms_nNoOfInVisibleEntities;
+ static CEntity *ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES];
- static CVector &ms_vecCameraPosition;
- static CVehicle *&m_pFirstPersonVehicle;
+ static CVector ms_vecCameraPosition;
+ static CVehicle *m_pFirstPersonVehicle;
public:
- static float ms_lodDistScale; // defined in Frontend.cpp
- static bool &m_loadingPriority;
+ static float ms_lodDistScale;
+ static bool m_loadingPriority;
static void Init(void);
static void Shutdown(void);
diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp
index 65d8b2dd..d21dd558 100644
--- a/src/render/Rubbish.cpp
+++ b/src/render/Rubbish.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "General.h"
#include "Timer.h"
#include "Weather.h"
@@ -217,9 +217,9 @@ CRubbish::Update(void)
// FRAMETIME
if(bRubbishInvisible)
- RubbishVisibility = max(RubbishVisibility-5, 0);
+ RubbishVisibility = Max(RubbishVisibility-5, 0);
else
- RubbishVisibility = min(RubbishVisibility+5, 255);
+ RubbishVisibility = Min(RubbishVisibility+5, 255);
// Spawn a new sheet
COneSheet *sheet = StartEmptyList.m_next;
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index e14b0453..d5970ebe 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "TxdStore.h"
#include "Timer.h"
@@ -13,6 +13,9 @@
#include "Weather.h"
#include "ModelIndices.h"
#include "RenderBuffer.h"
+#ifdef FIX_BUGS
+#include "Replay.h"
+#endif
#include "PointLights.h"
#include "SpecialFX.h"
#include "Shadows.h"
@@ -20,43 +23,31 @@
SETTWEAKPATH("Shadows");
TWEAKBOOL(gbPrintShite);
-#if 1
RwImVertexIndex ShadowIndexList[24];
-#else
-RwImVertexIndex (&ShadowIndexList)[24] = *(RwImVertexIndex (*)[24])*(int *)0x649188;
-#endif
-RwTexture *&gpShadowCarTex = *(RwTexture **)0x8F2C90;
-RwTexture *&gpShadowPedTex = *(RwTexture **)0x8F59D0;
-RwTexture *&gpShadowHeliTex = *(RwTexture **)0x8E2A90;
-RwTexture *&gpShadowExplosionTex = *(RwTexture **)0x8F2A00;
-RwTexture *&gpShadowHeadLightsTex = *(RwTexture **)0x95CB98;
-RwTexture *&gpOutline1Tex = *(RwTexture **)0x8F1B24;
-RwTexture *&gpOutline2Tex = *(RwTexture **)0x8F1B04;
-RwTexture *&gpOutline3Tex = *(RwTexture **)0x8F1B08;
-RwTexture *&gpBloodPoolTex = *(RwTexture **)0x9415F8;
-RwTexture *&gpReflectionTex = *(RwTexture **)0x8F582C;
-RwTexture *&gpGoalMarkerTex = *(RwTexture **)0x94142C;
-RwTexture *&gpWalkDontTex = *(RwTexture **)0x95CB4C;
-RwTexture *&gpCrackedGlassTex = *(RwTexture **)0x95CB94;
-RwTexture *&gpPostShadowTex = *(RwTexture **)0x8F59D4;
-RwTexture *&gpGoalTex = *(RwTexture**)0x94142C;
-
-#if 1
+RwTexture *gpShadowCarTex;
+RwTexture *gpShadowPedTex;
+RwTexture *gpShadowHeliTex;
+RwTexture *gpShadowExplosionTex;
+RwTexture *gpShadowHeadLightsTex;
+RwTexture *gpOutline1Tex;
+RwTexture *gpOutline2Tex;
+RwTexture *gpOutline3Tex;
+RwTexture *gpBloodPoolTex;
+RwTexture *gpReflectionTex;
+RwTexture *gpGoalMarkerTex;
+RwTexture *gpWalkDontTex;
+RwTexture *gpCrackedGlassTex;
+RwTexture *gpPostShadowTex;
+RwTexture *gpGoalTex;
+
int16 CShadows::ShadowsStoredToBeRendered;
CStoredShadow CShadows::asShadowsStored [MAX_STOREDSHADOWS];
CPolyBunch CShadows::aPolyBunches [MAX_POLYBUNCHES];
CStaticShadow CShadows::aStaticShadows [MAX_STATICSHADOWS];
CPolyBunch *CShadows::pEmptyBunchList;
CPermanentShadow CShadows::aPermanentShadows[MAX_PERMAMENTSHADOWS];
-#else
-int16 &CShadows::ShadowsStoredToBeRendered = *(int16*)0x95CCEE;
-CStoredShadow (&CShadows::asShadowsStored)[MAX_STOREDSHADOWS] = *(CStoredShadow (*)[MAX_STOREDSHADOWS])*(int *)0x779058;
-CPolyBunch (&CShadows::aPolyBunches)[MAX_POLYBUNCHES] = *(CPolyBunch (*)[MAX_POLYBUNCHES])*(int *)0x86F4C8;
-CStaticShadow (&CShadows::aStaticShadows)[MAX_STATICSHADOWS] = *(CStaticShadow (*)[MAX_STATICSHADOWS])*(int *)0x773BE8;
-CPolyBunch *&CShadows::pEmptyBunchList = *(CPolyBunch**)0x8F435C;
-CPermanentShadow (&CShadows::aPermanentShadows)[MAX_PERMAMENTSHADOWS] = *(CPermanentShadow (*)[MAX_PERMAMENTSHADOWS])*(int *)0x712040;
-#endif
+
void
CShadows::Init(void)
@@ -728,10 +719,10 @@ CShadows::RenderStoredShadows(void)
float fStartY = shadowPos.y - fHeight;
float fEndY = shadowPos.y + fHeight;
- int32 nStartX = max(CWorld::GetSectorIndexX(fStartX), 0);
- int32 nStartY = max(CWorld::GetSectorIndexY(fStartY), 0);
- int32 nEndX = min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1);
- int32 nEndY = min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1);
+ int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
+ int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
+ int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1);
+ int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1);
CWorld::AdvanceCurrentScanCode();
@@ -874,10 +865,10 @@ CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID)
float fStartY = shadowPos.y - fHeight;
float fEndY = shadowPos.y + fHeight;
- int32 nStartX = max(CWorld::GetSectorIndexX(fStartX), 0);
- int32 nStartY = max(CWorld::GetSectorIndexY(fStartY), 0);
- int32 nEndX = min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1);
- int32 nEndY = min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1);
+ int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
+ int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
+ int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X-1);
+ int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y-1);
CWorld::AdvanceCurrentScanCode();
@@ -1017,11 +1008,11 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
Points[3].x = (fLengthRight - fFrontRight) - fSideRight;
Points[3].y = (fLengthForward - fFrontForward) - fSideForward;
- float MinX = min(min(Points[0].x, Points[1].x), min(Points[2].x, Points[3].x));
- float MaxX = max(max(Points[0].x, Points[1].x), max(Points[2].x, Points[3].x));
+ float MinX = Min(Min(Points[0].x, Points[1].x), Min(Points[2].x, Points[3].x));
+ float MaxX = Max(Max(Points[0].x, Points[1].x), Max(Points[2].x, Points[3].x));
- float MinY = min(min(Points[0].y, Points[1].y), min(Points[2].y, Points[3].y));
- float MaxY = max(max(Points[0].y, Points[1].y), max(Points[2].y, Points[3].y));
+ float MinY = Min(Min(Points[0].y, Points[1].y), Min(Points[2].y, Points[3].y));
+ float MaxY = Max(Max(Points[0].y, Points[1].y), Max(Points[2].y, Points[3].y));
float MaxZ = pPosn->z - pEntity->GetPosition().z;
float MinZ = MaxZ - fZDistance;
@@ -1621,6 +1612,10 @@ CShadows::CalcPedShadowValues(CVector vecLightDir,
void
CShadows::RenderExtraPlayerShadows(void)
{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return;
+#endif
if ( CTimeCycle::GetLightShadowStrength() != 0 )
{
CVehicle *pCar = FindPlayerVehicle();
@@ -1647,9 +1642,9 @@ CShadows::RenderExtraPlayerShadows(void)
int32 nColorStrength;
if ( fLightDist < fRadius*0.5f )
- nColorStrength = CTimeCycle::GetLightShadowStrength();
+ nColorStrength = (5*CTimeCycle::GetLightShadowStrength()/8);
else
- nColorStrength = int32(CTimeCycle::GetLightShadowStrength() * fMult);
+ nColorStrength = int32((5*CTimeCycle::GetLightShadowStrength()/8) * fMult);
float fInv = 1.0f / fLightDist;
vecLight.x *= fInv;
@@ -1768,40 +1763,7 @@ CShadows::RenderIndicatorShadow(uint32 nID, uint8 ShadowType, RwTexture *pTextur
{
ASSERT(pPosn != NULL);
- C3dMarkers::PlaceMarkerSet(nID, _TODOCONST(4), *pPosn, max(fFrontX, -fSideY),
+ C3dMarkers::PlaceMarkerSet(nID, _TODOCONST(4), *pPosn, Max(fFrontX, -fSideY),
0, 128, 255, 128,
2048, 0.2f, 0);
}
-
-
-STARTPATCHES
- InjectHook(0x512AB0, CShadows::Init, PATCH_JUMP);
- InjectHook(0x512F20, CShadows::Shutdown, PATCH_JUMP);
- InjectHook(0x512FD0, CShadows::AddPermanentShadow, PATCH_JUMP);
- InjectHook(0x5130A0, CShadows::StoreStaticShadow, PATCH_JUMP);
- InjectHook(0x513550, (void(*)(uint8, CVector *, float, float, float, float, int16, uint8, uint8, uint8))CShadows::StoreShadowToBeRendered, PATCH_JUMP);
- InjectHook(0x513750, (void(*)(uint8, RwTexture *, CVector *, float, float, float, float, int16, uint8, uint8, uint8, float, bool, float))CShadows::StoreShadowToBeRendered, PATCH_JUMP);
- InjectHook(0x513830, CShadows::StoreShadowForCar, PATCH_JUMP);
- InjectHook(0x513A70, CShadows::StoreCarLightShadow, PATCH_JUMP);
- InjectHook(0x513C50, CShadows::StoreShadowForPed, PATCH_JUMP);
- InjectHook(0x513CB0, CShadows::StoreShadowForPedObject, PATCH_JUMP);
- InjectHook(0x513E00, CShadows::StoreShadowForTree, PATCH_JUMP);
- InjectHook(0x513E10, CShadows::StoreShadowForPole, PATCH_JUMP);
- InjectHook(0x513FC0, CShadows::SetRenderModeForShadowType, PATCH_JUMP);
- InjectHook(0x514010, CShadows::RenderStoredShadows, PATCH_JUMP);
- InjectHook(0x5145F0, CShadows::RenderStaticShadows, PATCH_JUMP);
- InjectHook(0x514910, CShadows::GeneratePolysForStaticShadow, PATCH_JUMP);
- InjectHook(0x514C90, CShadows::CastShadowSectorList, PATCH_JUMP);
- InjectHook(0x514E30, CShadows::CastShadowEntity, PATCH_JUMP);
- InjectHook(0x516BE0, CShadows::UpdateStaticShadows, PATCH_JUMP);
- InjectHook(0x516C40, CShadows::UpdatePermanentShadows, PATCH_JUMP);
- InjectHook(0x516E70, &CStaticShadow::Free, PATCH_JUMP);
- InjectHook(0x516EB0, CShadows::CalcPedShadowValues, PATCH_JUMP);
- InjectHook(0x516F90, CShadows::RenderExtraPlayerShadows, PATCH_JUMP);
- InjectHook(0x517570, CShadows::TidyUpShadows, PATCH_JUMP);
- InjectHook(0x517810, CShadows::RenderIndicatorShadow, PATCH_JUMP);
- //InjectHook(0x517900, &CPermanentShadow::CPermanentShadow, PATCH_JUMP);
- //InjectHook(0x517910, &CStaticShadow::CStaticShadow, PATCH_JUMP);
- //InjectHook(0x517920, &CPolyBunch::CPolyBunch, PATCH_JUMP);
- //InjectHook(0x517940, &CStoredShadow::CStoredShadow, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index fb41ebbc..65274879 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -6,7 +6,6 @@
#define MAX_PERMAMENTSHADOWS 48
-struct RwTexture;
class CEntity;
enum eShadowType
@@ -47,7 +46,6 @@ public:
uint8 bRendered : 1;
//uint8 bDrawOnBuildings : 1;
} m_nFlags;
- char _pad0;
RwTexture *m_pTexture;
CStoredShadow()
@@ -59,11 +57,9 @@ class CPolyBunch
{
public:
int16 m_nNumVerts;
- char _pad0[2];
CVector m_aVerts[7];
uint8 m_aU[7];
uint8 m_aV[7];
- char _pad1[2];
CPolyBunch *m_pNext;
CPolyBunch()
@@ -83,7 +79,6 @@ public:
float m_fZDistance;
float m_fScale;
uint8 m_nType;
- char _pad0;
int16 m_nIntensity; // unsigned ?
uint8 m_nRed;
uint8 m_nGreen;
@@ -91,7 +86,6 @@ public:
bool m_bJustCreated;
bool m_bRendered;
bool m_bTemp;
- char _pad1[2];
RwTexture *m_pTexture;
CStaticShadow()
@@ -114,7 +108,6 @@ public:
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
- char _pad0[2];
uint32 m_nTimeCreated;
uint32 m_nLifeTime;
RwTexture *m_pTexture;
@@ -175,18 +168,18 @@ public:
static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
};
-extern RwTexture *&gpShadowCarTex;
-extern RwTexture *&gpShadowPedTex;
-extern RwTexture *&gpShadowHeliTex;
-extern RwTexture *&gpShadowExplosionTex;
-extern RwTexture *&gpShadowHeadLightsTex;
-extern RwTexture *&gpOutline1Tex;
-extern RwTexture *&gpOutline2Tex;
-extern RwTexture *&gpOutline3Tex;
-extern RwTexture *&gpBloodPoolTex;
-extern RwTexture *&gpReflectionTex;
-extern RwTexture *&gpGoalMarkerTex;
-extern RwTexture *&gpWalkDontTex;
-extern RwTexture *&gpCrackedGlassTex;
-extern RwTexture *&gpPostShadowTex;
-extern RwTexture *&gpGoalTex;
+extern RwTexture *gpShadowCarTex;
+extern RwTexture *gpShadowPedTex;
+extern RwTexture *gpShadowHeliTex;
+extern RwTexture *gpShadowExplosionTex;
+extern RwTexture *gpShadowHeadLightsTex;
+extern RwTexture *gpOutline1Tex;
+extern RwTexture *gpOutline2Tex;
+extern RwTexture *gpOutline3Tex;
+extern RwTexture *gpBloodPoolTex;
+extern RwTexture *gpReflectionTex;
+extern RwTexture *gpGoalMarkerTex;
+extern RwTexture *gpWalkDontTex;
+extern RwTexture *gpCrackedGlassTex;
+extern RwTexture *gpPostShadowTex;
+extern RwTexture *gpGoalTex;
diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp
index 41ee5d1d..f3479536 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/render/Skidmarks.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "TxdStore.h"
#include "Timer.h"
@@ -214,7 +214,8 @@ CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *i
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
- dist.Normalise();
+ dist.NormaliseSafe();
+ fwd.NormaliseSafe();
CVector2D right(dist.y, -dist.x);
float turn = DotProduct2D(fwd, right);
turn = Abs(turn) + 1.0f;
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 9189a7c2..fc081fa3 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "SpecialFX.h"
#include "RenderBuffer.h"
#include "Timer.h"
@@ -117,8 +117,14 @@ CSpecialFX::Update(void)
if(FindPlayerPed() &&
FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
- FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING)
- RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
+ FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING){
+#ifdef PED_SKIN
+ if(IsClumpSkinned(FindPlayerPed()->GetClump())){
+ LookForBatCB((RwObject*)FindPlayerPed()->m_pWeaponModel, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
+ }else
+#endif
+ RwFrameForAllObjects(FindPlayerPed()->m_pFrames[PED_HANDR]->frame, LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
+ }
}
void
@@ -1151,32 +1157,3 @@ CSpecialParticleStuff::UpdateBoatFoamAnimation(CMatrix* pMatrix)
dZ = 2.0f;
}
}
-
-STARTPATCHES
- InjectHook(0x518DE0, &CBulletTraces::Init, PATCH_JUMP);
- InjectHook(0x518E90, &CBulletTraces::AddTrace, PATCH_JUMP);
- InjectHook(0x518F20, &CBulletTraces::Render, PATCH_JUMP);
- InjectHook(0x519240, &CBulletTraces::Update, PATCH_JUMP);
-
- InjectHook(0x51B070, &C3dMarker::AddMarker, PATCH_JUMP);
- InjectHook(0x51B170, &C3dMarker::DeleteMarkerObject, PATCH_JUMP);
- InjectHook(0x51B1B0, &C3dMarker::Render, PATCH_JUMP);
- InjectHook(0x51B2B0, C3dMarkers::Init, PATCH_JUMP);
- InjectHook(0x51B480, C3dMarkers::PlaceMarker, PATCH_JUMP);
- InjectHook(0x51BB80, C3dMarkers::PlaceMarkerSet, PATCH_JUMP);
- InjectHook(0x51B400, C3dMarkers::Render, PATCH_JUMP);
- InjectHook(0x51B3B0, C3dMarkers::Shutdown, PATCH_JUMP);
-
- InjectHook(0x5197A0, CBrightLights::Init, PATCH_JUMP);
- InjectHook(0x51A410, CBrightLights::RegisterOne, PATCH_JUMP);
- InjectHook(0x5197B0, CBrightLights::Render, PATCH_JUMP);
- InjectHook(0x51A3B0, CBrightLights::RenderOutGeometryBuffer, PATCH_JUMP);
-
- InjectHook(0x51A5A0, CShinyTexts::Init, PATCH_JUMP);
- InjectHook(0x51AAB0, CShinyTexts::RegisterOne, PATCH_JUMP);
- InjectHook(0x51A5B0, CShinyTexts::Render, PATCH_JUMP);
- InjectHook(0x51AA50, CShinyTexts::RenderOutGeometryBuffer, PATCH_JUMP);
-
- InjectHook(0x51AF70, CMoneyMessages::Init, PATCH_JUMP);
- InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp
index 8ac2315f..30eaf840 100644
--- a/src/render/Sprite.cpp
+++ b/src/render/Sprite.cpp
@@ -1,14 +1,14 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Draw.h"
#include "Camera.h"
#include "Sprite.h"
-float &CSprite::m_f2DNearScreenZ = *(float*)0x8F1ABC;
-float &CSprite::m_f2DFarScreenZ = *(float*)0x8F2C94;
-float &CSprite::m_fRecipNearClipPlane = *(float*)0x8F5FFC;
-int32 &CSprite::m_bFlushSpriteBufferSwitchZTest = *(int32*)0x8F5FB0;
+float CSprite::m_f2DNearScreenZ;
+float CSprite::m_f2DFarScreenZ;
+float CSprite::m_fRecipNearClipPlane;
+int32 CSprite::m_bFlushSpriteBufferSwitchZTest;
float
CSprite::CalcHorizonCoors(void)
@@ -40,9 +40,9 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
}
#define SPRITEBUFFERSIZE 64
-static int32 &nSpriteBufferIndex = *(int32*)0x649A80;
-static RwIm2DVertex *SpriteBufferVerts = (RwIm2DVertex*)0x649A84; //[SPRITEBUFFERSIZE*6];
-static RwIm2DVertex *verts = (RwIm2DVertex*)0x64C484; //[4];
+static int32 nSpriteBufferIndex;
+static RwIm2DVertex SpriteBufferVerts[SPRITEBUFFERSIZE*6];
+static RwIm2DVertex verts[4];
void
CSprite::InitSpriteBuffer(void)
@@ -137,8 +137,8 @@ CSprite::RenderOneXLUSprite(float x, float y, float z, float w, float h, uint8 r
void
CSprite::RenderOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a)
{
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
float xs[4];
float ys[4];
@@ -315,8 +315,8 @@ void
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, float h, uint8 r, uint8 g, uint8 b, int16 intens, float recipz, float rotation, uint8 a)
{
m_bFlushSpriteBufferSwitchZTest = 0;
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
float xs[4];
float ys[4];
@@ -367,8 +367,8 @@ void
CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours(float x, float y, float z, float w, float h, uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2, float cx, float cy, float recipz, float rotation, uint8 a)
{
m_bFlushSpriteBufferSwitchZTest = 0;
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
float xs[4];
float ys[4];
@@ -398,11 +398,11 @@ CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours(float x, float y, float z, f
// Colour factors, cx/y is the direction in which colours change from rgb1 to rgb2
cf[0] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
cf[0] = clamp(cf[0], 0.0f, 1.0f);
- cf[1] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
+ cf[1] = (cx*(-c+s) + cy*( c+s))*0.5f + 0.5f;
cf[1] = clamp(cf[1], 0.0f, 1.0f);
- cf[2] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
+ cf[2] = (cx*( c+s) + cy*( c-s))*0.5f + 0.5f;
cf[2] = clamp(cf[2], 0.0f, 1.0f);
- cf[3] = (cx*(-c-s) + cy*(-c+s))*0.5f + 0.5f;
+ cf[3] = (cx*( c-s) + cy*(-c-s))*0.5f + 0.5f;
cf[3] = clamp(cf[3], 0.0f, 1.0f);
float screenz = m_f2DNearScreenZ +
@@ -593,19 +593,3 @@ CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(float x, float y, float w
if(nSpriteBufferIndex >= SPRITEBUFFERSIZE)
FlushSpriteBuffer();
}
-
-STARTPATCHES
- InjectHook(0x51C4A0, CSprite::CalcHorizonCoors, PATCH_JUMP);
- InjectHook(0x51C3A0, CSprite::CalcScreenCoors, PATCH_JUMP);
- InjectHook(0x51C590, CSprite::InitSpriteBuffer, PATCH_JUMP);
- InjectHook(0x51C5B0, CSprite::InitSpriteBuffer2D, PATCH_JUMP);
- InjectHook(0x51C520, CSprite::FlushSpriteBuffer, PATCH_JUMP);
- InjectHook(0x51C960, CSprite::RenderOneXLUSprite, PATCH_JUMP);
- InjectHook(0x51D110, CSprite::RenderOneXLUSprite_Rotate_Aspect, PATCH_JUMP);
- InjectHook(0x51C5D0, CSprite::RenderBufferedOneXLUSprite, PATCH_JUMP);
- InjectHook(0x51D5B0, CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension, PATCH_JUMP);
- InjectHook(0x51CCD0, CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect, PATCH_JUMP);
- InjectHook(0x51D9E0, CSprite::RenderBufferedOneXLUSprite_Rotate_2Colours, PATCH_JUMP);
- InjectHook(0x51E3C0, CSprite::RenderBufferedOneXLUSprite2D, PATCH_JUMP);
- InjectHook(0x51E490, CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Sprite.h b/src/render/Sprite.h
index 33953ff3..ec4c1d1b 100644
--- a/src/render/Sprite.h
+++ b/src/render/Sprite.h
@@ -2,10 +2,10 @@
class CSprite
{
- static float &m_f2DNearScreenZ;
- static float &m_f2DFarScreenZ;
- static float &m_fRecipNearClipPlane;
- static int32 &m_bFlushSpriteBufferSwitchZTest;
+ static float m_f2DNearScreenZ;
+ static float m_f2DFarScreenZ;
+ static float m_fRecipNearClipPlane;
+ static int32 m_bFlushSpriteBufferSwitchZTest;
public:
static float CalcHorizonCoors(void);
static bool CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh, bool farclip);
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index 3f21516a..52b85018 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -1,17 +1,17 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Draw.h"
#include "Camera.h"
#include "Sprite2d.h"
-RwIm2DVertex *CSprite2d::maVertices = (RwIm2DVertex*)0x6E9168;
-float &CSprite2d::RecipNearClip = *(float*)0x880DB4;
-int32 &CSprite2d::mCurrentBank = *(int32*)0x8F1AF4;
-RwTexture **CSprite2d::mpBankTextures = (RwTexture**)0x774DC0;
-int32 *CSprite2d::mCurrentSprite = (int32*)0x6F4500;
-int32 *CSprite2d::mBankStart = (int32*)0x774BE8;
-RwIm2DVertex *CSprite2d::maBankVertices = (RwIm2DVertex*)0x8429F8;
+RwIm2DVertex CSprite2d::maVertices[8];
+float CSprite2d::RecipNearClip;
+int32 CSprite2d::mCurrentBank;
+RwTexture *CSprite2d::mpBankTextures[10];
+int32 CSprite2d::mCurrentSprite[10];
+int32 CSprite2d::mBankStart[10];
+RwIm2DVertex CSprite2d::maBankVertices[500];
void
CSprite2d::SetRecipNearClip(void)
@@ -474,37 +474,3 @@ void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3,
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
}
-
-STARTPATCHES
-#define C4 const CRGBA&, const CRGBA&, const CRGBA&, const CRGBA&
-#define F8 float, float, float, float, float, float, float, float
-
- InjectHook(0x51EA20, CSprite2d::SetRecipNearClip, PATCH_JUMP);
- InjectHook(0x51EAE0, CSprite2d::InitPerFrame, PATCH_JUMP);
- InjectHook(0x51EB70, CSprite2d::GetBank, PATCH_JUMP);
- InjectHook(0x51EBC0, CSprite2d::AddSpriteToBank, PATCH_JUMP);
- InjectHook(0x51EC50, CSprite2d::DrawBank, PATCH_JUMP);
-
- InjectHook(0x51EA00, &CSprite2d::Delete, PATCH_JUMP);
- InjectHook(0x51F950, &CSprite2d::SetRenderState, PATCH_JUMP);
- InjectHook(0x51EA40, (void (CSprite2d::*)(const char*))&CSprite2d::SetTexture, PATCH_JUMP);
- InjectHook(0x51EA70, (void (CSprite2d::*)(const char*,const char*))&CSprite2d::SetTexture, PATCH_JUMP);
- InjectHook(0x51EAA0, &CSprite2d::SetAddressing, PATCH_JUMP);
-
- InjectHook(0x51EE90, (void (*)(const CRect&, C4, uint32))CSprite2d::SetVertices, PATCH_JUMP);
- InjectHook(0x51F220, (void (*)(const CRect&, C4, F8))CSprite2d::SetVertices, PATCH_JUMP);
- InjectHook(0x51F070, (void (*)(F8, C4))CSprite2d::SetVertices, PATCH_JUMP);
- InjectHook(0x51F3E0, (void (*)(int, float*, float*, const CRGBA&))CSprite2d::SetVertices, PATCH_JUMP);
- InjectHook(0x51F490, CSprite2d::SetMaskVertices, PATCH_JUMP);
- InjectHook(0x51F720, (void (*)(RwIm2DVertex*, const CRect&, C4, F8))CSprite2d::SetVertices, PATCH_JUMP);
-
- InjectHook(0x51ECE0, (void (CSprite2d::*)(float, float, float, float, const CRGBA &))&CSprite2d::Draw, PATCH_JUMP);
- InjectHook(0x51ED50, (void (CSprite2d::*)(const CRect &, const CRGBA &))&CSprite2d::Draw, PATCH_JUMP);
- InjectHook(0x51ED90, (void (CSprite2d::*)(const CRect &, const CRGBA &, F8))&CSprite2d::Draw, PATCH_JUMP);
- InjectHook(0x51EDF0, (void (CSprite2d::*)(const CRect &, C4))&CSprite2d::Draw, PATCH_JUMP);
- InjectHook(0x51EE40, (void (CSprite2d::*)(F8, const CRGBA &))&CSprite2d::Draw, PATCH_JUMP);
-
- InjectHook(0x51F970, (void (*)(const CRect&, const CRGBA&))CSprite2d::DrawRect, PATCH_JUMP);
- InjectHook(0x51FA00, (void (*)(const CRect&, C4))CSprite2d::DrawRect, PATCH_JUMP);
- InjectHook(0x51FA80, CSprite2d::DrawRectXLU, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Sprite2d.h b/src/render/Sprite2d.h
index 268c7d2b..0e12d441 100644
--- a/src/render/Sprite2d.h
+++ b/src/render/Sprite2d.h
@@ -2,13 +2,13 @@
class CSprite2d
{
- static float &RecipNearClip;
- static int32 &mCurrentBank;
- static RwTexture **mpBankTextures; //[10];
- static int32 *mCurrentSprite; //[10];
- static int32 *mBankStart; //[10];
- static RwIm2DVertex *maBankVertices; //[500];
- static RwIm2DVertex *maVertices; //[4];
+ static float RecipNearClip;
+ static int32 mCurrentBank;
+ static RwTexture *mpBankTextures[10];
+ static int32 mCurrentSprite[10];
+ static int32 mBankStart[10];
+ static RwIm2DVertex maBankVertices[500];
+ static RwIm2DVertex maVertices[8];
public:
RwTexture *m_pTexture;
diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp
index 7ab3e91e..cf3426d7 100644
--- a/src/render/Timecycle.cpp
+++ b/src/render/Timecycle.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "Clock.h"
#include "Weather.h"
@@ -10,101 +10,101 @@
#include "FileMgr.h"
#include "Timecycle.h"
-int (*CTimeCycle::m_nAmbientRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x86AF78;
-int (*CTimeCycle::m_nAmbientGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x665308;
-int (*CTimeCycle::m_nAmbientBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x72CF88;
-int (*CTimeCycle::m_nDirectionalRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6FAB78;
-int (*CTimeCycle::m_nDirectionalGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6F4528;
-int (*CTimeCycle::m_nDirectionalBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x83CE58;
-int (*CTimeCycle::m_nSkyTopRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x87FB90;
-int (*CTimeCycle::m_nSkyTopGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x8460A8;
-int (*CTimeCycle::m_nSkyTopBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x87B158;
-int (*CTimeCycle::m_nSkyBottomRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6FA960;
-int (*CTimeCycle::m_nSkyBottomGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x70D6A8;
-int (*CTimeCycle::m_nSkyBottomBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x83D288;
-int (*CTimeCycle::m_nSunCoreRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x878360;
-int (*CTimeCycle::m_nSunCoreGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6EE088;
-int (*CTimeCycle::m_nSunCoreBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x773A68;
-int (*CTimeCycle::m_nSunCoronaRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x664B60;
-int (*CTimeCycle::m_nSunCoronaGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6F01E0;
-int (*CTimeCycle::m_nSunCoronaBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6E6340;
-float (*CTimeCycle::m_fSunSize)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x733510;
-float (*CTimeCycle::m_fSpriteSize)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x87F820;
-float (*CTimeCycle::m_fSpriteBrightness)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x6E96F0;
-short (*CTimeCycle::m_nShadowStrength)[NUMWEATHERS] = (short(*)[NUMWEATHERS])0x83CFD8;
-short (*CTimeCycle::m_nLightShadowStrength)[NUMWEATHERS] = (short(*)[NUMWEATHERS])0x72B0F8;
-short (*CTimeCycle::m_nTreeShadowStrength)[NUMWEATHERS] = (short(*)[NUMWEATHERS])0x733450;
-float (*CTimeCycle::m_fFogStart)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x8806C8;
-float (*CTimeCycle::m_fFarClip)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x8804E0;
-float (*CTimeCycle::m_fLightsOnGroundBrightness)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x83D108;
-int (*CTimeCycle::m_nLowCloudsRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x726770;
-int (*CTimeCycle::m_nLowCloudsGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x87BF08;
-int (*CTimeCycle::m_nLowCloudsBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x87FA10;
-int (*CTimeCycle::m_nFluffyCloudsTopRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x70F2B0;
-int (*CTimeCycle::m_nFluffyCloudsTopGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x72D288;
-int (*CTimeCycle::m_nFluffyCloudsTopBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x86B108;
-int (*CTimeCycle::m_nFluffyCloudsBottomRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6E8DA8;
-int (*CTimeCycle::m_nFluffyCloudsBottomGreen)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x715AA8;
-int (*CTimeCycle::m_nFluffyCloudsBottomBlue)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x6EE2D0;
-float (*CTimeCycle::m_fBlurRed)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x87C7E0;
-float (*CTimeCycle::m_fBlurGreen)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x774C10;
-float (*CTimeCycle::m_fBlurBlue)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x8784E0;
-float (*CTimeCycle::m_fBlurAlpha)[NUMWEATHERS] = (float(*)[NUMWEATHERS])0x733690;
-
-float &CTimeCycle::m_fCurrentAmbientRed = *(float*)0x8F29B4;
-float &CTimeCycle::m_fCurrentAmbientGreen = *(float*)0x94144C;
-float &CTimeCycle::m_fCurrentAmbientBlue = *(float*)0x942FC0;
-float &CTimeCycle::m_fCurrentDirectionalRed = *(float*)0x8F29D8;
-float &CTimeCycle::m_fCurrentDirectionalGreen = *(float*)0x940594;
-float &CTimeCycle::m_fCurrentDirectionalBlue = *(float*)0x942FAC;
-int &CTimeCycle::m_nCurrentSkyTopRed = *(int*)0x9403C0;
-int &CTimeCycle::m_nCurrentSkyTopGreen = *(int*)0x943074;
-int &CTimeCycle::m_nCurrentSkyTopBlue = *(int*)0x8F29B8;
-int &CTimeCycle::m_nCurrentSkyBottomRed = *(int*)0x9414D0;
-int &CTimeCycle::m_nCurrentSkyBottomGreen = *(int*)0x8F2BD0;
-int &CTimeCycle::m_nCurrentSkyBottomBlue = *(int*)0x8F625C;
-int &CTimeCycle::m_nCurrentSunCoreRed = *(int*)0x8F2534;
-int &CTimeCycle::m_nCurrentSunCoreGreen = *(int*)0x8F6264;
-int &CTimeCycle::m_nCurrentSunCoreBlue = *(int*)0x94149C;
-int &CTimeCycle::m_nCurrentSunCoronaRed = *(int*)0x8F2C1C;
-int &CTimeCycle::m_nCurrentSunCoronaGreen = *(int*)0x885B54;
-int &CTimeCycle::m_nCurrentSunCoronaBlue = *(int*)0x880F60;
-float &CTimeCycle::m_fCurrentSunSize = *(float*)0x940588;
-float &CTimeCycle::m_fCurrentSpriteSize = *(float*)0x8F1AA8;
-float &CTimeCycle::m_fCurrentSpriteBrightness = *(float*)0x8F5FDC;
-int &CTimeCycle::m_nCurrentShadowStrength = *(int*)0x95CC76;
-int &CTimeCycle::m_nCurrentLightShadowStrength = *(int*)0x95CC66;
-int &CTimeCycle::m_nCurrentTreeShadowStrength = *(int*)0x95CC86;
-float &CTimeCycle::m_fCurrentFogStart = *(float*)0x8F1AE0;
-float &CTimeCycle::m_fCurrentFarClip = *(float*)0x8F5FD8;
-float &CTimeCycle::m_fCurrentLightsOnGroundBrightness = *(float*)0x8F1B60;
-int &CTimeCycle::m_nCurrentLowCloudsRed = *(int*)0x95CB54;
-int &CTimeCycle::m_nCurrentLowCloudsGreen = *(int*)0x95CB48;
-int &CTimeCycle::m_nCurrentLowCloudsBlue = *(int*)0x95CC1C;
-int &CTimeCycle::m_nCurrentFluffyCloudsTopRed = *(int*)0x8F2550;
-int &CTimeCycle::m_nCurrentFluffyCloudsTopGreen = *(int*)0x8F59CC;
-int &CTimeCycle::m_nCurrentFluffyCloudsTopBlue = *(int*)0x941434;
-int &CTimeCycle::m_nCurrentFluffyCloudsBottomRed = *(int*)0x8F1A38;
-int &CTimeCycle::m_nCurrentFluffyCloudsBottomGreen = *(int*)0x8E28B8;
-int &CTimeCycle::m_nCurrentFluffyCloudsBottomBlue = *(int*)0x8F3960;
-float &CTimeCycle::m_fCurrentBlurRed = *(float*)0x8F6000;
-float &CTimeCycle::m_fCurrentBlurGreen = *(float*)0x9405A0;
-float &CTimeCycle::m_fCurrentBlurBlue = *(float*)0x8F250C;
-float &CTimeCycle::m_fCurrentBlurAlpha = *(float*)0x940728;
-int &CTimeCycle::m_nCurrentFogColourRed = *(int*)0x940714;
-int &CTimeCycle::m_nCurrentFogColourGreen = *(int*)0x8E2A60;
-int &CTimeCycle::m_nCurrentFogColourBlue = *(int*)0x8F57EC;
-
-int &CTimeCycle::m_FogReduction = *(int*)0x880FB8;
-
-int &CTimeCycle::m_CurrentStoredValue = *(int*)0x94057C;
-CVector *CTimeCycle::m_VectorToSun = (CVector*)0x665548; // [16]
-float *CTimeCycle::m_fShadowFrontX = (float*)0x72CE90;
-float *CTimeCycle::m_fShadowFrontY = (float*)0x72CE50;
-float *CTimeCycle::m_fShadowSideX = (float*)0x87C708;
-float *CTimeCycle::m_fShadowSideY = (float*)0x87C6C8;
-float *CTimeCycle::m_fShadowDisplacementX = (float*)0x6F0748;
-float *CTimeCycle::m_fShadowDisplacementY = (float*)0x6F0788;
+int CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+short CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+short CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+short CTimeCycle::m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
+
+float CTimeCycle::m_fCurrentAmbientRed;
+float CTimeCycle::m_fCurrentAmbientGreen;
+float CTimeCycle::m_fCurrentAmbientBlue;
+float CTimeCycle::m_fCurrentDirectionalRed;
+float CTimeCycle::m_fCurrentDirectionalGreen;
+float CTimeCycle::m_fCurrentDirectionalBlue;
+int CTimeCycle::m_nCurrentSkyTopRed;
+int CTimeCycle::m_nCurrentSkyTopGreen;
+int CTimeCycle::m_nCurrentSkyTopBlue;
+int CTimeCycle::m_nCurrentSkyBottomRed;
+int CTimeCycle::m_nCurrentSkyBottomGreen;
+int CTimeCycle::m_nCurrentSkyBottomBlue;
+int CTimeCycle::m_nCurrentSunCoreRed;
+int CTimeCycle::m_nCurrentSunCoreGreen;
+int CTimeCycle::m_nCurrentSunCoreBlue;
+int CTimeCycle::m_nCurrentSunCoronaRed;
+int CTimeCycle::m_nCurrentSunCoronaGreen;
+int CTimeCycle::m_nCurrentSunCoronaBlue;
+float CTimeCycle::m_fCurrentSunSize;
+float CTimeCycle::m_fCurrentSpriteSize;
+float CTimeCycle::m_fCurrentSpriteBrightness;
+int CTimeCycle::m_nCurrentShadowStrength;
+int CTimeCycle::m_nCurrentLightShadowStrength;
+int CTimeCycle::m_nCurrentTreeShadowStrength;
+float CTimeCycle::m_fCurrentFogStart;
+float CTimeCycle::m_fCurrentFarClip;
+float CTimeCycle::m_fCurrentLightsOnGroundBrightness;
+int CTimeCycle::m_nCurrentLowCloudsRed;
+int CTimeCycle::m_nCurrentLowCloudsGreen;
+int CTimeCycle::m_nCurrentLowCloudsBlue;
+int CTimeCycle::m_nCurrentFluffyCloudsTopRed;
+int CTimeCycle::m_nCurrentFluffyCloudsTopGreen;
+int CTimeCycle::m_nCurrentFluffyCloudsTopBlue;
+int CTimeCycle::m_nCurrentFluffyCloudsBottomRed;
+int CTimeCycle::m_nCurrentFluffyCloudsBottomGreen;
+int CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
+float CTimeCycle::m_fCurrentBlurRed;
+float CTimeCycle::m_fCurrentBlurGreen;
+float CTimeCycle::m_fCurrentBlurBlue;
+float CTimeCycle::m_fCurrentBlurAlpha;
+int CTimeCycle::m_nCurrentFogColourRed;
+int CTimeCycle::m_nCurrentFogColourGreen;
+int CTimeCycle::m_nCurrentFogColourBlue;
+
+int CTimeCycle::m_FogReduction;
+
+int CTimeCycle::m_CurrentStoredValue;
+CVector CTimeCycle::m_VectorToSun[16];
+float CTimeCycle::m_fShadowFrontX[16];
+float CTimeCycle::m_fShadowFrontY[16];
+float CTimeCycle::m_fShadowSideX[16];
+float CTimeCycle::m_fShadowSideY[16];
+float CTimeCycle::m_fShadowDisplacementX[16];
+float CTimeCycle::m_fShadowDisplacementY[16];
void
@@ -290,7 +290,7 @@ CTimeCycle::Update(void)
TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, m_fCurrentBlurAlpha, MBLUR_NORMAL);
if(m_FogReduction != 0)
- m_fCurrentFarClip = max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
+ m_fCurrentFarClip = Max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
@@ -311,12 +311,7 @@ CTimeCycle::Update(void)
if(TheCamera.GetForward().z < -0.9f ||
!CWeather::bScriptsForceRain && (CCullZones::PlayerNoRain() || CCullZones::CamNoRain() || CCutsceneMgr::IsRunning()))
- m_FogReduction = min(m_FogReduction+1, 64);
+ m_FogReduction = Min(m_FogReduction+1, 64);
else
- m_FogReduction = max(m_FogReduction-1, 0);
+ m_FogReduction = Max(m_FogReduction-1, 0);
}
-
-STARTPATCHES
- InjectHook(0x4ABAE0, CTimeCycle::Initialise, PATCH_JUMP);
- InjectHook(0x4ABF40, CTimeCycle::Update, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h
index ed4a026b..28a0b7dd 100644
--- a/src/render/Timecycle.h
+++ b/src/render/Timecycle.h
@@ -2,102 +2,102 @@
class CTimeCycle
{
- static int (*m_nAmbientRed)[NUMWEATHERS];
- static int (*m_nAmbientGreen)[NUMWEATHERS];
- static int (*m_nAmbientBlue)[NUMWEATHERS];
- static int (*m_nDirectionalRed)[NUMWEATHERS];
- static int (*m_nDirectionalGreen)[NUMWEATHERS];
- static int (*m_nDirectionalBlue)[NUMWEATHERS];
- static int (*m_nSkyTopRed)[NUMWEATHERS];
- static int (*m_nSkyTopGreen)[NUMWEATHERS];
- static int (*m_nSkyTopBlue)[NUMWEATHERS];
- static int (*m_nSkyBottomRed)[NUMWEATHERS];
- static int (*m_nSkyBottomGreen)[NUMWEATHERS];
- static int (*m_nSkyBottomBlue)[NUMWEATHERS];
- static int (*m_nSunCoreRed)[NUMWEATHERS];
- static int (*m_nSunCoreGreen)[NUMWEATHERS];
- static int (*m_nSunCoreBlue)[NUMWEATHERS];
- static int (*m_nSunCoronaRed)[NUMWEATHERS];
- static int (*m_nSunCoronaGreen)[NUMWEATHERS];
- static int (*m_nSunCoronaBlue)[NUMWEATHERS];
- static float (*m_fSunSize)[NUMWEATHERS];
- static float (*m_fSpriteSize)[NUMWEATHERS];
- static float (*m_fSpriteBrightness)[NUMWEATHERS];
- static short (*m_nShadowStrength)[NUMWEATHERS];
- static short (*m_nLightShadowStrength)[NUMWEATHERS];
- static short (*m_nTreeShadowStrength)[NUMWEATHERS];
- static float (*m_fFogStart)[NUMWEATHERS];
- static float (*m_fFarClip)[NUMWEATHERS];
- static float (*m_fLightsOnGroundBrightness)[NUMWEATHERS];
- static int (*m_nLowCloudsRed)[NUMWEATHERS];
- static int (*m_nLowCloudsGreen)[NUMWEATHERS];
- static int (*m_nLowCloudsBlue)[NUMWEATHERS];
- static int (*m_nFluffyCloudsTopRed)[NUMWEATHERS];
- static int (*m_nFluffyCloudsTopGreen)[NUMWEATHERS];
- static int (*m_nFluffyCloudsTopBlue)[NUMWEATHERS];
- static int (*m_nFluffyCloudsBottomRed)[NUMWEATHERS];
- static int (*m_nFluffyCloudsBottomGreen)[NUMWEATHERS];
- static int (*m_nFluffyCloudsBottomBlue)[NUMWEATHERS];
- static float (*m_fBlurRed)[NUMWEATHERS];
- static float (*m_fBlurGreen)[NUMWEATHERS];
- static float (*m_fBlurBlue)[NUMWEATHERS];
- static float (*m_fBlurAlpha)[NUMWEATHERS];
+ static int m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+ static int m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+ static float m_fSunSize[NUMHOURS][NUMWEATHERS];
+ static float m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+ static float m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+ static short m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+ static short m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+ static short m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
+ static float m_fFogStart[NUMHOURS][NUMWEATHERS];
+ static float m_fFarClip[NUMHOURS][NUMWEATHERS];
+ static float m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+ static int m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+ static int m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+ static int m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+ static float m_fBlurRed[NUMHOURS][NUMWEATHERS];
+ static float m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+ static float m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+ static float m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
- static float &m_fCurrentAmbientRed;
- static float &m_fCurrentAmbientGreen;
- static float &m_fCurrentAmbientBlue;
- static float &m_fCurrentDirectionalRed;
- static float &m_fCurrentDirectionalGreen;
- static float &m_fCurrentDirectionalBlue;
- static int &m_nCurrentSkyTopRed;
- static int &m_nCurrentSkyTopGreen;
- static int &m_nCurrentSkyTopBlue;
- static int &m_nCurrentSkyBottomRed;
- static int &m_nCurrentSkyBottomGreen;
- static int &m_nCurrentSkyBottomBlue;
- static int &m_nCurrentSunCoreRed;
- static int &m_nCurrentSunCoreGreen;
- static int &m_nCurrentSunCoreBlue;
- static int &m_nCurrentSunCoronaRed;
- static int &m_nCurrentSunCoronaGreen;
- static int &m_nCurrentSunCoronaBlue;
- static float &m_fCurrentSunSize;
- static float &m_fCurrentSpriteSize;
- static float &m_fCurrentSpriteBrightness;
- static int &m_nCurrentShadowStrength;
- static int &m_nCurrentLightShadowStrength;
- static int &m_nCurrentTreeShadowStrength;
- static float &m_fCurrentFogStart;
- static float &m_fCurrentFarClip;
- static float &m_fCurrentLightsOnGroundBrightness;
- static int &m_nCurrentLowCloudsRed;
- static int &m_nCurrentLowCloudsGreen;
- static int &m_nCurrentLowCloudsBlue;
- static int &m_nCurrentFluffyCloudsTopRed;
- static int &m_nCurrentFluffyCloudsTopGreen;
- static int &m_nCurrentFluffyCloudsTopBlue;
- static int &m_nCurrentFluffyCloudsBottomRed;
- static int &m_nCurrentFluffyCloudsBottomGreen;
- static int &m_nCurrentFluffyCloudsBottomBlue;
- static float &m_fCurrentBlurRed;
- static float &m_fCurrentBlurGreen;
- static float &m_fCurrentBlurBlue;
- static float &m_fCurrentBlurAlpha;
- static int &m_nCurrentFogColourRed;
- static int &m_nCurrentFogColourGreen;
- static int &m_nCurrentFogColourBlue;
+ static float m_fCurrentAmbientRed;
+ static float m_fCurrentAmbientGreen;
+ static float m_fCurrentAmbientBlue;
+ static float m_fCurrentDirectionalRed;
+ static float m_fCurrentDirectionalGreen;
+ static float m_fCurrentDirectionalBlue;
+ static int m_nCurrentSkyTopRed;
+ static int m_nCurrentSkyTopGreen;
+ static int m_nCurrentSkyTopBlue;
+ static int m_nCurrentSkyBottomRed;
+ static int m_nCurrentSkyBottomGreen;
+ static int m_nCurrentSkyBottomBlue;
+ static int m_nCurrentSunCoreRed;
+ static int m_nCurrentSunCoreGreen;
+ static int m_nCurrentSunCoreBlue;
+ static int m_nCurrentSunCoronaRed;
+ static int m_nCurrentSunCoronaGreen;
+ static int m_nCurrentSunCoronaBlue;
+ static float m_fCurrentSunSize;
+ static float m_fCurrentSpriteSize;
+ static float m_fCurrentSpriteBrightness;
+ static int m_nCurrentShadowStrength;
+ static int m_nCurrentLightShadowStrength;
+ static int m_nCurrentTreeShadowStrength;
+ static float m_fCurrentFogStart;
+ static float m_fCurrentFarClip;
+ static float m_fCurrentLightsOnGroundBrightness;
+ static int m_nCurrentLowCloudsRed;
+ static int m_nCurrentLowCloudsGreen;
+ static int m_nCurrentLowCloudsBlue;
+ static int m_nCurrentFluffyCloudsTopRed;
+ static int m_nCurrentFluffyCloudsTopGreen;
+ static int m_nCurrentFluffyCloudsTopBlue;
+ static int m_nCurrentFluffyCloudsBottomRed;
+ static int m_nCurrentFluffyCloudsBottomGreen;
+ static int m_nCurrentFluffyCloudsBottomBlue;
+ static float m_fCurrentBlurRed;
+ static float m_fCurrentBlurGreen;
+ static float m_fCurrentBlurBlue;
+ static float m_fCurrentBlurAlpha;
+ static int m_nCurrentFogColourRed;
+ static int m_nCurrentFogColourGreen;
+ static int m_nCurrentFogColourBlue;
- static int &m_FogReduction;
+ static int m_FogReduction;
public:
- static int &m_CurrentStoredValue;
- static CVector *m_VectorToSun; // [16]
- static float *m_fShadowFrontX; // [16]
- static float *m_fShadowFrontY; // [16]
- static float *m_fShadowSideX; // [16]
- static float *m_fShadowSideY; // [16]
- static float *m_fShadowDisplacementX; // [16]
- static float *m_fShadowDisplacementY; // [16]
+ static int m_CurrentStoredValue;
+ static CVector m_VectorToSun[16];
+ static float m_fShadowFrontX[16];
+ static float m_fShadowFrontY[16];
+ static float m_fShadowSideX[16];
+ static float m_fShadowSideY[16];
+ static float m_fShadowDisplacementX[16];
+ static float m_fShadowDisplacementY[16];
static float GetAmbientRed(void) { return m_fCurrentAmbientRed; }
static float GetAmbientGreen(void) { return m_fCurrentAmbientGreen; }
diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp
index e848fb43..2ef10d77 100644
--- a/src/render/WaterCannon.cpp
+++ b/src/render/WaterCannon.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "WaterCannon.h"
#include "Vector.h"
#include "General.h"
@@ -195,14 +195,14 @@ void CWaterCannon::PushPeds(void)
{
if ( m_abUsed[i] )
{
- minx = min(minx, m_avecPos[i].x);
- maxx = max(maxx, m_avecPos[i].x);
+ minx = Min(minx, m_avecPos[i].x);
+ maxx = Max(maxx, m_avecPos[i].x);
- miny = min(miny, m_avecPos[i].y);
- maxy = max(maxy, m_avecPos[i].y);
+ miny = Min(miny, m_avecPos[i].y);
+ maxy = Max(maxy, m_avecPos[i].y);
- minz = min(minz, m_avecPos[i].z);
- maxz = max(maxz, m_avecPos[i].z);
+ minz = Min(minz, m_avecPos[i].z);
+ maxz = Max(maxz, m_avecPos[i].z);
}
}
@@ -304,17 +304,3 @@ void CWaterCannons::Render(void)
aCannons[i].Render();
}
}
-
-STARTPATCHES
- InjectHook(0x521A30, &CWaterCannon::Init, PATCH_JUMP);
- InjectHook(0x521B80, &CWaterCannon::Update_OncePerFrame, PATCH_JUMP);
- InjectHook(0x521CC0, &CWaterCannon::Update_NewInput, PATCH_JUMP);
- InjectHook(0x521D30, &CWaterCannon::Render, PATCH_JUMP);
- InjectHook(0x5220B0, &CWaterCannon::PushPeds, PATCH_JUMP);
- InjectHook(0x522440, CWaterCannons::Init, PATCH_JUMP);
- InjectHook(0x522470, CWaterCannons::UpdateOne, PATCH_JUMP);
- InjectHook(0x522510, CWaterCannons::Update, PATCH_JUMP);
- InjectHook(0x522550, CWaterCannons::Render, PATCH_JUMP);
- //InjectHook(0x522B40, `global constructor keyed to'watercannon.cpp, PATCH_JUMP);
- //InjectHook(0x522B60, CWaterCannon::CWaterCannon, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h
index 826dc78e..d2d20863 100644
--- a/src/render/WaterCannon.h
+++ b/src/render/WaterCannon.h
@@ -13,7 +13,6 @@ public:
int32 m_nId;
int16 m_nCur;
- char _pad0[2];
uint32 m_nTimeCreated;
CVector m_avecPos[NUM_SEGMENTPOINTS];
CVector m_avecVelocity[NUM_SEGMENTPOINTS];
diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp
index a1c2af93..d7035ab1 100644
--- a/src/render/WaterLevel.cpp
+++ b/src/render/WaterLevel.cpp
@@ -21,7 +21,7 @@
#include "RenderBuffer.h"
#include <rpworld.h>
#include "WaterLevel.h"
-#include "patcher.h"
+
float TEXTURE_ADDU;
float TEXTURE_ADDV;
@@ -39,8 +39,8 @@ int16 CWaterLevel::nGeomUsed;
//RwTexture *gpWaterTex;
//RwRaster *gpWaterRaster;
-RwTexture *&gpWaterTex = *(RwTexture **)0x64D070;
-RwRaster *&gpWaterRaster = *(RwRaster **)0x8F5FD4;
+RwTexture *gpWaterTex;
+RwRaster *gpWaterRaster;
const float fAdd1 = 180.0f;
@@ -979,7 +979,7 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col
SMALL_SECTOR_SIZE / 2,
apBoatList) )
{
- float fWakeColor = fAdd1 - max(255.0f - float(color.blue + color.red + color.green) / 3, fAdd2);
+ float fWakeColor = fAdd1 - Max(255.0f - float(color.blue + color.red + color.green) / 3, fAdd2);
RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
RpGeometry *geom = apGeomArray[nGeomUsed++];
@@ -1035,9 +1035,9 @@ CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &col
RwRGBAAssign(&wakeColor, &color);
- wakeColor.red = min(color.red + int32(fWakeColor * fRedMult * fDistMult), 255);
- wakeColor.green = min(color.green + int32(fWakeColor * fGreenMult * fDistMult), 255);
- wakeColor.blue = min(color.blue + int32(fWakeColor * fBlueMult * fDistMult), 255);
+ wakeColor.red = Min(color.red + int32(fWakeColor * fRedMult * fDistMult), 255);
+ wakeColor.green = Min(color.green + int32(fWakeColor * fGreenMult * fDistMult), 255);
+ wakeColor.blue = Min(color.blue + int32(fWakeColor * fBlueMult * fDistMult), 255);
RwRGBAAssign(&geomPreLights[9*i+j], &wakeColor);
@@ -1114,7 +1114,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY)
fSectorY + SMALL_SECTOR_SIZE - fY
);
- fDistSqr = min(vecDist.MagnitudeSqr(), fDistSqr);
+ fDistSqr = Min(vecDist.MagnitudeSqr(), fDistSqr);
}
}
}
@@ -1234,22 +1234,3 @@ CWaterLevel::FreeBoatWakeArray()
nGeomUsed = 0;
}
-
-STARTPATCHES
- InjectHook(0x554EA0, &CWaterLevel::Initialise, PATCH_JUMP);
- InjectHook(0x554FE0, &CWaterLevel::Shutdown, PATCH_JUMP);
- InjectHook(0x555010, &CWaterLevel::CreateWavyAtomic, PATCH_JUMP);
- InjectHook(0x5552A0, &CWaterLevel::DestroyWavyAtomic, PATCH_JUMP);
- InjectHook(0x5552C0, (bool (*)(float,float,float,float*,bool))&CWaterLevel::GetWaterLevel, PATCH_JUMP);
- InjectHook(0x555440, &CWaterLevel::GetWaterLevelNoWaves, PATCH_JUMP);
- InjectHook(0x5554E0, &CWaterLevel::RenderWater, PATCH_JUMP);
- InjectHook(0x556C30, &CWaterLevel::RenderOneFlatSmallWaterPoly, PATCH_JUMP);
- InjectHook(0x556E80, &CWaterLevel::RenderOneFlatLargeWaterPoly, PATCH_JUMP);
- InjectHook(0x5570D0, &CWaterLevel::RenderOneFlatHugeWaterPoly, PATCH_JUMP);
- InjectHook(0x557320, &CWaterLevel::RenderOneFlatExtraHugeWaterPoly, PATCH_JUMP);
- InjectHook(0x557570, &CWaterLevel::RenderOneWavySector, PATCH_JUMP);
- InjectHook(0x557C30, &CWaterLevel::CalcDistanceToWater, PATCH_JUMP);
- InjectHook(0x557EA0, &CWaterLevel::RenderAndEmptyRenderBuffer, PATCH_JUMP);
- InjectHook(0x557F00, &CWaterLevel::AllocateBoatWakeArray, PATCH_JUMP);
- InjectHook(0x5581C0, &CWaterLevel::FreeBoatWakeArray, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h
index 827e83d2..a471bc52 100644
--- a/src/render/WaterLevel.h
+++ b/src/render/WaterLevel.h
@@ -64,7 +64,7 @@
#define MAX_BOAT_WAKES 8
-extern RwRaster*& gpWaterRaster;
+extern RwRaster* gpWaterRaster;
class CWaterLevel
{
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index b440e77c..b4031705 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Weather.h"
#include "Camera.h"
@@ -18,35 +18,35 @@
#include "World.h"
#include "ZoneCull.h"
-int32 &CWeather::SoundHandle = *(int32*)0x5FFBC4;
+int32 CWeather::SoundHandle = -1;
-int32 &CWeather::WeatherTypeInList = *(int32*)0x8F626C;
-int16 &CWeather::OldWeatherType = *(int16*)0x95CCEC;
-int16 &CWeather::NewWeatherType = *(int16*)0x95CC70;
-int16 &CWeather::ForcedWeatherType = *(int16*)0x95CC80;
+int32 CWeather::WeatherTypeInList;
+int16 CWeather::OldWeatherType;
+int16 CWeather::NewWeatherType;
+int16 CWeather::ForcedWeatherType;
-bool &CWeather::LightningFlash = *(bool*)0x95CDA3;
-bool &CWeather::LightningBurst = *(bool*)0x95CDAC;
-uint32 &CWeather::LightningStart = *(uint32*)0x8F5F84;
-uint32 &CWeather::LightningFlashLastChange = *(uint32*)0x8E2C0C;
-uint32 &CWeather::WhenToPlayLightningSound = *(uint32*)0x8F57E4;
-uint32 &CWeather::LightningDuration = *(uint32*)0x940578;
+bool CWeather::LightningFlash;
+bool CWeather::LightningBurst;
+uint32 CWeather::LightningStart;
+uint32 CWeather::LightningFlashLastChange;
+uint32 CWeather::WhenToPlayLightningSound;
+uint32 CWeather::LightningDuration;
-float &CWeather::Foggyness = *(float*)0x885AF4;
-float &CWeather::CloudCoverage = *(float*)0x8E2818;
-float &CWeather::Wind = *(float*)0x8E2BF8;
-float &CWeather::Rain = *(float*)0x8E2BFC;
-float &CWeather::InterpolationValue = *(float*)0x8F2520;
-float &CWeather::WetRoads = *(float*)0x8F5FF8;
-float &CWeather::Rainbow = *(float*)0x940598;
+float CWeather::Foggyness;
+float CWeather::CloudCoverage;
+float CWeather::Wind;
+float CWeather::Rain;
+float CWeather::InterpolationValue;
+float CWeather::WetRoads;
+float CWeather::Rainbow;
-bool &CWeather::bScriptsForceRain = *(bool*)0x95CD7D;
-bool &CWeather::Stored_StateStored = *(bool*)0x95CDC1;
+bool CWeather::bScriptsForceRain;
+bool CWeather::Stored_StateStored;
-float &CWeather::Stored_InterpolationValue = *(float*)0x942F54;
-int16 &CWeather::Stored_OldWeatherType = *(int16*)0x95CC68;
-int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE;
-float &CWeather::Stored_Rain = *(float*)0x885B4C;
+float CWeather::Stored_InterpolationValue;
+int16 CWeather::Stored_OldWeatherType;
+int16 CWeather::Stored_NewWeatherType;
+float CWeather::Stored_Rain;
tRainStreak Streaks[NUM_RAIN_STREAKS];
@@ -126,7 +126,7 @@ void CWeather::Update(void)
if (ForcedWeatherType >= 0)
NewWeatherType = ForcedWeatherType;
else {
- WeatherTypeInList = (WeatherTypeInList + 1) % ARRAYSIZE(WeatherTypesList);
+ WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList);
NewWeatherType = WeatherTypesList[WeatherTypeInList];
#ifdef FIX_BUGS
}
@@ -163,7 +163,7 @@ void CWeather::Update(void)
else {
// 0.125 probability
LightningBurst = false;
- LightningDuration = min(CTimer::GetFrameCounter() - LightningStart, 20);
+ LightningDuration = Min(CTimer::GetFrameCounter() - LightningStart, 20);
LightningFlash = false;
WhenToPlayLightningSound = CTimer::GetTimeInMilliseconds() + 150 * (20 - LightningDuration);
}
@@ -219,9 +219,9 @@ void CWeather::Update(void)
fNewRain = 0.0f;
if (Rain != fNewRain) { // ok to use comparasion
if (Rain < fNewRain)
- Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
+ Rain = Min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
else
- Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
+ Rain = Max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
}
// Clouds
diff --git a/src/render/Weather.h b/src/render/Weather.h
index 9e4ea378..9c670317 100644
--- a/src/render/Weather.h
+++ b/src/render/Weather.h
@@ -16,34 +16,34 @@ public:
WEATHER_FOGGY = 3,
WEATHER_TOTAL = 4
};
- static int32 &SoundHandle;
+ static int32 SoundHandle;
- static int32 &WeatherTypeInList;
- static int16 &OldWeatherType;
- static int16 &NewWeatherType;
- static int16 &ForcedWeatherType;
+ static int32 WeatherTypeInList;
+ static int16 OldWeatherType;
+ static int16 NewWeatherType;
+ static int16 ForcedWeatherType;
- static bool &LightningFlash;
- static bool &LightningBurst;
- static uint32 &LightningStart;
- static uint32 &LightningFlashLastChange;
- static uint32 &WhenToPlayLightningSound;
- static uint32 &LightningDuration;
+ static bool LightningFlash;
+ static bool LightningBurst;
+ static uint32 LightningStart;
+ static uint32 LightningFlashLastChange;
+ static uint32 WhenToPlayLightningSound;
+ static uint32 LightningDuration;
- static float &Foggyness;
- static float &CloudCoverage;
- static float &Wind;
- static float &Rain;
- static float &InterpolationValue;
- static float &WetRoads;
- static float &Rainbow;
+ static float Foggyness;
+ static float CloudCoverage;
+ static float Wind;
+ static float Rain;
+ static float InterpolationValue;
+ static float WetRoads;
+ static float Rainbow;
- static bool &bScriptsForceRain;
- static bool &Stored_StateStored;
- static float &Stored_InterpolationValue;
- static int16 &Stored_OldWeatherType;
- static int16 &Stored_NewWeatherType;
- static float &Stored_Rain;
+ static bool bScriptsForceRain;
+ static bool Stored_StateStored;
+ static float Stored_InterpolationValue;
+ static int16 Stored_OldWeatherType;
+ static int16 Stored_NewWeatherType;
+ static float Stored_Rain;
static void RenderRainStreaks(void);
static void Update(void);
@@ -68,4 +68,4 @@ struct tRainStreak
uint32 timer;
};
-extern RwTexture* (&gpRainDropTex)[4]; \ No newline at end of file
+extern RwTexture* gpRainDropTex[4]; \ No newline at end of file
diff --git a/src/rw/ClumpRead.cpp b/src/rw/ClumpRead.cpp
index c9f027e7..5f50f52d 100644
--- a/src/rw/ClumpRead.cpp
+++ b/src/rw/ClumpRead.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
struct rpGeometryList
{
@@ -153,7 +153,7 @@ RpClumpGtaStreamRead1(RwStream *stream)
if(!RwStreamFindChunk(stream, rwID_FRAMELIST, nil, &version))
return false;
- if(_rwFrameListStreamRead(stream, &gFrameList) == nil)
+ if(rwFrameListStreamRead(stream, &gFrameList) == nil)
return false;
if(!RwStreamFindChunk(stream, rwID_GEOMETRYLIST, nil, &version)){
@@ -164,7 +164,7 @@ RpClumpGtaStreamRead1(RwStream *stream)
rwFrameListDeinitialize(&gFrameList);
return false;
}
- streamPosition = stream->Type.memory.position;
+ streamPosition = STREAMPOS(stream);
return true;
}
@@ -180,7 +180,7 @@ RpClumpGtaStreamRead2(RwStream *stream)
if(clump == nil)
return nil;
- RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
+ RwStreamSkip(stream, streamPosition - STREAMPOS(stream));
if(GeometryListStreamRead2(stream, &gGeomList) == nil){
GeometryListDeinitialize(&gGeomList);
@@ -222,9 +222,3 @@ RpClumpGtaCancelStream(void)
rwFrameListDeinitialize(&gFrameList);
gFrameList.numFrames = 0;
}
-
-STARTPATCHES
- InjectHook(0x526060, RpClumpGtaStreamRead1, PATCH_JUMP);
- InjectHook(0x526180, RpClumpGtaStreamRead2, PATCH_JUMP);
- InjectHook(0x5262D0, RpClumpGtaCancelStream, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index cd83a898..5a253854 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -1,7 +1,7 @@
#include "common.h"
#include <rwcore.h>
#include <rpworld.h>
-#include "patcher.h"
+
#include "Lights.h"
#include "Timecycle.h"
#include "Coronas.h"
@@ -9,18 +9,18 @@
#include "ZoneCull.h"
#include "Frontend.h"
-RpLight *&pAmbient = *(RpLight**)0x885B6C;
-RpLight *&pDirect = *(RpLight**)0x880F7C;
-RpLight **pExtraDirectionals = (RpLight**)0x60009C;
-int *LightStrengths = (int*)0x87BEF0;
-int &NumExtraDirLightsInWorld = *(int*)0x64C608;
+RpLight *pAmbient;
+RpLight *pDirect;
+RpLight *pExtraDirectionals[4] = { nil };
+int LightStrengths[4];
+int NumExtraDirLightsInWorld;
-RwRGBAReal &AmbientLightColourForFrame = *(RwRGBAReal*)0x6F46F8;
-RwRGBAReal &AmbientLightColourForFrame_PedsCarsAndObjects = *(RwRGBAReal*)0x6F1D10;
-RwRGBAReal &DirectionalLightColourForFrame = *(RwRGBAReal*)0x87C6B8;
+RwRGBAReal AmbientLightColourForFrame;
+RwRGBAReal AmbientLightColourForFrame_PedsCarsAndObjects;
+RwRGBAReal DirectionalLightColourForFrame;
-RwRGBAReal &AmbientLightColour = *(RwRGBAReal*)0x86B0F8;
-RwRGBAReal &DirectionalLightColour = *(RwRGBAReal*)0x72E308;
+RwRGBAReal AmbientLightColour;
+RwRGBAReal DirectionalLightColour;
void
SetLightsWithTimeOfDayColour(RpWorld *)
@@ -37,9 +37,9 @@ SetLightsWithTimeOfDayColour(RpWorld *)
AmbientLightColourForFrame.green = 1.0f;
AmbientLightColourForFrame.blue = 1.0f;
}
- AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame.red*1.3f);
- AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame.green*1.3f);
- AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame.blue*1.3f);
+ AmbientLightColourForFrame_PedsCarsAndObjects.red = Min(1.0f, AmbientLightColourForFrame.red*1.3f);
+ AmbientLightColourForFrame_PedsCarsAndObjects.green = Min(1.0f, AmbientLightColourForFrame.green*1.3f);
+ AmbientLightColourForFrame_PedsCarsAndObjects.blue = Min(1.0f, AmbientLightColourForFrame.blue*1.3f);
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
}
@@ -70,20 +70,20 @@ SetLightsWithTimeOfDayColour(RpWorld *)
float f1 = 2.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f;
float f2 = 3.0f * (CMenuManager::m_PrefsBrightness/256.0f - 1.0f) * 0.6f + 1.0f;
- AmbientLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f2);
- AmbientLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f2);
- AmbientLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f2);
- AmbientLightColourForFrame_PedsCarsAndObjects.red = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.red * f1);
- AmbientLightColourForFrame_PedsCarsAndObjects.green = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.green * f1);
- AmbientLightColourForFrame_PedsCarsAndObjects.blue = min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.blue * f1);
+ AmbientLightColourForFrame.red = Min(1.0f, AmbientLightColourForFrame.red * f2);
+ AmbientLightColourForFrame.green = Min(1.0f, AmbientLightColourForFrame.green * f2);
+ AmbientLightColourForFrame.blue = Min(1.0f, AmbientLightColourForFrame.blue * f2);
+ AmbientLightColourForFrame_PedsCarsAndObjects.red = Min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.red * f1);
+ AmbientLightColourForFrame_PedsCarsAndObjects.green = Min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.green * f1);
+ AmbientLightColourForFrame_PedsCarsAndObjects.blue = Min(1.0f, AmbientLightColourForFrame_PedsCarsAndObjects.blue * f1);
#ifdef FIX_BUGS
- DirectionalLightColourForFrame.red = min(1.0f, DirectionalLightColourForFrame.red * f1);
- DirectionalLightColourForFrame.green = min(1.0f, DirectionalLightColourForFrame.green * f1);
- DirectionalLightColourForFrame.blue = min(1.0f, DirectionalLightColourForFrame.blue * f1);
+ DirectionalLightColourForFrame.red = Min(1.0f, DirectionalLightColourForFrame.red * f1);
+ DirectionalLightColourForFrame.green = Min(1.0f, DirectionalLightColourForFrame.green * f1);
+ DirectionalLightColourForFrame.blue = Min(1.0f, DirectionalLightColourForFrame.blue * f1);
#else
- DirectionalLightColourForFrame.red = min(1.0f, AmbientLightColourForFrame.red * f1);
- DirectionalLightColourForFrame.green = min(1.0f, AmbientLightColourForFrame.green * f1);
- DirectionalLightColourForFrame.blue = min(1.0f, AmbientLightColourForFrame.blue * f1);
+ DirectionalLightColourForFrame.red = Min(1.0f, AmbientLightColourForFrame.red * f1);
+ DirectionalLightColourForFrame.green = Min(1.0f, AmbientLightColourForFrame.green * f1);
+ DirectionalLightColourForFrame.blue = Min(1.0f, AmbientLightColourForFrame.blue * f1);
#endif
}
}
@@ -108,7 +108,7 @@ LightsCreate(RpWorld *world)
pDirect = RpLightCreate(rpLIGHTDIRECTIONAL);
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
color.red = 1.0f;
- color.green = 0.84f;
+ color.green = 0.85f;
color.blue = 0.45f;
RpLightSetColor(pDirect, &color);
RpLightSetRadius(pDirect, 2.0f);
@@ -193,7 +193,7 @@ AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, f
RwRGBAReal color;
RwV3d *dir;
- strength = max(max(red, green), blue);
+ strength = Max(Max(red, green), blue);
n = -1;
if(NumExtraDirLightsInWorld < NUMEXTRADIRECTIONALS)
n = NumExtraDirLightsInWorld;
@@ -221,7 +221,7 @@ AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, f
RwFrameUpdateObjects(RpLightGetFrame(pExtraDirectionals[n]));
RpLightSetFlags(pExtraDirectionals[n], rpLIGHTLIGHTATOMICS);
LightStrengths[n] = strength;
- NumExtraDirLightsInWorld = min(NumExtraDirLightsInWorld+1, NUMEXTRADIRECTIONALS);
+ NumExtraDirLightsInWorld = Min(NumExtraDirLightsInWorld+1, NUMEXTRADIRECTIONALS);
}
void
@@ -312,22 +312,3 @@ SetAmbientColours(RwRGBAReal *color)
{
RpLightSetColor(pAmbient, color);
}
-
-
-STARTPATCHES
- InjectHook(0x526510, SetLightsWithTimeOfDayColour, PATCH_JUMP);
- InjectHook(0x5269A0, LightsCreate, PATCH_JUMP);
- InjectHook(0x526B40, LightsDestroy, PATCH_JUMP);
- InjectHook(0x526C10, WorldReplaceNormalLightsWithScorched, PATCH_JUMP);
- InjectHook(0x526C50, WorldReplaceScorchedLightsWithNormal, PATCH_JUMP);
- InjectHook(0x526C70, AddAnExtraDirectionalLight, PATCH_JUMP);
- InjectHook(0x526DB0, RemoveExtraDirectionalLights, PATCH_JUMP);
- InjectHook(0x526DE0, SetAmbientAndDirectionalColours, PATCH_JUMP);
- InjectHook(0x526E60, SetBrightMarkerColours, PATCH_JUMP);
- InjectHook(0x526F10, ReSetAmbientAndDirectionalColours, PATCH_JUMP);
- InjectHook(0x526F40, DeActivateDirectional, PATCH_JUMP);
- InjectHook(0x526F50, ActivateDirectional, PATCH_JUMP);
- InjectHook(0x526F60, (void (*)(void))SetAmbientColours, PATCH_JUMP);
- InjectHook(0x526F80, SetAmbientColoursForPedsCarsAndObjects, PATCH_JUMP);
- InjectHook(0x526FA0, (void (*)(RwRGBAReal*))SetAmbientColours, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/rw/NodeName.cpp b/src/rw/NodeName.cpp
index 2aea3c83..d62884f7 100644
--- a/src/rw/NodeName.cpp
+++ b/src/rw/NodeName.cpp
@@ -1,8 +1,8 @@
#include "common.h"
-#include "patcher.h"
+
#include "NodeName.h"
-static int32 &gPluginOffset = *(int32*)0x64C610;
+static int32 gPluginOffset;
enum
{
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index 44ca3a0a..ed618dd8 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -1,43 +1,55 @@
+#if defined RW_D3D9 || defined RWLIBS
#define WITHD3D
+#endif
#include "common.h"
-#include "patcher.h"
+
#include "Timecycle.h"
#include "skeleton.h"
-#if defined(RWLIBS) && !defined(FINAL)
+#include "Debug.h"
+#ifndef FINAL
#include "rtcharse.h"
-#pragma comment( lib, "rtcharse.lib" )
-
RtCharset *debugCharset;
#endif
+bool gPS2alphaTest = 1;
+
+static bool charsetOpen;
+void OpenCharsetSafe()
+{
+ if(!charsetOpen)
+ RtCharsetOpen();
+ charsetOpen = true;
+}
+
void CreateDebugFont()
{
-#if defined(RWLIBS) && !defined(FINAL)
+#ifndef FINAL
RwRGBA color = { 255, 255, 128, 255 };
RwRGBA colorbg = { 0, 0, 0, 0 };
- RtCharsetOpen();
+ OpenCharsetSafe();
debugCharset = RtCharsetCreate(&color, &colorbg);
#endif
}
void DestroyDebugFont()
{
-#if defined(RWLIBS) && !defined(FINAL)
+#ifndef FINAL
RtCharsetDestroy(debugCharset);
RtCharsetClose();
+ charsetOpen = false;
#endif
}
void ObrsPrintfString(const char *str, short x, short y)
{
-#if defined(RWLIBS) && !defined(FINAL)
- RtCharsetPrintBuffered(debugCharset, str, x, y, true);
+#ifndef FINAL
+ RtCharsetPrintBuffered(debugCharset, str, x*8, y*16, true);
#endif
}
void FlushObrsPrintfs()
{
-#if defined(RWLIBS) && !defined(FINAL)
+#ifndef FINAL
RtCharsetBufferFlush();
#endif
}
@@ -90,9 +102,16 @@ DefinedState(void)
RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+#ifdef LIBRW
+ rw::SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL);
+ rw::SetRenderState(rw::ALPHATESTREF, 3);
+
+ rw::SetRenderState(rw::GSALPHATEST, gPS2alphaTest);
+#else
// D3D stuff
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
RwD3D8SetRenderState(D3DRS_ALPHAREF, 2);
+#endif
}
RwFrame*
@@ -163,6 +182,190 @@ GetFirstTexture(RwTexDictionary *txd)
return tex;
}
+#ifdef PED_SKIN
+static RpAtomic*
+isSkinnedCb(RpAtomic *atomic, void *data)
+{
+ RpAtomic **pAtomic = (RpAtomic**)data;
+ if(*pAtomic)
+ return nil; // already found one
+ if(RpSkinGeometryGetSkin(atomic->geometry))
+ *pAtomic = atomic; // we could just return nil here directly...
+ return atomic;
+}
+
+RpAtomic*
+IsClumpSkinned(RpClump *clump)
+{
+ RpAtomic *atomic = nil;
+ RpClumpForAllAtomics(clump, isSkinnedCb, &atomic);
+ return atomic;
+}
+
+static RpAtomic*
+GetAnimHierarchyCallback(RpAtomic *atomic, void *data)
+{
+ *(RpHAnimHierarchy**)data = RpSkinAtomicGetHAnimHierarchy(atomic);
+ return nil;
+}
+
+RpHAnimHierarchy*
+GetAnimHierarchyFromSkinClump(RpClump *clump)
+{
+ RpHAnimHierarchy *hier = nil;
+ RpClumpForAllAtomics(clump, GetAnimHierarchyCallback, &hier);
+ return hier;
+}
+
+static RwFrame*
+GetAnimHierarchyFromClumpCB(RwFrame *frame, void *data)
+{
+ RpHAnimHierarchy *hier = RpHAnimFrameGetHierarchy(frame);
+ if(hier){
+ *(RpHAnimHierarchy**)data = hier;
+ return nil;
+ }
+ RwFrameForAllChildren(frame, GetAnimHierarchyFromClumpCB, data);
+ return frame;
+}
+
+RpHAnimHierarchy*
+GetAnimHierarchyFromClump(RpClump *clump)
+{
+ RpHAnimHierarchy *hier = nil;
+ RwFrameForAllChildren(RpClumpGetFrame(clump), GetAnimHierarchyFromClumpCB, &hier);
+ return hier;
+}
+
+RwFrame*
+GetHierarchyFromChildNodesCB(RwFrame *frame, void *data)
+{
+ RpHAnimHierarchy **pHier = (RpHAnimHierarchy**)data;
+ RpHAnimHierarchy *hier = RpHAnimFrameGetHierarchy(frame);
+ if(hier == nil)
+ RwFrameForAllChildren(frame, GetHierarchyFromChildNodesCB, &hier);
+ *pHier = hier;
+ return nil;
+}
+
+void
+SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable)
+{
+ int i, parent;
+ RpAtomic *atomic;
+ RpSkin *skin;
+ RpHAnimHierarchy *hier;
+ int numBones;
+ RwMatrix m, invmat;
+ int stack[32];
+ int sp;
+
+ if(boneTable == nil)
+ return;
+
+// atomic = GetFirstAtomic(clump); // mobile, also VC
+ atomic = IsClumpSkinned(clump); // xbox, seems safer
+ assert(atomic);
+ skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
+ assert(skin);
+ hier = GetAnimHierarchyFromSkinClump(clump);
+ assert(hier);
+ boneTable[0].x = 0.0f;
+ boneTable[0].y = 0.0f;
+ boneTable[0].z = 0.0f;
+ numBones = RpSkinGetNumBones(skin);
+ parent = 0;
+ sp = 0;
+#ifdef FIX_BUGS
+ stack[0] = 0; // i think this is ok
+#endif
+ for(i = 1; i < numBones; i++){
+ RwMatrixCopy(&m, &RpSkinGetSkinToBoneMatrices(skin)[i]);
+ RwMatrixInvert(&invmat, &m);
+ const RwMatrix *x = RpSkinGetSkinToBoneMatrices(skin);
+ RwV3dTransformPoints(&boneTable[i], &invmat.pos, 1, &x[parent]);
+ if(HIERNODEINFO(hier)[i].flags & rpHANIMPUSHPARENTMATRIX)
+ stack[++sp] = parent;
+ if(HIERNODEINFO(hier)[i].flags & rpHANIMPOPPARENTMATRIX)
+ parent = stack[sp--];
+ else
+ parent = i;
+ assert(parent >= 0 && parent < numBones);
+ }
+}
+
+RpHAnimAnimation*
+HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier)
+{
+ int i;
+#ifdef FIX_BUGS
+ int numNodes = hier->numNodes*2; // you're supposed to have at least two KFs per node
+#else
+ int numNodes = hier->numNodes;
+#endif
+ RpHAnimAnimation *anim = RpHAnimAnimationCreate(rpHANIMSTDKEYFRAMETYPEID, numNodes, 0, 0.0f);
+ if(anim == nil)
+ return nil;
+ RpHAnimStdKeyFrame *frame = (RpHAnimStdKeyFrame*)HANIMFRAMES(anim);
+ for(i = 0; i < numNodes; i++){
+ frame->q.real = 1.0f;
+ frame->q.imag.x = frame->q.imag.y = frame->q.imag.z = 0.0f;
+ frame->t.x = frame->t.y = frame->t.z = 0.0f;
+ frame->time = 0.0f;
+ frame->prevFrame = nil;
+ frame++;
+ }
+ return anim;
+}
+
+RpAtomic*
+AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
+{
+ if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){
+ RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic);
+#ifdef LIBRW
+ if(hier && hier->interpolator->currentAnim){
+ RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
+ hier->interpolator->currentAnim = nil;
+ }
+#else
+ if(hier && hier->pCurrentAnim){
+ RpHAnimAnimationDestroy(hier->pCurrentAnim);
+ hier->pCurrentAnim = nil;
+ }
+#endif
+ }
+ return atomic;
+}
+
+void
+RenderSkeleton(RpHAnimHierarchy *hier)
+{
+ int i;
+ int sp;
+ int stack[32];
+ int par;
+ CVector p1, p2;
+ int numNodes = hier->numNodes;
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ p1 = mats[0].pos;
+
+ par = 0;
+ sp = 0;
+ stack[sp++] = par;
+ for(i = 1; i < numNodes; i++){
+ p1 = mats[par].pos;
+ p2 = mats[i].pos;
+ CDebug::AddLine(p1, p2, 0xFFFFFFFF, 0xFFFFFFFF);
+ if(HIERNODEINFO(hier)[i].flags & rpHANIMPUSHPARENTMATRIX)
+ stack[sp++] = par;
+ par = i;
+ if(HIERNODEINFO(hier)[i].flags & rpHANIMPOPPARENTMATRIX)
+ par = stack[--sp];
+ }
+}
+#endif
+
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)
@@ -385,13 +588,7 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
return (nil);
}
+#ifdef USE_TEXTURE_POOL
WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
-
-STARTPATCHES
- //InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP);
- InjectHook(0x526460, GetFirstObject, PATCH_JUMP);
- InjectHook(0x527170, CameraSize, PATCH_JUMP);
- InjectHook(0x527340, CameraDestroy, PATCH_JUMP);
- InjectHook(0x5273B0, CameraCreate, PATCH_JUMP);
-ENDPATCHES
+#endif
diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h
index 5b47cb6f..a751ee39 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -1,8 +1,11 @@
#pragma once
+extern bool gPS2alphaTest;
+
void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
void RwFreeAlign(void *mem);
+void OpenCharsetSafe();
void CreateDebugFont();
void DestroyDebugFont();
void ObrsPrintfString(const char *str, short x, short y);
@@ -13,6 +16,17 @@ RwObject *GetFirstObject(RwFrame *frame);
RpAtomic *GetFirstAtomic(RpClump *clump);
RwTexture *GetFirstTexture(RwTexDictionary *txd);
+#ifdef PED_SKIN
+RpAtomic *IsClumpSkinned(RpClump *clump);
+RpHAnimHierarchy *GetAnimHierarchyFromSkinClump(RpClump *clump); // get from atomic
+RpHAnimHierarchy *GetAnimHierarchyFromClump(RpClump *clump); // get from frame
+RwFrame *GetHierarchyFromChildNodesCB(RwFrame *frame, void *data);
+void SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable);
+RpHAnimAnimation *HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier);
+RpAtomic *AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data);
+void RenderSkeleton(RpHAnimHierarchy *hier);
+#endif
+
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict);
diff --git a/src/rw/RwMatFX.cpp b/src/rw/RwMatFX.cpp
index 3af6fabe..1e64c560 100644
--- a/src/rw/RwMatFX.cpp
+++ b/src/rw/RwMatFX.cpp
@@ -1,6 +1,10 @@
+#ifndef LIBRW
+
#define WITHD3D
#include "common.h"
+#ifdef RWLIBS
#include "patcher.h"
+#endif
struct MatFXNothing { int pad[5]; int effect; };
@@ -214,13 +218,12 @@ _rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int se
RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
}
-
-STARTPATCHES
#ifdef RWLIBS
+STARTPATCHES
InjectHook((uintptr)&_rpMatFXD3D8AtomicMatFXEnvRender, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP);
-#else
- InjectHook(0x5CF6C0, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP);
-#endif
ENDPATCHES
+#endif
+
+#endif
#endif
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index 50b99d47..60945665 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -1,12 +1,9 @@
#pragma warning( push )
#pragma warning( disable : 4005)
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
#pragma warning( pop )
-#define WITHWINDOWS
#include "common.h"
-#include "win.h"
-#include "patcher.h"
+#include "crossplatform.h"
+
#include "Timer.h"
#ifdef GTA_PC
#include "FileMgr.h"
@@ -22,8 +19,14 @@
#include "RwHelper.h"
#endif //GTA_PC
-float &texLoadTime = *(float*)0x8F1B50;
-int32 &texNumLoaded = *(int32*)0x8F252C;
+float texLoadTime;
+int32 texNumLoaded;
+
+#ifdef LIBRW
+#define READNATIVE(stream, tex, size) rwNativeTextureHackRead(stream, tex, size)
+#else
+#define READNATIVE(stream, tex, size) RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, tex, size))
+#endif
RwTexture*
RwTextureGtaStreamRead(RwStream *stream)
@@ -36,7 +39,7 @@ RwTextureGtaStreamRead(RwStream *stream)
float preloadTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
- if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
+ if(!READNATIVE(stream, &tex, size))
return nil;
if (gGameState == GS_INIT_PLAYING_GAME) {
@@ -63,7 +66,6 @@ RwTexDictionaryGtaStreamRead(RwStream *stream)
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
return nil;
- assert(size == 4);
if(RwStreamRead(stream, &numTextures, size) != size)
return nil;
@@ -121,7 +123,7 @@ RwTexDictionaryGtaStreamRead1(RwStream *stream)
}
numberTextures = numTextures;
- streamPosition = stream->Type.memory.position;
+ streamPosition = STREAMPOS(stream);
return texDict;
}
@@ -131,7 +133,7 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
{
RwTexture *tex;
- RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
+ RwStreamSkip(stream, streamPosition - STREAMPOS(stream));
while(numberTextures--){
tex = RwTextureGtaStreamRead(stream);
@@ -150,9 +152,8 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
#ifdef RWLIBS
extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
#else
-WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); }
+RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
#endif
-
void
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
{
@@ -251,6 +252,12 @@ DealWithTxdWriteError(uint32 num, uint32 count, const char *text)
RsGlobal.quit = true;
}
+#ifdef LIBRW
+#define STREAMTELL(str) str->tell()
+#else
+#define STREAMTELL(str) filesys->rwftell((str)->Type.file.fpFile)
+#endif
+
bool
CreateTxdImageForVideoCard()
{
@@ -260,7 +267,9 @@ CreateTxdImageForVideoCard()
CStreaming::FlushRequestList();
+#ifndef LIBRW
RwFileFunctions *filesys = RwOsGetFileInterface();
+#endif
RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img");
if (img == nil) {
@@ -287,7 +296,8 @@ CreateTxdImageForVideoCard()
sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i));
if (CTxdStore::GetSlot(i)->texDict) {
- int32 pos = filesys->rwftell(img->Type.file.fpFile);
+
+ int32 pos = STREAMTELL(img);
if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
@@ -298,7 +308,7 @@ CreateTxdImageForVideoCard()
return false;
}
- int32 size = filesys->rwftell(img->Type.file.fpFile) - pos;
+ int32 size = STREAMTELL(img) - pos;
int32 num = size % CDSTREAM_SECTOR_SIZE;
size /= CDSTREAM_SECTOR_SIZE;
@@ -333,17 +343,3 @@ CreateTxdImageForVideoCard()
return true;
}
#endif // GTA_PC
-
-STARTPATCHES
- InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
- InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
- InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
- InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
-
- InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP);
- InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP);
- InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP);
- InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP);
- InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP);
- InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/rw/TxdStore.cpp b/src/rw/TxdStore.cpp
index c751147d..51d018f6 100644
--- a/src/rw/TxdStore.cpp
+++ b/src/rw/TxdStore.cpp
@@ -1,13 +1,13 @@
#include "common.h"
-#include "patcher.h"
+
#include "templates.h"
#include "General.h"
#include "Streaming.h"
#include "RwHelper.h"
#include "TxdStore.h"
-CPool<TxdDef,TxdDef> *&CTxdStore::ms_pTxdPool = *(CPool<TxdDef,TxdDef>**)0x8F5FB8;
-RwTexDictionary *&CTxdStore::ms_pStoredTxd = *(RwTexDictionary**)0x9405BC;
+CPool<TxdDef,TxdDef> *CTxdStore::ms_pTxdPool;
+RwTexDictionary *CTxdStore::ms_pStoredTxd;
void
CTxdStore::Initialise(void)
@@ -185,25 +185,3 @@ CTxdStore::RemoveTxd(int slot)
RwTexDictionaryDestroy(def->texDict);
def->texDict = nil;
}
-
-STARTPATCHES
- InjectHook(0x527440, CTxdStore::Initialise, PATCH_JUMP);
- InjectHook(0x527470, CTxdStore::Shutdown, PATCH_JUMP);
- InjectHook(0x527490, CTxdStore::GameShutdown, PATCH_JUMP);
- InjectHook(0x5274E0, CTxdStore::AddTxdSlot, PATCH_JUMP);
- InjectHook(0x5275D0, CTxdStore::FindTxdSlot, PATCH_JUMP);
- InjectHook(0x527590, CTxdStore::GetTxdName, PATCH_JUMP);
- InjectHook(0x527900, CTxdStore::PushCurrentTxd, PATCH_JUMP);
- InjectHook(0x527910, CTxdStore::PopCurrentTxd, PATCH_JUMP);
- InjectHook(0x5278C0, CTxdStore::SetCurrentTxd, PATCH_JUMP);
- InjectHook(0x527830, CTxdStore::Create, PATCH_JUMP);
- InjectHook(0x527A00, CTxdStore::GetNumRefs, PATCH_JUMP);
- InjectHook(0x527930, CTxdStore::AddRef, PATCH_JUMP);
- InjectHook(0x527970, CTxdStore::RemoveRef, PATCH_JUMP);
- InjectHook(0x5279C0, CTxdStore::RemoveRefWithoutDelete, PATCH_JUMP);
- InjectHook(0x527700, (bool (*)(int, RwStream*))CTxdStore::LoadTxd, PATCH_JUMP);
- InjectHook(0x5276B0, (bool (*)(int, const char*))CTxdStore::LoadTxd, PATCH_JUMP);
- InjectHook(0x527770, CTxdStore::StartLoadTxd, PATCH_JUMP);
- InjectHook(0x5277E0, CTxdStore::FinishLoadTxd, PATCH_JUMP);
- InjectHook(0x527870, CTxdStore::RemoveTxd, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/rw/TxdStore.h b/src/rw/TxdStore.h
index 12ac708f..937fd1b7 100644
--- a/src/rw/TxdStore.h
+++ b/src/rw/TxdStore.h
@@ -10,8 +10,8 @@ struct TxdDef {
class CTxdStore
{
- static CPool<TxdDef,TxdDef> *&ms_pTxdPool;
- static RwTexDictionary *&ms_pStoredTxd;
+ static CPool<TxdDef,TxdDef> *ms_pTxdPool;
+ static RwTexDictionary *ms_pStoredTxd;
public:
static void Initialise(void);
static void Shutdown(void);
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index f8b1f6b2..7dc27f48 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "templates.h"
#include "Entity.h"
#include "ModelInfo.h"
@@ -11,40 +11,37 @@
#define FADE_DISTANCE 20.0f
-/*
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
int32 CVisibilityPlugins::ms_atomicPluginOffset = -1;
int32 CVisibilityPlugins::ms_framePluginOffset = -1;
int32 CVisibilityPlugins::ms_clumpPluginOffset = -1;
-*/
-CLinkList<CVisibilityPlugins::AlphaObjectInfo> &CVisibilityPlugins::m_alphaList = *(CLinkList<CVisibilityPlugins::AlphaObjectInfo>*)0x8F42E4;
-CLinkList<CVisibilityPlugins::AlphaObjectInfo> &CVisibilityPlugins::m_alphaEntityList = *(CLinkList<CVisibilityPlugins::AlphaObjectInfo>*)0x943084;
-
-int32 &CVisibilityPlugins::ms_atomicPluginOffset = *(int32*)0x600124;
-int32 &CVisibilityPlugins::ms_framePluginOffset = *(int32*)0x600128;
-int32 &CVisibilityPlugins::ms_clumpPluginOffset = *(int32*)0x60012C;
-
-RwCamera *&CVisibilityPlugins::ms_pCamera = *(RwCamera**)0x8F2514;
-RwV3d *&CVisibilityPlugins::ms_pCameraPosn = *(RwV3d**)0x8F6270;
-float &CVisibilityPlugins::ms_cullCompsDist = *(float*)0x8F2BC4;
-float &CVisibilityPlugins::ms_vehicleLod0Dist = *(float*)0x885B28;
-float &CVisibilityPlugins::ms_vehicleLod1Dist = *(float*)0x885B30;
-float &CVisibilityPlugins::ms_vehicleFadeDist = *(float*)0x8E28B4;
-float &CVisibilityPlugins::ms_bigVehicleLod0Dist = *(float*)0x8E2A84;
-float &CVisibilityPlugins::ms_bigVehicleLod1Dist = *(float*)0x8E2A8C;
-float &CVisibilityPlugins::ms_pedLod0Dist = *(float*)0x8F2BD4;
-float &CVisibilityPlugins::ms_pedLod1Dist = *(float*)0x8F2BD8;
-float &CVisibilityPlugins::ms_pedFadeDist = *(float*)0x8E2C34;
+
+RwCamera *CVisibilityPlugins::ms_pCamera;
+RwV3d *CVisibilityPlugins::ms_pCameraPosn;
+float CVisibilityPlugins::ms_cullCompsDist;
+float CVisibilityPlugins::ms_vehicleLod0Dist;
+float CVisibilityPlugins::ms_vehicleLod1Dist;
+float CVisibilityPlugins::ms_vehicleFadeDist;
+float CVisibilityPlugins::ms_bigVehicleLod0Dist;
+float CVisibilityPlugins::ms_bigVehicleLod1Dist;
+float CVisibilityPlugins::ms_pedLod0Dist;
+float CVisibilityPlugins::ms_pedLod1Dist;
+float CVisibilityPlugins::ms_pedFadeDist;
void
CVisibilityPlugins::Initialise(void)
{
- m_alphaList.Init(20);
+ m_alphaList.Init(NUMALPHALIST);
m_alphaList.head.item.sort = 0.0f;
m_alphaList.tail.item.sort = 100000000.0f;
- m_alphaEntityList.Init(150);
+#ifdef ASPECT_RATIO_SCALE
+ // default 150 if not enough for bigger FOVs
+ m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3);
+#else
+ m_alphaEntityList.Init(NUMALPHAENTITYLIST);
+#endif // ASPECT_RATIO_SCALE
m_alphaEntityList.head.item.sort = 0.0f;
m_alphaEntityList.tail.item.sort = 100000000.0f;
}
@@ -546,6 +543,21 @@ CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
return atomic;
}
+// This is needed for peds with only one clump, i.e. skinned models
+// strangely even the xbox version has no such thing
+RpAtomic*
+CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
+{
+ int32 alpha;
+
+ alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
+ if(alpha == 255)
+ AtomicDefaultRenderCallBack(atomic);
+ else
+ RenderAlphaAtomic(atomic, alpha);
+ return atomic;
+}
+
float
CVisibilityPlugins::GetDistanceSquaredFromCamera(RwFrame *frame)
{
@@ -603,6 +615,16 @@ CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump)
}
bool
+CVisibilityPlugins::MloVisibilityCB(RpClump *clump)
+{
+ RwFrame *frame = RpClumpGetFrame(clump);
+ CMloModelInfo *modelInfo = (CMloModelInfo*)GetFrameHierarchyId(frame);
+ if (sq(modelInfo->field_34) < GetDistanceSquaredFromCamera(frame))
+ return false;
+ return CVisibilityPlugins::FrustumSphereCB(clump);
+}
+
+bool
CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
{
RwSphere sphere;
@@ -831,59 +853,3 @@ CVisibilityPlugins::GetClumpAlpha(RpClump *clump)
{
return CLUMPEXT(clump)->alpha;
}
-
-
-STARTPATCHES
- InjectHook(0x527E50, CVisibilityPlugins::Initialise, PATCH_JUMP);
- InjectHook(0x527EA0, CVisibilityPlugins::Shutdown, PATCH_JUMP);
- InjectHook(0x528F90, CVisibilityPlugins::InitAlphaEntityList, PATCH_JUMP);
- InjectHook(0x528FF0, CVisibilityPlugins::InsertEntityIntoSortedList, PATCH_JUMP);
- InjectHook(0x528F80, CVisibilityPlugins::InitAlphaAtomicList, PATCH_JUMP);
- InjectHook(0x528FA0, CVisibilityPlugins::InsertAtomicIntoSortedList, PATCH_JUMP);
- InjectHook(0x528C50, CVisibilityPlugins::SetRenderWareCamera, PATCH_JUMP);
-
- InjectHook(0x527F60, SetAlphaCB, PATCH_JUMP);
- InjectHook(0x529040, CVisibilityPlugins::RenderAlphaAtomics, PATCH_JUMP);
- InjectHook(0x529070, CVisibilityPlugins::RenderFadingEntities, PATCH_JUMP);
-
- InjectHook(0x527F70, CVisibilityPlugins::RenderWheelAtomicCB, PATCH_JUMP);
- InjectHook(0x528000, CVisibilityPlugins::RenderObjNormalAtomic, PATCH_JUMP);
- InjectHook(0x5280B0, CVisibilityPlugins::RenderAlphaAtomic, PATCH_JUMP);
- InjectHook(0x528100, CVisibilityPlugins::RenderFadingAtomic, PATCH_JUMP);
-
- InjectHook(0x5283E0, CVisibilityPlugins::RenderVehicleHiDetailCB, PATCH_JUMP);
- InjectHook(0x5284B0, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB, PATCH_JUMP);
- InjectHook(0x5288A0, CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x528A10, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x528AD0, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat, PATCH_JUMP);
- InjectHook(0x5287F0, CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x528940, CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x528240, CVisibilityPlugins::RenderVehicleReallyLowDetailCB, PATCH_JUMP);
- InjectHook(0x5287B0, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle, PATCH_JUMP);
- InjectHook(0x5285D0, CVisibilityPlugins::RenderTrainHiDetailCB, PATCH_JUMP);
- InjectHook(0x5286A0, CVisibilityPlugins::RenderTrainHiDetailAlphaCB, PATCH_JUMP);
-
- InjectHook(0x528BC0, CVisibilityPlugins::RenderPedHiDetailCB, PATCH_JUMP);
- InjectHook(0x528B60, CVisibilityPlugins::RenderPedLowDetailCB, PATCH_JUMP);
-
-
- InjectHook(0x527DC0, CVisibilityPlugins::PluginAttach, PATCH_JUMP);
-
- InjectHook(0x527EC0, CVisibilityPlugins::SetAtomicModelInfo, PATCH_JUMP);
- InjectHook(0x527F00, CVisibilityPlugins::GetAtomicModelInfo, PATCH_JUMP);
- InjectHook(0x527F10, CVisibilityPlugins::SetAtomicFlag, PATCH_JUMP);
- InjectHook(0x527F30, CVisibilityPlugins::ClearAtomicFlag, PATCH_JUMP);
- InjectHook(0x527F50, CVisibilityPlugins::GetAtomicId, PATCH_JUMP);
- InjectHook(0x528C20, CVisibilityPlugins::SetAtomicRenderCallback, PATCH_JUMP);
-
- InjectHook(0x528D60, CVisibilityPlugins::SetFrameHierarchyId, PATCH_JUMP);
- InjectHook(0x528D80, CVisibilityPlugins::GetFrameHierarchyId, PATCH_JUMP);
-
- InjectHook(0x528ED0, CVisibilityPlugins::SetClumpModelInfo, PATCH_JUMP);
- InjectHook(0x528F50, CVisibilityPlugins::SetClumpAlpha, PATCH_JUMP);
- InjectHook(0x528F70, CVisibilityPlugins::GetClumpAlpha, PATCH_JUMP);
-
-
- InjectHook(0x529120, CVisibilityPlugins::GetDistanceSquaredFromCamera, PATCH_JUMP);
- InjectHook(0x5282A0, CVisibilityPlugins::GetDotProductWithCameraVector, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index 65d2675a..b367d7ee 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -20,19 +20,19 @@ public:
float sort;
};
- static CLinkList<AlphaObjectInfo> &m_alphaList;
- static CLinkList<AlphaObjectInfo> &m_alphaEntityList;
- static RwCamera *&ms_pCamera;
- static RwV3d *&ms_pCameraPosn;
- static float &ms_cullCompsDist;
- static float &ms_vehicleLod0Dist;
- static float &ms_vehicleLod1Dist;
- static float &ms_vehicleFadeDist;
- static float &ms_bigVehicleLod0Dist;
- static float &ms_bigVehicleLod1Dist;
- static float &ms_pedLod0Dist;
- static float &ms_pedLod1Dist;
- static float &ms_pedFadeDist;
+ static CLinkList<AlphaObjectInfo> m_alphaList;
+ static CLinkList<AlphaObjectInfo> m_alphaEntityList;
+ static RwCamera *ms_pCamera;
+ static RwV3d *ms_pCameraPosn;
+ static float ms_cullCompsDist;
+ static float ms_vehicleLod0Dist;
+ static float ms_vehicleLod1Dist;
+ static float ms_vehicleFadeDist;
+ static float ms_bigVehicleLod0Dist;
+ static float ms_bigVehicleLod1Dist;
+ static float ms_pedLod0Dist;
+ static float ms_pedLod1Dist;
+ static float ms_pedFadeDist;
static void Initialise(void);
static void Shutdown(void);
@@ -63,6 +63,7 @@ public:
static RpAtomic *RenderPlayerCB(RpAtomic *atomic);
static RpAtomic *RenderPedLowDetailCB(RpAtomic *atomic);
static RpAtomic *RenderPedHiDetailCB(RpAtomic *atomic);
+ static RpAtomic *RenderPedCB(RpAtomic *atomic); // for skinned models with only one clump
static void RenderAlphaAtomics(void);
static void RenderFadingEntities(void);
@@ -70,7 +71,7 @@ public:
// All actually unused
static bool DefaultVisibilityCB(RpClump *clump);
static bool FrustumSphereCB(RpClump *clump);
-// static bool MloVisibilityCB(RpClump *clump);
+ static bool MloVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB_BigVehicle(RpClump *clump);
@@ -97,7 +98,7 @@ public:
static void *AtomicDestructor(void *object, int32 offset, int32 len);
static void *AtomicCopyConstructor(void *dst, const void *src,
int32 offset, int32 len);
- static int32 &ms_atomicPluginOffset;
+ static int32 ms_atomicPluginOffset;
struct FrameExt
{
@@ -111,7 +112,7 @@ public:
static void *FrameDestructor(void *object, int32 offset, int32 len);
static void *FrameCopyConstructor(void *dst, const void *src,
int32 offset, int32 len);
- static int32 &ms_framePluginOffset;
+ static int32 ms_framePluginOffset;
// Not actually used
struct ClumpExt
@@ -127,7 +128,9 @@ public:
static void *ClumpDestructor(void *object, int32 offset, int32 len);
static void *ClumpCopyConstructor(void *dst, const void *src,
int32 offset, int32 len);
- static int32 &ms_clumpPluginOffset;
+ static int32 ms_clumpPluginOffset;
static bool PluginAttach(void);
};
+
+RpMaterial *SetAlphaCB(RpMaterial *material, void *data);
diff --git a/src/rw/rw.cpp b/src/rw/rw.cpp
deleted file mode 100644
index 3875f2a1..00000000
--- a/src/rw/rw.cpp
+++ /dev/null
@@ -1,839 +0,0 @@
-#include "common.h"
-#include "patcher.h"
-#include "rwcore.h"
-#include "rpworld.h"
-#include "rpmatfx.h"
-#include "rpskin.h"
-#include "rphanim.h"
-#include "rtbmp.h"
-
-typedef RwV3d *(*rwVectorsMultFn) (RwV3d * pointsOut,
- const RwV3d * pointsIn,
- RwInt32 numPoints,
- const RwMatrix * matrix);
-
-#ifndef RWLIBS
-
-WRAPPER void _rwObjectHasFrameSetFrame(void* object, RwFrame* frame) { EAXJMP(0x5BC950); }
-WRAPPER RpAtomic* AtomicDefaultRenderCallBack(RpAtomic* atomic) { EAXJMP(0x59E690); }
-WRAPPER void _rpAtomicResyncInterpolatedSphere(RpAtomic* atomic) { EAXJMP(0x59E6C0); }
-WRAPPER RwSphere const* RpAtomicGetWorldBoundingSphere(RpAtomic* atomic) { EAXJMP(0x59E800); }
-WRAPPER RwInt32 RpClumpGetNumAtomics(RpClump* clump) { EAXJMP(0x59ED50); }
-WRAPPER RpClump* RpClumpRender(RpClump* clump) { EAXJMP(0x59ED80); }
-WRAPPER RpClump* RpClumpForAllAtomics(RpClump* clump, RpAtomicCallBack callback, void* pData) { EAXJMP(0x59EDD0); }
-WRAPPER RpClump* RpClumpForAllCameras(RpClump* clump, RwCameraCallBack callback, void* pData) { EAXJMP(0x59EE10); }
-WRAPPER RpClump* RpClumpForAllLights(RpClump* clump, RpLightCallBack callback, void* pData) { EAXJMP(0x59EE60); }
-WRAPPER RpAtomic* RpAtomicCreate() { EAXJMP(0x59EEB0); }
-WRAPPER RpAtomic* RpAtomicSetGeometry(RpAtomic* atomic, RpGeometry* geometry, RwUInt32 flags) { EAXJMP(0x59EFA0); }
-WRAPPER RwBool RpAtomicDestroy(RpAtomic* atomic) { EAXJMP(0x59F020); }
-WRAPPER RpAtomic* RpAtomicClone(RpAtomic* atomic) { EAXJMP(0x59F0A0); }
-WRAPPER RpClump* RpClumpClone(RpClump* clump) { EAXJMP(0x59F1B0); }
-WRAPPER RpClump* RpClumpCreate() { EAXJMP(0x59F490); }
-WRAPPER RwBool RpClumpDestroy(RpClump* clump) { EAXJMP(0x59F500); }
-WRAPPER RpClump* RpClumpAddAtomic(RpClump* clump, RpAtomic* atomic) { EAXJMP(0x59F680); }
-WRAPPER RpClump* RpClumpRemoveAtomic(RpClump* clump, RpAtomic* atomic) { EAXJMP(0x59F6B0); }
-WRAPPER RpClump* RpClumpRemoveLight(RpClump* clump, RpLight* light) { EAXJMP(0x59F6E0); }
-WRAPPER RpClump* RpClumpStreamRead(RwStream* stream) { EAXJMP(0x59FC50); }
-WRAPPER RwInt32 RpAtomicRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A0510); }
-WRAPPER RwInt32 RpClumpRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A0540); }
-WRAPPER RwInt32 RpAtomicRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5A0570); }
-WRAPPER RwInt32 RpAtomicSetStreamAlwaysCallBack(RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB) { EAXJMP(0x5A05A0); }
-WRAPPER RwInt32 RpAtomicSetStreamRightsCallBack(RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB) { EAXJMP(0x5A05C0); }
-WRAPPER RwInt32 RpAtomicGetPluginOffset(RwUInt32 pluginID) { EAXJMP(0x5A05E0); }
-WRAPPER RpAtomic* RpAtomicSetFrame(RpAtomic* atomic, RwFrame* frame) { EAXJMP(0x5A0600); }
-WRAPPER RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor initCB, RwPluginObjectDestructor termCB) { EAXJMP(0x5A0DC0); }
-WRAPPER RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID) { EAXJMP(0x5A0DF0); }
-WRAPPER RwInt32 RwEngineGetNumSubSystems() { EAXJMP(0x5A0E10); }
-WRAPPER RwSubSystemInfo* RwEngineGetSubSystemInfo(RwSubSystemInfo* subSystemInfo, RwInt32 subSystemIndex) { EAXJMP(0x5A0E40); }
-WRAPPER RwInt32 RwEngineGetCurrentSubSystem() { EAXJMP(0x5A0E70); }
-WRAPPER RwBool RwEngineSetSubSystem(RwInt32 subSystemIndex) { EAXJMP(0x5A0EA0); }
-WRAPPER RwInt32 RwEngineGetNumVideoModes() { EAXJMP(0x5A0ED0); }
-WRAPPER RwVideoMode* RwEngineGetVideoModeInfo(RwVideoMode* modeinfo, RwInt32 modeIndex) { EAXJMP(0x5A0F00); }
-WRAPPER RwInt32 RwEngineGetCurrentVideoMode() { EAXJMP(0x5A0F30); }
-WRAPPER RwBool RwEngineSetVideoMode(RwInt32 modeIndex) { EAXJMP(0x5A0F60); }
-WRAPPER RwBool RwEngineStop() { EAXJMP(0x5A0F90); }
-WRAPPER RwBool RwEngineStart() { EAXJMP(0x5A0FE0); }
-WRAPPER RwBool RwEngineClose() { EAXJMP(0x5A1070); }
-WRAPPER RwBool RwEngineOpen(RwEngineOpenParams* initParams) { EAXJMP(0x5A10E0); }
-WRAPPER RwBool RwEngineTerm() { EAXJMP(0x5A1290); }
-WRAPPER RwBool RwEngineInit(RwMemoryFunctions* memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { EAXJMP(0x5A12D0); }
-WRAPPER void* _rwFrameOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A15E0); }
-WRAPPER void* _rwFrameClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A1650); }
-WRAPPER RwFrame* _rwFrameCloneAndLinkClones(RwFrame* root) { EAXJMP(0x5A1690); }
-WRAPPER RwFrame* _rwFramePurgeClone(RwFrame* root) { EAXJMP(0x5A1880); }
-WRAPPER RwBool RwFrameDirty(RwFrame const* frame) { EAXJMP(0x5A1930); }
-WRAPPER void _rwFrameInit(RwFrame* frame) { EAXJMP(0x5A1950); }
-WRAPPER RwFrame* RwFrameCreate() { EAXJMP(0x5A1A00); }
-WRAPPER RwBool RwFrameDestroy(RwFrame* frame) { EAXJMP(0x5A1A30); }
-WRAPPER RwBool RwFrameDestroyHierarchy(RwFrame* frame) { EAXJMP(0x5A1BF0); }
-WRAPPER RwFrame* RwFrameUpdateObjects(RwFrame* frame) { EAXJMP(0x5A1C60); }
-WRAPPER RwMatrix* RwFrameGetLTM(RwFrame* frame) { EAXJMP(0x5A1CE0); }
-WRAPPER RwFrame* RwFrameAddChild(RwFrame* parent, RwFrame* child) { EAXJMP(0x5A1D00); }
-WRAPPER RwFrame* RwFrameRemoveChild(RwFrame* child) { EAXJMP(0x5A1ED0); }
-WRAPPER RwFrame* RwFrameForAllChildren(RwFrame* frame, RwFrameCallBack callBack, void* data) { EAXJMP(0x5A1FC0); }
-WRAPPER RwFrame* RwFrameTranslate(RwFrame* frame, RwV3d const* v, RwOpCombineType combine) { EAXJMP(0x5A2000); }
-WRAPPER RwFrame* RwFrameScale(RwFrame* frame, RwV3d const* v, RwOpCombineType combine) { EAXJMP(0x5A20A0); }
-WRAPPER RwFrame* RwFrameTransform(RwFrame* frame, RwMatrix const* m, RwOpCombineType combine) { EAXJMP(0x5A2140); }
-WRAPPER RwFrame* RwFrameRotate(RwFrame* frame, RwV3d const* axis, RwReal angle, RwOpCombineType combine) { EAXJMP(0x5A21E0); }
-WRAPPER RwFrame* RwFrameSetIdentity(RwFrame* frame) { EAXJMP(0x5A2280); }
-WRAPPER RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, void* data) { EAXJMP(0x5A2340); }
-WRAPPER RwInt32 RwFrameRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A2380); }
-WRAPPER RwBool _rwMatrixSetMultFn(rwMatrixMultFn multMat) { EAXJMP(0x5A23B0); }
-WRAPPER RwReal _rwMatrixDeterminant(RwMatrix const* matrix) { EAXJMP(0x5A2520); }
-WRAPPER RwReal _rwMatrixOrthogonalError(RwMatrix const* matrix) { EAXJMP(0x5A2570); }
-WRAPPER RwReal _rwMatrixNormalError(RwMatrix const* matrix) { EAXJMP(0x5A25D0); }
-WRAPPER RwReal _rwMatrixIdentityError(RwMatrix const* matrix) { EAXJMP(0x5A2660); }
-WRAPPER void* _rwMatrixClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A2730); }
-WRAPPER void* _rwMatrixOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A2770); }
-WRAPPER RwMatrix* RwMatrixOptimize(RwMatrix* matrix, RwMatrixTolerance const* tolerance) { EAXJMP(0x5A2820); }
-WRAPPER RwMatrix* RwMatrixUpdate(RwMatrix* matrix) { EAXJMP(0x5A28E0); }
-WRAPPER RwMatrix* RwMatrixMultiply(RwMatrix* matrixOut, RwMatrix const* MatrixIn1, RwMatrix const* matrixIn2) { EAXJMP(0x5A28F0); }
-WRAPPER RwMatrix* RwMatrixRotateOneMinusCosineSine(RwMatrix* matrix, RwV3d const* unitAxis, RwReal oneMinusCosine, RwReal sine, RwOpCombineType combineOp) { EAXJMP(0x5A2960); }
-WRAPPER RwMatrix* RwMatrixRotate(RwMatrix* matrix, RwV3d const* axis, RwReal angle, RwOpCombineType combineOp) { EAXJMP(0x5A2BF0); }
-WRAPPER RwMatrix* RwMatrixInvert(RwMatrix* matrixOut, RwMatrix const* matrixIn) { EAXJMP(0x5A2C90); }
-WRAPPER RwMatrix* RwMatrixScale(RwMatrix* matrix, RwV3d const* scale, RwOpCombineType combineOp) { EAXJMP(0x5A2EE0); }
-WRAPPER RwMatrix* RwMatrixTranslate(RwMatrix* matrix, RwV3d const* translation, RwOpCombineType combineOp) { EAXJMP(0x5A3070); }
-WRAPPER RwMatrix* RwMatrixTransform(RwMatrix* matrix, RwMatrix const* transform, RwOpCombineType combineOp) { EAXJMP(0x5A31C0); }
-WRAPPER RwBool RwMatrixDestroy(RwMatrix* mpMat) { EAXJMP(0x5A3300); }
-WRAPPER RwMatrix* RwMatrixCreate() { EAXJMP(0x5A3330); }
-WRAPPER RwBool _rwVectorSetMultFn(rwVectorMultFn multPoint, rwVectorsMultFn multPoints, rwVectorMultFn multVector, rwVectorsMultFn multVectors) { EAXJMP(0x5A3450); }
-WRAPPER RwReal _rwV3dNormalize(RwV3d* out, RwV3d const* in) { EAXJMP(0x5A3600); }
-WRAPPER RwReal RwV3dLength(RwV3d const* in) { EAXJMP(0x5A36A0); }
-WRAPPER RwReal _rwSqrt(RwReal const num) { EAXJMP(0x5A3710); }
-WRAPPER RwReal _rwInvSqrt(RwReal const num) { EAXJMP(0x5A3770); }
-WRAPPER RwV3d* RwV3dTransformPoints(RwV3d* pointsOut, RwV3d const* pointsIn, RwInt32 numPoints, RwMatrix const* matrix) { EAXJMP(0x5A37D0); }
-WRAPPER RwV3d* RwV3dTransformVectors(RwV3d* vectorsOut, RwV3d const* vectorsIn, RwInt32 numPoints, RwMatrix const* matrix) { EAXJMP(0x5A37E0); }
-WRAPPER void* _rwVectorClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A37F0); }
-WRAPPER void* _rwVectorOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5A3860); }
-WRAPPER RwUInt32 RwStreamRead(RwStream* stream, void* buffer, RwUInt32 length) { EAXJMP(0x5A3AD0); }
-WRAPPER RwStream* RwStreamWrite(RwStream* stream, void const* buffer, RwUInt32 length) { EAXJMP(0x5A3C30); }
-WRAPPER RwStream* RwStreamSkip(RwStream* stream, RwUInt32 offset) { EAXJMP(0x5A3DF0); }
-WRAPPER RwBool RwStreamClose(RwStream* stream, void* pData) { EAXJMP(0x5A3F10); }
-WRAPPER RwStream* RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, void const* pData) { EAXJMP(0x5A3FE0); }
-WRAPPER RwReal RwIm2DGetNearScreenZ() { EAXJMP(0x5A43A0); }
-WRAPPER RwReal RwIm2DGetFarScreenZ() { EAXJMP(0x5A43B0); }
-WRAPPER RwBool RwRenderStateSet(RwRenderState state, void* value) { EAXJMP(0x5A43C0); }
-WRAPPER RwBool RwRenderStateGet(RwRenderState state, void* value) { EAXJMP(0x5A4410); }
-WRAPPER RwBool RwIm2DRenderLine(RwIm2DVertex* vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2) { EAXJMP(0x5A4420); }
-WRAPPER RwBool RwIm2DRenderPrimitive(RwPrimitiveType primType, RwIm2DVertex* vertices, RwInt32 numVertices) { EAXJMP(0x5A4430); }
-WRAPPER RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType primType, RwIm2DVertex* vertices, RwInt32 numVertices, RwImVertexIndex* indices, RwInt32 numIndices) { EAXJMP(0x5A4440); }
-WRAPPER RwCamera* RwCameraEndUpdate(RwCamera* camera) { EAXJMP(0x5A5020); }
-WRAPPER RwCamera* RwCameraBeginUpdate(RwCamera* camera) { EAXJMP(0x5A5030); }
-WRAPPER RwCamera* RwCameraSetViewOffset(RwCamera* camera, RwV2d const* offset) { EAXJMP(0x5A5040); }
-WRAPPER RwCamera* RwCameraSetNearClipPlane(RwCamera* camera, RwReal nearClip) { EAXJMP(0x5A5070); }
-WRAPPER RwCamera* RwCameraSetFarClipPlane(RwCamera* camera, RwReal farClip) { EAXJMP(0x5A5140); }
-WRAPPER RwFrustumTestResult RwCameraFrustumTestSphere(RwCamera const* camera, RwSphere const* sphere) { EAXJMP(0x5A5170); }
-WRAPPER RwCamera* RwCameraClear(RwCamera* camera, RwRGBA* colour, RwInt32 clearMode) { EAXJMP(0x5A51E0); }
-WRAPPER RwCamera* RwCameraShowRaster(RwCamera* camera, void* pDev, RwUInt32 flags) { EAXJMP(0x5A5210); }
-WRAPPER RwCamera* RwCameraSetProjection(RwCamera* camera, RwCameraProjection projection) { EAXJMP(0x5A5240); }
-WRAPPER RwCamera* RwCameraSetViewWindow(RwCamera* camera, RwV2d const* viewWindow) { EAXJMP(0x5A52B0); }
-WRAPPER RwInt32 RwCameraRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5A52F0); }
-WRAPPER RwBool RwCameraDestroy(RwCamera* camera) { EAXJMP(0x5A5320); }
-WRAPPER RwCamera* RwCameraCreate() { EAXJMP(0x5A5360); }
-WRAPPER RwBool RwTextureSetMipmapping(RwBool enable) { EAXJMP(0x5A7100); }
-WRAPPER RwBool RwTextureGetMipmapping() { EAXJMP(0x5A7120); }
-WRAPPER RwBool RwTextureSetAutoMipmapping(RwBool enable) { EAXJMP(0x5A7130); }
-WRAPPER RwBool RwTextureGetAutoMipmapping() { EAXJMP(0x5A7150); }
-WRAPPER RwTexDictionary* RwTexDictionaryCreate() { EAXJMP(0x5A7160); }
-WRAPPER RwBool RwTexDictionaryDestroy(RwTexDictionary* dict) { EAXJMP(0x5A7200); }
-WRAPPER RwTexDictionary const* RwTexDictionaryForAllTextures(RwTexDictionary const* dict, RwTextureCallBack fpCallBack, void* pData) { EAXJMP(0x5A7290); }
-WRAPPER RwTexture* RwTextureCreate(RwRaster* raster) { EAXJMP(0x5A72D0); }
-WRAPPER RwBool RwTextureDestroy(RwTexture* texture) { EAXJMP(0x5A7330); }
-WRAPPER RwTexture* RwTextureSetName(RwTexture* texture, RwChar const* name) { EAXJMP(0x5A73B0); }
-WRAPPER RwTexture* RwTextureSetMaskName(RwTexture* texture, RwChar const* maskName) { EAXJMP(0x5A7420); }
-WRAPPER RwTexture* RwTexDictionaryAddTexture(RwTexDictionary* dict, RwTexture* texture) { EAXJMP(0x5A7490); }
-WRAPPER RwTexture* RwTexDictionaryFindNamedTexture(RwTexDictionary* dict, RwChar const* name) { EAXJMP(0x5A74D0); }
-WRAPPER RwTexDictionary* RwTexDictionarySetCurrent(RwTexDictionary* dict) { EAXJMP(0x5A7550); }
-WRAPPER RwTexDictionary* RwTexDictionaryGetCurrent() { EAXJMP(0x5A7570); }
-WRAPPER RwTexture* RwTextureRead(RwChar const* name, RwChar const* maskName) { EAXJMP(0x5A7580); }
-WRAPPER RwBool RwTextureRasterGenerateMipmaps(RwRaster* raster, RwImage* image) { EAXJMP(0x5A7780); }
-WRAPPER RwImage* RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth) { EAXJMP(0x5A9120); }
-WRAPPER RwBool RwImageDestroy(RwImage* image) { EAXJMP(0x5A9180); }
-WRAPPER RwImage* RwImageAllocatePixels(RwImage* image) { EAXJMP(0x5A91E0); }
-WRAPPER RwImage* RwImageFreePixels(RwImage* image) { EAXJMP(0x5A92A0); }
-WRAPPER RwImage* RwImageMakeMask(RwImage* image) { EAXJMP(0x5A92D0); }
-WRAPPER RwImage* RwImageApplyMask(RwImage* image, RwImage const* mask) { EAXJMP(0x5A93A0); }
-WRAPPER RwChar const* RwImageSetPath(RwChar const* path) { EAXJMP(0x5A9750); }
-WRAPPER RwImage* RwImageRead(RwChar const* imageName) { EAXJMP(0x5A9810); }
-WRAPPER RwChar const* RwImageFindFileType(RwChar const* imageName) { EAXJMP(0x5A9B40); }
-WRAPPER RwImage* RwImageReadMaskedImage(RwChar const* imageName, RwChar const* maskname) { EAXJMP(0x5A9C10); }
-WRAPPER RwImage* RwImageCopy(RwImage* destImage, RwImage const* sourceImage) { EAXJMP(0x5A9F50); }
-WRAPPER RwImage* RwImageGammaCorrect(RwImage* image) { EAXJMP(0x5AA130); }
-WRAPPER RwBool RwImageSetGamma(RwReal gammaValue) { EAXJMP(0x5AA2C0); }
-WRAPPER RwStream* _rwStreamWriteVersionedChunkHeader(RwStream* stream, RwInt32 type, RwInt32 size, RwUInt32 version, RwUInt32 buildNum) { EAXJMP(0x5AA4E0); }
-WRAPPER RwBool RwStreamFindChunk(RwStream* stream, RwUInt32 type, RwUInt32* lengthOut, RwUInt32* versionOut) { EAXJMP(0x5AA540); }
-WRAPPER void* RwMemLittleEndian32(void* mem, RwUInt32 size) { EAXJMP(0x5AA640); }
-WRAPPER void* RwMemNative32(void* mem, RwUInt32 size) { EAXJMP(0x5AA650); }
-WRAPPER void* RwMemFloat32ToReal(void* mem, RwUInt32 size) { EAXJMP(0x5AA660); }
-WRAPPER RwStream* RwStreamWriteReal(RwStream* stream, RwReal const* reals, RwUInt32 numBytes) { EAXJMP(0x5AA680); }
-WRAPPER RwStream* RwStreamWriteInt32(RwStream* stream, RwInt32 const* ints, RwUInt32 numBytes) { EAXJMP(0x5AA720); }
-WRAPPER RwStream* RwStreamReadReal(RwStream* stream, RwReal* reals, RwUInt32 numBytes) { EAXJMP(0x5AA740); }
-WRAPPER RwStream* RwStreamReadInt32(RwStream* stream, RwInt32* ints, RwUInt32 numBytes) { EAXJMP(0x5AA7B0); }
-WRAPPER RwUInt32 RwTextureStreamGetSize(RwTexture const* texture) { EAXJMP(0x5AA800); }
-WRAPPER RwTexture const* RwTextureStreamWrite(RwTexture const* texture, RwStream* stream) { EAXJMP(0x5AA870); }
-WRAPPER RwTexture* RwTextureStreamRead(RwStream* stream) { EAXJMP(0x5AAA40); }
-WRAPPER RwTexDictionary const* RwTexDictionaryStreamWrite(RwTexDictionary const* texDict, RwStream* stream) { EAXJMP(0x5AB020); }
-WRAPPER RpMorphTarget const* RpMorphTargetCalcBoundingSphere(RpMorphTarget const* morphTarget, RwSphere* boundingSphere) { EAXJMP(0x5AC890); }
-WRAPPER RwInt32 RpGeometryAddMorphTargets(RpGeometry* geometry, RwInt32 mtcount) { EAXJMP(0x5AC9A0); }
-WRAPPER RpGeometry const* RpGeometryTriangleSetVertexIndices(RpGeometry const* geometry, RpTriangle* triangle, RwUInt16 vert1, RwUInt16 vert2, RwUInt16 vert3) { EAXJMP(0x5ACB60); }
-WRAPPER RpGeometry* RpGeometryTriangleSetMaterial(RpGeometry* geometry, RpTriangle* triangle, RpMaterial* material) { EAXJMP(0x5ACB90); }
-WRAPPER RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, RpMaterialCallBack fpCallBack, void* pData) { EAXJMP(0x5ACBF0); }
-WRAPPER RpGeometry* RpGeometryLock(RpGeometry* geometry, RwInt32 lockMode) { EAXJMP(0x5ACC30); }
-WRAPPER RpGeometry* RpGeometryUnlock(RpGeometry* geometry) { EAXJMP(0x5ACC60); }
-WRAPPER RpGeometry* RpGeometryCreate(RwInt32 numVert, RwInt32 numTriangles, RwUInt32 format) { EAXJMP(0x5ACD10); }
-WRAPPER RpGeometry* _rpGeometryAddRef(RpGeometry* geometry) { EAXJMP(0x5ACF40); }
-WRAPPER RwBool RpGeometryDestroy(RpGeometry* geometry) { EAXJMP(0x5ACF50); }
-WRAPPER RwInt32 RpGeometryRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5ACFF0); }
-WRAPPER RwInt32 RpGeometryRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5AD020); }
-WRAPPER RpGeometry* RpGeometryStreamRead(RwStream* stream) { EAXJMP(0x5AD050); }
-WRAPPER RwRaster* RwRasterGetCurrentContext() { EAXJMP(0x5AD6D0); }
-WRAPPER RwRaster* RwRasterUnlock(RwRaster* raster) { EAXJMP(0x5AD6F0); }
-WRAPPER RwRaster* RwRasterRenderFast(RwRaster* raster, RwInt32 x, RwInt32 y) { EAXJMP(0x5AD710); }
-WRAPPER RwRaster* RwRasterUnlockPalette(RwRaster* raster) { EAXJMP(0x5AD750); }
-WRAPPER RwBool RwRasterDestroy(RwRaster* raster) { EAXJMP(0x5AD780); }
-WRAPPER RwRaster* RwRasterPushContext(RwRaster* raster) { EAXJMP(0x5AD7C0); }
-WRAPPER RwInt32 RwRasterRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5AD810); }
-WRAPPER RwUInt8* RwRasterLockPalette(RwRaster* raster, RwInt32 lockMode) { EAXJMP(0x5AD840); }
-WRAPPER RwRaster* RwRasterPopContext() { EAXJMP(0x5AD870); }
-WRAPPER RwInt32 RwRasterGetNumLevels(RwRaster* raster) { EAXJMP(0x5AD8C0); }
-WRAPPER RwRaster* RwRasterShowRaster(RwRaster* raster, void* dev, RwUInt32 flags) { EAXJMP(0x5AD900); }
-WRAPPER RwRaster* RwRasterCreate(RwInt32 width, RwInt32 height, RwInt32 depth, RwInt32 flags) { EAXJMP(0x5AD930); }
-WRAPPER RwUInt8* RwRasterLock(RwRaster* raster, RwUInt8 level, RwInt32 lockMode) { EAXJMP(0x5AD9D0); }
-WRAPPER RpMaterial* RpMaterialCreate() { EAXJMP(0x5ADC30); }
-WRAPPER RwBool RpMaterialDestroy(RpMaterial* material) { EAXJMP(0x5ADCB0); }
-WRAPPER RpMaterial* RpMaterialSetTexture(RpMaterial* material, RwTexture* texture) { EAXJMP(0x5ADD10); }
-WRAPPER RwInt32 RpMaterialRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5ADD40); }
-WRAPPER RwInt32 RpMaterialRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5ADD70); }
-WRAPPER RpMaterial* RpMaterialStreamRead(RwStream* stream) { EAXJMP(0x5ADDA0); }
-WRAPPER RpWorldSector* _rpSectorDefaultRenderCallBack(RpWorldSector* sector) { EAXJMP(0x5AE0B0); }
-WRAPPER RwBool _rpWorldForAllGlobalLights(RpLightCallBack callBack, void* pData) { EAXJMP(0x5AE100); }
-WRAPPER RpWorldSector* _rpWorldSectorForAllLocalLights(RpWorldSector* sector, RpLightCallBack callBack, void* pData) { EAXJMP(0x5AE150); }
-WRAPPER RpWorld* RpWorldUnlock(RpWorld* world) { EAXJMP(0x5AE190); }
-WRAPPER RpWorld* RpWorldSectorGetWorld(RpWorldSector const* sector) { EAXJMP(0x5AE2B0); }
-WRAPPER RwBool RpWorldDestroy(RpWorld* world) { EAXJMP(0x5AE340); }
-WRAPPER RpWorld* RpWorldCreate(RwBBox* boundingBox) { EAXJMP(0x5AE6A0); }
-WRAPPER RwInt32 RpWorldRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5AEA40); }
-WRAPPER RwInt32 RpWorldRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5AEA70); }
-WRAPPER RwBool RpWorldPluginAttach() { EAXJMP(0x5AEAA0); }
-WRAPPER RpWorld* RpWorldAddCamera(RpWorld* world, RwCamera* camera) { EAXJMP(0x5AFB80); }
-WRAPPER RpWorld* RpWorldRemoveCamera(RpWorld* world, RwCamera* camera) { EAXJMP(0x5AFBB0); }
-WRAPPER RpWorld* RpAtomicGetWorld(RpAtomic const* atomic) { EAXJMP(0x5AFC10); }
-WRAPPER RpWorld* RpWorldAddClump(RpWorld* world, RpClump* clump) { EAXJMP(0x5AFC20); }
-WRAPPER RpWorld* RpWorldAddLight(RpWorld* world, RpLight* light) { EAXJMP(0x5AFDA0); }
-WRAPPER RpWorld* RpWorldRemoveLight(RpWorld* world, RpLight* light) { EAXJMP(0x5AFDF0); }
-WRAPPER RwImage* RtBMPImageRead(RwChar const* imageName) { EAXJMP(0x5AFE70); }
-WRAPPER RwBool RpSkinPluginAttach() { EAXJMP(0x5B07D0); }
-WRAPPER RpAtomic* RpSkinAtomicSetHAnimHierarchy(RpAtomic* atomic, RpHAnimHierarchy* hierarchy) { EAXJMP(0x5B1050); }
-WRAPPER RpHAnimHierarchy* RpSkinAtomicGetHAnimHierarchy(RpAtomic const* atomic) { EAXJMP(0x5B1070); }
-WRAPPER RpSkin* RpSkinGeometryGetSkin(RpGeometry* geometry) { EAXJMP(0x5B1080); }
-WRAPPER RpGeometry* RpSkinGeometrySetSkin(RpGeometry* geometry, RpSkin* skin) { EAXJMP(0x5B1090); }
-WRAPPER RwMatrix const* RpSkinGetSkinToBoneMatrices(RpSkin* skin) { EAXJMP(0x5B10D0); }
-WRAPPER RpHAnimHierarchy* RpHAnimHierarchyCreate(RwInt32 numNodes, RwUInt32* nodeFlags, RwInt32* nodeIDs, RpHAnimHierarchyFlag flags, RwInt32 maxKeyFrameSize) { EAXJMP(0x5B10E0); }
-WRAPPER RpHAnimHierarchy* RpHAnimFrameGetHierarchy(RwFrame* frame) { EAXJMP(0x5B11F0); }
-WRAPPER RwBool RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy* hierarchy, RpHAnimAnimation* anim) { EAXJMP(0x5B1200); }
-WRAPPER RwBool RpHAnimHierarchySubAnimTime(RpHAnimHierarchy* hierarchy, RwReal time) { EAXJMP(0x5B12B0); }
-WRAPPER RwBool RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy* hierarchy, RwReal time) { EAXJMP(0x5B1480); }
-WRAPPER RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy* hierarchy) { EAXJMP(0x5B1780); }
-WRAPPER RpHAnimAnimation* RpHAnimAnimationStreamRead(RwStream* stream) { EAXJMP(0x5B1C10); }
-WRAPPER RwBool RpHAnimPluginAttach() { EAXJMP(0x5B1D50); }
-WRAPPER RwBool RpMatFXPluginAttach() { EAXJMP(0x5B2640); }
-WRAPPER RpAtomic* RpMatFXAtomicEnableEffects(RpAtomic* atomic) { EAXJMP(0x5B3750); }
-WRAPPER RpMaterial* RpMatFXMaterialSetEffects(RpMaterial* material, RpMatFXMaterialFlags flags) { EAXJMP(0x5B3780); }
-WRAPPER RpMaterial* RpMatFXMaterialSetupEnvMap(RpMaterial* material, RwTexture* texture, RwFrame* frame, RwBool useFrameBufferAlpha, RwReal coef) { EAXJMP(0x5B38D0); }
-WRAPPER RpMaterial* RpMatFXMaterialSetBumpMapTexture(RpMaterial* material, RwTexture* texture) { EAXJMP(0x5B3A40); }
-WRAPPER RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) { EAXJMP(0x5B3CF0); }
-WRAPPER void RwD3D8GetRenderState(RwUInt32 state, void* value) { EAXJMP(0x5B3D40); }
-WRAPPER RwBool RwD3D8SetTextureStageState(RwUInt32 stage, RwUInt32 type, RwUInt32 value) { EAXJMP(0x5B3D60); }
-WRAPPER RwBool RwD3D8SetTexture(RwTexture* texture, RwUInt32 stage) { EAXJMP(0x5B53A0); }
-WRAPPER void* RwIm3DTransform(RwIm3DVertex* pVerts, RwUInt32 numVerts, RwMatrix* ltm, RwUInt32 flags) { EAXJMP(0x5B6720); }
-WRAPPER RwBool RwIm3DEnd() { EAXJMP(0x5B67F0); }
-WRAPPER RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType, RwImVertexIndex* indices, RwInt32 numIndices) { EAXJMP(0x5B6820); }
-WRAPPER RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2) { EAXJMP(0x5B6980); }
-WRAPPER RxPipeline* RwIm3DSetTransformPipeline(RxPipeline* pipeline) { EAXJMP(0x5B6A50); }
-WRAPPER RxPipeline* RwIm3DSetRenderPipeline(RxPipeline* pipeline, RwPrimitiveType primType) { EAXJMP(0x5B6AC0); }
-WRAPPER void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) { EAXJMP(0x5B95D0); }
-WRAPPER RwBool RwD3D8CameraAttachWindow(void* camera, void* hwnd) { EAXJMP(0x5B9640); }
-WRAPPER RwBool RwD3D8DeviceSupportsDXTTexture() { EAXJMP(0x5BAEB0); }
-WRAPPER RwBool RwD3D8SetVertexShader(RwUInt32 handle) { EAXJMP(0x5BAF90); }
-WRAPPER RwBool RwD3D8SetPixelShader(RwUInt32 handle) { EAXJMP(0x5BAFD0); }
-WRAPPER RwBool RwD3D8SetStreamSource(RwUInt32 streamNumber, void* streamData, RwUInt32 stride) { EAXJMP(0x5BB010); }
-WRAPPER RwBool RwD3D8SetIndices(void* indexData, RwUInt32 baseVertexIndex) { EAXJMP(0x5BB060); }
-WRAPPER RwBool RwD3D8DrawIndexedPrimitive(RwUInt32 primitiveType, RwUInt32 minIndex, RwUInt32 numVertices, RwUInt32 startIndex, RwUInt32 numIndices) { EAXJMP(0x5BB0B0); }
-WRAPPER RwBool RwD3D8DrawPrimitive(RwUInt32 primitiveType, RwUInt32 startVertex, RwUInt32 numVertices) { EAXJMP(0x5BB140); }
-WRAPPER RwBool RwD3D8SetTransform(RwUInt32 state, void const* matrix) { EAXJMP(0x5BB1D0); }
-WRAPPER void RwD3D8GetTransform(RwUInt32 state, void* matrix) { EAXJMP(0x5BB310); }
-WRAPPER RwBool RwD3D8SetTransformWorld(RwMatrix const* matrix) { EAXJMP(0x5BB340); }
-WRAPPER RwBool RwD3D8SetSurfaceProperties(RwRGBA const* color, RwSurfaceProperties const* surfaceProps, RwBool modulate) { EAXJMP(0x5BB490); }
-WRAPPER RwBool RwD3D8SetLight(RwInt32 index, void const* light) { EAXJMP(0x5BB7A0); }
-WRAPPER RwBool RwD3D8EnableLight(RwInt32 index, RwBool enable) { EAXJMP(0x5BB890); }
-WRAPPER RwBool RwD3D8DynamicVertexBufferCreate(RwUInt32 fvf, RwUInt32 size, void** vertexBuffer) { EAXJMP(0x5BB9F0); }
-WRAPPER void RwD3D8DynamicVertexBufferDestroy(void* vertexBuffer) { EAXJMP(0x5BBAE0); }
-WRAPPER RwBool RwD3D8IndexBufferCreate(RwUInt32 numIndices, void** indexBuffer) { EAXJMP(0x5BBB10); }
-WRAPPER RwBool RwD3D8CreatePixelShader(RwUInt32 const* function, RwUInt32* handle) { EAXJMP(0x5BBB40); }
-WRAPPER void RwD3D8DeletePixelShader(RwUInt32 handle) { EAXJMP(0x5BBB90); }
-WRAPPER RwBool RwD3D8SetPixelShaderConstant(RwUInt32 registerAddress, void const* antData, RwUInt32 antCount) { EAXJMP(0x5BBC00); }
-WRAPPER void const* RwD3D8GetCaps() { EAXJMP(0x5BBC30); }
-WRAPPER RwBool RwD3D8CameraIsSphereFullyInsideFrustum(void const* camera, void const* sphere) { EAXJMP(0x5BBC40); }
-WRAPPER RwBool RwD3D8CameraIsBBoxFullyInsideFrustum(void const* camera, void const* boundingBox) { EAXJMP(0x5BBCA0); }
-WRAPPER RwBool RwD3D8DynamicVertexBufferLock(RwUInt32 vertexSize, RwUInt32 numVertex, void** vertexBufferOut, void** vertexDataOut, RwUInt32* baseIndexOut) { EAXJMP(0x5BBD30); }
-WRAPPER RwBool RwD3D8DynamicVertexBufferUnlock(void* vertexBuffer) { EAXJMP(0x5BBEB0); }
-WRAPPER RwBool _rwIntelSSEsupported() { EAXJMP(0x5BBED0); }
-WRAPPER RwImage* RwImageSetFromRaster(RwImage* image, RwRaster* raster) { EAXJMP(0x5BBF10); }
-WRAPPER RwRaster* RwRasterSetFromImage(RwRaster* raster, RwImage* image) { EAXJMP(0x5BBF50); }
-WRAPPER RwImage* RwImageFindRasterFormat(RwImage* ipImage, RwInt32 nRasterType, RwInt32* npWidth, RwInt32* npHeight, RwInt32* npDepth, RwInt32* npFormat) { EAXJMP(0x5BBF80); }
-WRAPPER RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5BBFF0); }
-WRAPPER rwFrameList* _rwFrameListDeinitialize(rwFrameList* frameList) { EAXJMP(0x5BC020); }
-WRAPPER rwFrameList* _rwFrameListStreamRead(RwStream* stream, rwFrameList* fl) { EAXJMP(0x5BC050); }
-WRAPPER RpLight* RpLightSetRadius(RpLight* light, RwReal radius) { EAXJMP(0x5BC300); }
-WRAPPER RpLight* RpLightSetColor(RpLight* light, RwRGBAReal const* color) { EAXJMP(0x5BC320); }
-WRAPPER RwReal RpLightGetConeAngle(RpLight const* light) { EAXJMP(0x5BC370); }
-WRAPPER RwInt32 RpLightRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5BC5B0); }
-WRAPPER RpLight* RpLightStreamRead(RwStream* stream) { EAXJMP(0x5BC5E0); }
-WRAPPER RwBool RpLightDestroy(RpLight* light) { EAXJMP(0x5BC780); }
-WRAPPER RpLight* RpLightCreate(RwInt32 type) { EAXJMP(0x5BC7C0); }
-WRAPPER void _rwD3D8TexDictionaryEnableRasterFormatConversion(RwBool enable) { EAXJMP(0x5BE280); }
-WRAPPER RwFileFunctions* RwOsGetFileInterface() { EAXJMP(0x5BF110); }
-WRAPPER RwBool RwFreeListDestroy(RwFreeList* freelist) { EAXJMP(0x5C1720); }
-WRAPPER RwFreeList* RwFreeListCreate(RwInt32 entrySize, RwInt32 entriesPerBlock, RwInt32 alignment) { EAXJMP(0x5C1790); }
-WRAPPER RwInt32 RwFreeListPurge(RwFreeList* freelist) { EAXJMP(0x5C19F0); }
-WRAPPER RwInt32 RwFreeListPurgeAllFreeLists() { EAXJMP(0x5C1B90); }
-WRAPPER RwFreeList* RwFreeListForAllUsed(RwFreeList* freelist, RwFreeListCallBack fpCallBack, void* pData) { EAXJMP(0x5C1D40); }
-WRAPPER RwBool _rxPipelineClose() { EAXJMP(0x5C2780); }
-WRAPPER RwBool _rxPipelineOpen() { EAXJMP(0x5C27E0); }
-WRAPPER RxHeap* RxHeapGetGlobalHeap() { EAXJMP(0x5C2AD0); }
-WRAPPER RxPacket* RxPacketCreate(RxPipelineNode* node) { EAXJMP(0x5C2AE0); }
-WRAPPER RxCluster* RxClusterSetExternalData(RxCluster* cluster, void* data, RwInt32 stride, RwInt32 numElements) { EAXJMP(0x5C2B10); }
-WRAPPER RxCluster* RxClusterSetData(RxCluster* cluster, void* data, RwInt32 stride, RwInt32 numElements) { EAXJMP(0x5C2B70); }
-WRAPPER RxCluster* RxClusterInitializeData(RxCluster* cluster, RwUInt32 numElements, RwUInt16 stride) { EAXJMP(0x5C2BD0); }
-WRAPPER RxCluster* RxClusterResizeData(RxCluster* CurrentCluster, RwUInt32 NumElements) { EAXJMP(0x5C2C40); }
-WRAPPER RxCluster* RxClusterLockWrite(RxPacket* packet, RwUInt32 clusterIndex, RxPipelineNode* node) { EAXJMP(0x5C2C90); }
-WRAPPER RxPipeline* RxPipelineExecute(RxPipeline* pipeline, void* data, RwBool heapReset) { EAXJMP(0x5C2D60); }
-WRAPPER RxPipeline* RxPipelineCreate() { EAXJMP(0x5C2E00); }
-WRAPPER void _rxPipelineDestroy(RxPipeline* Pipeline) { EAXJMP(0x5C2E70); }
-WRAPPER RwBool RwResourcesFreeResEntry(RwResEntry* entry) { EAXJMP(0x5C3080); }
-WRAPPER void _rwResourcesPurge() { EAXJMP(0x5C30F0); }
-WRAPPER RwResEntry* RwResourcesAllocateResEntry(void* owner, RwResEntry** ownerRef, RwInt32 size, RwResEntryDestroyNotify destroyNotify) { EAXJMP(0x5C3170); }
-WRAPPER RwBool RwResourcesEmptyArena() { EAXJMP(0x5C3360); }
-WRAPPER RwBool _rwPluginRegistryOpen() { EAXJMP(0x5C3450); }
-WRAPPER RwBool _rwPluginRegistryClose() { EAXJMP(0x5C3480); }
-WRAPPER RwInt32 _rwPluginRegistryGetPluginOffset(RwPluginRegistry const* reg, RwUInt32 pluginID) { EAXJMP(0x5C3590); }
-WRAPPER RwInt32 _rwPluginRegistryAddPlugin(RwPluginRegistry* reg, RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5C35C0); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryInitObject(RwPluginRegistry const* reg, void* object) { EAXJMP(0x5C37F0); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryDeInitObject(RwPluginRegistry const* reg, void* object) { EAXJMP(0x5C3850); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryCopyObject(RwPluginRegistry const* reg, void* dstObject, void const* srcObject) { EAXJMP(0x5C3880); }
-WRAPPER RwError* RwErrorSet(RwError* code) { EAXJMP(0x5C3910); }
-WRAPPER RwInt32 _rwerror(RwInt32 code, ...) { EAXJMP(0x5C3970); }
-WRAPPER RwInt32 _rwPluginRegistryAddPluginStream(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5C3980); }
-WRAPPER RwInt32 _rwPluginRegistryAddPlgnStrmlwysCB(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkAlwaysCallBack alwaysCB) { EAXJMP(0x5C39C0); }
-WRAPPER RwInt32 _rwPluginRegistryAddPlgnStrmRightsCB(RwPluginRegistry* reg, RwUInt32 pluginID, RwPluginDataChunkRightsCallBack rightsCB) { EAXJMP(0x5C39F0); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryReadDataChunks(RwPluginRegistry const* reg, RwStream* stream, void* object) { EAXJMP(0x5C3A20); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryInvokeRights(RwPluginRegistry const* reg, RwUInt32 id, void* obj, RwUInt32 extraData) { EAXJMP(0x5C3B50); }
-WRAPPER RwInt32 _rwPluginRegistryGetSize(RwPluginRegistry const* reg, void const* object) { EAXJMP(0x5C3BA0); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistryWriteDataChunks(RwPluginRegistry const* reg, RwStream* stream, void const* object) { EAXJMP(0x5C3BE0); }
-WRAPPER RwPluginRegistry const* _rwPluginRegistrySkipDataChunks(RwPluginRegistry const* reg, RwStream* stream) { EAXJMP(0x5C3CB0); }
-WRAPPER RwCamera* RwCameraStreamRead(RwStream* stream) { EAXJMP(0x5C3D30); }
-WRAPPER RwBBox* RwBBoxCalculate(RwBBox* boundBox, RwV3d const* verts, RwInt32 numVerts) { EAXJMP(0x5C5570); }
-WRAPPER RwImage* RwImageResample(RwImage* dstImage, RwImage const* srcImage) { EAXJMP(0x5C72B0); }
-WRAPPER RwImage* RwImageCreateResample(RwImage const* srcImage, RwInt32 width, RwInt32 height) { EAXJMP(0x5C7B30); }
-WRAPPER RxRenderStateVector* RxRenderStateVectorSetDefaultRenderStateVector(RxRenderStateVector* rsvp) { EAXJMP(0x5D9240); }
-WRAPPER RxRenderStateVector* RxRenderStateVectorCreate(RwBool current) { EAXJMP(0x5D9340); }
-WRAPPER void RxRenderStateVectorDestroy(RxRenderStateVector* rsvp) { EAXJMP(0x5D9410); }
-WRAPPER RxRenderStateVector* RxRenderStateVectorLoadDriverState(RxRenderStateVector* rsvp) { EAXJMP(0x5D9460); }
-WRAPPER void _rxEmbeddedPacketBetweenPipelines(RxPipeline* fromPipeline, RxPipeline* toPipeline) { EAXJMP(0x5D95D0); }
-WRAPPER RxPipelineNode* _rxEmbeddedPacketBetweenNodes(RxPipeline* pipeline, RxPipelineNode* nodeFrom, RwUInt32 whichOutput) { EAXJMP(0x5D9740); }
-WRAPPER void _rxPacketDestroy(RxPacket* Packet) { EAXJMP(0x5D9810); }
-WRAPPER RpMaterialList* _rpMaterialListDeinitialize(RpMaterialList* matList) { EAXJMP(0x5C8B10); }
-WRAPPER RpMaterialList* _rpMaterialListInitialize(RpMaterialList* matList) { EAXJMP(0x5C8B70); }
-WRAPPER RpMaterial* _rpMaterialListGetMaterial(RpMaterialList const* matList, RwInt32 matIndex) { EAXJMP(0x5C8B80); }
-WRAPPER RwInt32 _rpMaterialListAppendMaterial(RpMaterialList* matList, RpMaterial* material) { EAXJMP(0x5C8B90); }
-WRAPPER RwInt32 _rpMaterialListFindMaterialIndex(RpMaterialList const* matList, RpMaterial const* material) { EAXJMP(0x5C8C50); }
-WRAPPER RpMaterialList* _rpMaterialListStreamRead(RwStream* stream, RpMaterialList* matList) { EAXJMP(0x5C8C80); }
-WRAPPER RpMeshHeader* _rpMeshHeaderCreate(RwUInt32 size) { EAXJMP(0x5C8FE0); }
-WRAPPER void* _rpMeshClose(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5C8FF0); }
-WRAPPER void* _rpMeshOpen(void* instance, RwInt32 offset, RwInt32 size) { EAXJMP(0x5C9020); }
-WRAPPER RpBuildMesh* _rpBuildMeshCreate(RwUInt32 bufferSize) { EAXJMP(0x5C9140); }
-WRAPPER RwBool _rpBuildMeshDestroy(RpBuildMesh* mesh) { EAXJMP(0x5C9220); }
-WRAPPER RwBool _rpMeshDestroy(RpMeshHeader* mesh) { EAXJMP(0x5C9260); }
-WRAPPER RpBuildMesh* _rpBuildMeshAddTriangle(RpBuildMesh* mesh, RpMaterial* material, RwInt32 vert1, RwInt32 vert2, RwInt32 vert3) { EAXJMP(0x5C92A0); }
-WRAPPER RpMeshHeader* _rpMeshHeaderForAllMeshes(RpMeshHeader* meshHeader, RpMeshCallBack fpCallBack, void* pData) { EAXJMP(0x5C9380); }
-WRAPPER RwStream* _rpMeshWrite(RpMeshHeader const* meshHeader, void const* object, RwStream* stream, RpMaterialList const* matList) { EAXJMP(0x5C93C0); }
-WRAPPER RpMeshHeader* _rpMeshRead(RwStream* stream, void const* object, RpMaterialList const* matList) { EAXJMP(0x5C9510); }
-WRAPPER RwInt32 _rpMeshSize(RpMeshHeader const* meshHeader, void const* object) { EAXJMP(0x5C96E0); }
-WRAPPER RpMeshHeader* RpBuildMeshGenerateDefaultTriStrip(RpBuildMesh* buildmesh, void* data) { EAXJMP(0x5C9730); }
-WRAPPER RpMeshHeader* _rpTriListMeshGenerate(RpBuildMesh* buildMesh, void* data) { EAXJMP(0x5CAE10); }
-WRAPPER RpMeshHeader* _rpMeshOptimise(RpBuildMesh* buildmesh, RwUInt32 flags) { EAXJMP(0x5CB230); }
-WRAPPER RwInt32 RpWorldSectorRegisterPlugin(RwInt32 size, RwUInt32 pluginID, RwPluginObjectConstructor ructCB, RwPluginObjectDestructor destructCB, RwPluginObjectCopy copyCB) { EAXJMP(0x5CB2B0); }
-WRAPPER RwInt32 RpWorldSectorRegisterPluginStream(RwUInt32 pluginID, RwPluginDataChunkReadCallBack readCB, RwPluginDataChunkWriteCallBack writeCB, RwPluginDataChunkGetSizeCallBack getSizeCB) { EAXJMP(0x5CB2E0); }
-WRAPPER RxPipeline* RpWorldSetDefaultSectorPipeline(RxPipeline* pipeline) { EAXJMP(0x5CB630); }
-WRAPPER RxPipeline* RpAtomicSetDefaultPipeline(RxPipeline* pipeline) { EAXJMP(0x5CB670); }
-WRAPPER void RpHAnimStdKeyFrameToMatrix(RwMatrix* matrix, void* voidIFrame) { EAXJMP(0x5CDEE0); }
-WRAPPER void RpHAnimStdKeyFrameInterpolate(void* voidOut, void* voidIn1, void* voidIn2, RwReal time) { EAXJMP(0x5CE000); }
-WRAPPER void RpHAnimStdKeyFrameBlend(void* voidOut, void* voidIn1, void* voidIn2, RwReal alpha) { EAXJMP(0x5CE420); }
-WRAPPER RpHAnimAnimation* RpHAnimStdKeyFrameStreamRead(RwStream* stream, RpHAnimAnimation* animation) { EAXJMP(0x5CE820); }
-WRAPPER RwBool RpHAnimStdKeyFrameStreamWrite(RpHAnimAnimation* animation, RwStream* stream) { EAXJMP(0x5CE8C0); }
-WRAPPER RwInt32 RpHAnimStdKeyFrameStreamGetSize(RpHAnimAnimation* animation) { EAXJMP(0x5CE930); }
-WRAPPER void RpHAnimStdKeyFrameMulRecip(void* voidFrame, void* voidStart) { EAXJMP(0x5CE950); }
-WRAPPER void RpHAnimStdKeyFrameAdd(void* voidOut, void* voidIn1, void* voidIn2) { EAXJMP(0x5CEAB0); }
-WRAPPER void RxHeapFree(RxHeap* heap, void* block) { EAXJMP(0x5D1070); }
-WRAPPER void* RxHeapAlloc(RxHeap* heap, RwUInt32 size) { EAXJMP(0x5D1260); }
-WRAPPER void* RxHeapRealloc(RxHeap* heap, void* block, RwUInt32 newSize, RwBool allowCopy) { EAXJMP(0x5D14D0); }
-WRAPPER RwBool _rxHeapReset(RxHeap* heap) { EAXJMP(0x5D1680); }
-WRAPPER void RxHeapDestroy(RxHeap* heap) { EAXJMP(0x5D16F0); }
-WRAPPER RxHeap* RxHeapCreate(RwUInt32 size) { EAXJMP(0x5D1750); }
-WRAPPER RxNodeOutput RxPipelineNodeFindOutputByName(RxPipelineNode* node, RwChar const* outputname) { EAXJMP(0x5D1EC0); }
-WRAPPER RxNodeInput RxPipelineNodeFindInput(RxPipelineNode* node) { EAXJMP(0x5D1F20); }
-WRAPPER RxPipeline* RxPipelineNodeRequestCluster(RxPipeline* pipeline, RxPipelineNode* node, RxClusterDefinition* clusterDef) { EAXJMP(0x5D1F30); }
-WRAPPER RxPipeline* RxLockedPipeUnlock(RxLockedPipe* pipeline) { EAXJMP(0x5D1FA0); }
-WRAPPER RxLockedPipe* RxPipelineLock(RxPipeline* pipeline) { EAXJMP(0x5D29F0); }
-WRAPPER RxPipelineNode* RxPipelineFindNodeByName(RxPipeline* pipeline, RwChar const* name, RxPipelineNode* start, RwInt32* nodeIndex) { EAXJMP(0x5D2B10); }
-WRAPPER RxLockedPipe* RxLockedPipeAddFragment(RxLockedPipe *pipeline, RwUInt32 *firstIndex, RxNodeDefinition *nodeDef0, ...) { EAXJMP(0x5D2BA0); }
-WRAPPER RxPipeline* RxLockedPipeAddPath(RxLockedPipe* pipeline, RxNodeOutput out, RxNodeInput in) { EAXJMP(0x5D2EE0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmRenderSetup() { EAXJMP(0x5D31C0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmMangleTriangleIndices() { EAXJMP(0x5D35C0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetCullTriangle() { EAXJMP(0x5D3C60); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetClipTriangle() { EAXJMP(0x5D4F80); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetSubmitTriangle() { EAXJMP(0x5D51C0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmInstance() { EAXJMP(0x5D5400); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetTransform() { EAXJMP(0x5D6000); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmStash() { EAXJMP(0x5D61C0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetImmMangleLineIndices() { EAXJMP(0x5D6470); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetClipLine() { EAXJMP(0x5D7230); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetSubmitLine() { EAXJMP(0x5D74C0); }
-WRAPPER RwBool _rwD3D8LightsOpen() { EAXJMP(0x5D9C90); }
-WRAPPER void _rwD3D8LightsClose() { EAXJMP(0x5D9EF0); }
-WRAPPER RwBool _rwD3D8LightsGlobalEnable(RpLightFlag flags) { EAXJMP(0x5D9F80); }
-WRAPPER RwBool _rwD3D8LightLocalEnable(RpLight* light) { EAXJMP(0x5DA210); }
-WRAPPER void _rwD3D8LightsEnable(RwBool enable, RwUInt32 type) { EAXJMP(0x5DA450); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetD3D8WorldSectorAllInOne() { EAXJMP(0x5DAAC0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetD3D8AtomicAllInOne() { EAXJMP(0x5DC500); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetWorldSectorInstance() { EAXJMP(0x5DCC50); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetWorldSectorEnumerateLights() { EAXJMP(0x5DCD80); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetAtomicInstance() { EAXJMP(0x5DD800); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetAtomicEnumerateLights() { EAXJMP(0x5DD9B0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetMaterialScatter() { EAXJMP(0x5DDAA0); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetLight() { EAXJMP(0x5DF040); }
-WRAPPER RxNodeDefinition* RxNodeDefinitionGetPostLight() { EAXJMP(0x5DF560); }
-WRAPPER void RxD3D8AllInOneSetRenderCallBack(RxPipelineNode* node, RxD3D8AllInOneRenderCallBack callback) { EAXJMP(0x5DFC60); }
-#else
-
-extern "C"
-{
- void* _rwFrameOpen(void* instance, RwInt32 offset, RwInt32 size);
- void* _rwFrameClose(void* instance, RwInt32 offset, RwInt32 size);
- RwFrame* _rwFrameCloneAndLinkClones(RwFrame* root);
- RwFrame* _rwFramePurgeClone(RwFrame* root);
- RwBool RwFrameDirty(RwFrame const* frame);
- void _rwFrameInit(RwFrame* frame);
- RwBool _rwMatrixSetMultFn(rwMatrixMultFn multMat);
- void* _rwMatrixClose(void* instance, RwInt32 offset, RwInt32 size);
- void* _rwMatrixOpen(void* instance, RwInt32 offset, RwInt32 size);
- RwBool _rwVectorSetMultFn(rwVectorMultFn multPoint, rwVectorsMultFn multPoints, rwVectorMultFn multVector, rwVectorsMultFn multVectors);
- void* _rwVectorClose(void* instance, RwInt32 offset, RwInt32 size);
- void* _rwVectorOpen(void* instance, RwInt32 offset, RwInt32 size);
- RwBool _rwPluginRegistryOpen();
- RwBool _rwPluginRegistryClose();
-}
-
-STARTPATCHES
-InjectHook(0x5BC950, &_rwObjectHasFrameSetFrame, PATCH_JUMP);
-InjectHook(0x59E690, &AtomicDefaultRenderCallBack, PATCH_JUMP);
-InjectHook(0x59E6C0, &_rpAtomicResyncInterpolatedSphere, PATCH_JUMP);
-InjectHook(0x59E800, &RpAtomicGetWorldBoundingSphere, PATCH_JUMP);
-InjectHook(0x59ED50, &RpClumpGetNumAtomics, PATCH_JUMP);
-InjectHook(0x59ED80, &RpClumpRender, PATCH_JUMP);
-InjectHook(0x59EDD0, &RpClumpForAllAtomics, PATCH_JUMP);
-InjectHook(0x59EE10, &RpClumpForAllCameras, PATCH_JUMP);
-InjectHook(0x59EE60, &RpClumpForAllLights, PATCH_JUMP);
-InjectHook(0x59EEB0, &RpAtomicCreate, PATCH_JUMP);
-InjectHook(0x59EFA0, &RpAtomicSetGeometry, PATCH_JUMP);
-InjectHook(0x59F020, &RpAtomicDestroy, PATCH_JUMP);
-InjectHook(0x59F0A0, &RpAtomicClone, PATCH_JUMP);
-InjectHook(0x59F1B0, &RpClumpClone, PATCH_JUMP);
-InjectHook(0x59F490, &RpClumpCreate, PATCH_JUMP);
-InjectHook(0x59F500, &RpClumpDestroy, PATCH_JUMP);
-InjectHook(0x59F680, &RpClumpAddAtomic, PATCH_JUMP);
-InjectHook(0x59F6B0, &RpClumpRemoveAtomic, PATCH_JUMP);
-InjectHook(0x59F6E0, &RpClumpRemoveLight, PATCH_JUMP);
-InjectHook(0x59FC50, &RpClumpStreamRead, PATCH_JUMP);
-InjectHook(0x5A0510, &RpAtomicRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5A0540, &RpClumpRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5A0570, &RpAtomicRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5A05A0, &RpAtomicSetStreamAlwaysCallBack, PATCH_JUMP);
-InjectHook(0x5A05C0, &RpAtomicSetStreamRightsCallBack, PATCH_JUMP);
-InjectHook(0x5A05E0, &RpAtomicGetPluginOffset, PATCH_JUMP);
-InjectHook(0x5A0600, &RpAtomicSetFrame, PATCH_JUMP);
-InjectHook(0x5A0DC0, &RwEngineRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5A0DF0, &RwEngineGetPluginOffset, PATCH_JUMP);
-InjectHook(0x5A0E10, &RwEngineGetNumSubSystems, PATCH_JUMP);
-InjectHook(0x5A0E40, &RwEngineGetSubSystemInfo, PATCH_JUMP);
-InjectHook(0x5A0E70, &RwEngineGetCurrentSubSystem, PATCH_JUMP);
-InjectHook(0x5A0EA0, &RwEngineSetSubSystem, PATCH_JUMP);
-InjectHook(0x5A0ED0, &RwEngineGetNumVideoModes, PATCH_JUMP);
-InjectHook(0x5A0F00, &RwEngineGetVideoModeInfo, PATCH_JUMP);
-InjectHook(0x5A0F30, &RwEngineGetCurrentVideoMode, PATCH_JUMP);
-InjectHook(0x5A0F60, &RwEngineSetVideoMode, PATCH_JUMP);
-InjectHook(0x5A0F90, &RwEngineStop, PATCH_JUMP);
-InjectHook(0x5A0FE0, &RwEngineStart, PATCH_JUMP);
-InjectHook(0x5A1070, &RwEngineClose, PATCH_JUMP);
-InjectHook(0x5A10E0, &RwEngineOpen, PATCH_JUMP);
-InjectHook(0x5A1290, &RwEngineTerm, PATCH_JUMP);
-InjectHook(0x5A12D0, &RwEngineInit, PATCH_JUMP);
-InjectHook(0x5A15E0, &_rwFrameOpen, PATCH_JUMP);
-InjectHook(0x5A1650, &_rwFrameClose, PATCH_JUMP);
-InjectHook(0x5A1690, &_rwFrameCloneAndLinkClones, PATCH_JUMP);
-InjectHook(0x5A1880, &_rwFramePurgeClone, PATCH_JUMP);
-InjectHook(0x5A1930, &RwFrameDirty, PATCH_JUMP);
-InjectHook(0x5A1950, &_rwFrameInit, PATCH_JUMP);
-InjectHook(0x5A1A00, &RwFrameCreate, PATCH_JUMP);
-InjectHook(0x5A1A30, &RwFrameDestroy, PATCH_JUMP);
-InjectHook(0x5A1BF0, &RwFrameDestroyHierarchy, PATCH_JUMP);
-InjectHook(0x5A1C60, &RwFrameUpdateObjects, PATCH_JUMP);
-InjectHook(0x5A1CE0, &RwFrameGetLTM, PATCH_JUMP);
-InjectHook(0x5A1D00, &RwFrameAddChild, PATCH_JUMP);
-InjectHook(0x5A1ED0, &RwFrameRemoveChild, PATCH_JUMP);
-InjectHook(0x5A1FC0, &RwFrameForAllChildren, PATCH_JUMP);
-InjectHook(0x5A2000, &RwFrameTranslate, PATCH_JUMP);
-InjectHook(0x5A20A0, &RwFrameScale, PATCH_JUMP);
-InjectHook(0x5A2140, &RwFrameTransform, PATCH_JUMP);
-InjectHook(0x5A21E0, &RwFrameRotate, PATCH_JUMP);
-InjectHook(0x5A2280, &RwFrameSetIdentity, PATCH_JUMP);
-InjectHook(0x5A2340, &RwFrameForAllObjects, PATCH_JUMP);
-InjectHook(0x5A2380, &RwFrameRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5A23B0, &_rwMatrixSetMultFn, PATCH_JUMP);
-InjectHook(0x5A2520, &_rwMatrixDeterminant, PATCH_JUMP);
-InjectHook(0x5A2570, &_rwMatrixOrthogonalError, PATCH_JUMP);
-InjectHook(0x5A25D0, &_rwMatrixNormalError, PATCH_JUMP);
-InjectHook(0x5A2660, &_rwMatrixIdentityError, PATCH_JUMP);
-InjectHook(0x5A2730, &_rwMatrixClose, PATCH_JUMP);
-InjectHook(0x5A2770, &_rwMatrixOpen, PATCH_JUMP);
-InjectHook(0x5A2820, &RwMatrixOptimize, PATCH_JUMP);
-InjectHook(0x5A28E0, &RwMatrixUpdate, PATCH_JUMP);
-InjectHook(0x5A28F0, &RwMatrixMultiply, PATCH_JUMP);
-InjectHook(0x5A2960, &RwMatrixRotateOneMinusCosineSine, PATCH_JUMP);
-InjectHook(0x5A2BF0, &RwMatrixRotate, PATCH_JUMP);
-InjectHook(0x5A2C90, &RwMatrixInvert, PATCH_JUMP);
-InjectHook(0x5A2EE0, &RwMatrixScale, PATCH_JUMP);
-InjectHook(0x5A3070, &RwMatrixTranslate, PATCH_JUMP);
-InjectHook(0x5A31C0, &RwMatrixTransform, PATCH_JUMP);
-InjectHook(0x5A3300, &RwMatrixDestroy, PATCH_JUMP);
-InjectHook(0x5A3330, &RwMatrixCreate, PATCH_JUMP);
-InjectHook(0x5A3450, &_rwVectorSetMultFn, PATCH_JUMP);
-InjectHook(0x5A3600, &_rwV3dNormalize, PATCH_JUMP);
-InjectHook(0x5A36A0, &RwV3dLength, PATCH_JUMP);
-InjectHook(0x5A3710, &_rwSqrt, PATCH_JUMP);
-InjectHook(0x5A3770, &_rwInvSqrt, PATCH_JUMP);
-InjectHook(0x5A37D0, &RwV3dTransformPoints, PATCH_JUMP);
-InjectHook(0x5A37E0, &RwV3dTransformVectors, PATCH_JUMP);
-InjectHook(0x5A37F0, &_rwVectorClose, PATCH_JUMP);
-InjectHook(0x5A3860, &_rwVectorOpen, PATCH_JUMP);
-InjectHook(0x5A3AD0, &RwStreamRead, PATCH_JUMP);
-InjectHook(0x5A3C30, &RwStreamWrite, PATCH_JUMP);
-InjectHook(0x5A3DF0, &RwStreamSkip, PATCH_JUMP);
-InjectHook(0x5A3F10, &RwStreamClose, PATCH_JUMP);
-InjectHook(0x5A3FE0, &RwStreamOpen, PATCH_JUMP);
-InjectHook(0x5A43A0, &RwIm2DGetNearScreenZ, PATCH_JUMP);
-InjectHook(0x5A43B0, &RwIm2DGetFarScreenZ, PATCH_JUMP);
-InjectHook(0x5A43C0, &RwRenderStateSet, PATCH_JUMP);
-InjectHook(0x5A4410, &RwRenderStateGet, PATCH_JUMP);
-InjectHook(0x5A4420, &RwIm2DRenderLine, PATCH_JUMP);
-InjectHook(0x5A4430, &RwIm2DRenderPrimitive, PATCH_JUMP);
-InjectHook(0x5A4440, &RwIm2DRenderIndexedPrimitive, PATCH_JUMP);
-InjectHook(0x5A5020, &RwCameraEndUpdate, PATCH_JUMP);
-InjectHook(0x5A5030, &RwCameraBeginUpdate, PATCH_JUMP);
-InjectHook(0x5A5040, &RwCameraSetViewOffset, PATCH_JUMP);
-InjectHook(0x5A5070, &RwCameraSetNearClipPlane, PATCH_JUMP);
-InjectHook(0x5A5140, &RwCameraSetFarClipPlane, PATCH_JUMP);
-InjectHook(0x5A5170, &RwCameraFrustumTestSphere, PATCH_JUMP);
-InjectHook(0x5A51E0, &RwCameraClear, PATCH_JUMP);
-InjectHook(0x5A5210, &RwCameraShowRaster, PATCH_JUMP);
-InjectHook(0x5A5240, &RwCameraSetProjection, PATCH_JUMP);
-InjectHook(0x5A52B0, &RwCameraSetViewWindow, PATCH_JUMP);
-InjectHook(0x5A52F0, &RwCameraRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5A5320, &RwCameraDestroy, PATCH_JUMP);
-InjectHook(0x5A5360, &RwCameraCreate, PATCH_JUMP);
-InjectHook(0x5A7100, &RwTextureSetMipmapping, PATCH_JUMP);
-InjectHook(0x5A7120, &RwTextureGetMipmapping, PATCH_JUMP);
-InjectHook(0x5A7130, &RwTextureSetAutoMipmapping, PATCH_JUMP);
-InjectHook(0x5A7150, &RwTextureGetAutoMipmapping, PATCH_JUMP);
-InjectHook(0x5A7160, &RwTexDictionaryCreate, PATCH_JUMP);
-InjectHook(0x5A7200, &RwTexDictionaryDestroy, PATCH_JUMP);
-InjectHook(0x5A7290, &RwTexDictionaryForAllTextures, PATCH_JUMP);
-InjectHook(0x5A72D0, &RwTextureCreate, PATCH_JUMP);
-InjectHook(0x5A7330, &RwTextureDestroy, PATCH_JUMP);
-InjectHook(0x5A73B0, &RwTextureSetName, PATCH_JUMP);
-InjectHook(0x5A7420, &RwTextureSetMaskName, PATCH_JUMP);
-InjectHook(0x5A7490, &RwTexDictionaryAddTexture, PATCH_JUMP);
-InjectHook(0x5A74D0, &RwTexDictionaryFindNamedTexture, PATCH_JUMP);
-InjectHook(0x5A7550, &RwTexDictionarySetCurrent, PATCH_JUMP);
-InjectHook(0x5A7570, &RwTexDictionaryGetCurrent, PATCH_JUMP);
-InjectHook(0x5A7580, &RwTextureRead, PATCH_JUMP);
-InjectHook(0x5A7780, &RwTextureRasterGenerateMipmaps, PATCH_JUMP);
-InjectHook(0x5A9120, &RwImageCreate, PATCH_JUMP);
-InjectHook(0x5A9180, &RwImageDestroy, PATCH_JUMP);
-InjectHook(0x5A91E0, &RwImageAllocatePixels, PATCH_JUMP);
-InjectHook(0x5A92A0, &RwImageFreePixels, PATCH_JUMP);
-InjectHook(0x5A92D0, &RwImageMakeMask, PATCH_JUMP);
-InjectHook(0x5A93A0, &RwImageApplyMask, PATCH_JUMP);
-InjectHook(0x5A9750, &RwImageSetPath, PATCH_JUMP);
-InjectHook(0x5A9810, &RwImageRead, PATCH_JUMP);
-InjectHook(0x5A9B40, &RwImageFindFileType, PATCH_JUMP);
-InjectHook(0x5A9C10, &RwImageReadMaskedImage, PATCH_JUMP);
-InjectHook(0x5A9F50, &RwImageCopy, PATCH_JUMP);
-InjectHook(0x5AA130, &RwImageGammaCorrect, PATCH_JUMP);
-InjectHook(0x5AA2C0, &RwImageSetGamma, PATCH_JUMP);
-InjectHook(0x5AA4E0, &_rwStreamWriteVersionedChunkHeader, PATCH_JUMP);
-InjectHook(0x5AA540, &RwStreamFindChunk, PATCH_JUMP);
-InjectHook(0x5AA640, &RwMemLittleEndian32, PATCH_JUMP);
-InjectHook(0x5AA650, &RwMemNative32, PATCH_JUMP);
-InjectHook(0x5AA660, &RwMemFloat32ToReal, PATCH_JUMP);
-InjectHook(0x5AA680, &RwStreamWriteReal, PATCH_JUMP);
-InjectHook(0x5AA720, &RwStreamWriteInt32, PATCH_JUMP);
-InjectHook(0x5AA740, &RwStreamReadReal, PATCH_JUMP);
-InjectHook(0x5AA7B0, &RwStreamReadInt32, PATCH_JUMP);
-InjectHook(0x5AA800, &RwTextureStreamGetSize, PATCH_JUMP);
-InjectHook(0x5AA870, &RwTextureStreamWrite, PATCH_JUMP);
-InjectHook(0x5AAA40, &RwTextureStreamRead, PATCH_JUMP);
-InjectHook(0x5AB020, &RwTexDictionaryStreamWrite, PATCH_JUMP);
-InjectHook(0x5AC890, &RpMorphTargetCalcBoundingSphere, PATCH_JUMP);
-InjectHook(0x5AC9A0, &RpGeometryAddMorphTargets, PATCH_JUMP);
-InjectHook(0x5ACB60, &RpGeometryTriangleSetVertexIndices, PATCH_JUMP);
-InjectHook(0x5ACB90, &RpGeometryTriangleSetMaterial, PATCH_JUMP);
-InjectHook(0x5ACBF0, &RpGeometryForAllMaterials, PATCH_JUMP);
-InjectHook(0x5ACC30, &RpGeometryLock, PATCH_JUMP);
-InjectHook(0x5ACC60, &RpGeometryUnlock, PATCH_JUMP);
-InjectHook(0x5ACD10, &RpGeometryCreate, PATCH_JUMP);
-InjectHook(0x5ACF40, &_rpGeometryAddRef, PATCH_JUMP);
-InjectHook(0x5ACF50, &RpGeometryDestroy, PATCH_JUMP);
-InjectHook(0x5ACFF0, &RpGeometryRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5AD020, &RpGeometryRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5AD050, &RpGeometryStreamRead, PATCH_JUMP);
-InjectHook(0x5AD6D0, &RwRasterGetCurrentContext, PATCH_JUMP);
-InjectHook(0x5AD6F0, &RwRasterUnlock, PATCH_JUMP);
-InjectHook(0x5AD710, &RwRasterRenderFast, PATCH_JUMP);
-InjectHook(0x5AD750, &RwRasterUnlockPalette, PATCH_JUMP);
-InjectHook(0x5AD780, &RwRasterDestroy, PATCH_JUMP);
-InjectHook(0x5AD7C0, &RwRasterPushContext, PATCH_JUMP);
-InjectHook(0x5AD810, &RwRasterRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5AD840, &RwRasterLockPalette, PATCH_JUMP);
-InjectHook(0x5AD870, &RwRasterPopContext, PATCH_JUMP);
-InjectHook(0x5AD8C0, &RwRasterGetNumLevels, PATCH_JUMP);
-InjectHook(0x5AD900, &RwRasterShowRaster, PATCH_JUMP);
-InjectHook(0x5AD930, &RwRasterCreate, PATCH_JUMP);
-InjectHook(0x5AD9D0, &RwRasterLock, PATCH_JUMP);
-InjectHook(0x5ADC30, &RpMaterialCreate, PATCH_JUMP);
-InjectHook(0x5ADCB0, &RpMaterialDestroy, PATCH_JUMP);
-InjectHook(0x5ADD10, &RpMaterialSetTexture, PATCH_JUMP);
-InjectHook(0x5ADD40, &RpMaterialRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5ADD70, &RpMaterialRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5ADDA0, &RpMaterialStreamRead, PATCH_JUMP);
-InjectHook(0x5AE0B0, &_rpSectorDefaultRenderCallBack, PATCH_JUMP);
-InjectHook(0x5AE100, &_rpWorldForAllGlobalLights, PATCH_JUMP);
-InjectHook(0x5AE150, &_rpWorldSectorForAllLocalLights, PATCH_JUMP);
-InjectHook(0x5AE190, &RpWorldUnlock, PATCH_JUMP);
-InjectHook(0x5AE2B0, &RpWorldSectorGetWorld, PATCH_JUMP);
-InjectHook(0x5AE340, &RpWorldDestroy, PATCH_JUMP);
-InjectHook(0x5AE6A0, &RpWorldCreate, PATCH_JUMP);
-InjectHook(0x5AEA40, &RpWorldRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5AEA70, &RpWorldRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5AEAA0, &RpWorldPluginAttach, PATCH_JUMP);
-InjectHook(0x5AFB80, &RpWorldAddCamera, PATCH_JUMP);
-InjectHook(0x5AFBB0, &RpWorldRemoveCamera, PATCH_JUMP);
-InjectHook(0x5AFC10, &RpAtomicGetWorld, PATCH_JUMP);
-InjectHook(0x5AFC20, &RpWorldAddClump, PATCH_JUMP);
-InjectHook(0x5AFDA0, &RpWorldAddLight, PATCH_JUMP);
-InjectHook(0x5AFDF0, &RpWorldRemoveLight, PATCH_JUMP);
-InjectHook(0x5AFE70, &RtBMPImageRead, PATCH_JUMP);
-InjectHook(0x5B07D0, &RpSkinPluginAttach, PATCH_JUMP);
-InjectHook(0x5B1050, &RpSkinAtomicSetHAnimHierarchy, PATCH_JUMP);
-InjectHook(0x5B1070, &RpSkinAtomicGetHAnimHierarchy, PATCH_JUMP);
-InjectHook(0x5B1080, &RpSkinGeometryGetSkin, PATCH_JUMP);
-InjectHook(0x5B1090, &RpSkinGeometrySetSkin, PATCH_JUMP);
-InjectHook(0x5B10D0, &RpSkinGetSkinToBoneMatrices, PATCH_JUMP);
-InjectHook(0x5B10E0, &RpHAnimHierarchyCreate, PATCH_JUMP);
-InjectHook(0x5B11F0, &RpHAnimFrameGetHierarchy, PATCH_JUMP);
-InjectHook(0x5B1200, &RpHAnimHierarchySetCurrentAnim, PATCH_JUMP);
-InjectHook(0x5B12B0, &RpHAnimHierarchySubAnimTime, PATCH_JUMP);
-InjectHook(0x5B1480, &RpHAnimHierarchyAddAnimTime, PATCH_JUMP);
-InjectHook(0x5B1780, &RpHAnimHierarchyUpdateMatrices, PATCH_JUMP);
-InjectHook(0x5B1C10, &RpHAnimAnimationStreamRead, PATCH_JUMP);
-InjectHook(0x5B1D50, &RpHAnimPluginAttach, PATCH_JUMP);
-InjectHook(0x5B2640, &RpMatFXPluginAttach, PATCH_JUMP);
-InjectHook(0x5B3750, &RpMatFXAtomicEnableEffects, PATCH_JUMP);
-InjectHook(0x5B3780, &RpMatFXMaterialSetEffects, PATCH_JUMP);
-InjectHook(0x5B38D0, &RpMatFXMaterialSetupEnvMap, PATCH_JUMP);
-InjectHook(0x5B3A40, &RpMatFXMaterialSetBumpMapTexture, PATCH_JUMP);
-InjectHook(0x5B3CF0, &RwD3D8SetRenderState, PATCH_JUMP);
-InjectHook(0x5B3D40, &RwD3D8GetRenderState, PATCH_JUMP);
-InjectHook(0x5B3D60, &RwD3D8SetTextureStageState, PATCH_JUMP);
-InjectHook(0x5B53A0, &RwD3D8SetTexture, PATCH_JUMP);
-InjectHook(0x5B6720, &RwIm3DTransform, PATCH_JUMP);
-InjectHook(0x5B67F0, &RwIm3DEnd, PATCH_JUMP);
-InjectHook(0x5B6820, &RwIm3DRenderIndexedPrimitive, PATCH_JUMP);
-InjectHook(0x5B6980, &RwIm3DRenderLine, PATCH_JUMP);
-InjectHook(0x5B6A50, &RwIm3DSetTransformPipeline, PATCH_JUMP);
-InjectHook(0x5B6AC0, &RwIm3DSetRenderPipeline, PATCH_JUMP);
-InjectHook(0x5B95D0, &RwD3D8EngineSetRefreshRate, PATCH_JUMP);
-InjectHook(0x5B9640, &RwD3D8CameraAttachWindow, PATCH_JUMP);
-InjectHook(0x5BAEB0, &RwD3D8DeviceSupportsDXTTexture, PATCH_JUMP);
-InjectHook(0x5BAF90, &RwD3D8SetVertexShader, PATCH_JUMP);
-InjectHook(0x5BAFD0, &RwD3D8SetPixelShader, PATCH_JUMP);
-InjectHook(0x5BB010, &RwD3D8SetStreamSource, PATCH_JUMP);
-InjectHook(0x5BB060, &RwD3D8SetIndices, PATCH_JUMP);
-InjectHook(0x5BB0B0, &RwD3D8DrawIndexedPrimitive, PATCH_JUMP);
-InjectHook(0x5BB140, &RwD3D8DrawPrimitive, PATCH_JUMP);
-InjectHook(0x5BB1D0, &RwD3D8SetTransform, PATCH_JUMP);
-InjectHook(0x5BB310, &RwD3D8GetTransform, PATCH_JUMP);
-InjectHook(0x5BB340, &RwD3D8SetTransformWorld, PATCH_JUMP);
-InjectHook(0x5BB490, &RwD3D8SetSurfaceProperties, PATCH_JUMP);
-InjectHook(0x5BB7A0, &RwD3D8SetLight, PATCH_JUMP);
-InjectHook(0x5BB890, &RwD3D8EnableLight, PATCH_JUMP);
-InjectHook(0x5BB9F0, &RwD3D8DynamicVertexBufferCreate, PATCH_JUMP);
-InjectHook(0x5BBAE0, &RwD3D8DynamicVertexBufferDestroy, PATCH_JUMP);
-InjectHook(0x5BBB10, &RwD3D8IndexBufferCreate, PATCH_JUMP);
-InjectHook(0x5BBB40, &RwD3D8CreatePixelShader, PATCH_JUMP);
-InjectHook(0x5BBB90, &RwD3D8DeletePixelShader, PATCH_JUMP);
-InjectHook(0x5BBC00, &RwD3D8SetPixelShaderConstant, PATCH_JUMP);
-InjectHook(0x5BBC30, &RwD3D8GetCaps, PATCH_JUMP);
-InjectHook(0x5BBC40, &RwD3D8CameraIsSphereFullyInsideFrustum, PATCH_JUMP);
-InjectHook(0x5BBCA0, &RwD3D8CameraIsBBoxFullyInsideFrustum, PATCH_JUMP);
-InjectHook(0x5BBD30, &RwD3D8DynamicVertexBufferLock, PATCH_JUMP);
-InjectHook(0x5BBEB0, &RwD3D8DynamicVertexBufferUnlock, PATCH_JUMP);
-InjectHook(0x5BBED0, &_rwIntelSSEsupported, PATCH_JUMP);
-InjectHook(0x5BBF10, &RwImageSetFromRaster, PATCH_JUMP);
-InjectHook(0x5BBF50, &RwRasterSetFromImage, PATCH_JUMP);
-InjectHook(0x5BBF80, &RwImageFindRasterFormat, PATCH_JUMP);
-InjectHook(0x5BBFF0, &RwFrameRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5BC020, &_rwFrameListDeinitialize, PATCH_JUMP);
-InjectHook(0x5BC050, &_rwFrameListStreamRead, PATCH_JUMP);
-InjectHook(0x5BC300, &RpLightSetRadius, PATCH_JUMP);
-InjectHook(0x5BC320, &RpLightSetColor, PATCH_JUMP);
-InjectHook(0x5BC370, &RpLightGetConeAngle, PATCH_JUMP);
-InjectHook(0x5BC5B0, &RpLightRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5BC5E0, &RpLightStreamRead, PATCH_JUMP);
-InjectHook(0x5BC780, &RpLightDestroy, PATCH_JUMP);
-InjectHook(0x5BC7C0, &RpLightCreate, PATCH_JUMP);
-InjectHook(0x5BE280, &_rwD3D8TexDictionaryEnableRasterFormatConversion, PATCH_JUMP);
-InjectHook(0x5BF110, &RwOsGetFileInterface, PATCH_JUMP);
-InjectHook(0x5C1720, &RwFreeListDestroy, PATCH_JUMP);
-InjectHook(0x5C1790, &RwFreeListCreate, PATCH_JUMP);
-InjectHook(0x5C19F0, &RwFreeListPurge, PATCH_JUMP);
-InjectHook(0x5C1B90, &RwFreeListPurgeAllFreeLists, PATCH_JUMP);
-InjectHook(0x5C1D40, &RwFreeListForAllUsed, PATCH_JUMP);
-InjectHook(0x5C2780, &_rxPipelineClose, PATCH_JUMP);
-InjectHook(0x5C27E0, &_rxPipelineOpen, PATCH_JUMP);
-InjectHook(0x5C2AD0, &RxHeapGetGlobalHeap, PATCH_JUMP);
-InjectHook(0x5C2AE0, &RxPacketCreate, PATCH_JUMP);
-InjectHook(0x5C2B10, &RxClusterSetExternalData, PATCH_JUMP);
-InjectHook(0x5C2B70, &RxClusterSetData, PATCH_JUMP);
-InjectHook(0x5C2BD0, &RxClusterInitializeData, PATCH_JUMP);
-InjectHook(0x5C2C40, &RxClusterResizeData, PATCH_JUMP);
-InjectHook(0x5C2C90, &RxClusterLockWrite, PATCH_JUMP);
-InjectHook(0x5C2D60, &RxPipelineExecute, PATCH_JUMP);
-InjectHook(0x5C2E00, &RxPipelineCreate, PATCH_JUMP);
-InjectHook(0x5C2E70, &_rxPipelineDestroy, PATCH_JUMP);
-InjectHook(0x5C3080, &RwResourcesFreeResEntry, PATCH_JUMP);
-InjectHook(0x5C30F0, &_rwResourcesPurge, PATCH_JUMP);
-InjectHook(0x5C3170, &RwResourcesAllocateResEntry, PATCH_JUMP);
-InjectHook(0x5C3360, &RwResourcesEmptyArena, PATCH_JUMP);
-InjectHook(0x5C3450, &_rwPluginRegistryOpen, PATCH_JUMP);
-InjectHook(0x5C3480, &_rwPluginRegistryClose, PATCH_JUMP);
-InjectHook(0x5C3590, &_rwPluginRegistryGetPluginOffset, PATCH_JUMP);
-InjectHook(0x5C35C0, &_rwPluginRegistryAddPlugin, PATCH_JUMP);
-InjectHook(0x5C37F0, &_rwPluginRegistryInitObject, PATCH_JUMP);
-InjectHook(0x5C3850, &_rwPluginRegistryDeInitObject, PATCH_JUMP);
-InjectHook(0x5C3880, &_rwPluginRegistryCopyObject, PATCH_JUMP);
-InjectHook(0x5C3910, &RwErrorSet, PATCH_JUMP);
-InjectHook(0x5C3970, &_rwerror, PATCH_JUMP);
-InjectHook(0x5C3980, &_rwPluginRegistryAddPluginStream, PATCH_JUMP);
-InjectHook(0x5C39C0, &_rwPluginRegistryAddPlgnStrmlwysCB, PATCH_JUMP);
-InjectHook(0x5C39F0, &_rwPluginRegistryAddPlgnStrmRightsCB, PATCH_JUMP);
-InjectHook(0x5C3A20, & _rwPluginRegistryReadDataChunks, PATCH_JUMP);
-InjectHook(0x5C3B50, & _rwPluginRegistryInvokeRights, PATCH_JUMP);
-InjectHook(0x5C3BA0, &_rwPluginRegistryGetSize, PATCH_JUMP);
-InjectHook(0x5C3BE0, &_rwPluginRegistryWriteDataChunks, PATCH_JUMP);
-InjectHook(0x5C3CB0, &_rwPluginRegistrySkipDataChunks, PATCH_JUMP);
-InjectHook(0x5C3D30, &RwCameraStreamRead, PATCH_JUMP);
-InjectHook(0x5C5570, &RwBBoxCalculate, PATCH_JUMP);
-InjectHook(0x5C72B0, &RwImageResample, PATCH_JUMP);
-InjectHook(0x5C7B30, &RwImageCreateResample, PATCH_JUMP);
-InjectHook(0x5D9240, &RxRenderStateVectorSetDefaultRenderStateVector, PATCH_JUMP);
-InjectHook(0x5D9340, &RxRenderStateVectorCreate, PATCH_JUMP);
-InjectHook(0x5D9410, &RxRenderStateVectorDestroy, PATCH_JUMP);
-InjectHook(0x5D9460, &RxRenderStateVectorLoadDriverState, PATCH_JUMP);
-InjectHook(0x5D95D0, &_rxEmbeddedPacketBetweenPipelines, PATCH_JUMP);
-InjectHook(0x5D9740, &_rxEmbeddedPacketBetweenNodes, PATCH_JUMP);
-InjectHook(0x5D9810, &_rxPacketDestroy, PATCH_JUMP);
-InjectHook(0x5C8B10, &_rpMaterialListDeinitialize, PATCH_JUMP);
-InjectHook(0x5C8B70, &_rpMaterialListInitialize, PATCH_JUMP);
-InjectHook(0x5C8B80, &_rpMaterialListGetMaterial, PATCH_JUMP);
-InjectHook(0x5C8B90, &_rpMaterialListAppendMaterial, PATCH_JUMP);
-InjectHook(0x5C8C50, &_rpMaterialListFindMaterialIndex, PATCH_JUMP);
-InjectHook(0x5C8C80, &_rpMaterialListStreamRead, PATCH_JUMP);
-InjectHook(0x5C8FE0, &_rpMeshHeaderCreate, PATCH_JUMP);
-InjectHook(0x5C8FF0, &_rpMeshClose, PATCH_JUMP);
-InjectHook(0x5C9020, &_rpMeshOpen, PATCH_JUMP);
-InjectHook(0x5C9140, &_rpBuildMeshCreate, PATCH_JUMP);
-InjectHook(0x5C9220, &_rpBuildMeshDestroy, PATCH_JUMP);
-InjectHook(0x5C9260, &_rpMeshDestroy, PATCH_JUMP);
-InjectHook(0x5C92A0, &_rpBuildMeshAddTriangle, PATCH_JUMP);
-InjectHook(0x5C9380, &_rpMeshHeaderForAllMeshes, PATCH_JUMP);
-InjectHook(0x5C93C0, &_rpMeshWrite, PATCH_JUMP);
-InjectHook(0x5C9510, &_rpMeshRead, PATCH_JUMP);
-InjectHook(0x5C96E0, &_rpMeshSize, PATCH_JUMP);
-InjectHook(0x5C9730, &RpBuildMeshGenerateDefaultTriStrip, PATCH_JUMP);
-InjectHook(0x5CAE10, &_rpTriListMeshGenerate, PATCH_JUMP);
-InjectHook(0x5CB230, &_rpMeshOptimise, PATCH_JUMP);
-InjectHook(0x5CB2B0, &RpWorldSectorRegisterPlugin, PATCH_JUMP);
-InjectHook(0x5CB2E0, &RpWorldSectorRegisterPluginStream, PATCH_JUMP);
-InjectHook(0x5CB630, &RpWorldSetDefaultSectorPipeline, PATCH_JUMP);
-InjectHook(0x5CB670, &RpAtomicSetDefaultPipeline, PATCH_JUMP);
-InjectHook(0x5CDEE0, &RpHAnimStdKeyFrameToMatrix, PATCH_JUMP);
-InjectHook(0x5CE000, &RpHAnimStdKeyFrameInterpolate, PATCH_JUMP);
-InjectHook(0x5CE420, &RpHAnimStdKeyFrameBlend, PATCH_JUMP);
-InjectHook(0x5CE820, &RpHAnimStdKeyFrameStreamRead, PATCH_JUMP);
-InjectHook(0x5CE8C0, &RpHAnimStdKeyFrameStreamWrite, PATCH_JUMP);
-InjectHook(0x5CE930, &RpHAnimStdKeyFrameStreamGetSize, PATCH_JUMP);
-InjectHook(0x5CE950, &RpHAnimStdKeyFrameMulRecip, PATCH_JUMP);
-InjectHook(0x5CEAB0, &RpHAnimStdKeyFrameAdd, PATCH_JUMP);
-InjectHook(0x5D1070, &RxHeapFree, PATCH_JUMP);
-InjectHook(0x5D1260, &RxHeapAlloc, PATCH_JUMP);
-InjectHook(0x5D14D0, &RxHeapRealloc, PATCH_JUMP);
-InjectHook(0x5D1680, &_rxHeapReset, PATCH_JUMP);
-InjectHook(0x5D16F0, &RxHeapDestroy, PATCH_JUMP);
-InjectHook(0x5D1750, &RxHeapCreate, PATCH_JUMP);
-InjectHook(0x5D1EC0, &RxPipelineNodeFindOutputByName, PATCH_JUMP);
-InjectHook(0x5D1F20, &RxPipelineNodeFindInput, PATCH_JUMP);
-InjectHook(0x5D1F30, &RxPipelineNodeRequestCluster, PATCH_JUMP);
-InjectHook(0x5D1FA0, &RxLockedPipeUnlock, PATCH_JUMP);
-InjectHook(0x5D29F0, &RxPipelineLock, PATCH_JUMP);
-InjectHook(0x5D2B10, &RxPipelineFindNodeByName, PATCH_JUMP);
-InjectHook(0x5D2BA0, &RxLockedPipeAddFragment, PATCH_JUMP);
-InjectHook(0x5D2EE0, &RxLockedPipeAddPath, PATCH_JUMP);
-InjectHook(0x5D31C0, &RxNodeDefinitionGetImmRenderSetup, PATCH_JUMP);
-InjectHook(0x5D35C0, &RxNodeDefinitionGetImmMangleTriangleIndices, PATCH_JUMP);
-InjectHook(0x5D3C60, &RxNodeDefinitionGetCullTriangle, PATCH_JUMP);
-InjectHook(0x5D4F80, &RxNodeDefinitionGetClipTriangle, PATCH_JUMP);
-InjectHook(0x5D51C0, &RxNodeDefinitionGetSubmitTriangle, PATCH_JUMP);
-InjectHook(0x5D5400, &RxNodeDefinitionGetImmInstance, PATCH_JUMP);
-InjectHook(0x5D6000, &RxNodeDefinitionGetTransform, PATCH_JUMP);
-InjectHook(0x5D61C0, &RxNodeDefinitionGetImmStash, PATCH_JUMP);
-InjectHook(0x5D6470, &RxNodeDefinitionGetImmMangleLineIndices, PATCH_JUMP);
-InjectHook(0x5D7230, &RxNodeDefinitionGetClipLine, PATCH_JUMP);
-InjectHook(0x5D74C0, &RxNodeDefinitionGetSubmitLine, PATCH_JUMP);
-InjectHook(0x5D9C90, &_rwD3D8LightsOpen, PATCH_JUMP);
-InjectHook(0x5D9EF0, &_rwD3D8LightsClose, PATCH_JUMP);
-InjectHook(0x5D9F80, &_rwD3D8LightsGlobalEnable, PATCH_JUMP);
-InjectHook(0x5DA210, &_rwD3D8LightLocalEnable, PATCH_JUMP);
-InjectHook(0x5DA450, &_rwD3D8LightsEnable, PATCH_JUMP);
-InjectHook(0x5DAAC0, &RxNodeDefinitionGetD3D8WorldSectorAllInOne, PATCH_JUMP);
-InjectHook(0x5DC500, &RxNodeDefinitionGetD3D8AtomicAllInOne, PATCH_JUMP);
-InjectHook(0x5DCC50, &RxNodeDefinitionGetWorldSectorInstance, PATCH_JUMP);
-InjectHook(0x5DCD80, &RxNodeDefinitionGetWorldSectorEnumerateLights, PATCH_JUMP);
-InjectHook(0x5DD800, &RxNodeDefinitionGetAtomicInstance, PATCH_JUMP);
-InjectHook(0x5DD9B0, &RxNodeDefinitionGetAtomicEnumerateLights, PATCH_JUMP);
-InjectHook(0x5DDAA0, &RxNodeDefinitionGetMaterialScatter, PATCH_JUMP);
-InjectHook(0x5DF040, &RxNodeDefinitionGetLight, PATCH_JUMP);
-InjectHook(0x5DF560, &RxNodeDefinitionGetPostLight, PATCH_JUMP);
-InjectHook(0x5DFC60, &RxD3D8AllInOneSetRenderCallBack, PATCH_JUMP);
-ENDPATCHES
-#endif \ No newline at end of file
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index 0ec0b117..29f666df 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -1,7 +1,8 @@
-#define WITHWINDOWS
#include "common.h"
+#define USEALTERNATIVEWINFUNCS
+#include "crossplatform.h"
#include "main.h"
-#include "patcher.h"
+
#include "AudioScriptObject.h"
#include "Camera.h"
#include "CarGen.h"
@@ -40,22 +41,22 @@
const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729;
-char (&DefaultPCSaveFileName)[260] = *(char(*)[260])*(uintptr*)0x8E28C0;
-char (&ValidSaveName)[260] = *(char(*)[260])*(uintptr*)0x8E2CBC;
-char (&LoadFileName)[256] = *(char(*)[256])*(uintptr*)0x9403C4;
-wchar (&SlotFileName)[SLOT_COUNT][260] = *(wchar(*)[SLOT_COUNT][260])*(uintptr*)0x6F07C8;
-wchar (&SlotSaveDate)[SLOT_COUNT][70] = *(wchar(*)[SLOT_COUNT][70])*(uintptr*)0x72B858;
-int &CheckSum = *(int*)0x8E2BE0;
-eLevelName &m_LevelToLoad = *(eLevelName*)0x8E29CC;
+char DefaultPCSaveFileName[260];
+char ValidSaveName[260];
+char LoadFileName[256];
+wchar SlotFileName[SLOT_COUNT][260];
+wchar SlotSaveDate[SLOT_COUNT][70];
+int CheckSum;
+eLevelName m_LevelToLoad;
char SaveFileNameJustSaved[260];
-int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
-CDate &CompileDateAndTime = *(CDate*)0x72BCB8;
+int Slots[SLOT_COUNT+1];
+CDate CompileDateAndTime;
-bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
-bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
-bool &StillToFadeOut = *(bool*)0x95CD99;
-uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
-uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
+bool b_FoundRecentSavedGameWantToLoad;
+bool JustLoadedDontFadeInYet;
+bool StillToFadeOut;
+uint32 TimeStartedCountingForFade;
+uint32 TimeToStayFadedBeforeFadeOut = 1750;
#define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
#define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));
@@ -112,14 +113,22 @@ GenericSave(int file)
// Save simple vars
lastMissionPassed = TheText.Get(CStats::LastMissionPassedName);
- if (*lastMissionPassed) {
+ if (lastMissionPassed[0] != '\0') {
AsciiToUnicode("...'", suffix);
+#ifdef FIX_BUGS
+ // fix buffer overflow
+ int len = UnicodeStrlen(lastMissionPassed);
+ if (len > ARRAY_SIZE(saveName)-1)
+ len = ARRAY_SIZE(saveName)-1;
+ memcpy(saveName, lastMissionPassed, sizeof(wchar) * len);
+#else
TextCopy(saveName, lastMissionPassed);
int len = UnicodeStrlen(saveName);
+#endif
saveName[len] = '\0';
- if (len > 22)
- TextCopy(saveName + 18, suffix);
- saveName[23] = '\0';
+ if (len > ARRAY_SIZE(saveName)-2)
+ TextCopy(&saveName[ARRAY_SIZE(saveName)-ARRAY_SIZE(suffix)], suffix);
+ saveName[ARRAY_SIZE(saveName)-1] = '\0';
}
WriteDataToBufferPointer(buf, saveName);
GetLocalTime(&saveTime);
@@ -154,8 +163,17 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMonth);
WriteDataToBufferPointer(buf, CompileDateAndTime.m_nYear);
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
+#ifdef FIX_BUGS
+ // converted to float for compatibility with original format
+ // TODO: maybe remove this? not really gonna break anything vital
+ float f = TheCamera.CarZoomIndicator;
+ WriteDataToBufferPointer(buf, f);
+ f = TheCamera.PedZoomIndicator;
+ WriteDataToBufferPointer(buf, f);
+#else
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
+#endif
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
// Save scripts, block is nested within the same block as simple vars for some reason
@@ -264,8 +282,18 @@ GenericLoad()
ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth);
ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear);
ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList);
+#ifdef FIX_BUGS
+ // converted to float for compatibility with original format
+ // TODO: maybe remove this? not really gonna break anything vital
+ float f;
+ ReadDataFromBufferPointer(buf, f);
+ TheCamera.CarZoomIndicator = f;
+ ReadDataFromBufferPointer(buf, f);
+ TheCamera.PedZoomIndicator = f;
+#else
ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator);
ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
+#endif
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts);
@@ -534,22 +562,3 @@ align4bytes(int32 size)
{
return (size + 3) & 0xFFFFFFFC;
}
-
-STARTPATCHES
- InjectHook(0x58F8D0, GenericSave, PATCH_JUMP);
- InjectHook(0x590A00, GenericLoad, PATCH_JUMP);
- InjectHook(0x591910, ReadInSizeofSaveFileBuffer, PATCH_JUMP);
- InjectHook(0x591990, ReadDataFromFile, PATCH_JUMP);
- InjectHook(0x591A00, CloseFile, PATCH_JUMP);
- InjectHook(0x591A20, DoGameSpecificStuffAfterSucessLoad, PATCH_JUMP);
- InjectHook(0x591A40, CheckSlotDataValid, PATCH_JUMP);
- InjectHook(0x591A80, MakeSpaceForSizeInBufferPointer, PATCH_JUMP);
- InjectHook(0x591AA0, CopySizeAndPreparePointer, PATCH_JUMP);
- InjectHook(0x591AE0, DoGameSpecificStuffBeforeSave, PATCH_JUMP);
- InjectHook(0x591B10, MakeValidSaveName, PATCH_JUMP);
- InjectHook(0x591B50, GetSavedGameDateAndTime, PATCH_JUMP);
- InjectHook(0x591B60, GetNameOfSavedGame, PATCH_JUMP);
- InjectHook(0x591B70, CheckDataNotCorrupt, PATCH_JUMP);
- InjectHook(0x591D60, RestoreForStartLoad, PATCH_JUMP);
- InjectHook(0x591E80, align4bytes, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index e6fd2e2d..b913c305 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -21,22 +21,22 @@ bool CheckDataNotCorrupt(int32 slot, char *name);
bool RestoreForStartLoad();
int align4bytes(int32 size);
-extern class CDate& CompileDateAndTime;
-
-extern char (&DefaultPCSaveFileName)[260];
-extern char (&ValidSaveName)[260];
-extern char (&LoadFileName)[256];
-extern wchar (&SlotFileName)[SLOT_COUNT][260];
-extern wchar (&SlotSaveDate)[SLOT_COUNT][70];
-extern int &CheckSum;
-extern enum eLevelName &m_LevelToLoad;
-extern int (&Slots)[SLOT_COUNT+1];
-
-extern bool &b_FoundRecentSavedGameWantToLoad;
-extern bool &JustLoadedDontFadeInYet;
-extern bool &StillToFadeOut;
-extern uint32 &TimeStartedCountingForFade;
-extern uint32 &TimeToStayFadedBeforeFadeOut;
+extern class CDate CompileDateAndTime;
+
+extern char DefaultPCSaveFileName[260];
+extern char ValidSaveName[260];
+extern char LoadFileName[256];
+extern wchar SlotFileName[SLOT_COUNT][260];
+extern wchar SlotSaveDate[SLOT_COUNT][70];
+extern int CheckSum;
+extern enum eLevelName m_LevelToLoad;
+extern int Slots[SLOT_COUNT+1];
+
+extern bool b_FoundRecentSavedGameWantToLoad;
+extern bool JustLoadedDontFadeInYet;
+extern bool StillToFadeOut;
+extern uint32 TimeStartedCountingForFade;
+extern uint32 TimeToStayFadedBeforeFadeOut;
extern char SaveFileNameJustSaved[260]; // 8F2570
diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp
index 744f5e0d..6f1b1b45 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -1,6 +1,7 @@
-#define WITHWINDOWS
#include "common.h"
-#include "patcher.h"
+#define USEALTERNATIVEWINFUNCS
+#include "crossplatform.h"
+
#include "FileMgr.h"
#include "GenericGameStorage.h"
#include "Messages.h"
@@ -9,7 +10,7 @@
const char* _psGetUserFilesFolder();
-C_PcSave &PcSaveHelper = *(C_PcSave*)0x8E2C60;
+C_PcSave PcSaveHelper;
void
C_PcSave::SetSaveDirectory(const char *path)
@@ -86,11 +87,15 @@ C_PcSave::PopulateSlotInfo()
SlotSaveDate[i][0] = '\0';
}
for (int i = 0; i < SLOT_COUNT; i++) {
+#ifdef FIX_BUGS
+ char savename[MAX_PATH];
+#else
char savename[52];
+#endif
struct {
int size;
wchar FileName[24];
- _SYSTEMTIME SaveDateTime;
+ SYSTEMTIME SaveDateTime;
} header;
sprintf(savename, "%s%i%s", DefaultPCSaveFileName, i + 1, ".b");
int file = CFileMgr::OpenFile(savename, "rb");
@@ -106,8 +111,8 @@ C_PcSave::PopulateSlotInfo()
}
if (Slots[i + 1] == SLOT_OK) {
if (CheckDataNotCorrupt(i, savename)) {
- _SYSTEMTIME st;
- memcpy(&st, &header.SaveDateTime, sizeof(_SYSTEMTIME));
+ SYSTEMTIME st;
+ memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME));
const char *month;
switch (st.wMonth)
{
@@ -136,11 +141,3 @@ C_PcSave::PopulateSlotInfo()
}
}
}
-
-STARTPATCHES
- InjectHook(0x591EA0, C_PcSave::SetSaveDirectory, PATCH_JUMP);
- InjectHook(0x5922F0, &C_PcSave::DeleteSlot, PATCH_JUMP);
- InjectHook(0x591EC0, &C_PcSave::SaveSlot, PATCH_JUMP);
- InjectHook(0x591F80, &C_PcSave::PcClassSaveRoutine, PATCH_JUMP);
- InjectHook(0x592090, &C_PcSave::PopulateSlotInfo, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/save/PCSave.h b/src/save/PCSave.h
index c58a5c9e..4a2d9a66 100644
--- a/src/save/PCSave.h
+++ b/src/save/PCSave.h
@@ -37,4 +37,4 @@ public:
static void SetSaveDirectory(const char *path);
};
-extern C_PcSave &PcSaveHelper;
+extern C_PcSave PcSaveHelper;
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
new file mode 100644
index 00000000..f9464bb6
--- /dev/null
+++ b/src/skel/crossplatform.cpp
@@ -0,0 +1,81 @@
+#include "common.h"
+#define USEALTERNATIVEWINFUNCS
+#include "crossplatform.h"
+
+// For internal use
+// wMilliseconds is not needed
+void tmToSystemTime(const tm *tm, SYSTEMTIME *out) {
+ out->wYear = tm->tm_year + 1900;
+ out->wMonth = tm->tm_mon + 1;
+ out->wDayOfWeek = tm->tm_wday;
+ out->wDay = tm->tm_mday;
+ out->wHour = tm->tm_hour;
+ out->wMinute = tm->tm_min;
+ out->wSecond = tm->tm_sec;
+}
+
+void GetLocalTime_CP(SYSTEMTIME *out) {
+ time_t timestamp = time(nil);
+ tm *localTm = localtime(&timestamp);
+ tmToSystemTime(localTm, out);
+}
+
+#if !defined _WIN32 || defined __MINGW32__
+HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
+ char newpathname[32];
+ strncpy(newpathname, pathname, 32);
+ char* path = strtok(newpathname, "\\*");
+ strncpy(firstfile->folder, path, sizeof(firstfile->folder));
+
+ // Both w/ extension and w/o extension is ok
+ if (strlen(path) + 2 != strlen(pathname))
+ strncpy(firstfile->extension, strtok(NULL, "\\*"), sizeof(firstfile->extension));
+ else
+ strncpy(firstfile->extension, "", sizeof(firstfile->extension));
+
+ HANDLE d;
+ if ((d = opendir(path)) == NULL || !FindNextFile(d, firstfile))
+ return NULL;
+
+ return d;
+}
+
+bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) {
+ dirent *file;
+ static struct stat fileStats;
+ static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1];
+ int extensionLen = strlen(finddata->extension);
+ while ((file = readdir(d)) != NULL) {
+
+ // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type.
+ if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) &&
+ (extensionLen == 0 || strncmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) {
+
+ sprintf(relativepath, "%s/%s", finddata->folder, file->d_name);
+ realpath(relativepath, path);
+ stat(path, &fileStats);
+ strncpy(finddata->cFileName, file->d_name, sizeof(finddata->cFileName));
+ finddata->ftLastWriteTime = fileStats.st_mtime;
+ return true;
+ }
+ }
+ return false;
+}
+
+void GetDateFormat(int unused1, int unused2, SYSTEMTIME* in, int unused3, char* out, int size) {
+ tm linuxTime;
+ linuxTime.tm_year = in->wYear - 1900;
+ linuxTime.tm_mon = in->wMonth - 1;
+ linuxTime.tm_wday = in->wDayOfWeek;
+ linuxTime.tm_mday = in->wDay;
+ linuxTime.tm_hour = in->wHour;
+ linuxTime.tm_min = in->wMinute;
+ linuxTime.tm_sec = in->wSecond;
+ strftime(out, size, nl_langinfo(D_FMT), &linuxTime);
+}
+
+void FileTimeToSystemTime(time_t* writeTime, SYSTEMTIME* out) {
+ tm *ptm = gmtime(writeTime);
+ tmToSystemTime(ptm, out);
+}
+#endif \ No newline at end of file
diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h
new file mode 100644
index 00000000..342aab4e
--- /dev/null
+++ b/src/skel/crossplatform.h
@@ -0,0 +1,114 @@
+#include <time.h>
+
+// This is the common include for platform/renderer specific skeletons(glfw, win etc.) and cross platform things (like Windows directories wrapper, platform specific global arrays etc.)
+
+// This only has <windef.h> as Win header.
+#ifdef _WIN32
+#include "win.h"
+#endif
+
+#ifdef RW_GL3
+typedef struct
+{
+ GLFWwindow* window;
+ RwBool fullScreen;
+ RwV2d lastMousePos;
+ double mouseWheel; // glfw doesn't cache it
+ int8 joy1id;
+ int8 joy2id;
+}
+psGlobalType;
+
+#define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var)
+
+void CapturePad(RwInt32 padID);
+void joysChangeCB(int jid, int event);
+#endif
+
+enum eGameState
+{
+ GS_START_UP = 0,
+ GS_INIT_LOGO_MPEG,
+ GS_LOGO_MPEG,
+ GS_INIT_INTRO_MPEG,
+ GS_INTRO_MPEG,
+ GS_INIT_ONCE,
+ GS_INIT_FRONTEND,
+ GS_FRONTEND,
+ GS_INIT_PLAYING_GAME,
+ GS_PLAYING_GAME,
+#ifndef MASTER
+ GS_ANIMVIEWER,
+#endif
+};
+extern RwUInt32 gGameState;
+
+RwBool IsForegroundApp();
+void InitialiseLanguage();
+RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode);
+
+RwChar** _psGetVideoModeList();
+RwInt32 _psGetNumVideModes();
+
+void _psSelectScreenVM(RwInt32 videoMode);
+void HandleExit();
+void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs);
+
+// Mostly wrappers around Windows functions
+
+#ifndef MAX_PATH
+ #if !defined _WIN32 || defined __MINGW32__
+ #define MAX_PATH PATH_MAX
+ #else
+ #define MAX_PATH 260
+ #endif
+#endif
+
+// TODO: Remove USEALTERNATIVEWINFUNCS and don't use it anywhere when re3 becomes fully cross-platform, this is for testing
+// Codes compatible with Windows and Linux
+#if defined USEALTERNATIVEWINFUNCS || !defined _WIN32 || defined __MINGW32__
+#define DeleteFile unlink
+
+// Needed for save games
+struct SYSTEMTIME {
+ uint16 wYear;
+ uint16 wMonth;
+ uint16 wDayOfWeek;
+ uint16 wDay;
+ uint16 wHour;
+ uint16 wMinute;
+ uint16 wSecond;
+ uint16 wMilliseconds;
+};
+
+void GetLocalTime_CP(SYSTEMTIME* out);
+#define GetLocalTime GetLocalTime_CP
+#define OutputDebugString(s) re3_debug("[DBG-2]: " s "\n")
+#endif
+
+// Only runs on GNU/POSIX/etc.
+#if !defined _WIN32 || defined __MINGW32__
+#include <iostream>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <langinfo.h>
+
+typedef DIR* HANDLE;
+#define INVALID_HANDLE_VALUE NULL
+#define FindClose closedir
+#define LOCALE_USER_DEFAULT 0
+#define DATE_SHORTDATE 0
+
+struct WIN32_FIND_DATA {
+ char extension[32]; // for searching
+ char folder[32]; // for searching
+ char cFileName[256]; // because tSkinInfo has it 256
+ time_t ftLastWriteTime;
+};
+
+HANDLE FindFirstFile(char*, WIN32_FIND_DATA*);
+bool FindNextFile(HANDLE, WIN32_FIND_DATA*);
+void FileTimeToSystemTime(time_t*, SYSTEMTIME*);
+void GetDateFormat(int, int, SYSTEMTIME*, int, char*, int);
+#endif \ No newline at end of file
diff --git a/src/skel/events.cpp b/src/skel/events.cpp
index 60e1482e..3e1e95b3 100644
--- a/src/skel/events.cpp
+++ b/src/skel/events.cpp
@@ -1,18 +1,13 @@
-#include "rwcore.h"
-#include "skeleton.h"
-#include "events.h"
-
-//#include "main.h"
- #define DIRECTINPUT_VERSION 0x0800
- #include <dinput.h>
#include "common.h"
#include "Pad.h"
#include "ControllerConfig.h"
#include "Frontend.h"
#include "Camera.h"
+#include "rwcore.h"
+#include "skeleton.h"
+#include "events.h"
-#include "patcher.h"
/*
*****************************************************************************
@@ -832,14 +827,3 @@ AttachInputDevices(void)
return TRUE;
}
-
-
-STARTPATCHES
- InjectHook(0x583F10, HandleKeyDown, PATCH_JUMP);
- InjectHook(0x5842F0, HandleKeyUp, PATCH_JUMP);
- InjectHook(0x5846C0, KeyboardHandler, PATCH_JUMP);
- InjectHook(0x5846F0, HandlePadButtonDown, PATCH_JUMP);
- InjectHook(0x584770, HandlePadButtonUp, PATCH_JUMP);
- InjectHook(0x584830, PadHandler, PATCH_JUMP);
- InjectHook(0x584860, AttachInputDevices, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
new file mode 100644
index 00000000..db6be3a2
--- /dev/null
+++ b/src/skel/glfw/glfw.cpp
@@ -0,0 +1,1652 @@
+#if defined RW_GL3 && !defined LIBRW_SDL2
+
+#define WITHWINDOWS
+#include "common.h"
+
+#pragma warning( push )
+#pragma warning( disable : 4005)
+#pragma warning( pop )
+
+#pragma comment( lib, "Winmm.lib" ) // Needed for time
+
+#if (defined(_MSC_VER))
+#include <tchar.h>
+#endif /* (defined(_MSC_VER)) */
+#include <stdio.h>
+#include "rwcore.h"
+#include "resource.h"
+#include "skeleton.h"
+#include "platform.h"
+#include "crossplatform.h"
+
+#include "patcher.h"
+#include "main.h"
+#include "FileMgr.h"
+#include "Text.h"
+#include "Pad.h"
+#include "Timer.h"
+#include "DMAudio.h"
+#include "ControllerConfig.h"
+#include "Frontend.h"
+#include "Game.h"
+#include "PCSave.h"
+#include "Sprite2d.h"
+#include "AnimViewer.h"
+
+
+#define MAX_SUBSYSTEMS (16)
+
+
+rw::EngineOpenParams openParams;
+
+static RwBool ForegroundApp = TRUE;
+
+static RwBool RwInitialised = FALSE;
+
+static RwSubSystemInfo GsubSysInfo[MAX_SUBSYSTEMS];
+static RwInt32 GnumSubSystems = 0;
+static RwInt32 GcurSel = 0, GcurSelVM = 0;
+
+static RwBool useDefault;
+
+static RwBool defaultFullscreenRes = TRUE;
+
+static psGlobalType PsGlobal;
+
+
+#define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var)
+
+#undef MAKEPOINTS
+#define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l)))
+
+#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
+#define JIF(x) if (FAILED(hr=(x))) \
+ {debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;}
+
+
+// TODO: This is used on selecting video mode, so either think something or remove it completely
+DWORD _dwMemTotalVideo = 1024 * (1024 * 1024); // 1024 MB as placeholder
+DWORD _dwMemAvailPhys;
+
+DWORD _dwOperatingSystemVersion;
+
+RwUInt32 gGameState;
+/*
+ *****************************************************************************
+ */
+void _psCreateFolder(const char *path)
+{
+#ifdef _WIN32
+ HANDLE hfle = CreateFile(path, GENERIC_READ,
+ FILE_SHARE_READ,
+ nil,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL,
+ nil);
+
+ if ( hfle == INVALID_HANDLE_VALUE )
+ CreateDirectory(path, nil);
+ else
+ CloseHandle(hfle);
+#else
+ struct stat info;
+ char fullpath[PATH_MAX];
+ realpath(path, fullpath);
+
+ if (lstat(fullpath, &info) != 0) {
+ if (errno == ENOENT || (errno != EACCES && !S_ISDIR(info.st_mode))) {
+ mkdir(fullpath, 0755);
+ }
+ }
+#endif
+}
+
+/*
+ *****************************************************************************
+ */
+const char *_psGetUserFilesFolder()
+{
+#if defined USE_MY_DOCUMENTS && defined _WIN32
+ HKEY hKey = NULL;
+
+ static CHAR szUserFiles[256];
+
+ if ( RegOpenKeyEx(HKEY_CURRENT_USER,
+ REGSTR_PATH_SPECIAL_FOLDERS,
+ REG_OPTION_RESERVED,
+ KEY_READ,
+ &hKey) == ERROR_SUCCESS )
+ {
+ DWORD KeyType;
+ DWORD KeycbData = sizeof(szUserFiles);
+ if ( RegQueryValueEx(hKey,
+ "Personal",
+ NULL,
+ &KeyType,
+ (LPBYTE)szUserFiles,
+ &KeycbData) == ERROR_SUCCESS )
+ {
+ RegCloseKey(hKey);
+ strcat(szUserFiles, "\\GTA3 User Files");
+ _psCreateFolder(szUserFiles);
+ return szUserFiles;
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ strcpy(szUserFiles, "data");
+ return szUserFiles;
+#else
+ static CHAR szUserFiles[256];
+ strcpy(szUserFiles, "userfiles");
+ _psCreateFolder(szUserFiles);
+ return szUserFiles;
+#endif
+}
+
+/*
+ *****************************************************************************
+ */
+RwBool
+psCameraBeginUpdate(RwCamera *camera)
+{
+ if ( !RwCameraBeginUpdate(Scene.camera) )
+ {
+ ForegroundApp = FALSE;
+ RsEventHandler(rsACTIVATE, (void *)FALSE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ *****************************************************************************
+ */
+void
+psCameraShowRaster(RwCamera *camera)
+{
+ if (CMenuManager::m_PrefsVsync)
+ RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC);
+ else
+ RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT);
+
+ return;
+}
+
+
+/*
+ *****************************************************************************
+ */
+RwUInt32
+psTimer(void)
+{
+ RwUInt32 time;
+
+ TIMECAPS TimeCaps;
+
+ timeGetDevCaps(&TimeCaps, sizeof(TIMECAPS));
+
+ timeBeginPeriod(TimeCaps.wPeriodMin);
+
+ time = (RwUInt32) timeGetTime();
+
+ timeEndPeriod(TimeCaps.wPeriodMin);
+
+ return time;
+}
+
+/*
+ *****************************************************************************
+ */
+void
+psMouseSetPos(RwV2d *pos)
+{
+ POINT point;
+
+ point.x = (RwInt32) pos->x;
+ point.y = (RwInt32) pos->y;
+
+ glfwSetCursorPos(PSGLOBAL(window), point.x, point.y);
+
+ PSGLOBAL(lastMousePos.x) = (RwInt32)pos->x;
+
+ PSGLOBAL(lastMousePos.y) = (RwInt32)pos->y;
+
+ return;
+}
+
+/*
+ *****************************************************************************
+ */
+RwMemoryFunctions*
+psGetMemoryFunctions(void)
+{
+ return nil;
+}
+
+/*
+ *****************************************************************************
+ */
+RwBool
+psInstallFileSystem(void)
+{
+ return (TRUE);
+}
+
+
+/*
+ *****************************************************************************
+ */
+RwBool
+psNativeTextureSupport(void)
+{
+ return true;
+}
+
+/*
+ *****************************************************************************
+ */
+static char cpuvendor[16] = "UnknownVendr";
+__declspec(naked) const char * _psGetCpuVendr()
+{
+ __asm
+ {
+ push ebx
+ xor eax, eax
+ cpuid
+ mov dword ptr [cpuvendor+0], ebx
+ mov dword ptr [cpuvendor+4], edx
+ mov dword ptr [cpuvendor+8], ecx
+ mov eax, offset cpuvendor
+ pop ebx
+ retn
+ }
+}
+
+/*
+ *****************************************************************************
+ */
+__declspec(naked) RwUInt32 _psGetCpuFeatures()
+{
+ __asm
+ {
+ mov eax, 1
+ cpuid
+ mov eax, edx
+ retn
+ }
+}
+
+/*
+ *****************************************************************************
+ */
+__declspec(naked) RwUInt32 _psGetCpuFeaturesEx()
+{
+ __asm
+ {
+ mov eax, 80000000h
+ cpuid
+
+ cmp eax, 80000000h
+ jbe short _NOEX
+
+ mov eax, 80000001h
+ cpuid
+
+ mov eax, edx
+ jmp short _RETEX
+
+_NOEX:
+ xor eax, eax
+ mov eax, eax
+
+_RETEX:
+ retn
+ }
+}
+
+void _psPrintCpuInfo()
+{
+ RwUInt32 features = _psGetCpuFeatures();
+ RwUInt32 FeaturesEx = _psGetCpuFeaturesEx();
+
+ debug("Running on a %s", _psGetCpuVendr());
+
+ if ( features & 0x800000 )
+ debug("with MMX");
+ if ( features & 0x2000000 )
+ debug("with SSE");
+ if ( FeaturesEx & 0x80000000 )
+ debug("with 3DNow");
+}
+
+/*
+ *****************************************************************************
+ */
+#ifdef UNDER_CE
+#define CMDSTR LPWSTR
+#else
+#define CMDSTR LPSTR
+#endif
+
+/*
+ *****************************************************************************
+ */
+RwBool
+psInitialise(void)
+{
+ PsGlobal.lastMousePos.x = PsGlobal.lastMousePos.y = 0.0f;
+
+ RsGlobal.ps = &PsGlobal;
+
+ PsGlobal.fullScreen = FALSE;
+
+ PsGlobal.joy1id = -1;
+ PsGlobal.joy2id = -1;
+
+ CFileMgr::Initialise();
+
+ C_PcSave::SetSaveDirectory(_psGetUserFilesFolder());
+
+ InitialiseLanguage();
+
+ FrontEndMenuManager.LoadSettings();
+
+ gGameState = GS_START_UP;
+ TRACE("gGameState = GS_START_UP");
+
+ _psPrintCpuInfo();
+
+ OSVERSIONINFO verInfo;
+ verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ GetVersionEx(&verInfo);
+
+ _dwOperatingSystemVersion = OS_WIN95;
+
+ if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ {
+ if ( verInfo.dwMajorVersion == 4 )
+ {
+ debug("Operating System is WinNT\n");
+ _dwOperatingSystemVersion = OS_WINNT;
+ }
+ else if ( verInfo.dwMajorVersion == 5 )
+ {
+ debug("Operating System is Win2000\n");
+ _dwOperatingSystemVersion = OS_WIN2000;
+ }
+ else if ( verInfo.dwMajorVersion > 5 )
+ {
+ debug("Operating System is WinXP or greater\n");
+ _dwOperatingSystemVersion = OS_WINXP;
+ }
+ }
+ else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 )
+ {
+ debug("Operating System is Win98\n");
+ _dwOperatingSystemVersion = OS_WIN98;
+ }
+ else
+ {
+ debug("Operating System is Win95\n");
+ _dwOperatingSystemVersion = OS_WIN95;
+ }
+ }
+
+ MEMORYSTATUS memstats;
+ GlobalMemoryStatus(&memstats);
+
+ _dwMemAvailPhys = memstats.dwAvailPhys;
+
+#ifdef FIX_BUGS
+ debug("Physical memory size %u\n", memstats.dwTotalPhys);
+ debug("Available physical memory %u\n", memstats.dwAvailPhys);
+#else
+ debug("Physical memory size %d\n", memstats.dwTotalPhys);
+ debug("Available physical memory %d\n", memstats.dwAvailPhys);
+#endif
+
+ TheText.Unload();
+
+ return TRUE;
+}
+
+
+/*
+ *****************************************************************************
+ */
+void
+psTerminate(void)
+{
+ return;
+}
+
+/*
+ *****************************************************************************
+ */
+static RwChar **_VMList;
+
+RwInt32 _psGetNumVideModes()
+{
+ return RwEngineGetNumVideoModes();
+}
+
+/*
+ *****************************************************************************
+ */
+RwBool _psFreeVideoModeList()
+{
+ RwInt32 numModes;
+ RwInt32 i;
+
+ numModes = _psGetNumVideModes();
+
+ if ( _VMList == nil )
+ return TRUE;
+
+ for ( i = 0; i < numModes; i++ )
+ {
+ RwFree(_VMList[i]);
+ }
+
+ RwFree(_VMList);
+
+ _VMList = nil;
+
+ return TRUE;
+}
+
+/*
+ *****************************************************************************
+ */
+RwChar **_psGetVideoModeList()
+{
+ RwInt32 numModes;
+ RwInt32 i;
+
+ if ( _VMList != nil )
+ {
+ return _VMList;
+ }
+
+ numModes = RwEngineGetNumVideoModes();
+
+ _VMList = (RwChar **)RwCalloc(numModes, sizeof(RwChar*));
+
+ for ( i = 0; i < numModes; i++ )
+ {
+ RwVideoMode vm;
+
+ RwEngineGetVideoModeInfo(&vm, i);
+
+ if ( vm.flags & rwVIDEOMODEEXCLUSIVE )
+ {
+ if ( vm.width >= 640
+ && vm.height >= 480
+ && (vm.width == 640
+ && vm.height == 480)
+ || !(vm.flags & rwVIDEOMODEEXCLUSIVE)
+ || (_dwMemTotalVideo - vm.depth * vm.height * vm.width / 8) > (12 * 1024 * 1024)/*12 MB*/ )
+ {
+ _VMList[i] = (RwChar*)RwCalloc(100, sizeof(RwChar));
+ rwsprintf(_VMList[i],"%lu X %lu X %lu", vm.width, vm.height, vm.depth);
+ }
+ else
+ _VMList[i] = nil;
+ }
+ else
+ _VMList[i] = nil;
+ }
+
+ return _VMList;
+}
+
+/*
+ *****************************************************************************
+ */
+void _psSelectScreenVM(RwInt32 videoMode)
+{
+ RwTexDictionarySetCurrent( nil );
+
+ FrontEndMenuManager.UnloadTextures();
+
+ if ( !_psSetVideoMode(RwEngineGetCurrentSubSystem(), videoMode) )
+ {
+ RsGlobal.quit = TRUE;
+ }
+ else
+ FrontEndMenuManager.LoadAllTextures();
+}
+
+/*
+ *****************************************************************************
+ */
+
+RwBool IsForegroundApp()
+{
+ return !!ForegroundApp;
+}
+/*
+UINT GetBestRefreshRate(UINT width, UINT height, UINT depth)
+{
+ LPDIRECT3D8 d3d = Direct3DCreate8(D3D_SDK_VERSION);
+
+ ASSERT(d3d != nil);
+
+ UINT refreshRate = INT_MAX;
+ D3DFORMAT format;
+
+ if ( depth == 32 )
+ format = D3DFMT_X8R8G8B8;
+ else if ( depth == 24 )
+ format = D3DFMT_R8G8B8;
+ else
+ format = D3DFMT_R5G6B5;
+
+ UINT modeCount = d3d->GetAdapterModeCount(GcurSel);
+
+ for ( UINT i = 0; i < modeCount; i++ )
+ {
+ D3DDISPLAYMODE mode;
+
+ d3d->EnumAdapterModes(GcurSel, i, &mode);
+
+ if ( mode.Width == width && mode.Height == height && mode.Format == format )
+ {
+ if ( mode.RefreshRate == 0 )
+ return 0;
+
+ if ( mode.RefreshRate < refreshRate && mode.RefreshRate >= 60 )
+ refreshRate = mode.RefreshRate;
+ }
+ }
+
+#ifdef FIX_BUGS
+ d3d->Release();
+#endif
+
+ if ( refreshRate == -1 )
+ return -1;
+
+ return refreshRate;
+}
+*/
+/*
+ *****************************************************************************
+ */
+RwBool
+psSelectDevice()
+{
+ RwVideoMode vm;
+ RwInt32 subSysNum;
+ RwInt32 AutoRenderer = 0;
+
+
+ RwBool modeFound = FALSE;
+
+ if ( !useDefault )
+ {
+ GnumSubSystems = RwEngineGetNumSubSystems();
+ if ( !GnumSubSystems )
+ {
+ return FALSE;
+ }
+
+ /* Just to be sure ... */
+ GnumSubSystems = (GnumSubSystems > MAX_SUBSYSTEMS) ? MAX_SUBSYSTEMS : GnumSubSystems;
+
+ /* Get the names of all the sub systems */
+ for (subSysNum = 0; subSysNum < GnumSubSystems; subSysNum++)
+ {
+ RwEngineGetSubSystemInfo(&GsubSysInfo[subSysNum], subSysNum);
+ }
+
+ /* Get the default selection */
+ GcurSel = RwEngineGetCurrentSubSystem();
+ }
+
+ /* Set the driver to use the correct sub system */
+ if (!RwEngineSetSubSystem(GcurSel))
+ {
+ return FALSE;
+ }
+
+
+ if ( !useDefault )
+ {
+ if ( _psGetVideoModeList()[FrontEndMenuManager.m_nDisplayVideoMode] && FrontEndMenuManager.m_nDisplayVideoMode )
+ {
+ FrontEndMenuManager.m_nPrefsVideoMode = FrontEndMenuManager.m_nDisplayVideoMode;
+ GcurSelVM = FrontEndMenuManager.m_nDisplayVideoMode;
+ }
+ else
+ {
+#ifdef DEFAULT_NATIVE_RESOLUTION
+ // get the native video mode
+ HDC hDevice = GetDC(NULL);
+ int w = GetDeviceCaps(hDevice, HORZRES);
+ int h = GetDeviceCaps(hDevice, VERTRES);
+ int d = GetDeviceCaps(hDevice, BITSPIXEL);
+#else
+ const int w = 640;
+ const int h = 480;
+ const int d = 16;
+#endif
+ while ( !modeFound && GcurSelVM < RwEngineGetNumVideoModes() )
+ {
+ RwEngineGetVideoModeInfo(&vm, GcurSelVM);
+ if ( defaultFullscreenRes && vm.width != w
+ || vm.height != h
+ || vm.depth != d
+ || !(vm.flags & rwVIDEOMODEEXCLUSIVE) )
+ ++GcurSelVM;
+ else
+ modeFound = TRUE;
+ }
+
+ if ( !modeFound )
+ {
+#ifdef DEFAULT_NATIVE_RESOLUTION
+ GcurSelVM = 1;
+#else
+ MessageBox(nil, "Cannot find 640x480 video mode", "GTA3", MB_OK);
+ return FALSE;
+#endif
+ }
+ }
+ }
+
+ RwEngineGetVideoModeInfo(&vm, GcurSelVM);
+
+ FrontEndMenuManager.m_nCurrOption = 0;
+
+ /* Set up the video mode and set the apps window
+ * dimensions to match */
+ if (!RwEngineSetVideoMode(GcurSelVM))
+ {
+ return FALSE;
+ }
+ /*
+ TODO
+ if (vm.flags & rwVIDEOMODEEXCLUSIVE)
+ {
+ debug("%dx%dx%d", vm.width, vm.height, vm.depth);
+
+ UINT refresh = GetBestRefreshRate(vm.width, vm.height, vm.depth);
+
+ if ( refresh != (UINT)-1 )
+ {
+ debug("refresh %d", refresh);
+ RwD3D8EngineSetRefreshRate((RwUInt32)refresh);
+ }
+ }
+ */
+ if (vm.flags & rwVIDEOMODEEXCLUSIVE)
+ {
+ RsGlobal.maximumWidth = vm.width;
+ RsGlobal.maximumHeight = vm.height;
+ RsGlobal.width = vm.width;
+ RsGlobal.height = vm.height;
+
+ PSGLOBAL(fullScreen) = TRUE;
+ }
+
+ return TRUE;
+}
+
+/*
+ *****************************************************************************
+ */
+RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode)
+{
+ RwInitialised = FALSE;
+
+ RsEventHandler(rsRWTERMINATE, nil);
+
+ GcurSel = subSystem;
+ GcurSelVM = videoMode;
+
+ useDefault = TRUE;
+
+ if ( RsEventHandler(rsRWINITIALISE, &PSGLOBAL(window)) == rsEVENTERROR )
+ return FALSE;
+
+ RwInitialised = TRUE;
+ useDefault = FALSE;
+
+ RwRect r;
+
+ r.x = 0;
+ r.y = 0;
+ r.w = RsGlobal.maximumWidth;
+ r.h = RsGlobal.maximumHeight;
+
+ RsEventHandler(rsCAMERASIZE, &r);
+
+ return TRUE;
+}
+
+
+/*
+ *****************************************************************************
+ */
+static RwChar **
+CommandLineToArgv(RwChar *cmdLine, RwInt32 *argCount)
+{
+ RwInt32 numArgs = 0;
+ RwBool inArg, inString;
+ RwInt32 i, len;
+ RwChar *res, *str, **aptr;
+
+ len = strlen(cmdLine);
+
+ /*
+ * Count the number of arguments...
+ */
+ inString = FALSE;
+ inArg = FALSE;
+
+ for(i=0; i<=len; i++)
+ {
+ if( cmdLine[i] == '"' )
+ {
+ inString = !inString;
+ }
+
+ if( (cmdLine[i] <= ' ' && !inString) || i == len )
+ {
+ if( inArg )
+ {
+ inArg = FALSE;
+
+ numArgs++;
+ }
+ }
+ else if( !inArg )
+ {
+ inArg = TRUE;
+ }
+ }
+
+ /*
+ * Allocate memory for result...
+ */
+ res = (RwChar *)malloc(sizeof(RwChar *) * numArgs + len + 1);
+ str = res + sizeof(RwChar *) * numArgs;
+ aptr = (RwChar **)res;
+
+ strcpy(str, cmdLine);
+
+ /*
+ * Walk through cmdLine again this time setting pointer to each arg...
+ */
+ inArg = FALSE;
+ inString = FALSE;
+
+ for(i=0; i<=len; i++)
+ {
+ if( cmdLine[i] == '"' )
+ {
+ inString = !inString;
+ }
+
+ if( (cmdLine[i] <= ' ' && !inString) || i == len )
+ {
+ if( inArg )
+ {
+ if( str[i-1] == '"' )
+ {
+ str[i-1] = '\0';
+ }
+ else
+ {
+ str[i] = '\0';
+ }
+
+ inArg = FALSE;
+ }
+ }
+ else if( !inArg && cmdLine[i] != '"' )
+ {
+ inArg = TRUE;
+
+ *aptr++ = &str[i];
+ }
+ }
+
+ *argCount = numArgs;
+
+ return (RwChar **)res;
+}
+
+/*
+ *****************************************************************************
+ */
+void InitialiseLanguage()
+{
+ WORD primUserLCID = PRIMARYLANGID(GetSystemDefaultLCID());
+ WORD primSystemLCID = PRIMARYLANGID(GetUserDefaultLCID());
+ WORD primLayout = PRIMARYLANGID((DWORD)GetKeyboardLayout(0));
+
+ WORD subUserLCID = SUBLANGID(GetSystemDefaultLCID());
+ WORD subSystemLCID = SUBLANGID(GetUserDefaultLCID());
+ WORD subLayout = SUBLANGID((DWORD)GetKeyboardLayout(0));
+
+ if ( primUserLCID == LANG_GERMAN
+ || primSystemLCID == LANG_GERMAN
+ || primLayout == LANG_GERMAN )
+ {
+ CGame::nastyGame = false;
+ CMenuManager::m_PrefsAllowNastyGame = false;
+ CGame::germanGame = true;
+ }
+
+ if ( primUserLCID == LANG_FRENCH
+ || primSystemLCID == LANG_FRENCH
+ || primLayout == LANG_FRENCH )
+ {
+ CGame::nastyGame = false;
+ CMenuManager::m_PrefsAllowNastyGame = false;
+ CGame::frenchGame = true;
+ }
+
+ if ( subUserLCID == SUBLANG_ENGLISH_AUS
+ || subSystemLCID == SUBLANG_ENGLISH_AUS
+ || subLayout == SUBLANG_ENGLISH_AUS )
+ CGame::noProstitutes = true;
+
+#ifdef NASTY_GAME
+ CGame::nastyGame = true;
+ CMenuManager::m_PrefsAllowNastyGame = true;
+ CGame::noProstitutes = false;
+#endif
+
+ int32 lang;
+
+ switch ( primSystemLCID )
+ {
+ case LANG_GERMAN:
+ {
+ lang = LANG_GERMAN;
+ break;
+ }
+ case LANG_FRENCH:
+ {
+ lang = LANG_FRENCH;
+ break;
+ }
+ case LANG_SPANISH:
+ {
+ lang = LANG_SPANISH;
+ break;
+ }
+ case LANG_ITALIAN:
+ {
+ lang = LANG_ITALIAN;
+ break;
+ }
+ default:
+ {
+ lang = ( subSystemLCID == SUBLANG_ENGLISH_AUS ) ? -99 : LANG_ENGLISH;
+ break;
+ }
+ }
+
+ CMenuManager::OS_Language = primUserLCID;
+
+ switch ( lang )
+ {
+ case LANG_GERMAN:
+ {
+ CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN;
+ break;
+ }
+ case LANG_SPANISH:
+ {
+ CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH;
+ break;
+ }
+ case LANG_FRENCH:
+ {
+ CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH;
+ break;
+ }
+ case LANG_ITALIAN:
+ {
+ CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN;
+ break;
+ }
+ default:
+ {
+ CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN;
+ break;
+ }
+ }
+
+ TheText.Unload();
+ TheText.Load();
+}
+
+/*
+ *****************************************************************************
+ */
+void HandleExit()
+{
+ MSG message;
+ while ( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
+ {
+ if( message.message == WM_QUIT )
+ {
+ RsGlobal.quit = TRUE;
+ }
+ else
+ {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ }
+ }
+}
+
+void resizeCB(GLFWwindow* window, int width, int height) {
+ /*
+ * Handle event to ensure window contents are displayed during re-size
+ * as this can be disabled by the user, then if there is not enough
+ * memory things don't work.
+ */
+ /* redraw window */
+ if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER))
+ {
+ RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void*)TRUE);
+ }
+
+ if (RwInitialised && height > 0 && width > 0) {
+ RwRect r;
+
+ r.x = 0;
+ r.y = 0;
+ r.w = RsGlobal.maximumWidth;
+ r.h = RsGlobal.maximumHeight;
+
+ RsEventHandler(rsCAMERASIZE, &r);
+ }
+ glfwSetWindowPos(window, 0, 0);
+}
+
+void scrollCB(GLFWwindow* window, double xoffset, double yoffset) {
+ PSGLOBAL(mouseWheel) = yoffset;
+}
+
+int keymap[GLFW_KEY_LAST + 1];
+
+static void
+initkeymap(void)
+{
+ int i;
+ for (i = 0; i < GLFW_KEY_LAST + 1; i++)
+ keymap[i] = rsNULL;
+
+ keymap[GLFW_KEY_SPACE] = ' ';
+ keymap[GLFW_KEY_APOSTROPHE] = '\'';
+ keymap[GLFW_KEY_COMMA] = ',';
+ keymap[GLFW_KEY_MINUS] = '-';
+ keymap[GLFW_KEY_PERIOD] = '.';
+ keymap[GLFW_KEY_SLASH] = '/';
+ keymap[GLFW_KEY_0] = '0';
+ keymap[GLFW_KEY_1] = '1';
+ keymap[GLFW_KEY_2] = '2';
+ keymap[GLFW_KEY_3] = '3';
+ keymap[GLFW_KEY_4] = '4';
+ keymap[GLFW_KEY_5] = '5';
+ keymap[GLFW_KEY_6] = '6';
+ keymap[GLFW_KEY_7] = '7';
+ keymap[GLFW_KEY_8] = '8';
+ keymap[GLFW_KEY_9] = '9';
+ keymap[GLFW_KEY_SEMICOLON] = ';';
+ keymap[GLFW_KEY_EQUAL] = '=';
+ keymap[GLFW_KEY_A] = 'A';
+ keymap[GLFW_KEY_B] = 'B';
+ keymap[GLFW_KEY_C] = 'C';
+ keymap[GLFW_KEY_D] = 'D';
+ keymap[GLFW_KEY_E] = 'E';
+ keymap[GLFW_KEY_F] = 'F';
+ keymap[GLFW_KEY_G] = 'G';
+ keymap[GLFW_KEY_H] = 'H';
+ keymap[GLFW_KEY_I] = 'I';
+ keymap[GLFW_KEY_J] = 'J';
+ keymap[GLFW_KEY_K] = 'K';
+ keymap[GLFW_KEY_L] = 'L';
+ keymap[GLFW_KEY_M] = 'M';
+ keymap[GLFW_KEY_N] = 'N';
+ keymap[GLFW_KEY_O] = 'O';
+ keymap[GLFW_KEY_P] = 'P';
+ keymap[GLFW_KEY_Q] = 'Q';
+ keymap[GLFW_KEY_R] = 'R';
+ keymap[GLFW_KEY_S] = 'S';
+ keymap[GLFW_KEY_T] = 'T';
+ keymap[GLFW_KEY_U] = 'U';
+ keymap[GLFW_KEY_V] = 'V';
+ keymap[GLFW_KEY_W] = 'W';
+ keymap[GLFW_KEY_X] = 'X';
+ keymap[GLFW_KEY_Y] = 'Y';
+ keymap[GLFW_KEY_Z] = 'Z';
+ keymap[GLFW_KEY_LEFT_BRACKET] = '[';
+ keymap[GLFW_KEY_BACKSLASH] = '\\';
+ keymap[GLFW_KEY_RIGHT_BRACKET] = ']';
+ keymap[GLFW_KEY_GRAVE_ACCENT] = '`';
+ keymap[GLFW_KEY_ESCAPE] = rsESC;
+ keymap[GLFW_KEY_ENTER] = rsENTER;
+ keymap[GLFW_KEY_TAB] = rsTAB;
+ keymap[GLFW_KEY_BACKSPACE] = rsBACKSP;
+ keymap[GLFW_KEY_INSERT] = rsINS;
+ keymap[GLFW_KEY_DELETE] = rsDEL;
+ keymap[GLFW_KEY_RIGHT] = rsRIGHT;
+ keymap[GLFW_KEY_LEFT] = rsLEFT;
+ keymap[GLFW_KEY_DOWN] = rsDOWN;
+ keymap[GLFW_KEY_UP] = rsUP;
+ keymap[GLFW_KEY_PAGE_UP] = rsPGUP;
+ keymap[GLFW_KEY_PAGE_DOWN] = rsPGDN;
+ keymap[GLFW_KEY_HOME] = rsHOME;
+ keymap[GLFW_KEY_END] = rsEND;
+ keymap[GLFW_KEY_CAPS_LOCK] = rsCAPSLK;
+ keymap[GLFW_KEY_SCROLL_LOCK] = rsSCROLL;
+ keymap[GLFW_KEY_NUM_LOCK] = rsNUMLOCK;
+ keymap[GLFW_KEY_PRINT_SCREEN] = rsNULL;
+ keymap[GLFW_KEY_PAUSE] = rsPAUSE;
+
+ keymap[GLFW_KEY_F1] = rsF1;
+ keymap[GLFW_KEY_F2] = rsF2;
+ keymap[GLFW_KEY_F3] = rsF3;
+ keymap[GLFW_KEY_F4] = rsF4;
+ keymap[GLFW_KEY_F5] = rsF5;
+ keymap[GLFW_KEY_F6] = rsF6;
+ keymap[GLFW_KEY_F7] = rsF7;
+ keymap[GLFW_KEY_F8] = rsF8;
+ keymap[GLFW_KEY_F9] = rsF9;
+ keymap[GLFW_KEY_F10] = rsF10;
+ keymap[GLFW_KEY_F11] = rsF11;
+ keymap[GLFW_KEY_F12] = rsF12;
+ keymap[GLFW_KEY_F13] = rsNULL;
+ keymap[GLFW_KEY_F14] = rsNULL;
+ keymap[GLFW_KEY_F15] = rsNULL;
+ keymap[GLFW_KEY_F16] = rsNULL;
+ keymap[GLFW_KEY_F17] = rsNULL;
+ keymap[GLFW_KEY_F18] = rsNULL;
+ keymap[GLFW_KEY_F19] = rsNULL;
+ keymap[GLFW_KEY_F20] = rsNULL;
+ keymap[GLFW_KEY_F21] = rsNULL;
+ keymap[GLFW_KEY_F22] = rsNULL;
+ keymap[GLFW_KEY_F23] = rsNULL;
+ keymap[GLFW_KEY_F24] = rsNULL;
+ keymap[GLFW_KEY_F25] = rsNULL;
+ keymap[GLFW_KEY_KP_0] = rsPADINS;
+ keymap[GLFW_KEY_KP_1] = rsPADEND;
+ keymap[GLFW_KEY_KP_2] = rsPADDOWN;
+ keymap[GLFW_KEY_KP_3] = rsPADPGDN;
+ keymap[GLFW_KEY_KP_4] = rsPADLEFT;
+ keymap[GLFW_KEY_KP_5] = rsPAD5;
+ keymap[GLFW_KEY_KP_6] = rsPADRIGHT;
+ keymap[GLFW_KEY_KP_7] = rsPADHOME;
+ keymap[GLFW_KEY_KP_8] = rsPADUP;
+ keymap[GLFW_KEY_KP_9] = rsPADPGUP;
+ keymap[GLFW_KEY_KP_DECIMAL] = rsPADDEL;
+ keymap[GLFW_KEY_KP_DIVIDE] = rsDIVIDE;
+ keymap[GLFW_KEY_KP_MULTIPLY] = rsTIMES;
+ keymap[GLFW_KEY_KP_SUBTRACT] = rsMINUS;
+ keymap[GLFW_KEY_KP_ADD] = rsPLUS;
+ keymap[GLFW_KEY_KP_ENTER] = rsPADENTER;
+ keymap[GLFW_KEY_KP_EQUAL] = rsNULL;
+ keymap[GLFW_KEY_LEFT_SHIFT] = rsLSHIFT;
+ keymap[GLFW_KEY_LEFT_CONTROL] = rsLCTRL;
+ keymap[GLFW_KEY_LEFT_ALT] = rsLALT;
+ keymap[GLFW_KEY_LEFT_SUPER] = rsLWIN;
+ keymap[GLFW_KEY_RIGHT_SHIFT] = rsRSHIFT;
+ keymap[GLFW_KEY_RIGHT_CONTROL] = rsRCTRL;
+ keymap[GLFW_KEY_RIGHT_ALT] = rsRALT;
+ keymap[GLFW_KEY_RIGHT_SUPER] = rsRWIN;
+ keymap[GLFW_KEY_MENU] = rsNULL;
+}
+
+bool lshiftStatus = false;
+bool rshiftStatus = false;
+
+void
+keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
+{
+ if (key >= 0 && key <= GLFW_KEY_LAST) {
+ RsKeyCodes ks = (RsKeyCodes)keymap[key];
+
+ if (key == GLFW_KEY_LEFT_SHIFT)
+ lshiftStatus = action != GLFW_RELEASE;
+
+ if (key == GLFW_KEY_RIGHT_SHIFT)
+ rshiftStatus = action != GLFW_RELEASE;
+
+ if (action == GLFW_RELEASE) RsKeyboardEventHandler(rsKEYUP, &ks);
+ else if (action == GLFW_PRESS) RsKeyboardEventHandler(rsKEYDOWN, &ks);
+ else if (action == GLFW_REPEAT) RsKeyboardEventHandler(rsKEYDOWN, &ks);
+ }
+}
+
+// R* calls that in ControllerConfig, idk why
+void
+_InputTranslateShiftKeyUpDown(RsKeyCodes *rs) {
+ RsKeyboardEventHandler(lshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsLSHIFT));
+ RsKeyboardEventHandler(rshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsRSHIFT));
+}
+
+// TODO this only works in frontend(and luckily only frontend use this), maybe because of glfw knows that mouse pos is > 32000 in game??
+void
+cursorCB(GLFWwindow* window, double xpos, double ypos) {
+ FrontEndMenuManager.m_nMouseTempPosX = xpos;
+ FrontEndMenuManager.m_nMouseTempPosY = ypos;
+}
+
+void _InputInitialiseJoys()
+{
+ for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
+ if (glfwJoystickPresent(i)) {
+ if (PSGLOBAL(joy1id) == -1)
+ PSGLOBAL(joy1id) = i;
+ else if (PSGLOBAL(joy2id) == -1)
+ PSGLOBAL(joy2id) = i;
+ else
+ break;
+ }
+ }
+
+ if (PSGLOBAL(joy1id) != -1) {
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ }
+}
+
+void _InputInitialiseMouse()
+{
+ glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+}
+
+/*
+ *****************************************************************************
+ */
+int PASCAL
+WinMain(HINSTANCE instance,
+ HINSTANCE prevInstance __RWUNUSED__,
+ CMDSTR cmdLine,
+ int cmdShow)
+{
+ RwV2d pos;
+ RwInt32 argc, i;
+ RwChar** argv;
+ StaticPatcher::Apply();
+ SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
+
+ /*
+ * Initialize the platform independent data.
+ * This will in turn initialize the platform specific data...
+ */
+ if( RsEventHandler(rsINITIALISE, nil) == rsEVENTERROR )
+ {
+ return FALSE;
+ }
+
+
+ /*
+ * Get proper command line params, cmdLine passed to us does not
+ * work properly under all circumstances...
+ */
+ cmdLine = GetCommandLine();
+
+ /*
+ * Parse command line into standard (argv, argc) parameters...
+ */
+ argv = CommandLineToArgv(cmdLine, &argc);
+
+
+ /*
+ * Parse command line parameters (except program name) one at
+ * a time BEFORE RenderWare initialization...
+ */
+ for(i=1; i<argc; i++)
+ {
+ RsEventHandler(rsPREINITCOMMANDLINE, argv[i]);
+ }
+
+ /*
+ * Parameters to be used in RwEngineOpen / rsRWINITIALISE event
+ */
+
+ openParams.width = RsGlobal.maximumWidth;
+ openParams.height = RsGlobal.maximumHeight;
+ openParams.windowtitle = RsGlobal.appName;
+
+ ControlsManager.MakeControllerActionsBlank();
+ ControlsManager.InitDefaultControlConfiguration();
+
+ /*
+ * Initialize the 3D (RenderWare) components of the app...
+ */
+ if( rsEVENTERROR == RsEventHandler(rsRWINITIALISE, &PSGLOBAL(window)) )
+ {
+ RsEventHandler(rsTERMINATE, nil);
+
+ return 0;
+ }
+
+ _InputInitialiseJoys();
+ _InputInitialiseMouse();
+ ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
+
+ glfwSetWindowPos(PSGLOBAL(window), 0, 0);
+
+ /*
+ * Parse command line parameters (except program name) one at
+ * a time AFTER RenderWare initialization...
+ */
+ for(i=1; i<argc; i++)
+ {
+ RsEventHandler(rsCOMMANDLINE, argv[i]);
+ }
+
+ /*
+ * Force a camera resize event...
+ */
+ {
+ RwRect r;
+
+ r.x = 0;
+ r.y = 0;
+ r.w = RsGlobal.maximumWidth;
+ r.h = RsGlobal.maximumHeight;
+
+ RsEventHandler(rsCAMERASIZE, &r);
+ }
+
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, nil, SPIF_SENDCHANGE);
+
+
+ STICKYKEYS SavedStickyKeys;
+ SavedStickyKeys.cbSize = sizeof(STICKYKEYS);
+
+ SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE);
+
+ STICKYKEYS NewStickyKeys;
+ NewStickyKeys.cbSize = sizeof(STICKYKEYS);
+ NewStickyKeys.dwFlags = SKF_TWOKEYSOFF;
+
+ SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &NewStickyKeys, SPIF_SENDCHANGE);
+
+
+ {
+ CFileMgr::SetDirMyDocuments();
+
+ int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+
+ if ( gta3set )
+ {
+ ControlsManager.LoadSettings(gta3set);
+ CFileMgr::CloseFile(gta3set);
+ }
+
+ CFileMgr::SetDir("");
+ }
+
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+
+#ifndef MASTER
+ if (TurnOnAnimViewer) {
+ CAnimViewer::Initialise();
+ FrontEndMenuManager.m_bGameNotLoaded = false;
+ gGameState = GS_ANIMVIEWER;
+ TurnOnAnimViewer = false;
+ }
+#endif
+
+ initkeymap();
+ glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
+ glfwSetWindowSizeCallback(PSGLOBAL(window), resizeCB);
+ glfwSetScrollCallback(PSGLOBAL(window), scrollCB);
+ glfwSetCursorPosCallback(PSGLOBAL(window), cursorCB);
+ glfwSetJoystickCallback(joysChangeCB);
+
+ while ( TRUE )
+ {
+ RwInitialised = TRUE;
+
+ /*
+ * Set the initial mouse position...
+ */
+ pos.x = RsGlobal.maximumWidth * 0.5f;
+ pos.y = RsGlobal.maximumHeight * 0.5f;
+
+ RsMouseSetPos(&pos);
+
+ /*
+ * Enter the message processing loop...
+ */
+
+ while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart && !glfwWindowShouldClose(PSGLOBAL(window)))
+ {
+ glfwPollEvents();
+ if( ForegroundApp )
+ {
+ switch ( gGameState )
+ {
+ case GS_START_UP:
+ {
+ gGameState = GS_INIT_ONCE;
+ TRACE("gGameState = GS_INIT_ONCE");
+ break;
+ }
+
+ case GS_INIT_ONCE:
+ {
+ CoUninitialize();
+
+ LoadingScreen(nil, nil, "loadsc0");
+
+ if ( !CGame::InitialiseOnceAfterRW() )
+ RsGlobal.quit = TRUE;
+
+ gGameState = GS_INIT_FRONTEND;
+ TRACE("gGameState = GS_INIT_FRONTEND;");
+ break;
+ }
+
+ case GS_INIT_FRONTEND:
+ {
+ LoadingScreen(nil, nil, "loadsc0");
+
+ FrontEndMenuManager.m_bGameNotLoaded = true;
+
+ CMenuManager::m_bStartUpFrontEndRequested = true;
+
+ if ( defaultFullscreenRes )
+ {
+ defaultFullscreenRes = FALSE;
+ FrontEndMenuManager.m_nPrefsVideoMode = GcurSelVM;
+ FrontEndMenuManager.m_nDisplayVideoMode = GcurSelVM;
+ }
+
+ gGameState = GS_FRONTEND;
+ TRACE("gGameState = GS_FRONTEND;");
+ break;
+ }
+
+ case GS_FRONTEND:
+ {
+ if(!glfwGetWindowAttrib(PSGLOBAL(window), GLFW_ICONIFIED))
+ RsEventHandler(rsFRONTENDIDLE, nil);
+
+ if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
+ {
+ gGameState = GS_INIT_PLAYING_GAME;
+ TRACE("gGameState = GS_INIT_PLAYING_GAME;");
+ }
+
+ if ( FrontEndMenuManager.m_bWantToLoad )
+ {
+ InitialiseGame();
+ FrontEndMenuManager.m_bGameNotLoaded = false;
+ gGameState = GS_PLAYING_GAME;
+ TRACE("gGameState = GS_PLAYING_GAME;");
+ }
+ break;
+ }
+
+ case GS_INIT_PLAYING_GAME:
+ {
+ InitialiseGame();
+ FrontEndMenuManager.m_bGameNotLoaded = false;
+ gGameState = GS_PLAYING_GAME;
+ TRACE("gGameState = GS_PLAYING_GAME;");
+ break;
+ }
+
+ case GS_PLAYING_GAME:
+ {
+ float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
+ if ( RwInitialised )
+ {
+ if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms)
+ RsEventHandler(rsIDLE, (void *)TRUE);
+ }
+ 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
+ {
+ if ( RwCameraBeginUpdate(Scene.camera) )
+ {
+ RwCameraEndUpdate(Scene.camera);
+ ForegroundApp = TRUE;
+ RsEventHandler(rsACTIVATE, (void *)TRUE);
+ }
+
+ }
+ }
+
+
+ /*
+ * About to shut down - block resize events again...
+ */
+ RwInitialised = FALSE;
+
+ FrontEndMenuManager.UnloadTextures();
+ if ( !FrontEndMenuManager.m_bWantToRestart )
+ break;
+
+ CPad::ResetCheats();
+ CPad::StopPadsShaking();
+
+ DMAudio.ChangeMusicMode(MUSICMODE_DISABLE);
+
+ CTimer::Stop();
+
+ if ( FrontEndMenuManager.m_bWantToLoad )
+ {
+ CGame::ShutDownForRestart();
+ CGame::InitialiseWhenRestarting();
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+ FrontEndMenuManager.m_bWantToLoad = false;
+ }
+ else
+ {
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
+ else if ( gGameState == GS_ANIMVIEWER )
+ CAnimViewer::Shutdown();
+
+ CTimer::Stop();
+
+ if ( FrontEndMenuManager.m_bFirstTime == true )
+ {
+ gGameState = GS_INIT_FRONTEND;
+ TRACE("gGameState = GS_INIT_FRONTEND;");
+ }
+ else
+ {
+ gGameState = GS_INIT_PLAYING_GAME;
+ TRACE("gGameState = GS_INIT_PLAYING_GAME;");
+ }
+ }
+
+ FrontEndMenuManager.m_bFirstTime = false;
+ FrontEndMenuManager.m_bWantToRestart = false;
+ }
+
+
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
+ else if ( gGameState == GS_ANIMVIEWER )
+ CAnimViewer::Shutdown();
+
+ DMAudio.Terminate();
+
+ _psFreeVideoModeList();
+
+
+ /*
+ * Tidy up the 3D (RenderWare) components of the application...
+ */
+ RsEventHandler(rsRWTERMINATE, nil);
+
+ /*
+ * Free the platform dependent data...
+ */
+ RsEventHandler(rsTERMINATE, nil);
+
+ /*
+ * Free the argv strings...
+ */
+ free(argv);
+
+ SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+
+ SetErrorMode(0);
+
+ return 0;
+}
+
+/*
+ *****************************************************************************
+ */
+
+RwV2d leftStickPos;
+RwV2d rightStickPos;
+
+void CapturePad(RwInt32 padID)
+{
+ int8 glfwPad = -1;
+
+ if( padID == 0 )
+ glfwPad = PSGLOBAL(joy1id);
+ else if( padID == 1)
+ glfwPad = PSGLOBAL(joy2id);
+ else
+ assert("invalid padID");
+
+ if ( glfwPad == -1 )
+ return;
+
+ int numButtons, numAxes;
+ const uint8 *buttons = glfwGetJoystickButtons(glfwPad, &numButtons);
+ const float *axes = glfwGetJoystickAxes(glfwPad, &numAxes);
+ GLFWgamepadstate gamepadState;
+
+ if (ControlsManager.m_bFirstCapture == false)
+ {
+ memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
+ }
+
+ ControlsManager.m_NewState.buttons = (uint8*)buttons;
+ ControlsManager.m_NewState.numButtons = numButtons;
+ ControlsManager.m_NewState.id = glfwPad;
+ ControlsManager.m_NewState.isGamepad = glfwJoystickIsGamepad(glfwPad);
+ if (ControlsManager.m_NewState.isGamepad) {
+ glfwGetGamepadState(glfwPad, &gamepadState);
+ memcpy(&ControlsManager.m_NewState.mappedButtons, gamepadState.buttons, sizeof(gamepadState.buttons));
+ ControlsManager.m_NewState.mappedButtons[15] = gamepadState.axes[4] > -0.8f;
+ ControlsManager.m_NewState.mappedButtons[16] = gamepadState.axes[5] > -0.8f;
+ }
+ // TODO I'm not sure how to find/what to do with L2-R2, if joystick isn't registered in SDL database.
+
+ if (ControlsManager.m_bFirstCapture == true) {
+ memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
+
+ ControlsManager.m_bFirstCapture = false;
+ }
+
+ RsPadButtonStatus bs;
+ bs.padID = padID;
+
+ RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
+
+ // Gamepad axes are guaranteed to return 0.0f if that particular gamepad doesn't have that axis.
+ if ( glfwPad != -1 ) {
+ leftStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[0] : numAxes >= 0 ? axes[0] : 0.0f;
+ leftStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[1] : numAxes >= 1 ? axes[1] : 0.0f;
+
+ rightStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[2] : numAxes >= 2 ? axes[2] : 0.0f;
+ rightStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[3] : numAxes >= 3 ? axes[3] : 0.0f;
+ }
+
+ {
+ if (CPad::m_bMapPadOneToPadTwo)
+ bs.padID = 1;
+
+ RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
+ RsPadEventHandler(rsPADBUTTONDOWN, (void *)&bs);
+ }
+
+ {
+ if (CPad::m_bMapPadOneToPadTwo)
+ bs.padID = 1;
+
+ CPad *pad = CPad::GetPad(bs.padID);
+
+ if ( Abs(leftStickPos.x) > 0.3f )
+ pad->PCTempJoyState.LeftStickX = (int32)(leftStickPos.x * 128.0f);
+
+ if ( Abs(leftStickPos.y) > 0.3f )
+ pad->PCTempJoyState.LeftStickY = (int32)(leftStickPos.y * 128.0f);
+
+ if ( Abs(rightStickPos.x) > 0.3f )
+ pad->PCTempJoyState.RightStickX = (int32)(rightStickPos.x * 128.0f);
+
+ if ( Abs(rightStickPos.y) > 0.3f )
+ pad->PCTempJoyState.RightStickY = (int32)(rightStickPos.y * 128.0f);
+ }
+
+ return;
+}
+
+void joysChangeCB(int jid, int event)
+{
+ if (event == GLFW_CONNECTED)
+ {
+ if (PSGLOBAL(joy1id) == -1)
+ PSGLOBAL(joy1id) = jid;
+ else if (PSGLOBAL(joy2id) == -1)
+ PSGLOBAL(joy2id) = jid;
+ }
+ else if (event == GLFW_DISCONNECTED)
+ {
+ if (PSGLOBAL(joy1id) == jid)
+ PSGLOBAL(joy1id) = -1;
+ else if (PSGLOBAL(joy2id) == jid)
+ PSGLOBAL(joy2id) = -1;
+ }
+}
+
+#if (defined(_MSC_VER))
+int strcasecmp(const char* str1, const char* str2)
+{
+ return _strcmpi(str1, str2);
+}
+#endif
+#endif \ No newline at end of file
diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp
index 73dd8bf8..b5ce744a 100644
--- a/src/skel/skeleton.cpp
+++ b/src/skel/skeleton.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include <stdio.h>
#include <math.h>
@@ -17,8 +17,7 @@ static RwBool DefaultVideoMode = TRUE;
bool TurnOnAnimViewer = false;
-//RsGlobalType RsGlobal;
-RsGlobalType &RsGlobal = *(RsGlobalType*)0x8F4360;
+RsGlobalType RsGlobal;
RwUInt32
RsTimer(void)
@@ -294,7 +293,7 @@ RwBool
RsRwInitialise(void *displayID)
{
RwEngineOpenParams openParams;
-
+
/*
* Start RenderWare...
*/
@@ -416,26 +415,3 @@ RsInitialise(void)
return result;
}
-
-
-
-
-STARTPATCHES
- InjectHook(0x584890, RsTimer, PATCH_JUMP);
- InjectHook(0x5848A0, RsCameraShowRaster, PATCH_JUMP);
- InjectHook(0x5848B0, RsCameraBeginUpdate, PATCH_JUMP);
- InjectHook(0x5848C0, RsRegisterImageLoader, PATCH_JUMP);
- InjectHook(0x5848D0, RsSetDebug, PATCH_JUMP);
- InjectHook(0x5848E0, RsMouseSetPos, PATCH_JUMP);
- InjectHook(0x5848F0, RsSelectDevice, PATCH_JUMP);
- InjectHook(0x584900, RsInputDeviceAttach, PATCH_JUMP);
- InjectHook(0x584960, rsCommandLine, PATCH_JUMP);
- InjectHook(0x584980, rsPreInitCommandLine, PATCH_JUMP);
- InjectHook(0x5849C0, RsKeyboardEventHandler, PATCH_JUMP);
- InjectHook(0x5849F0, RsPadEventHandler, PATCH_JUMP);
- InjectHook(0x584A20, RsEventHandler, PATCH_JUMP);
- InjectHook(0x584B30, RsRwTerminate, PATCH_JUMP);
- InjectHook(0x584B40, RsRwInitialise, PATCH_JUMP);
- InjectHook(0x584C30, RsTerminate, PATCH_JUMP);
- InjectHook(0x584C40, RsInitialise, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h
index 6bf8d2fd..13588411 100644
--- a/src/skel/skeleton.h
+++ b/src/skel/skeleton.h
@@ -232,7 +232,7 @@ enum RsPadButtons
typedef enum RsPadButtons RsPadButtons;
-extern RsGlobalType &RsGlobal;
+extern RsGlobalType RsGlobal;
extern RsEventStatus AppEventHandler(RsEvent event, void *param);
extern RwBool AttachInputDevices(void);
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index ec84e968..e623defb 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -1,3 +1,5 @@
+#if defined RW_D3D9 || defined RWLIBS
+
#define _WIN32_WINDOWS 0x0500
#define WINVER 0x0500
#define DIRECTINPUT_VERSION 0x0800
@@ -40,36 +42,30 @@
#include "resource.h"
#include "skeleton.h"
#include "platform.h"
-#include "win.h"
+#include "crossplatform.h"
#define MAX_SUBSYSTEMS (16)
-//static RwBool ForegroundApp = TRUE;
-static RwBool &ForegroundApp = *(RwBool*)0x060F000;
+static RwBool ForegroundApp = TRUE;
-//static RwBool RwInitialised = FALSE;
-static RwBool &RwInitialised = *(RwBool*)0x885B88;
+static RwBool RwInitialised = FALSE;
static RwSubSystemInfo GsubSysInfo[MAX_SUBSYSTEMS];
static RwInt32 GnumSubSystems = 0;
static RwInt32 GcurSel = 0, GcurSelVM = 0;
-//static RwBool startupDeactivate;
-static RwBool &startupDeactivate = *(RwBool*)0x8E2878;
+static RwBool startupDeactivate;
-//static RwBool useDefault;
-static RwBool &useDefault = *(RwBool*)0x6510D4;
+static RwBool useDefault;
-//static RwBool defaultFullscreenRes = TRUE;
-static RwBool &defaultFullscreenRes = *(RwBool*)0x60EFFC;
+static RwBool defaultFullscreenRes = TRUE;
/* Class name for the MS Window's window class. */
static const RwChar *AppClassName = RWSTRING("Grand theft auto 3");
-//static psGlobalType PsGlobal;
-static psGlobalType &PsGlobal = *(psGlobalType*)0x72CF60;
+static psGlobalType PsGlobal;
#define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var)
@@ -107,14 +103,14 @@ IMediaSeeking *pMS = nil;
DWORD dwDXVersion;
DWORD _dwMemTotalPhys;
-DWORD &_dwMemAvailPhys = *(DWORD*)0x70F29C;
+DWORD _dwMemAvailPhys;
DWORD _dwMemTotalVirtual;
DWORD _dwMemAvailVirtual;
-DWORD &_dwMemTotalVideo = *(DWORD*)0x70F2A8;
+DWORD _dwMemTotalVideo;
DWORD _dwMemAvailVideo;
-DWORD &_dwOperatingSystemVersion = *(DWORD*)0x70F290;
+DWORD _dwOperatingSystemVersion;
-RwUInt32 &gGameState = *(RwUInt32*)0x8F5838;
+RwUInt32 gGameState;
CJoySticks AllValidWinJoys;
CJoySticks::CJoySticks()
@@ -679,11 +675,17 @@ psInitialise(void)
_dwMemAvailVirtual = memstats.dwAvailVirtual;
_GetVideoMemInfo(&_dwMemTotalVideo, &_dwMemAvailVideo);
-
+#ifdef FIX_BUGS
+ debug("Physical memory size %u\n", _dwMemTotalPhys);
+ debug("Available physical memory %u\n", _dwMemAvailPhys);
+ debug("Video memory size %u\n", _dwMemTotalVideo);
+ debug("Available video memory %u\n", _dwMemAvailVideo);
+#else
debug("Physical memory size %d\n", _dwMemTotalPhys);
debug("Available physical memory %d\n", _dwMemAvailPhys);
debug("Video memory size %d\n", _dwMemTotalVideo);
debug("Available video memory %d\n", _dwMemAvailVideo);
+#endif
if ( _dwMemAvailVideo < (12 * 1024 * 1024) /*12 MB*/ )
{
@@ -1321,12 +1323,23 @@ psSelectDevice()
}
else
{
+#ifdef DEFAULT_NATIVE_RESOLUTION
+ // get the native video mode
+ HDC hDevice = GetDC(NULL);
+ int w = GetDeviceCaps(hDevice, HORZRES);
+ int h = GetDeviceCaps(hDevice, VERTRES);
+ int d = GetDeviceCaps(hDevice, BITSPIXEL);
+#else
+ const int w = 640;
+ const int h = 480;
+ const int d = 16;
+#endif
while ( !modeFound && GcurSelVM < RwEngineGetNumVideoModes() )
{
RwEngineGetVideoModeInfo(&vm, GcurSelVM);
- if ( defaultFullscreenRes && vm.width != 640
- || vm.height != 480
- || vm.depth != 16
+ if ( defaultFullscreenRes && vm.width != w
+ || vm.height != h
+ || vm.depth != d
|| !(vm.flags & rwVIDEOMODEEXCLUSIVE) )
++GcurSelVM;
else
@@ -1335,8 +1348,12 @@ psSelectDevice()
if ( !modeFound )
{
+#ifdef DEFAULT_NATIVE_RESOLUTION
+ GcurSelVM = 1;
+#else
MessageBox(nil, "Cannot find 640x480 video mode", "GTA3", MB_OK);
return FALSE;
+#endif
}
}
}
@@ -1351,7 +1368,7 @@ psSelectDevice()
{
return FALSE;
}
-
+
if (vm.flags & rwVIDEOMODEEXCLUSIVE)
{
debug("%dx%dx%d", vm.width, vm.height, vm.depth);
@@ -1739,7 +1756,7 @@ void HandleExit()
*****************************************************************************
*/
int PASCAL
-_WinMain(HINSTANCE instance,
+WinMain(HINSTANCE instance,
HINSTANCE prevInstance __RWUNUSED__,
CMDSTR cmdLine,
int cmdShow)
@@ -1748,9 +1765,17 @@ _WinMain(HINSTANCE instance,
RwV2d pos;
RwInt32 argc, i;
RwChar **argv;
-
+ StaticPatcher::Apply();
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
+/*
+ // TODO: make this an option somewhere
+ AllocConsole();
+ freopen("CONIN$", "r", stdin);
+ freopen("CONOUT$", "w", stdout);
+ freopen("CONOUT$", "w", stderr);
+*/
+
/*
* Initialize the platform independent data.
* This will in turn initialize the platform specific data...
@@ -1971,7 +1996,7 @@ _WinMain(HINSTANCE instance,
++gGameState;
else if ( CPad::GetPad(0)->GetEnterJustDown() )
++gGameState;
- else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) )
+ else if ( CPad::GetPad(0)->GetCharJustDown(' ') )
++gGameState;
else if ( CPad::GetPad(0)->GetAltJustDown() )
++gGameState;
@@ -2007,7 +2032,7 @@ _WinMain(HINSTANCE instance,
++gGameState;
else if ( CPad::GetPad(0)->GetEnterJustDown() )
++gGameState;
- else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) )
+ else if ( CPad::GetPad(0)->GetCharJustDown(' ') )
++gGameState;
else if ( CPad::GetPad(0)->GetAltJustDown() )
++gGameState;
@@ -3010,60 +3035,4 @@ int strcasecmp(const char *str1, const char *str2)
return _strcmpi(str1, str2);
}
#endif
-
-
-STARTPATCHES
- //InjectHook(0x580B30, &CJoySticks::CJoySticks, PATCH_JUMP);
- //InjectHook(0x580B50, &CJoySticks::ClearJoyInfo, PATCH_JUMP);
- InjectHook(0x580B70, _psCreateFolder, PATCH_JUMP);
- InjectHook(0x580BB0, _psGetUserFilesFolder, PATCH_JUMP);
- InjectHook(0x580C70, psCameraBeginUpdate, PATCH_JUMP);
- InjectHook(0x580CA0, psCameraShowRaster, PATCH_JUMP);
- InjectHook(0x580CE0, psTimer, PATCH_JUMP);
- InjectHook(0x580D20, psMouseSetPos, PATCH_JUMP);
- InjectHook(0x580E10, psGetMemoryFunctions, PATCH_JUMP);
- InjectHook(0x580E20, psInstallFileSystem, PATCH_JUMP);
- InjectHook(0x580E30, psNativeTextureSupport, PATCH_JUMP);
- InjectHook(0x580E40, InitApplication, PATCH_JUMP);
- InjectHook(0x580EB0, InitInstance, PATCH_JUMP);
- InjectHook(0x580F30, _GetVideoMemInfo, PATCH_JUMP);
- InjectHook(0x580FA0, GetDXVersion, PATCH_JUMP);
- InjectHook(0x5810C0, _psGetCpuVendr, PATCH_JUMP);
- InjectHook(0x5810E0, _psGetCpuFeatures, PATCH_JUMP);
- InjectHook(0x5810F0, _psGetCpuFeaturesEx, PATCH_JUMP);
- InjectHook(0x581120, _psPrintCpuInfo, PATCH_JUMP);
- InjectHook(0x581180, psInitialise, PATCH_JUMP);
- InjectHook(0x581460, psTerminate, PATCH_JUMP);
- InjectHook(0x581470, _psGetNumVideModes, PATCH_JUMP);
- InjectHook(0x581480, _psFreeVideoModeList, PATCH_JUMP);
- InjectHook(0x5814F0, _psGetVideoModeList, PATCH_JUMP);
- InjectHook(0x581630, _psSelectScreenVM, PATCH_JUMP);
- InjectHook(0x5816B0, WaitForState, PATCH_JUMP);
- InjectHook(0x5816E0, HandleGraphEvent, PATCH_JUMP);
- InjectHook(0x581790, MainWndProc, PATCH_JUMP);
- InjectHook(0x581C90, IsForegroundApp, PATCH_JUMP);
- InjectHook(0x581CB0, GetBestRefreshRate, PATCH_JUMP);
- InjectHook(0x581D80, psSelectDevice, PATCH_JUMP);
- InjectHook(0x581F90, _psSetVideoMode, PATCH_JUMP);
- InjectHook(0x582030, CommandLineToArgv, PATCH_JUMP);
- InjectHook(0x582160, InitialiseLanguage, PATCH_JUMP);
- InjectHook(0x5822F0, CenterVideo, PATCH_JUMP);
- InjectHook(0x582380, PlayMovieInWindow, PATCH_JUMP);
- InjectHook(0x5825E0, CloseInterfaces, PATCH_JUMP);
- InjectHook(0x582680, CloseClip, PATCH_JUMP);
- InjectHook(0x5826A0, HandleExit, PATCH_JUMP);
- InjectHook(0x582710, _WinMain, PATCH_JUMP);
- InjectHook(0x5830D0, _InputInitialise, PATCH_JUMP);
- InjectHook(0x583110, _InputInitialiseMouse, PATCH_JUMP);
- InjectHook(0x583190, CapturePad, PATCH_JUMP);
- InjectHook(0x583580, _InputInitialiseJoys, PATCH_JUMP);
- InjectHook(0x583670, _InputAddJoyStick, PATCH_JUMP);
- InjectHook(0x583810, _InputAddJoys, PATCH_JUMP);
- InjectHook(0x583870, _InputGetMouseState, PATCH_JUMP);
- InjectHook(0x583910, _InputShutdown, PATCH_JUMP);
- InjectHook(0x583940, _InputEnumDevicesCallback, PATCH_JUMP);
- InjectHook(0x583A20, _InputTranslateKey, PATCH_JUMP);
- InjectHook(0x583DC0, _InputTranslateShiftKeyUpDown, PATCH_JUMP);
- InjectHook(0x583E50, _InputTranslateShiftKey, PATCH_JUMP);
- InjectHook(0x583EE0, _InputIsExtended, PATCH_JUMP);
-ENDPATCHES
+#endif \ No newline at end of file
diff --git a/src/skel/win/win.h b/src/skel/win/win.h
index 242438ea..d05e3951 100644
--- a/src/skel/win/win.h
+++ b/src/skel/win/win.h
@@ -1,3 +1,6 @@
+
+// DON'T include directly. crossplatform.h includes this if you're on Windows.
+
#if (!defined(_PLATFORM_WIN_H))
#define _PLATFORM_WIN_H
@@ -5,20 +8,10 @@
#define RSREGSETBREAKALLOC(_name) /* No op */
#endif /* (!defined(RSREGSETBREAKALLOC)) */
-enum eGameState
-{
- GS_START_UP = 0,
- GS_INIT_LOGO_MPEG,
- GS_LOGO_MPEG,
- GS_INIT_INTRO_MPEG,
- GS_INTRO_MPEG,
- GS_INIT_ONCE,
- GS_INIT_FRONTEND,
- GS_FRONTEND,
- GS_INIT_PLAYING_GAME,
- GS_PLAYING_GAME,
- GS_ANIMVIEWER,
-};
+#ifndef _INC_WINDOWS
+#define _X86_
+#include <windef.h>
+#endif
enum eWinVersion
{
@@ -29,10 +22,9 @@ enum eWinVersion
OS_WINXP,
};
-extern DWORD &_dwOperatingSystemVersion;
-
-extern RwUInt32 &gGameState;
+extern DWORD _dwOperatingSystemVersion;
+#ifdef __DINPUT_INCLUDED__
/* platform specfic global data */
typedef struct
{
@@ -71,7 +63,6 @@ struct tJoy
bool m_bInitialised;
bool m_bHasAxisZ;
bool m_bHasAxisR;
- char _pad0;
int m_nVendorID;
int m_nProductID;
};
@@ -86,17 +77,17 @@ public:
};
extern CJoySticks AllValidWinJoys;
+#endif
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
+#ifdef __DINPUT_INCLUDED__
extern LRESULT CALLBACK
MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
-RwBool IsForegroundApp();
-
HRESULT _InputInitialise();
HRESULT _InputInitialiseMouse();
HRESULT CapturePad(RwInt32 padID);
@@ -107,25 +98,15 @@ HRESULT _InputGetMouseState(DIMOUSESTATE2 *state);
void _InputShutdown();
BOOL CALLBACK _InputEnumDevicesCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );
BOOL _InputTranslateKey(RsKeyCodes *rs, UINT flag, UINT key);
-void _InputTranslateShiftKeyUpDown(RsKeyCodes *rs);;
BOOL _InputTranslateShiftKey(RsKeyCodes *rs, UINT key, BOOLEAN bDown);
BOOL _InputIsExtended(INT flag);
+#endif
-void InitialiseLanguage();
-RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode);
void CenterVideo(void);
void CloseClip(void);
-RwChar **_psGetVideoModeList();
-RwInt32 _psGetNumVideModes();
-
-void _psSelectScreenVM(RwInt32 videoMode);
-void HandleExit();
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
-
-extern DWORD &_dwOperatingSystemVersion;
#endif /* (!defined(_PLATFORM_WIN_H)) */
diff --git a/src/text/Messages.cpp b/src/text/Messages.cpp
index d429ee8a..8a667adb 100644
--- a/src/text/Messages.cpp
+++ b/src/text/Messages.cpp
@@ -1,8 +1,5 @@
-#define DIRECTINPUT_VERSION 0x0800
-#include "dinput.h"
-
#include "common.h"
-#include "patcher.h"
+
#include "Messages.h"
#include "RwHelper.h"
#include "Hud.h"
@@ -14,9 +11,9 @@
#include "Font.h"
-tMessage(&CMessages::BriefMessages)[NUMBRIEFMESSAGES] = *(tMessage(*)[NUMBRIEFMESSAGES])*(uintptr*)0x8786E0;
-tPreviousBrief(&CMessages::PreviousBriefs)[NUMPREVIOUSBRIEFS] = *(tPreviousBrief(*)[NUMPREVIOUSBRIEFS])*(uintptr*)0x713C08;
-tBigMessage(&CMessages::BIGMessages)[NUMBIGMESSAGES] = *(tBigMessage(*)[NUMBIGMESSAGES])*(uintptr*)0x773628;
+tMessage CMessages::BriefMessages[NUMBRIEFMESSAGES];
+tPreviousBrief CMessages::PreviousBriefs[NUMPREVIOUSBRIEFS];
+tBigMessage CMessages::BIGMessages[NUMBIGMESSAGES];
char CMessages::PreviousMissionTitle[16]; // unused
void
@@ -819,33 +816,3 @@ CMessages::ClearAllMessagesDisplayedByGame()
CHud::GetRidOfAllHudMessages();
CUserDisplay::Pager.ClearMessages();
}
-
-STARTPATCHES
- InjectHook(0x529310, CMessages::Init, PATCH_JUMP);
- InjectHook(0x529490, CMessages::GetWideStringLength, PATCH_JUMP);
- InjectHook(0x5294B0, CMessages::WideStringCopy, PATCH_JUMP);
- InjectHook(0x529510, CMessages::WideStringCompare, PATCH_JUMP);
- InjectHook(0x529580, CMessages::Process, PATCH_JUMP);
- InjectHook(0x529800, CMessages::Display, PATCH_JUMP);
- InjectHook(0x529900, CMessages::AddMessage, PATCH_JUMP);
- InjectHook(0x529A10, CMessages::AddMessageJumpQ, PATCH_JUMP);
- InjectHook(0x529AF0, CMessages::AddMessageSoon, PATCH_JUMP);
- InjectHook(0x529CE0, CMessages::ClearMessages, PATCH_JUMP);
- InjectHook(0x529E00, CMessages::ClearSmallMessagesOnly, PATCH_JUMP);
- InjectHook(0x529EB0, CMessages::AddBigMessage, PATCH_JUMP);
- InjectHook(0x529F60, CMessages::AddBigMessageQ, PATCH_JUMP);
- InjectHook(0x52A040, CMessages::AddToPreviousBriefArray, PATCH_JUMP);
- InjectHook(0x52A1A0, CMessages::InsertNumberInString, PATCH_JUMP);
- InjectHook(0x52A300, CMessages::InsertStringInString, PATCH_JUMP);
- InjectHook(0x52A490, CMessages::InsertPlayerControlKeysInString, PATCH_JUMP);
- InjectHook(0x52A850, CMessages::AddMessageWithNumber, PATCH_JUMP);
- InjectHook(0x52A9A0, CMessages::AddMessageJumpQWithNumber, PATCH_JUMP);
- InjectHook(0x52AAC0, CMessages::AddMessageSoonWithNumber, PATCH_JUMP);
- InjectHook(0x52AD10, CMessages::AddBigMessageWithNumber, PATCH_JUMP);
- InjectHook(0x52AE00, CMessages::AddBigMessageWithNumberQ, PATCH_JUMP);
- InjectHook(0x52AF30, CMessages::AddMessageWithString, PATCH_JUMP);
- InjectHook(0x52B050, CMessages::AddMessageJumpQWithString, PATCH_JUMP);
- InjectHook(0x52B140, CMessages::ClearThisPrint, PATCH_JUMP);
- InjectHook(0x52B3C0, CMessages::ClearThisBigPrint, PATCH_JUMP);
- InjectHook(0x52B670, CMessages::ClearAllMessagesDisplayedByGame, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/text/Messages.h b/src/text/Messages.h
index 8044c626..e8ba1bf7 100644
--- a/src/text/Messages.h
+++ b/src/text/Messages.h
@@ -29,9 +29,9 @@ struct tPreviousBrief
class CMessages
{
public:
- static tMessage(&BriefMessages)[NUMBRIEFMESSAGES];
- static tBigMessage(&BIGMessages)[NUMBIGMESSAGES];
- static tPreviousBrief(&PreviousBriefs)[NUMPREVIOUSBRIEFS];
+ static tMessage BriefMessages[NUMBRIEFMESSAGES];
+ static tBigMessage BIGMessages[NUMBIGMESSAGES];
+ static tPreviousBrief PreviousBriefs[NUMPREVIOUSBRIEFS];
static char PreviousMissionTitle[16]; // unused
public:
static void Init(void);
diff --git a/src/text/Pager.cpp b/src/text/Pager.cpp
index 5c6b3ee2..609c6860 100644
--- a/src/text/Pager.cpp
+++ b/src/text/Pager.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Pager.h"
#include "Timer.h"
#include "Messages.h"
@@ -98,7 +98,7 @@ CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
m_messages[i].m_pText = str;
m_messages[i].m_nSpeedMs = speed;
m_messages[i].m_nPriority = priority;
- m_messages[i].field_10 = a5;
+ m_messages[i].unused = a5;
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
m_messages[i].m_nStringLength = size;
@@ -142,7 +142,7 @@ CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4,
m_messages[i].m_pText = str;
m_messages[i].m_nSpeedMs = speed;
m_messages[i].m_nPriority = priority;
- m_messages[i].field_10 = a11;
+ m_messages[i].unused = a11;
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
m_messages[i].m_nStringLength = size;
@@ -181,14 +181,4 @@ CPager::RestartCurrentMessage()
m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
}
-}
-
-STARTPATCHES
- InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
- InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
- InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
- InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
- InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
- InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
- InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/text/Pager.h b/src/text/Pager.h
index a628be6f..16307971 100644
--- a/src/text/Pager.h
+++ b/src/text/Pager.h
@@ -7,7 +7,7 @@ struct PagerMessage {
uint16 m_nStringLength;
uint16 m_nPriority;
uint32 m_nTimeToChangePosition;
- int16 field_10;
+ int16 unused; // but still set in SCM. importance? ringtone?
int32 m_nNumber[6];
};
diff --git a/src/text/Text.cpp b/src/text/Text.cpp
index ca98c2a5..117ba9cf 100644
--- a/src/text/Text.cpp
+++ b/src/text/Text.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "FileMgr.h"
#include "Frontend.h"
#include "Messages.h"
@@ -7,7 +7,7 @@
static wchar WideErrorString[25];
-CText &TheText = *(CText*)0x941520;
+CText TheText;
CText::CText(void)
{
@@ -44,6 +44,9 @@ CText::Load(void)
sprintf(filename, "SPANISH.GXT");
break;
#ifdef MORE_LANGUAGES
+ case LANGUAGE_POLISH:
+ sprintf(filename, "POLISH.GXT");
+ break;
case LANGUAGE_RUSSIAN:
sprintf(filename, "RUSSIAN.GXT");
break;
@@ -311,21 +314,4 @@ TextCopy(wchar *dst, const wchar *src)
}
-STARTPATCHES
- InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
- InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
- InjectHook(0x52C5A0, &CText::Get, PATCH_JUMP);
- InjectHook(0x52C220, &CText::GetUpperCase, PATCH_JUMP);
- InjectHook(0x52C2C0, &CText::UpperCase, PATCH_JUMP);
-
- InjectHook(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
- InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);
- InjectHook(0x52BF80, &CKeyArray::Update, PATCH_JUMP);
- InjectHook(0x52C060, &CKeyArray::BinarySearch, PATCH_JUMP);
- InjectHook(0x52BFB0, &CKeyArray::Search, PATCH_JUMP);
-
- InjectHook(0x52C120, &CData::Load, PATCH_JUMP);
- InjectHook(0x52C200, &CData::Unload, PATCH_JUMP);
-
- InjectHook(0x52C2F0, &UnicodeToAscii, PATCH_JUMP);
-ENDPATCHES
+ InjectHook(0x52C2F0, &UnicodeToAscii, PATCH_JUMP); \ No newline at end of file
diff --git a/src/text/Text.h b/src/text/Text.h
index 6f39ba49..00d1c5e6 100644
--- a/src/text/Text.h
+++ b/src/text/Text.h
@@ -56,4 +56,4 @@ public:
void UpperCase(wchar *s);
};
-extern CText &TheText;
+extern CText TheText;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 257c8d33..74609e15 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "General.h"
#include "RwHelper.h"
#include "Pad.h"
@@ -49,7 +49,7 @@ bool bAllCarCheat; // unused
RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data);
-bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21;
+bool CAutomobile::m_sAllTaxiLights;
CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
@@ -356,7 +356,7 @@ CAutomobile::ProcessControl(void)
PruneReferences();
- if(m_status == STATUS_PLAYER && CRecordDataForChase::IsRecording())
+ if(m_status == STATUS_PLAYER && !CRecordDataForChase::IsRecording())
DoDriveByShootings();
}
break;
@@ -562,7 +562,7 @@ CAutomobile::ProcessControl(void)
bWasPostponed = false;
bHasHitWall = false;
m_fDistanceTravelled = 0.0f;
- field_EF = false;
+ m_bIsVehicleBeingShifted = false;
m_phy_flagA80 = false;
ApplyMoveSpeed();
ApplyTurnSpeed();
@@ -692,7 +692,7 @@ CAutomobile::ProcessControl(void)
if(m_aSuspensionSpringRatio[i] < 1.0f)
m_aWheelTimer[i] = 4.0f;
else
- m_aWheelTimer[i] = max(m_aWheelTimer[i]-CTimer::GetTimeStep(), 0.0f);
+ m_aWheelTimer[i] = Max(m_aWheelTimer[i]-CTimer::GetTimeStep(), 0.0f);
if(m_aWheelTimer[i] > 0.0f){
m_nWheelsOnGround++;
@@ -1010,7 +1010,7 @@ CAutomobile::ProcessControl(void)
if(m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PHYSICS){
if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW)
- m_aWheelSpeed[0] = max(m_aWheelSpeed[0]-0.0005f, 0.0f);
+ m_aWheelSpeed[0] = Max(m_aWheelSpeed[0]-0.0005f, 0.0f);
}else if((GetModelIndex() == MI_DODO || CVehicle::bAllDodosCheat) &&
m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
FlyingControl(FLIGHT_MODEL_DODO);
@@ -1018,7 +1018,7 @@ CAutomobile::ProcessControl(void)
FlyingControl(FLIGHT_MODEL_RCPLANE);
}else if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW || bAllCarCheat){
if(CPad::GetPad(0)->GetCircleJustDown())
- m_aWheelSpeed[0] = max(m_aWheelSpeed[0]-0.03f, 0.0f);
+ m_aWheelSpeed[0] = Max(m_aWheelSpeed[0]-0.03f, 0.0f);
if(m_aWheelSpeed[0] < 0.22f)
m_aWheelSpeed[0] += 0.0001f;
if(m_aWheelSpeed[0] > 0.15f)
@@ -1130,10 +1130,10 @@ CAutomobile::ProcessControl(void)
if(speed > sq(0.1f)){
speed = Sqrt(speed);
if(suspShake > 0.0f){
- uint8 freq = min(200.0f*suspShake*speed*2000.0f/m_fMass + 100.0f, 250.0f);
+ uint8 freq = Min(200.0f*suspShake*speed*2000.0f/m_fMass + 100.0f, 250.0f);
CPad::GetPad(0)->StartShake(20000.0f*CTimer::GetTimeStep()/freq, freq);
}else{
- uint8 freq = min(200.0f*surfShake*speed*2000.0f/m_fMass + 40.0f, 145.0f);
+ uint8 freq = Min(200.0f*surfShake*speed*2000.0f/m_fMass + 40.0f, 145.0f);
CPad::GetPad(0)->StartShake(5000.0f*CTimer::GetTimeStep()/freq, freq);
}
}
@@ -2148,7 +2148,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
// m_aSuspensionSpringRatio are now set to the point where the tyre touches ground.
// In ProcessControl these will be re-normalized to ignore the tyre radius.
- if(field_EF || m_phy_flagA80 ||
+ if(m_bIsVehicleBeingShifted || m_phy_flagA80 ||
GetModelIndex() == MI_DODO && (ent->IsPed() || ent->IsVehicle())){
// don't do line collision
for(i = 0; i < 4; i++)
@@ -2601,7 +2601,7 @@ CAutomobile::HydraulicControl(void)
float minz = pos.z + extendedLowerLimit - wheelRadius;
if(minz < specialColModel->boundingBox.min.z)
specialColModel->boundingBox.min.z = minz;
- float radius = max(specialColModel->boundingBox.min.Magnitude(), specialColModel->boundingBox.max.Magnitude());
+ float radius = Max(specialColModel->boundingBox.min.Magnitude(), specialColModel->boundingBox.max.Magnitude());
if(specialColModel->boundingSphere.radius < radius)
specialColModel->boundingSphere.radius = radius;
@@ -2700,10 +2700,10 @@ CAutomobile::HydraulicControl(void)
float front = -rear;
float right = CPad::GetPad(0)->GetCarGunLeftRight()/128.0f;
float left = -right;
- suspChange[CARWHEEL_FRONT_LEFT] = max(front+left, 0.0f);
- suspChange[CARWHEEL_REAR_LEFT] = max(rear+left, 0.0f);
- suspChange[CARWHEEL_FRONT_RIGHT] = max(front+right, 0.0f);
- suspChange[CARWHEEL_REAR_RIGHT] = max(rear+right, 0.0f);
+ suspChange[CARWHEEL_FRONT_LEFT] = Max(front+left, 0.0f);
+ suspChange[CARWHEEL_REAR_LEFT] = Max(rear+left, 0.0f);
+ suspChange[CARWHEEL_FRONT_RIGHT] = Max(front+right, 0.0f);
+ suspChange[CARWHEEL_REAR_RIGHT] = Max(rear+right, 0.0f);
if(m_hydraulicState < 100){
// Lowered, move wheels up
@@ -2819,7 +2819,7 @@ CAutomobile::ProcessBuoyancy(void)
ApplyTurnForce(impulse, point);
CVector initialSpeed = m_vecMoveSpeed;
- float timeStep = max(CTimer::GetTimeStep(), 0.01f);
+ float timeStep = Max(CTimer::GetTimeStep(), 0.01f);
float impulseRatio = impulse.z / (GRAVITY * m_fMass * timeStep);
float waterResistance = Pow(1.0f - 0.05f*impulseRatio, CTimer::GetTimeStep());
m_vecMoveSpeed *= waterResistance;
@@ -2848,6 +2848,7 @@ CAutomobile::ProcessBuoyancy(void)
static uint32 nGenerateWaterCircles = 0;
if(initialSpeed.z < -0.3f && impulse.z > 0.3f){
+#if defined(PC_PARTICLE) || defined (PS2_ALTERNATIVE_CARSPLASH)
RwRGBA color;
color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.45f*255;
color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.45f*255;
@@ -2856,6 +2857,30 @@ CAutomobile::ProcessBuoyancy(void)
CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition(),
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.15f, 0.3f)),
0.0f, 75, color, true);
+#else
+ CVector pos = (initialSpeed * 2.0f) + (GetPosition() + point);
+
+ for ( int32 i = 0; i < 360; i += 4 )
+ {
+ float fSin = Sin(float(i));
+ float fCos = Cos(float(i));
+
+ CVector dir(fSin*0.01f, fCos*0.01f, CGeneral::GetRandomNumberInRange(0.25f, 0.45f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH,
+ pos + CVector(fSin*4.5f, fCos*4.5f, 0.0f),
+ dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
+
+ for ( int32 j = 0; j < 3; j++ )
+ {
+ float fMul = 1.5f * float(j + 1);
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH,
+ pos + CVector(fSin * fMul, fCos * fMul, 0.0f),
+ dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
+ }
+ }
+#endif
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
@@ -2909,10 +2934,17 @@ CAutomobile::ProcessBuoyancy(void)
CVector pos = m_aWheelColPoints[i].point + 0.3f*GetUp() - GetPosition();
CVector vSpeed = GetSpeed(pos);
vSpeed.z = 0.0f;
+#ifdef GTA_PS2_STUFF
+ // ps2 puddle physics
+ CVector moveForce = CTimer::GetTimeStep() * (m_fMass * (vSpeed * -0.003f));
+ ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
+#endif
float fSpeed = vSpeed.MagnitudeSqr();
+#ifdef PC_PARTICLE
if(fSpeed > sq(0.05f)){
fSpeed = Sqrt(fSpeed);
- float size = min((fSpeed < 0.15f ? 0.25f : 0.75f)*fSpeed, 0.6f);
+
+ float size = Min((fSpeed < 0.15f ? 0.25f : 0.75f)*fSpeed, 0.6f);
CVector right = 0.2f*fSpeed*GetRight() + 0.2f*vSpeed;
CParticle::AddParticle(PARTICLE_PED_SPLASH,
@@ -2924,10 +2956,39 @@ CAutomobile::ProcessBuoyancy(void)
CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
pos + GetPosition(), -0.6f*right,
nil, size, smokeCol, 0, 0, 0, 0);
-
+
if((CTimer::GetFrameCounter() & 0xF) == 0)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
}
+#else
+ if ( ( (CTimer::GetFrameCounter() + i) & 3 ) == 0 )
+ {
+ if(fSpeed > sq(0.05f))
+ {
+ fSpeed = Sqrt(fSpeed);
+ CRGBA color(155, 185, 155, 255);
+ float boxY = GetColModel()->boundingBox.max.y;
+ CVector right = 0.5f * GetRight();
+
+ if ( i == 2 )
+ {
+ CParticle::AddParticle(PARTICLE_PED_SPLASH,
+ GetPosition() + (boxY * GetForward()) + right,
+ 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
+
+ }
+ else if ( i == 0 )
+ {
+ CParticle::AddParticle(PARTICLE_PED_SPLASH,
+ GetPosition() + (boxY * GetForward()) - right,
+ 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
+ }
+
+ if((CTimer::GetFrameCounter() & 0xF) == 0)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
+ }
+ }
+#endif
}
}
}
@@ -2994,11 +3055,11 @@ CAutomobile::DoDriveByShootings(void)
// TODO: what is this?
if(!lookingLeft && m_weaponDoorTimerLeft > 0.0f){
- m_weaponDoorTimerLeft = max(m_weaponDoorTimerLeft - CTimer::GetTimeStep()*0.1f, 0.0f);
+ m_weaponDoorTimerLeft = Max(m_weaponDoorTimerLeft - CTimer::GetTimeStep()*0.1f, 0.0f);
ProcessOpenDoor(CAR_DOOR_LF, NUM_ANIMS, m_weaponDoorTimerLeft);
}
if(!lookingRight && m_weaponDoorTimerRight > 0.0f){
- m_weaponDoorTimerRight = max(m_weaponDoorTimerRight - CTimer::GetTimeStep()*0.1f, 0.0f);
+ m_weaponDoorTimerRight = Max(m_weaponDoorTimerRight - CTimer::GetTimeStep()*0.1f, 0.0f);
ProcessOpenDoor(CAR_DOOR_RF, NUM_ANIMS, m_weaponDoorTimerRight);
}
}
@@ -3146,7 +3207,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
FindPlayerPed()->SetWantedLevelNoDrop(1);
if(m_status == STATUS_PLAYER && impulse > 50.0f){
- uint8 freq = min(0.4f*impulse*2000.0f/m_fMass + 100.0f, 250.0f);
+ uint8 freq = Min(0.4f*impulse*2000.0f/m_fMass + 100.0f, 250.0f);
CPad::GetPad(0)->StartShake(40000/freq, freq);
}
@@ -3299,7 +3360,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
if(m_pDamageEntity && m_pDamageEntity == FindPlayerVehicle() && impulse > 10.0f){
int money = (doubleMoney ? 2 : 1) * impulse*pHandling->nMonetaryValue/1000000.0f;
- money = min(money, 40);
+ money = Min(money, 40);
if(money > 2){
sprintf(gString, "$%d", money);
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += money;
@@ -3486,14 +3547,29 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
}
return 0;
default:
- // Is this even visible?
- if(CWeather::WetRoads > 0.01f && CTimer::GetFrameCounter() & 1){
- CParticle::AddParticle(PARTICLE_WATERSPRAY,
+ if ( CWeather::WetRoads > 0.01f
+#ifdef PC_PARTICLE
+ && CTimer::GetFrameCounter() & 1
+#endif
+ )
+ {
+ CParticle::AddParticle(
+#ifdef FIX_BUGS
+ PARTICLE_WHEEL_WATER,
+#else
+ PARTICLE_WATERSPRAY,
+#endif
colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
- CVector(0.0f, 0.0f, 1.0f), nil,
+#ifdef PC_PARTICLE
+ CVector(0.0f, 0.0f, 1.0f),
+#else
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+#endif
+ nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
return 0;
}
+
return 1;
}
}
@@ -4004,7 +4080,7 @@ CAutomobile::SetupSuspensionLines(void)
// adjust col model to include suspension lines
if(colModel->boundingBox.min.z > colModel->lines[0].p1.z)
colModel->boundingBox.min.z = colModel->lines[0].p1.z;
- float radius = max(colModel->boundingBox.min.Magnitude(), colModel->boundingBox.max.Magnitude());
+ float radius = Max(colModel->boundingBox.min.Magnitude(), colModel->boundingBox.max.Magnitude());
if(colModel->boundingSphere.radius < radius)
colModel->boundingSphere.radius = radius;
@@ -4206,8 +4282,7 @@ GetCurrentAtomicObjectCB(RwObject *object, void *data)
return object;
}
-CColPoint aTempPedColPts[32]; // this name doesn't make any sense
- // they probably copied it from Ped (both serves same purpose) and didn't change the name
+CColPoint spherepoints[MAX_COLLISION_POINTS];
CObject*
CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
@@ -4327,7 +4402,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
if(CCollision::ProcessColModels(obj->GetMatrix(), *obj->GetColModel(),
this->GetMatrix(), *this->GetColModel(),
- aTempPedColPts, nil, nil) > 0)
+ spherepoints, nil, nil) > 0)
obj->m_pCollidingEntity = this;
if(bRenderScorched)
@@ -4493,88 +4568,3 @@ CAutomobile::SetAllTaxiLights(bool set)
{
m_sAllTaxiLights = set;
}
-
-#include <new>
-
-class CAutomobile_ : public CAutomobile
-{
-public:
- void ctor(int32 id, uint8 CreatedBy) { ::new (this) CAutomobile(id, CreatedBy); }
- void dtor() { CAutomobile::~CAutomobile(); }
- void SetModelIndex_(uint32 id) { CAutomobile::SetModelIndex(id); }
- void ProcessControl_(void) { CAutomobile::ProcessControl(); }
- void Teleport_(CVector v) { CAutomobile::Teleport(v); }
- void PreRender_(void) { CAutomobile::PreRender(); }
- void Render_(void) { CAutomobile::Render(); }
-
- int32 ProcessEntityCollision_(CEntity *ent, CColPoint *colpoints){ return CAutomobile::ProcessEntityCollision(ent, colpoints); }
-
- void ProcessControlInputs_(uint8 pad) { CAutomobile::ProcessControlInputs(pad); }
- void GetComponentWorldPosition_(int32 component, CVector &pos) { CAutomobile::GetComponentWorldPosition(component, pos); }
- bool IsComponentPresent_(int32 component) { return CAutomobile::IsComponentPresent(component); }
- void SetComponentRotation_(int32 component, CVector rotation) { CAutomobile::SetComponentRotation(component, rotation); }
- void OpenDoor_(int32 component, eDoors door, float ratio) { CAutomobile::OpenDoor(component, door, ratio); }
- void ProcessOpenDoor_(uint32 component, uint32 anim, float time) { CAutomobile::ProcessOpenDoor(component, anim, time); }
- bool IsDoorReady_(eDoors door) { return CAutomobile::IsDoorReady(door); }
- bool IsDoorFullyOpen_(eDoors door) { return CAutomobile::IsDoorFullyOpen(door); }
- bool IsDoorClosed_(eDoors door) { return CAutomobile::IsDoorClosed(door); }
- bool IsDoorMissing_(eDoors door) { return CAutomobile::IsDoorMissing(door); }
- void RemoveRefsToVehicle_(CEntity *ent) { CAutomobile::RemoveRefsToVehicle(ent); }
- void BlowUpCar_(CEntity *ent) { CAutomobile::BlowUpCar(ent); }
- bool SetUpWheelColModel_(CColModel *colModel) { return CAutomobile::SetUpWheelColModel(colModel); }
- void BurstTyre_(uint8 tyre) { CAutomobile::BurstTyre(tyre); }
- bool IsRoomForPedToLeaveCar_(uint32 door, CVector *pos) { return CAutomobile::IsRoomForPedToLeaveCar(door, pos); }
- float GetHeightAboveRoad_(void) { return CAutomobile::GetHeightAboveRoad(); }
- void PlayCarHorn_(void) { CAutomobile::PlayCarHorn(); }
-};
-
-STARTPATCHES
- InjectHook(0x52C6B0, &CAutomobile_::ctor, PATCH_JUMP);
- InjectHook(0x52D170, &CAutomobile_::dtor, PATCH_JUMP);
- InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x531470, &CAutomobile_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x535180, &CAutomobile_::Teleport_, PATCH_JUMP);
- InjectHook(0x539EA0, &CAutomobile_::Render_, PATCH_JUMP);
- InjectHook(0x535B40, &CAutomobile_::PreRender_, PATCH_JUMP);
- InjectHook(0x53B270, &CAutomobile_::ProcessEntityCollision_, PATCH_JUMP);
- InjectHook(0x53B660, &CAutomobile_::ProcessControlInputs_, PATCH_JUMP);
- InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP);
- InjectHook(0x52E660, &CAutomobile_::IsComponentPresent_, PATCH_JUMP);
- InjectHook(0x52E680, &CAutomobile_::SetComponentRotation_, PATCH_JUMP);
- InjectHook(0x52E750, &CAutomobile_::OpenDoor_, PATCH_JUMP);
- InjectHook(0x52EF10, &CAutomobile_::IsDoorReady_, PATCH_JUMP);
- InjectHook(0x52EF90, &CAutomobile_::IsDoorFullyOpen_, PATCH_JUMP);
- InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP);
- InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP);
- InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP);
- InjectHook(0x53BC60, &CAutomobile_::BlowUpCar_, PATCH_JUMP);
- InjectHook(0x53BF70, &CAutomobile_::SetUpWheelColModel_, PATCH_JUMP);
- InjectHook(0x53C0E0, &CAutomobile_::BurstTyre_, PATCH_JUMP);
- InjectHook(0x53C5B0, &CAutomobile_::IsRoomForPedToLeaveCar_, PATCH_JUMP);
- InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP);
- InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP);
- InjectHook(0x53E090, &CAutomobile::PlaceOnRoadProperly, PATCH_JUMP);
- InjectHook(0x52F030, &CAutomobile::dmgDrawCarCollidingParticles, PATCH_JUMP);
- InjectHook(0x535450, &CAutomobile::AddDamagedVehicleParticles, PATCH_JUMP);
- InjectHook(0x5357D0, &CAutomobile::AddWheelDirtAndWater, PATCH_JUMP);
- InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP);
- InjectHook(0x52D210, &CAutomobile::SetupSuspensionLines, PATCH_JUMP);
- InjectHook(0x53E000, &CAutomobile::BlowUpCarsInPath, PATCH_JUMP);
- InjectHook(0x42E220, &CAutomobile::HasCarStoppedBecauseOfLight, PATCH_JUMP);
- InjectHook(0x53D320, &CAutomobile::SetBusDoorTimer, PATCH_JUMP);
- InjectHook(0x53D370, &CAutomobile::ProcessAutoBusDoors, PATCH_JUMP);
- InjectHook(0x535250, &CAutomobile::ProcessSwingingDoor, PATCH_JUMP);
- InjectHook(0x53C240, &CAutomobile::Fix, PATCH_JUMP);
- InjectHook(0x53C310, &CAutomobile::SetupDamageAfterLoad, PATCH_JUMP);
- InjectHook(0x530300, &CAutomobile::SpawnFlyingComponent, PATCH_JUMP);
- InjectHook(0x535320, &CAutomobile::RemoveBonnetInPedCollision, PATCH_JUMP);
- InjectHook(0x5301A0, &CAutomobile::SetPanelDamage, PATCH_JUMP);
- InjectHook(0x530120, &CAutomobile::SetBumperDamage, PATCH_JUMP);
- InjectHook(0x530200, &CAutomobile::SetDoorDamage, PATCH_JUMP);
- InjectHook(0x5300E0, &CAutomobile::SetComponentVisibility, PATCH_JUMP);
- InjectHook(0x52D1B0, &CAutomobile::SetupModelNodes, PATCH_JUMP);
- InjectHook(0x53C420, &CAutomobile::SetTaxiLight, PATCH_JUMP);
- InjectHook(0x53BC40, &CAutomobile::GetAllWheelsOffGround, PATCH_JUMP);
- InjectHook(0x5308C0, &CAutomobile::ReduceHornCounter, PATCH_JUMP);
- InjectHook(0x53C440, &CAutomobile::SetAllTaxiLights, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index 561ab566..2de85a99 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -92,7 +92,6 @@ public:
uint8 bWaterTight : 1; // no damage for non-player peds
uint8 bNotDamagedUpsideDown : 1;
uint8 bMoreResistantToDamage : 1;
- uint8 field_4DB;
CEntity *m_pBombRigger;
int16 field_4E0;
uint16 m_hydraulicState;
@@ -120,7 +119,7 @@ public:
float m_fGasPedalAudio;
tWheelState m_aWheelState[4];
- static bool &m_sAllTaxiLights;
+ static bool m_sAllTaxiLights;
CAutomobile(int32 id, uint8 CreatedBy);
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 0159d168..14eb2f05 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "Timecycle.h"
#include "HandlingMgr.h"
@@ -21,16 +21,16 @@
#define INVALID_ORIENTATION (-9999.99f)
-float &fShapeLength = *(float*)0x600E78;
-float &fShapeTime = *(float*)0x600E7C;
-float &fRangeMult = *(float*)0x600E80; //0.6f; // 0.75f gta 3
-float &fTimeMult = *(float*)0x943008;
+float fShapeLength = 0.4f;
+float fShapeTime = 0.05f;
+float fRangeMult = 0.75f; //0.6f; // 0.75f gta 3
+float fTimeMult;
float MAX_WAKE_LENGTH = 50.0f;
float MIN_WAKE_INTERVAL = 1.0f;
float WAKE_LIFETIME = 400.0f;
-CBoat * (&CBoat::apFrameWakeGeneratingBoats)[4] = *(CBoat * (*)[4])*(uintptr*)0x8620E0;
+CBoat *CBoat::apFrameWakeGeneratingBoats[4];
CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
{
@@ -272,7 +272,7 @@ CBoat::ProcessControl(void)
impulse = m_vecMoveSpeed.MagnitudeSqr()*pHandling->fSuspensionForceLevel*buoyanceImpulse.z*CTimer::GetTimeStep()*0.5f*m_fGasPedal;
else
impulse = 0.0f;
- impulse = min(impulse, GRAVITY*pHandling->fSuspensionDampingLevel*m_fMass*CTimer::GetTimeStep());
+ impulse = Min(impulse, GRAVITY*pHandling->fSuspensionDampingLevel*m_fMass*CTimer::GetTimeStep());
ApplyMoveForce(impulse*GetUp());
ApplyTurnForce(impulse*GetUp(), buoyancePoint - pHandling->fSuspensionBias*GetForward());
}
@@ -340,27 +340,46 @@ CBoat::ProcessControl(void)
else
jetPos.z = 0.0f;
+#ifdef PC_PARTICLE
CVector wakePos = GetPosition() + sternPos;
wakePos.z -= 0.65f;
+#else
+ CVector wakePos = GetPosition() + sternPos;
+ wakePos.z = -0.3f;
+#endif
CVector wakeDir = 0.75f * jetDir;
CParticle::AddParticle(PARTICLE_BOAT_THRUSTJET, jetPos, jetDir, nil, 0.0f, jetColor);
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, jetPos, 0.25f * jetDir, nil, 1.0f, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 3);
+#endif
if(!cameraHack)
CParticle::AddParticle(PARTICLE_BOAT_WAKE, wakePos, wakeDir, nil, 0.0f, jetColor);
}else if((CTimer::GetFrameCounter() + m_randomSeed) & 1){
+#ifdef PC_PARTICLE
jetDir.z = 0.018f;
jetDir.x *= 0.01f;
jetDir.y *= 0.01f;
propellerWorld.z += 1.5f;
-
+
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.5f, jetColor);
+#else
+ jetDir.z = 0.018f;
+ jetDir.x *= 0.03f;
+ jetDir.y *= 0.03f;
+ propellerWorld.z += 1.0f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 0.0f, jetColor);
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.1f * jetDir, nil, 0.5f, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 3);
+#endif
}
}
}else if(!onLand){
@@ -375,10 +394,10 @@ CBoat::ProcessControl(void)
}
// Slow down or push down boat as it approaches the world limits
- m_vecMoveSpeed.x = min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east
- m_vecMoveSpeed.x = max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west
- m_vecMoveSpeed.y = min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north
- m_vecMoveSpeed.y = max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
+ m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east
+ m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west
+ m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north
+ m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
if(!onLand && bBoatInWater)
ApplyWaterResistance();
@@ -416,36 +435,66 @@ CBoat::ProcessControl(void)
}
// Spray particles on sides of boat
- if(m_nDeltaVolumeUnderWater > 75){
+#ifdef PC_PARTICLE
+ if(m_nDeltaVolumeUnderWater > 75)
+#else
+ if(m_nDeltaVolumeUnderWater > 120)
+#endif
+ {
float speed = m_vecMoveSpeed.Magnitude();
float splash1Size = speed;
- float splash2Size = m_nDeltaVolumeUnderWater * 0.005f * 0.2f;
+ float splash2Size = float(m_nDeltaVolumeUnderWater) * 0.005f * 0.2f;
float front = 0.9f * GetColModel()->boundingBox.max.y;
if(splash1Size > 0.75f) splash1Size = 0.75f;
CVector dir, pos;
// right
+#ifdef PC_PARTICLE
dir = -0.5f*m_vecMoveSpeed;
dir.z += 0.1f*speed;
dir += 0.5f*GetRight()*speed;
pos = front*GetForward() + 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+#else
+ dir = 0.3f*m_vecMoveSpeed;
+ dir.z += 0.05f*speed;
+ dir += 0.5f*GetRight()*speed;
+ pos = (GetPosition() + m_vecBuoyancePoint) + (1.5f*GetRight());
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 1);
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+#else
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
+#endif
+
// left
+#ifdef PC_PARTICLE
dir = -0.5f*m_vecMoveSpeed;
dir.z += 0.1f*speed;
dir -= 0.5f*GetRight()*speed;
pos = front*GetForward() - 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+#else
+ dir = 0.3f*m_vecMoveSpeed;
+ dir.z += 0.05f*speed;
+ dir -= 0.5f*GetRight()*speed;
+ pos = (GetPosition() + m_vecBuoyancePoint) - (1.5f*GetRight());
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 1);
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+#else
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
+#endif
}
m_fPrevVolumeUnderWater = m_fVolumeUnderWater;
@@ -658,13 +707,13 @@ CBoat::Render()
((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->SetVehicleColour(m_currentColour1, m_currentColour2);
if (!CVehicle::bWheelsOnlyCheat)
CEntity::Render();
- KeepWaterOutVertices[0].color = -1;
+ RwIm3DVertexSetRGBA(&KeepWaterOutVertices[0], 255, 255, 255, 255);
KeepWaterOutIndices[0] = 0;
- KeepWaterOutVertices[1].color = -1;
+ RwIm3DVertexSetRGBA(&KeepWaterOutVertices[1], 255, 255, 255, 255);
KeepWaterOutIndices[1] = 2;
- KeepWaterOutVertices[2].color = -1;
+ RwIm3DVertexSetRGBA(&KeepWaterOutVertices[2], 255, 255, 255, 255);
KeepWaterOutIndices[2] = 1;
- KeepWaterOutVertices[3].color = -1;
+ RwIm3DVertexSetRGBA(&KeepWaterOutVertices[3], 255, 255, 255, 255);
KeepWaterOutIndices[3] = 1;
KeepWaterOutIndices[4] = 2;
KeepWaterOutIndices[5] = 3;
@@ -765,7 +814,7 @@ CBoat::IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat)
float fDist = vecDist.MagnitudeSqr();
if ( fDist < SQR(fMaxDist) )
- return 1.0f - min(fRangeMult * Sqrt(fDist / SQR(fMaxDist)) + (WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[i]) * fTimeMult, 1.0f);
+ return 1.0f - Min(fRangeMult * Sqrt(fDist / SQR(fMaxDist)) + (WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[i]) * fTimeMult, 1.0f);
}
return 0.0f;
@@ -837,7 +886,7 @@ CBoat::AddWakePoint(CVector point)
int i;
if(m_afWakePointLifeTime[0] > 0.0f){
if((CVector2D(GetPosition()) - m_avec2dWakePoints[0]).MagnitudeSqr() < SQR(1.0f)){
- for(i = min(m_nNumWakePoints, ARRAY_SIZE(m_afWakePointLifeTime)-1); i != 0; i--){
+ for(i = Min(m_nNumWakePoints, ARRAY_SIZE(m_afWakePointLifeTime)-1); i != 0; i--){
m_avec2dWakePoints[i] = m_avec2dWakePoints[i-1];
m_afWakePointLifeTime[i] = m_afWakePointLifeTime[i-1];
}
@@ -850,24 +899,3 @@ CBoat::AddWakePoint(CVector point)
m_nNumWakePoints = 1;
}
}
-
-#include <new>
-
-class CBoat_ : public CBoat
-{
-public:
- CBoat* ctor(int32 id, uint8 CreatedBy) { return ::new (this) CBoat(id, CreatedBy); }
- void dtor() { CBoat::~CBoat(); };
-};
-
-STARTPATCHES
- InjectHook(0x53E3E0, &CBoat_::ctor, PATCH_JUMP);
- InjectHook(0x53E790, &CBoat_::dtor, PATCH_JUMP);
- InjectHook(0x53E7D0, &CBoat::SetupModelNodes, PATCH_JUMP);
- InjectHook(0x542370, CBoat::IsSectorAffectedByWake, PATCH_JUMP);
- InjectHook(0x5424A0, CBoat::IsVertexAffectedByWake, PATCH_JUMP);
- InjectHook(0x542250, CBoat::FillBoatList, PATCH_JUMP);
- InjectHook(0x542140, &CBoat::AddWakePoint, PATCH_JUMP);
- InjectHook(0x5420D0, &CBoat::PruneWakeTrail, PATCH_JUMP);
- InjectHook(0x541A30, &CBoat::ApplyWaterResistance, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h
index f4c6a747..ba56e355 100644
--- a/src/vehicles/Boat.h
+++ b/src/vehicles/Boat.h
@@ -58,7 +58,7 @@ public:
void PruneWakeTrail(void);
void AddWakePoint(CVector point);
- static CBoat *(&apFrameWakeGeneratingBoats)[4];
+ static CBoat *apFrameWakeGeneratingBoats[4];
static bool IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats);
static float IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat);
diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp
index c35005a1..64743929 100644
--- a/src/vehicles/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "CarGen.h"
#include "Automobile.h"
@@ -157,7 +157,7 @@ void CCarGenerator::Setup(float x, float y, float z, float angle, int32 mi, int1
m_bIsBlocking = false;
m_vecInf = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.min;
m_vecSup = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.max;
- m_fSize = max(m_vecInf.Magnitude(), m_vecSup.Magnitude());
+ m_fSize = Max(m_vecInf.Magnitude(), m_vecSup.Magnitude());
}
bool CCarGenerator::CheckForBlockage()
@@ -249,10 +249,3 @@ INITSAVEBUF
CarGeneratorArray[i] = ReadSaveBuf<CCarGenerator>(buffer);
VALIDATESAVEBUF(size)
}
-
-STARTPATCHES
-InjectHook(0x543020, CTheCarGenerators::Init, PATCH_JUMP);
-InjectHook(0x542F40, CTheCarGenerators::Process, PATCH_JUMP);
-InjectHook(0x543050, CTheCarGenerators::SaveAllCarGenerators, PATCH_JUMP);
-InjectHook(0x5431E0, CTheCarGenerators::LoadAllCarGenerators, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index dbc3c340..7d2160d9 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Cranes.h"
#include "Camera.h"
@@ -213,10 +213,10 @@ void CCrane::Update(void)
CTimer::GetTimeInMilliseconds() > m_nTimeForNextCheck) {
CWorld::AdvanceCurrentScanCode();
#ifdef FIX_BUGS
- int xstart = max(0, CWorld::GetSectorIndexX(m_fPickupX1));
- int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fPickupX2));
- int ystart = max(0, CWorld::GetSectorIndexY(m_fPickupY1));
- int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fPickupY2));
+ int xstart = Max(0, CWorld::GetSectorIndexX(m_fPickupX1));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fPickupX2));
+ int ystart = Max(0, CWorld::GetSectorIndexY(m_fPickupY1));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fPickupY2));
#else
int xstart = CWorld::GetSectorIndexX(m_fPickupX1);
int xend = CWorld::GetSectorIndexX(m_fPickupX2);
diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp
index 9a697b6b..03ccfe77 100644
--- a/src/vehicles/DamageManager.cpp
+++ b/src/vehicles/DamageManager.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "General.h"
#include "Vehicle.h"
#include "DamageManager.h"
@@ -228,24 +228,3 @@ CDamageManager::ProgressEngineDamage(void)
SetEngineStatus(newstatus);
return true;
}
-
-STARTPATCHES
- InjectHook(0x545850, &CDamageManager::ResetDamageStatus, PATCH_JUMP);
- InjectHook(0x545B70, &CDamageManager::FuckCarCompletely, PATCH_JUMP);
- InjectHook(0x545790, &CDamageManager::GetComponentGroup, PATCH_JUMP);
- InjectHook(0x545A80, &CDamageManager::ApplyDamage, PATCH_JUMP);
- InjectHook(0x545920, &CDamageManager::SetDoorStatus, PATCH_JUMP);
- InjectHook(0x545930, &CDamageManager::GetDoorStatus, PATCH_JUMP);
- InjectHook(0x545970, &CDamageManager::ProgressDoorDamage, PATCH_JUMP);
- InjectHook(0x5458B0, &CDamageManager::SetPanelStatus, PATCH_JUMP);
- InjectHook(0x5458E0, (int32 (CDamageManager::*)(int32))&CDamageManager::GetPanelStatus, PATCH_JUMP);
- InjectHook(0x545A00, &CDamageManager::ProgressPanelDamage, PATCH_JUMP);
- InjectHook(0x545860, &CDamageManager::SetLightStatus, PATCH_JUMP);
- InjectHook(0x545890, &CDamageManager::GetLightStatus, PATCH_JUMP);
- InjectHook(0x545900, &CDamageManager::SetWheelStatus, PATCH_JUMP);
- InjectHook(0x545910, &CDamageManager::GetWheelStatus, PATCH_JUMP);
- InjectHook(0x545A40, &CDamageManager::ProgressWheelDamage, PATCH_JUMP);
- InjectHook(0x545940, &CDamageManager::SetEngineStatus, PATCH_JUMP);
- InjectHook(0x545960, &CDamageManager::GetEngineStatus, PATCH_JUMP);
- InjectHook(0x5459B0, &CDamageManager::ProgressEngineDamage, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Door.cpp b/src/vehicles/Door.cpp
index c569be59..c80965aa 100644
--- a/src/vehicles/Door.cpp
+++ b/src/vehicles/Door.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Vehicle.h"
#include "Door.h"
@@ -168,19 +168,3 @@ CTrainDoor::IsClosed(void)
{
return m_fPosn == RetTranslationWhenClosed();
}
-
-STARTPATCHES
- InjectHook(0x545EF0, &CDoor::Open, PATCH_JUMP);
- InjectHook(0x545BD0, &CDoor::Process, PATCH_JUMP);
- InjectHook(0x545FE0, &CDoor::RetAngleWhenClosed, PATCH_JUMP);
- InjectHook(0x546020, &CDoor::RetAngleWhenOpen, PATCH_JUMP);
- InjectHook(0x545F80, &CDoor::GetAngleOpenRatio, PATCH_JUMP);
- InjectHook(0x546090, &CDoor::IsFullyOpen, PATCH_JUMP);
- InjectHook(0x546060, &CDoor::IsClosed, PATCH_JUMP);
-
- InjectHook(0x546200, &CTrainDoor::Open, PATCH_JUMP);
- InjectHook(0x546180, &CTrainDoor::RetTranslationWhenClosed, PATCH_JUMP);
- InjectHook(0x5461C0, &CTrainDoor::RetTranslationWhenOpen, PATCH_JUMP);
- InjectHook(0x546120, &CTrainDoor::IsFullyOpen, PATCH_JUMP);
- InjectHook(0x5460F0, &CTrainDoor::IsClosed, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Floater.cpp b/src/vehicles/Floater.cpp
index 62d55925..1ae1c5c3 100644
--- a/src/vehicles/Floater.cpp
+++ b/src/vehicles/Floater.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Timer.h"
#include "WaterLevel.h"
#include "ModelIndices.h"
@@ -7,10 +7,9 @@
#include "Vehicle.h"
#include "Floater.h"
-cBuoyancy &mod_Buoyancy = *(cBuoyancy*)0x8F2674;
+cBuoyancy mod_Buoyancy;
-//static float fVolMultiplier = 1.0f;
-static float &fVolMultiplier = *(float*)0x601394;
+static float fVolMultiplier = 1.0f;
// amount of boat volume in bounding box
// 1.0-volume is the empty space in the bbox
static float fBoatVolumeDistribution[9] = {
@@ -184,12 +183,3 @@ cBuoyancy::CalcBuoyancyForce(CPhysical *phys, CVector *point, CVector *impulse)
*impulse = CVector(0.0f, 0.0f, m_volumeUnderWater*m_buoyancy*CTimer::GetTimeStep());
return true;
}
-
-STARTPATCHES
- InjectHook(0x546270, &cBuoyancy::ProcessBuoyancy, PATCH_JUMP);
- InjectHook(0x546360, &cBuoyancy::PreCalcSetup, PATCH_JUMP);
- InjectHook(0x5466F0, &cBuoyancy::SimpleCalcBuoyancy, PATCH_JUMP);
- InjectHook(0x546820, &cBuoyancy::SimpleSumBuoyancyData, PATCH_JUMP);
- InjectHook(0x546620, &cBuoyancy::FindWaterLevel, PATCH_JUMP);
- InjectHook(0x5465A0, &cBuoyancy::CalcBuoyancyForce, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Floater.h b/src/vehicles/Floater.h
index 4754a235..1cfb46fb 100644
--- a/src/vehicles/Floater.h
+++ b/src/vehicles/Floater.h
@@ -42,4 +42,4 @@ public:
void FindWaterLevel(const CVector &zpos, CVector *waterLevel, tWaterLevel *waterPosition);
bool CalcBuoyancyForce(CPhysical *phys, CVector *impulse, CVector *point);
};
-extern cBuoyancy &mod_Buoyancy;
+extern cBuoyancy mod_Buoyancy;
diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp
index 0f16401e..3ac0da38 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -1,10 +1,10 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "FileMgr.h"
#include "HandlingMgr.h"
-cHandlingDataMgr &mod_HandlingManager = *(cHandlingDataMgr*)0x728060;
+cHandlingDataMgr mod_HandlingManager;
const char *HandlingFilename = "HANDLING.CFG";
@@ -237,11 +237,3 @@ cHandlingDataMgr::GetHandlingId(const char *name)
break;
return i;
}
-
-STARTPATCHES
- InjectHook(0x546D80, &cHandlingDataMgr::Initialise, PATCH_JUMP);
- InjectHook(0x546DB0, &cHandlingDataMgr::LoadHandlingData, PATCH_JUMP);
- InjectHook(0x546BB0, &cHandlingDataMgr::ConvertDataToGameUnits, PATCH_JUMP);
- InjectHook(0x546AA0, &cHandlingDataMgr::FindExactWord, PATCH_JUMP);
- InjectHook(0x546B70, &cHandlingDataMgr::GetHandlingId, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index 70f1c005..398a415f 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -101,7 +101,7 @@ struct tHandlingData
float fSteeringLock;
float fTractionLoss;
float fTractionBias;
- uint32 field_AC;
+ float fABS; // should be VC leftover
float fSuspensionForceLevel;
float fSuspensionDampingLevel;
float fSuspensionUpperLimit;
@@ -126,7 +126,7 @@ private:
float field_C; // unused it seems
float field_10; //
tHandlingData HandlingData[NUMHANDLINGS];
- uint32 field_302C; // unused it seems, padding?
+ uint32 field_302C; // unused it seems
public:
cHandlingDataMgr(void);
@@ -140,4 +140,4 @@ public:
bool HasFrontWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
};
VALIDATE_SIZE(cHandlingDataMgr, 0x3030);
-extern cHandlingDataMgr &mod_HandlingManager;
+extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index 3dc1deeb..0073a5ad 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "General.h"
#include "Darkel.h"
#include "Stats.h"
@@ -24,6 +24,9 @@
#include "Object.h"
#include "HandlingMgr.h"
#include "Heli.h"
+#ifdef FIX_BUGS
+#include "Replay.h"
+#endif
enum
{
@@ -34,13 +37,13 @@ enum
HELI_STATUS_HOVER2,
};
-CHeli **CHeli::pHelis = (CHeli**)0x72CF50;
-int16 &CHeli::NumRandomHelis = *(int16*)0x95CCAA;
-uint32 &CHeli::TestForNewRandomHelisTimer = *(uint32*)0x8F1A7C;
+CHeli *CHeli::pHelis[NUM_HELIS];
+int16 CHeli::NumRandomHelis;
+uint32 CHeli::TestForNewRandomHelisTimer;
int16 CHeli::NumScriptHelis; // unused
-bool &CHeli::CatalinaHeliOn = *(bool*)0x95CD85;
-bool &CHeli::CatalinaHasBeenShotDown = *(bool*)0x95CD56;
-bool &CHeli::ScriptHeliOn = *(bool*)0x95CD43;
+bool CHeli::CatalinaHeliOn;
+bool CHeli::CatalinaHasBeenShotDown;
+bool CHeli::ScriptHeliOn;
CHeli::CHeli(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
@@ -78,6 +81,9 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
m_bTestRight = true;
m_fTargetOffset = 0.0f;
m_fSearchLightX = m_fSearchLightY = 0.0f;
+
+ // BUG: not in game but gets initialized to CDCDCDCD in debug
+ m_nLastShotTime = 0;
}
void
@@ -225,19 +231,19 @@ CHeli::ProcessControl(void)
switch(m_heliStatus){
case HELI_STATUS_HOVER:
groundZ = CWorld::FindGroundZFor3DCoord(GetPosition().x, GetPosition().y, 1000.0f, nil);
- m_fTargetZ = max(groundZ, m_fTargetZ) + 8.0f;
+ m_fTargetZ = Max(groundZ, m_fTargetZ) + 8.0f;
break;
case HELI_STATUS_SHOT_DOWN:
groundZ = CWorld::FindGroundZFor3DCoord(GetPosition().x, GetPosition().y, 1000.0f, nil);
- m_fTargetZ = max(groundZ, m_fTargetZ) + 8.0f + m_fTargetOffset;
+ m_fTargetZ = Max(groundZ, m_fTargetZ) + 8.0f + m_fTargetOffset;
break;
case HELI_STATUS_HOVER2:
groundZ = CWorld::FindGroundZFor3DCoord(GetPosition().x, GetPosition().y, 1000.0f, nil);
- m_fTargetZ = max(groundZ, m_fTargetZ) + 8.0f + m_fTargetOffset;
+ m_fTargetZ = Max(groundZ, m_fTargetZ) + 8.0f + m_fTargetOffset;
break;
default:
groundZ = CWorld::FindGroundZFor3DCoord(GetPosition().x, GetPosition().y, 1000.0f, nil);
- m_fTargetZ = max(groundZ, m_fTargetZ) + 12.0f;
+ m_fTargetZ = Max(groundZ, m_fTargetZ) + 12.0f;
break;
}
@@ -425,89 +431,95 @@ CHeli::ProcessControl(void)
// Search light and shooting
if(m_heliStatus == HELI_STATUS_FLY_AWAY || m_heliType == HELI_TYPE_CATALINA || CCullZones::PlayerNoRain())
m_fSearchLightIntensity = 0.0f;
- else{
+ else {
// Update search light history once every 1000ms
int timeDiff = CTimer::GetTimeInMilliseconds() - m_nSearchLightTimer;
- while(timeDiff > 1000){
- for(i = 5; i > 0; i--){
- m_aSearchLightHistoryX[i] = m_aSearchLightHistoryX[i-1];
- m_aSearchLightHistoryY[i] = m_aSearchLightHistoryY[i-1];
+ while (timeDiff > 1000) {
+ for (i = 5; i > 0; i--) {
+ m_aSearchLightHistoryX[i] = m_aSearchLightHistoryX[i - 1];
+ m_aSearchLightHistoryY[i] = m_aSearchLightHistoryY[i - 1];
}
- m_aSearchLightHistoryX[0] = FindPlayerCoors().x + FindPlayerSpeed().x*50.0f*(m_nHeliId+2);
- m_aSearchLightHistoryY[0] = FindPlayerCoors().y + FindPlayerSpeed().y*50.0f*(m_nHeliId+2);
+ m_aSearchLightHistoryX[0] = FindPlayerCoors().x + FindPlayerSpeed().x * 50.0f * (m_nHeliId + 2);
+ m_aSearchLightHistoryY[0] = FindPlayerCoors().y + FindPlayerSpeed().y * 50.0f * (m_nHeliId + 2);
timeDiff -= 1000;
m_nSearchLightTimer += 1000;
}
assert(timeDiff <= 1000);
- float f1 = timeDiff/1000.0f;
+ float f1 = timeDiff / 1000.0f;
float f2 = 1.0f - f1;
- m_fSearchLightX = m_aSearchLightHistoryX[m_nHeliId+2]*f2 + m_aSearchLightHistoryX[m_nHeliId+2-1]*f1;
- m_fSearchLightY = m_aSearchLightHistoryY[m_nHeliId+2]*f2 + m_aSearchLightHistoryY[m_nHeliId+2-1]*f1;
+ m_fSearchLightX = m_aSearchLightHistoryX[m_nHeliId + 2] * f2 + m_aSearchLightHistoryX[m_nHeliId + 2 - 1] * f1;
+ m_fSearchLightY = m_aSearchLightHistoryY[m_nHeliId + 2] * f2 + m_aSearchLightHistoryY[m_nHeliId + 2 - 1] * f1;
float searchLightDist = (CVector2D(m_fSearchLightX, m_fSearchLightY) - GetPosition()).Magnitude();
- if(searchLightDist > 60.0f)
+ if (searchLightDist > 60.0f)
m_fSearchLightIntensity = 0.0f;
- else if(searchLightDist < 40.0f)
+ else if (searchLightDist < 40.0f)
m_fSearchLightIntensity = 1.0f;
else
- m_fSearchLightIntensity = 1.0f - (40.0f-searchLightDist)/40.0f;
+ m_fSearchLightIntensity = 1.0f - (40.0f - searchLightDist) / 40.0f;
- if(m_fSearchLightIntensity < 0.9f || sq(FindPlayerCoors().x-m_fSearchLightX) + sq(FindPlayerCoors().y-m_fSearchLightY) > sq(7.0f))
+ if (m_fSearchLightIntensity < 0.9f || sq(FindPlayerCoors().x - m_fSearchLightX) + sq(FindPlayerCoors().y - m_fSearchLightY) > sq(7.0f))
m_nShootTimer = CTimer::GetTimeInMilliseconds();
- else if(CTimer::GetTimeInMilliseconds() > m_nPoliceShoutTimer){
+ else if (CTimer::GetTimeInMilliseconds() > m_nPoliceShoutTimer) {
DMAudio.PlayOneShot(m_audioEntityId, SOUND_PED_HELI_PLAYER_FOUND, 0.0f);
- m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds() + 4500 + (CGeneral::GetRandomNumber()&0xFFF);
+ m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds() + 4500 + (CGeneral::GetRandomNumber() & 0xFFF);
}
-
- // Shoot
- int shootTimeout;
- if(m_heliType == HELI_TYPE_RANDOM){
- switch(FindPlayerPed()->m_pWanted->m_nWantedLevel){
- case 0:
- case 1:
- case 2: shootTimeout = 999999; break;
- case 3: shootTimeout = 10000; break;
- case 4: shootTimeout = 5000; break;
- case 5: shootTimeout = 3500; break;
- case 6: shootTimeout = 2000; break;
- }
- if(CCullZones::NoPolice())
- shootTimeout /= 2;
- }else
- shootTimeout = 1500;
-
- if(FindPlayerPed()->m_pWanted->IsIgnored())
- m_nShootTimer = CTimer::GetTimeInMilliseconds();
- else{
- // Check if line of sight is clear
- if(CTimer::GetTimeInMilliseconds() > m_nShootTimer + shootTimeout &&
- CTimer::GetPreviousTimeInMilliseconds() <= m_nShootTimer + shootTimeout){
- if(CWorld::GetIsLineOfSightClear(GetPosition(), FindPlayerCoors(), true, false, false, false, false, false)){
- if(m_heliStatus == HELI_STATUS_HOVER2)
- m_heliStatus = HELI_STATUS_HOVER;
- }else{
- m_nShootTimer = CTimer::GetTimeInMilliseconds();
- if(m_heliStatus == HELI_STATUS_HOVER)
- m_heliStatus = HELI_STATUS_HOVER2;
+#ifdef FIX_BUGS
+ if (!CReplay::IsPlayingBack())
+#endif
+ {
+ // Shoot
+ int shootTimeout;
+ if (m_heliType == HELI_TYPE_RANDOM) {
+ switch (FindPlayerPed()->m_pWanted->m_nWantedLevel) {
+ case 0:
+ case 1:
+ case 2: shootTimeout = 999999; break;
+ case 3: shootTimeout = 10000; break;
+ case 4: shootTimeout = 5000; break;
+ case 5: shootTimeout = 3500; break;
+ case 6: shootTimeout = 2000; break;
}
+ if (CCullZones::NoPolice())
+ shootTimeout /= 2;
}
+ else
+ shootTimeout = 1500;
+
+ if (FindPlayerPed()->m_pWanted->IsIgnored())
+ m_nShootTimer = CTimer::GetTimeInMilliseconds();
+ else {
+ // Check if line of sight is clear
+ if (CTimer::GetTimeInMilliseconds() > m_nShootTimer + shootTimeout &&
+ CTimer::GetPreviousTimeInMilliseconds() <= m_nShootTimer + shootTimeout) {
+ if (CWorld::GetIsLineOfSightClear(GetPosition(), FindPlayerCoors(), true, false, false, false, false, false)) {
+ if (m_heliStatus == HELI_STATUS_HOVER2)
+ m_heliStatus = HELI_STATUS_HOVER;
+ }
+ else {
+ m_nShootTimer = CTimer::GetTimeInMilliseconds();
+ if (m_heliStatus == HELI_STATUS_HOVER)
+ m_heliStatus = HELI_STATUS_HOVER2;
+ }
+ }
- // Shoot!
- if(CTimer::GetTimeInMilliseconds() > m_nShootTimer + shootTimeout &&
- CTimer::GetTimeInMilliseconds() > m_nLastShotTime + 200){
- CVector shotTarget = FindPlayerCoors();
- // some inaccuracy
- shotTarget.x += ((CGeneral::GetRandomNumber()&0xFF)-128)/50.0f;
- shotTarget.y += ((CGeneral::GetRandomNumber()&0xFF)-128)/50.0f;
- CVector direction = FindPlayerCoors() - GetPosition();
- direction.Normalise();
- shotTarget += 3.0f*direction;
- CVector shotSource = GetPosition();
- shotSource += 3.0f*direction;
- FireOneInstantHitRound(&shotSource, &shotTarget, 20);
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
- m_nLastShotTime = CTimer::GetTimeInMilliseconds();
+ // Shoot!
+ if (CTimer::GetTimeInMilliseconds() > m_nShootTimer + shootTimeout &&
+ CTimer::GetTimeInMilliseconds() > m_nLastShotTime + 200) {
+ CVector shotTarget = FindPlayerCoors();
+ // some inaccuracy
+ shotTarget.x += ((CGeneral::GetRandomNumber() & 0xFF) - 128) / 50.0f;
+ shotTarget.y += ((CGeneral::GetRandomNumber() & 0xFF) - 128) / 50.0f;
+ CVector direction = FindPlayerCoors() - GetPosition();
+ direction.Normalise();
+ shotTarget += 3.0f * direction;
+ CVector shotSource = GetPosition();
+ shotSource += 3.0f * direction;
+ FireOneInstantHitRound(&shotSource, &shotTarget, 20);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+ m_nLastShotTime = CTimer::GetTimeInMilliseconds();
+ }
}
}
}
@@ -590,7 +602,12 @@ CHeli::PreRender(void)
break;
}
RwRGBA col = { r, g, b, 32 };
+#ifdef FIX_BUGS
+ pos.z = m_fHeliDustZ[frm];
+#else
+ // What the hell is the point of this?
pos.z = m_fHeliDustZ[(i - (i&3))/4]; // advance every 4 iterations, why not just /4?
+#endif
if(pos.z > -200.0f && GetPosition().z - pos.z < 20.0f)
CParticle::AddParticle(PARTICLE_HELI_DUST, pos, dir, nil, 0.0f, col);
i++;
@@ -817,7 +834,11 @@ CHeli::UpdateHelis(void)
int i, j;
// Spawn new police helis
- int numHelisRequired = FindPlayerPed()->m_pWanted->NumOfHelisRequired();
+ int numHelisRequired =
+#ifdef FIX_BUGS
+ CReplay::IsPlayingBack() ? 0 :
+#endif
+ FindPlayerPed()->m_pWanted->NumOfHelisRequired();
if(CStreaming::HasModelLoaded(MI_CHOPPER) && CTimer::GetTimeInMilliseconds() > TestForNewRandomHelisTimer){
// Spawn a police heli
TestForNewRandomHelisTimer = CTimer::GetTimeInMilliseconds() + 15000;
@@ -996,7 +1017,7 @@ CHeli::TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, i
float distToHeli = (pHelis[i]->GetPosition() - *line0).Magnitude();
CVector line = (*line1 - *line0);
float lineLength = line.Magnitude();
- *bulletPos = *line0 + line*max(1.0f, distToHeli-5.0f);
+ *bulletPos = *line0 + line*Max(1.0f, distToHeli-5.0f);
pHelis[i]->m_nBulletDamage += damage;
@@ -1035,24 +1056,3 @@ void CHeli::MakeCatalinaHeliFlyAway(void) { pHelis[HELI_CATALINA]->m_pathState =
bool CHeli::HasCatalinaBeenShotDown(void) { return CatalinaHasBeenShotDown; }
void CHeli::ActivateHeli(bool activate) { ScriptHeliOn = activate; }
-
-#include <new>
-
-class CHeli_ : public CHeli
-{
-public:
- void ctor(int32 id, uint8 CreatedBy) { ::new (this) CHeli(id, CreatedBy); }
- void dtor(void) { CHeli::~CHeli(); }
-};
-
-STARTPATCHES
- InjectHook(0x547220, &CHeli_::ctor, PATCH_JUMP);
- InjectHook(0x5474A0, &CHeli_::dtor, PATCH_JUMP);
- InjectHook(0x54AE50, &CHeli::SpawnFlyingComponent, PATCH_JUMP);
- InjectHook(0x549970, CHeli::InitHelis, PATCH_JUMP);
- InjectHook(0x5499F0, CHeli::UpdateHelis, PATCH_JUMP);
- InjectHook(0x54AE10, CHeli::SpecialHeliPreRender, PATCH_JUMP);
- InjectHook(0x54AA30, CHeli::TestRocketCollision, PATCH_JUMP);
- InjectHook(0x54AB30, CHeli::TestBulletCollision, PATCH_JUMP);
- InjectHook(0x54A640, GenerateHeli, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h
index bb10345d..39e4cbcf 100644
--- a/src/vehicles/Heli.h
+++ b/src/vehicles/Heli.h
@@ -61,16 +61,15 @@ public:
float m_fTargetOffset;
bool m_bTestRight;
- static CHeli **pHelis; //[NUM_HELIS]
- static int16 &NumRandomHelis;
- static uint32 &TestForNewRandomHelisTimer;
+ static CHeli *pHelis[NUM_HELIS];
+ static int16 NumRandomHelis;
+ static uint32 TestForNewRandomHelisTimer;
static int16 NumScriptHelis; // unused
- static bool &CatalinaHeliOn;
- static bool &CatalinaHasBeenShotDown;
- static bool &ScriptHeliOn;
+ static bool CatalinaHeliOn;
+ static bool CatalinaHasBeenShotDown;
+ static bool ScriptHeliOn;
CHeli(int32 id, uint8 CreatedBy);
- CHeli* ctor(int, uint8);
// from CEntity
void SetModelIndex(uint32 id);
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index c2b9e493..273ac54a 100644
--- a/src/vehicles/Plane.cpp
+++ b/src/vehicles/Plane.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "General.h"
#include "ModelIndices.h"
#include "FileMgr.h"
@@ -16,35 +16,35 @@
#include "HandlingMgr.h"
#include "Plane.h"
-CPlaneNode *&pPathNodes = *(CPlaneNode**)0x8F1B68;
-CPlaneNode *&pPath2Nodes = *(CPlaneNode**)0x885B8C;
-CPlaneNode *&pPath3Nodes = *(CPlaneNode**)0x885B78;
-CPlaneNode *&pPath4Nodes = *(CPlaneNode**)0x885AD8;
-int32 &NumPathNodes = *(int32*)0x8F2BE4;
-int32 &NumPath2Nodes = *(int32*)0x941498;
-int32 &NumPath3Nodes = *(int32*)0x9414D8;
-int32 &NumPath4Nodes = *(int32*)0x9412C8;
-float &TotalLengthOfFlightPath = *(float*)0x8F2C6C;
-float &TotalLengthOfFlightPath2 = *(float*)0x64CFBC;
-float &TotalLengthOfFlightPath3 = *(float*)0x64CFD0;
-float &TotalLengthOfFlightPath4 = *(float*)0x64CFDC;
-float &TotalDurationOfFlightPath = *(float*)0x64CFB8;
-float &TotalDurationOfFlightPath2 = *(float*)0x64CFC0;
-float &TotalDurationOfFlightPath3 = *(float*)0x64CFD4;
-float &TotalDurationOfFlightPath4 = *(float*)0x64CFE0;
-float &LandingPoint = *(float*)0x8F2C7C;
-float &TakeOffPoint = *(float*)0x8E28A4;
-CPlaneInterpolationLine *aPlaneLineBits = (CPlaneInterpolationLine*)0x734168; //[6]
-
-float *PlanePathPosition = (float*)0x8F5FC8; //[3]
-float *OldPlanePathPosition = (float*)0x8F5FBC; //[3]
-float *PlanePathSpeed = (float*)0x941538; //[3]
-float *PlanePath2Position = (float*)0x64CFC4; //[3]
-float &PlanePath3Position = *(float*)0x64CFD8;
-float &PlanePath4Position = *(float*)0x64CFE4;
-float *PlanePath2Speed = (float*)0x8F1A54; //[3]
-float &PlanePath3Speed = *(float*)0x8F1A94;
-float &PlanePath4Speed = *(float*)0x8F1AFC;
+CPlaneNode *pPathNodes;
+CPlaneNode *pPath2Nodes;
+CPlaneNode *pPath3Nodes;
+CPlaneNode *pPath4Nodes;
+int32 NumPathNodes;
+int32 NumPath2Nodes;
+int32 NumPath3Nodes;
+int32 NumPath4Nodes;
+float TotalLengthOfFlightPath;
+float TotalLengthOfFlightPath2;
+float TotalLengthOfFlightPath3;
+float TotalLengthOfFlightPath4;
+float TotalDurationOfFlightPath;
+float TotalDurationOfFlightPath2;
+float TotalDurationOfFlightPath3;
+float TotalDurationOfFlightPath4;
+float LandingPoint;
+float TakeOffPoint;
+CPlaneInterpolationLine aPlaneLineBits[6];
+
+float PlanePathPosition[3];
+float OldPlanePathPosition[3];
+float PlanePathSpeed[3];
+float PlanePath2Position[3];
+float PlanePath3Position;
+float PlanePath4Position;
+float PlanePath2Speed[3];
+float PlanePath3Speed;
+float PlanePath4Speed;
enum
@@ -55,12 +55,12 @@ enum
CESNA_STATUS_LANDED,
};
-int32 &CesnaMissionStatus = *(int32*)0x64CFE8;
-int32 &CesnaMissionStartTime = *(int32*)0x64CFEC;
-CPlane *&pDrugRunCesna = *(CPlane**)0x8F5F80;
-int32 &DropOffCesnaMissionStatus = *(int32*)0x64CFF0;
-int32 &DropOffCesnaMissionStartTime = *(int32*)0x64CFF4;
-CPlane *&pDropOffCesna = *(CPlane**)0x8E2A38;
+int32 CesnaMissionStatus;
+int32 CesnaMissionStartTime;
+CPlane *pDrugRunCesna;
+int32 DropOffCesnaMissionStatus;
+int32 DropOffCesnaMissionStartTime;
+CPlane *pDropOffCesna;
CPlane::CPlane(int32 id, uint8 CreatedBy)
@@ -965,24 +965,3 @@ const CVector CPlane::FindDropOffCesnaCoordinates(void) { return pDropOffCesna->
bool CPlane::HasCesnaLanded(void) { return CesnaMissionStatus == CESNA_STATUS_LANDED; }
bool CPlane::HasCesnaBeenDestroyed(void) { return CesnaMissionStatus == CESNA_STATUS_DESTROYED; }
bool CPlane::HasDropOffCesnaBeenShotDown(void) { return DropOffCesnaMissionStatus == CESNA_STATUS_DESTROYED; }
-
-#include <new>
-
-class CPlane_ : public CPlane
-{
-public:
- void ctor(int32 id, uint8 CreatedBy) { ::new (this) CPlane(id, CreatedBy); }
- void dtor(void) { CPlane::~CPlane(); }
-};
-
-STARTPATCHES
- InjectHook(0x54B170, &CPlane_::ctor, PATCH_JUMP);
- InjectHook(0x54B270, &CPlane_::dtor, PATCH_JUMP);
- InjectHook(0x54B820, CPlane::InitPlanes, PATCH_JUMP);
- InjectHook(0x54BCD0, CPlane::Shutdown, PATCH_JUMP);
- InjectHook(0x54BD50, CPlane::LoadPath, PATCH_JUMP);
- InjectHook(0x54BEC0, CPlane::UpdatePlanes, PATCH_JUMP);
- InjectHook(0x54DE90, CPlane::TestRocketCollision, PATCH_JUMP);
- InjectHook(0x54E000, CPlane::CreateIncomingCesna, PATCH_JUMP);
- InjectHook(0x54E160, CPlane::CreateDropOffCesna, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h
index edca92ec..79738858 100644
--- a/src/vehicles/Plane.h
+++ b/src/vehicles/Plane.h
@@ -33,8 +33,6 @@ public:
int16 m_nPlaneId;
int16 m_isFarAway;
int16 m_nCurPathNode;
- char field_654;
- char field_655;
float m_fSpeed;
uint32 m_nFrameWhenHit;
bool m_bHasBeenHit;
@@ -67,6 +65,6 @@ public:
};
static_assert(sizeof(CPlane) == 0x29C, "CPlane: error");
-extern float &LandingPoint;
-extern float &TakeOffPoint;
-extern float *PlanePathPosition; //[3]
+extern float LandingPoint;
+extern float TakeOffPoint;
+extern float PlanePathPosition[3];
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index 7d81fd57..0d1ff9b0 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "Timer.h"
#include "ModelIndices.h"
#include "FileMgr.h"
@@ -14,23 +14,23 @@
#include "HandlingMgr.h"
#include "Train.h"
-static CTrainNode *&pTrackNodes = *(CTrainNode**)0x8F4338;
-static int16 &NumTrackNodes = *(int16*)0x95CC5C;
+static CTrainNode* pTrackNodes;
+static int16 NumTrackNodes;
static float StationDist[3] = { 873.0f, 1522.0f, 2481.0f };
-static float &TotalLengthOfTrack = *(float*)0x64D000;
-static float &TotalDurationOfTrack = *(float*)0x64D004;
-static CTrainInterpolationLine *aLineBits = (CTrainInterpolationLine*)0x70D838; // [17]
-static float *EngineTrackPosition = (float*)0x64D008; //[2]
-static float *EngineTrackSpeed = (float*)0x880848; //[2]
-
-static CTrainNode *&pTrackNodes_S = *(CTrainNode**)0x8F2560;
-static int16 &NumTrackNodes_S = *(int16*)0x95CC6A;
+static float TotalLengthOfTrack;
+static float TotalDurationOfTrack;
+static CTrainInterpolationLine aLineBits[17];
+static float EngineTrackPosition[2];
+static float EngineTrackSpeed[2];
+
+static CTrainNode* pTrackNodes_S;
+static int16 NumTrackNodes_S;
static float StationDist_S[4] = { 55.0f, 1388.0f, 2337.0f, 3989.0f };
-static float &TotalLengthOfTrack_S = *(float*)0x64D010;
-static float &TotalDurationOfTrack_S = *(float*)0x64D014;
-static CTrainInterpolationLine *aLineBits_S = (CTrainInterpolationLine*)0x726600; // [18]
-static float *EngineTrackPosition_S = (float*)0x64D018; //[4]
-static float *EngineTrackSpeed_S = (float*)0x87C7C8; //[4]
+static float TotalLengthOfTrack_S;
+static float TotalDurationOfTrack_S;
+static CTrainInterpolationLine aLineBits_S[18];
+static float EngineTrackPosition_S[4];
+static float EngineTrackSpeed_S[4];
CVector CTrain::aStationCoors[3];
CVector CTrain::aStationCoors_S[4];
@@ -691,32 +691,3 @@ CTrain::UpdateTrains(void)
time += 0x40000/4;
}
}
-
-#include <new>
-
-class CTrain_ : public CTrain
-{
-public:
- void ctor(int32 id, uint8 CreatedBy) { ::new (this) CTrain(id, CreatedBy); }
- void SetModelIndex_(uint32 id) { CTrain::SetModelIndex(id); }
- void ProcessControl_(void) { CTrain::ProcessControl(); }
- void PreRender_(void) { CTrain::PreRender(); }
- void Render_(void) { CTrain::Render(); }
- void dtor(void) { CTrain::~CTrain(); }
-};
-
-STARTPATCHES
- InjectHook(0x54E470, &CTrain_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x54E4C0, &CTrain_::PreRender_, PATCH_JUMP);
- InjectHook(0x54EAA0, &CTrain_::Render_, PATCH_JUMP);
- InjectHook(0x54E450, &CTrain_::dtor, PATCH_JUMP);
- InjectHook(0x54E2A0, &CTrain_::ctor, PATCH_JUMP);
- InjectHook(0x550300, &CTrain::TrainHitStuff, PATCH_JUMP);
- InjectHook(0x5504A0, &CTrain::AddPassenger, PATCH_JUMP);
- InjectHook(0x550360, &CTrain::OpenTrainDoor, PATCH_JUMP);
-
- InjectHook(0x54F000, CTrain::InitTrains, PATCH_JUMP);
- InjectHook(0x54F360, CTrain::Shutdown, PATCH_JUMP);
- InjectHook(0x54EAB0, CTrain::ReadAndInterpretTrackFile, PATCH_JUMP);
- InjectHook(0x54F3A0, CTrain::UpdateTrains, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index d500d004..5287055d 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Timer.h"
#include "HandlingMgr.h"
#include "Transmission.h"
@@ -136,8 +136,3 @@ cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, fl
}
return fAcceleration;
}
-
-STARTPATCHES
- InjectHook(0x550A00, &cTransmission::CalculateGearForSimpleCar, PATCH_JUMP);
- InjectHook(0x5506B0, &cTransmission::CalculateDriveAcceleration, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index f47fd131..06894447 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -1,6 +1,6 @@
#include "common.h"
#include "main.h"
-#include "patcher.h"
+
#include "General.h"
#include "Timer.h"
#include "Pad.h"
@@ -19,12 +19,12 @@
#include "Fire.h"
#include "Darkel.h"
-bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78;
-bool &CVehicle::bAllDodosCheat = *(bool *)0x95CD75;
-bool &CVehicle::bCheat3 = *(bool *)0x95CD66;
-bool &CVehicle::bCheat4 = *(bool *)0x95CD65;
-bool &CVehicle::bCheat5 = *(bool *)0x95CD64;
-bool &CVehicle::m_bDisableMouseSteering = *(bool *)0x60252C;
+bool CVehicle::bWheelsOnlyCheat;
+bool CVehicle::bAllDodosCheat;
+bool CVehicle::bCheat3;
+bool CVehicle::bCheat4;
+bool CVehicle::bCheat5;
+bool CVehicle::m_bDisableMouseSteering = true;
void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); }
void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); }
@@ -65,7 +65,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_nNumGettingIn = 0;
m_nGettingInFlags = 0;
m_nGettingOutFlags = 0;
- m_nNumMaxPassengers = 8;
+ m_nNumMaxPassengers = ARRAY_SIZE(pPassengers);
for(i = 0; i < m_nNumMaxPassengers; i++)
pPassengers[i] = nil;
m_nBombTimer = 0;
@@ -101,7 +101,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_nLastWeaponDamage = -1;
m_fMapObjectHeightAhead = m_fMapObjectHeightBehind = 0.0f;
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
- if(m_audioEntityId)
+ if(m_audioEntityId >= 0)
DMAudio.SetEntityStatus(m_audioEntityId, true);
m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK;
m_pCurGroundEntity = nil;
@@ -281,7 +281,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
right = -contactSpeedRight/wheelsOnGround;
if(wheelStatus == WHEEL_STATUS_BURST){
- float fwdspeed = min(contactSpeedFwd, 0.3f);
+ float fwdspeed = Min(contactSpeedFwd, 0.3f);
right += fwdspeed * CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
}
}
@@ -533,7 +533,7 @@ CVehicle::DoFixedMachineGuns(void)
void
CVehicle::ExtinguishCarFire(void)
{
- m_fHealth = max(m_fHealth, 300.0f);
+ m_fHealth = Max(m_fHealth, 300.0f);
if(m_pCarFire)
m_pCarFire->Extinguish();
if(IsCar()){
@@ -728,7 +728,7 @@ CVehicle::CanBeDeleted(void)
return false;
}
- for(i = 0; i < 8; i++){
+ for(i = 0; i < ARRAY_SIZE(pPassengers); i++){
// Same check as above
if(pPassengers[i]){
if(pPassengers[i]->CharCreatedBy == MISSION_CHAR)
@@ -787,6 +787,10 @@ CVehicle::CanPedExitCar(void)
{
CVector up = GetUp();
if(up.z > 0.1f || up.z < -0.1f){
+#ifdef VC_PED_PORTS
+ if (IsBoat())
+ return true;
+#endif
// can't exit when car is moving too fast
if(m_vecMoveSpeed.MagnitudeSqr() > 0.005f)
return false;
@@ -870,13 +874,13 @@ CVehicle::SetDriver(CPed *driver)
if(bFreebies && driver == FindPlayerPed()){
if(GetModelIndex() == MI_AMBULAN)
- FindPlayerPed()->m_fHealth = min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f);
+ FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f);
else if(GetModelIndex() == MI_TAXI)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
else if(GetModelIndex() == MI_POLICE)
driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5);
else if(GetModelIndex() == MI_ENFORCER)
- driver->m_fArmour = max(driver->m_fArmour, 100.0f);
+ driver->m_fArmour = Max(driver->m_fArmour, 100.0f);
else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
bFreebies = false;
@@ -937,7 +941,7 @@ void
CVehicle::RemovePassenger(CPed *p)
{
if (IsTrain()){
- for (int i = 0; i < 8; i++){
+ for (int i = 0; i < ARRAY_SIZE(pPassengers); i++){
if (pPassengers[i] == p) {
pPassengers[i] = nil;
m_nNumPassengers--;
@@ -998,66 +1002,15 @@ void
DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
{
if (pVehicle->pDriver) {
-#ifndef FIX_BUGS
- // this just isn't fair
CDarkel::RegisterKillByPlayer(pVehicle->pDriver, WEAPONTYPE_UNIDENTIFIED);
-#endif
pVehicle->pDriver->FlagToDestroyWhenNextProcessed();
}
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
if (pVehicle->pPassengers[i]) {
-#ifndef FIX_BUGS
- // this just isn't fair
CDarkel::RegisterKillByPlayer(pVehicle->pPassengers[i], WEAPONTYPE_UNIDENTIFIED);
-#endif
pVehicle->pPassengers[i]->FlagToDestroyWhenNextProcessed();
}
}
CWorld::Remove(pVehicle);
delete pVehicle;
}
-
-
-class CVehicle_ : public CVehicle
-{
-public:
- void dtor(void) { CVehicle::~CVehicle(); }
- void SetModelIndex_(uint32 id) { CVehicle::SetModelIndex(id); }
- bool SetupLighting_(void) { return CVehicle::SetupLighting(); }
- void RemoveLighting_(bool reset) { CVehicle::RemoveLighting(reset); }
- float GetHeightAboveRoad_(void) { return CVehicle::GetHeightAboveRoad(); }
-};
-
-STARTPATCHES
- InjectHook(0x551170, &CVehicle_::SetModelIndex_, PATCH_JUMP);
- InjectHook(0x4A7DD0, &CVehicle_::SetupLighting_, PATCH_JUMP);
- InjectHook(0x4A7E60, &CVehicle_::RemoveLighting_, PATCH_JUMP);
- InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP);
-
- InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP);
- InjectHook(0x5512E0, &CVehicle::ProcessWheel, PATCH_JUMP);
- InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP);
- InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP);
- InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP);
- InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP);
- InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP);
- InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP);
- InjectHook(0x5527E0, &CVehicle::IsVehicleNormal, PATCH_JUMP);
- InjectHook(0x552B70, &CVehicle::CarHasRoof, PATCH_JUMP);
- InjectHook(0x552230, &CVehicle::IsUpsideDown, PATCH_JUMP);
- InjectHook(0x552260, &CVehicle::IsOnItsSide, PATCH_JUMP);
- InjectHook(0x5511B0, &CVehicle::CanBeDeleted, PATCH_JUMP);
- InjectHook(0x5522A0, &CVehicle::CanPedOpenLocks, PATCH_JUMP);
- InjectHook(0x5522F0, &CVehicle::CanPedEnterCar, PATCH_JUMP);
- InjectHook(0x5523C0, &CVehicle::CanPedExitCar, PATCH_JUMP);
- InjectHook(0x5520C0, &CVehicle::SetUpDriver, PATCH_JUMP);
- InjectHook(0x552160, &CVehicle::SetupPassenger, PATCH_JUMP);
- InjectHook(0x551F20, &CVehicle::SetDriver, PATCH_JUMP);
- InjectHook(0x551D90, (bool (CVehicle::*)(CPed*))&CVehicle::AddPassenger, PATCH_JUMP);
- InjectHook(0x551E10, (bool (CVehicle::*)(CPed*,uint8))&CVehicle::AddPassenger, PATCH_JUMP);
- InjectHook(0x5520A0, &CVehicle::RemoveDriver, PATCH_JUMP);
- InjectHook(0x551EB0, &CVehicle::RemovePassenger, PATCH_JUMP);
- InjectHook(0x5525A0, &CVehicle::ProcessCarAlarm, PATCH_JUMP);
- InjectHook(0x552620, &CVehicle::IsSphereTouchingVehicle, PATCH_JUMP);
- InjectHook(0x551950, &CVehicle::InflictDamage, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index f9becda0..2ae78829 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -130,7 +130,6 @@ public:
int8 m_nGettingInFlags;
int8 m_nGettingOutFlags;
uint8 m_nNumMaxPassengers;
- char field_1CD[3];
float field_1D0[4];
CEntity *m_pCurGroundEntity;
CFire *m_pCarFire;
@@ -180,7 +179,6 @@ public:
int16 m_nRoadblockNode;
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
uint8 m_nCurrentGear;
- int8 field_205[3];
float m_fChangeGearTime;
uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats)
uint32 m_nTimeOfDeath;
@@ -277,12 +275,12 @@ public:
bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE; }
AnimationId GetDriverAnim(void) { return IsCar() && bLowVehicle ? ANIM_CAR_LSIT : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_DRIVE_BOAT : ANIM_CAR_SIT); }
- static bool &bWheelsOnlyCheat;
- static bool &bAllDodosCheat;
- static bool &bCheat3;
- static bool &bCheat4;
- static bool &bCheat5;
- static bool &m_bDisableMouseSteering;
+ static bool bWheelsOnlyCheat;
+ static bool bAllDodosCheat;
+ static bool bCheat3;
+ static bool bCheat4;
+ static bool bCheat5;
+ static bool m_bDisableMouseSteering;
};
static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error");
@@ -296,7 +294,6 @@ class cVehicleParams
{
public:
bool m_bDistanceCalculated;
- char gap_1[3];
float m_fDistance;
CVehicle *m_pVehicle;
cTransmission *m_pTransmission;
diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp
index 54fa6844..36c3cc78 100644
--- a/src/weapons/BulletInfo.cpp
+++ b/src/weapons/BulletInfo.cpp
@@ -1,5 +1,269 @@
#include "common.h"
-#include "patcher.h"
+
#include "BulletInfo.h"
-WRAPPER bool CBulletInfo::TestForSniperBullet(float x1, float x2, float y1, float y2, float z1, float z2) { EAXJMP(0x558D40); }
+#include "AnimBlendAssociation.h"
+#include "AudioManager.h"
+#include "AudioScriptObject.h"
+#ifdef FIX_BUGS
+#include "Collision.h"
+#endif
+#include "RpAnimBlend.h"
+#include "Entity.h"
+#include "EventList.h"
+#include "Fire.h"
+#include "Glass.h"
+#include "Particle.h"
+#include "Ped.h"
+#include "Object.h"
+#include "Stats.h"
+#include "Timer.h"
+#include "Vehicle.h"
+#include "Weapon.h"
+#include "WeaponInfo.h"
+#include "World.h"
+
+#define BULLET_LIFETIME (1000)
+#define NUM_PED_BLOOD_PARTICLES (8)
+#define BLOOD_PARTICLE_OFFSET (CVector(0.0f, 0.0f, 0.0f))
+#define NUM_VEHICLE_SPARKS (16)
+#define NUM_OTHER_SPARKS (8)
+#define BULLET_HIT_FORCE (7.5f)
+#define MAP_BORDER (1960.0f)
+
+CBulletInfo gaBulletInfo[CBulletInfo::NUM_BULLETS];
+bool bPlayerSniperBullet;
+CVector PlayerSniperBulletStart;
+CVector PlayerSniperBulletEnd;
+
+void CBulletInfo::Initialise(void)
+{
+ debug("Initialising CBulletInfo...\n");
+ for (int i = 0; i < NUM_BULLETS; i++) {
+ gaBulletInfo[i].m_bInUse = false;
+ gaBulletInfo[i].m_eWeaponType = WEAPONTYPE_COLT45;
+ gaBulletInfo[i].m_fTimer = 0.0f;
+ gaBulletInfo[i].m_pSource = nil;
+ }
+ debug("CBulletInfo ready\n");
+}
+
+void CBulletInfo::Shutdown(void)
+{
+ debug("Shutting down CBulletInfo...\n");
+ debug("CBulletInfo shut down\n");
+}
+
+bool CBulletInfo::AddBullet(CEntity* pSource, eWeaponType type, CVector vecPosition, CVector vecSpeed)
+{
+ int i;
+ for (i = 0; i < NUM_BULLETS; i++) {
+ if (!gaBulletInfo[i].m_bInUse)
+ break;
+ }
+ if (i == NUM_BULLETS)
+ return false;
+ gaBulletInfo[i].m_pSource = pSource;
+ gaBulletInfo[i].m_eWeaponType = type;
+ gaBulletInfo[i].m_nDamage = CWeaponInfo::GetWeaponInfo(type)->m_nDamage;
+ gaBulletInfo[i].m_vecPosition = vecPosition;
+ gaBulletInfo[i].m_vecSpeed = vecSpeed;
+ gaBulletInfo[i].m_fTimer = CTimer::GetTimeInMilliseconds() + BULLET_LIFETIME;
+ gaBulletInfo[i].m_bInUse = true;
+ return true;
+}
+
+void CBulletInfo::Update(void)
+{
+ bool bAddSound = true;
+ bPlayerSniperBullet = false;
+ for (int i = 0; i < NUM_BULLETS; i++) {
+ CBulletInfo* pBullet = &gaBulletInfo[i];
+ if (pBullet->m_pSource && pBullet->m_pSource->IsPed() && !((CPed*)pBullet->m_pSource)->IsPointerValid())
+ pBullet->m_pSource = nil;
+ if (!pBullet->m_bInUse)
+ continue;
+ if (CTimer::GetTimeInMilliseconds() > pBullet->m_fTimer)
+ pBullet->m_bInUse = false;
+ CVector vecOldPos = pBullet->m_vecPosition;
+ CVector vecNewPos = pBullet->m_vecPosition + pBullet->m_vecSpeed * CTimer::GetTimeStep() * 0.5f;
+ CWorld::bIncludeCarTyres = true;
+ CWorld::bIncludeDeadPeds = true;
+ CWorld::pIgnoreEntity = pBullet->m_pSource;
+ CColPoint point;
+ CEntity* pHitEntity;
+ if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, true)) {
+ if (pBullet->m_pSource && (pHitEntity->IsPed() || pHitEntity->IsVehicle()))
+ CStats::InstantHitsHitByPlayer++;
+ if (pHitEntity->IsPed()) {
+ CPed* pPed = (CPed*)pHitEntity;
+ if (!pPed->DyingOrDead() && pPed != pBullet->m_pSource) {
+ if (pPed->DoesLOSBulletHitPed(point)) {
+ if (pPed->IsPedInControl() && !pPed->bIsDucking) {
+ pPed->ClearAttackByRemovingAnim();
+ CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_SHOT_FRONT_PARTIAL);
+ pAnim->SetBlend(0.0f, 8.0f);
+ }
+ pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point));
+ CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000);
+ pBullet->m_bInUse = false;
+ vecNewPos = point.point;
+ }
+ else {
+ bAddSound = false;
+ }
+ }
+ if (CGame::nastyGame) {
+ CVector vecParticleDirection = (point.point - pPed->GetPosition()) * 0.01f;
+ vecParticleDirection.z = 0.01f;
+ if (pPed->GetIsOnScreen()) {
+ for (int j = 0; j < NUM_PED_BLOOD_PARTICLES; j++)
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point + BLOOD_PARTICLE_OFFSET, vecParticleDirection);
+ }
+ if (pPed->GetPedState() == PED_DEAD) {
+ CAnimBlendAssociation* pAnim;
+ if (RpAnimBlendClumpGetFirstAssociation(pPed->GetClump(), ASSOC_FLAG800))
+ pAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f);
+ else
+ pAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f);
+ if (pAnim) {
+ pAnim->SetCurrentTime(0.0f);
+ pAnim->flags |= ASSOC_RUNNING;
+ pAnim->flags &= ~ASSOC_FADEOUTWHENDONE;
+ }
+ }
+ pBullet->m_bInUse = false;
+ vecNewPos = point.point;
+ }
+ }
+ else if (pHitEntity->IsVehicle()) {
+ CVehicle* pVehicle = (CVehicle*)pHitEntity;
+ pVehicle->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage);
+ if (pBullet->m_eWeaponType == WEAPONTYPE_FLAMETHROWER) // huh?
+ gFireManager.StartFire(pVehicle, pBullet->m_pSource, 0.8f, true);
+ else {
+ for (int j = 0; j < NUM_VEHICLE_SPARKS; j++)
+ CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20);
+ }
+#ifdef FIX_BUGS
+ pBullet->m_bInUse = false;
+ vecNewPos = point.point;
+#endif
+ }
+ else {
+ for (int j = 0; j < NUM_OTHER_SPARKS; j++)
+ CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20);
+ if (pHitEntity->IsObject()) {
+ CObject* pObject = (CObject*)pHitEntity;
+ if (!pObject->bInfiniteMass) {
+ if (pObject->bIsStatic && pObject->m_fUprootLimit <= 0.0f) {
+ pObject->bIsStatic = false;
+ pObject->AddToMovingList();
+ }
+ if (!pObject->bIsStatic)
+ pObject->ApplyMoveForce(-BULLET_HIT_FORCE * point.normal);
+ }
+ }
+#ifdef FIX_BUGS
+ pBullet->m_bInUse = false;
+ vecNewPos = point.point;
+#endif
+ }
+ if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE && bAddSound) {
+ cAudioScriptObject* pAudio;
+ switch (pHitEntity->m_type) {
+ case ENTITY_TYPE_BUILDING:
+ pAudio = new cAudioScriptObject();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_1;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_OBJECT:
+ pAudio = new cAudioScriptObject();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_2;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_DUMMY:
+ pAudio = new cAudioScriptObject();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_3;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_PED:
+ DMAudio.PlayOneShot(((CPed*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)pHitEntity)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ DMAudio.PlayOneShot(((CVehicle*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ }
+ }
+ CGlass::WasGlassHitByBullet(pHitEntity, point.point);
+ CWeapon::BlowUpExplosiveThings(pHitEntity);
+ }
+ CWorld::pIgnoreEntity = nil;
+ CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeCarTyres = false;
+ if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) {
+ bPlayerSniperBullet = true;
+ PlayerSniperBulletStart = pBullet->m_vecPosition;
+ PlayerSniperBulletEnd = vecNewPos;
+ }
+ pBullet->m_vecPosition = vecNewPos;
+ if (pBullet->m_vecPosition.x < -MAP_BORDER || pBullet->m_vecPosition.x > MAP_BORDER ||
+ pBullet->m_vecPosition.y < -MAP_BORDER || pBullet->m_vecPosition.y > MAP_BORDER)
+ pBullet->m_bInUse = false;
+ }
+}
+
+bool CBulletInfo::TestForSniperBullet(float x1, float x2, float y1, float y2, float z1, float z2)
+{
+ if (!bPlayerSniperBullet)
+ return false;
+#ifdef FIX_BUGS // original code is not going work anyway...
+ CColLine line(PlayerSniperBulletStart, PlayerSniperBulletEnd);
+ CColBox box;
+ box.Set(CVector(x1, y1, z1), CVector(x2, y2, z2), 0, 0);
+ return CCollision::TestLineBox(line, box);
+#else
+ float minP = 0.0f;
+ float maxP = 1.0f;
+ float minX = Min(PlayerSniperBulletStart.x, PlayerSniperBulletEnd.x);
+ float maxX = Max(PlayerSniperBulletStart.x, PlayerSniperBulletEnd.x);
+ if (minX < x2 || maxX > x1) {
+ if (minX < x1)
+ minP = Min(minP, (x1 - minX) / (maxX - minX));
+ if (maxX > x2)
+ maxP = Max(maxP, (maxX - x2) / (maxX - minX));
+ }
+ else
+ return false;
+ float minY = Min(PlayerSniperBulletStart.y, PlayerSniperBulletEnd.y);
+ float maxY = Max(PlayerSniperBulletStart.y, PlayerSniperBulletEnd.y);
+ if (minY < y2 || maxY > y1) {
+ if (minY < y1)
+ minP = Min(minP, (y1 - minY) / (maxY - minY));
+ if (maxY > y2)
+ maxP = Max(maxP, (maxY - y2) / (maxY - minY));
+ }
+#ifdef FIX_BUGS
+ else
+ return false;
+#endif
+ float minZ = Min(PlayerSniperBulletStart.z, PlayerSniperBulletEnd.z);
+ float maxZ = Max(PlayerSniperBulletStart.z, PlayerSniperBulletEnd.z);
+ if (minZ < z2 || maxZ > z1) {
+ if (minZ < z1)
+ minP = Min(minP, (z1 - minZ) / (maxZ - minZ));
+ if (maxZ > z2)
+ maxP = Max(maxP, (maxZ - z2) / (maxZ - minZ));
+ }
+ else
+ return false;
+ return minP <= maxP;
+#endif
+}
diff --git a/src/weapons/BulletInfo.h b/src/weapons/BulletInfo.h
index 3905b56d..cf1dd27f 100644
--- a/src/weapons/BulletInfo.h
+++ b/src/weapons/BulletInfo.h
@@ -1,7 +1,25 @@
#pragma once
+#include "WeaponType.h"
+
+class CEntity;
+
class CBulletInfo
{
+ eWeaponType m_eWeaponType;
+ CEntity* m_pSource;
+ float m_fTimer; // big mistake
+ bool m_bInUse;
+ CVector m_vecPosition;
+ CVector m_vecSpeed;
+ int16 m_nDamage;
public:
+ enum {
+ NUM_BULLETS = 100
+ };
+ static void Initialise(void);
+ static void Shutdown(void);
+ static bool AddBullet(CEntity* pSource, eWeaponType type, CVector vecPosition, CVector vecSpeed);
+ static void Update(void);
static bool TestForSniperBullet(float x1, float x2, float y1, float y2, float z1, float z2);
}; \ No newline at end of file
diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp
index 3d00052a..d0a68279 100644
--- a/src/weapons/Explosion.cpp
+++ b/src/weapons/Explosion.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Automobile.h"
#include "Bike.h"
#include "Camera.h"
@@ -19,7 +19,7 @@
#include "WaterLevel.h"
#include "World.h"
-CExplosion(&gaExplosion)[NUM_EXPLOSIONS] = *(CExplosion(*)[NUM_EXPLOSIONS])*(uintptr*)0x64E208;
+CExplosion gaExplosion[NUM_EXPLOSIONS];
// these two were not initialised in original code, I'm really not sure what were they meant to be
RwRGBA colMedExpl = { 0, 0, 0, 0 };
@@ -457,17 +457,4 @@ CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
gaExplosion[i].m_nIteration = 0;
}
}
-}
-
-STARTPATCHES
- InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP);
- InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP);
- InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP);
- InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP);
- InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
- InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
- InjectHook(0x5591C0, &CExplosion::AddExplosion, PATCH_JUMP);
- InjectHook(0x55A0C0, &CExplosion::Update, PATCH_JUMP);
- InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP);
- InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/weapons/Explosion.h b/src/weapons/Explosion.h
index 45e2d5bb..bf54328c 100644
--- a/src/weapons/Explosion.h
+++ b/src/weapons/Explosion.h
@@ -46,4 +46,4 @@ public:
static void RemoveAllExplosionsInArea(CVector pos, float radius);
};
-extern CExplosion (&gaExplosion)[NUM_EXPLOSIONS]; \ No newline at end of file
+extern CExplosion gaExplosion[NUM_EXPLOSIONS]; \ No newline at end of file
diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp
index b33d2d62..c174305c 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "Camera.h"
#include "General.h"
#include "Heli.h"
@@ -13,8 +13,8 @@
#include "Weapon.h"
#include "World.h"
-CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES] = *(CProjectileInfo(*)[NUM_PROJECTILES])*(uintptr*)0x64ED50;
-CProjectile* (&CProjectileInfo::ms_apProjectile)[NUM_PROJECTILES] = *(CProjectile*(*)[NUM_PROJECTILES])*(uintptr*)0x87C748;
+CProjectileInfo gaProjectileInfo[NUM_PROJECTILES];
+CProjectile *CProjectileInfo::ms_apProjectile[NUM_PROJECTILES];
void
CProjectileInfo::Initialise()
@@ -287,16 +287,3 @@ CProjectileInfo::RemoveIfThisIsAProjectile(CObject *object)
ms_apProjectile[i] = nil;
return true;
}
-
-STARTPATCHES
- InjectHook(0x55ADF0, CProjectileInfo::Initialise, PATCH_JUMP);
- InjectHook(0x55AFF0, CProjectileInfo::Shutdown, PATCH_JUMP);
- InjectHook(0x55B010, CProjectileInfo::GetProjectileInfo, PATCH_JUMP);
- InjectHook(0x55B030, CProjectileInfo::AddProjectile, PATCH_JUMP);
- InjectHook(0x55B700, CProjectileInfo::RemoveProjectile, PATCH_JUMP);
- InjectHook(0x55B770, CProjectileInfo::RemoveNotAdd, PATCH_JUMP);
- InjectHook(0x55B7C0, CProjectileInfo::Update, PATCH_JUMP);
- InjectHook(0x55BA50, CProjectileInfo::IsProjectileInRange, PATCH_JUMP);
- InjectHook(0x55BB80, CProjectileInfo::RemoveAllProjectiles, PATCH_JUMP);
- InjectHook(0x55BBD0, CProjectileInfo::RemoveIfThisIsAProjectile, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/weapons/ProjectileInfo.h b/src/weapons/ProjectileInfo.h
index a4ea369a..3d8074c9 100644
--- a/src/weapons/ProjectileInfo.h
+++ b/src/weapons/ProjectileInfo.h
@@ -1,22 +1,23 @@
#pragma once
+#include "WeaponType.h"
+
class CEntity;
class CObject;
class CProjectile;
-enum eWeaponType;
class CProjectileInfo
{
public:
eWeaponType m_eWeaponType;
- CEntity* m_pSource;
+ CEntity *m_pSource;
uint32 m_nExplosionTime;
bool m_bInUse;
CVector m_vecPos;
public:
- static CProjectileInfo* GetProjectileInfo(int32 id);
- static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
+ static CProjectileInfo *GetProjectileInfo(int32 id);
+ static CProjectile *ms_apProjectile[NUM_PROJECTILES];
static void Initialise();
static void Shutdown();
@@ -29,4 +30,4 @@ public:
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
};
-extern CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES]; \ No newline at end of file
+extern CProjectileInfo gaProjectileInfo[NUM_PROJECTILES]; \ No newline at end of file
diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp
index 43d0579d..f09ae052 100644
--- a/src/weapons/ShotInfo.cpp
+++ b/src/weapons/ShotInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "ShotInfo.h"
#include "Entity.h"
#include "Weapon.h"
@@ -13,8 +13,6 @@
CShotInfo gaShotInfo[NUMSHOTINFOS];
float CShotInfo::ms_afRandTable[20];
-// CShotInfo (&gaShotInfo)[100] = *(CShotInfo(*)[100])*(uintptr*)0x64F0D0;
-// float (&CShotInfo::ms_afRandTable)[20] = *(float(*)[20])*(uintptr*)0x6E9878;
/*
Used for flamethrower. I don't know why it's name is CShotInfo.
@@ -111,7 +109,7 @@ CShotInfo::Update()
if (shot.m_sourceEntity) {
assert(shot.m_sourceEntity->IsPed());
CPed *ped = (CPed*) shot.m_sourceEntity;
- float radius = max(1.0f, shot.m_radius);
+ float radius = Max(1.0f, shot.m_radius);
for (int i = 0; i < ped->m_numNearPeds; ++i) {
CPed *nearPed = ped->m_nearPeds[i];
@@ -130,11 +128,4 @@ CShotInfo::Update()
if (!((CTimer::GetFrameCounter() + slot) & 3))
CWorld::SetCarsOnFire(shot.m_startPos.x, shot.m_startPos.y, shot.m_startPos.z, 4.0f, shot.m_sourceEntity);
}
-}
-
-STARTPATCHES
- InjectHook(0x55BFF0, &CShotInfo::Update, PATCH_JUMP);
- InjectHook(0x55BD70, &CShotInfo::AddShot, PATCH_JUMP);
- InjectHook(0x55BC60, &CShotInfo::Initialise, PATCH_JUMP);
- InjectHook(0x55BD50, &CShotInfo::Shutdown, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/weapons/ShotInfo.h b/src/weapons/ShotInfo.h
index a5e5fd35..db6158c2 100644
--- a/src/weapons/ShotInfo.h
+++ b/src/weapons/ShotInfo.h
@@ -1,7 +1,8 @@
#pragma once
+#include "WeaponType.h"
+
class CEntity;
-enum eWeaponType;
class CShotInfo
{
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 0f41264f..a3d52f69 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -1,23 +1,92 @@
#include "common.h"
-#include "patcher.h"
+
#include "Weapon.h"
+#include "AnimBlendAssociation.h"
+#include "AudioManager.h"
+#include "BulletInfo.h"
+#include "Camera.h"
+#include "Coronas.h"
+#include "DMAudio.h"
+#include "Explosion.h"
+#include "General.h"
+#include "Glass.h"
+#include "Heli.h"
+#include "ModelIndices.h"
+#include "Object.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "Ped.h"
+#include "PointLights.h"
+#include "Pools.h"
+#include "ProjectileInfo.h"
+#include "RpAnimBlend.h"
+#include "ShotInfo.h"
+#include "SpecialFX.h"
+#include "Stats.h"
+#include "TempColModels.h"
#include "Timer.h"
+#include "Vehicle.h"
+#include "WaterLevel.h"
#include "WeaponInfo.h"
-#include "Ped.h"
#include "World.h"
-WRAPPER void CWeapon::ShutdownWeapons(void) { EAXJMP(0x55C2F0); }
-WRAPPER void CWeapon::UpdateWeapons(void) { EAXJMP(0x55C310); }
-WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); }
-WRAPPER void CWeapon::FireFromCar(CAutomobile *car, bool left) { EAXJMP(0x55C940); }
-WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, float) { EAXJMP(0x55F770); }
-WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); }
-WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); }
-WRAPPER void CWeapon::InitialiseWeapons(void) { EAXJMP(0x55C2D0); }
-WRAPPER void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage) { EAXJMP(0x563B00); }
+uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] =
+{
+ 0, // UNARMED
+ 0, // BASEBALLBAT
+ 250, // COLT45
+ 400, // UZI
+ 650, // SHOTGUN
+ 300, // AK47
+ 300, // M16
+ 423, // SNIPERRIFLE
+ 400, // ROCKETLAUNCHER
+ 0, // FLAMETHROWER
+ 0, // MOLOTOV
+ 0, // GRENADE
+ 0, // DETONATOR
+ 0 // HELICANNON
+};
+
+CWeaponInfo *
+CWeapon::GetInfo()
+{
+ CWeaponInfo *info = CWeaponInfo::GetWeaponInfo(m_eWeaponType);
+ ASSERT(info!=nil);
+ return info;
+}
+
+void
+CWeapon::InitialiseWeapons(void)
+{
+ CWeaponInfo::Initialise();
+ CShotInfo::Initialise();
+ CExplosion::Initialise();
+ CProjectileInfo::Initialise();
+ CBulletInfo::Initialise();
+}
void
-CWeapon::Initialise(eWeaponType type, int ammo)
+CWeapon::ShutdownWeapons(void)
+{
+ CWeaponInfo::Shutdown();
+ CShotInfo::Shutdown();
+ CExplosion::Shutdown();
+ CProjectileInfo::Shutdown();
+ CBulletInfo::Shutdown();
+}
+
+void
+CWeapon::UpdateWeapons(void)
+{
+ CShotInfo::Update();
+ CExplosion::Update();
+ CProjectileInfo::Update();
+ CBulletInfo::Update();
+}
+
+void
+CWeapon::Initialise(eWeaponType type, int32 ammo)
{
m_eWeaponType = type;
m_eWeaponState = WEAPONSTATE_READY;
@@ -30,13 +99,1873 @@ CWeapon::Initialise(eWeaponType type, int ammo)
m_nTimer = 0;
}
+bool
+CWeapon::Fire(CEntity *shooter, CVector *fireSource)
+{
+ ASSERT(shooter!=nil);
+
+ CVector fireOffset(0.0f, 0.0f, 0.6f);
+ CVector *source = fireSource;
+
+ if (!fireSource) {
+ static CVector tmp;
+ tmp = shooter->GetMatrix() * fireOffset;
+ source = &tmp;
+ }
+ if ( m_bAddRotOffset )
+ {
+ float heading = RADTODEG(shooter->GetForward().Heading());
+ float angle = DEGTORAD(heading);
+ (*source).x += -Sin(angle) * 0.15f;
+ (*source).y += Cos(angle) * 0.15f;
+ }
+
+ if ( m_eWeaponState != WEAPONSTATE_READY && m_eWeaponState != WEAPONSTATE_FIRING )
+ return false;
+
+ bool fired;
+
+ if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE )
+ {
+ if ( m_nAmmoInClip <= 0 )
+ return false;
+
+ switch ( m_eWeaponType )
+ {
+ case WEAPONTYPE_SHOTGUN:
+ {
+ fired = FireShotgun(shooter, source);
+
+ break;
+ }
+
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_AK47:
+ {
+ fired = FireInstantHit(shooter, source);
+
+ break;
+ }
+
+ case WEAPONTYPE_SNIPERRIFLE:
+ {
+ fired = FireSniper(shooter);
+
+ break;
+ }
+
+ case WEAPONTYPE_M16:
+ {
+ if ( TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON && shooter == FindPlayerPed() )
+ fired = FireM16_1stPerson(shooter);
+ else
+ fired = FireInstantHit(shooter, source);
+
+ break;
+ }
+
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ {
+ if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
+ {
+ float distToTarget = (shooter->GetPosition() - ((CPed*)shooter)->m_pSeekTarget->GetPosition()).Magnitude();
+
+ if ( distToTarget > 8.0f || ((CPed*)shooter)->IsPlayer() )
+ fired = FireProjectile(shooter, source, 0.0f);
+ else
+ fired = false;
+ }
+ else
+ fired = FireProjectile(shooter, source, 0.0f);
+
+ break;
+ }
+
+ case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_GRENADE:
+ {
+ if ( shooter == FindPlayerPed() )
+ {
+ fired = FireProjectile(shooter, source, ((CPlayerPed*)shooter)->m_fAttackButtonCounter*0.0375f);
+ if ( m_eWeaponType == WEAPONTYPE_GRENADE )
+ CStats::KgsOfExplosivesUsed++;
+ }
+ else if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
+ {
+ float distToTarget = (shooter->GetPosition() - ((CPed*)shooter)->m_pSeekTarget->GetPosition()).Magnitude();
+ float power = clamp((distToTarget-10.0f)*0.02f, 0.2f, 1.0f);
+
+ fired = FireProjectile(shooter, source, power);
+ }
+ else
+ fired = FireProjectile(shooter, source, 0.3f);
+
+ break;
+ }
+
+ case WEAPONTYPE_FLAMETHROWER:
+ {
+ fired = FireAreaEffect(shooter, source);
+
+ break;
+ }
+
+ case WEAPONTYPE_DETONATOR:
+ {
+ CWorld::UseDetonator(shooter);
+ m_nAmmoTotal = 1;
+ m_nAmmoInClip = m_nAmmoTotal;
+ fired = true;
+
+ break;
+ }
+
+ case WEAPONTYPE_HELICANNON:
+ {
+ if ( (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON )
+ && shooter == FindPlayerPed() )
+ {
+ fired = FireM16_1stPerson(shooter);
+ }
+ else
+ fired = FireInstantHit(shooter, source);
+
+ break;
+ }
+
+ default:
+ {
+ debug("Unknown weapon type, Weapon.cpp");
+ break;
+ }
+ }
+
+ if ( fired )
+ {
+ bool isPlayer = false;
+
+ if ( shooter->IsPed() )
+ {
+ CPed *shooterPed = (CPed*)shooter;
+
+ shooterPed->bIsShooting = true;
+
+ if ( shooterPed->IsPlayer() )
+ isPlayer = true;
+
+ DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+ }
+
+ if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--;
+ if ( m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer) ) m_nAmmoTotal--;
+
+ if ( m_eWeaponState == WEAPONSTATE_READY && m_eWeaponType == WEAPONTYPE_FLAMETHROWER )
+ DMAudio.PlayOneShot(((CPhysical*)shooter)->m_audioEntityId, SOUND_WEAPON_FLAMETHROWER_FIRE, 0.0f);
+
+ m_eWeaponState = WEAPONSTATE_FIRING;
+ }
+
+ if ( m_nAmmoInClip == 0 )
+ {
+ if ( m_nAmmoTotal == 0 )
+ return true;
+
+ m_eWeaponState = WEAPONSTATE_RELOADING;
+ m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
+
+ if ( shooter == FindPlayerPed() )
+ {
+ if ( CWorld::Players[CWorld::PlayerInFocus].m_bFastReload )
+ m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload / 4;
+ }
+
+ return true;
+ }
+
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ if ( shooter == FindPlayerPed() )
+ CStats::RoundsFiredByPlayer++;
+ }
+ else
+ {
+ if ( m_eWeaponState != WEAPONSTATE_FIRING )
+ {
+ m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
+ m_eWeaponState = WEAPONSTATE_FIRING;
+ }
+
+ FireMelee(shooter, *source);
+ }
+
+ if ( m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BASEBALLBAT )
+ return true;
+ else
+ return fired;
+}
+
+bool
+CWeapon::FireFromCar(CAutomobile *shooter, bool left)
+{
+ ASSERT(shooter!=nil);
+
+ if ( m_eWeaponState != WEAPONSTATE_READY && m_eWeaponState != WEAPONSTATE_FIRING )
+ return false;
+
+ if ( m_nAmmoInClip <= 0 )
+ return false;
+
+ if ( FireInstantHitFromCar(shooter, left) )
+ {
+ DMAudio.PlayOneShot(shooter->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--;
+ if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 ) m_nAmmoTotal--;
+
+ m_eWeaponState = WEAPONSTATE_FIRING;
+
+ if ( m_nAmmoInClip == 0 )
+ {
+ if ( m_nAmmoTotal == 0 )
+ return true;
+
+ m_eWeaponState = WEAPONSTATE_RELOADING;
+ m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
+
+ return true;
+ }
+
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ if ( shooter == FindPlayerVehicle() )
+ CStats::RoundsFiredByPlayer++;
+ }
+
+ return true;
+}
+
+bool
+CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
+{
+ ASSERT(shooter!=nil);
+
+ CWeaponInfo *info = GetInfo();
+
+ bool anim2Playing = false;
+ if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), info->m_Anim2ToPlay) )
+ anim2Playing = true;
+
+ ASSERT(shooter->IsPed());
+
+ CPed *shooterPed = (CPed*)shooter;
+
+ for ( int32 i = 0; i < shooterPed->m_numNearPeds; i++ )
+ {
+ CPed *victimPed = shooterPed->m_nearPeds[i];
+ ASSERT(victimPed!=nil);
+
+ if ( (victimPed->m_nPedType != shooterPed->m_nPedType || victimPed == shooterPed->m_pSeekTarget)
+ && victimPed != shooterPed->m_leader || !(CGeneral::GetRandomNumber() & 31) )
+ {
+ bool collided = false;
+
+ CColModel *victimPedCol = &CTempColModels::ms_colModelPed1;
+ if ( victimPed->OnGround() || !victimPed->IsPedHeadAbovePos(-0.3f) )
+ victimPedCol = &CTempColModels::ms_colModelPedGroundHit;
+
+
+ float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius;
+ if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() )
+ {
+ CVector victimPedPos = victimPed->GetPosition();
+ if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() )
+ {
+ CVector collisionDist;
+
+ int32 s = 0;
+ while ( s < victimPedCol->numSpheres )
+ {
+ CColSphere *sphere = &victimPedCol->spheres[s];
+ collisionDist = victimPedPos+sphere->center-(*fireSource);
+
+ if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() )
+ {
+ collided = true;
+ break;
+ }
+ s++;
+ }
+
+ if ( !(victimPed->IsPlayer() && victimPed->GetPedState() == PED_GETUP) )
+ {
+ if ( collided )
+ {
+ float victimPedHealth = victimPed->m_fHealth;
+ CVector bloodPos = fireSource + (collisionDist*0.7f);
+
+ CVector2D posOffset(shooterPed->GetPosition().x-victimPedPos.x, shooterPed->GetPosition().y-victimPedPos.y);
+
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
+
+ bool isBat = m_eWeaponType == WEAPONTYPE_BASEBALLBAT;
+
+ if ( !victimPed->DyingOrDead() )
+ victimPed->ReactToAttack(shooterPed);
+
+ uint8 hitLevel = HITLEVEL_HIGH;
+ if ( isBat && victimPed->OnGround() )
+ hitLevel = HITLEVEL_GROUND;
+
+ victimPed->StartFightDefend(localDir, hitLevel, 10);
+
+ if ( !victimPed->DyingOrDead() )
+ {
+ if ( shooterPed->IsPlayer() && isBat && anim2Playing )
+ victimPed->InflictDamage(shooterPed, m_eWeaponType, 100.0f, PEDPIECE_TORSO, localDir);
+ else if ( shooterPed->IsPlayer() && ((CPlayerPed*)shooterPed)->m_bAdrenalineActive )
+ victimPed->InflictDamage(shooterPed, m_eWeaponType, 3.5f*info->m_nDamage, PEDPIECE_TORSO, localDir);
+ else
+ {
+ if ( victimPed->IsPlayer() && isBat ) // wtf, it's not fair
+ victimPed->InflictDamage(shooterPed, m_eWeaponType, 2.0f*info->m_nDamage, PEDPIECE_TORSO, localDir);
+ else
+ victimPed->InflictDamage(shooterPed, m_eWeaponType, info->m_nDamage, PEDPIECE_TORSO, localDir);
+ }
+ }
+
+ if ( CGame::nastyGame )
+ {
+ if ( victimPed->GetIsOnScreen() )
+ {
+ CVector dir = collisionDist * RecipSqrt(1.0f, 10.0f*collisionDist.MagnitudeSqr());
+
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir);
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir);
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir);
+
+ if ( isBat )
+ {
+ dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir);
+
+ dir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ dir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir);
+ }
+ }
+ }
+
+ if ( !victimPed->OnGround() )
+ {
+ if ( victimPed->m_fHealth > 0.0f
+ && (victimPed->m_fHealth < 20.0f && victimPedHealth > 20.0f || isBat && !victimPed->IsPlayer()) )
+ {
+ posOffset.Normalise();
+ victimPed->bIsStanding = false;
+ victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f);
+
+ if ( isBat && victimPed->IsPlayer() )
+ victimPed->SetFall(3000, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
+ else
+ victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
+
+ shooterPed->m_pSeekTarget = victimPed;
+ shooterPed->m_pSeekTarget->RegisterReference(&shooterPed->m_pSeekTarget);
+ }
+ }
+ else if (victimPed->Dying() && !anim2Playing)
+ {
+ posOffset.Normalise();
+ victimPed->bIsStanding = false;
+ victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 3.0f);
+ }
+
+ m_eWeaponState = WEAPONSTATE_MELEE_MADECONTACT;
+
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_ASSAULT_POLICE, EVENT_ENTITY_PED, victimPed, shooterPed, 2000);
+ else
+ CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_PED, victimPed, shooterPed, 2000);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(fireSource!=nil);
+
+ CWeaponInfo *info = GetInfo();
+
+ CVector source, target;
+ CColPoint point;
+ CEntity *victim = nil;
+
+ float heading = RADTODEG(shooter->GetForward().Heading());
+ float angle = DEGTORAD(heading);
+
+ CVector2D ahead(-Sin(angle), Cos(angle));
+ ahead.Normalise();
+
+ CVector vel = ((CPed *)shooter)->m_vecMoveSpeed;
+ int32 shooterMoving = false;
+ if ( Abs(vel.x) > 0.0f && Abs(vel.y) > 0.0f )
+ shooterMoving = true;
+
+ if ( shooter == FindPlayerPed() )
+ {
+ static float prev_heading = 0.0f;
+ prev_heading = ((CPed*)shooter)->m_fRotationCur;
+ }
+
+ if ( shooter->IsPed() && ((CPed *)shooter)->m_pPointGunAt )
+ {
+ CPed *shooterPed = (CPed *)shooter;
+ if ( shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY )
+ {
+ int32 accuracy = shooterPed->m_wepAccuracy;
+ int32 inaccuracy = 100-accuracy;
+
+ if ( accuracy != 100 )
+ FindPlayerPed(); //what ?
+
+ CPed *threatAttack = (CPed*)shooterPed->m_pPointGunAt;
+ if ( threatAttack->IsPed() )
+ {
+ threatAttack->m_pedIK.GetComponentPosition(target, PED_MID);
+ threatAttack->ReactToPointGun(shooter);
+ }
+ else
+ target = threatAttack->GetPosition();
+
+ target -= *fireSource;
+ target *= info->m_fRange / target.Magnitude();
+ target += *fireSource;
+
+ if ( inaccuracy != 0 )
+ {
+ target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
+ target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
+ target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy;
+ }
+
+ CWorld::bIncludeDeadPeds = true;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeDeadPeds = false;
+ }
+ else
+ {
+ target.x = info->m_fRange;
+ target.y = 0.0f;
+ target.z = 0.0f;
+
+ shooterPed->TransformToNode(target, PED_HANDR);
+
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ }
+ }
+ else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
+ {
+ CVector src, trgt;
+ TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
+
+ CWorld::bIncludeDeadPeds = true;
+ ProcessLineOfSight(src, trgt,point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeDeadPeds = false;
+
+ int32 rotSpeed = 1;
+ if ( m_eWeaponType == WEAPONTYPE_M16 )
+ rotSpeed = 4;
+
+ CVector bulletPos;
+ if ( CHeli::TestBulletCollision(&src, &trgt, &bulletPos, 4) )
+ {
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
+ }
+ }
+ else
+ {
+ float shooterHeading = RADTODEG(shooter->GetForward().Heading());
+ float shooterAngle = DEGTORAD(shooterHeading);
+
+ CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle));
+ rotOffset.Normalise();
+
+ target = *fireSource;
+ target.x += rotOffset.x * info->m_fRange;
+ target.y += rotOffset.y * info->m_fRange;
+
+ if ( shooter->IsPed() )
+ DoDoomAiming(shooter, fireSource, &target);
+
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+
+ int32 rotSpeed = 1;
+ if ( m_eWeaponType == WEAPONTYPE_M16 )
+ rotSpeed = 4;
+
+ CVector bulletPos;
+ if ( CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4) )
+ {
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
+ }
+ }
+
+ if ( victim && shooter->IsPed() && victim == ((CPed*)shooter)->m_leader )
+ return false;
+
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed *)shooter, 1000);
+
+ if ( shooter == FindPlayerPed() )
+ {
+ CStats::InstantHitsFiredByPlayer++;
+ if ( !(CTimer::GetFrameCounter() & 3) )
+ MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target);
+ }
+
+ switch ( m_eWeaponType )
+ {
+ case WEAPONTYPE_AK47:
+ {
+ static uint8 counter = 0;
+
+ if ( !(++counter & 1) )
+ {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CVector gunflashPos = *fireSource;
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.10f);
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
+ gunflashPos += CVector(0.05f*ahead.x, 0.05f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+ gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+
+ CVector gunsmokePos = *fireSource;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f));
+
+ CVector gunshellPos = *fireSource;
+ gunshellPos -= CVector(0.5f*ahead.x, 0.5f*ahead.y, 0.0f);
+ CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ dir.Normalise2D();
+ AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.018f);
+ }
+
+ break;
+ }
+
+ case WEAPONTYPE_M16:
+ {
+ static uint8 counter = 0;
+
+ if ( !(++counter & 1) )
+ {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CVector gunflashPos = *fireSource;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+
+ gunflashPos = *fireSource;
+ gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z += 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = *fireSource;
+ gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z -= 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ offset.Normalise2D();
+
+ gunflashPos = *fireSource;
+ gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
+ gunflashPos += CVector(0.06f*offset.x, 0.06f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f*offset.x, 0.04f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f*offset.x, 0.03f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = *fireSource;
+ gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
+ gunflashPos -= CVector(0.06f*offset.x, 0.06f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos -= CVector(0.04f*offset.x, 0.04f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos -= CVector(0.03f*offset.x, 0.03f*offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector gunsmokePos = *fireSource;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f));
+
+ CVector gunshellPos = *fireSource;
+ gunshellPos -= CVector(0.65f*ahead.x, 0.65f*ahead.y, 0.0f);
+ CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ dir.Normalise2D();
+ AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.02f);
+ }
+
+ break;
+ }
+
+ case WEAPONTYPE_UZI:
+ {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CVector gunflashPos = *fireSource;
+
+ if ( shooterMoving )
+ gunflashPos += CVector(1.5f*vel.x, 1.5f*vel.y, 0.0f);
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.07f);
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.05f);
+ gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f*ahead.x, 0.03f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f*ahead.x, 0.03f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos += CVector(0.02f*ahead.x, 0.02f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.01f);
+
+ CVector gunsmokePos = *fireSource;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f));
+
+ CVector gunshellPos = *fireSource;
+ gunshellPos -= CVector(0.2f*ahead.x, 0.2f*ahead.y, 0.0f);
+ CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ dir.Normalise2D();
+ AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.015f);
+
+ break;
+ }
+
+ case WEAPONTYPE_COLT45:
+ {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ *fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CVector gunflashPos = *fireSource;
+
+ if ( shooterMoving )
+ gunflashPos += CVector(1.5f*vel.x, 1.5f*vel.y, 0.0f);
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+ gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector gunsmokePos = *fireSource;
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*0.10f, ahead.y*0.10f, 0.0f), nil, 0.005f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*0.15f, ahead.y*0.15f, 0.0f), nil, 0.015f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*0.20f, ahead.y*0.20f, 0.0f), nil, 0.025f);
+
+ CVector gunshellPos = *fireSource;
+ gunshellPos -= CVector(0.2f*ahead.x, 0.2f*ahead.y, 0.0f);
+ CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ dir.Normalise2D();
+ AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.015f);
+
+ break;
+ }
+ }
+
+ DoBulletImpact(shooter, victim, fireSource, &target, &point, ahead);
+
+ return true;
+}
+
+void
+CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &direction, float size)
+{
+ ASSERT(shooter!=nil);
+
+ if ( shooter == nil)
+ return;
+
+ CVector dir(direction.x*0.05f, direction.y*0.05f, CGeneral::GetRandomNumberInRange(0.02f, 0.08f));
+
+ static CVector prevEntityPosition(0.0f, 0.0f, 0.0f);
+ CVector entityPosition = shooter->GetPosition();
+
+ CVector diff = entityPosition - prevEntityPosition;
+
+ if ( Abs(diff.x)+Abs(diff.y)+Abs(diff.z) > 1.5f )
+ {
+ prevEntityPosition = entityPosition;
+
+ CParticle::AddParticle(PARTICLE_GUNSHELL_FIRST,
+ source, dir, nil, size, CGeneral::GetRandomNumberInRange(-20.0f, 20.0f));
+ }
+ else
+ {
+ CParticle::AddParticle(PARTICLE_GUNSHELL,
+ source, dir, nil, size, CGeneral::GetRandomNumberInRange(-20.0f, 20.0f));
+ }
+}
+
+void
+CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
+ CVector *source, CVector *target, CColPoint *point, CVector2D ahead)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(source!=nil);
+ ASSERT(target!=nil);
+ ASSERT(point!=nil);
+
+ CWeaponInfo *info = GetInfo();
+
+ if ( victim )
+ {
+ CGlass::WasGlassHitByBullet(victim, point->point);
+
+ CVector traceTarget = point->point;
+ CBulletTraces::AddTrace(source, &traceTarget);
+
+ if ( shooter != nil )
+ {
+ if ( shooter == FindPlayerPed() )
+ {
+ if ( victim->IsPed() || victim->IsVehicle() )
+ CStats::InstantHitsHitByPlayer++;
+ }
+ }
+
+ if ( victim->IsPed() && ((CPed*)shooter)->m_nPedType != ((CPed*)victim)->m_nPedType || ((CPed*)shooter)->m_nPedType == PEDTYPE_PLAYER2 )
+ {
+ CPed *victimPed = (CPed *)victim;
+ if ( !victimPed->OnGround() && victim != shooter )
+ {
+ if ( victimPed->DoesLOSBulletHitPed(*point) )
+ {
+ CVector pos = victimPed->GetPosition();
+
+ CVector2D posOffset(source->x-pos.x, source->y-pos.y);
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
+
+ victimPed->ReactToAttack(shooter);
+
+ if ( !victimPed->IsPedInControl() || victimPed->bIsDucking )
+ {
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ }
+ else
+ {
+ if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON )
+ {
+ posOffset.Normalise();
+ victimPed->bIsStanding = false;
+
+ victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 5.0f);
+ victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
+
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ }
+ else
+ {
+ if ( victimPed->IsPlayer() )
+ {
+ CPlayerPed *victimPlayer = (CPlayerPed *)victimPed;
+ if ( victimPlayer->m_nHitAnimDelayTimer < CTimer::GetTimeInMilliseconds() )
+ {
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_SHOT_FRONT_PARTIAL + localDir));
+ ASSERT(asoc!=nil);
+
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
+
+ if ( m_eWeaponType == WEAPONTYPE_AK47 || m_eWeaponType == WEAPONTYPE_M16 )
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ else
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ }
+ }
+ else
+ {
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_SHOT_FRONT_PARTIAL + localDir));
+ ASSERT(asoc!=nil);
+
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
+ }
+
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ }
+ }
+
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ else
+ CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+
+ if ( CGame::nastyGame )
+ {
+ uint8 bloodAmount = 8;
+ if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON )
+ bloodAmount = 32;
+
+ CVector dir = (point->point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
+
+ if ( victimPed->GetIsOnScreen() )
+ {
+ for ( uint8 i = 0; i < bloodAmount; i++ )
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point, dir);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( CGame::nastyGame )
+ {
+ CVector dir = (point->point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
+
+ if ( victim->GetIsOnScreen() )
+ {
+ for ( int32 i = 0; i < 8; i++ )
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point + CVector(0.0f, 0.0f, 0.15f), dir);
+ }
+
+ if ( victimPed->Dead() )
+ {
+ CAnimBlendAssociation *asoc;
+ if ( RpAnimBlendClumpGetFirstAssociation(victimPed->GetClump(), ASSOC_FLAG800) )
+ asoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f);
+ else
+ asoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f);
+
+ if ( asoc )
+ {
+ asoc->SetCurrentTime(0.0f);
+ asoc->flags |= ASSOC_RUNNING;
+ asoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_BUILDING:
+ {
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
+
+ CVector dist = point->point - (*source);
+ CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(ahead.x, ahead.y, 0.0f);
+ CVector smokePos = *source + offset;
+
+ smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ smokePos.z += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
+
+ break;
+ }
+ case ENTITY_TYPE_VEHICLE:
+ {
+ ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage);
+
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
+
+ CVector dist = point->point - (*source);
+ CVector offset = dist - Max(0.2f*dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f);
+ CVector smokePos = *source + offset;
+
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
+
+ if ( shooter->IsPed() )
+ {
+ CPed *shooterPed = (CPed *)shooter;
+
+ if ( shooterPed->bNotAllowedToDuck )
+ {
+ if ( shooterPed->bKindaStayInSamePlace && victim != shooterPed->m_pPointGunAt )
+ {
+ shooterPed->bKindaStayInSamePlace = false;
+ shooterPed->m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds() + 15000;
+ }
+ }
+ }
+
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ {
+ for ( int32 i = 0; i < 8; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
+
+ CObject *victimObject = (CObject *)victim;
+
+ if ( !victimObject->bInfiniteMass )
+ {
+ if ( victimObject->bIsStatic && victimObject->m_fUprootLimit <= 0.0f )
+ {
+ victimObject->bIsStatic = false;
+ victimObject->AddToMovingList();
+ }
+
+ if ( !victimObject->bIsStatic )
+ {
+ CVector moveForce = point->normal*-4.0f;
+ victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_BUILDING:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_1, point->point);
+ break;
+ }
+ case ENTITY_TYPE_VEHICLE:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ }
+ case ENTITY_TYPE_PED:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point->point);
+ break;
+ }
+ case ENTITY_TYPE_DUMMY:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_3, point->point);
+ break;
+ }
+ }
+ }
+ else
+ CBulletTraces::AddTrace(source, target);
+
+ if ( shooter == FindPlayerPed() )
+ CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
+
+ BlowUpExplosiveThings(victim);
+}
+
+bool
+CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(fireSource!=nil);
+
+ CWeaponInfo *info = GetInfo();
+
+ float heading = RADTODEG(shooter->GetForward().Heading());
+ float angle = DEGTORAD(heading);
+
+ CVector2D rotOffset(-Sin(angle), Cos(angle));
+ rotOffset.Normalise();
+
+ CVector gunflashPos = *fireSource;
+ gunflashPos += CVector(rotOffset.x*0.1f, rotOffset.y*0.1f, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f);
+ gunflashPos += CVector(rotOffset.x*0.1f, rotOffset.y*0.1f, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.15f);
+ gunflashPos += CVector(rotOffset.x*0.1f, rotOffset.y*0.1f, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.2f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH, *fireSource, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f);
+
+ CVector gunsmokePos = *fireSource;
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(rotOffset.x*0.10f, rotOffset.y*0.10f, 0.0f), nil, 0.1f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(rotOffset.x*0.15f, rotOffset.y*0.15f, 0.0f), nil, 0.1f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(rotOffset.x*0.20f, rotOffset.y*0.20f, 0.0f), nil, 0.1f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(rotOffset.x*0.25f, rotOffset.y*0.25f, 0.0f), nil, 0.1f);
+
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed*)shooter, 1000);
+
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, *fireSource, CVector(0.0, 0.0, 0.0), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ float shooterAngle;
+
+ if ( shooter->IsPed() && ((CPed*)shooter)->m_pPointGunAt != nil )
+ {
+ CEntity *threatAttack = ((CPed*)shooter)->m_pPointGunAt;
+ shooterAngle = CGeneral::GetAngleBetweenPoints(threatAttack->GetPosition().x, threatAttack->GetPosition().y,
+ (*fireSource).x, (*fireSource).y);
+ }
+ else
+ shooterAngle = RADTODEG(shooter->GetForward().Heading());
+
+
+ for ( int32 i = 0; i < 5; i++ ) // five shoots at once
+ {
+ float shootAngle = DEGTORAD(7.5f*i + shooterAngle - 15.0f);
+ CVector2D shootRot(-Sin(shootAngle), Cos(shootAngle));
+
+ CVector source, target;
+ CColPoint point;
+ CEntity *victim;
+
+ if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
+ {
+ TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
+ CVector Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up);
+
+ float f = float(i - 2) * (DEGTORAD(7.5f) / 2);
+ target = f * Left + target - source;
+ target *= info->m_fRange;
+ target += source;
+
+ ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ }
+ else
+ {
+ target = *fireSource;
+ target.x += shootRot.x * info->m_fRange;
+ target.y += shootRot.y * info->m_fRange;
+
+ if ( shooter->IsPed() )
+ {
+ CPed *shooterPed = (CPed *)shooter;
+
+ if ( shooterPed->m_pPointGunAt == nil )
+ DoDoomAiming(shooter, fireSource, &target);
+ else
+ {
+ float distToTarget = (shooterPed->m_pPointGunAt->GetPosition() - (*fireSource)).Magnitude2D();
+ target.z += info->m_fRange / distToTarget * (shooterPed->m_pPointGunAt->GetPosition().z - target.z);
+ }
+ }
+
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ }
+
+ if ( victim )
+ {
+ CGlass::WasGlassHitByBullet(victim, point.point);
+
+ CBulletTraces::AddTrace(fireSource, &point.point);
+
+ if ( victim->IsPed() )
+ {
+ CPed *victimPed = (CPed *)victim;
+ if ( !victimPed->OnGround() && victim != shooter && victimPed->DoesLOSBulletHitPed(point) )
+ {
+ bool cantStandup = true;
+
+ CVector pos = victimPed->GetPosition();
+
+ CVector2D posOffset((*fireSource).x-pos.x, (*fireSource).y-pos.y);
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
+
+ victimPed->ReactToAttack(FindPlayerPed());
+
+ posOffset.Normalise();
+
+ if ( victimPed->m_getUpTimer > (CTimer::GetTimeInMilliseconds() - 3000) )
+ cantStandup = false;
+
+ if ( victimPed->bIsStanding && cantStandup )
+ {
+ victimPed->bIsStanding = false;
+
+ victimPed->ApplyMoveForce(posOffset.x*-6.0f, posOffset.y*-6.0f, 5.0f);
+ }
+ else
+ victimPed->ApplyMoveForce(posOffset.x*-2.0f, posOffset.y*-2.0f, 0.0f);
+
+ if ( cantStandup )
+ victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
+
+ victimPed->InflictDamage(nil, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point.pieceB, localDir);
+
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ else
+ CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+
+ if ( CGame::nastyGame )
+ {
+ uint8 bloodAmount = 8;
+ if ( m_eWeaponType == WEAPONTYPE_SHOTGUN )
+ bloodAmount = 32;
+
+ CVector dir = (point.point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
+
+ if ( victimPed->GetIsOnScreen() )
+ {
+ for ( uint8 i = 0; i < bloodAmount; i++ )
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point, dir);
+ }
+ }
+ }
+ }
+ else
+ {
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_VEHICLE:
+ {
+ ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage);
+
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f);
+
+ CVector dist = point.point - (*fireSource);
+ CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f);
+ CVector smokePos = *fireSource + offset;
+
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
+
+ break;
+ }
+
+ case ENTITY_TYPE_BUILDING:
+ case ENTITY_TYPE_OBJECT:
+ {
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal*0.05f);
+
+ CVector dist = point.point - (*fireSource);
+ CVector offset = dist - Max(0.2f*dist.Magnitude(), 2.0f) * CVector(shootRot.x, shootRot.y, 0.0f);
+ CVector smokePos = *fireSource + offset;
+
+ smokePos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ smokePos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ smokePos.z += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, smokePos, CVector(0.0f, 0.0f, 0.0f));
+
+ if ( victim->IsObject() )
+ {
+ CObject *victimObject = (CObject *)victim;
+
+ if ( !victimObject->bInfiniteMass )
+ {
+ if ( victimObject->bIsStatic && victimObject->m_fUprootLimit <= 0.0f )
+ {
+ victimObject->bIsStatic = false;
+ victimObject->AddToMovingList();
+ }
+
+ if ( !victimObject->bIsStatic )
+ {
+ CVector moveForce = point.normal*-5.0f;
+ victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_BUILDING:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_1, point.point);
+ break;
+ }
+ case ENTITY_TYPE_VEHICLE:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ }
+ case ENTITY_TYPE_PED:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
+ break;
+ }
+ case ENTITY_TYPE_DUMMY:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_3, point.point);
+ break;
+ }
+ }
+ }
+ else
+ {
+ CVector traceTarget = *fireSource;
+ traceTarget += (target - (*fireSource)) * Min(info->m_fRange, 30.0f) / info->m_fRange;
+ CBulletTraces::AddTrace(fireSource, &traceTarget);
+ }
+ }
+
+ if ( shooter == FindPlayerPed() )
+ CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
+
+ return true;
+}
+
+bool
+CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(fireSource!=nil);
+
+ CVector source, target;
+
+ if ( m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER )
+ {
+ source = *fireSource;
+
+ if ( shooter->IsPed() && ((CPed*)shooter)->IsPlayer() )
+ {
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+ {
+ return false;
+ }
+
+ *fireSource += TheCamera.Cams[TheCamera.ActiveCam].Front;
+ }
+ else
+ *fireSource += shooter->GetForward();
+
+ target = *fireSource;
+ }
+ else
+ {
+ float dot = DotProduct(*fireSource-shooter->GetPosition(), shooter->GetForward());
+
+ if ( dot < 0.3f )
+ *fireSource += (0.3f-dot) * shooter->GetForward();
+
+ target = *fireSource;
+
+ if ( target.z - shooter->GetPosition().z > 0.0f )
+ target += 0.6f*shooter->GetForward();
+
+ source = *fireSource - shooter->GetPosition();
+
+ source = *fireSource - DotProduct(source, shooter->GetForward()) * shooter->GetForward();
+ }
+
+ if ( !CWorld::GetIsLineOfSightClear(source, target, true, true, false, true, false, false, false) )
+ {
+ if ( m_eWeaponType != WEAPONTYPE_GRENADE )
+ CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
+ else
+ {
+ if ( shooter->IsPed() )
+ {
+ source = shooter->GetPosition() - shooter->GetForward();
+ source.z -= 0.4f;
+
+ if ( !CWorld::TestSphereAgainstWorld(source, 0.5f, nil, false, false, true, false, false, false) )
+ CProjectileInfo::AddProjectile(shooter, m_eWeaponType, source, 0.0f);
+ else
+ CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
+ }
+ }
+ }
+ else
+ CProjectileInfo::AddProjectile(shooter, m_eWeaponType, *fireSource, power);
+
+ return true;
+}
+
+void
+CWeapon::GenerateFlameThrowerParticles(CVector pos, CVector dir)
+{
+ dir *= 0.7f;
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos, dir);
+
+ dir *= 0.7f;
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos, dir);
+
+ dir *= 0.7f;
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos, dir);
+
+ dir *= 0.7f;
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos, dir);
+
+ dir *= 0.7f;
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos, dir);
+}
+
+bool
+CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(fireSource!=nil);
+
+ CWeaponInfo *info = GetInfo();
+
+ float heading = RADTODEG(shooter->GetForward().Heading());
+
+ CVector source;
+ CVector target;
+ CVector dir;
+
+ if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
+ {
+ TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+ float norm = (1.0f / info->m_fRange);
+ dir = (target - source) * norm;
+ }
+ else
+ {
+ float angle = DEGTORAD(heading);
+ dir = CVector(-Sin(angle)*0.5f, Cos(angle)*0.5f, 0.0f);
+ target = *fireSource + dir;
+ }
+
+ CShotInfo::AddShot(shooter, m_eWeaponType, *fireSource, target);
+ CWeapon::GenerateFlameThrowerParticles(*fireSource, dir);
+
+ return true;
+}
+
+bool
+CWeapon::FireSniper(CEntity *shooter)
+{
+ ASSERT(shooter!=nil);
+
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+ {
+ return false;
+ }
+
+#ifndef FIX_BUGS
+ CWeaponInfo *info = GetInfo(); //unused
+#endif
+
+ CCam *cam = &TheCamera.Cams[TheCamera.ActiveCam];
+ ASSERT(cam!=nil);
+
+ CVector source = cam->Source;
+ CVector dir = cam->Front;
+
+ if ( DotProduct(dir, CVector(0.0f, -0.9894f, 0.145f)) > 0.997f )
+ CCoronas::bSmallMoon = !CCoronas::bSmallMoon;
+
+ dir.Normalise();
+ dir *= 16.0f;
+
+ CBulletInfo::AddBullet(shooter, m_eWeaponType, source, dir);
+
+ if ( shooter == FindPlayerPed() )
+ CStats::InstantHitsFiredByPlayer++;
+
+ if ( shooter == FindPlayerPed() )
+ {
+ CPad::GetPad(0)->StartShake_Distance(240, 128,
+ FindPlayerPed()->GetPosition().x,
+ FindPlayerPed()->GetPosition().y,
+ FindPlayerPed()->GetPosition().z);
+
+ CamShakeNoPos(&TheCamera, 0.2f);
+ }
+
+ return true;
+}
+
+bool
+CWeapon::FireM16_1stPerson(CEntity *shooter)
+{
+ ASSERT(shooter!=nil);
+
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT
+ || mode == CCam::MODE_HELICANNON_1STPERSON) )
+ {
+ return false;
+ }
+
+ CWeaponInfo *info = GetInfo();
+
+ CColPoint point;
+ CEntity *victim;
+
+ CWorld::bIncludeCarTyres = true;
+ CWorld::pIgnoreEntity = shooter;
+ CWorld::bIncludeDeadPeds = true;
+
+ CCam *cam = &TheCamera.Cams[TheCamera.ActiveCam];
+ ASSERT(cam!=nil);
+
+ CVector source = cam->Source;
+ CVector target = cam->Front*info->m_fRange + source;
+
+ ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeDeadPeds = false;
+ CWorld::pIgnoreEntity = nil;
+ CWorld::bIncludeCarTyres = false;
+
+ CVector2D front(cam->Front.x, cam->Front.y);
+ front.Normalise();
+
+ DoBulletImpact(shooter, victim, &source, &target, &point, front);
+
+ CVector bulletPos;
+ if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, 4) )
+ {
+ for ( int32 i = 0; i < 16; i++ )
+ CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f));
+ }
+
+ if ( shooter == FindPlayerPed() )
+ {
+ CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
+
+ if ( m_eWeaponType == WEAPONTYPE_M16 )
+ {
+ TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
+ TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
+ }
+ else if ( m_eWeaponType == WEAPONTYPE_HELICANNON )
+ {
+ TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
+ TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
+ }
+ }
+
+ return true;
+}
+
+bool
+CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
+{
+ CWeaponInfo *info = GetInfo();
+
+ CVehicleModelInfo *modelInfo = shooter->GetModelInfo();
+
+ #define FRONTSEATPOS() (&(shooter->IsBoat() ? modelInfo->m_positions[BOAT_POS_FRONTSEAT] : modelInfo->m_positions[CAR_POS_FRONTSEAT]))
+
+ CVector source, target;
+ if ( left )
+ {
+ source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.2f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + FRONTSEATPOS()->y,
+ FRONTSEATPOS()->z + 0.5f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+
+ target = shooter->GetMatrix() * CVector(-info->m_fRange,
+ FRONTSEATPOS()->y,
+ FRONTSEATPOS()->z + 0.5f);
+ }
+ else
+ {
+ source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.2f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + FRONTSEATPOS()->y,
+ FRONTSEATPOS()->z + 0.5f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(info->m_fRange,
+ FRONTSEATPOS()->y,
+ FRONTSEATPOS()->z + 0.5f);
+ }
+ #undef FRONTSEATPOS
+
+ if ( TheCamera.GetLookingLRBFirstPerson() && !left )
+ {
+ source -= 0.3f * shooter->GetForward();
+ target -= 0.3f * shooter->GetForward();
+ }
+
+ target += CVector(float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
+ float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
+ float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f);
+
+ DoDriveByAutoAiming(FindPlayerPed(), &source, &target);
+
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
+
+ if ( !TheCamera.GetLookingLRBFirstPerson() )
+ CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ else
+ CamShakeNoPos(&TheCamera, 0.01f);
+
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, FindPlayerPed(), 1000);
+
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, source, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CColPoint point;
+ CEntity *victim;
+ ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+
+ if ( !(CTimer::GetFrameCounter() & 3) )
+ MakePedsJumpAtShot(shooter, &source, &target);
+
+ if ( victim )
+ {
+ CVector traceTarget = point.point;
+ CBulletTraces::AddTrace(&source, &traceTarget);
+
+ if ( victim->IsPed() )
+ {
+ CPed *victimPed = (CPed*)victim;
+
+ if ( !victimPed->DyingOrDead() && victim != (CEntity *)shooter )
+ {
+ CVector pos = victimPed->GetPosition();
+
+ CVector2D posOffset(source.x-pos.x, source.y-pos.y);
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
+
+ victimPed->ReactToAttack(FindPlayerPed());
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_SHOT_FRONT_PARTIAL + localDir));
+ ASSERT(asoc!=nil);
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
+
+ victimPed->InflictDamage(shooter, WEAPONTYPE_UZI_DRIVEBY, 3*info->m_nDamage, (ePedPieceTypes)point.pieceB, localDir);
+
+ pos.z += 0.8f;
+
+ if ( victimPed->GetIsOnScreen() )
+ {
+ if ( CGame::nastyGame )
+ {
+ for ( int32 i = 0; i < 4; i++ )
+ {
+ CVector dir;
+ dir.x = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+ dir.y = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+ dir.z = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+
+ CParticle::AddParticle(PARTICLE_BLOOD, pos, dir);
+ }
+ }
+ }
+
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victimPed, FindPlayerPed(), 10000);
+ else
+ CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victimPed, FindPlayerPed(), 10000);
+ }
+ }
+ else if ( victim->IsVehicle() )
+ ((CVehicle *)victim)->InflictDamage(FindPlayerPed(), WEAPONTYPE_UZI_DRIVEBY, info->m_nDamage);
+ else
+ CGlass::WasGlassHitByBullet(victim, point.point);
+
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_BUILDING:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_1, point.point);
+ break;
+ }
+ case ENTITY_TYPE_VEHICLE:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ }
+ case ENTITY_TYPE_PED:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
+ break;
+ }
+ case ENTITY_TYPE_DUMMY:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_3, point.point);
+ break;
+ }
+ }
+ }
+ else
+ {
+ float norm = 30.0f/info->m_fRange;
+ CVector traceTarget = (target-source)*norm + source;
+ CBulletTraces::AddTrace(&source, &traceTarget);
+ }
+
+ if ( shooter == FindPlayerVehicle() )
+ CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerVehicle()->GetPosition().x, FindPlayerVehicle()->GetPosition().y, FindPlayerVehicle()->GetPosition().z);
+
+ return true;
+}
+
+void
+CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(source!=nil);
+ ASSERT(target !=nil);
+
+#ifndef FIX_BUGS
+ CEntity entity; // unused
+#endif
+
+ CPed *shooterPed = (CPed*)shooter;
+ if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
+ return;
+
+ int16 lastEntity;
+ CEntity *entities[16];
+ CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, true, true, false, false);
+
+ float closestEntityDist = 10000.0f;
+ int16 closestEntity;
+
+ for ( int32 i = 0; i < lastEntity; i++ )
+ {
+ CEntity *victim = entities[i];
+ ASSERT(victim!=nil);
+
+ if ( (CEntity*)shooterPed != victim && shooterPed->CanSeeEntity(victim, DEGTORAD(22.5f)) )
+ {
+ if ( !(victim->m_status == STATUS_TRAIN_MOVING
+ || victim->m_status == STATUS_TRAIN_NOT_MOVING
+ || victim->m_status == STATUS_HELI
+ || victim->m_status == STATUS_PLANE) )
+ {
+ float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D();
+ float distToVictimZ = Abs(shooterPed->GetPosition().z-victim->GetPosition().z);
+
+ if ( 1.5f*distToVictimZ < distToVictim )
+ {
+ float entityDist = Sqrt(SQR(distToVictim) + SQR(distToVictimZ));
+
+ if ( entityDist < closestEntityDist )
+ {
+ closestEntityDist = entityDist;
+ closestEntity = i;
+ }
+ }
+ }
+ }
+ }
+
+ if ( closestEntityDist < DOOMAUTOAIMING_MAXDIST )
+ {
+ CEntity *victim = entities[closestEntity];
+ ASSERT(victim !=nil);
+
+ float distToTarget = (*target - *source).Magnitude2D();
+ float distToSource = (victim->GetPosition() - *source).Magnitude2D();
+
+ float victimZ = victim->GetPosition().z + 0.3f;
+ if ( victim->IsPed() )
+ {
+ if ( ((CPed*)victim)->bIsDucking )
+ victimZ -= 0.8f;
+ }
+
+ (*target).z = (distToTarget / distToSource) * (victimZ - (*source).z) + (*source).z;
+ }
+}
+
+void
+CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CVector *target)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(driver!=nil);
+ ASSERT(source!=nil);
+ ASSERT(target!=nil);
+
+#ifndef FIX_BUGS
+ CEntity entity; // unused
+#endif
+
+ int16 lastEntity;
+ CEntity *entities[16];
+ CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, true, false, false, false);
+
+ float closestEntityDist = 10000.0f;
+ int16 closestEntity;
+
+ float normZ = (target->z - source->z) / (*target-*source).Magnitude();
+
+ for ( int32 i = 0; i < lastEntity; i++ )
+ {
+ CEntity *victim = entities[i];
+
+ ASSERT(victim!=nil);
+
+ if ( shooter != victim && driver != victim )
+ {
+ if ( !(victim->m_status == STATUS_TRAIN_MOVING
+ || victim->m_status == STATUS_TRAIN_NOT_MOVING
+ || victim->m_status == STATUS_HELI
+ || victim->m_status == STATUS_PLANE) )
+ {
+ if ( !(victim->IsVehicle() && victim->bRenderScorched) )
+ {
+ float distToVictim = (shooter->GetPosition()-victim->GetPosition()).Magnitude2D();
+ float distToVictimZ = Abs(shooter->GetPosition().z - (distToVictim*normZ + victim->GetPosition().z));
+
+ if ( 3.0f*distToVictimZ < distToVictim )
+ {
+ CVector tmp = CVector(victim->GetPosition().x, victim->GetPosition().y, 0.0f);
+ if ( CCollision::DistToLine(source, target,
+ &tmp) < victim->GetBoundRadius()*3.0f )
+ {
+ float vehicleDist = Sqrt(SQR(distToVictim) + SQR(distToVictimZ));
+ if ( vehicleDist < closestEntityDist )
+ {
+ closestEntityDist = vehicleDist;
+ closestEntity = i;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( closestEntityDist < DOOMAUTOAIMING_MAXDIST )
+ {
+ CEntity *victim = entities[closestEntity];
+ ASSERT(victim!=nil);
+
+ float distToTarget = (*target - *source).Magnitude2D();
+ float distToSource = (victim->GetPosition() - *source).Magnitude2D();
+
+ (*target).z = (distToTarget / distToSource) * (0.3f + victim->GetPosition().z - (*source).z) + (*source).z;
+ }
+}
+
+void
+CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(source!=nil);
+ ASSERT(target!=nil);
+
+#ifndef FIX_BUGS
+ CEntity entity; // unused
+#endif
+
+ CPed *shooterPed = (CPed*)shooter;
+ if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
+ return;
+
+ int16 lastEntity;
+ CEntity *entities[16];
+ CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, false, true, false, false);
+
+ float closestEntityDist = 10000.0f;
+ int16 closestEntity;
+
+ for ( int32 i = 0; i < lastEntity; i++ )
+ {
+ CEntity *victim = entities[i];
+ ASSERT(victim!=nil);
+
+ if ( shooter != victim )
+ {
+ float lineDist = CCollision::DistToLine(source, target, &victim->GetPosition());
+ float distToVictim = (victim->GetPosition() - shooter->GetPosition()).Magnitude();
+ float pedDist = 0.15f*distToVictim + lineDist;
+
+ if ( DotProduct((*target-*source), victim->GetPosition()-*source) > 0.0f && pedDist < closestEntityDist)
+ {
+ closestEntity = i;
+ closestEntityDist = pedDist;
+ }
+ }
+ }
+
+ if ( closestEntityDist < DRIVEBYAUTOAIMING_MAXDIST )
+ {
+ CEntity *victim = entities[closestEntity];
+ ASSERT(victim!=nil);
+
+ float distToTarget = (*source - *target).Magnitude();
+ float distToSource = (*source - victim->GetPosition()).Magnitude();
+ *target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source;
+ }
+}
+
void
CWeapon::Reload(void)
{
if (m_nAmmoTotal == 0)
return;
- CWeaponInfo *info = CWeaponInfo::GetWeaponInfo(m_eWeaponType);
+ CWeaponInfo *info = GetInfo();
if (m_nAmmoTotal >= info->m_nAmountofAmmunition)
m_nAmmoInClip = info->m_nAmountofAmmunition;
@@ -44,10 +1973,159 @@ CWeapon::Reload(void)
m_nAmmoInClip = m_nAmmoTotal;
}
-bool
-CWeapon::IsType2Handed(void)
+void
+CWeapon::Update(int32 audioEntity)
{
- return m_eWeaponType >= WEAPONTYPE_SHOTGUN && m_eWeaponType <= WEAPONTYPE_FLAMETHROWER && m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER;
+ switch ( m_eWeaponState )
+ {
+ case WEAPONSTATE_MELEE_MADECONTACT:
+ {
+ m_eWeaponState = WEAPONSTATE_READY;
+ break;
+ }
+
+ case WEAPONSTATE_FIRING:
+ {
+ if ( m_eWeaponType == WEAPONTYPE_SHOTGUN && AEHANDLE_IS_OK(audioEntity) )
+ {
+ uint32 timePassed = m_nTimer - gReloadSampleTime[WEAPONTYPE_SHOTGUN];
+ if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
+ DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
+ }
+
+ if ( CTimer::GetTimeInMilliseconds() > m_nTimer )
+ {
+ if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 )
+ m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO;
+ else
+ m_eWeaponState = WEAPONSTATE_READY;
+ }
+
+ break;
+ }
+
+ case WEAPONSTATE_RELOADING:
+ {
+ if ( AEHANDLE_IS_OK(audioEntity) && m_eWeaponType < WEAPONTYPE_LAST_WEAPONTYPE )
+ {
+ uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
+ if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
+ DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
+ }
+
+ if ( CTimer::GetTimeInMilliseconds() > m_nTimer )
+ {
+ Reload();
+ m_eWeaponState = WEAPONSTATE_READY;
+ }
+
+ break;
+ }
+ }
+}
+
+void
+FireOneInstantHitRound(CVector *source, CVector *target, int32 damage)
+{
+ ASSERT(source!=nil);
+ ASSERT(target!=nil);
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH, *source, CVector(0.0f, 0.0f, 0.0f));
+
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ *source, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+
+ CColPoint point;
+ CEntity *victim;
+ CWorld::ProcessLineOfSight(*source, *target, point, victim, true, true, true, true, true, true, false);
+
+ CParticle::AddParticle(PARTICLE_HELI_ATTACK, *source, ((*target) - (*source)) * 0.15f);
+
+ if ( victim )
+ {
+ if ( victim->IsPed() )
+ {
+ CPed *victimPed = (CPed *)victim;
+ if ( !victimPed->DyingOrDead() )
+ {
+ CVector pos = victimPed->GetPosition();
+
+ CVector2D posOffset((*source).x-pos.x, (*source).y-pos.y);
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
+
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_SHOT_FRONT_PARTIAL + localDir));
+ ASSERT(asoc!=nil);
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
+
+ victimPed->InflictDamage(nil, WEAPONTYPE_UZI, damage, (ePedPieceTypes)point.pieceB, localDir);
+
+ pos.z += 0.8f;
+
+ if ( victimPed->GetIsOnScreen() )
+ {
+ if ( CGame::nastyGame )
+ {
+ for ( int32 i = 0; i < 4; i++ )
+ {
+ CVector dir;
+ dir.x = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+ dir.y = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+ dir.z = CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+
+ CParticle::AddParticle(PARTICLE_BLOOD, pos, dir);
+ }
+ }
+ }
+ }
+ }
+ else if ( victim->IsVehicle() )
+ ((CVehicle *)victim)->InflictDamage(nil, WEAPONTYPE_UZI, damage);
+ //BUG ? no CGlass::WasGlassHitByBullet
+
+ switch ( victim->m_type )
+ {
+ case ENTITY_TYPE_BUILDING:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_1, point.point);
+ CParticle::AddParticle(PARTICLE_SMOKE, point.point, CVector(0.0f, 0.0f, 0.01f));
+ break;
+ }
+ case ENTITY_TYPE_VEHICLE:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ }
+ case ENTITY_TYPE_PED:
+ {
+ DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
+ break;
+ }
+ case ENTITY_TYPE_DUMMY:
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_3, point.point);
+ break;
+ }
+ }
+ }
+ else
+ {
+ float waterLevel;
+ if ( CWaterLevel::GetWaterLevel((*target).x, (*target).y, (*target).z + 10.0f, &waterLevel, false) )
+ {
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, CVector((*target).x, (*target).y, waterLevel), CVector(0.0f, 0.0f, 0.01f));
+ PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_WATER, point.point); // no sound(empty)
+ }
+ }
}
bool
@@ -57,32 +2135,75 @@ CWeapon::IsTypeMelee(void)
}
bool
-CWeapon::HitsGround(CEntity *holder, CVector *firePos, CEntity *aimingTo)
+CWeapon::IsType2Handed(void)
+{
+ return m_eWeaponType >= WEAPONTYPE_SHOTGUN && m_eWeaponType <= WEAPONTYPE_FLAMETHROWER && m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER;
+}
+
+void
+CWeapon::MakePedsJumpAtShot(CPhysical *shooter, CVector *source, CVector *target)
+{
+ ASSERT(shooter!=nil);
+ ASSERT(source!=nil);
+ ASSERT(target!=nil);
+
+ float minx = Min(source->x, target->x) - 2.0f;
+ float maxx = Max(source->x, target->x) + 2.0f;
+ float miny = Min(source->y, target->y) - 2.0f;
+ float maxy = Max(source->y, target->y) + 2.0f;
+ float minz = Min(source->z, target->z) - 2.0f;
+ float maxz = Max(source->z, target->z) + 2.0f;
+
+ for ( int32 i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--)
+ {
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+
+ if ( ped )
+ {
+ if ( ped->GetPosition().x > minx && ped->GetPosition().x < maxx
+ && ped->GetPosition().y > miny && ped->GetPosition().y < maxy
+ && ped->GetPosition().z > minz && ped->GetPosition().z < maxz )
+ {
+ if ( ped != FindPlayerPed() && !((uint8)(ped->m_randomSeed ^ CGeneral::GetRandomNumber()) & 31) )
+ ped->SetEvasiveDive(shooter, 1);
+ }
+ }
+ }
+}
+
+bool
+CWeapon::HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo)
{
+ ASSERT(holder!=nil);
+ ASSERT(aimingTo!=nil);
+
if (!holder->IsPed() || !((CPed*)holder)->m_pSeekTarget)
return false;
- CWeaponInfo *ourType = CWeaponInfo::GetWeaponInfo(m_eWeaponType);
- CVector adjustedOffset = ourType->m_vecFireOffset;
+ CWeaponInfo *info = GetInfo();
+
+ CVector adjustedOffset = info->m_vecFireOffset;
adjustedOffset.z += 0.6f;
- CVector point1, point2;
+ CVector source, target;
CEntity *foundEnt = nil;
CColPoint foundCol;
- if (firePos)
- point1 = *firePos;
+ if (fireSource)
+ source = *fireSource;
else
- point1 = holder->GetMatrix() * adjustedOffset;
+ source = holder->GetMatrix() * adjustedOffset;
CEntity *aimEntity = aimingTo ? aimingTo : ((CPed*)holder)->m_pSeekTarget;
- point2 = aimEntity->GetPosition();
- point2.z += 0.6f;
+ ASSERT(aimEntity!=nil);
- CWorld::ProcessLineOfSight(point1, point2, foundCol, foundEnt, true, false, false, false, false, false, false);
+ target = aimEntity->GetPosition();
+ target.z += 0.6f;
+
+ CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, false, false, false, false, false, false);
if (foundEnt && foundEnt->IsBuilding()) {
// That was supposed to be Magnitude, according to leftover code in assembly
- float diff = (foundCol.point.z - point1.z);
+ float diff = (foundCol.point.z - source.z);
if (diff < 0.0f && diff > -3.0f)
return true;
}
@@ -90,6 +2211,36 @@ CWeapon::HitsGround(CEntity *holder, CVector *firePos, CEntity *aimingTo)
return false;
}
+void
+CWeapon::BlowUpExplosiveThings(CEntity *thing)
+{
+ if ( thing )
+ {
+ CObject *object = (CObject*)thing;
+ int32 mi = object->GetModelIndex();
+ if ( IsExplosiveThingModel(mi) && !object->bHasBeenDamaged )
+ {
+ object->bHasBeenDamaged = true;
+
+ CExplosion::AddExplosion(object, FindPlayerPed(), EXPLOSION_BARREL, object->GetPosition()+CVector(0.0f,0.0f,0.5f), 100);
+
+ if ( MI_EXPLODINGBARREL == mi )
+ object->m_vecMoveSpeed.z += 0.75f;
+ else
+ object->m_vecMoveSpeed.z += 0.45f;
+
+ object->m_vecMoveSpeed.x += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f;
+ object->m_vecMoveSpeed.y += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f;
+
+ if ( object->bIsStatic )
+ {
+ object->bIsStatic = false;
+ object->AddToMovingList();
+ }
+ }
+ }
+}
+
bool
CWeapon::HasWeaponAmmoToBeUsed(void)
{
@@ -102,8 +2253,8 @@ CWeapon::HasWeaponAmmoToBeUsed(void)
}
}
-STARTPATCHES
- InjectHook(0x55C330, &CWeapon::Initialise, PATCH_JUMP);
- InjectHook(0x5639D0, &CWeapon::Reload, PATCH_JUMP);
- InjectHook(0x564890, &CWeapon::HitsGround, PATCH_JUMP);
-ENDPATCHES
+bool
+CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects);
+} \ No newline at end of file
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index 84760550..2c3a9657 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -1,55 +1,15 @@
#pragma once
-enum eWeaponType
-{
- WEAPONTYPE_UNARMED,
- WEAPONTYPE_BASEBALLBAT,
- WEAPONTYPE_COLT45,
- WEAPONTYPE_UZI,
- WEAPONTYPE_SHOTGUN,
- WEAPONTYPE_AK47,
- WEAPONTYPE_M16,
- WEAPONTYPE_SNIPERRIFLE,
- WEAPONTYPE_ROCKETLAUNCHER,
- WEAPONTYPE_FLAMETHROWER,
- WEAPONTYPE_MOLOTOV,
- WEAPONTYPE_GRENADE,
- WEAPONTYPE_DETONATOR,
- WEAPONTYPE_HELICANNON,
- WEAPONTYPE_LAST_WEAPONTYPE,
- WEAPONTYPE_ARMOUR,
- WEAPONTYPE_RAMMEDBYCAR,
- WEAPONTYPE_RUNOVERBYCAR,
- WEAPONTYPE_EXPLOSION,
- WEAPONTYPE_UZI_DRIVEBY,
- WEAPONTYPE_DROWNING,
- WEAPONTYPE_FALL,
- WEAPONTYPE_UNIDENTIFIED,
-
- WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE,
- WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13,
-};
+#include "WeaponType.h"
-enum eWeaponFire {
- WEAPON_FIRE_MELEE,
- WEAPON_FIRE_INSTANT_HIT,
- WEAPON_FIRE_PROJECTILE,
- WEAPON_FIRE_AREA_EFFECT,
- WEAPON_FIRE_USE
-};
-
-// Taken from MTA SA, seems it's unchanged
-enum eWeaponState
-{
- WEAPONSTATE_READY,
- WEAPONSTATE_FIRING,
- WEAPONSTATE_RELOADING,
- WEAPONSTATE_OUT_OF_AMMO,
- WEAPONSTATE_MELEE_MADECONTACT
-};
+#define DRIVEBYAUTOAIMING_MAXDIST (2.5f)
+#define DOOMAUTOAIMING_MAXDIST (9000.0f)
class CEntity;
+class CPhysical;
class CAutomobile;
+struct CColPoint;
+class CWeaponInfo;
class CWeapon
{
@@ -64,22 +24,50 @@ public:
CWeapon() {
m_bAddRotOffset = false;
}
+
+ CWeaponInfo *GetInfo();
- static void ShutdownWeapons(void);
- void Initialise(eWeaponType type, int ammo);
- void Update(int32 audioEntity);
+ static void InitialiseWeapons(void);
+ static void ShutdownWeapons (void);
+ static void UpdateWeapons (void);
+
+ void Initialise(eWeaponType type, int32 ammo);
+
+ bool Fire (CEntity *shooter, CVector *fireSource);
+ bool FireFromCar (CAutomobile *shooter, bool left);
+ bool FireMelee (CEntity *shooter, CVector &fireSource);
+ bool FireInstantHit(CEntity *shooter, CVector *fireSource);
+
+ void AddGunshell (CEntity *shooter, CVector const &source, CVector2D const &direction, float size);
+ void DoBulletImpact(CEntity *shooter, CEntity *victim, CVector *source, CVector *target, CColPoint *point, CVector2D ahead);
+
+ bool FireShotgun (CEntity *shooter, CVector *fireSource);
+ bool FireProjectile(CEntity *shooter, CVector *fireSource, float power);
+
+ static void GenerateFlameThrowerParticles(CVector pos, CVector dir);
+
+ bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
+ bool FireSniper (CEntity *shooter);
+ bool FireM16_1stPerson (CEntity *shooter);
+ bool FireInstantHitFromCar(CAutomobile *shooter, bool left);
+
+ static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
+ static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
+ static void DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target);
+
void Reload(void);
- bool Fire(CEntity*, CVector*);
- void FireFromCar(CAutomobile *car, bool left);
- void AddGunshell(CEntity*, CVector const&, CVector2D const&, float);
- bool IsTypeMelee(void);
+ void Update(int32 audioEntity);
+ bool IsTypeMelee (void);
bool IsType2Handed(void);
- static void DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end);
- bool HitsGround(CEntity* holder, CVector* firePos, CEntity* aimingTo);
+
+ static void MakePedsJumpAtShot(CPhysical *shooter, CVector *source, CVector *target);
+
+ bool HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo);
+ static void BlowUpExplosiveThings(CEntity *thing);
bool HasWeaponAmmoToBeUsed(void);
- static void InitialiseWeapons(void);
- static void UpdateWeapons(void);
+
+ static bool ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects);
};
-static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
+VALIDATE_SIZE(CWeapon, 0x18);
-void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage); \ No newline at end of file
+void FireOneInstantHitRound(CVector *source, CVector *target, int32 damage); \ No newline at end of file
diff --git a/src/render/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp
index 2ed9e662..f7e50f78 100644
--- a/src/render/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "WeaponEffects.h"
#include "TxdStore.h"
#include "Sprite.h"
@@ -93,14 +93,4 @@ CWeaponEffects::Render(void)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
}
-}
-
-STARTPATCHES
- //InjectHook(0x564C40, CWeaponEffects::CWeaponEffects, PATCH_JUMP);
- //InjectHook(0x564C50, CWeaponEffects::~CWeaponEffects, PATCH_JUMP);
- InjectHook(0x564C60, CWeaponEffects::Init, PATCH_JUMP);
- InjectHook(0x564CF0, CWeaponEffects::Shutdown, PATCH_JUMP);
- InjectHook(0x564D00, CWeaponEffects::MarkTarget, PATCH_JUMP);
- InjectHook(0x564D60, CWeaponEffects::ClearCrossHair, PATCH_JUMP);
- InjectHook(0x564D70, CWeaponEffects::Render, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/render/WeaponEffects.h b/src/weapons/WeaponEffects.h
index 31c5a309..f6592b3e 100644
--- a/src/render/WeaponEffects.h
+++ b/src/weapons/WeaponEffects.h
@@ -4,7 +4,6 @@ class CWeaponEffects
{
public:
bool m_bActive;
- char _pad[3];
CVector m_vecPos;
uint8 m_nRed;
uint8 m_nGreen;
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index a4a1a085..aec9c69a 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-#include "patcher.h"
+
#include "main.h"
#include "FileMgr.h"
#include "WeaponInfo.h"
@@ -7,7 +7,6 @@
#include "AnimBlendAssociation.h"
#include "Weapon.h"
-//CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC;
CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
static char ms_aWeaponNames[][32] = {
@@ -202,13 +201,4 @@ CWeaponInfo::Shutdown(void)
{
debug("Shutting down CWeaponInfo...\n");
debug("CWeaponInfo shut down\n");
-}
-
-STARTPATCHES
- InjectHook(0x564EA0, &CWeaponInfo::Initialise, PATCH_JUMP);
- InjectHook(0x564FD0, &CWeaponInfo::GetWeaponInfo, PATCH_JUMP);
- InjectHook(0x5653E0, &CWeaponInfo::FindWeaponType, PATCH_JUMP);
- InjectHook(0x5653B0, &CWeaponInfo::FindWeaponFireType, PATCH_JUMP);
- InjectHook(0x564FE0, &CWeaponInfo::LoadWeaponData, PATCH_JUMP);
- InjectHook(0x564FB0, &CWeaponInfo::Shutdown, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index e2e71d23..3bafd324 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -1,8 +1,7 @@
#pragma once
-enum AnimationId;
-enum eWeaponFire;
-enum eWeaponType;
+#include "AnimationId.h"
+#include "WeaponType.h"
class CWeaponInfo {
// static CWeaponInfo(&ms_apWeaponInfos)[14];
@@ -38,7 +37,6 @@ public:
uint8 m_b1stPerson : 1;
uint8 m_bHeavy : 1;
uint8 m_bThrow : 1;
- uint8 stuff;
static void Initialise(void);
static void LoadWeaponData(void);
diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h
new file mode 100644
index 00000000..b45740b7
--- /dev/null
+++ b/src/weapons/WeaponType.h
@@ -0,0 +1,49 @@
+#pragma once
+
+enum eWeaponType
+{
+ WEAPONTYPE_UNARMED,
+ WEAPONTYPE_BASEBALLBAT,
+ WEAPONTYPE_COLT45,
+ WEAPONTYPE_UZI,
+ WEAPONTYPE_SHOTGUN,
+ WEAPONTYPE_AK47,
+ WEAPONTYPE_M16,
+ WEAPONTYPE_SNIPERRIFLE,
+ WEAPONTYPE_ROCKETLAUNCHER,
+ WEAPONTYPE_FLAMETHROWER,
+ WEAPONTYPE_MOLOTOV,
+ WEAPONTYPE_GRENADE,
+ WEAPONTYPE_DETONATOR,
+ WEAPONTYPE_HELICANNON,
+ WEAPONTYPE_LAST_WEAPONTYPE,
+ WEAPONTYPE_ARMOUR,
+ WEAPONTYPE_RAMMEDBYCAR,
+ WEAPONTYPE_RUNOVERBYCAR,
+ WEAPONTYPE_EXPLOSION,
+ WEAPONTYPE_UZI_DRIVEBY,
+ WEAPONTYPE_DROWNING,
+ WEAPONTYPE_FALL,
+ WEAPONTYPE_UNIDENTIFIED,
+
+ WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE,
+ WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13,
+};
+
+enum eWeaponFire {
+ WEAPON_FIRE_MELEE,
+ WEAPON_FIRE_INSTANT_HIT,
+ WEAPON_FIRE_PROJECTILE,
+ WEAPON_FIRE_AREA_EFFECT,
+ WEAPON_FIRE_USE
+};
+
+// Taken from MTA SA, seems it's unchanged
+enum eWeaponState
+{
+ WEAPONSTATE_READY,
+ WEAPONSTATE_FIRING,
+ WEAPONSTATE_RELOADING,
+ WEAPONSTATE_OUT_OF_AMMO,
+ WEAPONSTATE_MELEE_MADECONTACT
+}; \ No newline at end of file