summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation/AnimBlendClumpData.h1
-rw-r--r--src/animation/AnimBlendHierarchy.h1
-rw-r--r--src/animation/CutsceneMgr.cpp292
-rw-r--r--src/animation/CutsceneMgr.h9
-rw-r--r--src/audio/AudioLogic.cpp1
-rw-r--r--src/audio/AudioScriptObject.cpp10
-rw-r--r--src/audio/AudioScriptObject.h3
-rw-r--r--src/audio/DMAudio.cpp4
-rw-r--r--src/audio/audio_enums.h3
-rw-r--r--src/audio/sampman_oal.cpp6
-rw-r--r--src/audio/soundlist.h6
-rw-r--r--src/control/CarCtrl.cpp67
-rw-r--r--src/control/CarCtrl.h1
-rw-r--r--src/control/Darkel.cpp6
-rw-r--r--src/control/Darkel.h6
-rw-r--r--src/control/GameLogic.cpp8
-rw-r--r--src/control/Garages.cpp5
-rw-r--r--src/control/Remote.cpp21
-rw-r--r--src/control/Remote.h2
-rw-r--r--src/control/Replay.cpp5
-rw-r--r--src/control/Script.cpp398
-rw-r--r--src/control/Script.h2
-rw-r--r--src/core/Cam.cpp22
-rw-r--r--src/core/Camera.cpp5
-rw-r--r--src/core/CdStreamPosix.cpp11
-rw-r--r--src/core/ColStore.cpp1
-rw-r--r--src/core/Collision.cpp12
-rw-r--r--src/core/Collision.h3
-rw-r--r--src/core/ControllerConfig.cpp185
-rw-r--r--src/core/ControllerConfig.h3
-rw-r--r--src/core/FileMgr.h1
-rw-r--r--src/core/Frontend.cpp1241
-rw-r--r--src/core/Frontend.h53
-rw-r--r--src/core/Frontend_PS2.cpp27
-rw-r--r--src/core/Game.cpp24
-rw-r--r--src/core/MenuScreens.cpp66
-rw-r--r--src/core/Pad.cpp63
-rw-r--r--src/core/Pad.h5
-rw-r--r--src/core/PlayerInfo.cpp365
-rw-r--r--src/core/PlayerInfo.h25
-rw-r--r--src/core/Pools.cpp24
-rw-r--r--src/core/Pools.h3
-rw-r--r--src/core/Radar.h2
-rw-r--r--src/core/Stats.cpp534
-rw-r--r--src/core/Stats.h81
-rw-r--r--src/core/Streaming.cpp527
-rw-r--r--src/core/Streaming.h10
-rw-r--r--src/core/SurfaceTable.cpp8
-rw-r--r--src/core/SurfaceTable.h1
-rw-r--r--src/core/Wanted.cpp13
-rw-r--r--src/core/ZoneCull.cpp25
-rw-r--r--src/core/ZoneCull.h12
-rw-r--r--src/core/Zones.cpp60
-rw-r--r--src/core/Zones.h4
-rw-r--r--src/core/config.h25
-rw-r--r--src/core/main.cpp101
-rw-r--r--src/core/main.h3
-rw-r--r--src/core/re3.cpp189
-rw-r--r--src/core/templates.h4
-rw-r--r--src/entities/Entity.cpp2
-rw-r--r--src/extras/custompipes.cpp536
-rw-r--r--src/extras/custompipes.h133
-rw-r--r--src/extras/custompipes_d3d9.cpp527
-rw-r--r--src/extras/custompipes_gl.cpp623
-rw-r--r--src/extras/postfx.cpp492
-rw-r--r--src/extras/postfx.h45
-rw-r--r--src/extras/shaders/Makefile67
-rw-r--r--src/extras/shaders/colourfilterVC.frag26
-rw-r--r--src/extras/shaders/colourfilterVC_PS.csobin0 -> 648 bytes
-rw-r--r--src/extras/shaders/colourfilterVC_PS.hlsl23
-rw-r--r--src/extras/shaders/colourfilterVC_PS.inc56
-rw-r--r--src/extras/shaders/colourfilterVC_fs_gl3.inc28
-rw-r--r--src/extras/shaders/contrast.frag18
-rw-r--r--src/extras/shaders/contrastPS.csobin0 -> 344 bytes
-rw-r--r--src/extras/shaders/contrastPS.hlsl21
-rw-r--r--src/extras/shaders/contrastPS.inc31
-rw-r--r--src/extras/shaders/contrast_fs_gl3.inc20
-rw-r--r--src/extras/shaders/default_UV2.vert29
-rw-r--r--src/extras/shaders/default_UV2_VS.csobin0 -> 628 bytes
-rw-r--r--src/extras/shaders/default_UV2_VS.hlsl54
-rw-r--r--src/extras/shaders/default_UV2_VS.inc55
-rw-r--r--src/extras/shaders/default_UV2_gl3.inc31
-rw-r--r--src/extras/shaders/im2d.vert21
-rw-r--r--src/extras/shaders/im2d_gl3.inc23
-rw-r--r--src/extras/shaders/lighting.h44
-rw-r--r--src/extras/shaders/make.cmd3
-rw-r--r--src/extras/shaders/makeinc.sh5
-rw-r--r--src/extras/shaders/neoGloss.frag26
-rw-r--r--src/extras/shaders/neoGloss.vert29
-rw-r--r--src/extras/shaders/neoGloss_PS.csobin0 -> 444 bytes
-rw-r--r--src/extras/shaders/neoGloss_PS.hlsl20
-rw-r--r--src/extras/shaders/neoGloss_PS.inc39
-rw-r--r--src/extras/shaders/neoGloss_VS.csobin0 -> 764 bytes
-rw-r--r--src/extras/shaders/neoGloss_VS.hlsl35
-rw-r--r--src/extras/shaders/neoGloss_VS.inc66
-rw-r--r--src/extras/shaders/neoGloss_fs_gl3.inc28
-rw-r--r--src/extras/shaders/neoGloss_vs_gl3.inc31
-rw-r--r--src/extras/shaders/neoRim.vert37
-rw-r--r--src/extras/shaders/neoRimSkin.vert48
-rw-r--r--src/extras/shaders/neoRimSkin_VS.csobin0 -> 2404 bytes
-rw-r--r--src/extras/shaders/neoRimSkin_VS.hlsl73
-rw-r--r--src/extras/shaders/neoRimSkin_VS.inc203
-rw-r--r--src/extras/shaders/neoRimSkin_gl3.inc50
-rw-r--r--src/extras/shaders/neoRim_VS.csobin0 -> 1384 bytes
-rw-r--r--src/extras/shaders/neoRim_VS.hlsl61
-rw-r--r--src/extras/shaders/neoRim_VS.inc118
-rw-r--r--src/extras/shaders/neoRim_gl3.inc39
-rw-r--r--src/extras/shaders/neoVehicle.frag28
-rw-r--r--src/extras/shaders/neoVehicle.vert54
-rw-r--r--src/extras/shaders/neoVehicle_PS.csobin0 -> 476 bytes
-rw-r--r--src/extras/shaders/neoVehicle_PS.hlsl34
-rw-r--r--src/extras/shaders/neoVehicle_PS.inc42
-rw-r--r--src/extras/shaders/neoVehicle_VS.csobin0 -> 1896 bytes
-rw-r--r--src/extras/shaders/neoVehicle_VS.hlsl64
-rw-r--r--src/extras/shaders/neoVehicle_VS.inc160
-rw-r--r--src/extras/shaders/neoVehicle_fs_gl3.inc30
-rw-r--r--src/extras/shaders/neoVehicle_vs_gl3.inc56
-rw-r--r--src/extras/shaders/neoWorldVC.frag25
-rw-r--r--src/extras/shaders/neoWorldVC_PS.csobin0 -> 524 bytes
-rw-r--r--src/extras/shaders/neoWorldVC_PS.hlsl25
-rw-r--r--src/extras/shaders/neoWorldVC_PS.inc46
-rw-r--r--src/extras/shaders/neoWorldVC_fs_gl3.inc27
-rw-r--r--src/extras/shaders/simple.frag16
-rw-r--r--src/extras/shaders/simple_fs_gl3.inc18
-rw-r--r--src/extras/shaders/standardConstants.h28
-rw-r--r--src/modelinfo/PedModelInfo.cpp4
-rw-r--r--src/modelinfo/SimpleModelInfo.cpp8
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp9
-rw-r--r--src/objects/ParticleObject.cpp2
-rw-r--r--src/peds/Ped.cpp119
-rw-r--r--src/peds/Ped.h3
-rw-r--r--src/peds/PedChat.cpp6
-rw-r--r--src/peds/PlayerPed.cpp2
-rw-r--r--src/peds/PlayerPed.h2
-rw-r--r--src/peds/Population.cpp3
-rw-r--r--src/render/Antennas.cpp2
-rw-r--r--src/render/Clouds.cpp84
-rw-r--r--src/render/Coronas.cpp188
-rw-r--r--src/render/Coronas.h26
-rw-r--r--src/render/Fluff.cpp198
-rw-r--r--src/render/Fluff.h32
-rw-r--r--src/render/Hud.cpp62
-rw-r--r--src/render/MBlur.cpp68
-rw-r--r--src/render/PlayerSkin.cpp12
-rw-r--r--src/render/PointLights.cpp68
-rw-r--r--src/render/PointLights.h5
-rw-r--r--src/render/Renderer.cpp88
-rw-r--r--src/render/Rubbish.cpp67
-rw-r--r--src/render/ShadowCamera.cpp4
-rw-r--r--src/render/Shadows.cpp2
-rw-r--r--src/render/Shadows.h2
-rw-r--r--src/render/Skidmarks.cpp13
-rw-r--r--src/render/SpecialFX.cpp40
-rw-r--r--src/render/SpecialFX.h1
-rw-r--r--src/render/Sprite.cpp6
-rw-r--r--src/render/Sprite2d.cpp234
-rw-r--r--src/render/Sprite2d.h3
-rw-r--r--src/render/Timecycle.cpp325
-rw-r--r--src/render/Timecycle.h238
-rw-r--r--src/render/Weather.cpp308
-rw-r--r--src/render/Weather.h7
-rw-r--r--src/render/WindModifiers.cpp44
-rw-r--r--src/render/WindModifiers.h7
-rw-r--r--src/rw/ClumpRead.cpp1
-rw-r--r--src/rw/Lights.cpp22
-rw-r--r--src/rw/Lights.h6
-rw-r--r--src/rw/NodeName.cpp4
-rw-r--r--src/rw/RwHelper.cpp37
-rw-r--r--src/rw/RwHelper.h6
-rw-r--r--src/rw/TexRead.cpp38
-rw-r--r--src/rw/TxdStore.cpp16
-rw-r--r--src/rw/VisibilityPlugins.cpp5
-rw-r--r--src/save/GenericGameStorage.cpp25
-rw-r--r--src/save/GenericGameStorage.h2
-rw-r--r--src/save/PCSave.cpp8
-rw-r--r--src/skel/glfw/glfw.cpp22
-rw-r--r--src/skel/platform.h1
-rw-r--r--src/skel/skeleton.cpp9
-rw-r--r--src/skel/skeleton.h3
-rw-r--r--src/skel/win/win.cpp30
-rw-r--r--src/vehicles/Automobile.cpp13
-rw-r--r--src/vehicles/Automobile.h2
-rw-r--r--src/vehicles/Bike.cpp20
-rw-r--r--src/vehicles/Boat.cpp2
-rw-r--r--src/vehicles/Transmission.cpp78
185 files changed, 9084 insertions, 2622 deletions
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 4043c778..af7e5df5 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -12,6 +12,7 @@ struct AnimBlendFrameData
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
UPDATE_KEYFRAMES = 0x20,
+ UNK_COMPRESSED = 0x40,
};
uint8 flag;
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index 45c9217e..b34ae210 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -25,6 +25,7 @@ public:
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
+ bool IsCompressed() { return !!compressed; };
};
VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index e720fccb..31128990 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -19,6 +19,11 @@
#include "RpAnimBlend.h"
#include "ModelIndices.h"
#include "TempColModels.h"
+#include "ColStore.h"
+#include "Radar.h"
+#include "Pools.h"
+
+//--MIAMI: file done
const struct {
const char *szTrackName;
@@ -119,15 +124,22 @@ int32 CCutsceneMgr::ms_numCutsceneObjs;
bool CCutsceneMgr::ms_loaded;
bool CCutsceneMgr::ms_animLoaded;
bool CCutsceneMgr::ms_useLodMultiplier;
-bool CCutsceneMgr::ms_camLoaded;
char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
-char CCutsceneMgr::ms_uncompressedAnims[8][32];
-uint32 CCutsceneMgr::ms_numUncompressedAnims;
CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector CCutsceneMgr::ms_cutsceneOffset;
float CCutsceneMgr::ms_cutsceneTimer;
bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
+bool CCutsceneMgr::ms_useCutsceneShadows = true;
+
+bool bCamLoaded;
+bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P
+int32 NumberOfSavedWeapons;
+eWeaponType SavedWeaponIDs[TOTAL_WEAPON_SLOTS];
+int32 SavedWeaponAmmo[TOTAL_WEAPON_SLOTS];
+char uncompressedAnims[8][32];
+uint32 numUncompressedAnims;
+
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@@ -151,15 +163,15 @@ CCutsceneMgr::Initialise(void)
ms_loaded = false;
ms_wasCutsceneSkipped = false;
ms_running = false;
+ ms_useLodMultiplier = false;
ms_animLoaded = false;
ms_cutsceneProcessing = false;
- ms_useLodMultiplier = false;
ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
- ms_numUncompressedAnims = 0;
- ms_uncompressedAnims[0][0] = '\0';
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
}
void
@@ -178,9 +190,9 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_cutsceneProcessing = true;
ms_wasCutsceneSkipped = false;
- if (!strcasecmp(szCutsceneName, "jb"))
- ms_useLodMultiplier = true;
CTimer::Suspend();
+ if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver)
+ CStreaming::RemoveCurrentZonesModels();
ms_pCutsceneDir->numEntries = 0;
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
@@ -200,7 +212,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CStreaming::MakeSpaceFor(size << 11);
CStreaming::ImGonnaUseStreamingMemory();
RwStreamSkip(stream, offset << 11);
- CAnimManager::LoadAnimFile(stream, true, ms_uncompressedAnims);
+ CAnimManager::LoadAnimFile(stream, true, uncompressedAnims);
ms_cutsceneAssociations.CreateAssociations(szCutsceneName);
CStreaming::IHaveUsedStreamingMemory();
ms_animLoaded = true;
@@ -217,9 +229,9 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CFileMgr::Seek(file, offset << 11, SEEK_SET);
TheCamera.LoadPathSplines(file);
CStreaming::IHaveUsedStreamingMemory();
- ms_camLoaded = true;
+ bCamLoaded = true;
} else {
- ms_camLoaded = false;
+ bCamLoaded = false;
}
CFileMgr::CloseFile(file);
@@ -252,7 +264,7 @@ void
CCutsceneMgr::FinishCutscene()
{
ms_wasCutsceneSkipped = true;
- if (ms_camLoaded) {
+ if (bCamLoaded) {
CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
TheCamera.FinishCutscene();
}
@@ -264,7 +276,7 @@ CCutsceneMgr::FinishCutscene()
void
CCutsceneMgr::SetupCutsceneToStart(void)
{
- if (ms_camLoaded) {
+ if (bCamLoaded) {
TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
TheCamera.TakeControlWithSpline(JUMP_CUT);
TheCamera.SetWideScreenOn();
@@ -276,7 +288,16 @@ CCutsceneMgr::SetupCutsceneToStart(void)
assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP);
if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
- ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation);
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
+ pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
+ } else {
+ KeyFrameTrans* keyFrames;
+ if (pAnimBlendAssoc->hierarchy->IsCompressed())
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ else
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
+ }
pAnimBlendAssoc->SetRun();
} else {
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset);
@@ -300,19 +321,31 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
CAnimBlendClumpData *pAnimBlendClumpData;
assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP);
+ debug("Give cutscene anim %s\n", animName);
RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject);
- pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ pNewAnim = ms_cutsceneAssociations.GetAnimation(animName);
if (!pNewAnim) {
debug("\n\nHaven't I told you I can't find the fucking animation %s\n\n\n", animName);
return;
}
+
+ if (pNewAnim->hierarchy->IsCompressed())
+ pNewAnim->hierarchy->compressed2 = true;
+
+ CStreaming::ImGonnaUseStreamingMemory();
+ pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ CStreaming::IHaveUsedStreamingMemory();
+
pNewAnim->SetCurrentTime(0.0f);
pNewAnim->flags |= ASSOC_HAS_TRANSLATION;
pNewAnim->flags &= ~ASSOC_RUNNING;
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
+
+ if (pNewAnim->hierarchy->compressed2)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED;
}
void
@@ -327,25 +360,42 @@ CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
return nil;
}
+void UpdateCutsceneObjectBoundingBox(RpClump* clump, int modelId)
+{
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
+ CColModel* pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
+ float radius = 0.0f;
+ RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
+ pColModel->boundingSphere.radius = radius;
+ pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
+ pColModel->boundingBox.max = CVector(radius, radius, radius);
+ }
+}
+
CCutsceneObject *
CCutsceneMgr::CreateCutsceneObject(int modelId)
{
CBaseModelInfo *pModelInfo;
CColModel *pColModel;
- float radius;
- RpClump *clump;
CCutsceneObject *pCutsceneObject;
+ CStreaming::ImGonnaUseStreamingMemory();
+ debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetName());
if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
pModelInfo = CModelInfo::GetModelInfo(modelId);
pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
- radius = 0.0f;
-
pModelInfo->SetColModel(pColModel);
- clump = (RpClump*)pModelInfo->GetRwObject();
- assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
- RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
-
+ UpdateCutsceneObjectBoundingBox((RpClump*)pModelInfo->GetRwObject(), modelId);
+ } else if (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) {
+ pModelInfo = CModelInfo::GetModelInfo(modelId);
+ if (pModelInfo->GetColModel() == &CTempColModels::ms_colModelPed1) {
+ CColModel *colModel = new CColModel();
+ colModel->boundingSphere.radius = 2.0f;
+ colModel->boundingSphere.center = CVector(0.0f, 0.0f, 0.0f);
+ pModelInfo->SetColModel(colModel, true);
+ }
+ pColModel = pModelInfo->GetColModel();
+ float radius = 2.0f;
pColModel->boundingSphere.radius = radius;
pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
pColModel->boundingBox.max = CVector(radius, radius, radius);
@@ -353,7 +403,10 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pCutsceneObject = new CCutsceneObject();
pCutsceneObject->SetModelIndex(modelId);
+ if (ms_useCutsceneShadows)
+ pCutsceneObject->CreateShadow();
ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject;
+ CStreaming::IHaveUsedStreamingMemory();
return pCutsceneObject;
}
@@ -365,6 +418,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
ms_cutsceneProcessing = false;
ms_useLodMultiplier = false;
+ ms_useCutsceneShadows = true;
for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) {
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
@@ -374,14 +428,23 @@ CCutsceneMgr::DeleteCutsceneData(void)
}
ms_numCutsceneObjs = 0;
+ for (int i = MI_SPECIAL01; i < MI_SPECIAL21; i++) {
+ CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i);
+ CColModel *colModel = minfo->GetColModel();
+ if (colModel != &CTempColModels::ms_colModelPed1) {
+ delete colModel;
+ minfo->SetColModel(&CTempColModels::ms_colModelPed1);
+ }
+ }
+
if (ms_animLoaded)
CAnimManager::RemoveLastAnimFile();
ms_animLoaded = false;
- ms_numUncompressedAnims = 0;
- ms_uncompressedAnims[0][0] = '\0';
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
- if (ms_camLoaded) {
+ if (bCamLoaded) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetWideScreenOff();
TheCamera.DeleteCutSceneCamDataMemory();
@@ -397,10 +460,37 @@ CCutsceneMgr::DeleteCutsceneData(void)
DMAudio.StopCutSceneMusic();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
+
+ CStreaming::ms_disableStreaming = false;
+ CWorld::bProcessCutsceneOnly = false;
+
+ if(bCamLoaded)
+ CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
- if(ms_camLoaded)
- CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2);
-
+ CPad::GetPad(0)->Clear(false);
+ if (bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) {
+ CStreaming::LoadInitialPeds();
+ CStreaming::LoadInitialWeapons();
+ CStreaming::LoadInitialVehicles();
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = false;
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ for (int i = 0; i < NumberOfSavedWeapons; i++) {
+ int32 weaponModelId = CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModelId;
+ uint8 flags = CStreaming::ms_aInfoForModel[weaponModelId].m_flags;
+ CStreaming::RequestModel(weaponModelId, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id != -1) {
+ CStreaming::RequestModel(CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id, 0);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ if (!(flags & STREAMFLAGS_DONT_REMOVE))
+ CStreaming::SetModelIsDeletable(weaponModelId);
+ pPlayerPed->GiveWeapon(SavedWeaponIDs[i], SavedWeaponAmmo[i], true);
+ }
+ NumberOfSavedWeapons = 0;
+ }
+
CTimer::Resume();
}
@@ -437,26 +527,156 @@ CCutsceneMgr::Update(void)
ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
- if (ms_camLoaded)
+ for (int i = 0; i < ms_numCutsceneObjs; i++) {
+ int modelId = ms_pCutsceneObjects[i]->GetModelIndex();
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil && modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+ }
+
+ if (bCamLoaded)
if (CGeneral::faststricmp(ms_cutsceneName, "finale") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
if (CPad::GetPad(0)->GetCrossJustDown()
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|| CPad::GetPad(0)->GetEnterJustDown()
|| CPad::GetPad(0)->GetCharJustDown(' '))
- FinishCutscene();
+ FinishCutscene();
}
}
-bool CCutsceneMgr::HasCutsceneFinished(void) { return !ms_camLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
+bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
void
CCutsceneMgr::LoadAnimationUncompressed(char const* name)
{
- strcpy(ms_uncompressedAnims[ms_numUncompressedAnims], name);
+ strcpy(uncompressedAnims[numUncompressedAnims], name);
// Because that's how CAnimManager knows the end of array
- ++ms_numUncompressedAnims;
- assert(ms_numUncompressedAnims < ARRAY_SIZE(ms_uncompressedAnims));
- ms_uncompressedAnims[ms_numUncompressedAnims][0] = '\0';
+ ++numUncompressedAnims;
+ assert(numUncompressedAnims < ARRAY_SIZE(uncompressedAnims));
+ uncompressedAnims[numUncompressedAnims][0] = '\0';
+}
+
+void
+CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump());
+
+ debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame;
+ debug("Attach %s to component %s of %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ frame,
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+ if (RwObjectGetType(pObject->m_rwObject) == rpCLUMP) {
+ RpClump *clump = (RpClump*)pObject->m_rwObject;
+ if (IsClumpSkinned(clump))
+ RpAtomicGetBoundingSphere(GetFirstAtomic(clump))->radius *= 1.1f;
+ }
+}
+
+void
+CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone)
+{
+ RpHAnimHierarchy *hanim = GetAnimHierarchyFromSkinClump(pAttachTo->GetClump());
+ RwInt32 id = RpHAnimIDGetIndex(hanim, bone);
+ RwMatrix *matrixArray = RpHAnimHierarchyGetMatrixArray(hanim);
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id];
+ debug("Attach %s to %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver()
+{
+ CStreaming::ms_disableStreaming = true;
+ CColStore::RemoveAllCollision();
+ CWorld::bProcessCutsceneOnly = true;
+ ms_cutsceneProcessing = true;
+
+ for (int i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed) {
+ if (!pPed->IsPlayer() && pPed->CanBeDeleted()) {
+ CWorld::Remove(pPed);
+ delete pPed;
+ }
+ }
+ }
+
+ for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle) {
+ if (pVehicle->CanBeDeleted()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = true;
+ CStreaming::RemoveCurrentZonesModels();
+ CStreaming::SetModelIsDeletable(MI_MALE01);
+ CStreaming::SetModelTxdIsDeletable(MI_MALE01);
+ CStreaming::SetModelIsDeletable(MI_HMOCA);
+ CStreaming::SetModelTxdIsDeletable(MI_HMOCA);
+ CStreaming::SetModelIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelIsDeletable(MI_MISSILE);
+ CStreaming::SetModelTxdIsDeletable(MI_MISSILE);
+ CStreaming::SetModelIsDeletable(MI_POLICE);
+ CStreaming::SetModelTxdIsDeletable(MI_POLICE);
+
+ while (CStreaming::RemoveLoadedVehicle()) ;
+
+ CRadar::RemoveRadarSections();
+
+ for (int i = CPools::GetDummyPool()->GetSize() - 1; i >= 0; i--) {
+ CDummy* pDummy = CPools::GetDummyPool()->GetSlot(i);
+ if (pDummy)
+ pDummy->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i--) {
+ CObject* pObject = CPools::GetObjectPool()->GetSlot(i);
+ if (pObject)
+ pObject->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
+ CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i);
+ if (pBuilding && pBuilding->GetClump() != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) {
+ if (pBuilding->bIsBIGBuilding)
+ CStreaming::RequestModel(pBuilding->GetModelIndex(), 0);
+ if (!pBuilding->bImBeingRendered)
+ pBuilding->DeleteRwObject();
+ }
+ }
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ pPlayerPed->RemoveWeaponAnims(0, -1000.0f);
+ NumberOfSavedWeapons = 0;
+
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pPlayerPed->m_weapons[i].m_eWeaponType != WEAPONTYPE_UNARMED) {
+ SavedWeaponIDs[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_eWeaponType;
+ SavedWeaponAmmo[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_nAmmoTotal;
+ NumberOfSavedWeapons++;
+ }
+ }
+
+ pPlayerPed->ClearWeapons();
+ CGame::DrasticTidyUpMemory(true);
} \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index c3f86273..b4497b5b 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -17,15 +17,13 @@ class CCutsceneMgr
static bool ms_animLoaded;
static bool ms_useLodMultiplier;
- static bool ms_camLoaded;
static char ms_cutsceneName[CUTSCENENAMESIZE];
- static char ms_uncompressedAnims[8][32];
- static uint32 ms_numUncompressedAnims;
static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer;
static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
+ static bool ms_useCutsceneShadows;
public:
static CDirectory *ms_pCutsceneDir;
static uint32 ms_cutsceneLoadStatus;
@@ -54,4 +52,9 @@ public:
static void DeleteCutsceneData(void);
static void LoadAnimationUncompressed(char const*);
static void Update(void);
+
+ static void AttachObjectToParent(CObject *pObject, CEntity *pAttachTo);
+ static void AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame);
+ static void AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int frame);
+ static void RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver();
};
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index b814d58c..98ebf0d8 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -2756,7 +2756,6 @@ cAudioManager::ProcessPlane(cVehicleParams *params)
ProcessCesna(params);
break;
default:
- debug("Plane Model Id is %d\n, ", params->m_pVehicle->GetModelIndex());
break;
}
}
diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp
index 69d80fbc..ac30f757 100644
--- a/src/audio/AudioScriptObject.cpp
+++ b/src/audio/AudioScriptObject.cpp
@@ -4,6 +4,16 @@
#include "Pools.h"
#include "DMAudio.h"
+cAudioScriptObject::cAudioScriptObject()
+{
+ Reset();
+};
+
+cAudioScriptObject::~cAudioScriptObject()
+{
+ Reset();
+};
+
void
cAudioScriptObject::Reset()
{
diff --git a/src/audio/AudioScriptObject.h b/src/audio/AudioScriptObject.h
index ff36474d..8110b2bb 100644
--- a/src/audio/AudioScriptObject.h
+++ b/src/audio/AudioScriptObject.h
@@ -7,6 +7,9 @@ public:
CVector Posn;
int32 AudioEntity;
+ cAudioScriptObject();
+ ~cAudioScriptObject();
+
void Reset(); /// ok
static void* operator new(size_t);
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index 6859cba3..b3c16941 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -247,7 +247,7 @@ cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos)
int32
cDMAudio::CreateLoopingScriptObject(cAudioScriptObject *scriptObject)
{
- int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, (CPhysical *)scriptObject);
+ int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject);
if ( AEHANDLE_IS_OK(audioEntity) )
AudioManager.SetEntityStatus(audioEntity, true);
@@ -264,7 +264,7 @@ cDMAudio::DestroyLoopingScriptObject(int32 audioEntity)
void
cDMAudio::CreateOneShotScriptObject(cAudioScriptObject *scriptObject)
{
- int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, (CPhysical *)scriptObject);
+ int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject);
if ( AEHANDLE_IS_OK(audioEntity) )
{
diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h
index 1f13521b..375c4a70 100644
--- a/src/audio/audio_enums.h
+++ b/src/audio/audio_enums.h
@@ -12,7 +12,8 @@ enum eRadioStation
EMOTION,
WAVE,
USERTRACK,
- POLICE_RADIO,
+ NUM_RADIOS = 10,
+ POLICE_RADIO = 10,
//TAXI_RADIO,
RADIO_OFF,
};
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index a2943aff..ffa4c456 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -587,16 +587,16 @@ cSampleManager::Initialise(void)
}
nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (uintptr)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
- ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0);
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == 0 )
{
Terminate();
return false;
}
nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
- ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0);
}
diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h
index 2a5b83cf..bc9ac09a 100644
--- a/src/audio/soundlist.h
+++ b/src/audio/soundlist.h
@@ -146,9 +146,9 @@ enum eSound : uint16
SOUND_PED_LEAVE_VEHICLE,
SOUND_PED_EVADE,
SOUND_PED_FLEE_RUN,
- SOUND_PED_CAR_COLLISION,
- SOUND_PED_BOAT_COLLISION,
- SOUND_PED_HORN_ACTIVE,
+ SOUND_PED_CRASH_VEHICLE,
+ SOUND_PED_CRASH_CAR,
+ SOUND_PED_ANNOYED_DRIVER,
SOUND_PED_147,
SOUND_PED_SOLICIT,
SOUND_PED_149,
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index cd08753d..74c4f006 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -81,6 +81,9 @@
#define OFFSCREEN_DESPAWN_RANGE (40.0f)
#define EXTENDED_RANGE_DESPAWN_MULTIPLIER (1.5f)
+//--MIAMI: file done
+
+bool CCarCtrl::bMadDriversCheat;
int CCarCtrl::NumLawEnforcerCars;
int CCarCtrl::NumAmbulancesOnDuty;
int CCarCtrl::NumFiretrucksOnDuty;
@@ -158,7 +161,7 @@ CCarCtrl::GenerateOneRandomCar()
carModel = ChoosePoliceCarModel();
}else{
carModel = ChooseModel(&zone, &vecTargetPos, &carClass);
- if (carClass == COPS && pWanted->m_nWantedLevel >= 1 || carModel < 0)
+ if (carModel == -1 || (carClass == COPS && pWanted->m_nWantedLevel >= 1))
/* All cop spawns with wanted level are handled by condition above. */
/* In particular it means that cop cars never spawn if player has wanted level of 1. */
return;
@@ -664,7 +667,7 @@ CCarCtrl::GenerateOneRandomCar()
nMadDrivers = 6;
break;
}
- if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers /* TODO(MIAMI): || mad drivers cheat */) {
+ if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers || bMadDriversCheat) {
pVehicle->SetStatus(STATUS_PHYSICS);
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
pVehicle->AutoPilot.m_nCruiseSpeed += 10;
@@ -758,7 +761,8 @@ CCarCtrl::ChooseCarRating(CZoneInfo* pZoneInfo)
int32
CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
int32 model = -1;
- for (int i = 0; i < 10 && (model == -1 || !CStreaming::HasModelLoaded(model)); i++) {
+ int32 i;
+ for (i = 10; i > 0 && (model == -1 || !CStreaming::HasModelLoaded(model)); i--) {
int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
if (rnd < pZone->copThreshold) {
@@ -767,9 +771,9 @@ CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
continue;
}
- int j;
+ int32 j;
for (j = 0; j < NUM_GANG_CAR_CLASSES; j++) {
- if (rnd < pZone->gangThreshold[i]) {
+ if (rnd < pZone->gangThreshold[j]) {
*pClass = j + FIRST_GANG_CAR_RATING;
model = ChooseGangCarModel(j);
break;
@@ -782,6 +786,8 @@ CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
*pClass = ChooseCarRating(pZone);
model = ChooseCarModel(*pClass);
}
+ if (i == 0)
+ return -1;
return model;
}
@@ -950,6 +956,10 @@ CCarCtrl::RemoveCarsIfThePoolGetsFull(void)
void
CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
{
+#ifdef FIX_BUGS
+ if (pVehicle->bIsLocked)
+ return;
+#endif
CVector vecPlayerPos = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
/* BUG: this variable is initialized only in if-block below but can be used outside of it. */
if (!IsThisVehicleInteresting(pVehicle) && !pVehicle->bIsLocked &&
@@ -2515,7 +2525,7 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_PLANE_FLYTOCOORS:
- //SteerAIPlaneTowardsTargetCoors((CAutomobile*)pVehicle);
+ SteerAIPlaneTowardsTargetCoors((CAutomobile*)pVehicle);
return;
case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1:
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
@@ -2737,6 +2747,51 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
pHeli->GetMatrix().GetUp() = up;
}
+void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
+{
+ CVector2D vecToTarget = pPlane->AutoPilot.m_vecDestinationCoors - pPlane->GetPosition();
+ float fForwardZ = (pPlane->AutoPilot.m_vecDestinationCoors.z - pPlane->GetPosition().z) / vecToTarget.Magnitude();
+ fForwardZ = clamp(fForwardZ, -0.3f, 0.3f);
+ float angle = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y);
+ while (angle > TWOPI)
+ angle -= TWOPI;
+ float difference = LimitRadianAngle(angle - pPlane->m_fOrientation);
+ float steer = difference > 0.0f ? 0.04f : -0.04f;
+ if (Abs(difference) < 0.2f)
+ steer *= 5.0f * Abs(difference);
+ pPlane->m_fPlaneSteer *= Pow(0.96f, CTimer::GetTimeStep());
+ float steerChange = steer - pPlane->m_fPlaneSteer;
+ float maxChange = 0.003f * CTimer::GetTimeStep();
+ if (Abs(steerChange) < maxChange)
+ pPlane->m_fPlaneSteer = steer;
+ else if (steerChange < 0.0f)
+ pPlane->m_fPlaneSteer -= maxChange;
+ else
+ pPlane->m_fPlaneSteer += maxChange;
+ pPlane->m_fOrientation += pPlane->m_fPlaneSteer * CTimer::GetTimeStep();
+ CVector up(0.0f, 0.0f, 1.0f);
+ up.Normalise();
+ CVector forward(Cos(pPlane->m_fOrientation), Sin(pPlane->m_fOrientation), fForwardZ);
+ forward.Normalise();
+ CVector right = CrossProduct(forward, up);
+ right.z -= 5.0f * pPlane->m_fPlaneSteer;
+ right.Normalise();
+ up = CrossProduct(forward, right);
+ up.Normalise();
+ right = CrossProduct(forward, up);
+ pPlane->GetMatrix().GetRight() = right;
+ pPlane->GetMatrix().GetForward() = forward;
+ pPlane->GetMatrix().GetUp() = up;
+ float newSplit = 1.0f - Pow(0.95f, CTimer::GetTimeStep());
+ float oldSplit = 1.0f - newSplit;
+#ifdef FIX_BUGS
+ pPlane->m_vecMoveSpeed = pPlane->m_vecMoveSpeed * oldSplit + pPlane->AutoPilot.GetCruiseSpeed() * 0.01f * forward * newSplit;
+#else
+ pPlane->m_vecMoveSpeed = pPlane->m_vecMoveSpeed * oldSplit + pPlane->AutoPilot.m_nCruiseSpeed * 0.01f * forward * newSplit;
+#endif
+ pPlane->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+}
+
void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
{
CVector2D forward = pVehicle->GetForward();
diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h
index 6b4e94ee..76491193 100644
--- a/src/control/CarCtrl.h
+++ b/src/control/CarCtrl.h
@@ -145,6 +145,7 @@ public:
return angle;
}
+ static bool bMadDriversCheat;
static int32 NumLawEnforcerCars;
static int32 NumAmbulancesOnDuty;
static int32 NumFiretrucksOnDuty;
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index bbb35080..75d27e26 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -32,9 +32,9 @@ int8 CDarkel::InterruptedWeapon;
* 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 CDarkel::bNeedHeadShot;
-int8 CDarkel::bProperKillFrenzy;
+bool CDarkel::bStandardSoundAndMessages;
+bool CDarkel::bNeedHeadShot;
+bool CDarkel::bProperKillFrenzy;
uint16 CDarkel::Status;
uint16 CDarkel::RegisteredKills[NUM_DEFAULT_MODELS];
int32 CDarkel::ModelToKill;
diff --git a/src/control/Darkel.h b/src/control/Darkel.h
index 14529c63..0f5c2329 100644
--- a/src/control/Darkel.h
+++ b/src/control/Darkel.h
@@ -24,9 +24,9 @@ private:
static int32 AmmoInterruptedWeapon;
static int32 KillsNeeded;
static int8 InterruptedWeapon;
- static int8 bStandardSoundAndMessages;
- static int8 bNeedHeadShot;
- static int8 bProperKillFrenzy;
+ static bool bStandardSoundAndMessages;
+ static bool bNeedHeadShot;
+ static bool bProperKillFrenzy;
static uint16 Status;
static uint16 RegisteredKills[NUM_DEFAULT_MODELS];
static int32 ModelToKill;
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index 2af9464c..c5394e7c 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -28,6 +28,7 @@
#include "Particle.h"
#include "ColStore.h"
#include "Automobile.h"
+#include "MBlur.h"
uint8 CGameLogic::ActivePlayers;
uint8 CGameLogic::ShortCutState;
@@ -343,7 +344,10 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
pPlayerPed->bIsVisible = true;
pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
pPlayerPed->bDoBloodyFootprints = false;
- //TODO(MIAMI): clear drunk stuff
+ pPlayerPed->m_nDrunkenness = 0;
+ pPlayerPed->m_nFadeDrunkenness = 0;
+ CMBlur::ClearDrunkBlur();
+ pPlayerPed->m_nDrunkCountdown = 0;
pPlayerPed->ClearAdrenaline();
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
if (pPlayerPed->m_pFire)
@@ -368,7 +372,7 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
pPlayerPed->RestoreHeadingRate();
CGame::currArea = AREA_MAIN_MAP;
- //CStreaming::RemoveBuildingsNotInArea(0); // TODO(MIAMI)
+ CStreaming::RemoveBuildingsNotInArea(0);
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
TheCamera.Restore();
CReferences::RemoveReferencesToPlayer();
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index e7b5ebe6..9aba431c 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -1324,7 +1324,7 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
if (!IsEntityTouching3D(pVehicle))
continue;
if (!IsPointInsideGarage(pVehicle->GetPosition())) {
- if (pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
+ if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
CWorld::Remove(pVehicle);
delete pVehicle;
return; // WHY?
@@ -1817,8 +1817,9 @@ CVehicle* CStoredCar::RestoreCar()
pVehicle->m_nRadioStation = m_nRadioStation;
pVehicle->bFreebies = false;
#ifdef FIX_BUGS
- ((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType;
+ if (pVehicle->IsCar())
#endif
+ ((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType;
pVehicle->bHasBeenOwnedByPlayer = true;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
pVehicle->bBulletProof = m_bBulletproof;
diff --git a/src/control/Remote.cpp b/src/control/Remote.cpp
index 904e9023..164a2f4c 100644
--- a/src/control/Remote.cpp
+++ b/src/control/Remote.cpp
@@ -9,6 +9,8 @@
#include "PlayerInfo.h"
#include "Vehicle.h"
+//--MIAMI: file done
+
void
CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uint16 model)
{
@@ -35,17 +37,24 @@ CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uin
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = car;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle);
- TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAMCONTROL_SCRIPT);
+ if (car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE || car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI) {
+ TheCamera.TakeControl(car, CCam::MODE_CAM_ON_A_STRING, INTERPOLATION, CAMCONTROL_SCRIPT);
+ TheCamera.SetZoomValueCamStringScript(0);
+ } else
+ TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAMCONTROL_SCRIPT);
}
void
-CRemote::TakeRemoteControlledCarFromPlayer(void)
+CRemote::TakeRemoteControlledCarFromPlayer(bool blowUp)
{
- CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
- CCarCtrl::NumMissionCars--;
- CCarCtrl::NumRandomCars++;
+ if (CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
+ CCarCtrl::NumMissionCars--;
+ CCarCtrl::NumRandomCars++;
+ }
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bIsLocked = false;
CWorld::Players[CWorld::PlayerInFocus].m_nTimeLostRemoteCar = CTimer::GetTimeInMilliseconds();
CWorld::Players[CWorld::PlayerInFocus].m_bInRemoteMode = true;
- CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
+ CWorld::Players[CWorld::PlayerInFocus].field_D5 = blowUp;
+ CWorld::Players[CWorld::PlayerInFocus].field_D6 = true;
}
diff --git a/src/control/Remote.h b/src/control/Remote.h
index 5e474586..72cabb7c 100644
--- a/src/control/Remote.h
+++ b/src/control/Remote.h
@@ -4,5 +4,5 @@ class CRemote
{
public:
static void GivePlayerRemoteControlledCar(float, float, float, float, uint16);
- static void TakeRemoteControlledCarFromPlayer(void);
+ static void TakeRemoteControlledCarFromPlayer(bool blowUp = true);
};
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 1a050bee..80c05f31 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -39,6 +39,7 @@
#include "Text.h"
#include "Camera.h"
#include "Radar.h"
+#include "Fluff.h"
uint8 CReplay::Mode;
CAddressInReplayBuffer CReplay::Record;
@@ -229,7 +230,7 @@ void CReplay::EnableReplays(void)
void PlayReplayFromHD(void);
void CReplay::Update(void)
{
- if (CCutsceneMgr::IsCutsceneProcessing() || CTimer::GetIsPaused())
+ if (CCutsceneMgr::IsCutsceneProcessing() || CTimer::GetIsPaused() || CScriptPaths::IsOneActive())
return;
switch (Mode){
case MODE_RECORD:
@@ -1175,6 +1176,7 @@ void CReplay::StoreStuffInMem(void)
if (ped)
StoreDetailedPedAnimation(ped, &pPedAnims[i]);
}
+ CScriptPaths::Save_ForReplay();
}
void CReplay::RestoreStuffFromMem(void)
@@ -1351,6 +1353,7 @@ void CReplay::RestoreStuffFromMem(void)
}
delete[] pPedAnims;
pPedAnims = nil;
+ CScriptPaths::Load_ForReplay();
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index eb950464..bf761a3f 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -82,6 +82,7 @@
#include "main.h"
#include "Ropes.h"
#include "MBlur.h"
+#include "Fluff.h"
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#include <stdarg.h>
#endif
@@ -1806,7 +1807,7 @@ void CMissionCleanup::Process()
// TODO(MIAMI)
//CSpecialFX::bLiftCam = false;
//CSpecialFX::bVideoCam = false;
- //CTimeCycle::StopExtraColour(0);
+ CTimeCycle::StopExtraColour(0);
for (int i = 0; i < MISSION_AUDIO_SLOTS; i++)
DMAudio.ClearMissionAudio(i);
CWeather::ReleaseWeather();
@@ -1822,8 +1823,11 @@ void CMissionCleanup::Process()
CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false;
CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
CWorld::Players[0].MakePlayerSafe(false);
- //TODO(MIAMI): drunkenness, enable drive by
- //DMAudio::ShutUpPlayerTalking(0);
+ CWorld::Players[0].m_pPed->m_nFadeDrunkenness = 1;
+ CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0;
+ CPad::GetPad(0)->SetDrunkInputDelay(0);
+ CWorld::Players[0].m_bDriveByAllowed = true;
+ // DMAudio::ShutUpPlayerTalking(0); // TODO(Miami)
CVehicle::bDisableRemoteDetonation = false;
CVehicle::bDisableRemoteDetonationOnContact = false;
CGameLogic::ClearShortCut();
@@ -3130,7 +3134,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
{
CollectParameters(&m_nIp, 4);
int32 index = ScriptParams[0];
- assert(index < NUMPLAYERS);
+ script_assert(index < NUMPLAYERS);
printf("&&&&&&&&&&&&&Creating player: %d\n", index);
if (!CStreaming::HasModelLoaded(MI_PLAYER)) {
CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
@@ -5171,7 +5175,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
if (pPed->bInVehicle)
return 0;
pPed->m_fRotationDest = pPed->m_fRotationCur = DEGTORAD(*(float*)&ScriptParams[1]);
@@ -5353,7 +5357,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 2, BLIP_DISPLAY_BOTH);
+ int handle = CRadar::SetCoordBlip(BLIP_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
CRadar::ChangeBlipScale(handle, 3);
ScriptParams[0] = handle;
StoreParameters(&m_nIp, 1);
@@ -5997,7 +6001,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_DESTROY_OBJECT, pVehicle);
@@ -9792,7 +9796,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- C3dMarkers::PlaceMarkerSet((uintptr)this + m_nIp, 4, pos, *(float*)&ScriptParams[3],
+ C3dMarkers::PlaceMarkerSet((uintptr)this + m_nIp, MARKERTYPE_CYLINDER, pos, *(float*)&ScriptParams[3],
SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A,
SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
return 0;
@@ -10225,11 +10229,11 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
return 0;
CVehicle* car;
if (CModelInfo::IsBikeModel(model)) {
- car = new CBike(model, MISSION_VEHICLE);
+ car = new CBike(model, RANDOM_VEHICLE);
((CBike*)(car))->bIsStanding = true;
}
else
- car = new CAutomobile(model, MISSION_VEHICLE);
+ car = new CAutomobile(model, RANDOM_VEHICLE);
CVector pos = *(CVector*)&ScriptParams[0];
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
car->SetPosition(pos);
@@ -10447,7 +10451,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
return 0;
@@ -10587,15 +10591,17 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CollectParameters(&m_nIp, 1);
CTimer::Stop();
CGame::currLevel = (eLevelName)ScriptParams[0];
-#ifndef NO_ISLAND_LOADING
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
-#endif
+ ISLAND_LOADING_IS(LOW)
+ {
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ }
CCollision::SortOutCollisionAfterLoad();
-#ifndef NO_ISLAND_LOADING
- CStreaming::RequestIslands(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
-#endif
+ ISLAND_LOADING_ISNT(HIGH)
+ {
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ }
CTimer::Update();
return 0;
}
@@ -10642,14 +10648,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_SET_DRUNK_INPUT_DELAY:
{
CollectParameters(&m_nIp, 2);
- debug("SET_DRUNK_INPUT_DELAY not implemented\n");
+ assert(ScriptParams[1] < CPad::DRUNK_STEERING_BUFFER_SIZE);
+ CPad::GetPad(ScriptParams[0])->SetDrunkInputDelay(ScriptParams[1]);
return 0;
}
case COMMAND_SET_CHAR_MONEY:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->m_nPedMoney = ScriptParams[1];
pPed->bMoneyHasBeenGivenByScript = true;
return 0;
@@ -10659,7 +10666,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
CollectParameters(&m_nIp, 4);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
CVector result = Multiply3x3(pObject->GetMatrix(), *(CVector*)&ScriptParams[1]) + pObject->GetPosition();
*(CVector*)&ScriptParams[0] = result;
StoreParameters(&m_nIp, 3);
@@ -10692,7 +10699,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
CollectParameters(&m_nIp, 4);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
CVector result = Multiply3x3(pVehicle->GetMatrix(), *(CVector*)&ScriptParams[1]) + pVehicle->GetPosition();
*(CVector*)&ScriptParams[0] = result;
StoreParameters(&m_nIp, 3);
@@ -10920,7 +10927,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
#ifdef USE_MEASUREMENTS_IN_METERS
UpdateCompareFlag(true);
#else
- UpdateCompareFlag(false)
+ UpdateCompareFlag(false);
#endif
return 0;
case COMMAND_CONVERT_METRES_TO_FEET:
@@ -11050,7 +11057,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
UpdateCompareFlag(ScriptParams[1] < pVehicle->m_nNumMaxPassengers && pVehicle->pPassengers[ScriptParams[1]] == nil);
return 0;
}
@@ -11201,7 +11208,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
return 0;
*/
case COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED:
- UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3); // TODO(MIAMI): more cheats!
+ UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3 || CVehicle::bHoverCheat || CVehicle::bCheat8); // TODO(MIAMI): more cheats!
return 0;
case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS:
{
@@ -11273,24 +11280,33 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CTimer::Stop();
CGame::currLevel = (eLevelName)ScriptParams[0];
if (CGame::currLevel != CCollision::ms_collisionInMemory) {
-#ifndef NO_ISLAND_LOADING
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- CCollision::LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
-#endif
+ ISLAND_LOADING_IS(LOW)
+ {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+ }
CPopulation::DealWithZoneChange(CCollision::ms_collisionInMemory, CGame::currLevel, false);
-#ifndef NO_ISLAND_LOADING
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
-#endif
+
+ ISLAND_LOADING_IS(LOW)
+ {
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ }
CCollision::SortOutCollisionAfterLoad();
-#ifndef NO_ISLAND_LOADING
- CStreaming::RequestIslands(CGame::currLevel);
- CStreaming::RequestBigBuildings(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
- DMAudio.SetEffectsFadeVol(127);
-#endif
+
+ ISLAND_LOADING_ISNT(HIGH)
+ CStreaming::RequestIslands(CGame::currLevel);
+
+ ISLAND_LOADING_IS(LOW)
+ CStreaming::RequestBigBuildings(CGame::currLevel);
+
+ ISLAND_LOADING_ISNT(HIGH)
+ CStreaming::LoadAllRequestedModels(true);
+
+ ISLAND_LOADING_IS(LOW)
+ DMAudio.SetEffectsFadeVol(127);
}
CTimer::Update();
return 0;
@@ -11893,7 +11909,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->m_ceaseAttackTimer = ScriptParams[1];
return 0;
}
@@ -11929,7 +11945,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->m_nRouteSeed = ScriptParams[1];
return 0;
}
@@ -11946,7 +11962,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->ClearWeapons();
return 0;
}
@@ -11954,7 +11970,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
bool bFound = false;
for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
if (pPed->GetWeapon(i).m_eWeaponType == ScriptParams[1]) {
@@ -11971,7 +11987,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle && pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ script_assert(pVehicle && pVehicle->m_vehType == VEHICLE_TYPE_CAR);
((CAutomobile*)pVehicle)->bTankDetonateCars = ScriptParams[1];
return 0;
}
@@ -11990,7 +12006,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
bool bOnFire = false;
if (pVehicle->m_pCarFire)
bOnFire = true;
@@ -12005,7 +12021,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
bool bIsBurst = false;
CBike* pBike = (CBike*)pVehicle;
if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) {
@@ -12042,43 +12058,49 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
//case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE:
//case COMMAND_IS_PLAYER_FOOT_DOWN:
//case COMMAND_IS_CHAR_FOOT_DOWN:
- case COMMAND_INITIALISE_OBJECT_PATH:
- // TODO(MIAMI): script path
+ case COMMAND_INITIALISE_OBJECT_PATH: {
CollectParameters(&m_nIp, 2);
- debug("INITALISE_OBJECT_PATH not yet implemented, skipping\n");
- ScriptParams[0] = 0;
+ int32 counter = 0;
+ while (counter < 3 && CScriptPaths::aArray[counter].m_state != SCRIPT_PATH_DISABLED) {
+ counter++;
+ }
+ CScriptPaths::aArray[counter].InitialiseOne(ScriptParams[0], *(float*)&ScriptParams[1]);
+ ScriptParams[0] = counter;
StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_START_OBJECT_ON_PATH:
{
CollectParameters(&m_nIp, 2);
- debug("START_OBJECT_ON_PATH not yet implemented, skipping\n");
+ CObject *pObj = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ assert(pObj);
+ CScriptPaths::aArray[ScriptParams[1]].SetObjectToControl(pObj);
return 0;
}
case COMMAND_SET_OBJECT_PATH_SPEED:
{
CollectParameters(&m_nIp, 2);
- debug("SET_OBJECT_PATH_SPEED not yet implemented, skipping\n");
+ CScriptPaths::aArray[ScriptParams[0]].m_fSpeed = *(float*)&ScriptParams[1];
return 0;
}
case COMMAND_SET_OBJECT_PATH_POSITION:
{
CollectParameters(&m_nIp, 2);
- debug("SET_OBJECT_PATH_POSITION not yet implemented, skipping\n");
+ CScriptPaths::aArray[ScriptParams[0]].m_fPosition = *(float*)&ScriptParams[1];
return 0;
}
//case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH:
case COMMAND_CLEAR_OBJECT_PATH:
{
CollectParameters(&m_nIp, 1);
- debug("CLEAR_OBJECT_PATH not yet implemented, skipping\n");
+ CScriptPaths::aArray[ScriptParams[0]].Clear();
return 0;
}
case COMMAND_HELI_GOTO_COORDS:
{
CollectParameters(&m_nIp, 5);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
+ script_assert(pVehicle && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
((CAutomobile*)pVehicle)->TellHeliToGoToCoors(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], ScriptParams[4]);
return 0;
}
@@ -12121,7 +12143,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT);
return 0;
}
@@ -12129,7 +12151,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT);
return 0;
}
@@ -12137,7 +12159,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
return 0;
}
@@ -12145,7 +12167,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
return 0;
}
@@ -12153,7 +12175,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE);
return 0;
}
@@ -12161,7 +12183,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
return 0;
}
@@ -12256,7 +12278,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
ScriptParams[0] = pPed->GetWeapon(ScriptParams[1]).m_eWeaponType;
ScriptParams[1] = pPed->GetWeapon(ScriptParams[1]).m_nAmmoTotal;
ScriptParams[2] = CPickups::ModelForWeapon((eWeaponType)ScriptParams[0]);
@@ -12276,17 +12298,17 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
float speed = *(float*)&ScriptParams[1] / GAME_SPEED_TO_CARAI_SPEED;
pVehicle->SetMoveSpeed(pVehicle->GetForward() * speed);
- // TODO(MIAMI): heli hack!
+ if (pVehicle->IsRealHeli() && pVehicle->IsCar())
+ ((CAutomobile*)pVehicle)->m_aWheelSpeed[1] = 0.22f;
return 0;
}
case COMMAND_SET_AREA_VISIBLE:
CollectParameters(&m_nIp, 1);
CGame::currArea = ScriptParams[0];
- // TODO(MIAMI) !!
- //CStreaming::RemoveBuildingsNotInArea(ScriptParams[0]);
+ CStreaming::RemoveBuildingsNotInArea(ScriptParams[0]);
return 0;
case COMMAND_SET_CUTSCENE_ANIM_TO_LOOP:
{
@@ -12300,7 +12322,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->bPartOfConvoy = ScriptParams[1];
return 0;
}
@@ -12332,9 +12354,9 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- assert(pTargetPed);
+ script_assert(pTargetPed);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pTargetPed);
return 0;
@@ -12344,7 +12366,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 4);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CVector result = Multiply3x3(pPed->GetMatrix(), *(CVector*)&ScriptParams[1]) + pPed->GetPosition();
*(CVector*)&ScriptParams[0] = result;
StoreParameters(&m_nIp, 3);
@@ -12354,7 +12376,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
bool result = false;
if (pPed->bHasBeenPhotographed) {
result = true;
@@ -12367,9 +12389,9 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- assert(pTargetPed);
+ script_assert(pTargetPed);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_AIM_GUN_AT, pTargetPed);
return 0;
@@ -12385,7 +12407,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && (pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE));
return 0;
}
@@ -12415,7 +12437,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
float fAngle = DEGTORAD(*(float*)&ScriptParams[1] - 90.0f);
while (fAngle < 0.0f)
fAngle += TWOPI;
@@ -12428,14 +12450,16 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
pHeli->ClearHeliOrientation();
return 0;
}
case COMMAND_PLANE_GOTO_COORDS:
{
CollectParameters(&m_nIp, 5);
- debug("PLANE_GOTO_COORS is not implemented\n"); // TODO(MIAMI)
+ CAutomobile* pPlane = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pPlane && pPlane->IsCar() && pPlane->IsRealPlane());
+ pPlane->TellPlaneToGoToCoors(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], ScriptParams[4]);
return 0;
}
case COMMAND_GET_NTH_CLOSEST_CAR_NODE:
@@ -12467,7 +12491,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bIsFrozen = ScriptParams[1];
return 0;
}
@@ -12475,7 +12499,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bDrownsInWater = ScriptParams[1];
return 0;
}
@@ -12483,7 +12507,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
pObject->bUseCollisionRecords = ScriptParams[1];
return 0;
}
@@ -12491,7 +12515,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
UpdateCompareFlag(pObject->m_nCollisionRecords != 0);
return 0;
}
@@ -12505,7 +12529,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
ScriptParams[0] = pPed->m_fArmour;
StoreParameters(&m_nIp, 1);
return 0;
@@ -12515,7 +12539,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->bHeliMinimumTilt = ScriptParams[1];
return 0;
}
@@ -12523,7 +12547,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->AutoPilot.m_nSwitchDistance = ScriptParams[1];
return 0;
}
@@ -12531,7 +12555,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pCar&& pCar->IsCar());
+ script_assert(pCar&& pCar->IsCar());
pCar->PopBoot();
return 0;
}
@@ -12564,7 +12588,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
UpdateCompareFlag(pObject->bIsInWater);
return 0;
}
@@ -12577,7 +12601,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 3);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (ScriptParams[1]) {
pPed->bIsDucking = true;
pPed->SetDuck(ScriptParams[2], true);
@@ -12641,7 +12665,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bIsStaticWaitingForCollision);
return 0;
}
@@ -12649,7 +12673,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
UpdateCompareFlag(pVehicle->bIsStaticWaitingForCollision);
return 0;
}
@@ -12657,7 +12681,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
UpdateCompareFlag(pObject->bIsStaticWaitingForCollision);
return 0;
}
@@ -12680,7 +12704,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 3);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bIsPlayerFriend = ScriptParams[2];
return 0;
}
@@ -12688,7 +12712,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING:
{
char onscreen_str[12];
- assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
+ script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
int16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
CollectParameters(&m_nIp, 2);
wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ???
@@ -12709,27 +12733,33 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
case COMMAND_SET_EXTRA_COLOURS:
{
CollectParameters(&m_nIp, 2);
- debug("SET_EXTRA_COLOURS not implemented, skipping\n");
+ CTimeCycle::StartExtraColour(ScriptParams[0]-1, ScriptParams[1] != 0);
return 0;
}
case COMMAND_CLEAR_EXTRA_COLOURS:
{
CollectParameters(&m_nIp, 1);
- debug("CLEAR_EXTRA_COLOURS not implemented, skipping\n");
+ CTimeCycle::StopExtraColour(ScriptParams[0]);
return 0;
}
//case COMMAND_CLOSE_CAR_BOOT:
case COMMAND_GET_WHEELIE_STATS:
{
CollectParameters(&m_nIp, 1);
- static bool bShowed = false;
- if (!bShowed) {
- debug("GET_WHEELIE_STATS not implemented\n");
- bShowed = true;
- }
- for (int i = 0; i < 6; i++)
- ScriptParams[i] = 0;
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels;
+ ScriptParams[1] = *(int*)&pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels;
+ ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie;
+ ScriptParams[3] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnWheelie;
+ ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie;
+ ScriptParams[5] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnStoppie;
StoreParameters(&m_nIp, 6);
+ pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0;
+ pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f;
+ pPlayerInfo->m_nLastTimeSpentOnWheelie = 0;
+ pPlayerInfo->m_nLastDistanceTravelledOnWheelie = 0.0f;
+ pPlayerInfo->m_nLastTimeSpentOnStoppie = 0;
+ pPlayerInfo->m_nLastDistanceTravelledOnStoppie = 0.0f;
return 0;
}
//case COMMAND_DISARM_CHAR:
@@ -12753,7 +12783,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->m_prevObjective == OBJECTIVE_NONE && pPed->m_objective == OBJECTIVE_NONE);
return 0;
}
@@ -12766,7 +12796,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
key[i] = tolower(key[i]);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(strcmp(key, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName()) == 0);
return 0;
}
@@ -12781,7 +12811,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 3);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CVector pos;
pos.x = *(float*)&ScriptParams[1];
pos.y = *(float*)&ScriptParams[2];
@@ -12814,7 +12844,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pCar&& pCar->IsCar());
+ script_assert(pCar&& pCar->IsCar());
pCar->CloseAllDoors();
return 0;
}
@@ -12836,7 +12866,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pCar && pCar->IsCar());
+ script_assert(pCar && pCar->IsCar());
pCar->PopBootUsingPhysics();
return 0;
}
@@ -12845,7 +12875,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE);
return 0;
}
@@ -12853,7 +12883,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 2);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
pObject->m_pCollidingEntity = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
return 0;
}
@@ -12862,7 +12892,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
{
CollectParameters(&m_nIp, 5);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(CWorld::IsWanderPathClear(pPed->GetPosition(), *(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3], 4));
return 0;
}
@@ -12875,7 +12905,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
}
//case COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER:
default:
- assert(0);
+ script_assert(0);
}
return -1;
}
@@ -12887,7 +12917,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 3);
CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pTarget);
+ script_assert(pTarget);
uint8 flag = 1 << (uint8)ScriptParams[1];
if (ScriptParams[2])
pTarget->m_gangFlags |= flag;
@@ -12933,7 +12963,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->bIsFrozen = ScriptParams[1];
return 0;
}
@@ -12987,32 +13017,38 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE:
{
CollectParameters(&m_nIp, 3);
- debug("ATTACH_CUTSCENE_OBJECT_TO_BONE not implemented, skipping\n"); // TODO(MIAMI)
+ CCutsceneMgr::AttachObjectToBone(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetObjectPool()->GetAt(ScriptParams[1]), ScriptParams[2]);
return 0;
}
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT:
{
CollectParameters(&m_nIp, 2);
- debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI)
+ CObject *obj1 = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CObject *obj2 = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
m_nIp += KEY_LENGTH_IN_SCRIPT;
+
+ CCutsceneMgr::AttachObjectToFrame(obj1, obj2, key);
return 0;
}
case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bStayInCarOnJack = ScriptParams[1];
return 0;
}
//case COMMAND_IS_MISSION_AUDIO_LOADING:
case COMMAND_ADD_MONEY_SPENT_ON_WEAPONS:
CollectParameters(&m_nIp, 1);
- debug("ADD_MONEY_SPENT_ON_WEAPON not implemented\n"); // TODO(MIAMI)
+ CStats::MoneySpentOnWeapons(ScriptParams[0]);
return 0;
case COMMAND_ADD_MONEY_SPENT_ON_PROPERTY:
CollectParameters(&m_nIp, 1);
- debug("ADD_MONEY_SPENT_ON_PROPERTY not implemented\n"); // TODO(MIAMI)
+ CStats::MoneySpentOnProperty(ScriptParams[0]);
return 0;
//case COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING:
case COMMAND_SET_CHAR_ANSWERING_MOBILE:
@@ -13041,21 +13077,21 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
//case COMMAND_ADD_LOAN_SHARK_VISITS:
case COMMAND_ADD_STORES_KNOCKED_OFF:
CollectParameters(&m_nIp, 1);
- debug("ADD_STORES_KNOCKED_OFF not implemented\n"); // TODO(MIAMI)
+ CStats::NumOfStoresKnockedOff(ScriptParams[0]);
return 0;
//case COMMAND_ADD_MOVIE_STUNTS:
case COMMAND_ADD_NUMBER_OF_ASSASSINATIONS:
CollectParameters(&m_nIp, 1);
- debug("ADD_NUMBER_OF_ASSASSINATIONS not implemented\n"); // TODO(MIAMI)
+ CStats::NumOfAssassinations(ScriptParams[0]);
return 0;
case COMMAND_ADD_PIZZAS_DELIVERED:
CollectParameters(&m_nIp, 1);
- debug("ADD_PIZZAS_DELIVERED not implemented\n"); // TODO(MIAMI)
+ CStats::NumOfPizzasDelivered(ScriptParams[0]);
return 0;
//case COMMAND_ADD_GARBAGE_PICKUPS:
case COMMAND_ADD_ICE_CREAMS_SOLD:
CollectParameters(&m_nIp, 1);
- debug("ADD_ICE_CREAMS_SOLD not implemented\n"); // TODO(MIAMI)
+ CStats::NumOfIceCreamSold(ScriptParams[0]);
return 0;
//case COMMAND_SET_TOP_SHOOTING_RANGE_SCORE:
//case COMMAND_ADD_SHOOTING_RANGE_RANK:
@@ -13066,7 +13102,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bDontFight = !ScriptParams[1];
return 0;
}
@@ -13074,7 +13110,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->ClearWaitState();
return 0;
}
@@ -13109,7 +13145,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
pVehicle->bTyresDontBurst = !ScriptParams[1];
return 0;
}
@@ -13117,7 +13153,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
pPed->bDoomAim = ScriptParams[1];
return 0;
}
@@ -13137,15 +13173,15 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
}
case COMMAND_SET_PROPERTY_AS_OWNED:
CollectParameters(&m_nIp, 1);
- debug("SET_PROPERTY_AS_OWNED not implemented\n"); // TODO(MIAMI)
+ CStats::AddPropertyAsOwned(ScriptParams[0]);
return 0;
case COMMAND_ADD_BLOOD_RING_KILLS:
CollectParameters(&m_nIp, 1);
- debug("ADD_BLOOD_RING_KILLS not implemented\n"); // TODO(MIAMI)
+ CStats::AddNumBloodRingKills(ScriptParams[0]);
return 0;
case COMMAND_SET_LONGEST_TIME_IN_BLOOD_RING:
CollectParameters(&m_nIp, 1);
- debug("SET_LONGEST_TIME_IN_BLOOD_RING not implemented\n"); // TODO(MIAMI)
+ CStats::LongestTimeInBloodRing(ScriptParams[0]);
return 0;
case COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE:
{
@@ -13156,7 +13192,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
CPhysical* pTestedEntity = pPed;
if (pPed->bInVehicle && pPed->m_pMyVehicle)
@@ -13188,7 +13224,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (pPed->GetPedState() == PED_FOLLOW_PATH) {
pPed->RestorePreviousState();
pPed->ClearFollowPath();
@@ -13199,14 +13235,14 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bCanBeShotInVehicle = ScriptParams[1];
return 0;
}
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE:
{
CollectParameters(&m_nIp, 2);
- debug("ATTACH_CUTSCENE_OBJECT_TO_VEHICLE not implemented\n"); // TODO(MIAMI)
+ CCutsceneMgr::AttachObjectToParent(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetVehiclePool()->GetAt(ScriptParams[1]));
return 0;
}
case COMMAND_LOAD_MISSION_TEXT:
@@ -13238,7 +13274,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
pObject->bIsFrozen = ScriptParams[1];
return 0;
}
@@ -13271,7 +13307,8 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
//case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT:
//case COMMAND_GET_CLOSEST_WATER_NODE:
case COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH:
- debug("ADD_PORN_LEAFLET_TO_RUBBISH is not implemented\n"); // TODO(MIAMI)
+ CollectParameters(&m_nIp, 1);
+ CStats::PamphletMissionPassed = ScriptParams[0];
return 0;
case COMMAND_CREATE_CLOTHES_PICKUP:
{
@@ -13373,7 +13410,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bIgnoreThreatsBehindObjects = ScriptParams[1];
return 0;
}
@@ -13381,7 +13418,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
if (pPed->bInVehicle) {
if (pPed->GetWeapon(5).m_eWeaponType) { // TODO(MIAMI): enum
if (pPed->GetWeapon(5).m_nAmmoTotal < ScriptParams[1])
@@ -13400,7 +13437,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 1);
CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
pHeli->bHeliDestroyed = true;
return 0;
}
@@ -13414,7 +13451,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
pObject->m_area = ScriptParams[1];
return 0;
}
@@ -13423,7 +13460,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bNeverEverTargetThisPed = ScriptParams[1];
return 0;
}
@@ -13444,7 +13481,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
pPed->bCrouchWhenScared = true;
return 0;
}
@@ -13452,7 +13489,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle &&
pPed->m_pMyVehicle->IsLawEnforcementVehicle() &&
pPed->m_pMyVehicle->GetModelIndex() != MI_PREDATOR);
@@ -13481,7 +13518,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->m_nWaitState == WAITSTATE_STUCK);
return 0;
}
@@ -13495,7 +13532,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (ScriptParams[1]) {
pPed->bKindaStayInSamePlace = true;
pPed->bStopAndShoot = true;
@@ -13511,7 +13548,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
if (ScriptParams[1]) {
pVehicle->bIsFrozen = true;
pVehicle->bInfiniteMass = true;
@@ -13531,7 +13568,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
//case COMMAND_FREEZE_OBJECT_POSITION_AND_DONT_LOAD_COLLISION:
//case COMMAND_SET_FADE_AND_JUMPCUT_AFTER_RC_EXPLOSION:
default:
- assert(0);
+ script_assert(0);
}
return -1;
}
@@ -13541,13 +13578,13 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
switch (command) {
case COMMAND_REGISTER_VIGILANTE_LEVEL:
CollectParameters(&m_nIp, 1);
- debug("REGISTER_VIGILANTE_LEVEL not implemented\n"); // TODO(MIAMI)
+ CStats::RegisterLevelVigilanteMission(ScriptParams[0]);
return 0;
case COMMAND_CLEAR_ALL_CHAR_ANIMS:
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (!pPed->bInVehicle) {
pPed->m_pVehicleAnim = nil;
pPed->RestartNonPartialAnims();
@@ -13596,17 +13633,19 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
case COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER:
{
CollectParameters(&m_nIp, 1);
- debug("GET_BUS_FARES_COLLECTED_BY_PLAYER not implemented\n"); // TODO(MIAMI)
- ScriptParams[0] = 0;
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ ScriptParams[0] = pPlayerInfo->m_pPed->m_nLastBusFareCollected;
+ pPlayerInfo->m_pPed->m_nLastBusFareCollected = 0;
StoreParameters(&m_nIp, 1);
+ return 0;
}
case COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- assert(pVehicle);
+ script_assert(pVehicle);
ScriptParams[0] = 0;
if (pPed->m_objective == OBJECTIVE_NONE && !pPed->bHasAlreadyUsedAttractor) {
C2dEffect* pEffect = (C2dEffect*)GetPedAttractorManager()->GetEffectForIceCreamVan(pVehicle, pPed->GetPosition()); // has to be casted, because inner methods are const
@@ -13648,7 +13687,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (pPed->m_attractor)
GetPedAttractorManager()->DeRegisterPed(pPed, pPed->m_attractor);
return 0;
@@ -13660,7 +13699,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bHasAlreadyUsedAttractor);
return 0;
}
@@ -13668,7 +13707,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
if (ScriptParams[1]) {
pVehicle->bDontLoadCollision = false;
if (m_bMissionFlag) {
@@ -13691,7 +13730,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
if (ScriptParams[1]) {
pPed->bDontLoadCollision = false;
if (m_bMissionFlag) {
@@ -13721,7 +13760,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bBoughtIceCream);
return 0;
}
@@ -13795,20 +13834,39 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
}
//case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE:
case COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA:
+ {
CollectParameters(&m_nIp, 4);
- debug("UNLOCK_ALL_CAR_DOORS_IN_AREA not implemented\n"); // TODO(MIAMI)
+ uint32 i = CPools::GetVehiclePool()->GetSize();
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float supX = *(float*)&ScriptParams[2];
+ float supY = *(float*)&ScriptParams[3];
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ if (pVehicle->IsWithinArea(infX, infY, supX, supY))
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ }
return 0;
+ }
case COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS:
CollectParameters(&m_nIp, 2);
CGangs::SetWillAttackPlayerWithCops((ePedType)((int)PEDTYPE_GANG1 + ScriptParams[0]), !!ScriptParams[1]);
return 0;
case COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR:
- assert(0);
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bHeldHostageInCar = ScriptParams[1];
+ return 0;
+ }
case COMMAND_SET_VEHICLE_TO_FADE_IN:
{
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- assert(pVehicle);
+ script_assert(pVehicle);
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), ScriptParams[1]);
return 0;
}
@@ -13822,7 +13880,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle && pPed->m_pMyVehicle == CGameLogic::pShortCutTaxi);
return 0;
}
@@ -13830,7 +13888,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- assert(pPed);
+ script_assert(pPed);
UpdateCompareFlag(RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_DUCK_DOWN) != nil);
return 0;
}
@@ -13854,7 +13912,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
}
case COMMAND_REGISTER_FIRE_LEVEL:
CollectParameters(&m_nIp, 1);
- debug("REGISTER_FIRE_LEVEL not implemented\n"); // TODO(MIAMI)
+ CStats::RegisterLevelFireMission(ScriptParams[0]);
return 0;
case COMMAND_IS_AUSTRALIAN_GAME:
UpdateCompareFlag(false); // should we make some check?
@@ -13870,7 +13928,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
return 0;
}
default:
- assert(0);
+ script_assert(0);
}
return -1;
}
@@ -14007,7 +14065,7 @@ void CTheScripts::DrawScriptSpheres()
{
for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
if (ScriptSphereArray[i].m_bInUse)
- C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, 4, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius,
+ C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius,
SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
}
}
@@ -14850,7 +14908,7 @@ void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp)
}
CollectParameters(pIp, b3D ? 8 : 6);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
CVector pos = pObject->GetPosition();
X = *(float*)&ScriptParams[1];
Y = *(float*)&ScriptParams[2];
@@ -15405,7 +15463,7 @@ void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp)
}
CollectParameters(pIp, b3D ? 8 : 6);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- assert(pObject);
+ script_assert(pObject);
CVector pos = pObject->GetPosition();
infX = *(float*)&ScriptParams[1];
infY = *(float*)&ScriptParams[2];
@@ -15458,7 +15516,7 @@ void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp)
result = true;
break;
default:
- assert(false);
+ script_assert(false);
break;
}
}
diff --git a/src/control/Script.h b/src/control/Script.h
index 3577b401..ba315c46 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -374,10 +374,10 @@ private:
static int32 GetNewUniqueScriptSphereIndex(int32 index);
static void RemoveScriptSphere(int32 index);
static void RemoveScriptTextureDictionary();
+public:
static void RemoveThisPed(CPed* pPed);
#ifdef MISSION_SWITCHER
-public:
static void SwitchToMission(int32 mission);
#endif
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index 375e9d5b..b996e77f 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -4894,11 +4894,6 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (ResetStatics) {
FOV = DefaultFOV;
-
- // TODO(Miami): Remove that when cam is done!
- // GTA 3 has this in veh. camera
- if (TheCamera.m_bIdleOn)
- TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds();
} else {
if (isCar || isBike) {
// 0.4f: CAR_FOV_START_SPEED
@@ -4933,18 +4928,13 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
Rotating = false;
m_bCollisionChecksOn = true;
-
- // TODO(Miami): Uncomment that when cam is done!
-
- // Garage exit cam is not working well in III...
- // if (!TheCamera.m_bJustCameOutOfGarage)
- // {
- Alpha = 0.0f;
- Beta = car->GetForward().Heading() - HALFPI;
- if (TheCamera.m_bCamDirectlyInFront) {
- Beta += PI;
+ if (!TheCamera.m_bJustCameOutOfGarage) {
+ Alpha = 0.0f;
+ Beta = car->GetForward().Heading() - HALFPI;
+ if (TheCamera.m_bCamDirectlyInFront) {
+ Beta += PI;
+ }
}
- // }
BetaSpeed = 0.0;
AlphaSpeed = 0.0;
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 2f977a20..df778815 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -514,7 +514,12 @@ CCamera::Process(void)
int tableIndex = (int)(DEGTORAD(DrunkAngle)/TWOPI * CParticle::SIN_COS_TABLE_SIZE) & CParticle::SIN_COS_TABLE_SIZE-1;
DrunkAngle += 5.0f;
+#ifndef FIX_BUGS
+ // This just messes up interpolation, probably not what they intended
+ // and multiplying the interpolated FOV is also a bit extreme
+ // so let's not do any of this nonsense
Cams[ActiveCam].FOV *= (1.0f + CMBlur::Drunkness);
+#endif
CamSource.x += -0.02f*CMBlur::Drunkness * CParticle::m_CosTable[tableIndex];
CamSource.y += -0.02f*CMBlur::Drunkness * CParticle::m_SinTable[tableIndex];
diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp
index 45fd9832..e114a29a 100644
--- a/src/core/CdStreamPosix.cpp
+++ b/src/core/CdStreamPosix.cpp
@@ -150,9 +150,11 @@ CdStreamInit(int32 numChannels)
ASSERT(0);
return;
}
-
+#ifdef __linux__
_gdwCdStreamFlags = O_RDONLY | O_NOATIME;
-
+#else
+ _gdwCdStreamFlags = O_RDONLY;
+#endif
// People say it's slower
/*
if ( fsInfo.f_bsize <= CDSTREAM_SECTOR_SIZE )
@@ -400,9 +402,12 @@ void *CdStreamThread(void *param)
if (gCdStreamThreadStatus == 0){
gCdStreamThreadStatus = 1;
#endif
+
+#ifdef __linux__
pid_t tid = syscall(SYS_gettid);
int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1);
- }
+#endif
+ }
// spurious wakeup or we sent interrupt signal for flushing
if(pChannel->nSectorsToRead == 0)
diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp
index 070967e5..bca1e9b7 100644
--- a/src/core/ColStore.cpp
+++ b/src/core/ColStore.cpp
@@ -223,7 +223,6 @@ CColStore::EnsureCollisionIsInMemory(const CVector2D &pos)
}
}
-//--MIAMI: done
bool
CColStore::HasCollisionLoaded(const CVector2D &pos)
{
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index c2037dc5..91e7bba7 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -3049,6 +3049,18 @@ CColModel::GetTrianglePoint(CVector &v, int i) const
v = vertices[i].Get();
}
+void*
+CColModel::operator new(size_t){
+ CColModel *node = CPools::GetColModelPool()->New();
+ assert(node);
+ return node;
+}
+
+void
+CColModel::operator delete(void *p, size_t){
+ CPools::GetColModelPool()->Delete((CColModel*)p);
+}
+
CColModel&
CColModel::operator=(const CColModel &other)
{
diff --git a/src/core/Collision.h b/src/core/Collision.h
index fd079028..93959a72 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -181,7 +181,6 @@ struct CStoredCollPoly
bool valid;
};
-//--MIAMI: done struct
struct CColModel
{
CSphere boundingSphere;
@@ -208,6 +207,8 @@ struct CColModel
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
+ void *operator new(size_t);
+ void operator delete(void *p, size_t);
CColModel& operator=(const CColModel& other);
};
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index d194cebb..b0e04e2b 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -215,7 +215,10 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsPADINS, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsLCTRL, OPTIONAL_EXTRA);
-
+#ifdef BIND_VEHICLE_FIREWEAPON
+ SetControllerKeyAssociatedWithAction (VEHICLE_FIREWEAPON, rsPADINS, KEYBOARD);
+ SetControllerKeyAssociatedWithAction (VEHICLE_FIREWEAPON, rsLCTRL, OPTIONAL_EXTRA);
+#endif
SetControllerKeyAssociatedWithAction (PED_CYCLE_WEAPON_LEFT, rsPADDEL, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_CYCLE_WEAPON_RIGHT, rsPADENTER, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
@@ -285,6 +288,9 @@ void CControllerConfigManager::InitDefaultControlConfigMouse(CMouseControllerSta
{
m_bMouseAssociated = true;
SetMouseButtonAssociatedWithAction(PED_FIREWEAPON, 1);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ SetMouseButtonAssociatedWithAction(VEHICLE_FIREWEAPON, 1);
+#endif
}
if (availableButtons.RMB)
@@ -371,6 +377,9 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 3, JOYSTICK);
case 2:
SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 2, JOYSTICK);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 2, JOYSTICK);
+#endif
case 1:
SetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, 1, JOYSTICK);
/*******************************************************************************************/
@@ -422,6 +431,9 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 2, JOYSTICK);
case 1:
SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 1, JOYSTICK);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 1, JOYSTICK);
+#endif
/*******************************************************************************************/
}
}
@@ -463,6 +475,9 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(SHOW_MOUSE_POINTER_TOGGLE);
SETACTIONNAME(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
SETACTIONNAME(PED_FIREWEAPON);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ SETACTIONNAME(VEHICLE_FIREWEAPON);
+#endif
SETACTIONNAME(VEHICLE_ENTER_EXIT);
SETACTIONNAME(GO_LEFT);
SETACTIONNAME(GO_RIGHT);
@@ -651,12 +666,21 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown(int32 button,
}
AffectControllerStateOn_ButtonDown_AllStates(button, type, *state);
+
+#ifdef REGISTER_START_BUTTON
+ if (button == 12)
+ state->Start = 255;
+#endif
}
}
}
void CControllerConfigManager::AffectControllerStateOn_ButtonDown_Driving(int32 button, eControllerType type, CControllerState &state)
{
+#ifdef BIND_VEHICLE_FIREWEAPON
+ if (button == GetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, type))
+ state.Circle = 255;
+#endif
if (button == GetControllerKeyAssociatedWithAction(VEHICLE_LOOKBEHIND, type))
{
state.LeftShoulder2 = 255;
@@ -807,7 +831,11 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnl
void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstAndThirdPersonOnly(int32 button, eControllerType type, CControllerState &state)
{
CPad *pad = CPad::GetPad(PAD1);
-
+
+#ifdef BIND_VEHICLE_FIREWEAPON
+ if (button == GetControllerKeyAssociatedWithAction(PED_FIREWEAPON, type))
+ state.Circle = 255;
+#endif
if (button == GetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, type))
state.RightShoulder1 = 255;
@@ -889,8 +917,11 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_AllStates(int3
{
if (button == GetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, type))
state.Select = 255;
+
+#ifndef BIND_VEHICLE_FIREWEAPON
if (button == GetControllerKeyAssociatedWithAction(PED_FIREWEAPON, type))
state.Circle = 255;
+#endif
if (button == GetControllerKeyAssociatedWithAction(GO_LEFT, type))
{
@@ -1060,6 +1091,11 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonUp(int32 button, eC
{
if (FrontEndMenuManager.GetIsMenuActive())
AffectControllerStateOn_ButtonUp_All_Player_States(button, type, *state);
+
+#ifdef REGISTER_START_BUTTON
+ if (button == 12)
+ state->Start = 0;
+#endif
}
}
}
@@ -1601,28 +1637,25 @@ bool CControllerConfigManager::GetIsMouseButtonUp(RsKeyCodes keycode)
return false;
}
+#define CLEAR_ACTION_IF_NEEDED(action) \
+if (key == GetControllerKeyAssociatedWithAction(action, type))\
+ ClearSettingsAssociatedWithAction(action, type);
+
void CControllerConfigManager::DeleteMatchingCommonControls(e_ControllerAction action, int32 key, eControllerType type)
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS,type))
- ClearSettingsAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_FIREWEAPON, type))
- ClearSettingsAssociatedWithAction(PED_FIREWEAPON, type);
- if (key == GetControllerKeyAssociatedWithAction(GO_LEFT, type))
- ClearSettingsAssociatedWithAction(GO_LEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(GO_RIGHT, type))
- ClearSettingsAssociatedWithAction(GO_RIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(NETWORK_TALK, type))
- ClearSettingsAssociatedWithAction(NETWORK_TALK, type);
- if (key == GetControllerKeyAssociatedWithAction(SWITCH_DEBUG_CAM_ON, type))
- ClearSettingsAssociatedWithAction(SWITCH_DEBUG_CAM_ON, type);
- if (key == GetControllerKeyAssociatedWithAction(TOGGLE_DPAD, type))
- ClearSettingsAssociatedWithAction(TOGGLE_DPAD, type);
- if (key == GetControllerKeyAssociatedWithAction(TAKE_SCREEN_SHOT, type))
- ClearSettingsAssociatedWithAction(TAKE_SCREEN_SHOT, type);
- if (key == GetControllerKeyAssociatedWithAction(SHOW_MOUSE_POINTER_TOGGLE, type))
- ClearSettingsAssociatedWithAction(SHOW_MOUSE_POINTER_TOGGLE, type);
+ CLEAR_ACTION_IF_NEEDED(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
+#ifndef BIND_VEHICLE_FIREWEAPON
+ CLEAR_ACTION_IF_NEEDED(PED_FIREWEAPON);
+#endif
+ CLEAR_ACTION_IF_NEEDED(GO_LEFT);
+ CLEAR_ACTION_IF_NEEDED(GO_RIGHT);
+ CLEAR_ACTION_IF_NEEDED(NETWORK_TALK);
+ CLEAR_ACTION_IF_NEEDED(SWITCH_DEBUG_CAM_ON);
+ CLEAR_ACTION_IF_NEEDED(TOGGLE_DPAD);
+ CLEAR_ACTION_IF_NEEDED(TAKE_SCREEN_SHOT);
+ CLEAR_ACTION_IF_NEEDED(SHOW_MOUSE_POINTER_TOGGLE);
}
}
@@ -1630,16 +1663,11 @@ void CControllerConfigManager::DeleteMatching3rdPersonControls(e_ControllerActio
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(PED_LOOKBEHIND, type))
- ClearSettingsAssociatedWithAction(PED_LOOKBEHIND, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, type))
- ClearSettingsAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, type))
- ClearSettingsAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_JUMPING, type))
- ClearSettingsAssociatedWithAction(PED_JUMPING, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_SPRINT, type))
- ClearSettingsAssociatedWithAction(PED_SPRINT, type);
+ CLEAR_ACTION_IF_NEEDED(PED_LOOKBEHIND);
+ CLEAR_ACTION_IF_NEEDED(PED_CYCLE_WEAPON_LEFT);
+ CLEAR_ACTION_IF_NEEDED(PED_CYCLE_WEAPON_RIGHT);
+ CLEAR_ACTION_IF_NEEDED(PED_JUMPING);
+ CLEAR_ACTION_IF_NEEDED(PED_SPRINT);
if (key == GetControllerKeyAssociatedWithAction(PED_DUCK, type))
ClearSettingsAssociatedWithAction(PED_DUCK, type);
if (key == GetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, type))
@@ -1647,12 +1675,9 @@ void CControllerConfigManager::DeleteMatching3rdPersonControls(e_ControllerActio
if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{
- if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type))
- ClearSettingsAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_RIGHT, type))
- ClearSettingsAssociatedWithAction(PED_CYCLE_TARGET_RIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, type))
- ClearSettingsAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, type);
+ CLEAR_ACTION_IF_NEEDED(PED_CYCLE_TARGET_LEFT);
+ CLEAR_ACTION_IF_NEEDED(PED_CYCLE_TARGET_RIGHT);
+ CLEAR_ACTION_IF_NEEDED(PED_CENTER_CAMERA_BEHIND_PLAYER);
}
}
}
@@ -1661,23 +1686,19 @@ void CControllerConfigManager::DeleteMatching1rst3rdPersonControls(e_ControllerA
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, type))
- ClearSettingsAssociatedWithAction(PED_LOCK_TARGET, type);
- if (key == GetControllerKeyAssociatedWithAction(GO_FORWARD, type))
- ClearSettingsAssociatedWithAction(GO_FORWARD, type);
- if (key == GetControllerKeyAssociatedWithAction(GO_BACK, type))
- ClearSettingsAssociatedWithAction(GO_BACK, type);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ CLEAR_ACTION_IF_NEEDED(PED_FIREWEAPON);
+#endif
+ CLEAR_ACTION_IF_NEEDED(PED_LOCK_TARGET);
+ CLEAR_ACTION_IF_NEEDED(GO_FORWARD);
+ CLEAR_ACTION_IF_NEEDED(GO_BACK);
if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{
- if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type))
- ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_RIGHT, type))
- ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_RIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_DOWN, type))
- ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_DOWN, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_UP, type))
- ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_UP, type);
+ CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_LEFT);
+ CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_RIGHT);
+ CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_DOWN);
+ CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_UP);
}
}
}
@@ -1686,34 +1707,23 @@ void CControllerConfigManager::DeleteMatchingVehicleControls(e_ControllerAction
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_LOOKBEHIND, type))
- ClearSettingsAssociatedWithAction(VEHICLE_LOOKBEHIND, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_LOOKLEFT, type))
- ClearSettingsAssociatedWithAction(VEHICLE_LOOKLEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_LOOKRIGHT, type))
- ClearSettingsAssociatedWithAction(VEHICLE_LOOKRIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_LOOKBEHIND, type)) // note: dublicate
- ClearSettingsAssociatedWithAction(VEHICLE_LOOKBEHIND, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_HORN, type))
- ClearSettingsAssociatedWithAction(VEHICLE_HORN, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, type))
- ClearSettingsAssociatedWithAction(VEHICLE_HANDBRAKE, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_ACCELERATE, type))
- ClearSettingsAssociatedWithAction(VEHICLE_ACCELERATE, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_BRAKE, type))
- ClearSettingsAssociatedWithAction(VEHICLE_BRAKE, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, type))
- ClearSettingsAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, type);
- if (key == GetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, type))
- ClearSettingsAssociatedWithAction(TOGGLE_SUBMISSIONS, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_TURRETLEFT, type))
- ClearSettingsAssociatedWithAction(VEHICLE_TURRETLEFT, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_TURRETRIGHT, type))
- ClearSettingsAssociatedWithAction(VEHICLE_TURRETRIGHT, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_TURRETUP, type))
- ClearSettingsAssociatedWithAction(VEHICLE_TURRETUP, type);
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_TURRETDOWN, type))
- ClearSettingsAssociatedWithAction(VEHICLE_TURRETDOWN, type);
+#ifdef BIND_VEHICLE_FIREWEAPON
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_FIREWEAPON);
+#endif
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKBEHIND);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKLEFT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKRIGHT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKBEHIND); // note: duplicate
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_HORN);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_HANDBRAKE);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_ACCELERATE);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_BRAKE);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_CHANGE_RADIO_STATION);
+ CLEAR_ACTION_IF_NEEDED(TOGGLE_SUBMISSIONS);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETLEFT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETRIGHT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETUP);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETDOWN);
}
}
@@ -1721,8 +1731,7 @@ void CControllerConfigManager::DeleteMatchingVehicle_3rdPersonControls(e_Control
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, type))
- ClearSettingsAssociatedWithAction(VEHICLE_ENTER_EXIT, type);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_ENTER_EXIT);
}
}
@@ -1730,13 +1739,13 @@ void CControllerConfigManager::DeleteMatching1rstPersonControls(e_ControllerActi
{
if (!GetIsKeyBlank(key, type))
{
- if (key == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_IN, type))
- ClearSettingsAssociatedWithAction(PED_SNIPER_ZOOM_IN, type);
- if (key == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type))
- ClearSettingsAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type);
+ CLEAR_ACTION_IF_NEEDED(PED_SNIPER_ZOOM_IN);
+ CLEAR_ACTION_IF_NEEDED(PED_SNIPER_ZOOM_OUT);
}
}
+#undef CLEAR_ACTION_IF_NEEDED
+
void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction action, int32 key, eControllerType type)
{
if (!GetIsKeyBlank(key, type))
@@ -1814,7 +1823,9 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
{
switch (action)
{
+#ifndef BIND_VEHICLE_FIREWEAPON
case PED_FIREWEAPON:
+#endif
case GO_LEFT:
case GO_RIGHT:
case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
@@ -1839,6 +1850,9 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
return ACTIONTYPE_3RDPERSON;
break;
+#ifdef BIND_VEHICLE_FIREWEAPON
+ case VEHICLE_FIREWEAPON:
+#endif
case VEHICLE_LOOKBEHIND:
case VEHICLE_LOOKLEFT:
case VEHICLE_LOOKRIGHT:
@@ -1859,6 +1873,9 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
return ACTIONTYPE_VEHICLE_3RDPERSON;
break;
+#ifdef BIND_VEHICLE_FIREWEAPON
+ case PED_FIREWEAPON:
+#endif
case GO_FORWARD:
case GO_BACK:
case PED_1RST_PERSON_LOOK_LEFT:
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 05c37c22..eb66937a 100644
--- a/src/core/ControllerConfig.h
+++ b/src/core/ControllerConfig.h
@@ -34,6 +34,9 @@ enum e_ControllerAction
PED_LOOKBEHIND,
PED_DUCK,
PED_ANSWER_PHONE,
+#ifdef BIND_VEHICLE_FIREWEAPON
+ VEHICLE_FIREWEAPON,
+#endif
VEHICLE_ACCELERATE,
VEHICLE_BRAKE,
VEHICLE_CHANGE_RADIO_STATION,
diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h
index 51e30694..8278953b 100644
--- a/src/core/FileMgr.h
+++ b/src/core/FileMgr.h
@@ -19,4 +19,5 @@ public:
static bool ReadLine(int fd, char *buf, int len);
static int CloseFile(int fd);
static int GetErrorReadWrite(int fd);
+ static char *GetRootDirName() { return ms_rootDirName; }
};
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index ccb89fbd..c55b139c 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -36,6 +36,7 @@
#include "Stats.h"
#include "Messages.h"
#include "FileLoader.h"
+#include "User.h"
// TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places
#define CUSTOM_MAP
@@ -65,8 +66,6 @@ CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255);
#define FEET_IN_METER 3.33f
#endif
-#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
-
#ifdef TRIANGLE_BACK_BUTTON
#define GetBackJustUp GetTriangleJustUp
#define GetBackJustDown GetTriangleJustDown
@@ -291,7 +290,7 @@ CMenuManager::ThingsToDoBeforeLeavingPage()
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
#endif
- } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
+ } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_nDisplayVideoMode = m_nPrefsVideoMode;
#ifdef IMPROVED_VIDEOMODE
m_nSelectedScreenMode = m_nPrefsWindowed;
@@ -301,48 +300,13 @@ CMenuManager::ThingsToDoBeforeLeavingPage()
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
CPlayerSkin::EndFrontendSkinEdit();
}
-
-#ifdef CUSTOM_FRONTEND_OPTIONS
- for (int i = 0; i < numCustomFrontendOptions; i++) {
- FrontendOption& option = customFrontendOptions[i];
- if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) {
- if (option.returnPrevPageFunc)
- option.returnPrevPageFunc();
-
- if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC)
- option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
-
- if (option.onlyApplyOnEnter)
- option.displayedValue = *option.value;
- }
- }
-#endif
}
int8
CMenuManager::GetPreviousPageOption()
{
-#ifndef CUSTOM_FRONTEND_OPTIONS
- return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry :
- (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry))));
-#else
- int8 prevPage = aScreens[m_nCurrScreen].m_PreviousPage;
-
- if (prevPage == -1) // Game also does same
- return 0;
-
- prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage;
-
- for (int i = 0; i < NUM_MENUROWS; i++) {
- if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) {
- return i;
- }
- }
-
- // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?)
return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry :
(m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry))));
-#endif
}
// ------ Functions not in the game/inlined ends
@@ -924,9 +888,9 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
str = TheText.Get(aScreens[MENUPAGE_DELETE_SLOT_CONFIRM].m_aEntries[0].m_EntryName);
break;
case MENUPAGE_SAVE_OVERWRITE_CONFIRM:
- if (Slots[m_nCurrSaveSlot + 1] == SLOT_OK)
+ if (Slots[m_nCurrSaveSlot] == SLOT_OK)
str = TheText.Get("FESZ_QO");
- else if (Slots[m_nCurrSaveSlot + 1] == SLOT_CORRUPTED)
+ else if (Slots[m_nCurrSaveSlot] == SLOT_CORRUPTED)
str = TheText.Get("FESZ_QZ");
else
str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
@@ -1140,7 +1104,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
}
break;
#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENMODE:
+ case MENUACTION_SCREENFORMAT:
if (m_nSelectedScreenMode == 0)
sprintf(asciiTemp, "FULLSCREEN");
else
@@ -1211,32 +1175,6 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
rightText = TheText.Get("FEA_NM3");
}
break;
-#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_TRIGGERFUNC:
- FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu];
- if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) {
- leftText = (wchar*)option.leftText;
- if (option.type == FEOPTION_SELECT) {
- if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0)
- option.displayedValue = 0;
-
- rightText = (wchar*)option.rightTexts[option.displayedValue];
-
- } else if (option.type == FEOPTION_DYNAMIC) {
- if (option.drawFunc) {
- bool isOptionDisabled = false;
- rightText = option.drawFunc(&isOptionDisabled);
- if (isOptionDisabled)
- CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
- }
- }
- } else {
- debug("A- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, i, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu, option.screen, option.screenOptionOrder);
- assert(0 && "Custom frontend options is borked");
- }
-
- break;
-#endif
}
// Highlight trapezoid
@@ -1378,7 +1316,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
}
if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0
- && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
+ && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_nDisplayVideoMode = m_nPrefsVideoMode;
SetHelperText(3);
}
@@ -1386,29 +1324,11 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
#ifdef IMPROVED_VIDEOMODE
if (m_nSelectedScreenMode != m_nPrefsWindowed) {
if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_POS") != 0
- && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
+ && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_nSelectedScreenMode = m_nPrefsWindowed;
}
}
#endif
-#ifdef CUSTOM_FRONTEND_OPTIONS
- static int lastOption = m_nCurrOption;
-
- if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) {
- FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu];
- if (option.onlyApplyOnEnter && m_nCurrOption != i)
- option.displayedValue = *option.value;
-
- if (m_nCurrOption != lastOption && lastOption == i) {
- FrontendOption& oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu];
- if (oldOption.type == FEOPTION_DYNAMIC)
- oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
- }
- }
-
- if (i == MAX_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i + 1].m_EntryName[0] == '\0')
- lastOption = m_nCurrOption;
-#endif
// TODO(Miami): check
// Sliders
@@ -1465,7 +1385,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen)
case MENUPAGE_STATS:
case MENUPAGE_CONTROLLER_PC:
case MENUPAGE_SOUND_SETTINGS:
- case MENUPAGE_GRAPHICS_SETTINGS:
+ case MENUPAGE_DISPLAY_SETTINGS:
case MENUPAGE_MOUSE_CONTROLS:
DisplayHelperText(nil);
break;
@@ -1624,7 +1544,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
} else if (column == CONTSETUP_VEHICLE_COLUMN) {
switch (optionIdx) {
case 0:
- controllerAction = PED_FIREWEAPON;
+#ifdef BIND_VEHICLE_FIREWEAPON
+ controllerAction = VEHICLE_FIREWEAPON;
+#else
+ controllerAction = PED_FIREWEAPON;
+#endif
break;
case 1:
case 2:
@@ -2141,7 +2065,7 @@ CMenuManager::DrawFrontEnd()
bbNames[0] = { "FEB_SAV",MENUPAGE_NEW_GAME };
bbNames[1] = { "FEB_CON",MENUPAGE_CONTROLLER_PC };
bbNames[2] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS };
- bbNames[3] = { "FEB_DIS",MENUPAGE_GRAPHICS_SETTINGS };
+ bbNames[3] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS };
bbNames[4] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS };
bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT };
bbTabCount = 6;
@@ -2153,7 +2077,7 @@ CMenuManager::DrawFrontEnd()
bbNames[2] = { "FEB_BRI",MENUPAGE_BRIEFS };
bbNames[3] = { "FEB_CON",MENUPAGE_CONTROLLER_PC };
bbNames[4] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS };
- bbNames[5] = { "FEB_DIS",MENUPAGE_GRAPHICS_SETTINGS };
+ bbNames[5] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS };
bbNames[6] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS };
bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT };
bbTabCount = 8;
@@ -2226,7 +2150,7 @@ CMenuManager::DrawBackground()
case MENUPAGE_DELETE_SLOT_CONFIRM:
currentSprite = FE_ICONSAVE;
break;
- case MENUPAGE_GRAPHICS_SETTINGS:
+ case MENUPAGE_DISPLAY_SETTINGS:
currentSprite = FE_ICONDISPLAY;
break;
case MENUPAGE_SOUND_SETTINGS:
@@ -2472,7 +2396,7 @@ CMenuManager::DrawBackground(bool transitionCall)
menuBg.bottomRight_y = 398.0f;
break;
case MENUPAGE_BRIEFS:
- case MENUPAGE_GRAPHICS_SETTINGS:
+ case MENUPAGE_DISPLAY_SETTINGS:
case MENUPAGE_MAP:
case MENUPAGE_CHOOSE_LOAD_SLOT:
case MENUPAGE_CHOOSE_DELETE_SLOT:
@@ -3107,9 +3031,6 @@ CMenuManager::InitialiseChangedLanguageSettings()
break;
}
-#ifdef CUSTOM_FRONTEND_OPTIONS
- CustomFrontendOptionsPopulate();
-#endif
}
}
@@ -3583,7 +3504,7 @@ CMenuManager::Process(void)
InitialiseChangedLanguageSettings();
if (m_bMenuActive) {
- ProcessButtonPresses();
+ UserInput();
ProcessFileActions();
DMAudio.Service();
@@ -3593,100 +3514,249 @@ CMenuManager::Process(void)
SwitchMenuOnAndOff();
}
-// TODO(Miami)
+// Original name is unknown
void
-CMenuManager::ProcessButtonPresses(void)
+CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
{
- if (m_nCurrScreen == MENUPAGE_OUTRO)
+ if (m_bWaitingForNewKeyBind)
return;
- if (m_bWaitingForNewKeyBind) {
- if (m_bStartWaitingForKeyBind)
- m_bStartWaitingForKeyBind = false;
- else {
- pControlEdit = CPad::EditCodesForControls(pControlEdit, 1);
- JoyButtonJustClicked = false;
- MouseButtonJustClicked = false;
+ if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
+ m_nTotalListRow = m_nSkinsTotal;
+ }
+ if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
+ m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25;
+ if (m_nSelectedListRow > m_nTotalListRow)
+ m_nSelectedListRow = m_nTotalListRow - 1;
+ }
- if (CPad::GetPad(0)->GetLeftMouseJustDown())
- MouseButtonJustClicked = 1;
- else if (CPad::GetPad(0)->GetRightMouseJustUp())
- MouseButtonJustClicked = 3;
- else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
- MouseButtonJustClicked = 2;
- else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
- MouseButtonJustClicked = 4;
- else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
- MouseButtonJustClicked = 5;
- // TODO two more buttons
+ if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
+ m_bShowMouse = 0;
+ optionSelected = true;
+ }
+ if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_159) {
+ if (m_nCurrExLayer == HOVEROPTION_LIST) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ m_bWaitingForNewKeyBind = true;
+ m_bStartWaitingForKeyBind = true;
+ m_bKeyChangeNotProcessed = true;
+ pControlEdit = &m_KeyPressedCode;
+ }
+ } else {
+ field_159 = false;
+ }
- JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
+ static PauseModeTime lastTimeClickedScrollButton = 0;
- int32 TypeOfControl = KEYBOARD;
- if (JoyButtonJustClicked)
- TypeOfControl = JOYSTICK;
- if (MouseButtonJustClicked)
- TypeOfControl = MOUSE;
- if (*pControlEdit != rsNULL)
- TypeOfControl = KEYBOARD;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
+ m_bPressedPgUpOnList = false;
+ m_bPressedPgDnOnList = false;
+ m_bPressedUpOnList = false;
+ m_bPressedDownOnList = false;
+ m_bPressedScrollButton = false;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ }
- if (!m_bKeyIsOK) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
- pControlEdit = nil;
- m_bWaitingForNewKeyBind = false;
- m_KeyPressedCode = -1;
- m_bStartWaitingForKeyBind = false;
- }
- else if (!m_bKeyChangeNotProcessed) {
- if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked)
- CheckCodesForControls(TypeOfControl);
+ if (CPad::GetPad(0)->GetTabJustDown()) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ m_bShowMouse = false;
+ switch (m_nCurrExLayer) {
+ case HOVEROPTION_BACK:
+ default:
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ break;
+ case HOVEROPTION_LIST:
+ m_nCurrExLayer = HOVEROPTION_USESKIN;
+ break;
+ case HOVEROPTION_USESKIN:
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ }
- field_159 = true;
+ bool pressed = false;
+ if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
+ m_bShowMouse = false;
+ pressed = true;
+ } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) {
+ m_bShowMouse = true;
+ pressed = true;
+ }
+
+ // Up
+ if (pressed) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedUpOnList) {
+ m_bPressedUpOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ ScrollUpListByOne();
+ }
+ } else {
+ m_bPressedUpOnList = false;
+ }
+
+ pressed = false;
+ if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
+ m_bShowMouse = false;
+ pressed = true;
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
+ m_bShowMouse = true;
+ pressed = true;
+ }
+
+ // Down
+ if (pressed) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedDownOnList) {
+ m_bPressedDownOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ ScrollDownListByOne();
+ }
+ } else {
+ m_bPressedDownOnList = false;
+ }
+
+ if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
+ if (!CPad::GetPad(0)->GetPageUp()) {
+ m_bPressedPgUpOnList = false;
+ } else {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedPgUpOnList) {
+ m_bPressedPgUpOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ PageUpList(false);
}
- else {
+ }
+ if (!CPad::GetPad(0)->GetPageDown()) {
+ m_bPressedPgDnOnList = false;
+ } else {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedPgDnOnList) {
+ m_bPressedPgDnOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ PageDownList(false);
+ }
+ }
+ if (CPad::GetPad(0)->GetHome()) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
+ m_nFirstVisibleRowOnList = 0;
+ }
+ m_nSelectedListRow = 0;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ }
+ if (CPad::GetPad(0)->GetEnd()) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
+ if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
+ m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
+ }
+ m_nSelectedListRow = m_nTotalListRow - 1;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ }
+ }
+
+ if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
+ m_bShowMouse = false;
+ goBack = true;
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_BACK:
+ goBack = true;
+ break;
+ case HOVEROPTION_PAGEUP:
+ PageUpList(true);
+ break;
+ case HOVEROPTION_PAGEDOWN:
+ PageDownList(true);
+ break;
+ case HOVEROPTION_USESKIN:
+ if (m_nSkinsTotal > 0) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- for (int i = 0; i < 4; i++)
- ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i);
- m_bKeyIsOK = false;
- m_bKeyChangeNotProcessed = false;
- pControlEdit = nil;
- m_bWaitingForNewKeyBind = false;
- m_KeyPressedCode = -1;
- m_bStartWaitingForKeyBind = false;
+ m_pSelectedSkin = m_pSkinListHead.nextSkin;
+ strcpy(m_PrefsSkinFile, m_aSkinName);
+ CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+ SaveSettings();
}
}
}
- if (pEditString || pControlEdit)
- return;
+ if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_OVER_SCROLL_UP:
+ m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP;
+ break;
+ case HOVEROPTION_OVER_SCROLL_DOWN:
+ m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN;
+ break;
+ case HOVEROPTION_LIST:
+ m_nHoverOption = HOVEROPTION_SKIN;
+ }
+ } else if ((CPad::GetPad(0)->GetLeftMouseJustUp())
+ && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+
+ if (!CPad::GetPad(0)->GetLeftMouse()) {
+ holdingScrollBar = false;
+ } else {
+ if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) {
+ holdingScrollBar = true;
+ // TODO: This part is a bit hard to reverse. Not much code tho
+ assert(0 && "Holding scrollbar isn't done yet");
+ } else {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_OVER_SCROLL_UP:
+ case HOVEROPTION_CLICKED_SCROLL_UP:
+ if (!m_bPressedScrollButton) {
+ m_bPressedScrollButton = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ ScrollUpListByOne();
+ }
+ break;
+ case HOVEROPTION_OVER_SCROLL_DOWN:
+ case HOVEROPTION_CLICKED_SCROLL_DOWN:
+ if (!m_bPressedScrollButton) {
+ m_bPressedScrollButton = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ ScrollDownListByOne();
+ }
+ break;
+ default:
+ m_bPressedScrollButton = false;
+ }
+ }
+ }
+}
+void
+CMenuManager::UserInput(void)
+{
bool goBack = false;
bool optionSelected = false;
bool goUp = false;
bool goDown = false;
-#ifdef TIDY_UP_PBP
- bool assumeIncrease = false;
-#endif
-
-#ifdef USE_DEBUG_SCRIPT_LOADER
- if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
-#ifdef RW_GL3
- if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
- scriptToLoad = 1;
- DoSettingsBeforeStartingAGame();
- return;
- }
-#elif defined _WIN32
- if (GetAsyncKeyState('R') & 0x8000) {
- scriptToLoad = 1;
- DoSettingsBeforeStartingAGame();
- return;
- }
-#endif
- }
-#endif
+ int8 changeValueBy;
- if (!m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
+ if (!m_AllowNavigation && m_menuTransitionProgress == 255)
+ m_AllowNavigation = true;
+ if (!m_bShowMouse && m_nCurrScreen != MENUPAGE_MAP && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
m_bShowMouse = true;
}
@@ -3745,248 +3815,23 @@ CMenuManager::ProcessButtonPresses(void)
if (m_nMousePosY < 0) m_nMousePosY = 0;
if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT;
- if (m_nCurrScreen == MENUPAGE_SKIN_SELECT || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
-
- if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
- m_nTotalListRow = m_nSkinsTotal;
- }
- if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25;
- if (m_nSelectedListRow > m_nTotalListRow)
- m_nSelectedListRow = m_nTotalListRow - 1;
- }
-
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
- m_bShowMouse = 0;
- optionSelected = true;
- }
- if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_159) {
- if (m_nCurrExLayer == HOVEROPTION_LIST) {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- m_bWaitingForNewKeyBind = true;
- m_bStartWaitingForKeyBind = true;
- m_bKeyChangeNotProcessed = true;
- pControlEdit = &m_KeyPressedCode;
- }
- } else {
- field_159 = false;
- }
-
- static PauseModeTime lastTimeClickedScrollButton = 0;
-
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
- m_bPressedPgUpOnList = false;
- m_bPressedPgDnOnList = false;
- m_bPressedUpOnList = false;
- m_bPressedDownOnList = false;
- m_bPressedScrollButton = false;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- }
-
- if (CPad::GetPad(0)->GetTabJustDown()) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- m_bShowMouse = false;
- switch (m_nCurrExLayer) {
- case HOVEROPTION_BACK:
- default:
- m_nCurrExLayer = HOVEROPTION_LIST;
- break;
- case HOVEROPTION_LIST:
- m_nCurrExLayer = HOVEROPTION_USESKIN;
- break;
- case HOVEROPTION_USESKIN:
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) {
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- }
-
- bool pressed = false;
- if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
- m_bShowMouse = false;
- pressed = true;
- } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) {
- m_bShowMouse = true;
- pressed = true;
- }
-
- // Up
- if (pressed) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedUpOnList) {
- m_bPressedUpOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- ScrollUpListByOne();
- }
- } else {
- m_bPressedUpOnList = false;
- }
-
- pressed = false;
- if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
- m_bShowMouse = false;
- pressed = true;
- } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
- m_bShowMouse = true;
- pressed = true;
- }
-
- // Down
- if (pressed) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedDownOnList) {
- m_bPressedDownOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- ScrollDownListByOne();
- }
- } else {
- m_bPressedDownOnList = false;
- }
-
- if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- if (!CPad::GetPad(0)->GetPageUp()) {
- m_bPressedPgUpOnList = false;
- } else {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedPgUpOnList) {
- m_bPressedPgUpOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- PageUpList(false);
- }
- }
- if (!CPad::GetPad(0)->GetPageDown()) {
- m_bPressedPgDnOnList = false;
- } else {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedPgDnOnList) {
- m_bPressedPgDnOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- PageDownList(false);
- }
- }
- if (CPad::GetPad(0)->GetHome()) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
- m_nFirstVisibleRowOnList = 0;
- }
- m_nSelectedListRow = 0;
- m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
- }
- if (CPad::GetPad(0)->GetEnd()) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
- m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
- }
- m_nSelectedListRow = m_nTotalListRow - 1;
- m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
- }
- }
-
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
- m_bShowMouse = false;
- goBack = true;
- }
-
- if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
- switch (m_nHoverOption) {
- case HOVEROPTION_BACK:
- goBack = true;
- break;
- case HOVEROPTION_PAGEUP:
- PageUpList(true);
- break;
- case HOVEROPTION_PAGEDOWN:
- PageDownList(true);
- break;
- case HOVEROPTION_USESKIN:
- if (m_nSkinsTotal > 0) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_pSelectedSkin = m_pSkinListHead.nextSkin;
- strcpy(m_PrefsSkinFile, m_aSkinName);
- CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
- SaveSettings();
- }
- }
- }
-
- if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
- switch (m_nHoverOption) {
- case HOVEROPTION_OVER_SCROLL_UP:
- m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP;
- break;
- case HOVEROPTION_OVER_SCROLL_DOWN:
- m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN;
- break;
- case HOVEROPTION_LIST:
- m_nHoverOption = HOVEROPTION_SKIN;
- }
- } else if ((CPad::GetPad(0)->GetLeftMouseJustUp())
- && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- }
-
- if (!CPad::GetPad(0)->GetLeftMouse()) {
- holdingScrollBar = false;
- } else {
- if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) {
- holdingScrollBar = true;
- // TODO: This part is a bit hard to reverse. Not much code tho
- assert(0 && "Holding scrollbar isn't done yet");
- } else {
- switch (m_nHoverOption) {
- case HOVEROPTION_OVER_SCROLL_UP:
- case HOVEROPTION_CLICKED_SCROLL_UP:
- if (!m_bPressedScrollButton) {
- m_bPressedScrollButton = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- ScrollUpListByOne();
- }
- break;
- case HOVEROPTION_OVER_SCROLL_DOWN:
- case HOVEROPTION_CLICKED_SCROLL_DOWN:
- if (!m_bPressedScrollButton) {
- m_bPressedScrollButton = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- ScrollDownListByOne();
- }
- break;
- default:
- m_bPressedScrollButton = false;
- }
- }
- }
- } else if (isPlainTextScreen(m_nCurrScreen)) {
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()) {
- optionSelected = true;
- }
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU) {
- goBack = true;
- }
- }
+ changeValueBy = 0;
+ if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS || m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
+ ProcessList(optionSelected, goBack);
} else {
- if (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
+ // TODO(Miami): Seperate that code into a new function from ProcessButtonPresses
+ // ProcessScrollingExceptLists(goBack);
+
+ if (m_AllowNavigation &&
+ (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown())) {
m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
goDown = true;
m_nOptionHighlightTransitionBlend = 0;
- } else if (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
+
+ }
+ else if (m_AllowNavigation &&
+ (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) {
m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
goUp = true;
m_nOptionHighlightTransitionBlend = 0;
}
@@ -3996,25 +3841,23 @@ CMenuManager::ProcessButtonPresses(void)
m_bShowMouse = false;
optionSelected = true;
}
- } else {
+ }
+ else {
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
m_bShowMouse = false;
optionSelected = true;
}
}
- if (CPad::GetPad(0)->GetLeftMouseJustUp()) {
-#ifndef TIDY_UP_PBP
- if (((m_nCurrOption == 0) && (m_nCurrScreen == MENUPAGE_PAUSE_MENU)) &&
-#else
- if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_RESUME &&
-#endif
- (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)) {
+ if (CPad::GetPad(0)->GetLeftMouseJustUp() && m_nCurrScreen != MENUPAGE_MAP) {
+ // TODO(Miami): New radio selector
+ if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM) {
m_nCurrOption = m_nOptionMouseHovering;
optionSelected = true;
}
- } else if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
-#ifdef TIDY_UP_PBP
+ }
+ // TODO(Miami): This part is old radio selector, remove when new is reversed!!
+ else if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
if (m_nHoverOption >= HOVEROPTION_RADIO_0 && m_nHoverOption <= HOVEROPTION_RADIO_9) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
m_PrefsRadioStation = m_nHoverOption - HOVEROPTION_RADIO_0;
@@ -4022,206 +3865,28 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
- } else if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM
- && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) {
- m_nCurrOption = m_nOptionMouseHovering;
- optionSelected = true;
}
-#else
- switch (m_nHoverOption) {
- case HOVEROPTION_RADIO_0:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = HEAD_RADIO;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_1:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = DOUBLE_CLEF;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_2:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = JAH_RADIO;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_3:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = RISE_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_4:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = LIPS_106;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_5:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = GAME_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_6:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = MSX_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_7:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = FLASHBACK;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_8:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = CHATTERBOX;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_9:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = USERTRACK;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RANDOM_ITEM:
- if (((m_nCurrOption != 0) || (m_nCurrScreen != MENUPAGE_PAUSE_MENU)) {
- m_nCurrOption = m_nOptionMouseHovering;
- optionSelected = true;
- }
- break;
- }
-#endif
}
if (CPad::GetPad(0)->GetLeftMouse()) {
-#ifndef TIDY_UP_PBP
switch (m_nHoverOption) {
case HOVEROPTION_INCREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness + 32;
- if (m_PrefsBrightness < 0) {
- m_PrefsBrightness = 0;
- }
- if (510 < m_PrefsBrightness) {
- m_PrefsBrightness = 511;
- }
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness - 32;
- if (m_PrefsBrightness < 0) {
- m_PrefsBrightness = 0;
- }
- if (510 < m_PrefsBrightness) {
- m_PrefsBrightness = 511;
- }
- SaveSettings();
- break;
+ case HOVEROPTION_INCREASE_MP3BOOST:
case HOVEROPTION_INCREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD + (1.0f / 16);
- m_PrefsLOD = min(1.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD - (1.0f / 16);
- m_PrefsLOD = max(0.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume + 8;
- m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume - 8;
- if (m_PrefsMusicVolume < 0) {
- m_PrefsMusicVolume = 0;
- }
- if (126 < m_PrefsMusicVolume) {
- m_PrefsMusicVolume = 127;
- }
- DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume + 8;
- if (m_PrefsSFXVolume < 0) {
- m_PrefsSFXVolume = 0;
- }
- if (126 < m_PrefsSFXVolume) {
- m_PrefsSFXVolume = 127;
- }
- DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume - 8;
- if (m_PrefsSFXVolume < 0) {
- m_PrefsSFXVolume = 0;
- }
- if (126 < m_PrefsSFXVolume) {
- m_PrefsSFXVolume = 127;
- }
- DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl += (1.0f / 3000);
- TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
- SaveSettings();
+ CheckSliderMovement(1);
break;
+ case HOVEROPTION_DECREASE_BRIGHTNESS:
+ case HOVEROPTION_DECREASE_MP3BOOST:
+ case HOVEROPTION_DECREASE_DRAWDIST:
+ case HOVEROPTION_DECREASE_MUSICVOLUME:
+ case HOVEROPTION_DECREASE_SFXVOLUME:
case HOVEROPTION_DECREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl -= (1.0f / 3000);
- TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
- SaveSettings();
+ CheckSliderMovement(-1);
break;
}
-#else
- switch (m_nHoverOption) {
- case HOVEROPTION_INCREASE_BRIGHTNESS:
- case HOVEROPTION_INCREASE_DRAWDIST:
- case HOVEROPTION_INCREASE_MUSICVOLUME:
- case HOVEROPTION_INCREASE_SFXVOLUME:
- case HOVEROPTION_INCREASE_MOUSESENS:
- CheckSliderMovement(1);
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- case HOVEROPTION_DECREASE_DRAWDIST:
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- case HOVEROPTION_DECREASE_SFXVOLUME:
- case HOVEROPTION_DECREASE_MOUSESENS:
- CheckSliderMovement(-1);
- break;
- }
-#endif
}
if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp()
@@ -4229,23 +3894,19 @@ CMenuManager::ProcessButtonPresses(void)
|| CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp()
|| CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ if (option == MENUACTION_BRIGHTNESS)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
- else if (option == MENUACTION_MOUSESENS)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESTEER)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
}
- if (CPad::GetPad(0)->GetBackJustDown()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU) {
- m_bShowMouse = false;
- goBack = true;
- }
- }
-
- if (CPad::GetPad(0)->GetEscapeJustDown()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU) {
+ if (CPad::GetPad(0)->GetBackJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) {
+ if (m_nCurrScreen != MENUPAGE_NONE && m_nCurrScreen != MENUPAGE_PAUSE_MENU && m_nCurrScreen != MENUPAGE_CHOOSE_SAVE_SLOT
+ && m_nCurrScreen != MENUPAGE_SAVE_CHEAT_WARNING && m_nCurrScreen != MENUPAGE_SAVING_IN_PROGRESS
+ && m_nCurrScreen != MENUPAGE_DELETING_IN_PROGRESS && m_nCurrScreen != MENUPAGE_OUTRO)
+ {
m_bShowMouse = false;
goBack = true;
}
@@ -4254,8 +3915,156 @@ CMenuManager::ProcessButtonPresses(void)
if (((goDown) || (goUp)) || (optionSelected)) {
goBack = false;
}
+
+ }
+
+ int curAction = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
+ if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
+ static PauseModeTime lastSliderDecrease = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
+ if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
+ curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
+ curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
+ curAction == MENUACTION_MP3VOLUMEBOOST)
+ changeValueBy = -1;
+
+ lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
+ static PauseModeTime lastSliderIncrease = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
+ if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
+ curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
+ curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
+ curAction == MENUACTION_MP3VOLUMEBOOST)
+ changeValueBy = 1;
+ lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ }
+
+ if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
+ changeValueBy = 1;
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
+ changeValueBy = -1;
+ }
+
+ if (m_AllowNavigation) {
+ if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()) {
+ m_bShowMouse = false;
+ changeValueBy = 1;
+ }
+ }
+
+ if (m_AllowNavigation) {
+ if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()) {
+ m_bShowMouse = false;
+ changeValueBy = -1;
+ }
+ }
+ if (changeValueBy != 0) {
+ if ((m_nCurrScreen == MENUPAGE_SOUND_SETTINGS || m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS || m_nCurrScreen == MENUPAGE_CONTROLLER_PC || m_nCurrScreen == MENUPAGE_MOUSE_CONTROLS)
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_NOTHING
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_LABEL
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_YES
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_NO
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_CHANGEMENU
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_KEYBOARDCTRLS
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_GOBACK
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESTOREDEF
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_DRAWDIST
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_MOUSESENS
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_MP3VOLUMEBOOST) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ }
+ }
+ ProcessButtonPresses(goDown, goUp, optionSelected, goBack, changeValueBy);
+}
+
+// TODO(Miami)
+// Also rename it to ProcessUserInput when it's done
+void
+CMenuManager::ProcessButtonPresses(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount)
+{
+ if (m_nCurrScreen == MENUPAGE_OUTRO)
+ return;
+
+ if (m_bWaitingForNewKeyBind) {
+ if (m_bStartWaitingForKeyBind)
+ m_bStartWaitingForKeyBind = false;
+ else {
+ pControlEdit = CPad::EditCodesForControls(pControlEdit, 1);
+ JoyButtonJustClicked = false;
+ MouseButtonJustClicked = false;
+
+ if (CPad::GetPad(0)->GetLeftMouseJustDown())
+ MouseButtonJustClicked = 1;
+ else if (CPad::GetPad(0)->GetRightMouseJustUp())
+ MouseButtonJustClicked = 3;
+ else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
+ MouseButtonJustClicked = 2;
+ else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
+ MouseButtonJustClicked = 4;
+ else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
+ MouseButtonJustClicked = 5;
+ // TODO two more buttons
+
+ JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
+
+ int32 TypeOfControl = KEYBOARD;
+ if (JoyButtonJustClicked)
+ TypeOfControl = JOYSTICK;
+ if (MouseButtonJustClicked)
+ TypeOfControl = MOUSE;
+ if (*pControlEdit != rsNULL)
+ TypeOfControl = KEYBOARD;
+
+ if (!m_bKeyIsOK) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ pControlEdit = nil;
+ m_bWaitingForNewKeyBind = false;
+ m_KeyPressedCode = -1;
+ m_bStartWaitingForKeyBind = false;
+ }
+ else if (!m_bKeyChangeNotProcessed) {
+ if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked)
+ CheckCodesForControls(TypeOfControl);
+
+ field_159 = true;
+ }
+ else {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ for (int i = 0; i < 4; i++)
+ ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i);
+ m_bKeyIsOK = false;
+ m_bKeyChangeNotProcessed = false;
+ pControlEdit = nil;
+ m_bWaitingForNewKeyBind = false;
+ m_KeyPressedCode = -1;
+ m_bStartWaitingForKeyBind = false;
+ }
+ }
}
+ if (pEditString || pControlEdit)
+ return;
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
+#ifdef RW_GL3
+ if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
+ return;
+ }
+#elif defined _WIN32
+ if (GetAsyncKeyState('R') & 0x8000) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
+ return;
+ }
+#endif
+ }
+#endif
#ifdef PS2_LIKE_MENU
if (CPad::GetPad(0)->GetLeftMouseJustDown() && hoveredBottomBarOption != -1) {
@@ -4296,11 +4105,14 @@ CMenuManager::ProcessButtonPresses(void)
}
#endif
+ int oldOption = m_nCurrOption;
if (goDown) {
m_nCurrOption++;
if (m_nCurrOption == NUM_MENUROWS || (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NOTHING)) {
m_nCurrOption = 0;
}
+ if (oldOption != m_nCurrOption)
+ m_nOptionHighlightTransitionBlend = 0;
}
if (goUp) {
if (m_nCurrOption == (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL)) {
@@ -4311,6 +4123,8 @@ CMenuManager::ProcessButtonPresses(void)
} else {
m_nCurrOption--;
}
+ if (oldOption != m_nCurrOption)
+ m_nOptionHighlightTransitionBlend = 0;
}
if (optionSelected) {
@@ -4321,10 +4135,10 @@ CMenuManager::ProcessButtonPresses(void)
strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FESZ_CA", 8) != 0) {
if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) {
- if (Slots[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot - 1] == SLOT_EMPTY)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ if (Slots[m_nCurrOption] != SLOT_OK)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_BACK, 0);
else
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
} else
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
} else {
@@ -4399,21 +4213,17 @@ CMenuManager::ProcessButtonPresses(void)
option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
switch (option) {
case MENUACTION_RADIO:
-#ifdef TIDY_UP_PBP
- assumeIncrease = true;
-#else
++m_PrefsRadioStation;
if (DMAudio.IsMP3RadioChannelAvailable()) {
if (m_PrefsRadioStation > USERTRACK)
- m_PrefsRadioStation = HEAD_RADIO;
- } else if (m_PrefsRadioStation > CHATTERBOX) {
+ m_PrefsRadioStation = WILDSTYLE;
+ } else if (m_PrefsRadioStation > WAVE) {
m_PrefsRadioStation = USERTRACK;
}
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
-#endif
break;
case MENUACTION_LANG_ENG:
m_PrefsLanguage = LANGUAGE_AMERICAN;
@@ -4471,7 +4281,7 @@ CMenuManager::ProcessButtonPresses(void)
if (saveSlot >= 2 && saveSlot <= 9) {
m_nCurrSaveSlot = saveSlot - 2;
- if (Slots[m_nCurrSaveSlot + 1] != SLOT_EMPTY && Slots[m_nCurrSaveSlot + 1] != SLOT_CORRUPTED) {
+ if (Slots[m_nCurrSaveSlot] != SLOT_EMPTY && Slots[m_nCurrSaveSlot] != SLOT_CORRUPTED) {
if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) {
SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM);
} else if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) {
@@ -4531,7 +4341,7 @@ CMenuManager::ProcessButtonPresses(void)
}
break;
#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENMODE:
+ case MENUACTION_SCREENFORMAT:
if (m_nSelectedScreenMode != m_nPrefsWindowed) {
m_nPrefsWindowed = m_nSelectedScreenMode;
_psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution
@@ -4554,16 +4364,12 @@ CMenuManager::ProcessButtonPresses(void)
break;
}
case MENUACTION_SPEAKERCONF:
-#ifndef TIDY_UP_PBP
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
if (--m_PrefsSpeakers < 0)
m_PrefsSpeakers = 2;
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
SaveSettings();
}
-#else
- assumeIncrease = true;
-#endif
break;
case MENUACTION_PLAYERSETUP:
CPlayerSkin::BeginFrontendSkinEdit();
@@ -4587,7 +4393,7 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
SaveSettings();
- } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
+ } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_PrefsBrightness = 256;
m_PrefsLOD = 1.2f;
#ifdef LEGACY_MENU_OPTIONS
@@ -4633,7 +4439,6 @@ CMenuManager::ProcessButtonPresses(void)
SetHelperText(2);
break;
case MENUACTION_CTRLMETHOD:
-#ifndef TIDY_UP_PBP
if (m_ControlMethod == CONTROL_CLASSIC) {
CCamera::m_bUseMouse3rdPerson = true;
m_ControlMethod = CONTROL_STANDARD;
@@ -4642,9 +4447,6 @@ CMenuManager::ProcessButtonPresses(void)
m_ControlMethod = CONTROL_CLASSIC;
}
SaveSettings();
-#else
- assumeIncrease = true;
-#endif
break;
case MENUACTION_LOADRADIO:
SwitchToNewScreen(MENUPAGE_SOUND_SETTINGS);
@@ -4661,33 +4463,6 @@ CMenuManager::ProcessButtonPresses(void)
}
break;
}
-#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_TRIGGERFUNC:
- FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu];
- if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) {
- if (option.type == FEOPTION_SELECT) {
- if (!option.onlyApplyOnEnter) {
- option.displayedValue++;
- if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0)
- option.displayedValue = 0;
- }
- option.changeFunc(option.displayedValue);
- *option.value = option.displayedValue;
-
- } else if (option.type == FEOPTION_DYNAMIC) {
- option.buttonPressFunc(FEOPTION_ACTION_SELECT);
- } else if (option.type == FEOPTION_REDIRECT) {
- ChangeScreen(option.to, option.option, true, option.fadeIn);
- } else if (option.type == FEOPTION_GOBACK) {
- goBack = true;
- }
- } else {
- debug("B- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder);
- assert(0 && "Custom frontend options are borked");
- }
-
- break;
-#endif
}
}
ProcessOnOffMenuOptions();
@@ -4760,58 +4535,11 @@ CMenuManager::ProcessButtonPresses(void)
return;
#endif
- int changeValueBy = 0;
- bool decrease = false;
-#ifdef TIDY_UP_PBP
- bool increase = assumeIncrease;
-#else
- bool increase = false;
-#endif
- if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
- static PauseModeTime lastSliderDecrease = 0;
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
- CheckSliderMovement(-1);
- lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
- }
- } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
- static PauseModeTime lastSliderIncrease = 0;
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
- CheckSliderMovement(1);
- lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
- }
- }
-
- if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()) {
- m_bShowMouse = false;
- increase = true;
- } else if (CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- increase = true;
- CheckSliderMovement(1);
- m_bShowMouse = true;
- }
-
- if (!CPad::GetPad(0)->GetLeftJustDown() && !CPad::GetPad(0)->GetAnaloguePadLeft() && !CPad::GetPad(0)->GetDPadLeftJustDown()) {
- if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
- if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- decrease = true;
- CheckSliderMovement(-1);
- m_bShowMouse = true;
- }
- }
- } else {
- m_bShowMouse = false;
- decrease = true;
- }
- if (increase)
- changeValueBy++;
- else if (decrease)
- changeValueBy--;
-
- if (changeValueBy != 0) {
+ if (changeAmount != 0) {
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_RADIO:
- m_PrefsRadioStation += changeValueBy;
+ m_PrefsRadioStation += changeAmount;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
if (DMAudio.IsMP3RadioChannelAvailable()) {
if (m_PrefsRadioStation < WILDSTYLE)
@@ -4831,7 +4559,7 @@ CMenuManager::ProcessButtonPresses(void)
break;
#ifdef ASPECT_RATIO_SCALE
case MENUACTION_WIDESCREEN:
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
m_PrefsUseWideScreen++;
if (m_PrefsUseWideScreen > 2)
m_PrefsUseWideScreen = 0;
@@ -4848,7 +4576,7 @@ CMenuManager::ProcessButtonPresses(void)
if (m_bGameNotLoaded) {
RwChar** videoMods = _psGetVideoModeList();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
do {
++m_nDisplayVideoMode;
@@ -4866,21 +4594,21 @@ CMenuManager::ProcessButtonPresses(void)
}
break;
#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENMODE:
+ case MENUACTION_SCREENFORMAT:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
m_nSelectedScreenMode = !m_nSelectedScreenMode;
break;
#endif
case MENUACTION_AUDIOHW:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
- m_nPrefsAudio3DProviderIndex += changeValueBy;
+ m_nPrefsAudio3DProviderIndex += changeAmount;
m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1);
}
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
break;
case MENUACTION_SPEAKERCONF:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
- m_PrefsSpeakers -= changeValueBy;
+ m_PrefsSpeakers -= changeAmount;
m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2);
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
SaveSettings();
@@ -4893,45 +4621,15 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
-#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_TRIGGERFUNC:
- FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu];
- if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) {
- if (option.type == FEOPTION_SELECT) {
- if (changeValueBy > 0) {
- option.displayedValue++;
- if (option.displayedValue >= option.numRightTexts)
- option.displayedValue = 0;
- } else {
- option.displayedValue--;
- if (option.displayedValue < 0)
- option.displayedValue = option.numRightTexts - 1;
- }
- if (!option.onlyApplyOnEnter) {
- option.changeFunc(option.displayedValue);
- *option.value = option.displayedValue;
- }
- } else if (option.type == FEOPTION_DYNAMIC) {
- option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT);
- }
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- }
- else {
- debug("C- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder);
- assert(0 && "Custom frontend options are borked");
- }
-
- break;
-#endif
}
+ CheckSliderMovement(changeAmount);
ProcessOnOffMenuOptions();
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- if (changeValueBy < 1) {
+ if (changeAmount < 1) {
m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
} else {
m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
}
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
}
}
}
@@ -5226,9 +4924,13 @@ CMenuManager::SwitchMenuOnAndOff()
Initialise();
LoadAllTextures();
- // TODO(Miami): Cheat warning
- m_nCurrScreen = MENUPAGE_CHOOSE_SAVE_SLOT;
- m_nCurrOption = 8;
+ if (CPad::bHasPlayerCheated) {
+ m_nCurrScreen = MENUPAGE_SAVE_CHEAT_WARNING;
+ m_nCurrOption = 0;
+ } else {
+ m_nCurrScreen = MENUPAGE_CHOOSE_SAVE_SLOT;
+ m_nCurrOption = 8;
+ }
}
m_bStartUpFrontEndRequested = false;
@@ -5262,7 +4964,7 @@ CMenuManager::UnloadTextures()
m_bSpritesLoaded = false;
}
m_OnlySaveMenu = false;
- // TODO(Miami): Place name thing
+ CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown();
}
void
@@ -5565,27 +5267,6 @@ CMenuManager::ConstructStatLine(int rowIdx)
STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil);
STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil);
STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil);
- STAT_LINE("ACCURA", &(nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 :
- CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)), false, nil);
-
- if (CStats::ElBurroTime > 0) {
- STAT_LINE("ELBURRO", &CStats::ElBurroTime, false, nil);
- }
- if (CStats::Record4x4One > 0) {
- STAT_LINE("FEST_R1", &CStats::Record4x4One, false, nil);
- }
- if (CStats::Record4x4Two > 0) {
- STAT_LINE("FEST_R2", &CStats::Record4x4Two, false, nil);
- }
- if (CStats::Record4x4Three > 0) {
- STAT_LINE("FEST_R3", &CStats::Record4x4Three, false, nil);
- }
- if (CStats::Record4x4Mayhem > 0) {
- STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, false, nil);
- }
- if (CStats::TimeTakenDefuseMission > 0) {
- STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, false, nil);
- }
if (CStats::HighestScores[0] > 0) {
STAT_LINE("FEST_BB", nil, false, nil);
@@ -5612,7 +5293,11 @@ CMenuManager::ConstructStatLine(int rowIdx)
#ifndef USE_MEASUREMENTS_IN_METERS
float fTemp;
STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil);
- STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledInVehicle * MILES_IN_METER), true, nil);
+ STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledByCar * MILES_IN_METER), true, nil);
+ STAT_LINE("DISTBIK", &(fTemp = CStats::DistanceTravelledByBike * MILES_IN_METER), true, nil);
+ STAT_LINE("DISTBOA", &(fTemp = CStats::DistanceTravelledByBoat * MILES_IN_METER), true, nil);
+ STAT_LINE("DISTGOL", &(fTemp = CStats::DistanceTravelledByGolfCart * MILES_IN_METER), true, nil);
+ STAT_LINE("DISTHEL", &(fTemp = CStats::DistanceTravelledByHelicoptor * MILES_IN_METER), true, nil);
STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil);
STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil);
break;
@@ -5627,7 +5312,11 @@ CMenuManager::ConstructStatLine(int rowIdx)
case LANGUAGE_JAPANESE:
#endif
STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil);
- STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, true, nil);
+ STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, true, nil);
+ STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, true, nil);
+ STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, true, nil);
+ STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, true, nil);
+ STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, true, nil);
STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil);
STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil);
break;
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 83d86d5b..858ad1f3 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -160,7 +160,7 @@ enum eMenuScreen
MENUPAGE_NEW_GAME = 1,
MENUPAGE_BRIEFS = 2,
MENUPAGE_SOUND_SETTINGS = 3,
- MENUPAGE_GRAPHICS_SETTINGS = 4,
+ MENUPAGE_DISPLAY_SETTINGS = 4,
MENUPAGE_LANGUAGE_SETTINGS = 5,
MENUPAGE_MAP = 6,
MENUPAGE_NEW_GAME_RELOAD = 7,
@@ -200,6 +200,9 @@ enum eMenuScreen
MENUPAGE_CONTROLLER_PC_OLD4,
MENUPAGE_CONTROLLER_DEBUG,
#endif
+#ifdef GRAPHICS_MENU_OPTIONS
+ MENUPAGE_GRAPHICS_SETTINGS,
+#endif
MENUPAGES
};
@@ -266,12 +269,28 @@ enum eMenuAction
MENUACTION_MOUSESTEER,
MENUACTION_UNK110,
#ifdef IMPROVED_VIDEOMODE
- MENUACTION_SCREENMODE,
+ MENUACTION_SCREENFORMAT,
#endif
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
#endif
+#ifdef ANISOTROPIC_FILTERING
+ MENUACTION_MIPMAPS,
+ MENUACTION_TEXTURE_FILTERING,
+#endif
+#ifdef MULTISAMPLING
+ MENUACTION_MULTISAMPLING,
+#endif
+#ifdef NO_ISLAND_LOADING
+ MENUACTION_ISLANDLOADING,
+#endif
+#ifdef PS2_ALPHA_TEST
+ MENUACTION_PS2_ALPHA_TEST,
+#endif
+#ifdef CUTSCENE_BORDERS_SWITCH
+ MENUACTION_CUTSCENEBORDERS,
+#endif
};
enum eCheckHover
@@ -318,6 +337,8 @@ enum eCheckHover
HOVEROPTION_DECREASE_SFXVOLUME,
HOVEROPTION_INCREASE_MOUSESENS,
HOVEROPTION_DECREASE_MOUSESENS,
+ HOVEROPTION_INCREASE_MP3BOOST,
+ HOVEROPTION_DECREASE_MP3BOOST,
HOVEROPTION_NOT_HOVERING,
};
@@ -574,6 +595,10 @@ public:
int32 m_nPrefsSubsystem;
int32 m_nSelectedScreenMode;
#endif
+#ifdef MULTISAMPLING
+ static int8 m_nPrefsMSAALevel;
+ static int8 m_nDisplayMSAALevel;
+#endif
enum LANGUAGE
{
@@ -601,7 +626,25 @@ public:
CMenuManager(void);
~CMenuManager(void) { UnloadTextures(); }
-
+
+#ifdef NO_ISLAND_LOADING
+ enum
+ {
+ ISLAND_LOADING_LOW = 0,
+ ISLAND_LOADING_MEDIUM,
+ ISLAND_LOADING_HIGH
+ };
+
+ static int8 m_DisplayIslandLoading;
+ static int8 m_PrefsIslandLoading;
+
+ #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
+ #define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
+#else
+ #define ISLAND_LOADING_IS(p)
+ #define ISLAND_LOADING_ISNT(p)
+#endif
+
void Initialise();
void PrintMap();
void SetFrontEndRenderStates();
@@ -633,7 +676,9 @@ public:
static void PrintErrorMessage();
void PrintStats();
void Process();
- void ProcessButtonPresses();
+ void ProcessList(bool &optionSelected, bool &goBack);
+ void UserInput();
+ void ProcessButtonPresses(uint8, uint8, uint8, uint8, int8);
void ProcessFileActions();
void ProcessOnOffMenuOptions();
void RequestFrontEndShutDown();
diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp
index 8e604978..d9eff445 100644
--- a/src/core/Frontend_PS2.cpp
+++ b/src/core/Frontend_PS2.cpp
@@ -1179,30 +1179,9 @@ CMenuManager::InitialiseMenuContents(void)
STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, 0, nil);
- nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 : CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer);
- STAT_LINE("ACCURA", &nTemp, 0, nil);
-
- if (CStats::ElBurroTime > 0)
- STAT_LINE("ELBURRO", &CStats::ElBurroTime, 0, nil);
-
- if (CStats::Record4x4One > 0)
- STAT_LINE("FEST_R1", &CStats::Record4x4One, 0, nil);
-
- if (CStats::Record4x4Two > 0)
- STAT_LINE("FEST_R2", &CStats::Record4x4Two, 0, nil);
-
- if (CStats::Record4x4Three > 0)
- STAT_LINE("FEST_R3", &CStats::Record4x4Three, 0, nil);
-
- if (CStats::Record4x4Mayhem > 0)
- STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, 0, nil);
-
if (CStats::LongestFlightInDodo > 0)
STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, 0, nil);
- if (CStats::TimeTakenDefuseMission > 0)
- STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, 0, nil);
-
STAT_LINE("CAR_CRU", &CStats::CarsCrushed, 0, nil);
if (CStats::HighestScores[0] > 0)
@@ -1231,7 +1210,11 @@ CMenuManager::InitialiseMenuContents(void)
STAT_LINE("FEST_H4", &CStats::HighestScores[4], 0, nil);
STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, 0, nil);
- STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, 0, nil);
+ STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, 0, nil);
+ STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, 0, nil);
+ STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, 0, nil);
+ STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, 0, nil);
+ STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, 0, nil);
STAT_LINE("MMRAIN", &CStats::mmRain, 0, nil);
nTemp = (int32)CStats::MaximumJumpDistance;
STAT_LINE("MXCARDM", &nTemp, 0, nil);
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 6825c247..ee3c32b1 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,6 +89,9 @@
#include "Occlusion.h"
#include "debugmenu.h"
#include "Ropes.h"
+#include "WindModifiers.h"
+#include "postfx.h"
+#include "custompipes.h"
eLevelName CGame::currLevel;
int32 CGame::currArea;
@@ -151,6 +154,9 @@ CGame::InitialiseOnceBeforeRW(void)
CFileMgr::Initialise();
CdStreamInit(MAX_CDCHANNELS);
ValidateVersion();
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::InitOnce();
+#endif
return true;
}
@@ -288,10 +294,6 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
CWorld::Players[0].SetPlayerSkin(FrontEndMenuManager.m_PrefsSkinFile);
-
-#ifdef CUSTOM_FRONTEND_OPTIONS
- CustomFrontendOptionsPopulate();
-#endif
return true;
}
@@ -327,6 +329,7 @@ bool CGame::Initialise(const char* datFile)
CDebug::DebugInitTextBuffer();
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
+ CScriptPaths::Init();
CWeather::Init();
CCullZones::Init();
COcclusion::Init();
@@ -355,6 +358,10 @@ bool CGame::Initialise(const char* datFile)
CdStreamAddImage("MODELS\\GTA3.IMG");
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
+#ifdef EXTENDED_PIPELINES
+ // for generic fallback
+ CustomPipes::SetTxdFindCallback();
+#endif
CWorld::AddParticles();
CVehicleModelInfo::LoadVehicleColours();
CVehicleModelInfo::LoadEnvironmentMaps();
@@ -453,6 +460,7 @@ bool CGame::ShutDown(void)
CReplay::FinishPlayback();
CPlane::Shutdown();
CTrain::Shutdown();
+ CScriptPaths::Shutdown();
CSpecialFX::Shutdown();
#ifndef PS2
CGarages::Shutdown();
@@ -567,6 +575,7 @@ void CGame::ReInitGameObjectVariables(void)
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
+ CScriptPaths::Init();
CParticle::ReloadConfig();
#ifdef PS2_MENU
@@ -607,10 +616,7 @@ void CGame::ShutDownForRestart(void)
CWorld::ClearForRestart();
CGameLogic::ClearShortCut();
CTimer::Shutdown();
- CStreaming::FlushRequestList();
- CStreaming::DeleteAllRwObjects();
- CStreaming::RemoveAllUnusedModels();
- CStreaming::ms_disableStreaming = false;
+ CStreaming::ReInit();
CRadar::RemoveRadarSections();
FrontEndMenuManager.UnloadTextures();
CParticleObject::RemoveAllExpireableParticleObjects();
@@ -695,6 +701,7 @@ void CGame::Process(void)
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
CStreaming::Update();
+ CWindModifiers::Number = 0;
if (!CTimer::GetIsPaused())
{
CTheZones::Update();
@@ -708,6 +715,7 @@ void CGame::Process(void)
CWeather::Update();
CTheScripts::Process();
CCollision::Update();
+ CScriptPaths::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();
diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp
index 6fbf597b..65c265ed 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -2,7 +2,43 @@
#include "Frontend.h"
#ifdef PC_MENU
-// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp.
+#ifdef CUTSCENE_BORDERS_SWITCH
+#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen,
+#else
+#define MENU_CUTSCENE_BORDERS_SWITCH(screen)
+#endif
+
+#ifdef IMPROVED_VIDEOMODE
+#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen,
+#else
+#define MENU_IMPROVED_VIDEOMODE(screen)
+#endif
+
+#ifdef ANISOTROPIC_FILTERING
+#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen,
+#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen,
+#else
+#define MENU_MIPMAPS(screen)
+#define MENU_TEXTURE_FILTERING(screen)
+#endif
+
+#ifdef MULTISAMPLING
+#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen,
+#else
+#define MENU_MULTISAMPLING(screen)
+#endif
+
+#ifdef NO_ISLAND_LOADING
+#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen,
+#else
+#define MENU_ISLAND_LOADING(screen)
+#endif
+
+#ifdef PS2_ALPHA_TEST
+#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen,
+#else
+#define MENU_PS2_ALPHA_TEST(screen)
+#endif
CMenuScreen aScreens[] = {
// MENUPAGE_STATS = 0
@@ -44,24 +80,24 @@ CMenuScreen aScreens[] = {
#endif
{ "FEH_DIS", MENUPAGE_OPTIONS, 2,
- MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 78, MENUALIGN_LEFT,
- MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 103, MENUALIGN_LEFT,
+ MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 78, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 103, MENUALIGN_LEFT,
#ifdef LEGACY_MENU_OPTIONS
- MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 128, MENUALIGN_LEFT,
+ MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 128, MENUALIGN_LEFT,
#endif
- MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 128 + Y_OFFSET/2, MENUALIGN_LEFT,
+ MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 128 + Y_OFFSET/2, MENUALIGN_LEFT,
#ifdef LEGACY_MENU_OPTIONS
- MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 178, MENUALIGN_LEFT,
+ MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 178, MENUALIGN_LEFT,
#endif
- MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 153 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 178 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_LEGENDS, "MAP_LEG", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 202 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 153 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 178 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_LEGENDS, "MAP_LEG", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 202 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT,
#ifdef IMPROVED_VIDEOMODE
- MENUACTION_SCREENMODE, "FED_POS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
+ MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER,
#else
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER,
@@ -230,7 +266,7 @@ CMenuScreen aScreens[] = {
{ "FET_OPT", MENUPAGE_NONE, 5,
MENUACTION_CHANGEMENU, "FEO_CON", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 132, MENUALIGN_CENTER,
MENUACTION_LOADRADIO, "FEO_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_CENTER,
- MENUACTION_CHANGEMENU, "FEO_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEO_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEO_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
MENUACTION_PLAYERSETUP, "FET_PS", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, 0, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER,
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index c1016bdd..42b26c63 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -11,7 +11,11 @@
#include "platform.h"
#ifdef XINPUT
#include <xinput.h>
+#if !defined(PSAPI_VERSION) || (PSAPI_VERSION > 1)
#pragma comment( lib, "Xinput9_1_0.lib" )
+#else
+#pragma comment( lib, "Xinput.lib" )
+#endif
#endif
#include "Pad.h"
@@ -41,6 +45,8 @@
#include "Fluff.h"
#include "Gangs.h"
#include "platform.h"
+#include "Stats.h"
+#include "CarCtrl.h"
#ifdef GTA_PS2
#include "eetypes.h"
@@ -59,6 +65,7 @@ bool CPad::bDisplayNoControllerMessage;
bool CPad::bObsoleteControllerMessage;
bool CPad::bOldDisplayNoControllerMessage;
bool CPad::m_bMapPadOneToPadTwo;
+bool CPad::bHasPlayerCheated;
#ifdef GTA_PS2
unsigned char act_direct[6];
unsigned char act_align[6];
@@ -228,6 +235,8 @@ void VehicleCheat(bool something, int model)
CWorld::Add(vehicle);
}
}
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void BlowUpCarsCheat()
@@ -287,6 +296,8 @@ void MayhemCheat()
PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void EverybodyAttacksPlayerCheat()
@@ -294,12 +305,17 @@ void EverybodyAttacksPlayerCheat()
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::AddThreat(i, PED_FLAG_PLAYER1);
+
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void WeaponsForAllCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void FastTimeCheat()
@@ -380,19 +396,24 @@ void OnlyRenderWheelsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
-
void ChittyChittyBangBangCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void StrongGripCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bCheat3 = !CVehicle::bCheat3;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void NastyLimbsCheat()
@@ -404,6 +425,7 @@ void FannyMagnetCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPed::bFannyMagnetCheat = !CPed::bFannyMagnetCheat;
+ CPad::bHasPlayerCheated = true;
}
void BlackCarsCheat()
@@ -420,6 +442,12 @@ void PinkCarsCheat()
gbPinkCars = true;
}
+void MadCarsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CCarCtrl::bMadDriversCheat = true;
+}
+
void NoSeaBedCheat(void)
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
@@ -437,6 +465,7 @@ void BackToTheFuture(void)
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bHoverCheat = !CVehicle::bHoverCheat;
+ CPad::bHasPlayerCheated = true;
}
void SuicideCheat(void) {
@@ -453,6 +482,8 @@ void DoChicksWithGunsCheat(void) {
CStreaming::RemoveCurrentZonesModels();
CGangs::SetGangPedModels(GANG_PLAYER, MI_HFYBE, MI_WFYBE);
CGangs::SetGangWeapons(GANG_PLAYER, WEAPONTYPE_M4, WEAPONTYPE_M4);
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
//////////////////////////////////////////////////////////////////////////
@@ -611,6 +642,11 @@ void CPad::Clear(bool bResetPlayerControls)
ShakeFreq = 0;
ShakeDur = 0;
+ for (int32 i = 0; i < DRUNK_STEERING_BUFFER_SIZE; i++)
+ SteeringLeftRightBuffer[i] = 0;
+
+ DrunkDrivingBufferUsed = 0;
+
if ( bResetPlayerControls )
DisablePlayerControls = PLAYERCONTROL_ENABLED;
@@ -1203,6 +1239,7 @@ void CPad::AddToPCCheatString(char c)
// "MIAMITRAFFIC"
else if (!Cheat_strncmp(KeyBoardCheatString, "FNMGNmWPNLVU")) {
KeyBoardCheatString[0] = ' ';
+ MadCarsCheat();
}
// "AHAIRDRESSERSCAR"
else if (!Cheat_strncmp(KeyBoardCheatString, "UFJT_`VZF]QZPaUG")) {
@@ -1786,6 +1823,9 @@ void CPad::Update(int16 pad)
bHornHistory[iCurrHornHistory] = GetHorn();
+ for (int32 i = DRUNK_STEERING_BUFFER_SIZE - 2; i >= 0; i--) {
+ SteeringLeftRightBuffer[i + 1] = SteeringLeftRightBuffer[i];
+ }
if ( !bDisplayNoControllerMessage )
CGame::bDemoMode = false;
@@ -1879,6 +1919,7 @@ int16 CPad::GetSteeringLeftRight(void)
if ( ArePlayerControlsDisabled() )
return 0;
+ int16 value;
switch (CURMODE)
{
case 0:
@@ -1888,9 +1929,12 @@ int16 CPad::GetSteeringLeftRight(void)
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
if ( Abs(axis) > Abs(dpad) )
- return axis;
+ value = axis;
else
- return dpad;
+ value = dpad;
+
+ SteeringLeftRightBuffer[0] = value;
+ value = SteeringLeftRightBuffer[DrunkDrivingBufferUsed];
break;
}
@@ -1898,13 +1942,18 @@ int16 CPad::GetSteeringLeftRight(void)
case 1:
case 3:
{
- return NewState.LeftStickX;
-
+ SteeringLeftRightBuffer[0] = NewState.LeftStickX;
+ value = SteeringLeftRightBuffer[DrunkDrivingBufferUsed];
+ break;
+ }
+ default:
+ {
+ value = 0;
break;
}
}
- return 0;
+ return value;
}
int16 CPad::GetSteeringUpDown(void)
@@ -3067,7 +3116,7 @@ void CPad::ResetCheats(void)
CVehicle::bCheat8 = false;
gbBlackCars = false;
gbPinkCars = false;
-
+ CCarCtrl::bMadDriversCheat = false;
gbFastTime = false;
CTimer::SetTimeScale(1.0f);
}
diff --git a/src/core/Pad.h b/src/core/Pad.h
index 2a0bb7d3..72851317 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -141,9 +141,12 @@ public:
enum
{
HORNHISTORY_SIZE = 5,
+ DRUNK_STEERING_BUFFER_SIZE = 10,
};
CControllerState NewState;
CControllerState OldState;
+ int16 SteeringLeftRightBuffer[DRUNK_STEERING_BUFFER_SIZE];
+ int32 DrunkDrivingBufferUsed;
CControllerState PCTempKeyState;
CControllerState PCTempJoyState;
CControllerState PCTempMouseState;
@@ -171,6 +174,7 @@ public:
static bool bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
static bool m_bMapPadOneToPadTwo;
+ static bool bHasPlayerCheated;
static CKeyboardState OldKeyState;
static CKeyboardState NewKeyState;
@@ -262,6 +266,7 @@ public:
static char *EditString(char *pStr, int32 nSize);
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
uint32 InputHowLongAgo(void);
+ void SetDrunkInputDelay(int32 delay) { DrunkDrivingBufferUsed = delay; }
#ifdef XINPUT
void AffectFromXinput(uint32 pad);
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 3c01a176..61e2f67a 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -30,7 +30,13 @@
#include "World.h"
#include "ZoneCull.h"
#include "main.h"
+#include "Bike.h"
+#include "Automobile.h"
+#include "GameLogic.h"
+
+CVector lastPlayerPos;
+// --MIAMI: Done
void
CPlayerInfo::SetPlayerSkin(char *skin)
{
@@ -38,6 +44,7 @@ CPlayerInfo::SetPlayerSkin(char *skin)
LoadPlayerSkin();
}
+// --MIAMI: Done
const CVector &
CPlayerInfo::GetPos()
{
@@ -50,16 +57,16 @@ CPlayerInfo::GetPos()
return m_pPed->GetPosition();
}
+// --MIAMI: Done
void
CPlayerInfo::LoadPlayerSkin()
{
DeletePlayerSkin();
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
- if (!m_pSkinTexture)
- m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
}
+// --MIAMI: Done
void
CPlayerInfo::DeletePlayerSkin()
{
@@ -69,6 +76,7 @@ CPlayerInfo::DeletePlayerSkin()
}
}
+// --MIAMI: Done
void
CPlayerInfo::KillPlayer()
{
@@ -81,6 +89,7 @@ CPlayerInfo::KillPlayer()
CStats::TimesDied++;
}
+// --MIAMI: Done
void
CPlayerInfo::ArrestPlayer()
{
@@ -88,11 +97,13 @@ CPlayerInfo::ArrestPlayer()
m_WBState = WBSTATE_BUSTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
+ m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
CStats::TimesArrested++;
}
+// --MIAMI: Done
bool
CPlayerInfo::IsPlayerInRemoteMode()
{
@@ -109,6 +120,7 @@ CPlayerInfo::PlayerFailedCriticalMission()
CDarkel::ResetOnPlayerDeath();
}
+// --MIAMI: Done
void
CPlayerInfo::Clear(void)
{
@@ -125,6 +137,8 @@ CPlayerInfo::Clear(void)
m_nTrafficMultiplier = 0;
m_fRoadDensity = 1.0f;
m_bInRemoteMode = false;
+ field_D5 = false;
+ field_D6 = false;
m_bUnusedTaxiThing = false;
m_nUnusedTaxiTimer = 0;
m_nCollectedPackages = 0;
@@ -136,10 +150,25 @@ CPlayerInfo::Clear(void)
m_nSexFrequency = 0;
m_pHooker = nil;
m_nTimeTankShotGun = 0;
- field_248 = 0;
+ field_EC = 0;
m_nUpsideDownCounter = 0;
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0.0f;
+ m_nTimeSpentOnStoppie = 0;
+ m_nDistanceTravelledOnStoppie = 0.0f;
+ m_nCancelWheelStuntTimer = 0;
+ m_nLastTimeCarSpentOnTwoWheels = 0;
+ m_nLastDistanceCarTravelledOnTwoWheels = 0;
+ m_nLastTimeSpentOnWheelie = 0;
+ m_nLastDistanceTravelledOnWheelie = 0;
+ m_nLastTimeSpentOnStoppie = 0;
+ m_nLastDistanceTravelledOnStoppie = 0;
m_bInfiniteSprint = false;
m_bFastReload = false;
+ m_bFireproof = false;
m_nMaxHealth = m_nMaxArmour = 100;
m_bGetOutOfJailFree = false;
m_bGetOutOfHospitalFree = false;
@@ -147,22 +176,24 @@ CPlayerInfo::Clear(void)
m_nPreviousTimeRewardedForExplosion = 0;
m_nExplosionsSinceLastReward = 0;
m_nHavocLevel = 0;
- m_fMediaAttention = 0;
+ m_fMediaAttention = 0.0f;
m_nCurrentBustedAudio = 1;
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
}
+// --MIAMI: Done
void
CPlayerInfo::BlowUpRCBuggy(bool actually)
{
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
return;
- CRemote::TakeRemoteControlledCarFromPlayer();
+ CRemote::TakeRemoteControlledCarFromPlayer(actually);
if (actually)
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
}
+// --MIAMI: Done
void
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
{
@@ -174,6 +205,7 @@ CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
m_pPed->ClearObjective();
}
+// --MIAMI: Done
void
CPlayerInfo::MakePlayerSafe(bool toggle)
{
@@ -198,8 +230,7 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
CReplay::DisableReplays();
- }
- else {
+ } else {
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
m_pPed->bBulletProof = false;
@@ -214,18 +245,21 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
}
}
+// --MIAMI: Done
bool
CPlayerInfo::IsRestartingAfterDeath()
{
return m_WBState == WBSTATE_WASTED;
}
+// --MIAMI: Done
bool
CPlayerInfo::IsRestartingAfterArrest()
{
return m_WBState == WBSTATE_BUSTED;
}
+// --MIAMI: Done
// lastCloseness is passed to other calls of this function
void
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
@@ -250,32 +284,7 @@ CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoun
}
}
-// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
-void
-CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
-{
- if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
- ++m_nExplosionsSinceLastReward;
- else
- m_nExplosionsSinceLastReward = 1;
-
- m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
- int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
- sprintf(gString, "$%d", award);
-#ifdef MONEY_MESSAGES
- // This line is a leftover from PS2, I don't know what it was meant to be.
- // CVector sth(TheCamera.GetPosition() * 4.0f);
-
- CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
-#endif
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
-
- for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
- CGeneral::GetRandomNumber();
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
- }
-}
-
+// --MIAMI: Done
void
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
{
@@ -293,12 +302,19 @@ CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio);
#undef CopyToBuf
}
+// --MIAMI: Done
void
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
{
@@ -313,12 +329,19 @@ CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName)
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio)
#undef CopyFromBuf
}
+// --MIAMI: Done
void
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
{
@@ -333,7 +356,7 @@ CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1,
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
CVector carCentre = car->GetBoundCentre();
- if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
+ if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) {
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
@@ -367,6 +390,157 @@ CPlayerInfo::Process(void)
if (startTaxiTimer)
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
+ if (!m_pPed->InVehicle()) {
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ } else if (m_pPed->m_pMyVehicle->IsCar()) {
+ CAutomobile *car = (CAutomobile*)m_pPed->m_pMyVehicle;
+
+ if (car->m_nWheelsOnGround < 3)
+ m_nTimeNotFullyOnGround += CTimer::GetTimeInMilliseconds();
+ else
+ m_nTimeNotFullyOnGround = 0;
+
+ if (car->m_aSuspensionSpringRatioPrev[2] == 1.f && car->m_aSuspensionSpringRatioPrev[3] == 1.f) {
+ if (car->m_aSuspensionSpringRatioPrev[0] < 1.0f && car->m_aSuspensionSpringRatioPrev[1] < 1.0f && car->m_fDamageImpulse == 0.0f) {
+ m_nTimeCarSpentOnTwoWheels += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceCarTravelledOnTwoWheels += car->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.5f);
+
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ } else if (car->m_aSuspensionSpringRatioPrev[0] == 1.0f && car->m_aSuspensionSpringRatioPrev[1] == 1.0f) {
+#ifdef FIX_BUGS
+ if (car->m_aSuspensionSpringRatioPrev[2] < 1.f
+#else
+ if (car->m_aSuspensionSpringRatioPrev[1] < 1.f
+#endif
+ && car->m_aSuspensionSpringRatioPrev[3] < 1.f && 0.0f == car->m_fDamageImpulse) {
+ m_nTimeCarSpentOnTwoWheels += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceCarTravelledOnTwoWheels += car->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else if (m_nTimeCarSpentOnTwoWheels != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ } else if (m_nTimeCarSpentOnTwoWheels != 0) {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ } else if (m_pPed->m_pMyVehicle->IsBike()) {
+ CBike *bike = (CBike*)m_pPed->m_pMyVehicle;
+ if (bike->m_aSuspensionSpringRatioPrev[0] == 1.0f && bike->m_aSuspensionSpringRatioPrev[1] == 1.0f) {
+ if (bike->m_aSuspensionSpringRatioPrev[2] < 1.0f
+ || (bike->m_aSuspensionSpringRatioPrev[3] < 1.0f && 0.0f == bike->m_fDamageImpulse)) {
+ m_nTimeSpentOnWheelie += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceTravelledOnWheelie += bike->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else {
+ if (m_nTimeSpentOnWheelie != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeSpentOnWheelie >= 5000) {
+ m_nLastTimeSpentOnWheelie = m_nTimeSpentOnWheelie;
+ m_nLastDistanceTravelledOnWheelie = m_nDistanceTravelledOnWheelie;
+ if (CStats::LongestWheelie < m_nTimeSpentOnWheelie / 1000)
+ CStats::LongestWheelie = m_nTimeSpentOnWheelie / 1000;
+ if (CStats::LongestWheelieDist < m_nDistanceTravelledOnWheelie)
+ CStats::LongestWheelieDist = m_nDistanceTravelledOnWheelie;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ } else if (m_nTimeSpentOnWheelie != 0) {
+ if (m_nTimeSpentOnWheelie >= 5000) {
+ m_nLastTimeSpentOnWheelie = m_nTimeSpentOnWheelie;
+ m_nLastDistanceTravelledOnWheelie = m_nDistanceTravelledOnWheelie;
+ if (CStats::LongestWheelie < m_nTimeSpentOnWheelie / 1000)
+ CStats::LongestWheelie = m_nTimeSpentOnWheelie / 1000;
+ if (CStats::LongestWheelieDist < m_nDistanceTravelledOnWheelie)
+ CStats::LongestWheelieDist = m_nDistanceTravelledOnWheelie;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0;
+ m_nCancelWheelStuntTimer = 0;
+
+ } else if (bike->m_aSuspensionSpringRatioPrev[2] == 1.0f && bike->m_aSuspensionSpringRatioPrev[3] == 1.0f
+ && 0.0f == bike->m_fDamageImpulse) {
+ m_nTimeSpentOnStoppie += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceTravelledOnStoppie += bike->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else {
+ if (m_nTimeSpentOnStoppie != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeSpentOnStoppie >= 2000) {
+ m_nLastTimeSpentOnStoppie = m_nTimeSpentOnStoppie;
+ m_nLastDistanceTravelledOnStoppie = m_nDistanceTravelledOnStoppie;
+ if (CStats::LongestStoppie < m_nTimeSpentOnStoppie / 1000)
+ CStats::LongestStoppie = m_nTimeSpentOnStoppie / 1000;
+ if (CStats::LongestStoppieDist < m_nDistanceTravelledOnStoppie)
+ CStats::LongestStoppieDist = m_nDistanceTravelledOnStoppie;
+ }
+ m_nTimeSpentOnStoppie = 0;
+ m_nDistanceTravelledOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ } else {
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+
// The effect that makes money counter does while earning/losing money
if (m_nVisibleMoney != m_nMoney) {
int diff = m_nMoney - m_nVisibleMoney;
@@ -395,7 +569,7 @@ CPlayerInfo::Process(void)
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
}
- m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
+ m_fRoadDensity = clamp(m_fRoadDensity, 0.5f, 1.45f);
// Because vehicle enter/exit use same key binding.
bool enterOrExitVeh;
@@ -404,39 +578,31 @@ CPlayerInfo::Process(void)
else
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
- if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_MODE) {
+ if (enterOrExitVeh && m_pPed->m_nPedState != PED_ANSWER_MOBILE && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_MODE) {
if (m_pPed->bInVehicle) {
if (!m_pRemoteVehicle) {
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->GetModelIndex())) {
CVehicle *veh = m_pPed->m_pMyVehicle;
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
+ if (veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
+ bool canJumpOff = false;
+ if (veh->m_vehType == VEHICLE_TYPE_BIKE) {
+ canJumpOff = veh->CanPedJumpOffBike();
+ } else if (veh->pDriver == m_pPed) {
+ canJumpOff = veh->CanPedJumpOutCar();
+ }
- // This condition will always return true, else block was probably WIP Miami code.
- if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
+ if (canJumpOff || veh->m_vecMoveSpeed.Magnitude() < 0.1f) {
+ if (!veh->bIsInWater)
m_pPed->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- }
+
+ } else if (veh->GetStatus() != STATUS_PLAYER && veh != CGameLogic::pShortCutTaxi) {
+ veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
}
- } else {
- CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
- bool found = false;
- float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
-
- if (found)
- sth.z = 1.0f + groundZ;
- m_pPed->m_nPedState = PED_IDLE;
- m_pPed->SetMoveState(PEDMOVE_STILL);
- CPed::PedSetOutCarCB(0, m_pPed);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
- m_pPed->SetPosition(sth);
- m_pPed->SetMoveState(PEDMOVE_STILL);
- m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
}
} else {
- // The code in here was under CPed::SetExitBoat in VC, did the same for here.
m_pPed->SetExitBoat(veh);
m_pPed->bTryingToReachDryLand = true;
}
@@ -451,14 +617,10 @@ CPlayerInfo::Process(void)
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
if (surfaceBelow && surfaceBelow->IsVehicle()) {
carBelow = (CVehicle*)surfaceBelow;
- if (carBelow->IsBoat()) {
+ if (carBelow->IsBoat() && carBelow->m_modelIndex != MI_SKIMMER) {
weAreOnBoat = true;
m_pPed->bOnBoat = true;
-#ifdef VC_PED_PORTS
if (carBelow->GetStatus() != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
-#else
- if (carBelow->GetStatus() != STATUS_WRECKED)
-#endif
m_pPed->SetSeekBoatPosition(carBelow);
}
}
@@ -506,14 +668,15 @@ CPlayerInfo::Process(void)
}
}
}
+
if (m_bInRemoteMode) {
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
- if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
+ if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 0);
}
if (timeWithoutRemoteCar > 2000) {
- if (m_WBState == WBSTATE_PLAYING) {
+ if (m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 1);
@@ -525,6 +688,7 @@ CPlayerInfo::Process(void)
CTimer::Update();
}
m_bInRemoteMode = false;
+ CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
if (FindPlayerVehicle()) {
FindPlayerVehicle()->SetStatus(STATUS_PLAYER);
@@ -534,11 +698,10 @@ CPlayerInfo::Process(void)
if (!(CTimer::GetFrameCounter() & 31)) {
CVehicle *veh = FindPlayerVehicle();
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
- && veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
+ && veh->m_vecMoveSpeed.Magnitude() < 0.05f && (veh->IsCar() || veh->IsBoat()) && !veh->bIsInWater) {
if (veh->GetUp().z < -0.5f) {
m_nUpsideDownCounter += 2;
-
} else {
m_nUpsideDownCounter++;
}
@@ -562,8 +725,74 @@ CPlayerInfo::Process(void)
if (veh->pPassengers[i])
veh->pPassengers[i]->m_nZoneLevel = LEVEL_GENERIC;
}
- CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
+ if(veh->m_modelIndex == MI_CADDY)
+ CStats::DistanceTravelledByGolfCart += veh->m_fDistanceTravelled;
+ else {
+ if(veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI)
+ CStats::DistanceTravelledByHelicoptor += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)
+ CStats::DistanceTravelledByPlane += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR)
+ CStats::DistanceTravelledByCar += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
+ CStats::DistanceTravelledByBike += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT)
+ CStats::DistanceTravelledByBoat += veh->m_fDistanceTravelled;
+
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE) {
+ if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) {
+ CStats::FlightTime += CTimer::GetTimeStep() * 16.f; // what a weird choice
+ }
+ }
+ }
} else {
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
}
+
+ if (m_pPed->m_pWanted->m_nWantedLevel && !CTheScripts::IsPlayerOnAMission()) {
+ float maxDelta = 0.0f;
+ static bool movedSignificantly = true;
+ static bool thereIsACarPathNear = true;
+ // there was one more guard without variable's itself???
+
+ if (CTimer::GetTimeInMilliseconds() / 20000 != CTimer::GetPreviousTimeInMilliseconds() / 20000) {
+ float posChange = (lastPlayerPos - FindPlayerCoors()).Magnitude();
+ movedSignificantly = posChange >= 10.0f;
+ lastPlayerPos = FindPlayerCoors();
+ thereIsACarPathNear = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 60.0f, true, false, false, false) != 0;
+ }
+ switch (m_pPed->m_pWanted->m_nWantedLevel) {
+ case 1:
+ maxDelta = 31.f;
+ break;
+ case 2:
+ maxDelta = 62.f;
+ break;
+ case 3:
+ maxDelta = 125.f;
+ break;
+ case 4:
+ maxDelta = 250.f;
+ break;
+ case 5:
+ maxDelta = 500.f;
+ break;
+ case 6:
+ maxDelta = 1000.f;
+ break;
+ default:
+ break;
+ }
+ float increaseDelta = maxDelta - m_fMediaAttention;
+ float increaseAttentionBy = CTimer::GetTimeStep() * 0.0001f * increaseDelta;
+ if (increaseAttentionBy < 0.0f
+ || movedSignificantly && thereIsACarPathNear && !CCullZones::NoPolice() && !CCullZones::PoliceAbandonCars() && CGame::currArea == AREA_MAIN_MAP) {
+ m_fMediaAttention += increaseAttentionBy;
+ }
+ } else {
+ m_fMediaAttention = 0.0f;
+ }
+ CStats::HighestChaseValue = Max(m_fMediaAttention, CStats::HighestChaseValue);
+ m_nMoney = Min(999999999, m_nMoney);
+ m_nVisibleMoney = Min(999999999, m_nVisibleMoney);
}
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 11f51ac0..7d99a4e0 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -45,19 +45,33 @@ public:
int8 m_WBState; // eWastedBustedState
uint32 m_nWBTime;
bool m_bInRemoteMode;
+ bool field_D5;
+ bool field_D6;
uint32 m_nTimeLostRemoteCar;
uint32 m_nTimeLastHealthLoss;
uint32 m_nTimeLastArmourLoss;
uint32 m_nTimeTankShotGun;
- int32 m_nTimeNotFullyOnGround;
int32 m_nUpsideDownCounter;
- int32 field_248;
+ int32 field_EC;
+ int32 m_nTimeCarSpentOnTwoWheels;
+ int32 m_nDistanceCarTravelledOnTwoWheels;
+ int32 m_nTimeNotFullyOnGround;
+ int32 m_nTimeSpentOnWheelie;
+ float m_nDistanceTravelledOnWheelie;
+ int32 m_nTimeSpentOnStoppie;
+ float m_nDistanceTravelledOnStoppie;
+ int32 m_nCancelWheelStuntTimer;
+ int32 m_nLastTimeCarSpentOnTwoWheels;
+ int32 m_nLastDistanceCarTravelledOnTwoWheels;
+ int32 m_nLastTimeSpentOnWheelie;
+ int32 m_nLastDistanceTravelledOnWheelie;
+ int32 m_nLastTimeSpentOnStoppie;
+ int32 m_nLastDistanceTravelledOnStoppie;
int16 m_nTrafficMultiplier;
+ int16 field_12A;
float m_fRoadDensity;
uint32 m_nPreviousTimeRewardedForExplosion;
- int32 m_nExplosionsSinceLastReward;
- int32 field_268;
- int32 field_272;
+ uint32 m_nExplosionsSinceLastReward;
uint32 m_nHavocLevel;
float m_fMediaAttention;
bool m_bInfiniteSprint;
@@ -76,7 +90,6 @@ public:
void MakePlayerSafe(bool);
void LoadPlayerSkin();
void DeletePlayerSkin();
- void AwardMoneyForExplosion(CVehicle *vehicle);
void SetPlayerSkin(char* skin);
const CVector &GetPos();
void Process(void);
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 6e3799f4..fe2cf7ad 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -22,21 +22,25 @@ CTreadablePool *CPools::ms_pTreadablePool;
CObjectPool *CPools::ms_pObjectPool;
CDummyPool *CPools::ms_pDummyPool;
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
+CColModelPool *CPools::ms_pColModelPool;
+//--MIAMI: done
void
CPools::Initialise(void)
{
- ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
- ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
- ms_pPedPool = new CPedPool(NUMPEDS);
- ms_pVehiclePool = new CVehiclePool(NUMVEHICLES);
- ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS);
- ms_pTreadablePool = new CTreadablePool(NUMTREADABLES);
- ms_pObjectPool = new CObjectPool(NUMOBJECTS);
- ms_pDummyPool = new CDummyPool(NUMDUMMIES);
- ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
+ ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode");
+ ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode");
+ ms_pPedPool = new CPedPool(NUMPEDS, "Peds");
+ ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles");
+ ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings");
+ ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables");
+ ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects");
+ ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys");
+ ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj");
+ ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel");
}
+//--MIAMI: done
void
CPools::ShutDown(void)
{
@@ -49,6 +53,7 @@ CPools::ShutDown(void)
debug("Objects left %d\n", ms_pObjectPool->GetNoOfUsedSpaces());
debug("Dummys left %d\n", ms_pDummyPool->GetNoOfUsedSpaces());
debug("AudioScriptObjects left %d\n", ms_pAudioScriptObjectPool->GetNoOfUsedSpaces());
+ debug("ColModels left %d\n", ms_pColModelPool->GetNoOfUsedSpaces());
printf("Shutdown pool started\n");
delete ms_pPtrNodePool;
@@ -60,6 +65,7 @@ CPools::ShutDown(void)
delete ms_pObjectPool;
delete ms_pDummyPool;
delete ms_pAudioScriptObjectPool;
+ delete ms_pColModelPool;
printf("Shutdown pool done\n");
}
diff --git a/src/core/Pools.h b/src/core/Pools.h
index 2f0537ff..afef1b85 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -19,6 +19,7 @@ typedef CPool<CTreadable> CTreadablePool;
typedef CPool<CObject, CCutsceneObject> CObjectPool;
typedef CPool<CDummy, CDummyPed> CDummyPool;
typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
+typedef CPool<CColModel> CColModelPool;
class CPools
{
@@ -31,6 +32,7 @@ class CPools
static CObjectPool *ms_pObjectPool;
static CDummyPool *ms_pDummyPool;
static CAudioScriptObjectPool *ms_pAudioScriptObjectPool;
+ static CColModelPool *ms_pColModelPool;
public:
static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; }
static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; }
@@ -41,6 +43,7 @@ public:
static CObjectPool *GetObjectPool(void) { return ms_pObjectPool; }
static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; }
static CAudioScriptObjectPool *GetAudioScriptObjectPool(void) { return ms_pAudioScriptObjectPool; }
+ static CColModelPool *GetColModelPool(void) { return ms_pColModelPool; }
static void Initialise(void);
static void ShutDown(void);
diff --git a/src/core/Radar.h b/src/core/Radar.h
index a36faaea..100da8f3 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -19,7 +19,7 @@
#define COORDBLIP_MARKER_COLOR_R 252
#define COORDBLIP_MARKER_COLOR_G 138
#define COORDBLIP_MARKER_COLOR_B 242
-#define COORDBLIP_MARKER_COLOR_A 255
+#define COORDBLIP_MARKER_COLOR_A 228
#define NUM_MAP_LEGENDS 75
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 2e3a27b2..1efcee01 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -3,12 +3,14 @@
#include "Stats.h"
#include "Text.h"
#include "World.h"
+#include "Pad.h"
#include <climits>
-//TODO
int32 CStats::SeagullsKilled;
-
+int32 CStats::BoatsExploded;
+int32 CStats::WantedStarsAttained;
+int32 CStats::WantedStarsEvaded;
int32 CStats::DaysPassed;
int32 CStats::HeadsPopped;
int32 CStats::CommercialPassed;
@@ -21,8 +23,25 @@ int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
int32 CStats::TimesDied;
int32 CStats::TimesArrested;
int32 CStats::KillsSinceLastCheckpoint;
-float CStats::DistanceTravelledInVehicle;
+float CStats::DistanceTravelledByCar;
+float CStats::DistanceTravelledByHelicoptor;
+float CStats::DistanceTravelledByBike;
+float CStats::DistanceTravelledByBoat;
+float CStats::DistanceTravelledByPlane;
+float CStats::DistanceTravelledByGolfCart;
float CStats::DistanceTravelledOnFoot;
+int32 CStats::FlightTime;
+int32 CStats::TimesDrowned;
+int32 CStats::PhotosTaken;
+float CStats::LoanSharks;
+float CStats::StoresKnockedOff;
+float CStats::MovieStunts;
+float CStats::Assassinations;
+float CStats::PizzasDelivered;
+float CStats::GarbagePickups;
+float CStats::IceCreamSold;
+float CStats::TopShootingRangeScore;
+float CStats::ShootingRank;
int32 CStats::ProgressMade;
int32 CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
@@ -40,94 +59,155 @@ 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::HighestLevelVigilanteMission;
+int32 CStats::HighestLevelFireMission;
int32 CStats::FiresExtinguished;
-int32 CStats::TimeTakenDefuseMission;
int32 CStats::TotalNumberKillFrenzies;
int32 CStats::TotalNumberMissions;
int32 CStats::RoundsFiredByPlayer;
int32 CStats::KgsOfExplosivesUsed;
-int32 CStats::InstantHitsFiredByPlayer;
-int32 CStats::InstantHitsHitByPlayer;
+int32 CStats::BulletsThatHit;
int32 CStats::BestTimeBombDefusal;
int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
int32 CStats::BestPositions[CStats::TOTAL_BEST_POSITIONS];
+bool CStats::PropertyOwned[CStats::TOTAL_PROPERTIES];
+int32 CStats::NumPropertyOwned;
int32 CStats::PropertyDestroyed;
+float CStats::HighestChaseValue;
+int32 CStats::CheatedCount;
+int32 CStats::ShowChaseStatOnScreen;
+int32 CStats::PamphletMissionPassed;
+bool CStats::abSonyCDs[1];
+int32 CStats::BloodRingKills;
+int32 CStats::BloodRingTime;
+float CStats::FavoriteRadioStationList[NUM_RADIOS];
int32 CStats::Sprayings;
float CStats::AutoPaintingBudget;
int32 CStats::NoMoreHurricanes;
float CStats::FashionBudget;
+float CStats::PropertyBudget;
+float CStats::WeaponBudget;
int32 CStats::SafeHouseVisits;
int32 CStats::TyresPopped;
+int32 CStats::LongestWheelie;
+int32 CStats::LongestStoppie;
+int32 CStats::Longest2Wheel;
+float CStats::LongestWheelieDist;
+float CStats::LongestStoppieDist;
+float CStats::Longest2WheelDist;
+
+// --MIAMI: functions below are done except TODOs, but there are some to be moved from Frontend
+
void CStats::Init()
{
PeopleKilledByOthers = 0;
PeopleKilledByPlayer = 0;
- RoundsFiredByPlayer = 0;
CarsExploded = 0;
+ BoatsExploded = 0;
+ RoundsFiredByPlayer = 0;
+ for (int i = 0; i < NUM_PEDTYPES; i++)
+ PedsKilledOfThisType[i] = 0;
HelisDestroyed = 0;
ProgressMade = 0;
KgsOfExplosivesUsed = 0;
- InstantHitsFiredByPlayer = 0;
- InstantHitsHitByPlayer = 0;
+ BulletsThatHit = 0;
+ TyresPopped = 0;
HeadsPopped = 0;
+ WantedStarsAttained = 0;
+ WantedStarsEvaded = 0;
TimesArrested = 0;
TimesDied = 0;
DaysPassed = 0;
- NumberOfUniqueJumpsFound = 0;
- MaximumJumpFlips = 0;
- MaximumJumpSpins = 0;
+ SafeHouseVisits = 0;
+ Sprayings = 0;
MaximumJumpDistance = 0;
MaximumJumpHeight = 0;
+ MaximumJumpFlips = 0;
+ MaximumJumpSpins = 0;
BestStuntJump = 0;
+ NumberOfUniqueJumpsFound = 0;
TotalNumberOfUniqueJumps = 0;
- Record4x4One = 0;
- Record4x4Two = 0;
+ MissionsGiven = 0;
+ MissionsPassed = 0;
PassengersDroppedOffWithTaxi = 0;
- Record4x4Three = 0;
MoneyMadeWithTaxi = 0;
- Record4x4Mayhem = 0;
+ DistanceTravelledOnFoot = 0;
+ DistanceTravelledByCar = 0;
+ DistanceTravelledByBike = 0;
+ DistanceTravelledByBoat = 0;
+ DistanceTravelledByGolfCart = 0;
+ DistanceTravelledByHelicoptor = 0;
+#ifdef FIX_BUGS
+ DistanceTravelledByPlane = 0;
+#endif
LivesSavedWithAmbulance = 0;
- ElBurroTime = 0;
CriminalsCaught = 0;
- MissionsGiven = 0;
+ HighestLevelVigilanteMission = 0;
HighestLevelAmbulanceMission = 0;
- MissionsPassed = 0;
+ HighestLevelFireMission = 0;
FiresExtinguished = 0;
- DistanceTravelledOnFoot = 0;
- TimeTakenDefuseMission = 0;
+ PhotosTaken = 0;
NumberKillFrenziesPassed = 0;
- DistanceTravelledInVehicle = 0;
TotalNumberKillFrenzies = 0;
TotalNumberMissions = 0;
- KillsSinceLastCheckpoint = 0;
- TotalLegitimateKills = 0;
+ FlightTime = 0;
+ TimesDrowned = 0;
+ SeagullsKilled = 0;
+ WeaponBudget = 0.0f;
+ FashionBudget = 0.0f;
+ LoanSharks = 0.0f;
+ StoresKnockedOff = 0.0f;
+ MovieStunts = 0.0f;
+ Assassinations = 0.0f;
+ PizzasDelivered = 0.0f;
+ GarbagePickups = 0.0f;
+ IceCreamSold = 0.0f;
+ TopShootingRangeScore = 0.0f;
+ ShootingRank = 0.0f;
+ LongestWheelie = 0;
+ LongestStoppie = 0;
+ Longest2Wheel = 0;
+ LongestWheelieDist = 0.0f;
+ LongestStoppieDist = 0.0f;
+ Longest2WheelDist = 0.0f;
+ PropertyBudget = 0.0f;
+ AutoPaintingBudget = 0.0f;
+ PropertyDestroyed = 0;
+ HighestChaseValue = 0.0f;
+ CheatedCount = 0;
+
for (int i = 0; i < TOTAL_FASTEST_TIMES; i++)
FastestTimes[i] = 0;
for (int i = 0; i < TOTAL_HIGHEST_SCORES; i++)
HighestScores[i] = 0;
for (int i = 0; i < TOTAL_BEST_POSITIONS; i++)
BestPositions[i] = INT_MAX;
- for (int i = 0; i < NUM_PEDTYPES; i++)
- PedsKilledOfThisType[i] = 0;
+
+ KillsSinceLastCheckpoint = 0;
+ TotalLegitimateKills = 0;
IndustrialPassed = 0;
CommercialPassed = 0;
SuburbanPassed = 0;
-
- Sprayings = 0;
- AutoPaintingBudget = 0.0f;
+ PamphletMissionPassed = 0;
NoMoreHurricanes = 0;
- SafeHouseVisits = 0;
+ ShowChaseStatOnScreen = 0;
+ abSonyCDs[0] = 0;
+ // TODO(Miami): Change this with PopulateFavoriteRadioStationList(); !!
+ for (int i = 0; i < NUM_RADIOS; i++)
+ FavoriteRadioStationList[i] = 0.0f;
+
+ NumPropertyOwned = 0;
+ for (int i = 0; i < TOTAL_PROPERTIES; i++)
+ PropertyOwned[i] = false;
+
+ BloodRingKills = 0;
+ BloodRingTime = 0;
}
void CStats::RegisterFastestTime(int32 index, int32 time)
@@ -151,31 +231,6 @@ void CStats::RegisterBestPosition(int32 index, int32 position)
BestPositions[index] = Min(BestPositions[index], position);
}
-void CStats::RegisterElBurroTime(int32 time)
-{
- ElBurroTime = (ElBurroTime && ElBurroTime < time) ? ElBurroTime : time;
-}
-
-void CStats::Register4x4OneTime(int32 time)
-{
- Record4x4One = (Record4x4One && Record4x4One < time) ? Record4x4One : time;
-}
-
-void CStats::Register4x4TwoTime(int32 time)
-{
- Record4x4Two = (Record4x4Two && Record4x4Two < time) ? Record4x4Two : time;
-}
-
-void CStats::Register4x4ThreeTime(int32 time)
-{
- Record4x4Three = (Record4x4Three && Record4x4Three < time) ? Record4x4Three : time;
-}
-
-void CStats::Register4x4MayhemTime(int32 time)
-{
- Record4x4Mayhem = (Record4x4Mayhem && Record4x4Mayhem < time) ? Record4x4Mayhem : time;
-}
-
void CStats::AnotherLifeSavedWithAmbulance()
{
++LivesSavedWithAmbulance;
@@ -191,14 +246,19 @@ void CStats::RegisterLevelAmbulanceMission(int32 level)
HighestLevelAmbulanceMission = Max(HighestLevelAmbulanceMission, level);
}
-void CStats::AnotherFireExtinguished()
+void CStats::RegisterLevelVigilanteMission(int32 level)
{
- ++FiresExtinguished;
+ HighestLevelVigilanteMission = Max(HighestLevelVigilanteMission, level);
}
-void CStats::RegisterTimeTakenDefuseMission(int32 time)
+void CStats::RegisterLevelFireMission(int32 level)
{
- TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
+ HighestLevelFireMission = Max(HighestLevelFireMission, level);
+}
+
+void CStats::AnotherFireExtinguished()
+{
+ ++FiresExtinguished;
}
void CStats::AnotherKillFrenzyPassed()
@@ -220,40 +280,88 @@ wchar *CStats::FindCriminalRatingString()
{
int rating = FindCriminalRatingNumber();
- if (rating < 10) return TheText.Get("RATNG1");
- if (rating < 25) return TheText.Get("RATNG2");
- if (rating < 70) return TheText.Get("RATNG3");
- if (rating < 150) return TheText.Get("RATNG4");
- if (rating < 250) return TheText.Get("RATNG5");
- if (rating < 450) return TheText.Get("RATNG6");
- if (rating < 700) return TheText.Get("RATNG7");
- if (rating < 1000) return TheText.Get("RATNG8");
- if (rating < 1400) return TheText.Get("RATNG9");
- if (rating < 1900) return TheText.Get("RATNG10");
- if (rating < 2500) return TheText.Get("RATNG11");
- if (rating < 3200) return TheText.Get("RATNG12");
- if (rating < 4000) return TheText.Get("RATNG13");
- if (rating < 5000) return TheText.Get("RATNG14");
- return TheText.Get("RATNG15");
+ if (rating < 0) {
+ if (rating > -500) return TheText.Get("RATNG53");
+ if (rating > -2000) return TheText.Get("RATNG54");
+ if (rating > -4000) return TheText.Get("RATNG55");
+ if (rating > -6000) return TheText.Get("RATNG56");
+ return TheText.Get("RATNG57");
+ }
+ if (rating < 20) return TheText.Get("RATNG1");
+ if (rating < 50) return TheText.Get("RATNG2");
+ if (rating < 75) return TheText.Get("RATNG3");
+ if (rating < 100) return TheText.Get("RATNG4");
+ if (rating < 120) return TheText.Get("RATNG5");
+ if (rating < 150) return TheText.Get("RATNG6");
+ if (rating < 200) return TheText.Get("RATNG7");
+ if (rating < 240) return TheText.Get("RATNG8");
+ if (rating < 270) return TheText.Get("RATNG9");
+ if (rating < 300) return TheText.Get("RATNG10");
+ if (rating < 335) return TheText.Get("RATNG11");
+ if (rating < 370) return TheText.Get("RATNG12");
+ if (rating < 400) return TheText.Get("RATNG13");
+ if (rating < 450) return TheText.Get("RATNG14");
+ if (rating < 500) return TheText.Get("RATNG15");
+ if (rating < 550) return TheText.Get("RATNG16");
+ if (rating < 600) return TheText.Get("RATNG17");
+ if (rating < 610) return TheText.Get("RATNG18");
+ if (rating < 650) return TheText.Get("RATNG19");
+ if (rating < 700) return TheText.Get("RATNG20");
+ if (rating < 850) return TheText.Get("RATNG21");
+ if (rating < 1000) return TheText.Get("RATNG22");
+ if (rating < 1005) return TheText.Get("RATNG23");
+ if (rating < 1150) return TheText.Get("RATNG24");
+ if (rating < 1300) return TheText.Get(TimesArrested > 0 ? "RATNG25" : "RATNG24");
+ if (rating < 1500) return TheText.Get("RATNG26");
+ if (rating < 1700) return TheText.Get("RATNG27");
+ if (rating < 2000) return TheText.Get("RATNG28");
+ if (rating < 2100) return TheText.Get("RATNG29");
+ if (rating < 2300) return TheText.Get("RATNG30");
+ if (rating < 2500) return TheText.Get("RATNG31");
+ if (rating < 2750) return TheText.Get("RATNG32");
+ if (rating < 3000) return TheText.Get("RATNG33");
+ if (rating < 3500) return TheText.Get("RATNG34");
+ if (rating < 4000) return TheText.Get("RATNG35");
+ if (rating < 5000) return TheText.Get("RATNG36");
+ if (rating < 7500) return TheText.Get("RATNG37");
+ if (rating < 10000) return TheText.Get("RATNG38");
+ if (rating < 20000) return TheText.Get("RATNG39");
+ if (rating < 30000) return TheText.Get("RATNG40");
+ if (rating < 40000) return TheText.Get("RATNG41");
+ if (rating < 50000) return TheText.Get("RATNG42");
+ if (rating < 65000) return TheText.Get("RATNG43");
+ if (rating < 80000) return TheText.Get("RATNG44");
+ if (rating < 100000) return TheText.Get("RATNG45");
+ if (rating < 150000) return TheText.Get("RATNG46");
+ if (rating < 200000) return TheText.Get("RATNG47");
+ if (rating < 300000) return TheText.Get("RATNG48");
+ if (rating < 375000) return TheText.Get("RATNG49");
+ if (rating < 500000) return TheText.Get(FlightTime / 60000 / 60 > 10 ? "RATNG50" : "RATNG49");
+ if (rating < 1000000) return TheText.Get("RATNG51");
+ return TheText.Get(CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney > 10000000 ? "RATNG52" : "RATNG51");
}
int32 CStats::FindCriminalRatingNumber()
{
int32 rating;
- rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
+ rating = FiresExtinguished + 10 * HighestLevelFireMission + 10 * HighestLevelAmbulanceMission
+ + CriminalsCaught + LivesSavedWithAmbulance
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
- if (rating <= 0) rating = 0;
+ if (CPad::bHasPlayerCheated || CheatedCount > 0) {
+ rating -= CheatedCount;
+ if (rating <= -10000)
+ rating = -10000;
+
+ } else if (rating <= 0) {
+ rating = 0;
+ }
- if (InstantHitsFiredByPlayer > 100)
- rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
+ if (RoundsFiredByPlayer > 100)
+ rating += (float)CStats::BulletsThatHit / (float)CStats::RoundsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
- if (!IndustrialPassed && rating >= 3521)
- rating = 3521;
- if (!CommercialPassed && rating >= 4552)
- rating = 4552;
return rating;
}
@@ -265,11 +373,80 @@ float CStats::GetPercentageProgress()
return Min(percentCompleted, 100.0f);
}
+void CStats::MoneySpentOnWeapons(int32 money)
+{
+ WeaponBudget += money;
+}
+
+void CStats::MoneySpentOnProperty(int32 money)
+{
+ PropertyBudget += money;
+}
+
+void CStats::MoneySpentOnAutoPainting(int32 money)
+{
+ AutoPaintingBudget += money;
+}
+
void CStats::MoneySpentOnFashion(int32 money)
{
FashionBudget += money;
}
+void CStats::NumOfVisitsFromLoanSharks(int32 num)
+{
+ LoanSharks += num;
+}
+
+void CStats::NumOfStoresKnockedOff(int32 num)
+{
+ StoresKnockedOff += num;
+}
+
+void CStats::NumOfMovieStunts(int32 num)
+{
+ MovieStunts += num;
+}
+
+void CStats::NumOfAssassinations(int32 num)
+{
+ Assassinations += num;
+}
+
+void CStats::NumOfPizzasDelivered(int32 num)
+{
+ PizzasDelivered += num;
+}
+
+void CStats::NumOfGarbagePickups(int32 num)
+{
+ GarbagePickups += num;
+}
+
+void CStats::NumOfIceCreamSold(int32 num)
+{
+ IceCreamSold += num;
+}
+
+void CStats::AddNumBloodRingKills(int32 num)
+{
+ BloodRingKills += num;
+}
+
+void CStats::LongestTimeInBloodRing(int32 time)
+{
+ if (BloodRingTime < time)
+ BloodRingTime = time;
+}
+
+void CStats::AddPropertyAsOwned(int32 id)
+{
+ if (!PropertyOwned[id]) {
+ PropertyOwned[id] = true;
+ ++NumPropertyOwned;
+ }
+}
+
void CStats::SaveStats(uint8 *buf, uint32 *size)
{
CheckPointReachedSuccessfully();
@@ -277,18 +454,23 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
*size = sizeof(PeopleKilledByPlayer) +
sizeof(PeopleKilledByOthers) +
sizeof(CarsExploded) +
+ sizeof(BoatsExploded) +
+ sizeof(TyresPopped) +
sizeof(RoundsFiredByPlayer) +
sizeof(PedsKilledOfThisType) +
sizeof(HelisDestroyed) +
sizeof(ProgressMade) +
sizeof(TotalProgressInGame) +
sizeof(KgsOfExplosivesUsed) +
- sizeof(InstantHitsFiredByPlayer) +
- sizeof(InstantHitsHitByPlayer) +
+ sizeof(BulletsThatHit) +
sizeof(HeadsPopped) +
+ sizeof(WantedStarsAttained) +
+ sizeof(WantedStarsEvaded) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
+ sizeof(SafeHouseVisits) +
+ sizeof(Sprayings) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
@@ -297,50 +479,88 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(NumberOfUniqueJumpsFound) +
sizeof(TotalNumberOfUniqueJumps) +
sizeof(MissionsGiven) +
- sizeof(MissionsPassed) +
sizeof(PassengersDroppedOffWithTaxi) +
sizeof(MoneyMadeWithTaxi) +
sizeof(IndustrialPassed) +
sizeof(CommercialPassed) +
sizeof(SuburbanPassed) +
- sizeof(ElBurroTime) +
+ sizeof(PamphletMissionPassed) +
+ sizeof(NoMoreHurricanes) +
sizeof(DistanceTravelledOnFoot) +
- sizeof(DistanceTravelledInVehicle) +
- sizeof(Record4x4One) +
- sizeof(Record4x4Two) +
- sizeof(Record4x4Three) +
- sizeof(Record4x4Mayhem) +
+ sizeof(DistanceTravelledByCar) +
+ sizeof(DistanceTravelledByBike) +
+ sizeof(DistanceTravelledByBoat) +
+ sizeof(DistanceTravelledByGolfCart) +
+ sizeof(DistanceTravelledByHelicoptor) +
+ sizeof(DistanceTravelledByPlane) +
sizeof(LivesSavedWithAmbulance) +
sizeof(CriminalsCaught) +
- sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
- sizeof(TimeTakenDefuseMission) +
+ sizeof(HighestLevelVigilanteMission) +
+ sizeof(HighestLevelAmbulanceMission) +
+ sizeof(HighestLevelFireMission) +
+ sizeof(PhotosTaken) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
sizeof(TotalNumberMissions) +
+ sizeof(FlightTime) +
+ sizeof(TimesDrowned) +
+ sizeof(SeagullsKilled) +
+ sizeof(WeaponBudget) +
+ sizeof(FashionBudget) +
+ sizeof(LoanSharks) +
+ sizeof(StoresKnockedOff) +
+ sizeof(MovieStunts) +
+ sizeof(Assassinations) +
+ sizeof(PizzasDelivered) +
+ sizeof(GarbagePickups) +
+ sizeof(IceCreamSold) +
+ sizeof(TopShootingRangeScore) +
+ sizeof(ShootingRank) +
+ sizeof(LongestWheelie) +
+ sizeof(LongestStoppie) +
+ sizeof(Longest2Wheel) +
+ sizeof(LongestWheelieDist) +
+ sizeof(LongestStoppieDist) +
+ sizeof(Longest2WheelDist) +
+ sizeof(PropertyBudget) +
+ sizeof(AutoPaintingBudget) +
+ sizeof(PropertyDestroyed) +
+ sizeof(NumPropertyOwned) +
+ sizeof(BloodRingKills) +
+ sizeof(BloodRingTime) +
+ sizeof(PropertyOwned) +
+ sizeof(HighestChaseValue) +
sizeof(FastestTimes) +
sizeof(HighestScores) +
sizeof(BestPositions) +
sizeof(KillsSinceLastCheckpoint) +
sizeof(TotalLegitimateKills) +
- sizeof(LastMissionPassedName);
+ sizeof(LastMissionPassedName) +
+ sizeof(CheatedCount) +
+ sizeof(FavoriteRadioStationList);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, PeopleKilledByPlayer);
CopyToBuf(buf, PeopleKilledByOthers);
CopyToBuf(buf, CarsExploded);
+ CopyToBuf(buf, BoatsExploded);
+ CopyToBuf(buf, TyresPopped);
CopyToBuf(buf, RoundsFiredByPlayer);
CopyToBuf(buf, PedsKilledOfThisType);
CopyToBuf(buf, HelisDestroyed);
CopyToBuf(buf, ProgressMade);
CopyToBuf(buf, TotalProgressInGame);
CopyToBuf(buf, KgsOfExplosivesUsed);
- CopyToBuf(buf, InstantHitsFiredByPlayer);
- CopyToBuf(buf, InstantHitsHitByPlayer);
+ CopyToBuf(buf, BulletsThatHit);
CopyToBuf(buf, HeadsPopped);
+ CopyToBuf(buf, WantedStarsAttained);
+ CopyToBuf(buf, WantedStarsEvaded);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
+ CopyToBuf(buf, SafeHouseVisits);
+ CopyToBuf(buf, Sprayings);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
@@ -349,33 +569,67 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, NumberOfUniqueJumpsFound);
CopyToBuf(buf, TotalNumberOfUniqueJumps);
CopyToBuf(buf, MissionsGiven);
- CopyToBuf(buf, MissionsPassed);
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
CopyToBuf(buf, MoneyMadeWithTaxi);
CopyToBuf(buf, IndustrialPassed);
CopyToBuf(buf, CommercialPassed);
CopyToBuf(buf, SuburbanPassed);
- CopyToBuf(buf, ElBurroTime);
+ CopyToBuf(buf, PamphletMissionPassed);
+ CopyToBuf(buf, NoMoreHurricanes);
CopyToBuf(buf, DistanceTravelledOnFoot);
- CopyToBuf(buf, DistanceTravelledInVehicle);
- CopyToBuf(buf, Record4x4One);
- CopyToBuf(buf, Record4x4Two);
- CopyToBuf(buf, Record4x4Three);
- CopyToBuf(buf, Record4x4Mayhem);
+ CopyToBuf(buf, DistanceTravelledByCar);
+ CopyToBuf(buf, DistanceTravelledByBike);
+ CopyToBuf(buf, DistanceTravelledByBoat);
+ CopyToBuf(buf, DistanceTravelledByGolfCart);
+ CopyToBuf(buf, DistanceTravelledByHelicoptor);
+ CopyToBuf(buf, DistanceTravelledByPlane);
CopyToBuf(buf, LivesSavedWithAmbulance);
CopyToBuf(buf, CriminalsCaught);
- CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
- CopyToBuf(buf, TimeTakenDefuseMission);
+ CopyToBuf(buf, HighestLevelVigilanteMission);
+ CopyToBuf(buf, HighestLevelAmbulanceMission);
+ CopyToBuf(buf, HighestLevelFireMission);
+ CopyToBuf(buf, PhotosTaken);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
CopyToBuf(buf, TotalNumberMissions);
+ CopyToBuf(buf, FlightTime);
+ CopyToBuf(buf, TimesDrowned);
+ CopyToBuf(buf, SeagullsKilled);
+ CopyToBuf(buf, WeaponBudget);
+ CopyToBuf(buf, FashionBudget);
+ CopyToBuf(buf, LoanSharks);
+ CopyToBuf(buf, StoresKnockedOff);
+ CopyToBuf(buf, MovieStunts);
+ CopyToBuf(buf, Assassinations);
+ CopyToBuf(buf, PizzasDelivered);
+ CopyToBuf(buf, GarbagePickups);
+ CopyToBuf(buf, IceCreamSold);
+ CopyToBuf(buf, TopShootingRangeScore);
+ CopyToBuf(buf, ShootingRank);
+ CopyToBuf(buf, LongestWheelie);
+ CopyToBuf(buf, LongestStoppie);
+ CopyToBuf(buf, Longest2Wheel);
+ CopyToBuf(buf, LongestWheelieDist);
+ CopyToBuf(buf, LongestStoppieDist);
+ CopyToBuf(buf, Longest2WheelDist);
+ CopyToBuf(buf, PropertyBudget);
+ CopyToBuf(buf, AutoPaintingBudget);
+ CopyToBuf(buf, PropertyDestroyed);
+ CopyToBuf(buf, NumPropertyOwned);
+ CopyToBuf(buf, BloodRingKills);
+ CopyToBuf(buf, BloodRingTime);
+ CopyToBuf(buf, PropertyOwned);
+ CopyToBuf(buf, HighestChaseValue);
CopyToBuf(buf, FastestTimes);
CopyToBuf(buf, HighestScores);
CopyToBuf(buf, BestPositions);
CopyToBuf(buf, KillsSinceLastCheckpoint);
CopyToBuf(buf, TotalLegitimateKills);
CopyToBuf(buf, LastMissionPassedName);
+ CopyToBuf(buf, CheatedCount);
+ // TODO(Miami): Set favourite radio stations!!
+ CopyToBuf(buf, FavoriteRadioStationList);
assert(buf - buf_start == *size);
#undef CopyToBuf
@@ -390,18 +644,23 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, PeopleKilledByPlayer);
CopyFromBuf(buf, PeopleKilledByOthers);
CopyFromBuf(buf, CarsExploded);
+ CopyFromBuf(buf, BoatsExploded);
+ CopyFromBuf(buf, TyresPopped);
CopyFromBuf(buf, RoundsFiredByPlayer);
CopyFromBuf(buf, PedsKilledOfThisType);
CopyFromBuf(buf, HelisDestroyed);
CopyFromBuf(buf, ProgressMade);
CopyFromBuf(buf, TotalProgressInGame);
CopyFromBuf(buf, KgsOfExplosivesUsed);
- CopyFromBuf(buf, InstantHitsFiredByPlayer);
- CopyFromBuf(buf, InstantHitsHitByPlayer);
+ CopyFromBuf(buf, BulletsThatHit);
CopyFromBuf(buf, HeadsPopped);
+ CopyFromBuf(buf, WantedStarsAttained);
+ CopyFromBuf(buf, WantedStarsEvaded);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
+ CopyFromBuf(buf, SafeHouseVisits);
+ CopyFromBuf(buf, Sprayings);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
@@ -410,33 +669,66 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
CopyFromBuf(buf, MissionsGiven);
- CopyFromBuf(buf, MissionsPassed);
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
CopyFromBuf(buf, MoneyMadeWithTaxi);
CopyFromBuf(buf, IndustrialPassed);
CopyFromBuf(buf, CommercialPassed);
CopyFromBuf(buf, SuburbanPassed);
- CopyFromBuf(buf, ElBurroTime);
+ CopyFromBuf(buf, PamphletMissionPassed);
+ CopyFromBuf(buf, NoMoreHurricanes);
CopyFromBuf(buf, DistanceTravelledOnFoot);
- CopyFromBuf(buf, DistanceTravelledInVehicle);
- CopyFromBuf(buf, Record4x4One);
- CopyFromBuf(buf, Record4x4Two);
- CopyFromBuf(buf, Record4x4Three);
- CopyFromBuf(buf, Record4x4Mayhem);
+ CopyFromBuf(buf, DistanceTravelledByCar);
+ CopyFromBuf(buf, DistanceTravelledByBike);
+ CopyFromBuf(buf, DistanceTravelledByBoat);
+ CopyFromBuf(buf, DistanceTravelledByGolfCart);
+ CopyFromBuf(buf, DistanceTravelledByHelicoptor);
+ CopyFromBuf(buf, DistanceTravelledByPlane);
CopyFromBuf(buf, LivesSavedWithAmbulance);
CopyFromBuf(buf, CriminalsCaught);
- CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
- CopyFromBuf(buf, TimeTakenDefuseMission);
+ CopyFromBuf(buf, HighestLevelVigilanteMission);
+ CopyFromBuf(buf, HighestLevelAmbulanceMission);
+ CopyFromBuf(buf, HighestLevelFireMission);
+ CopyFromBuf(buf, PhotosTaken);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);
CopyFromBuf(buf, TotalNumberMissions);
+ CopyFromBuf(buf, FlightTime);
+ CopyFromBuf(buf, TimesDrowned);
+ CopyFromBuf(buf, SeagullsKilled);
+ CopyFromBuf(buf, WeaponBudget);
+ CopyFromBuf(buf, FashionBudget);
+ CopyFromBuf(buf, LoanSharks);
+ CopyFromBuf(buf, StoresKnockedOff);
+ CopyFromBuf(buf, MovieStunts);
+ CopyFromBuf(buf, Assassinations);
+ CopyFromBuf(buf, PizzasDelivered);
+ CopyFromBuf(buf, GarbagePickups);
+ CopyFromBuf(buf, IceCreamSold);
+ CopyFromBuf(buf, TopShootingRangeScore);
+ CopyFromBuf(buf, ShootingRank);
+ CopyFromBuf(buf, LongestWheelie);
+ CopyFromBuf(buf, LongestStoppie);
+ CopyFromBuf(buf, Longest2Wheel);
+ CopyFromBuf(buf, LongestWheelieDist);
+ CopyFromBuf(buf, LongestStoppieDist);
+ CopyFromBuf(buf, Longest2WheelDist);
+ CopyFromBuf(buf, PropertyBudget);
+ CopyFromBuf(buf, AutoPaintingBudget);
+ CopyFromBuf(buf, PropertyDestroyed);
+ CopyFromBuf(buf, NumPropertyOwned);
+ CopyFromBuf(buf, BloodRingKills);
+ CopyFromBuf(buf, BloodRingTime);
+ CopyFromBuf(buf, PropertyOwned);
+ CopyFromBuf(buf, HighestChaseValue);
CopyFromBuf(buf, FastestTimes);
CopyFromBuf(buf, HighestScores);
CopyFromBuf(buf, BestPositions);
CopyFromBuf(buf, KillsSinceLastCheckpoint);
CopyFromBuf(buf, TotalLegitimateKills);
CopyFromBuf(buf, LastMissionPassedName);
+ CopyFromBuf(buf, CheatedCount);
+ CopyFromBuf(buf, FavoriteRadioStationList);
assert(buf - buf_start == size);
#undef CopyFromBuf
diff --git a/src/core/Stats.h b/src/core/Stats.h
index 7dd527ea..f9ad4174 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -1,6 +1,7 @@
#pragma once
#include "PedType.h"
+#include "audio_enums.h"
class CStats
{
@@ -8,11 +9,10 @@ public:
enum {
TOTAL_FASTEST_TIMES = 23,
TOTAL_HIGHEST_SCORES = 5,
- TOTAL_BEST_POSITIONS = 1
+ TOTAL_BEST_POSITIONS = 1,
+ TOTAL_PROPERTIES = 15
};
- //TODO
static int32 SeagullsKilled;
-
static int32 DaysPassed;
static int32 HeadsPopped;
static int32 CommercialPassed;
@@ -25,9 +25,29 @@ public:
static int32 TimesDied;
static int32 TimesArrested;
static int32 KillsSinceLastCheckpoint;
- static float DistanceTravelledInVehicle;
+ static float DistanceTravelledByCar;
+ static float DistanceTravelledByHelicoptor;
+ static float DistanceTravelledByBike;
+ static float DistanceTravelledByBoat;
+ static float DistanceTravelledByPlane;
+ static float DistanceTravelledByGolfCart;
static float DistanceTravelledOnFoot;
+ static int32 FlightTime;
+ static int32 TimesDrowned;
+ static int32 PhotosTaken;
+ static float LoanSharks;
+ static float StoresKnockedOff;
+ static float MovieStunts;
+ static float Assassinations;
+ static float PizzasDelivered;
+ static float GarbagePickups;
+ static float IceCreamSold;
+ static float TopShootingRangeScore;
+ static float ShootingRank;
static int32 CarsExploded;
+ static int32 BoatsExploded;
+ static int32 WantedStarsAttained;
+ static int32 WantedStarsEvaded;
static int32 PeopleKilledByPlayer;
static int32 ProgressMade;
static int32 TotalProgressInGame;
@@ -44,50 +64,60 @@ public:
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 HighestLevelVigilanteMission;
+ static int32 HighestLevelFireMission;
static int32 FiresExtinguished;
- static int32 TimeTakenDefuseMission;
static int32 TotalNumberKillFrenzies;
static int32 TotalNumberMissions;
static int32 RoundsFiredByPlayer;
static int32 KgsOfExplosivesUsed;
- static int32 InstantHitsFiredByPlayer;
- static int32 InstantHitsHitByPlayer;
+ static int32 BulletsThatHit;
static int32 BestTimeBombDefusal;
static int32 FastestTimes[TOTAL_FASTEST_TIMES];
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
static int32 BestPositions[TOTAL_BEST_POSITIONS];
+ static bool PropertyOwned[TOTAL_PROPERTIES];
+ static int32 NumPropertyOwned;
static int32 PropertyDestroyed;
+ static float HighestChaseValue;
+ static int32 CheatedCount;
+ static int32 ShowChaseStatOnScreen;
+ static int32 PamphletMissionPassed;
+ static bool abSonyCDs[1];
+ static int32 BloodRingKills;
+ static int32 BloodRingTime;
+ static float FavoriteRadioStationList[NUM_RADIOS];
static int32 Sprayings;
static float AutoPaintingBudget;
static int32 NoMoreHurricanes;
static float FashionBudget;
+ static float PropertyBudget;
+ static float WeaponBudget;
static int32 SafeHouseVisits;
static int32 TyresPopped;
+ static int32 LongestWheelie;
+ static int32 LongestStoppie;
+ static int32 Longest2Wheel;
+ static float LongestWheelieDist;
+ static float LongestStoppieDist;
+ static float Longest2WheelDist;
+
public:
static void Init(void);
static void RegisterFastestTime(int32, int32);
static void RegisterHighestScore(int32, int32);
static void RegisterBestPosition(int32, int32);
- static void RegisterElBurroTime(int32);
- static void Register4x4OneTime(int32);
- static void Register4x4TwoTime(int32);
- static void Register4x4ThreeTime(int32);
- static void Register4x4MayhemTime(int32);
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
+ static void RegisterLevelVigilanteMission(int32);
+ static void RegisterLevelFireMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
- static void RegisterTimeTakenDefuseMission(int32);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32);
@@ -98,5 +128,20 @@ public:
static void LoadStats(uint8 *buf, uint32 size);
static float GetPercentageProgress();
+ static void MoneySpentOnWeapons(int32);
+ static void MoneySpentOnProperty(int32);
+ static void MoneySpentOnAutoPainting(int32);
static void MoneySpentOnFashion(int32);
+
+ static void NumOfVisitsFromLoanSharks(int32);
+ static void NumOfStoresKnockedOff(int32);
+ static void NumOfMovieStunts(int32);
+ static void NumOfAssassinations(int32);
+ static void NumOfPizzasDelivered(int32);
+ static void NumOfGarbagePickups(int32);
+ static void NumOfIceCreamSold(int32);
+ static void AddNumBloodRingKills(int32);
+
+ static void LongestTimeInBloodRing(int32);
+ static void AddPropertyAsOwned(int32);
};
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 3c32b856..d296496e 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -31,6 +31,9 @@
#include "main.h"
#include "ColStore.h"
#include "DMAudio.h"
+#include "Script.h"
+
+//--MIAMI: file done (possibly bugs)
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@@ -48,6 +51,7 @@ size_t CStreaming::ms_memoryUsed;
CStreamingChannel CStreaming::ms_channel[2];
int32 CStreaming::ms_channelError;
int32 CStreaming::ms_numVehiclesLoaded;
+int32 CStreaming::ms_numPedsLoaded;
int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
int32 CStreaming::ms_lastVehicleDeleted;
bool CStreaming::ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
@@ -70,7 +74,6 @@ CEntity *pIslandLODbeachEntity;
int32 islandLODmainland;
int32 islandLODbeach;
-//--MIAMI: done
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
{
@@ -81,7 +84,6 @@ CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
return true;
}
-//--MIAMI: done
void
CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size)
{
@@ -89,7 +91,6 @@ CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size)
m_size = size;
}
-//--MIAMI: done
void
CStreamingInfo::AddToList(CStreamingInfo *link)
{
@@ -100,7 +101,6 @@ CStreamingInfo::AddToList(CStreamingInfo *link)
m_next->m_prev = this;
}
-//--MIAMI: done
void
CStreamingInfo::RemoveFromList(void)
{
@@ -110,7 +110,6 @@ CStreamingInfo::RemoveFromList(void)
m_prev = nil;
}
-//--MIAMI: done
void
CStreaming::Init2(void)
{
@@ -179,6 +178,7 @@ CStreaming::Init2(void)
for(i = 0; i < MAXVEHICLESLOADED; i++)
ms_vehiclesLoaded[i] = -1;
ms_numVehiclesLoaded = 0;
+ ms_numPedsLoaded = 8;
for(i = 0; i < ARRAY_SIZE(ms_bIsPedFromPedGroupLoaded); i++)
ms_bIsPedFromPedGroupLoaded[i] = false;
@@ -199,11 +199,25 @@ CStreaming::Init2(void)
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
+ // PC only, figure out how much memory we got
+#ifdef GTA_PC
#define MB (1024*1024)
+#ifdef FIX_BUGS
+ // do what gta3 does
+ extern size_t _dwMemAvailPhys;
+ ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
+ if(ms_memoryAvailable < 65*MB)
+ ms_memoryAvailable = 65*MB;
+ desiredNumVehiclesLoaded = (int32)((ms_memoryAvailable / MB - 65) / 3 + 12);
+ if(desiredNumVehiclesLoaded > MAXVEHICLESLOADED)
+ desiredNumVehiclesLoaded = MAXVEHICLESLOADED;
+#else
ms_memoryAvailable = 65 * MB;
desiredNumVehiclesLoaded = 25;
- debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable / MB);
+ debug("Memory allocated to Streaming is %zuMB", ms_memoryAvailable/MB); // original modifier was %d
+#endif
#undef MB
+#endif
// find island LODs
@@ -219,36 +233,54 @@ void
CStreaming::Init(void)
{
#ifdef USE_TXD_CDIMAGE
- int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r");
- if (txdHandle)
- CFileMgr::CloseFile(txdHandle);
- if (!CheckVideoCardCaps() && txdHandle) {
- CdStreamAddImage("MODELS\\TXD.IMG");
- CStreaming::Init2();
- } else {
- CStreaming::Init2();
- if (CreateTxdImageForVideoCard()) {
- CStreaming::Shutdown();
+ if(!CanVideoCardDoDXT()){
+ int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r");
+ if (txdHandle)
+ CFileMgr::CloseFile(txdHandle);
+ if (!CheckVideoCardCaps() && txdHandle) {
CdStreamAddImage("MODELS\\TXD.IMG");
CStreaming::Init2();
+ } else {
+ CStreaming::Init2();
+ if (CreateTxdImageForVideoCard()) {
+ CStreaming::Shutdown();
+ CdStreamAddImage("MODELS\\TXD.IMG");
+ CStreaming::Init2();
+ }
}
- }
+ } else
+ CStreaming::Init2();
#else
CStreaming::Init2();
#endif
}
-//--MIAMI: done
+void
+CStreaming::ReInit(void)
+{
+ int i;
+ CStreaming::FlushRequestList();
+ CStreaming::DeleteAllRwObjects();
+ CStreaming::RemoveAllUnusedModels();
+ for(i = 0; i < MODELINFOSIZE; i++)
+ if(CModelInfo::GetModelInfo(i) && ms_aInfoForModel[i].m_flags & STREAMFLAGS_SCRIPTOWNED)
+ SetMissionDoesntRequireModel(i);
+ CStreaming::ms_disableStreaming = false;
+}
+
void
CStreaming::Shutdown(void)
{
RwFreeAlign(ms_pStreamingBuffer[0]);
ms_streamingBufferSize = 0;
- if(ms_pExtraObjectsDir)
+ if(ms_pExtraObjectsDir) {
delete ms_pExtraObjectsDir;
+#ifdef FIX_BUGS
+ ms_pExtraObjectsDir = nil;
+#endif
+ }
}
-//--MIAMI: done
void
CStreaming::Update(void)
{
@@ -267,7 +299,7 @@ CStreaming::Update(void)
LoadBigBuildingsWhenNeeded();
if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f)
- AddModelsToRequestList(TheCamera.GetPosition());
+ AddModelsToRequestList(TheCamera.GetPosition(), 0);
DeleteFarAwayRwObjects(TheCamera.GetPosition());
@@ -299,7 +331,6 @@ CStreaming::Update(void)
}
}
-//--MIAMI: done
void
CStreaming::LoadCdDirectory(void)
{
@@ -328,7 +359,6 @@ CStreaming::LoadCdDirectory(void)
ms_imageSize /= CDSTREAM_SECTOR_SIZE;
}
-//--MIAMI: done
void
CStreaming::LoadCdDirectory(const char *dirname, int n)
{
@@ -426,7 +456,6 @@ GetObjectName(int streamId)
}
-//--MIAMI: done
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
{
@@ -577,7 +606,6 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return true;
}
-//--MIAMI: done
bool
CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
{
@@ -640,7 +668,6 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
return true;
}
-//--MIAMI: done
void
CStreaming::RequestModel(int32 id, int32 flags)
{
@@ -696,7 +723,6 @@ CStreaming::RequestModel(int32 id, int32 flags)
#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
-//--MIAMI: done
void
CStreaming::RequestBigBuildings(eLevelName level)
{
@@ -713,7 +739,6 @@ CStreaming::RequestBigBuildings(eLevelName level)
RequestIslands(level);
}
-//--MIAMI: done
void
CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
{
@@ -737,7 +762,6 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
RequestIslands(level);
}
-//--MIAMI: done
void
CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
{
@@ -754,7 +778,6 @@ CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
}
}
-//--MIAMI: done
void
CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list)
{
@@ -767,7 +790,6 @@ CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list)
}
}
-//--MIAMI: done
void
CStreaming::InstanceLoadedModels(const CVector &pos)
{
@@ -795,7 +817,6 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
}
}
-//--MIAMI: done
void
CStreaming::RequestIslands(eLevelName level)
{
@@ -814,7 +835,56 @@ CStreaming::RequestIslands(eLevelName level)
#endif
}
-//--MIAMI: TODO
+static char *IGnames[] = {
+ "player",
+ "player2",
+ "player3",
+ "player4",
+ "player5",
+ "player6",
+ "player7",
+ "player8",
+ "player9",
+ "play10",
+ "play11",
+ "igken",
+ "igcandy",
+ "igsonny",
+ "igbuddy",
+ "igjezz",
+ "ighlary",
+ "igphil",
+ "igmerc",
+ "igdick",
+ "igdiaz",
+ ""
+};
+
+static char *CSnames[] = {
+ "csplay",
+ "csplay2",
+ "csplay3",
+ "csplay4",
+ "csplay5",
+ "csplay6",
+ "csplay7",
+ "csplay8",
+ "csplay9",
+ "csplay10",
+ "csplay11",
+ "csken",
+ "cscandy",
+ "cssonny",
+ "csbuddy",
+ "csjezz",
+ "cshlary",
+ "csphil",
+ "csmerc",
+ "csdick",
+ "csdiaz",
+ ""
+};
+
void
CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags)
{
@@ -822,14 +892,43 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
int txdId;
char oldName[48];
uint32 pos, size;
+ int i, n;
mi = CModelInfo::GetModelInfo(modelId);
+ if(!CGeneral::faststrcmp("CSPlay", modelName)){
+ char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetName();
+ for(int i = 0; CSnames[i][0]; i++){
+ if(strcasecmp(curname, IGnames[i]) == 0){
+ modelName = CSnames[i];
+ break;
+ }
+ }
+ }
if(!CGeneral::faststrcmp(mi->GetName(), modelName)){
// Already have the correct name, just request it
RequestModel(modelId, flags);
return;
}
+ if(mi->GetNumRefs() > 0){
+ n = CPools::GetPedPool()->GetSize()-1;
+ for(i = n; i >= 0 && mi->GetNumRefs() > 0; i--){
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+ if(ped && ped->GetModelIndex() == modelId &&
+ !ped->IsPlayer() && ped->CanBeDeletedEvenInVehicle())
+ CTheScripts::RemoveThisPed(ped);
+ }
+ n = CPools::GetObjectPool()->GetSize()-1;
+ for(i = n; i >= 0 && mi->GetNumRefs() > 0; i--){
+ CObject *obj = CPools::GetObjectPool()->GetSlot(i);
+ if(obj && obj->GetModelIndex() == modelId && obj->CanBeDeleted()){
+ CWorld::Remove(obj);
+ CWorld::RemoveReferencesToDeletedObject(obj);
+ delete obj;
+ }
+ }
+ }
+
strcpy(oldName, mi->GetName());
mi->SetName(modelName);
@@ -856,28 +955,24 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
RequestModel(modelId, flags);
}
-//--MIAMI: done
void
CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags)
{
RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags);
}
-//--MIAMI: done
bool
CStreaming::HasSpecialCharLoaded(int32 id)
{
return HasModelLoaded(id + MI_SPECIAL01);
}
-//--MIAMI: done
void
CStreaming::SetMissionDoesntRequireSpecialChar(int32 id)
{
return SetMissionDoesntRequireModel(id + MI_SPECIAL01);
}
-//--MIAMI: done
void
CStreaming::DecrementRef(int32 id)
{
@@ -888,7 +983,6 @@ CStreaming::DecrementRef(int32 id)
}
}
-//--MIAMI: done
void
CStreaming::RemoveModel(int32 id)
{
@@ -941,7 +1035,6 @@ CStreaming::RemoveModel(int32 id)
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
}
-//--MIAMI: done
void
CStreaming::RemoveUnusedBuildings(eLevelName level)
{
@@ -951,7 +1044,6 @@ CStreaming::RemoveUnusedBuildings(eLevelName level)
RemoveBuildings(LEVEL_MAINLAND);
}
-//--MIAMI: done
void
CStreaming::RemoveBuildings(eLevelName level)
{
@@ -1012,7 +1104,61 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
-//--MIAMI: done
+void
+CStreaming::RemoveBuildingsNotInArea(int32 area)
+{
+ int i, n;
+ CEntity *e;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetBuildingPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetTreadablePool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetTreadablePool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetObjectPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetObjectPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetDummyPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetDummyPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+}
+
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
@@ -1025,7 +1171,6 @@ CStreaming::RemoveUnusedBigBuildings(eLevelName level)
RemoveIslandsNotUsed(level);
}
-//--MIAMI: done
void
DeleteIsland(CEntity *island)
{
@@ -1039,7 +1184,6 @@ DeleteIsland(CEntity *island)
}
}
-//--MIAMI: done
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
@@ -1068,7 +1212,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
#endif // !NO_ISLAND_LOADING
}
-//--MIAMI: done
void
CStreaming::RemoveBigBuildings(eLevelName level)
{
@@ -1115,7 +1258,6 @@ found:
return true;
}
-//--MIAMI: done
bool
CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
{
@@ -1149,7 +1291,6 @@ CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle();
}
-//--MIAMI: done
void
CStreaming::RemoveAllUnusedModels(void)
{
@@ -1167,14 +1308,35 @@ CStreaming::RemoveAllUnusedModels(void)
}
}
-//--MIAMI: done
void
CStreaming::RemoveUnusedModelsInLoadedList(void)
{
// empty
}
-//--MIAMI: done
+bool
+CStreaming::RemoveLoadedZoneModel(void)
+{
+ int i;
+
+ if(ms_currentPedGrp == -1)
+ return false;
+
+ for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
+ int mi = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i];
+ if(mi != -1 && ms_bIsPedFromPedGroupLoaded[i] &&
+ HasModelLoaded(mi) && CanRemoveModel(mi) &&
+ CModelInfo::GetModelInfo(mi)->GetNumRefs() == 0){
+ RemoveModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ ms_numPedsLoaded--;
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool
CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
{
@@ -1277,7 +1439,7 @@ found:
if(id == -1)
return false; // still no luck
ms_lastVehicleDeleted = id;
- // this is more that we wanted actually
+ // this is more than we wanted actually
ms_numVehiclesLoaded++;
}
else{
@@ -1308,7 +1470,7 @@ void
CStreaming::SetModelIsDeletable(int32 id)
{
ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE;
- if ((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) &&
+ if ((id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) &&
(ms_aInfoForModel[id].m_flags & STREAMFLAGS_SCRIPTOWNED) == 0){
if(ms_aInfoForModel[id].m_loadState != STREAMSTATE_LOADED)
RemoveModel(id);
@@ -1323,7 +1485,6 @@ CStreaming::SetModelTxdIsDeletable(int32 id)
SetModelIsDeletable(CModelInfo::GetModelInfo(id)->GetTxdSlot() + STREAM_OFFSET_TXD);
}
-//--MIAMI: done
void
CStreaming::SetMissionDoesntRequireModel(int32 id)
{
@@ -1355,15 +1516,10 @@ CStreaming::LoadInitialWeapons(void)
void
CStreaming::LoadInitialVehicles(void)
{
- int id;
-
ms_numVehiclesLoaded = 0;
ms_lastVehicleDeleted = 0;
- if(CModelInfo::GetModelInfo("taxi", &id))
- RequestModel(id, STREAMFLAGS_DONT_REMOVE);
- if(CModelInfo::GetModelInfo("police", &id))
- RequestModel(id, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_POLICE, STREAMFLAGS_DONT_REMOVE);
}
void
@@ -1424,25 +1580,26 @@ CStreaming::StreamVehiclesAndPeds(void)
SetModelIsDeletable(MI_VICE6);
SetModelIsDeletable(MI_VICE7);
SetModelIsDeletable(MI_VICE8);
- switch (CCarCtrl::MiamiViceCycle) {
- case 0:
- RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE);
- break;
- case 1:
- RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE);
- break;
- case 2:
- RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE);
- break;
- case 3:
- RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE);
- break;
- }
RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE);
+ if(CPopulation::NumMiamiViceCops == 0)
+ switch (CCarCtrl::MiamiViceCycle) {
+ case 0:
+ RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 1:
+ RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 2:
+ RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 3:
+ RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE);
+ break;
+ }
}
else {
SetModelIsDeletable(MI_VICECHEE);
@@ -1481,13 +1638,13 @@ CStreaming::StreamVehiclesAndPeds(void)
}
}
-//--MIAMI: TODO
void
CStreaming::StreamZoneModels(const CVector &pos)
{
- int i;
+ int i, j;
uint16 gangsToLoad, gangCarsToLoad, bit;
CZoneInfo info;
+ static int timeBeforeNextLoad = 0;
CTheZones::GetZoneInfoForTimeOfDay(&pos, &info);
@@ -1496,22 +1653,64 @@ CStreaming::StreamZoneModels(const CVector &pos)
// unload pevious group
if(ms_currentPedGrp != -1)
for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
- if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
- break;
- SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
- SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1){
+ SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ }
}
ms_currentPedGrp = info.pedGroup;
- for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
- if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
- break;
- RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DEPENDENCY);
+ for(i = 0; i < MAXZONEPEDSLOADED; i++){
+ do
+ j = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ while(ms_bIsPedFromPedGroupLoaded[j]);
+ ms_bIsPedFromPedGroupLoaded[j] = true;
+ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j] != -1)
+ RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j], STREAMFLAGS_DEPENDENCY);
+ }
+ ms_numPedsLoaded = MAXZONEPEDSLOADED;
+ timeBeforeNextLoad = 300;
+ }
+
+ if(timeBeforeNextLoad >= 0)
+ timeBeforeNextLoad--;
+ else{
+ // Switch a ped
+ int oldMI;
+ // Find a ped to unload
+ for(i = 0; i < NUMMODELSPERPEDGROUP; i++)
+ if(ms_bIsPedFromPedGroupLoaded[i]){
+ oldMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i];
+ if(oldMI != -1 && CModelInfo::GetModelInfo(oldMI)->GetNumRefs() == 0)
+ break;
+ }
+ // And load a new one
+ if(i != NUMMODELSPERPEDGROUP || ms_numPedsLoaded < MAXZONEPEDSLOADED){
+ do
+ j = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ while(ms_bIsPedFromPedGroupLoaded[j]);
+ if(ms_numPedsLoaded == MAXZONEPEDSLOADED)
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ ms_bIsPedFromPedGroupLoaded[j] = true;
+ int newMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j];
+ if(newMI != oldMI){
+ RequestModel(newMI, STREAMFLAGS_DEPENDENCY);
+ debug("Request Ped %s\n", CModelInfo::GetModelInfo(newMI)->GetName());
+ if(ms_numPedsLoaded == MAXZONEPEDSLOADED){
+ SetModelIsDeletable(oldMI);
+ SetModelTxdIsDeletable(oldMI);
+ debug("Remove Ped %s\n", CModelInfo::GetModelInfo(oldMI)->GetName());
+ }else
+ ms_numPedsLoaded++;
+ timeBeforeNextLoad = 300;
+ }
}
}
+
RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE);
- //RequestModel(MI_HMOCA, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_TAXI_D, STREAMFLAGS_DONT_REMOVE);
gangsToLoad = 0;
gangCarsToLoad = 0;
@@ -1529,35 +1728,35 @@ CStreaming::StreamZoneModels(const CVector &pos)
if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars)
return;
- gangsToLoad |= gangCarsToLoad;
-
- for(i = 0; i < NUM_GANGS; i++){
- bit = 1<<i;
-
- if(gangsToLoad & bit && (ms_loadedGangs & bit) == 0){
- RequestModel(CGangs::GetGangPedModel1(i), STREAMFLAGS_DEPENDENCY);
- RequestModel(CGangs::GetGangPedModel2(i), STREAMFLAGS_DEPENDENCY);
- ms_loadedGangs |= bit;
- }else if((gangsToLoad & bit) == 0 && ms_loadedGangs & bit){
- SetModelIsDeletable(CGangs::GetGangPedModel1(i));
- SetModelIsDeletable(CGangs::GetGangPedModel2(i));
- SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i));
- SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i));
- ms_loadedGangs &= ~bit;
- }
-
- // TODO(MIAMI): check this
- if(CGangs::GetGangVehicleModel(i) < 0)
- continue;
+ int gangModelsToload = gangsToLoad | gangCarsToLoad;
+
+ if(gangsToLoad != ms_loadedGangs || gangCarsToLoad != ms_loadedGangCars){
+ for(i = 0; i < NUM_GANGS; i++){
+ bit = 1<<i;
+
+ if(gangModelsToload & bit && (ms_loadedGangs & bit) == 0){
+ RequestModel(CGangs::GetGangPedModel1(i), STREAMFLAGS_DEPENDENCY);
+ RequestModel(CGangs::GetGangPedModel2(i), STREAMFLAGS_DEPENDENCY);
+ ms_loadedGangs |= bit;
+ }else if((gangModelsToload & bit) == 0 && ms_loadedGangs & bit){
+ SetModelIsDeletable(CGangs::GetGangPedModel1(i));
+ SetModelIsDeletable(CGangs::GetGangPedModel2(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i));
+ ms_loadedGangs &= ~bit;
+ }
- if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){
- RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY);
- }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){
- SetModelIsDeletable(CGangs::GetGangVehicleModel(i));
- SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i));
+ if(CGangs::GetGangVehicleModel(i) != -1){
+ if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){
+ RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY);
+ }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){
+ SetModelIsDeletable(CGangs::GetGangVehicleModel(i));
+ SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i));
+ }
+ }
}
+ ms_loadedGangCars = gangCarsToLoad;
}
- ms_loadedGangCars = gangCarsToLoad;
}
void
@@ -1567,9 +1766,9 @@ CStreaming::RemoveCurrentZonesModels(void)
if (ms_currentPedGrp != -1)
for (i = 0; i < NUMMODELSPERPEDGROUP; i++) {
- if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
- break;
- if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1 &&
+ CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
}
@@ -1616,7 +1815,6 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
CCollision::LoadCollisionScreen(CGame::currLevel);
DMAudio.Service();
- // CPopulation::DealWithZoneChange is unused in VC
RemoveUnusedBigBuildings(CGame::currLevel);
RemoveUnusedBuildings(CGame::currLevel);
RemoveUnusedModelsInLoadedList();
@@ -1627,7 +1825,7 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
- CStreaming::LoadAllRequestedModels(true);
+ CStreaming::LoadAllRequestedModels(false);
CGame::TidyUpMemory(true, true);
CTimer::Resume();
@@ -1757,11 +1955,8 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
* Files larger than the buffer size can only be loaded by channel 0,
* which then uses both buffers, while channel 1 is idle.
* ms_bLoadingBigModel is set to true to indicate this state.
- *
- * TODO: two-part files
*/
-//--MIAMI: done
// Make channel read from disc
void
CStreaming::RequestModelStream(int32 ch)
@@ -1872,7 +2067,6 @@ CStreaming::RequestModelStream(int32 ch)
ms_channel[ch].numTries = 0;
}
-//--MIAMI: done
// Load data previously read from disc
bool
CStreaming::ProcessLoadingChannel(int32 ch)
@@ -1942,7 +2136,6 @@ CStreaming::ProcessLoadingChannel(int32 ch)
return true;
}
-//--MIAMI: done
void
CStreaming::RetryLoadFile(int32 ch)
{
@@ -1979,7 +2172,6 @@ CStreaming::RetryLoadFile(int32 ch)
}
}
-//--MIAMI: done
void
CStreaming::LoadRequestedModels(void)
{
@@ -2004,7 +2196,6 @@ CStreaming::LoadRequestedModels(void)
}
}
-//--MIAMI: done
void
CStreaming::LoadAllRequestedModels(bool priority)
{
@@ -2013,18 +2204,26 @@ CStreaming::LoadAllRequestedModels(bool priority)
int i;
uint32 posn, size;
+ int numRequests = 4*ms_numModelsRequested;
+
if(bInsideLoadAll)
return;
+ bInsideLoadAll = true;
+
+ if(priority)
+ numRequests = ms_numPriorityRequests;
FlushChannels();
imgOffset = GetCdImageOffset(CdStreamGetLastPosn());
- while(ms_endRequestedList.m_prev != &ms_startRequestedList){
+ while(ms_endRequestedList.m_prev != &ms_startRequestedList && numRequests > 0){
+ numRequests--;
streamId = GetNextFileOnCd(0, priority);
if(streamId == -1)
break;
ms_aInfoForModel[streamId].RemoveFromList();
+ ms_channel[0].streamIds[0] = streamId;
DecrementRef(streamId);
if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){
@@ -2058,7 +2257,6 @@ CStreaming::LoadAllRequestedModels(bool priority)
bInsideLoadAll = false;
}
-//--MIAMI: done
void
CStreaming::FlushChannels(void)
{
@@ -2080,7 +2278,6 @@ CStreaming::FlushChannels(void)
ProcessLoadingChannel(1);
}
-//--MIAMI: done
void
CStreaming::FlushRequestList(void)
{
@@ -2112,10 +2309,10 @@ CStreaming::UpdateMemoryUsed(void)
// empty
}
-#define STREAM_DIST (2*SECTOR_SIZE_X)
+#define STREAM_DIST 80.0f
void
-CStreaming::AddModelsToRequestList(const CVector &pos)
+CStreaming::AddModelsToRequestList(const CVector &pos, int32 flags)
{
float xmin, xmax, ymin, ymax;
int ixmin, ixmax, iymin, iymax;
@@ -2149,23 +2346,23 @@ CStreaming::AddModelsToRequestList(const CVector &pos)
dx = ix - CWorld::GetSectorIndexX(pos.x);
d = dx*dx + dy*dy;
sect = CWorld::GetSector(ix, iy);
- if(d <= 1){
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES]);
- }else if(d <= 4*4){
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], pos.x, pos.y, xmin, ymin, xmax, ymax);
+ if(d <= 0){
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], flags);
+ }else if(d <= 3*3){
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
}
}
}
}
void
-CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax)
+CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax, int32 flags)
{
CPtrNode *node;
CEntity *e;
@@ -2179,8 +2376,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
continue;
e->m_scanCode = CWorld::GetCurrentScanCode();
- if(!e->bStreamingDontDelete && !e->bIsSubway &&
- (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
+ if(!e->bStreamingDontDelete && IsAreaVisible(e->m_area) && !e->bDontStream && e->bIsVisible){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) {
lodDistSq = sq(mi->GetLargestLodDistance());
@@ -2189,14 +2385,14 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
if(xmin < pos.x && pos.x < xmax &&
ymin < pos.y && pos.y < ymax &&
(CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq)
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), flags);
}
}
}
}
void
-CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
+CStreaming::ProcessEntitiesInSectorList(CPtrList &list, int32 flags)
{
CPtrNode *node;
CEntity *e;
@@ -2208,11 +2404,10 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
continue;
e->m_scanCode = CWorld::GetCurrentScanCode();
- if(!e->bStreamingDontDelete && !e->bIsSubway &&
- (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
+ if(!e->bStreamingDontDelete && IsAreaVisible(e->m_area) && !e->bDontStream && e->bIsVisible){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), flags);
}
}
}
@@ -2407,7 +2602,7 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
assert(ymin <= ymax);
// Delete a block of sectors that we know is behind the camera
- if(TheCamera.GetForward().x > 0){
+ if(TheCamera.GetForward().x > 0.0f){
// looking east
xmax = Max(ix - 2, 0);
xmin = Max(ix - 10, 0);
@@ -2428,8 +2623,13 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
+
+ while(RemoveLoadedZoneModel())
+ if(ms_memoryUsed < mem)
+ return;
+
// Now a block that intersects with the camera's frustum
- if(TheCamera.GetForward().x > 0){
+ if(TheCamera.GetForward().x > 0.0f){
// looking east
xmax = Max(ix + 10, 0);
xmin = Max(ix - 2, 0);
@@ -2468,7 +2668,7 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
assert(xmin <= xmax);
// Delete a block of sectors that we know is behind the camera
- if(TheCamera.GetForward().y > 0){
+ if(TheCamera.GetForward().y > 0.0f){
// looking north
ymax = Max(iy - 2, 0);
ymin = Max(iy - 10, 0);
@@ -2489,8 +2689,12 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
+ while(RemoveLoadedZoneModel())
+ if(ms_memoryUsed < mem)
+ return;
+
// Now a block that intersects with the camera's frustum
- if(TheCamera.GetForward().y > 0){
+ if(TheCamera.GetForward().y > 0.0f){
// looking north
ymax = Max(iy + 10, 0);
ymin = Max(iy - 2, 0);
@@ -2511,6 +2715,10 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
+// this is gone in mobile together with RemoveReferencedTxds
+// if(RemoveReferencedTxds(mem))
+// return;
+
// As last resort, delete objects from the last step more aggressively
for(x = xmin; x <= xmax; x++){
for(y = ymax; y != ymin; y -= inc){
@@ -2522,6 +2730,8 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
}
+
+ while(ms_memoryUsed >= mem && RemoveLeastUsedModel(0));
}
void
@@ -2547,13 +2757,13 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y)
e = (CEntity*)node->item;
if(e->m_rwObject && !e->bStreamingDontDelete && !e->bImBeingRendered){
// Now this is pretty weird...
- if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f)
+ if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 1.6f)
// {
e->DeleteRwObject();
// return; // BUG?
// }
else // FIX?
- if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f)
+ if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 1.6f)
e->DeleteRwObject();
}
}
@@ -2568,7 +2778,8 @@ CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(!e->bStreamingDontDelete && !e->bImBeingRendered &&
- e->m_rwObject && ms_aInfoForModel[e->GetModelIndex()].m_next){
+ e->m_rwObject && ms_aInfoForModel[e->GetModelIndex()].m_next &&
+ FindPlayerPed()->m_pCurSurface != e){
e->DeleteRwObject();
if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) {
RemoveModel(e->GetModelIndex());
@@ -2589,7 +2800,7 @@ CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(!e->bStreamingDontDelete && !e->bImBeingRendered &&
- e->m_rwObject && !e->IsVisible() && ms_aInfoForModel[e->GetModelIndex()].m_next){
+ e->m_rwObject && (!e->IsVisible() || e->bOffscreen) && ms_aInfoForModel[e->GetModelIndex()].m_next){
e->DeleteRwObject();
if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) {
RemoveModel(e->GetModelIndex());
@@ -2615,7 +2826,6 @@ CStreaming::MakeSpaceFor(int32 size)
}
}
-//--MIAMI: done
void
CStreaming::LoadScene(const CVector &pos)
{
@@ -2641,7 +2851,7 @@ CStreaming::LoadScene(const CVector &pos)
LoadAllRequestedModels(false);
InstanceBigBuildings(level, pos);
InstanceBigBuildings(LEVEL_GENERIC, pos);
- AddModelsToRequestList(pos);
+ AddModelsToRequestList(pos, STREAMFLAGS_20);
CRadar::StreamRadarSections(pos);
if (!CGame::IsInInterior()) {
@@ -2660,7 +2870,6 @@ CStreaming::LoadScene(const CVector &pos)
debug("End load scene\n");
}
-//--MIAMI: done
void
CStreaming::LoadSceneCollision(const CVector &pos)
{
@@ -2697,7 +2906,7 @@ void
CStreaming::UpdateForAnimViewer(void)
{
if (CStreaming::ms_channelError == -1) {
- CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f));
+ CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f), 0);
CStreaming::LoadRequestedModels();
// original modifier was %d
sprintf(gString, "Requested %d, memory size %zuK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 569c06d8..dd85ce97 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -93,6 +93,7 @@ public:
static CStreamingChannel ms_channel[2];
static int32 ms_channelError;
static int32 ms_numVehiclesLoaded;
+ static int32 ms_numPedsLoaded;
static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED];
static int32 ms_lastVehicleDeleted;
static bool ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
@@ -110,6 +111,7 @@ public:
static void Init(void);
static void Init2(void);
+ static void ReInit(void);
static void Shutdown(void);
static void Update(void);
static void LoadCdDirectory(void);
@@ -149,6 +151,7 @@ public:
static void RemoveAnim(int32 id) { RemoveModel(id + STREAM_OFFSET_ANIM); }
static void RemoveUnusedBuildings(eLevelName level);
static void RemoveBuildings(eLevelName level);
+ static void RemoveBuildingsNotInArea(int32 area);
static void RemoveUnusedBigBuildings(eLevelName level);
static void RemoveIslandsNotUsed(eLevelName level);
static void RemoveBigBuildings(eLevelName level);
@@ -156,6 +159,7 @@ public:
static bool RemoveLeastUsedModel(uint32 excludeMask);
static void RemoveAllUnusedModels(void);
static void RemoveUnusedModelsInLoadedList(void);
+ static bool RemoveLoadedZoneModel(void);
static int32 GetAvailableVehicleSlot(void);
static bool IsTxdUsedByRequestedModels(int32 txdId);
static bool AreAnimsUsedByRequestedModels(int32 animId);
@@ -187,9 +191,9 @@ public:
static void IHaveUsedStreamingMemory(void);
static void UpdateMemoryUsed(void);
- static void AddModelsToRequestList(const CVector &pos);
- static void ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax);
- static void ProcessEntitiesInSectorList(CPtrList &list);
+ static void AddModelsToRequestList(const CVector &pos, int32 flags);
+ static void ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax, int32 flags);
+ static void ProcessEntitiesInSectorList(CPtrList &list, int32 flags);
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp
index 9076a9a6..56cea203 100644
--- a/src/core/SurfaceTable.cpp
+++ b/src/core/SurfaceTable.cpp
@@ -6,6 +6,8 @@
#include "Collision.h"
#include "SurfaceTable.h"
+//--MIAMI: file done
+
float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
void
@@ -148,3 +150,9 @@ CSurfaceTable::GetAdhesiveLimit(CColPoint &colpoint)
{
return ms_aAdhesiveLimitTable[GetAdhesionGroup(colpoint.surfaceB)][GetAdhesionGroup(colpoint.surfaceA)];
}
+
+bool
+CSurfaceTable::IsSoftLanding(uint8 surf)
+{
+ return surf == SURFACE_GRASS || surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH;
+}
diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h
index 359ebd5c..cd08c843 100644
--- a/src/core/SurfaceTable.h
+++ b/src/core/SurfaceTable.h
@@ -96,4 +96,5 @@ public:
static int GetAdhesionGroup(uint8 surfaceType);
static float GetWetMultiplier(uint8 surfaceType);
static float GetAdhesiveLimit(CColPoint &colpoint);
+ static bool IsSoftLanding(uint8 surf);
};
diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp
index c70a3ab5..f5ea6e53 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -10,6 +10,7 @@
#include "CopPed.h"
#include "Wanted.h"
#include "General.h"
+#include "Stats.h"
int32 CWanted::MaximumWantedLevel = 6;
int32 CWanted::nMaximumWantedLevel = 9600;
@@ -308,7 +309,6 @@ CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesnt
UpdateWantedLevel();
}
-// TODO(Miami): Stats
void
CWanted::UpdateWantedLevel()
{
@@ -318,36 +318,44 @@ CWanted::UpdateWantedLevel()
m_nChaos = nMaximumWantedLevel;
if (m_nChaos >= 0 && m_nChaos < 50) {
+ if (m_nWantedLevel == 1)
+ ++CStats::WantedStarsEvaded;
m_nWantedLevel = 0;
m_MaximumLawEnforcerVehicles = 0;
m_MaxCops = 0;
m_RoadblockDensity = 0;
} else if (m_nChaos >= 50 && m_nChaos < 180) {
+ CStats::WantedStarsAttained += 1 - m_nWantedLevel;
m_nWantedLevel = 1;
m_MaximumLawEnforcerVehicles = 1;
m_MaxCops = 1;
m_RoadblockDensity = 0;
} else if (m_nChaos >= 180 && m_nChaos < 550) {
+ CStats::WantedStarsAttained += 2 - m_nWantedLevel;
m_nWantedLevel = 2;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 3;
m_RoadblockDensity = 0;
} else if (m_nChaos >= 550 && m_nChaos < 1200) {
+ CStats::WantedStarsAttained += 3 - m_nWantedLevel;
m_nWantedLevel = 3;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 4;
m_RoadblockDensity = 12;
} else if (m_nChaos >= 1200 && m_nChaos < 2400) {
+ CStats::WantedStarsAttained += 4 - m_nWantedLevel;
m_nWantedLevel = 4;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 6;
m_RoadblockDensity = 18;
} else if (m_nChaos >= 2400 && m_nChaos < 4800) {
+ CStats::WantedStarsAttained += 5 - m_nWantedLevel;
m_nWantedLevel = 5;
m_MaximumLawEnforcerVehicles = 3;
m_MaxCops = 8;
m_RoadblockDensity = 24;
} else if (m_nChaos >= 4800) {
+ CStats::WantedStarsAttained += 6 - m_nWantedLevel;
m_nWantedLevel = 6;
m_MaximumLawEnforcerVehicles = 3;
m_MaxCops = 10;
@@ -494,8 +502,7 @@ CWanted::UpdateCrimesQ(void)
void
CWanted::Suspend(void)
{
- // TODO(Miami): Stats
- // dwStarsEvaded += m_nWantedLevel;
+ CStats::WantedStarsEvaded += m_nWantedLevel;
m_nMinChaos = m_nChaos;
m_nMinWantedLevel = m_nWantedLevel;
m_nLastTimeSuspended = CTimer::GetTimeInMilliseconds();
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index 729cc35d..69c7a796 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -11,6 +11,8 @@
#include "ZoneCull.h"
#include "Zones.h"
+//--MIAMI: done
+
int32 CCullZones::NumAttributeZones;
CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES];
@@ -18,6 +20,7 @@ int32 CCullZones::CurrentWantedLevelDrop_Player;
int32 CCullZones::CurrentFlags_Camera;
int32 CCullZones::CurrentFlags_Player;
bool CCullZones::bCurrentSubwayIsInvisible;
+bool CCullZones::bAtBeachForAudio;
void
CCullZones::Init(void)
@@ -37,6 +40,7 @@ CCullZones::Update(void)
switch(CTimer::GetFrameCounter() & 7){
case 0:
case 4:
+ UpdateAtBeachForAudio();
break;
case 2:
@@ -57,6 +61,27 @@ CCullZones::Update(void)
}
}
+// TODO? put somewhere else?
+bool
+IsPointWithinArbitraryArea(float px, float py, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
+{
+ if((px-x1)*(x2-x1) - (py-y1)*(y2-y1) < 0.0f) return false;
+ if((px-x2)*(x3-x2) - (py-y2)*(y3-y2) < 0.0f) return false;
+ if((px-x3)*(x4-x3) - (py-y3)*(y4-y3) < 0.0f) return false;
+ if((px-x4)*(x1-x4) - (py-y4)*(y1-y4) < 0.0f) return false;
+ return true;
+}
+
+void
+CCullZones::UpdateAtBeachForAudio(void)
+{
+ bAtBeachForAudio = IsPointWithinArbitraryArea(TheCamera.GetPosition().x, TheCamera.GetPosition().y,
+ 400.0f, -1644.4f,
+ 751.9f, 1267.8f,
+ 971.9f, 1216.2f,
+ 840.0f, -1744.0f);
+}
+
void
CCullZones::ForceCullZoneCoors(CVector coors)
{
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index aae06ca0..8200b09a 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -10,8 +10,9 @@ enum eZoneAttribs
ATTRZONE_NOTCULLZONE = 0x20,
ATTRZONE_DOINEEDCOLLISION = 0x40,
ATTRZONE_SUBWAYVISIBLE = 0x80,
-
- ATTRZONE_WATERFUDGE = 0x400,
+ ATTRZONE_POLICEABANDONCARS = 0x100,
+ ATTRZONE_ROOMFORAUDIO = 0x200,
+ ATTRZONE_WATERFUDGE = 0x400,
};
struct CAttributeZone
@@ -36,9 +37,11 @@ public:
static int32 CurrentFlags_Camera;
static int32 CurrentFlags_Player;
static bool bCurrentSubwayIsInvisible;
+ static bool bAtBeachForAudio;
static void Init(void);
static void Update(void);
+ static void UpdateAtBeachForAudio(void);
static void ForceCullZoneCoors(CVector coors);
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
@@ -55,9 +58,8 @@ public:
static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; }
static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; }
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
+ static bool PoliceAbandonCars(void) { return (CurrentFlags_Camera & ATTRZONE_POLICEABANDONCARS) != 0; }
+ static bool InRoomForAudio(void) { return (CurrentFlags_Camera & ATTRZONE_ROOMFORAUDIO) != 0; }
static bool WaterFudge(void) { return (CurrentFlags_Camera & ATTRZONE_WATERFUDGE) != 0; }
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
-
- //--MIAMI: TODO
- static bool PoliceAbandonCars(void) { return false; }
};
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 96f5dc62..a255fb7d 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -9,6 +9,8 @@
#include "World.h"
#include "Timer.h"
+//--MIAMI: file almost done (loading/saving will perhaps stay different)
+
eLevelName CTheZones::m_CurrLevel;
int16 CTheZones::FindIndex;
@@ -26,14 +28,12 @@ CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES];
#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
-//--MIAMI: done
wchar*
CZone::GetTranslatedName(void)
{
return TheText.Get(name);
}
-//--MIAMI: done
void
CTheZones::Init(void)
{
@@ -124,7 +124,6 @@ CTheZones::Init(void)
MapZoneArray[0].level = LEVEL_GENERIC;
}
-//--MIAMI: done
void
CTheZones::Update(void)
{
@@ -137,7 +136,6 @@ CTheZones::Update(void)
m_CurrLevel = GetLevelFromPosition(&pos);
}
-//--MIAMI: done
void
CTheZones::CreateZone(char *name, eZoneType type,
float minx, float miny, float minz,
@@ -204,7 +202,6 @@ CTheZones::CreateZone(char *name, eZoneType type,
}
}
-//--MIAMI: done
void
CTheZones::PostZoneCreation(void)
{
@@ -214,7 +211,6 @@ CTheZones::PostZoneCreation(void)
InitialiseAudioZoneArray();
}
-//--MIAMI: done, but does nothing
void
CTheZones::CheckZonesForOverlap(void)
{
@@ -231,7 +227,6 @@ CTheZones::CheckZonesForOverlap(void)
}
}
-//--MIAMI: done
void
CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
{
@@ -241,7 +236,6 @@ CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]);
}
-//--MIAMI: done
bool
CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
{
@@ -285,7 +279,6 @@ CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
return true;
}
-//--MIAMI: done
bool
CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
{
@@ -310,7 +303,6 @@ CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
return true;
}
-//--MIAMI: done
bool
CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
{
@@ -319,7 +311,6 @@ CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
zone->minz <= v->z && v->z <= zone->maxz;
}
-//--MIAMI: done
eLevelName
CTheZones::GetLevelFromPosition(CVector const *v)
{
@@ -333,7 +324,6 @@ CTheZones::GetLevelFromPosition(CVector const *v)
return MapZoneArray[0].level;
}
-//--MIAMI: done
CZone*
CTheZones::FindInformationZoneForPosition(const CVector *v)
{
@@ -347,7 +337,6 @@ CTheZones::FindInformationZoneForPosition(const CVector *v)
return &InfoZoneArray[0];
}
-//--MIAMI: done
CZone*
CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig)
{
@@ -370,7 +359,6 @@ CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefa
return best;
}
-//--MIAMI: done
int16
CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
@@ -400,7 +388,6 @@ CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type)
return -1;
}
-//--MIAMI: done
int16
CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
@@ -431,7 +418,6 @@ CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type)
return -1;
}
-//--MIAMI: done
CZoneInfo*
CTheZones::GetZoneInfo(const CVector *v, uint8 day)
{
@@ -556,7 +542,7 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
info->gangPedThreshold[8] = info->gangPedThreshold[7];
}
-//--MIAMI: done, unused
+//--MIAMI: unused
void
CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
{
@@ -565,7 +551,7 @@ CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
}
-//--MIAMI: done, unused
+//--MIAMI: unused
void
CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
{
@@ -574,7 +560,6 @@ CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
}
-//--MIAMI: done
void
CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
{
@@ -583,7 +568,6 @@ CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
}
-//--MIAMI: done
int16
CTheZones::FindAudioZone(CVector *pos)
{
@@ -595,7 +579,6 @@ CTheZones::FindAudioZone(CVector *pos)
return -1;
}
-//--MIAMI: done
void
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{
@@ -613,7 +596,6 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone)
AudioZoneArray[NumberOfAudioZones++] = z;
}
-//--MIAMI: done
void
CTheZones::InitialiseAudioZoneArray(void)
{
@@ -645,7 +627,6 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
-//--MIAMI: TODO
void
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
@@ -666,7 +647,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
WriteSaveBuf(buffer, FindIndex);
WriteSaveBuf(buffer, (int16)0); // padding
-// TODO(MIAMI): implement SaveOneZone
+// TODO(MIAMI) ? implement SaveOneZone
for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]);
zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child);
@@ -676,6 +657,14 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[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(InfoZoneArray[i].child == nil);
+ assert(InfoZoneArray[i].parent == nil);
+ assert(InfoZoneArray[i].next == nil);
zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next);
@@ -691,11 +680,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
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.
- */
+ // see above
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
@@ -713,7 +698,6 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
VALIDATESAVEBUF(*size)
}
-//--MIAMI: TODO
void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
@@ -726,7 +710,7 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
FindIndex = ReadSaveBuf<int16>(buffer);
ReadSaveBuf<int16>(buffer);
-// TODO(MIAMI): implement LoadOneZone
+// TODO(MIAMI) ? implement LoadOneZone
for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer);
@@ -738,6 +722,14 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
InfoZoneArray[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.
+ */
+ InfoZoneArray[i].child = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].child);
+ InfoZoneArray[i].parent = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].parent);
+ InfoZoneArray[i].next = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].next);
InfoZoneArray[i].child = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].child);
InfoZoneArray[i].parent = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].parent);
InfoZoneArray[i].next = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].next);
@@ -753,11 +745,7 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
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.
- */
+ // see above
MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 8d5af182..92e292b8 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -103,8 +103,8 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos);
- static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &InfoZoneArray[i]; }
- static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - InfoZoneArray; }
+ static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
+ static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length);
diff --git a/src/core/config.h b/src/core/config.h
index 469f9017..62c3fa73 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -27,16 +27,16 @@ enum Config {
// Pool sizes
NUMPTRNODES = 50000,
- NUMENTRYINFOS = 5400, // only 3200 in VC???
+ NUMENTRYINFOS = 3200,
NUMPEDS = 140,
NUMVEHICLES = 110,
NUMBUILDINGS = 7000,
- NUMTREADABLES = 1214, // 1 in VC
+ NUMTREADABLES = 1,
NUMOBJECTS = 460,
- NUMDUMMIES = 2802, // 2340 in VC
- NUMAUDIOSCRIPTOBJECTS = 256, // 192 in VC
+ NUMDUMMIES = 2340,
+ NUMAUDIOSCRIPTOBJECTS = 192,
+ NUMCOLMODELS = 4400,
NUMCUTSCENEOBJECTS = 50, // does not exist in VC
- // TODO(MIAMI): colmodel pool
NUMANIMBLOCKS = 35,
NUMANIMATIONS = 450,
@@ -113,6 +113,7 @@ enum Config {
NUMPHONES = 50,
NUMPEDGROUPS = 67,
NUMMODELSPERPEDGROUP = 16,
+ MAXZONEPEDSLOADED = 8,
NUMSHOTINFOS = 100,
NUMROADBLOCKS = 300,
@@ -224,7 +225,15 @@ enum Config {
//#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
//#define USE_TEXTURE_POOL
-#define CUTSCENE_BORDERS_SWITCH
+//#define CUTSCENE_BORDERS_SWITCH
+//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
+//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
+//#define MULTISAMPLING // adds MSAA option TODO
+
+#ifdef LIBRW
+// these are not supported with librw yet
+# undef MULTISAMPLING
+#endif
// Water & Particle
#define PC_PARTICLE
@@ -244,6 +253,7 @@ enum Config {
#define ALLCARSHELI_CHEAT
#define ALT_DODO_CHEAT
#define REGISTER_START_BUTTON
+//#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls
// Hud, frontend and radar
#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
@@ -254,12 +264,13 @@ enum Config {
#ifndef PC_MENU
# define PS2_MENU
//# define PS2_MENU_USEALLPAGEICONS
-#else
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
+#else
# define MAP_ENHANCEMENTS // Adding waypoint etc.
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
//#define CUSTOM_FRONTEND_OPTIONS
+# define GRAPHICS_MENU_OPTIONS
#define LEGACY_MENU_OPTIONS
#define MUCH_SHORTER_OUTRO_SCREEN
diff --git a/src/core/main.cpp b/src/core/main.cpp
index d4ef8c4b..0009048d 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -2,6 +2,10 @@
#include "rpmatfx.h"
#include "rphanim.h"
#include "rpskin.h"
+#include "rtbmp.h"
+#ifndef LIBRW
+#include "rpanisot.h"
+#endif
#include "main.h"
#include "CdStream.h"
@@ -61,8 +65,10 @@
#include "MemoryCard.h"
#include "SceneEdit.h"
#include "debugmenu.h"
+#include "Clock.h"
#include "Occlusion.h"
#include "Ropes.h"
+#include "custompipes.h"
GlobalScene Scene;
@@ -279,6 +285,28 @@ DoFade(void)
}
}
+bool
+RwGrabScreen(RwCamera *camera, RwChar *filename)
+{
+ char temp[255];
+ RwImage *pImage = RsGrabScreen(camera);
+ bool result = true;
+
+ if (pImage == nil)
+ return false;
+
+ strcpy(temp, CFileMgr::GetRootDirName());
+ strcat(temp, filename);
+
+ if (RtBMPImageWrite(pImage, &temp[0]) == nil)
+ result = false;
+ RwImageDestroy(pImage);
+ return result;
+}
+
+#define TILE_WIDTH 576
+#define TILE_HEIGHT 432
+
void
DoRWStuffEndOfFrame(void)
{
@@ -287,6 +315,20 @@ DoRWStuffEndOfFrame(void)
FlushObrsPrintfs();
RwCameraEndUpdate(Scene.camera);
RsCameraShowRaster(Scene.camera);
+#ifndef MASTER
+ char s[48];
+ if (CPad::GetPad(1)->GetLeftShockJustDown()) {
+ // try using both controllers for this thing... crazy bastards
+ if (CPad::GetPad(0)->GetRightStickY() > 0) {
+ sprintf(s, "screen%d%d.ras", CClock::ms_nGameClockHours, CClock::ms_nGameClockMinutes);
+ // TODO
+ //RtTileRender(Scene.camera, TILE_WIDTH * 2, TILE_HEIGHT * 2, TILE_WIDTH, TILE_HEIGHT, &NewTileRendererCB, nil, s);
+ } else {
+ sprintf(s, "screen%d%d.bmp", CClock::ms_nGameClockHours, CClock::ms_nGameClockMinutes);
+ RwGrabScreen(Scene.camera, s);
+ }
+ }
+#endif // !MASTER
}
static RwBool
@@ -345,6 +387,12 @@ PluginAttach(void)
return FALSE;
}
+#ifndef LIBRW
+ RpAnisotPluginAttach();
+#endif
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::CustomPipeRegister();
+#endif
return TRUE;
}
@@ -358,7 +406,11 @@ Initialise3D(void *param)
DebugMenuInit();
DebugMenuPopulate();
#endif // !DEBUGMENU
- return CGame::InitialiseRenderWare();
+ bool ret = CGame::InitialiseRenderWare();
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::CustomPipeInit(); // need Scene.world for this
+#endif
+ return ret;
}
return (FALSE);
@@ -367,6 +419,9 @@ Initialise3D(void *param)
static void
Terminate3D(void)
{
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::CustomPipeShutdown();
+#endif
CGame::ShutdownRenderWare();
#ifdef DEBUGMENU
DebugMenuShutdown();
@@ -554,17 +609,13 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
}
}
+//--MIAMI: done
void
LoadingIslandScreen(const char *levelName)
{
CSprite2d *splash;
- wchar *name;
- char str[100];
- wchar wstr[80];
- CRGBA col;
splash = LoadSplash(nil);
- name = TheText.Get(levelName);
if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
return;
@@ -572,26 +623,10 @@ LoadingIslandScreen(const char *levelName)
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
- col = CRGBA(255, 255, 255, 255);
+ CRGBA col = CRGBA(255, 255, 255, 255);
+ CRGBA col2 = CRGBA(0, 0, 0, 255);
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col2);
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col, col, col, col);
- CFont::SetBackgroundOff();
- CFont::SetScale(1.5f, 1.5f);
- CFont::SetPropOn();
- CFont::SetRightJustifyOn();
- CFont::SetRightJustifyWrap(150.0f);
- CFont::SetFontStyle(FONT_HEADING);
- sprintf(str, "WELCOME TO");
- AsciiToUnicode(str, wstr);
- CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- CFont::SetDropShadowPosition(3);
- CFont::SetColor(CRGBA(243, 237, 71, 255));
- CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
- CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
- TextCopy(wstr, name);
- TheText.UpperCase(wstr);
- CFont::SetColor(CRGBA(243, 237, 71, 255));
- CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
- CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
@@ -852,7 +887,7 @@ RenderScene(void)
CRenderer::RenderFadingInEntities();
RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWeather::RenderRainStreaks();
- // CCoronas::RenderSunReflection
+ CCoronas::RenderSunReflection();
}
void
@@ -1065,6 +1100,12 @@ Idle(void *arg)
tbEndTimer("PreRender");
#endif
+#ifdef FIX_BUGS
+ // This has to be done BEFORE RwCameraBeginUpdate
+ RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+ RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+#endif
+
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
return;
@@ -1077,9 +1118,10 @@ Idle(void *arg)
DefinedState();
- // BUG. This has to be done BEFORE RwCameraBeginUpdate
+#ifndef FIX_BUGS
RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+#endif
#ifdef TIMEBARS
tbStartTimer(0, "RenderScene");
@@ -1088,6 +1130,11 @@ Idle(void *arg)
#ifdef TIMEBARS
tbEndTimer("RenderScene");
#endif
+
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::EnvMapRender();
+#endif
+
RenderDebugShit();
RenderEffects();
diff --git a/src/core/main.h b/src/core/main.h
index 9ad4ed1c..96fbef05 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -20,6 +20,9 @@ extern bool gbShowTimebars;
class CSprite2d;
+bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
+bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
+void DoRWStuffEndOfFrame(void);
void InitialiseGame(void);
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
void LoadingIslandScreen(const char *levelName);
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 10f0e032..ce34dc0f 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -7,6 +7,7 @@
#include "Credits.h"
#include "Camera.h"
#include "Weather.h"
+#include "Timecycle.h"
#include "Clock.h"
#include "World.h"
#include "Vehicle.h"
@@ -32,6 +33,9 @@
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
+#include "MBlur.h"
+#include "postfx.h"
+#include "custompipes.h"
#ifndef _WIN32
#include "assert.h"
@@ -71,110 +75,6 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
-#ifdef CUSTOM_FRONTEND_OPTIONS
-#include "frontendoption.h"
-#include "platform.h"
-
-void ReloadFrontendOptions(void)
-{
- CustomFrontendOptionsPopulate();
-}
-
-#ifdef MORE_LANGUAGES
-void LangPolSelect(int8 action)
-{
- if (action == FEOPTION_ACTION_SELECT) {
- FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
- FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
- FrontEndMenuManager.InitialiseChangedLanguageSettings();
- FrontEndMenuManager.SaveSettings();
- }
-}
-
-void LangRusSelect(int8 action)
-{
- if (action == FEOPTION_ACTION_SELECT) {
- FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
- FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
- FrontEndMenuManager.InitialiseChangedLanguageSettings();
- FrontEndMenuManager.SaveSettings();
- }
-}
-
-void LangJapSelect(int8 action)
-{
- if (action == FEOPTION_ACTION_SELECT) {
- FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
- FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
- FrontEndMenuManager.InitialiseChangedLanguageSettings();
- FrontEndMenuManager.SaveSettings();
- }
-}
-#endif
-
-#ifdef IMPROVED_VIDEOMODE
-void ScreenModeChange(int8 displayedValue)
-{
- if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) {
- FrontEndMenuManager.m_nPrefsWindowed = displayedValue;
- _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
- FrontEndMenuManager.SetHelperText(0);
- FrontEndMenuManager.SaveSettings();
- }
-}
-#endif
-
-#ifdef FREE_CAM
-void ToggleFreeCam(int8 action)
-{
- if (action == FEOPTION_ACTION_SELECT) {
- TheCamera.bFreeCam = !TheCamera.bFreeCam;
- FrontEndMenuManager.SaveSettings();
- }
-}
-#endif
-
-#ifdef CUTSCENE_BORDERS_SWITCH
-void BorderModeChange(int8 displayedValue)
-{
- CMenuManager::m_PrefsCutsceneBorders = !!displayedValue;
- FrontEndMenuManager.SaveSettings();
-}
-#endif
-
-// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind
-void
-CustomFrontendOptionsPopulate(void)
-{
- RemoveCustomFrontendOptions(); // if exist
-
-#ifdef MORE_LANGUAGES
- FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS);
- FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil);
- FrontendOptionAddDynamic(TheText.Get("FEL_RUS"), nil, LangRusSelect, nil);
- FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, LangJapSelect, nil);
-#endif
-
-#ifdef IMPROVED_VIDEOMODE
- static const wchar *screenModes[] = { (wchar*)L"FULLSCREEN", (wchar*)L"WINDOWED" };
- FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 8);
- FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil);
-#endif
-
-#ifdef FREE_CAM
- static const wchar *text = (wchar*)L"TOGGLE FREE CAM";
- FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1);
- FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil);
-#endif
-
-#ifdef CUTSCENE_BORDERS_SWITCH
- static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") };
- FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 9);
- FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil);
-#endif
-}
-#endif
-
#ifdef DEBUGMENU
void WeaponCheat1();
void WeaponCheat2();
@@ -400,23 +300,50 @@ TWEAKSWITCH(CWeather::NewWeatherType, 0, 3, wt, NULL);
*/
void
+switchWeather(void)
+{
+ CWeather::StreamAfterRainTimer = 0;
+}
+
+void
DebugMenuPopulate(void)
{
if(1){
static const char *weathers[] = {
"Sunny", "Cloudy", "Rainy", "Foggy", "Extrasunny", "Stormy"
};
+ static const char *extracols[] = {
+ "1 - Malibu club",
+ "2 - Strib club",
+ "3 - Hotel",
+ "4 - Bank",
+ "5 - Police HQ",
+ "6 - Mall",
+ "7 - Rifle Range",
+ "8 - Mansion",
+ "9 - Dirt ring",
+ "10 - Blood ring",
+ "11 - Hot ring",
+ "12 - Concert hall",
+ "13 - Auntie Poulets",
+ "14 - Intro at docks",
+ "15 - Biker bar",
+ "16 - Intro cafe",
+ "17 - Studio",
+ "18", "19", "20", "21", "22", "23", "24"
+ };
DebugMenuEntry *e;
e = DebugMenuAddVar("Time & Weather", "Current Hour", &CClock::GetHoursRef(), nil, 1, 0, 23, nil);
DebugMenuEntrySetWrap(e, true);
e = DebugMenuAddVar("Time & Weather", "Current Minute", &CClock::GetMinutesRef(),
[](){ CWeather::InterpolationValue = CClock::GetMinutes()/60.0f; }, 1, 0, 59, nil);
DebugMenuEntrySetWrap(e, true);
- e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, nil, 1, 0, 5, weathers);
+ e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, switchWeather, 1, 0, 5, weathers);
DebugMenuEntrySetWrap(e, true);
- e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 5, weathers);
+ e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, switchWeather, 1, 0, 5, weathers);
DebugMenuEntrySetWrap(e, true);
- DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f);
+ DebugMenuAddVarBool32("Time & Weather", "Extracolours On", &CTimeCycle::m_bExtraColourOn, nil);
+ DebugMenuAddVar("Time & Weather", "Extracolour", &CTimeCycle::m_ExtraColour, nil, 1, 0, 23, extracols);
DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f);
DebugMenuAddCmd("Cheats", "Weapon set 1", WeaponCheat1);
@@ -493,7 +420,27 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);
+#ifdef EXTENDED_COLOURFILTER
+ static const char *filternames[] = { "None", "Simple", "Normal", "Mobile" };
+ e = DebugMenuAddVar("Render", "Colourfilter", &CPostFX::EffectSwitch, nil, 1, CPostFX::POSTFX_OFF, CPostFX::POSTFX_MOBILE, filternames);
+ DebugMenuEntrySetWrap(e, true);
+ DebugMenuAddVar("Render", "Intensity", &CPostFX::Intensity, nil, 0.05f, 0, 10.0f);
+ DebugMenuAddVarBool8("Render", "Blur", &CPostFX::BlurOn, nil);
+ DebugMenuAddVarBool8("Render", "Motion Blur", &CPostFX::MotionBlurOn, nil);
+#endif
+ DebugMenuAddVar("Render", "Drunkness", &CMBlur::Drunkness, nil, 0.05f, 0, 1.0f);
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil);
+#ifdef EXTENDED_PIPELINES
+ static const char *vehpipenames[] = { "MatFX", "Neo" };
+ e = DebugMenuAddVar("Render", "Vehicle Pipeline", &CustomPipes::VehiclePipeSwitch, nil,
+ 1, CustomPipes::VEHICLEPIPE_MATFX, CustomPipes::VEHICLEPIPE_NEO, vehpipenames);
+ DebugMenuEntrySetWrap(e, true);
+ DebugMenuAddVar("Render", "Neo Vehicle Shininess", &CustomPipes::VehicleShininess, nil, 0.1f, 0, 1.0f);
+ DebugMenuAddVar("Render", "Neo Vehicle Specularity", &CustomPipes::VehicleSpecularity, nil, 0.1f, 0, 1.0f);
+ DebugMenuAddVar("Render", "Neo Ped Rim light", &CustomPipes::RimlightMult, nil, 0.1f, 0, 1.0f);
+ DebugMenuAddVar("Render", "Neo World Lightmaps", &CustomPipes::LightmapMult, nil, 0.1f, 0, 1.0f);
+ DebugMenuAddVar("Render", "Neo Road Gloss", &CustomPipes::GlossMult, nil, 0.1f, 0, 1.0f);
+#endif
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
@@ -520,9 +467,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil);
-#ifdef CUSTOM_FRONTEND_OPTIONS
- DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions);
-#endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
@@ -534,7 +478,30 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
#endif
#ifdef MISSION_SWITCHER
- DebugMenuAddInt8("Debug", "Select mission no", &nextMissionToSwitch, nil, 1, 0, 96, nil);
+ DebugMenuEntry *missionEntry;
+ static const char* missions[] = {
+ "Initial", "Intro", "An Old Friend", "The Party", "Back Alley Brawl", "Jury Fury", "Riot",
+ "Treacherous Swine", "Mall Shootout", "Guardian Angels", "Sir, Yes Sir!", "All Hands On Deck!",
+ "The Chase", "Phnom Penh '86", "The Fastest Boat", "Supply & Demand", "Rub Out", "Death Row",
+ "Four Iron", "Demolition Man", "Two Bit Hit", "No Escape?", "The Shootist", "The Driver",
+ "The Job", "Gun Runner", "Boomshine Saigon", "Recruitment Drive", "Dildo Dodo", "Martha's Mug Shot",
+ "G-spotlight", "Shakedown", "Bar Brawl", "Cop Land", "Spilling the Beans", "Hit the Courier",
+ "Printworks Buy", "Sunshine Autos", "Interglobal Films Buy", "Cherry Popper Icecreams Buy",
+ "Kaufman Cabs Buy", "Malibu Club Buy", "The Boatyard Buy", "Pole Position Club Buy", "El Swanko Casa Buy",
+ "Links View Apartment Buy", "Hyman Condo Buy", "Ocean Heighs Aprt. Buy", "1102 Washington Street Buy",
+ "Vice Point Buy", "Skumole Shack Buy", "Cap the Collector", "Keep your Friends Close...",
+ "Alloy Wheels of Steel", "Messing with the Man", "Hog Tied", "Stunt Boat Challenge", "Cannon Fodder",
+ "Naval Engagement", "Trojan Voodoo", "Juju Scramble", "Bombs Away!", "Dirty Lickin's", "Love Juice",
+ "Psycho Killer", "Publicity Tour", "Weapon Range", "Road Kill", "Waste the Wife", "Autocide",
+ "Check Out at the Check In", "Loose Ends", "V.I.P.", "Friendly Rivalry", "Cabmaggedon", "TAXI DRIVER",
+ "PARAMEDIC", "FIREFIGHTER", "VIGILANTE", "HOTRING", "BLOODRING", "DIRTRING", "Sunshine Autos Races",
+ "Distribution", "Downtown Chopper Checkpoint", "Ocean Beach Chopper Checkpoint", "Vice Point Chopper Checkpoint",
+ "Little Haiti Chopper Checkpoint", "Trial by Dirt", "Test Track", "PCJ Playground", "Cone Crazy",
+ "PIZZA BOY", "RC Raider Pickup", "RC Bandit Race", "RC Baron Race", "Checkpoint Charlie"
+ };
+
+ missionEntry = DebugMenuAddVar("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, 96, missions);
+ DebugMenuEntrySetWrap(missionEntry, true);
DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission);
#endif
extern bool PrintDebugCode;
diff --git a/src/core/templates.h b/src/core/templates.h
index 465e3bef..9f5bd5ea 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -45,7 +45,7 @@ class CPool
public:
// TODO(MIAMI): remove ctor without name argument
- CPool(int size){
+ CPool(int size, const char *name){
// TODO: use new here
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
@@ -56,8 +56,6 @@ public:
m_flags[i].free = 1;
}
}
- CPool(int size, const char *name)
- : CPool(size) {}
~CPool() {
Flush();
}
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index b27284bc..cf1dd9e7 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -33,7 +33,7 @@
#include "WindModifiers.h"
#include "Occlusion.h"
-//--MIAMI: file almost done (see TODO)
+//--MIAMI: file done
int gBuildings;
diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp
new file mode 100644
index 00000000..2b4745e3
--- /dev/null
+++ b/src/extras/custompipes.cpp
@@ -0,0 +1,536 @@
+#define WITH_D3D
+#include "common.h"
+
+#ifdef EXTENDED_PIPELINES
+
+#include "main.h"
+#include "RwHelper.h"
+#include "Lights.h"
+#include "Timecycle.h"
+#include "FileMgr.h"
+#include "Clock.h"
+#include "Weather.h"
+#include "TxdStore.h"
+#include "Renderer.h"
+#include "World.h"
+#include "custompipes.h"
+
+#ifndef LIBRW
+#error "Need librw for EXTENDED_PIPELINES"
+#endif
+
+namespace CustomPipes {
+
+rw::int32 CustomMatOffset;
+
+void*
+CustomMatCtor(void *object, int32, int32)
+{
+ CustomMatExt *ext = GetCustomMatExt((rw::Material*)object);
+ ext->glossTex = nil;
+ ext->haveGloss = false;
+ return object;
+}
+
+void*
+CustomMatCopy(void *dst, void *src, int32, int32)
+{
+ CustomMatExt *srcext = GetCustomMatExt((rw::Material*)src);
+ CustomMatExt *dstext = GetCustomMatExt((rw::Material*)dst);
+ dstext->glossTex = srcext->glossTex;
+ dstext->haveGloss = srcext->haveGloss;
+ return dst;
+}
+
+
+
+static rw::TexDictionary *neoTxd;
+
+bool bRenderingEnvMap;
+int32 EnvMapSize = 128;
+rw::Camera *EnvMapCam;
+rw::Texture *EnvMapTex;
+rw::Texture *EnvMaskTex;
+static rw::RWDEVICE::Im2DVertex EnvScreenQuad[4];
+static int16 QuadIndices[6] = { 0, 1, 2, 0, 2, 3 };
+
+static rw::Camera*
+CreateEnvMapCam(rw::World *world)
+{
+ rw::Raster *fbuf = rw::Raster::create(EnvMapSize, EnvMapSize, 0, rw::Raster::CAMERATEXTURE);
+ if(fbuf){
+ rw::Raster *zbuf = rw::Raster::create(EnvMapSize, EnvMapSize, 0, rw::Raster::ZBUFFER);
+ if(zbuf){
+ rw::Frame *frame = rw::Frame::create();
+ if(frame){
+ rw::Camera *cam = rw::Camera::create();
+ if(cam){
+ cam->frameBuffer = fbuf;
+ cam->zBuffer = zbuf;
+ cam->setFrame(frame);
+ cam->setNearPlane(0.1f);
+ cam->setFarPlane(250.0f);
+ rw::V2d vw = { 2.0f, 2.0f };
+ cam->setViewWindow(&vw);
+ world->addCamera(cam);
+ EnvMapTex = rw::Texture::create(fbuf);
+ EnvMapTex->setFilter(rw::Texture::LINEAR);
+
+ frame->matrix.right.x = -1.0f;
+ frame->matrix.up.y = -1.0f;
+ frame->matrix.update();
+ return cam;
+ }
+ frame->destroy();
+ }
+ zbuf->destroy();
+ }
+ fbuf->destroy();
+ }
+ return nil;
+}
+
+static void
+DestroyCam(rw::Camera *cam)
+{
+ if(cam == nil)
+ return;
+ if(cam->frameBuffer){
+ cam->frameBuffer->destroy();
+ cam->frameBuffer = nil;
+ }
+ if(cam->zBuffer){
+ cam->zBuffer->destroy();
+ cam->zBuffer = nil;
+ }
+ rw::Frame *f = cam->getFrame();
+ if(f){
+ cam->setFrame(nil);
+ f->destroy();
+ }
+ cam->world->removeCamera(cam);
+ cam->destroy();
+}
+
+void
+RenderEnvMapScene(void)
+{
+ CRenderer::RenderRoads();
+ CRenderer::RenderEverythingBarRoads();
+ CRenderer::RenderFadingInEntities();
+}
+
+void
+EnvMapRender(void)
+{
+ if(VehiclePipeSwitch != VEHICLEPIPE_NEO)
+ return;
+
+ RwCameraEndUpdate(Scene.camera);
+
+ // Neo does this differently, but i'm not quite convinced it's much better
+ rw::V3d camPos = FindPlayerCoors();
+ EnvMapCam->getFrame()->matrix.pos = camPos;
+ EnvMapCam->getFrame()->transform(&EnvMapCam->getFrame()->matrix, rw::COMBINEREPLACE);
+
+ rw::RGBA skycol = { CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255 };
+ EnvMapCam->clear(&skycol, rwCAMERACLEARZ|rwCAMERACLEARIMAGE);
+ RwCameraBeginUpdate(EnvMapCam);
+ bRenderingEnvMap = true;
+ RenderEnvMapScene();
+ bRenderingEnvMap = false;
+
+ if(EnvMaskTex){
+ rw::SetRenderState(rw::VERTEXALPHA, TRUE);
+ rw::SetRenderState(rw::SRCBLEND, rw::BLENDZERO);
+ rw::SetRenderState(rw::DESTBLEND, rw::BLENDSRCCOLOR);
+ rw::SetRenderStatePtr(rw::TEXTURERASTER, EnvMaskTex->raster);
+ rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, EnvScreenQuad, 4, QuadIndices, 6);
+ rw::SetRenderState(rw::SRCBLEND, rw::BLENDSRCALPHA);
+ rw::SetRenderState(rw::DESTBLEND, rw::BLENDINVSRCALPHA);
+ }
+ RwCameraEndUpdate(EnvMapCam);
+
+
+ RwCameraBeginUpdate(Scene.camera);
+
+ // debug env map
+// rw::SetRenderStatePtr(rw::TEXTURERASTER, EnvMapTex->raster);
+// rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, EnvScreenQuad, 4, QuadIndices, 6);
+}
+
+static void
+EnvMapInit(void)
+{
+ if(neoTxd)
+ EnvMaskTex = neoTxd->find("CarReflectionMask");
+
+ EnvMapCam = CreateEnvMapCam(Scene.world);
+
+ int width = EnvMapCam->frameBuffer->width;
+ int height = EnvMapCam->frameBuffer->height;
+ float screenZ = RwIm2DGetNearScreenZ();
+ float recipZ = 1.0f/EnvMapCam->nearPlane;
+
+ EnvScreenQuad[0].setScreenX(0.0f);
+ EnvScreenQuad[0].setScreenY(0.0f);
+ EnvScreenQuad[0].setScreenZ(screenZ);
+ EnvScreenQuad[0].setCameraZ(EnvMapCam->nearPlane);
+ EnvScreenQuad[0].setRecipCameraZ(recipZ);
+ EnvScreenQuad[0].setColor(255, 255, 255, 255);
+ EnvScreenQuad[0].setU(0.0f, recipZ);
+ EnvScreenQuad[0].setV(0.0f, recipZ);
+
+ EnvScreenQuad[1].setScreenX(0.0f);
+ EnvScreenQuad[1].setScreenY(height);
+ EnvScreenQuad[1].setScreenZ(screenZ);
+ EnvScreenQuad[1].setCameraZ(EnvMapCam->nearPlane);
+ EnvScreenQuad[1].setRecipCameraZ(recipZ);
+ EnvScreenQuad[1].setColor(255, 255, 255, 255);
+ EnvScreenQuad[1].setU(0.0f, recipZ);
+ EnvScreenQuad[1].setV(1.0f, recipZ);
+
+ EnvScreenQuad[2].setScreenX(width);
+ EnvScreenQuad[2].setScreenY(height);
+ EnvScreenQuad[2].setScreenZ(screenZ);
+ EnvScreenQuad[2].setCameraZ(EnvMapCam->nearPlane);
+ EnvScreenQuad[2].setRecipCameraZ(recipZ);
+ EnvScreenQuad[2].setColor(255, 255, 255, 255);
+ EnvScreenQuad[2].setU(1.0f, recipZ);
+ EnvScreenQuad[2].setV(1.0f, recipZ);
+
+ EnvScreenQuad[3].setScreenX(width);
+ EnvScreenQuad[3].setScreenY(0.0f);
+ EnvScreenQuad[3].setScreenZ(screenZ);
+ EnvScreenQuad[3].setCameraZ(EnvMapCam->nearPlane);
+ EnvScreenQuad[3].setRecipCameraZ(recipZ);
+ EnvScreenQuad[3].setColor(255, 255, 255, 255);
+ EnvScreenQuad[3].setU(1.0f, recipZ);
+ EnvScreenQuad[3].setV(0.0f, recipZ);
+}
+
+static void
+EnvMapShutdown(void)
+{
+ EnvMapTex->raster = nil;
+ EnvMapTex->destroy();
+ EnvMapTex = nil;
+ DestroyCam(EnvMapCam);
+ EnvMapCam = nil;
+}
+
+/*
+ * Tweak values
+ */
+
+#define INTERP_SETUP \
+ int h1 = CClock::GetHours(); \
+ int h2 = (h1+1)%24; \
+ int w1 = CWeather::OldWeatherType; \
+ int w2 = CWeather::NewWeatherType; \
+ float timeInterp = (CClock::GetSeconds()/60.0f + CClock::GetMinutes())/60.0f; \
+ float c0 = (1.0f-timeInterp)*(1.0f-CWeather::InterpolationValue); \
+ float c1 = timeInterp*(1.0f-CWeather::InterpolationValue); \
+ float c2 = (1.0f-timeInterp)*CWeather::InterpolationValue; \
+ float c3 = timeInterp*CWeather::InterpolationValue;
+#define INTERP(v) v[h1][w1]*c0 + v[h2][w1]*c1 + v[h1][w2]*c2 + v[h2][w2]*c3;
+#define INTERPF(v,f) v[h1][w1].f*c0 + v[h2][w1].f*c1 + v[h1][w2].f*c2 + v[h2][w2].f*c3;
+
+InterpolatedFloat::InterpolatedFloat(float init)
+{
+ curInterpolator = 61; // compared against second
+ for(int h = 0; h < 24; h++)
+ for(int w = 0; w < NUMWEATHERS; w++)
+ data[h][w] = init;
+}
+
+void
+InterpolatedFloat::Read(char *s, int line, int field)
+{
+ sscanf(s, "%f", &data[line][field]);
+}
+
+float
+InterpolatedFloat::Get(void)
+{
+ if(curInterpolator != CClock::GetSeconds()){
+ INTERP_SETUP
+ curVal = INTERP(data);
+ curInterpolator = CClock::GetSeconds();
+ }
+ return curVal;
+}
+
+InterpolatedColor::InterpolatedColor(const Color &init)
+{
+ curInterpolator = 61; // compared against second
+ for(int h = 0; h < 24; h++)
+ for(int w = 0; w < NUMWEATHERS; w++)
+ data[h][w] = init;
+}
+
+void
+InterpolatedColor::Read(char *s, int line, int field)
+{
+ int r, g, b, a;
+ sscanf(s, "%i, %i, %i, %i", &r, &g, &b, &a);
+ data[line][field] = Color(r/255.0f, g/255.0f, b/255.0f, a/255.0f);
+}
+
+Color
+InterpolatedColor::Get(void)
+{
+ if(curInterpolator != CClock::GetSeconds()){
+ INTERP_SETUP
+ curVal.r = INTERPF(data, r);
+ curVal.g = INTERPF(data, g);
+ curVal.b = INTERPF(data, b);
+ curVal.a = INTERPF(data, a);
+ curInterpolator = CClock::GetSeconds();
+ }
+ return curVal;
+}
+
+void
+InterpolatedLight::Read(char *s, int line, int field)
+{
+ int r, g, b, a;
+ sscanf(s, "%i, %i, %i, %i", &r, &g, &b, &a);
+ data[line][field] = Color(r/255.0f, g/255.0f, b/255.0f, a/100.0f);
+}
+
+char*
+ReadTweakValueTable(char *fp, InterpolatedValue &interp)
+{
+ char buf[24], *p;
+ int c;
+ int line, field;
+
+ line = 0;
+ c = *fp++;
+ while(c != '\0' && line < 24){
+ field = 0;
+ if(c != '\0' && c != '#'){
+ while(c != '\0' && c != '\n' && field < NUMWEATHERS){
+ p = buf;
+ while(c != '\0' && c == '\t')
+ c = *fp++;
+ *p++ = c;
+ while(c = *fp++, c != '\0' && c != '\t' && c != '\n')
+ *p++ = c;
+ *p++ = '\0';
+ interp.Read(buf, line, field);
+ field++;
+ }
+ line++;
+ }
+ while(c != '\0' && c != '\n')
+ c = *fp++;
+ c = *fp++;
+ }
+ return fp-1;
+}
+
+
+
+/*
+ * Neo Vehicle pipe
+ */
+
+int32 VehiclePipeSwitch = VEHICLEPIPE_NEO;
+float VehicleShininess = 1.0f;
+float VehicleSpecularity = 1.0f;
+InterpolatedFloat Fresnel(0.4f);
+InterpolatedFloat Power(18.0f);
+InterpolatedLight DiffColor(Color(0.0f, 0.0f, 0.0f, 0.0f));
+InterpolatedLight SpecColor(Color(0.7f, 0.7f, 0.7f, 1.0f));
+rw::ObjPipeline *vehiclePipe;
+
+void
+AttachVehiclePipe(rw::Atomic *atomic)
+{
+ atomic->pipeline = vehiclePipe;
+}
+
+void
+AttachVehiclePipe(rw::Clump *clump)
+{
+ FORLIST(lnk, clump->atomics)
+ AttachVehiclePipe(rw::Atomic::fromClump(lnk));
+}
+
+
+
+/*
+ * Neo World pipe
+ */
+
+float LightmapMult = 1.0f;
+InterpolatedFloat WorldLightmapBlend(1.0f);
+rw::ObjPipeline *worldPipe;
+
+void
+AttachWorldPipe(rw::Atomic *atomic)
+{
+ atomic->pipeline = worldPipe;
+}
+
+void
+AttachWorldPipe(rw::Clump *clump)
+{
+ FORLIST(lnk, clump->atomics)
+ AttachWorldPipe(rw::Atomic::fromClump(lnk));
+}
+
+
+
+
+/*
+ * Neo Gloss pipe
+ */
+
+float GlossMult = 1.0f;
+rw::ObjPipeline *glossPipe;
+
+rw::Texture*
+GetGlossTex(rw::Material *mat)
+{
+ if(neoTxd == nil)
+ return nil;
+ CustomMatExt *ext = GetCustomMatExt(mat);
+ if(!ext->haveGloss){
+ char glossname[128];
+ strcpy(glossname, mat->texture->name);
+ strcat(glossname, "_gloss");
+ ext->glossTex = neoTxd->find(glossname);
+ ext->haveGloss = true;
+ }
+ return ext->glossTex;
+}
+
+void
+AttachGlossPipe(rw::Atomic *atomic)
+{
+ atomic->pipeline = glossPipe;
+}
+
+void
+AttachGlossPipe(rw::Clump *clump)
+{
+ FORLIST(lnk, clump->atomics)
+ AttachWorldPipe(rw::Atomic::fromClump(lnk));
+}
+
+
+
+/*
+ * Neo Rim pipes
+ */
+
+float RimlightMult = 1.0f;
+InterpolatedColor RampStart(Color(0.0f, 0.0f, 0.0f, 1.0f));
+InterpolatedColor RampEnd(Color(1.0f, 1.0f, 1.0f, 1.0f));
+InterpolatedFloat Offset(0.5f);
+InterpolatedFloat Scale(1.5f);
+InterpolatedFloat Scaling(2.0f);
+rw::ObjPipeline *rimPipe;
+rw::ObjPipeline *rimSkinPipe;
+
+void
+AttachRimPipe(rw::Atomic *atomic)
+{
+ if(rw::Skin::get(atomic->geometry))
+ atomic->pipeline = rimSkinPipe;
+ else
+ atomic->pipeline = rimPipe;
+}
+
+void
+AttachRimPipe(rw::Clump *clump)
+{
+ FORLIST(lnk, clump->atomics)
+ AttachRimPipe(rw::Atomic::fromClump(lnk));
+}
+
+/*
+ * High level stuff
+ */
+
+void
+CustomPipeInit(void)
+{
+ RwStream *stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "neo/neo.txd");
+ if(stream == nil)
+ printf("Error: couldn't open 'neo/neo.txd'\n");
+ else{
+ if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil))
+ neoTxd = RwTexDictionaryGtaStreamRead(stream);
+ RwStreamClose(stream, nil);
+ }
+
+ EnvMapInit();
+
+ CreateVehiclePipe();
+ CreateWorldPipe();
+ CreateGlossPipe();
+ CreateRimLightPipes();
+}
+
+void
+CustomPipeShutdown(void)
+{
+ DestroyVehiclePipe();
+ DestroyWorldPipe();
+ DestroyGlossPipe();
+ DestroyRimLightPipes();
+
+ EnvMapShutdown();
+
+ if(neoTxd){
+ neoTxd->destroy();
+ neoTxd = nil;
+ }
+}
+
+void
+CustomPipeRegister(void)
+{
+#ifdef RW_OPENGL
+ CustomPipeRegisterGL();
+#endif
+
+ CustomMatOffset = rw::Material::registerPlugin(sizeof(CustomMatExt), MAKECHUNKID(rwVENDORID_ROCKSTAR, 0x80),
+ CustomMatCtor, nil, CustomMatCopy);
+}
+
+
+// Load textures from generic as fallback
+
+rw::TexDictionary *genericTxd;
+rw::Texture *(*defaultFindCB)(const char *name);
+
+static rw::Texture*
+customFindCB(const char *name)
+{
+ rw::Texture *res = defaultFindCB(name);
+ if(res == nil)
+ res = genericTxd->find(name);
+ return res;
+}
+
+void
+SetTxdFindCallback(void)
+{
+ int slot = CTxdStore::FindTxdSlot("generic");
+ CTxdStore::AddRef(slot);
+ // TODO: function for this
+ genericTxd = CTxdStore::GetSlot(slot)->texDict;
+ assert(genericTxd);
+ if(defaultFindCB == nil)
+ defaultFindCB = rw::Texture::findCB;
+ rw::Texture::findCB = customFindCB;
+}
+
+}
+
+#endif
diff --git a/src/extras/custompipes.h b/src/extras/custompipes.h
new file mode 100644
index 00000000..4ebe586f
--- /dev/null
+++ b/src/extras/custompipes.h
@@ -0,0 +1,133 @@
+#pragma once
+
+#ifdef EXTENDED_PIPELINES
+#ifdef LIBRW
+
+namespace CustomPipes {
+
+
+
+struct CustomMatExt
+{
+ rw::Texture *glossTex;
+ bool haveGloss;
+};
+extern rw::int32 CustomMatOffset;
+inline CustomMatExt *GetCustomMatExt(rw::Material *mat) {
+ return PLUGINOFFSET(CustomMatExt, mat, CustomMatOffset);
+}
+
+
+struct Color
+{
+ float r, g, b, a;
+ Color(void) {}
+ Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
+};
+
+class InterpolatedValue
+{
+public:
+ virtual void Read(char *s, int line, int field) = 0;
+};
+
+class InterpolatedFloat : public InterpolatedValue
+{
+public:
+ float data[24][NUMWEATHERS];
+ float curInterpolator;
+ float curVal;
+
+ InterpolatedFloat(float init);
+ void Read(char *s, int line, int field);
+ float Get(void);
+};
+
+class InterpolatedColor : public InterpolatedValue
+{
+public:
+ Color data[24][NUMWEATHERS];
+ float curInterpolator;
+ Color curVal;
+
+ InterpolatedColor(const Color &init);
+ void Read(char *s, int line, int field);
+ Color Get(void);
+};
+
+class InterpolatedLight : public InterpolatedColor
+{
+public:
+ InterpolatedLight(const Color &init) : InterpolatedColor(init) {}
+ void Read(char *s, int line, int field);
+};
+
+char *ReadTweakValueTable(char *fp, InterpolatedValue &interp);
+
+
+
+
+
+void CustomPipeRegister(void);
+void CustomPipeRegisterGL(void);
+void CustomPipeInit(void);
+void CustomPipeShutdown(void);
+void SetTxdFindCallback(void);
+
+extern bool bRenderingEnvMap;
+extern int32 EnvMapSize;
+extern rw::Camera *EnvMapCam;
+extern rw::Texture *EnvMapTex;
+extern rw::Texture *EnvMaskTex;
+void EnvMapRender(void);
+
+enum {
+ VEHICLEPIPE_MATFX,
+ VEHICLEPIPE_NEO
+};
+extern int32 VehiclePipeSwitch;
+extern float VehicleShininess;
+extern float VehicleSpecularity;
+extern InterpolatedFloat Fresnel;
+extern InterpolatedFloat Power;
+extern InterpolatedLight DiffColor;
+extern InterpolatedLight SpecColor;
+extern rw::ObjPipeline *vehiclePipe;
+void CreateVehiclePipe(void);
+void DestroyVehiclePipe(void);
+void AttachVehiclePipe(rw::Atomic *atomic);
+void AttachVehiclePipe(rw::Clump *clump);
+
+extern float LightmapMult;
+extern InterpolatedFloat WorldLightmapBlend;
+extern rw::ObjPipeline *worldPipe;
+void CreateWorldPipe(void);
+void DestroyWorldPipe(void);
+void AttachWorldPipe(rw::Atomic *atomic);
+void AttachWorldPipe(rw::Clump *clump);
+
+extern float GlossMult;
+extern rw::ObjPipeline *glossPipe;
+void CreateGlossPipe(void);
+void DestroyGlossPipe(void);
+void AttachGlossPipe(rw::Atomic *atomic);
+void AttachGlossPipe(rw::Clump *clump);
+rw::Texture *GetGlossTex(rw::Material *mat);
+
+extern float RimlightMult;
+extern InterpolatedColor RampStart;
+extern InterpolatedColor RampEnd;
+extern InterpolatedFloat Offset;
+extern InterpolatedFloat Scale;
+extern InterpolatedFloat Scaling;
+extern rw::ObjPipeline *rimPipe;
+extern rw::ObjPipeline *rimSkinPipe;
+void CreateRimLightPipes(void);
+void DestroyRimLightPipes(void);
+void AttachRimPipe(rw::Atomic *atomic);
+void AttachRimPipe(rw::Clump *clump);
+
+}
+
+#endif
+#endif
diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp
new file mode 100644
index 00000000..63e91063
--- /dev/null
+++ b/src/extras/custompipes_d3d9.cpp
@@ -0,0 +1,527 @@
+#define WITH_D3D
+#include "common.h"
+
+#ifdef RW_D3D9
+#ifdef EXTENDED_PIPELINES
+
+#include "main.h"
+#include "RwHelper.h"
+#include "Lights.h"
+#include "Timecycle.h"
+#include "FileMgr.h"
+#include "Clock.h"
+#include "Weather.h"
+#include "TxdStore.h"
+#include "Renderer.h"
+#include "World.h"
+#include "custompipes.h"
+
+#ifndef LIBRW
+#error "Need librw for EXTENDED_PIPELINES"
+#endif
+
+extern RwTexture *gpWhiteTexture; // from vehicle model info
+
+namespace CustomPipes {
+
+enum {
+ // rim pipe
+ VSLOC_boneMatrices = rw::d3d::VSLOC_afterLights,
+ VSLOC_viewVec = VSLOC_boneMatrices + 64*3,
+ VSLOC_rampStart,
+ VSLOC_rampEnd,
+ VSLOC_rimData,
+
+ // gloss pipe
+ VSLOC_eye = rw::d3d::VSLOC_afterLights,
+
+ VSLOC_reflProps,
+ VSLOC_specLights
+};
+
+/*
+ * Neo Vehicle pipe
+ */
+
+static void *neoVehicle_VS;
+static void *neoVehicle_PS;
+
+void
+uploadSpecLights(void)
+{
+ struct VsLight {
+ rw::RGBAf color;
+ float pos[4]; // unused
+ rw::V3d dir;
+ float power;
+ } specLights[1 + NUMEXTRADIRECTIONALS];
+ memset(specLights, 0, sizeof(specLights));
+ for(int i = 0; i < 1+NUMEXTRADIRECTIONALS; i++)
+ specLights[i].power = 1.0f;
+ float power = Power.Get();
+ Color speccol = SpecColor.Get();
+ specLights[0].color.red = speccol.r;
+ specLights[0].color.green = speccol.g;
+ specLights[0].color.blue = speccol.b;
+ specLights[0].dir = pDirect->getFrame()->getLTM()->at;
+ specLights[0].power = power;
+ for(int i = 0; i < NUMEXTRADIRECTIONALS; i++){
+ if(pExtraDirectionals[i]->getFlags() & rw::Light::LIGHTATOMICS){
+ specLights[1+i].color = pExtraDirectionals[i]->color;
+ specLights[1+i].dir = pExtraDirectionals[i]->getFrame()->getLTM()->at;
+ specLights[1+i].power = power*2.0f;
+ }
+ }
+ rw::d3d::d3ddevice->SetVertexShaderConstantF(VSLOC_specLights, (float*)&specLights, 3*(1 + NUMEXTRADIRECTIONALS));
+}
+
+void
+vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ // TODO: make this less of a kludge
+ if(VehiclePipeSwitch == VEHICLEPIPE_MATFX){
+ matFXGlobals.pipelines[rw::platform]->render(atomic);
+ return;
+ }
+
+ int vsBits;
+ setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
+ setIndices(header->indexBuffer);
+ setVertexDeclaration(header->vertexDeclaration);
+
+ vsBits = lightingCB_Shader(atomic);
+ uploadSpecLights();
+ uploadMatrices(atomic->getFrame()->getLTM());
+
+ setVertexShader(neoVehicle_VS);
+
+ V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
+ d3ddevice->SetVertexShaderConstantF(VSLOC_eye, (float*)&eyePos, 1);
+
+ float reflProps[4];
+ reflProps[0] = Fresnel.Get();
+ reflProps[1] = SpecColor.Get().a;
+
+ d3d::setTexture(1, EnvMapTex);
+
+ SetRenderState(SRCBLEND, BLENDONE);
+
+ InstanceData *inst = header->inst;
+ for(rw::uint32 i = 0; i < header->numMeshes; i++){
+ Material *m = inst->material;
+
+ SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
+
+ reflProps[2] = m->surfaceProps.specular * VehicleShininess;
+ reflProps[3] = m->surfaceProps.specular == 0.0f ? 0.0f : VehicleSpecularity;
+ d3ddevice->SetVertexShaderConstantF(VSLOC_reflProps, reflProps, 1);
+
+ setMaterial(m->color, m->surfaceProps);
+
+ if(m->texture)
+ d3d::setTexture(0, m->texture);
+ else
+ d3d::setTexture(0, gpWhiteTexture);
+ setPixelShader(neoVehicle_PS);
+
+ drawInst(header, inst);
+ inst++;
+ }
+
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+}
+
+void
+CreateVehiclePipe(void)
+{
+ if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/carTweakingTable.dat'\n");
+ else{
+ char *fp = (char*)work_buff;
+ fp = ReadTweakValueTable(fp, Fresnel);
+ fp = ReadTweakValueTable(fp, Power);
+ fp = ReadTweakValueTable(fp, DiffColor);
+ fp = ReadTweakValueTable(fp, SpecColor);
+ }
+
+#include "shaders/neoVehicle_VS.inc"
+ neoVehicle_VS = rw::d3d::createVertexShader(neoVehicle_VS_cso);
+ assert(neoVehicle_VS);
+
+#include "shaders/neoVehicle_PS.inc"
+ neoVehicle_PS = rw::d3d::createPixelShader(neoVehicle_PS_cso);
+ assert(neoVehicle_PS);
+
+
+ rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
+ pipe->instanceCB = rw::d3d9::defaultInstanceCB;
+ pipe->uninstanceCB = rw::d3d9::defaultUninstanceCB;
+ pipe->renderCB = vehicleRenderCB;
+ vehiclePipe = pipe;
+}
+
+void
+DestroyVehiclePipe(void)
+{
+ rw::d3d::destroyVertexShader(neoVehicle_VS);
+ neoVehicle_VS = nil;
+
+ ((rw::d3d9::ObjPipeline*)vehiclePipe)->destroy();
+ vehiclePipe = nil;
+}
+
+
+
+/*
+ * Neo World pipe
+ */
+
+static void *neoWorld_VS;
+static void *neoWorldVC_PS;
+
+static void
+worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ int vsBits;
+ setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
+ setIndices(header->indexBuffer);
+ setVertexDeclaration(header->vertexDeclaration);
+
+ vsBits = lightingCB_Shader(atomic);
+ uploadMatrices(atomic->getFrame()->getLTM());
+
+
+ float lightfactor[4];
+
+ InstanceData *inst = header->inst;
+ for(rw::uint32 i = 0; i < header->numMeshes; i++){
+ Material *m = inst->material;
+
+ if(MatFX::getEffects(m) == MatFX::DUAL){
+ setVertexShader(neoWorld_VS);
+
+ MatFX *matfx = MatFX::get(m);
+ Texture *dualtex = matfx->getDualTexture();
+ if(dualtex == nil)
+ goto notex;
+ d3d::setTexture(1, dualtex);
+ lightfactor[0] = lightfactor[1] = lightfactor[2] = WorldLightmapBlend.Get()*LightmapMult;
+ }else{
+ notex:
+ setVertexShader(default_amb_VS);
+
+ d3d::setTexture(1, nil);
+ lightfactor[0] = lightfactor[1] = lightfactor[2] = 0.0f;
+ }
+ lightfactor[3] = m->color.alpha/255.0f;
+ d3d::setTexture(0, m->texture);
+ d3ddevice->SetPixelShaderConstantF(1, lightfactor, 1);
+
+ SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
+
+ RGBA color = { 255, 255, 255, m->color.alpha };
+ setMaterial(color, m->surfaceProps);
+
+ if(m->texture)
+ d3d::setTexture(0, m->texture);
+ else
+ d3d::setTexture(0, gpWhiteTexture);
+ setPixelShader(neoWorldVC_PS);
+
+ drawInst(header, inst);
+ inst++;
+ }
+}
+
+void
+CreateWorldPipe(void)
+{
+ if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n");
+ else
+ ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
+
+#include "shaders/default_UV2_VS.inc"
+ neoWorld_VS = rw::d3d::createVertexShader(default_UV2_VS_cso);
+ assert(neoWorld_VS);
+
+#include "shaders/neoWorldVC_PS.inc"
+ neoWorldVC_PS = rw::d3d::createPixelShader(neoWorldVC_PS_cso);
+ assert(neoWorldVC_PS);
+
+
+ rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
+ pipe->instanceCB = rw::d3d9::defaultInstanceCB;
+ pipe->uninstanceCB = rw::d3d9::defaultUninstanceCB;
+ pipe->renderCB = worldRenderCB;
+ worldPipe = pipe;
+}
+
+void
+DestroyWorldPipe(void)
+{
+ rw::d3d::destroyVertexShader(neoWorld_VS);
+ neoWorld_VS = nil;
+ rw::d3d::destroyPixelShader(neoWorldVC_PS);
+ neoWorldVC_PS = nil;
+
+
+ ((rw::d3d9::ObjPipeline*)worldPipe)->destroy();
+ worldPipe = nil;
+}
+
+
+
+
+/*
+ * Neo Gloss pipe
+ */
+
+static void *neoGloss_VS;
+static void *neoGloss_PS;
+
+static void
+glossRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
+{
+ worldRenderCB(atomic, header);
+
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ setVertexShader(neoGloss_VS);
+ setPixelShader(neoGloss_PS);
+
+ V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
+ d3ddevice->SetVertexShaderConstantF(VSLOC_eye, (float*)&eyePos, 1);
+ d3ddevice->SetPixelShaderConstantF(1, (float*)&GlossMult, 1);
+
+ SetRenderState(VERTEXALPHA, TRUE);
+ SetRenderState(SRCBLEND, BLENDONE);
+ SetRenderState(DESTBLEND, BLENDONE);
+ SetRenderState(ZWRITEENABLE, FALSE);
+ SetRenderState(ALPHATESTFUNC, ALPHAALWAYS);
+
+ InstanceData *inst = header->inst;
+ for(rw::uint32 i = 0; i < header->numMeshes; i++){
+ Material *m = inst->material;
+
+ if(m->texture){
+ Texture *tex = GetGlossTex(m);
+ if(tex){
+ d3d::setTexture(0, tex);
+ drawInst(header, inst);
+ }
+ }
+ inst++;
+ }
+
+ SetRenderState(ZWRITEENABLE, TRUE);
+ SetRenderState(ALPHATESTFUNC, ALPHAGREATEREQUAL);
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+ SetRenderState(DESTBLEND, BLENDINVSRCALPHA);
+}
+
+void
+CreateGlossPipe(void)
+{
+#include "shaders/neoGloss_VS.inc"
+ neoGloss_VS = rw::d3d::createVertexShader(neoGloss_VS_cso);
+ assert(neoGloss_VS);
+
+#include "shaders/neoGloss_PS.inc"
+ neoGloss_PS = rw::d3d::createPixelShader(neoGloss_PS_cso);
+ assert(neoGloss_PS);
+
+
+ rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
+ pipe->instanceCB = rw::d3d9::defaultInstanceCB;
+ pipe->uninstanceCB = rw::d3d9::defaultUninstanceCB;
+ pipe->renderCB = glossRenderCB;
+ glossPipe = pipe;
+}
+
+void
+DestroyGlossPipe(void)
+{
+ ((rw::d3d9::ObjPipeline*)glossPipe)->destroy();
+ glossPipe = nil;
+}
+
+
+
+/*
+ * Neo Rim pipes
+ */
+
+static void *neoRim_VS;
+static void *neoRimSkin_VS;
+
+static void
+uploadRimData(bool enable)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+
+ V3d viewVec = rw::engine->currentCamera->getFrame()->getLTM()->at;
+ d3ddevice->SetVertexShaderConstantF(VSLOC_viewVec, (float*)&viewVec, 1);
+ float rimData[4];
+ rimData[0] = Offset.Get();
+ rimData[1] = Scale.Get();
+ if(enable)
+ rimData[2] = Scaling.Get()*RimlightMult;
+ else
+ rimData[2] = 0.0f;
+ rimData[3] = 0.0f;
+ d3ddevice->SetVertexShaderConstantF(VSLOC_rimData, rimData, 1);
+ Color col = RampStart.Get();
+ d3ddevice->SetVertexShaderConstantF(VSLOC_rampStart, (float*)&col, 1);
+ col = RampEnd.Get();
+ d3ddevice->SetVertexShaderConstantF(VSLOC_rampEnd, (float*)&col, 1);
+}
+
+static void
+rimRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ int vsBits;
+ setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
+ setIndices(header->indexBuffer);
+ setVertexDeclaration(header->vertexDeclaration);
+
+ vsBits = lightingCB_Shader(atomic);
+ uploadMatrices(atomic->getFrame()->getLTM());
+
+ setVertexShader(neoRim_VS);
+
+ uploadRimData(atomic->geometry->flags & Geometry::LIGHT);
+
+ InstanceData *inst = header->inst;
+ for(rw::uint32 i = 0; i < header->numMeshes; i++){
+ Material *m = inst->material;
+
+ SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
+
+ setMaterial(m->color, m->surfaceProps);
+
+ if(m->texture){
+ d3d::setTexture(0, m->texture);
+ setPixelShader(default_tex_PS);
+ }else
+ setPixelShader(default_PS);
+
+ drawInst(header, inst);
+ inst++;
+ }
+}
+
+static void
+rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ int vsBits;
+
+ setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
+ 0, header->vertexStream[0].stride);
+ setIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
+ setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
+
+ vsBits = lightingCB_Shader(atomic);
+ uploadMatrices(atomic->getFrame()->getLTM());
+
+ uploadSkinMatrices(atomic);
+
+ setVertexShader(neoRimSkin_VS);
+
+ uploadRimData(atomic->geometry->flags & Geometry::LIGHT);
+
+ InstanceData *inst = header->inst;
+ for(rw::uint32 i = 0; i < header->numMeshes; i++){
+ Material *m = inst->material;
+
+ SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
+
+ setMaterial(m->color, m->surfaceProps);
+
+ if(inst->material->texture){
+ d3d::setTexture(0, m->texture);
+ setPixelShader(default_tex_PS);
+ }else
+ setPixelShader(default_PS);
+
+ drawInst(header, inst);
+ inst++;
+ }
+}
+
+void
+CreateRimLightPipes(void)
+{
+ if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n");
+ else{
+ char *fp = (char*)work_buff;
+ fp = ReadTweakValueTable(fp, RampStart);
+ fp = ReadTweakValueTable(fp, RampEnd);
+ fp = ReadTweakValueTable(fp, Offset);
+ fp = ReadTweakValueTable(fp, Scale);
+ fp = ReadTweakValueTable(fp, Scaling);
+ }
+
+
+#include "shaders/neoRim_VS.inc"
+ neoRim_VS = rw::d3d::createVertexShader(neoRim_VS_cso);
+ assert(neoRim_VS);
+
+#include "shaders/neoRimSkin_VS.inc"
+ neoRimSkin_VS = rw::d3d::createVertexShader(neoRimSkin_VS_cso);
+ assert(neoRimSkin_VS);
+
+
+ rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
+ pipe->instanceCB = rw::d3d9::defaultInstanceCB;
+ pipe->uninstanceCB = rw::d3d9::defaultUninstanceCB;
+ pipe->renderCB = rimRenderCB;
+ rimPipe = pipe;
+
+ pipe = rw::d3d9::ObjPipeline::create();
+ pipe->instanceCB = rw::d3d9::skinInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = rimSkinRenderCB;
+ rimSkinPipe = pipe;
+}
+
+void
+DestroyRimLightPipes(void)
+{
+ rw::d3d::destroyVertexShader(neoRim_VS);
+ neoRim_VS = nil;
+
+ rw::d3d::destroyVertexShader(neoRimSkin_VS);
+ neoRimSkin_VS = nil;
+
+ ((rw::d3d9::ObjPipeline*)rimPipe)->destroy();
+ rimPipe = nil;
+
+ ((rw::d3d9::ObjPipeline*)rimSkinPipe)->destroy();
+ rimSkinPipe = nil;
+}
+
+}
+
+#endif
+#endif
diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp
new file mode 100644
index 00000000..cb434ea1
--- /dev/null
+++ b/src/extras/custompipes_gl.cpp
@@ -0,0 +1,623 @@
+#include "common.h"
+
+#ifdef RW_OPENGL
+#ifdef EXTENDED_PIPELINES
+
+#include "main.h"
+#include "RwHelper.h"
+#include "Lights.h"
+#include "Timecycle.h"
+#include "FileMgr.h"
+#include "Clock.h"
+#include "Weather.h"
+#include "TxdStore.h"
+#include "Renderer.h"
+#include "World.h"
+#include "custompipes.h"
+
+#ifndef LIBRW
+#error "Need librw for EXTENDED_PIPELINES"
+#endif
+
+namespace CustomPipes {
+
+static int32 u_viewVec;
+static int32 u_rampStart;
+static int32 u_rampEnd;
+static int32 u_rimData;
+
+static int32 u_lightMap;
+
+static int32 u_eye;
+static int32 u_reflProps;
+static int32 u_specDir;
+static int32 u_specColor;
+
+#define U(i) currentShader->uniformLocations[i]
+
+/*
+ * Neo Vehicle pipe
+ */
+
+rw::gl3::Shader *neoVehicleShader;
+
+static void
+uploadSpecLights(void)
+{
+ using namespace rw::gl3;
+
+ rw::RGBAf colors[1 + NUMEXTRADIRECTIONALS];
+ struct {
+ rw::V3d dir;
+ float power;
+ } dirs[1 + NUMEXTRADIRECTIONALS];
+ memset(colors, 0, sizeof(colors));
+ memset(dirs, 0, sizeof(dirs));
+ for(int i = 0; i < 1+NUMEXTRADIRECTIONALS; i++)
+ dirs[i].power = 1.0f;
+ float power = Power.Get();
+ Color speccol = SpecColor.Get();
+ colors[0].red = speccol.r;
+ colors[0].green = speccol.g;
+ colors[0].blue = speccol.b;
+ dirs[0].dir = pDirect->getFrame()->getLTM()->at;
+ dirs[0].power = power;
+ for(int i = 0; i < NUMEXTRADIRECTIONALS; i++){
+ if(pExtraDirectionals[i]->getFlags() & rw::Light::LIGHTATOMICS){
+ colors[1+i] = pExtraDirectionals[i]->color;
+ dirs[1+i].dir = pExtraDirectionals[i]->getFrame()->getLTM()->at;
+ dirs[1+i].power = power*2.0f;
+ }
+ }
+ glUniform4fv(U(u_specDir), 1 + NUMEXTRADIRECTIONALS, (float*)&dirs);
+ glUniform4fv(U(u_specColor), 1 + NUMEXTRADIRECTIONALS, (float*)&colors);
+}
+
+static void
+vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ // TODO: make this less of a kludge
+ if(VehiclePipeSwitch == VEHICLEPIPE_MATFX){
+ matFXGlobals.pipelines[rw::platform]->render(atomic);
+ return;
+ }
+
+ Material *m;
+
+ setWorldMatrix(atomic->getFrame()->getLTM());
+ lightingCB(atomic);
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(header->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
+ setAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+
+ InstanceData *inst = header->inst;
+ rw::int32 n = header->numMeshes;
+
+ neoVehicleShader->use();
+
+ V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
+ glUniform3fv(U(u_eye), 1, (float*)&eyePos);
+
+ uploadSpecLights();
+
+ float reflProps[4];
+ reflProps[0] = Fresnel.Get();
+ reflProps[1] = SpecColor.Get().a;
+
+ setTexture(1, EnvMapTex);
+
+ SetRenderState(SRCBLEND, BLENDONE);
+
+ while(n--){
+ m = inst->material;
+
+ setMaterial(m->color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
+
+ reflProps[2] = m->surfaceProps.specular * VehicleShininess;
+ reflProps[3] = m->surfaceProps.specular == 0.0f ? 0.0f : VehicleSpecularity;
+ glUniform4fv(U(u_reflProps), 1, reflProps);
+
+ drawInst(header, inst);
+ inst++;
+ }
+
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+}
+
+void
+CreateVehiclePipe(void)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/carTweakingTable.dat'\n");
+ else{
+ char *fp = (char*)work_buff;
+ fp = ReadTweakValueTable(fp, Fresnel);
+ fp = ReadTweakValueTable(fp, Power);
+ fp = ReadTweakValueTable(fp, DiffColor);
+ fp = ReadTweakValueTable(fp, SpecColor);
+ }
+
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/neoVehicle_fs_gl2.inc"
+#include "gl2_shaders/neoVehicle_vs_gl2.inc"
+#else
+#include "shaders/neoVehicle_fs_gl3.inc"
+#include "shaders/neoVehicle_vs_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, neoVehicle_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, neoVehicle_frag_src, nil };
+ neoVehicleShader = Shader::create(vs, fs);
+ assert(neoVehicleShader);
+ }
+
+
+ rw::gl3::ObjPipeline *pipe = rw::gl3::ObjPipeline::create();
+ pipe->instanceCB = rw::gl3::defaultInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = vehicleRenderCB;
+ vehiclePipe = pipe;
+}
+
+void
+DestroyVehiclePipe(void)
+{
+ neoVehicleShader->destroy();
+ neoVehicleShader = nil;
+
+ ((rw::gl3::ObjPipeline*)vehiclePipe)->destroy();
+ vehiclePipe = nil;
+}
+
+
+
+/*
+ * Neo World pipe
+ */
+
+rw::gl3::Shader *neoWorldShader;
+
+static void
+worldRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ Material *m;
+
+ setWorldMatrix(atomic->getFrame()->getLTM());
+ lightingCB(atomic);
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(header->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
+ setAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+
+ InstanceData *inst = header->inst;
+ rw::int32 n = header->numMeshes;
+
+ neoWorldShader->use();
+
+ float lightfactor[4];
+
+ while(n--){
+ m = inst->material;
+
+ if(MatFX::getEffects(m) == MatFX::DUAL){
+ MatFX *matfx = MatFX::get(m);
+ Texture *dualtex = matfx->getDualTexture();
+ if(dualtex == nil)
+ goto notex;
+ setTexture(1, dualtex);
+ lightfactor[0] = lightfactor[1] = lightfactor[2] = WorldLightmapBlend.Get()*LightmapMult;
+ }else{
+ notex:
+ setTexture(1, nil);
+ lightfactor[0] = lightfactor[1] = lightfactor[2] = 0.0f;
+ }
+ lightfactor[3] = m->color.alpha/255.0f;
+ glUniform4fv(U(u_lightMap), 1, lightfactor);
+
+ RGBA color = { 255, 255, 255, m->color.alpha };
+ setMaterial(color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
+
+ drawInst(header, inst);
+ inst++;
+ }
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+}
+
+void
+CreateWorldPipe(void)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n");
+ else
+ ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/neoWorldIII_fs_gl2.inc"
+#include "gl2_shaders/default_UV2_gl2.inc"
+#else
+#include "shaders/neoWorldVC_fs_gl3.inc"
+#include "shaders/default_UV2_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, default_UV2_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, neoWorldVC_frag_src, nil };
+ neoWorldShader = Shader::create(vs, fs);
+ assert(neoWorldShader);
+ }
+
+
+ rw::gl3::ObjPipeline *pipe = rw::gl3::ObjPipeline::create();
+ pipe->instanceCB = rw::gl3::defaultInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = worldRenderCB;
+ worldPipe = pipe;
+}
+
+void
+DestroyWorldPipe(void)
+{
+ neoWorldShader->destroy();
+ neoWorldShader = nil;
+
+ ((rw::gl3::ObjPipeline*)worldPipe)->destroy();
+ worldPipe = nil;
+}
+
+
+
+
+/*
+ * Neo Gloss pipe
+ */
+
+rw::gl3::Shader *neoGlossShader;
+
+static void
+glossRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ worldRenderCB(atomic, header);
+
+ Material *m;
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(header->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
+ setAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+
+ InstanceData *inst = header->inst;
+ rw::int32 n = header->numMeshes;
+
+ neoGlossShader->use();
+
+ V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
+ glUniform3fv(U(u_eye), 1, (float*)&eyePos);
+ glUniform4fv(U(u_reflProps), 1, (float*)&GlossMult);
+
+ SetRenderState(VERTEXALPHA, TRUE);
+ SetRenderState(SRCBLEND, BLENDONE);
+ SetRenderState(DESTBLEND, BLENDONE);
+ SetRenderState(ZWRITEENABLE, FALSE);
+ SetRenderState(ALPHATESTFUNC, ALPHAALWAYS);
+
+ while(n--){
+ m = inst->material;
+
+ RGBA color = { 255, 255, 255, m->color.alpha };
+ setMaterial(color, m->surfaceProps);
+
+ if(m->texture){
+ Texture *tex = GetGlossTex(m);
+ if(tex){
+ setTexture(0, tex);
+ drawInst(header, inst);
+ }
+ }
+ inst++;
+ }
+
+ SetRenderState(ZWRITEENABLE, TRUE);
+ SetRenderState(ALPHATESTFUNC, ALPHAGREATEREQUAL);
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+ SetRenderState(DESTBLEND, BLENDINVSRCALPHA);
+
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+}
+
+void
+CreateGlossPipe(void)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/neoGloss_fs_gl2.inc"
+#include "gl2_shaders/neoGloss_vs_gl2.inc"
+#else
+#include "shaders/neoGloss_fs_gl3.inc"
+#include "shaders/neoGloss_vs_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, neoGloss_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, neoGloss_frag_src, nil };
+ neoGlossShader = Shader::create(vs, fs);
+ assert(neoGlossShader);
+ }
+
+ rw::gl3::ObjPipeline *pipe = rw::gl3::ObjPipeline::create();
+ pipe->instanceCB = rw::gl3::defaultInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = glossRenderCB;
+ glossPipe = pipe;
+}
+
+void
+DestroyGlossPipe(void)
+{
+ neoGlossShader->destroy();
+ neoGlossShader = nil;
+
+ ((rw::gl3::ObjPipeline*)glossPipe)->destroy();
+ glossPipe = nil;
+}
+
+
+
+/*
+ * Neo Rim pipes
+ */
+
+rw::gl3::Shader *neoRimShader;
+rw::gl3::Shader *neoRimSkinShader;
+
+static void
+uploadRimData(bool enable)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ V3d viewVec = rw::engine->currentCamera->getFrame()->getLTM()->at;
+ glUniform3fv(U(u_viewVec), 1, (float*)&viewVec);
+ float rimData[4];
+ rimData[0] = Offset.Get();
+ rimData[1] = Scale.Get();
+ if(enable)
+ rimData[2] = Scaling.Get()*RimlightMult;
+ else
+ rimData[2] = 0.0f;
+ rimData[3] = 0.0f;
+ glUniform3fv(U(u_rimData), 1, rimData);
+ Color col = RampStart.Get();
+ glUniform4fv(U(u_rampStart), 1, (float*)&col);
+ col = RampEnd.Get();
+ glUniform4fv(U(u_rampEnd), 1, (float*)&col);
+}
+
+static void
+rimSkinRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ Material *m;
+
+ setWorldMatrix(atomic->getFrame()->getLTM());
+ lightingCB(atomic);
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(header->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
+ setAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+
+ InstanceData *inst = header->inst;
+ rw::int32 n = header->numMeshes;
+
+ neoRimSkinShader->use();
+
+ uploadRimData(atomic->geometry->flags & Geometry::LIGHT);
+
+ uploadSkinMatrices(atomic);
+
+ while(n--){
+ m = inst->material;
+
+ setMaterial(m->color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
+
+ drawInst(header, inst);
+ inst++;
+ }
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+}
+
+static void
+rimRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ Material *m;
+
+ setWorldMatrix(atomic->getFrame()->getLTM());
+ lightingCB(atomic);
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(header->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
+ setAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+
+ InstanceData *inst = header->inst;
+ rw::int32 n = header->numMeshes;
+
+ neoRimShader->use();
+
+ uploadRimData(atomic->geometry->flags & Geometry::LIGHT);
+
+ while(n--){
+ m = inst->material;
+
+ setMaterial(m->color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
+
+ drawInst(header, inst);
+ inst++;
+ }
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(header->attribDesc, header->numAttribs);
+#endif
+}
+
+void
+CreateRimLightPipes(void)
+{
+ using namespace rw::gl3;
+
+ if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n");
+ else{
+ char *fp = (char*)work_buff;
+ fp = ReadTweakValueTable(fp, RampStart);
+ fp = ReadTweakValueTable(fp, RampEnd);
+ fp = ReadTweakValueTable(fp, Offset);
+ fp = ReadTweakValueTable(fp, Scale);
+ fp = ReadTweakValueTable(fp, Scaling);
+ }
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/simple_fs_gl2.inc"
+#include "gl2_shaders/neoRimSkin_gl2.inc"
+#else
+#include "shaders/simple_fs_gl3.inc"
+#include "shaders/neoRimSkin_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, neoRimSkin_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
+ neoRimSkinShader = Shader::create(vs, fs);
+ assert(neoRimSkinShader);
+ }
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/simple_fs_gl2.inc"
+#include "gl2_shaders/neoRim_gl2.inc"
+#else
+#include "shaders/simple_fs_gl3.inc"
+#include "shaders/neoRim_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, neoRim_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
+ neoRimShader = Shader::create(vs, fs);
+ assert(neoRimShader);
+ }
+
+
+ rw::gl3::ObjPipeline *pipe = rw::gl3::ObjPipeline::create();
+ pipe->instanceCB = rw::gl3::defaultInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = rimRenderCB;
+ rimPipe = pipe;
+
+ pipe = rw::gl3::ObjPipeline::create();
+ pipe->instanceCB = rw::gl3::skinInstanceCB;
+ pipe->uninstanceCB = nil;
+ pipe->renderCB = rimSkinRenderCB;
+ rimSkinPipe = pipe;
+}
+
+void
+DestroyRimLightPipes(void)
+{
+ neoRimShader->destroy();
+ neoRimShader = nil;
+
+ neoRimSkinShader->destroy();
+ neoRimSkinShader = nil;
+
+ ((rw::gl3::ObjPipeline*)rimPipe)->destroy();
+ rimPipe = nil;
+
+ ((rw::gl3::ObjPipeline*)rimSkinPipe)->destroy();
+ rimSkinPipe = nil;
+}
+
+
+
+void
+CustomPipeRegisterGL(void)
+{
+ u_viewVec = rw::gl3::registerUniform("u_viewVec");
+ u_rampStart = rw::gl3::registerUniform("u_rampStart");
+ u_rampEnd = rw::gl3::registerUniform("u_rampEnd");
+ u_rimData = rw::gl3::registerUniform("u_rimData");
+
+ u_lightMap = rw::gl3::registerUniform("u_lightMap");
+
+ u_eye = rw::gl3::registerUniform("u_eye");
+ u_reflProps = rw::gl3::registerUniform("u_reflProps");
+ u_specDir = rw::gl3::registerUniform("u_specDir");
+ u_specColor = rw::gl3::registerUniform("u_specColor");
+}
+
+
+}
+
+#endif
+#endif
diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp
new file mode 100644
index 00000000..7e9df4e7
--- /dev/null
+++ b/src/extras/postfx.cpp
@@ -0,0 +1,492 @@
+#define WITHWINDOWS
+#define WITH_D3D
+#include "common.h"
+
+#ifdef EXTENDED_COLOURFILTER
+
+#ifndef LIBRW
+#error "Need librw for EXTENDED_COLOURFILTER"
+#endif
+
+#include "RwHelper.h"
+#include "Camera.h"
+#include "MBlur.h"
+#include "postfx.h"
+
+RwRaster *CPostFX::pFrontBuffer;
+RwRaster *CPostFX::pBackBuffer;
+bool CPostFX::bJustInitialised;
+int CPostFX::EffectSwitch = POSTFX_NORMAL;
+bool CPostFX::BlurOn = false;
+bool CPostFX::MotionBlurOn = false;
+
+static RwIm2DVertex Vertex[4];
+static RwIm2DVertex Vertex2[4];
+static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
+
+#ifdef RW_D3D9
+void *colourfilterVC_PS;
+void *contrast_PS;
+#endif
+#ifdef RW_OPENGL
+int32 u_blurcolor;
+int32 u_contrastAdd;
+int32 u_contrastMult;
+rw::gl3::Shader *colourFilterVC;
+rw::gl3::Shader *contrast;
+#endif
+
+void
+CPostFX::InitOnce(void)
+{
+#ifdef RW_OPENGL
+ u_blurcolor = rw::gl3::registerUniform("u_blurcolor");
+ u_contrastAdd = rw::gl3::registerUniform("u_contrastAdd");
+ u_contrastMult = rw::gl3::registerUniform("u_contrastMult");
+#endif
+}
+
+void
+CPostFX::Open(RwCamera *cam)
+{
+ uint32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1);
+ uint32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1);
+ uint32 depth = RwRasterGetDepth(RwCameraGetRaster(cam));
+ pFrontBuffer = RwRasterCreate(width, height, depth, rwRASTERTYPECAMERATEXTURE);
+ pBackBuffer = RwRasterCreate(width, height, depth, rwRASTERTYPECAMERATEXTURE);
+ bJustInitialised = true;
+
+ float zero, xmax, ymax;
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ zero = HALFPX;
+ xmax = width + HALFPX;
+ ymax = height + HALFPX;
+ }else{
+ zero = -HALFPX;
+ xmax = width - HALFPX;
+ ymax = height - HALFPX;
+ }
+
+ RwIm2DVertexSetScreenX(&Vertex[0], zero);
+ RwIm2DVertexSetScreenY(&Vertex[0], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[1], zero);
+ RwIm2DVertexSetScreenY(&Vertex[1], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[2], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[2], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex[3], xmax);
+ RwIm2DVertexSetScreenY(&Vertex[3], zero);
+ RwIm2DVertexSetScreenZ(&Vertex[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
+
+
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
+
+
+#ifdef RW_D3D9
+#include "shaders/colourfilterVC_PS.inc"
+ colourfilterVC_PS = rw::d3d::createPixelShader(colourfilterVC_PS_cso);
+#include "shaders/contrastPS.inc"
+ contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
+#endif
+#ifdef RW_OPENGL
+ using namespace rw::gl3;
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/im2d_gl2.inc"
+#include "gl2_shaders/colourfilterVC_fs_gl2.inc"
+#else
+#include "shaders/im2d_gl3.inc"
+#include "shaders/colourfilterVC_fs_gl3.inc"
+#endif
+ const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
+ colourFilterVC = Shader::create(vs, fs);
+ assert(colourFilterVC);
+ }
+
+ {
+#ifdef RW_GLES2
+#include "gl2_shaders/im2d_gl2.inc"
+#include "gl2_shaders/contrast_fs_gl2.inc"
+#else
+#include "shaders/im2d_gl3.inc"
+#include "shaders/contrast_fs_gl3.inc"
+ const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil };
+ contrast = Shader::create(vs, fs);
+ assert(contrast);
+#endif
+ }
+
+#endif
+}
+
+void
+CPostFX::Close(void)
+{
+ if(pFrontBuffer){
+ RwRasterDestroy(pFrontBuffer);
+ pFrontBuffer = nil;
+ }
+ if(pBackBuffer){
+ RwRasterDestroy(pBackBuffer);
+ pBackBuffer = nil;
+ }
+#ifdef RW_D3D9
+ if(colourfilterVC_PS){
+ rw::d3d::destroyPixelShader(colourfilterVC_PS);
+ colourfilterVC_PS = nil;
+ }
+ if(contrast_PS){
+ rw::d3d::destroyPixelShader(contrast_PS);
+ contrast_PS = nil;
+ }
+#endif
+#ifdef RW_OPENGL
+ if(colourFilterVC){
+ colourFilterVC->destroy();
+ colourFilterVC = nil;
+ }
+ if(contrast){
+ contrast->destroy();
+ contrast = nil;
+ }
+#endif
+}
+
+void
+CPostFX::RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30);
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
+
+
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
+}
+
+void
+CPostFX::RenderOverlaySniper(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, 80);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+}
+
+float CPostFX::Intensity = 1.0f;
+
+void
+CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pBackBuffer);
+
+ if(EffectSwitch == POSTFX_MOBILE){
+ float mult[3], add[3];
+ mult[0] = (r-64)/256.0f + 1.4f;
+ mult[1] = (g-64)/256.0f + 1.4f;
+ mult[2] = (b-64)/256.0f + 1.4f;
+ add[0] = r/1536.f - 0.05f;
+ add[1] = g/1536.f - 0.05f;
+ add[2] = b/1536.f - 0.05f;
+#ifdef RW_D3D9
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(10, mult, 1);
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(11, add, 1);
+
+ rw::d3d::im2dOverridePS = contrast_PS;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = contrast;
+ contrast->use();
+ glUniform3fv(contrast->uniformLocations[u_contrastMult], 1, mult);
+ glUniform3fv(contrast->uniformLocations[u_contrastAdd], 1, add);
+#endif
+ }else{
+ float f = Intensity;
+ float blurcolors[4];
+ blurcolors[0] = r*f/255.0f;
+ blurcolors[1] = g*f/255.0f;
+ blurcolors[2] = b*f/255.0f;
+ blurcolors[3] = 30/255.0f;
+#ifdef RW_D3D9
+ rw::d3d::d3ddevice->SetPixelShaderConstantF(10, blurcolors, 1);
+ rw::d3d::im2dOverridePS = colourfilterVC_PS;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = colourFilterVC;
+ colourFilterVC->use();
+ glUniform4fv(colourFilterVC->uniformLocations[u_blurcolor], 1, blurcolors);
+#endif
+ }
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+#ifdef RW_D3D9
+ rw::d3d::im2dOverridePS = nil;
+#endif
+#ifdef RW_OPENGL
+ rw::gl3::im2dOverrideShader = nil;
+#endif
+}
+
+void
+CPostFX::RenderMotionBlur(RwCamera *cam, uint32 blur)
+{
+ if(blur == 0)
+ return;
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, blur);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, blur);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+}
+
+bool
+CPostFX::NeedBackBuffer(void)
+{
+ // Current frame -- needed for non-blur effect
+ switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ return false;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn)
+ return false;
+ else
+ return true;
+ case POSTFX_MOBILE:
+ return true;
+ }
+ return false;
+}
+
+bool
+CPostFX::NeedFrontBuffer(int32 type)
+{
+ // Last frame -- needed for motion blur
+ if(CMBlur::Drunkness > 0.0f)
+ return true;
+ if(type == MOTION_BLUR_SNIPER)
+ return true;
+
+ switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ return false;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn)
+ return true;
+ else
+ return false;
+ case POSTFX_MOBILE:
+ return false;
+ }
+ return false;
+}
+
+void
+CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
+{
+ if(pFrontBuffer == nil)
+ Open(cam);
+ assert(pFrontBuffer);
+ assert(pBackBuffer);
+
+ if(type == MOTION_BLUR_LIGHT_SCENE){
+ SmoothColor(red, green, blue, blur);
+ red = AvgRed;
+ green = AvgGreen;
+ blue = AvgBlue;
+ blur = AvgAlpha;
+ }
+
+ if(NeedBackBuffer()){
+ RwRasterPushContext(pBackBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+ }
+
+ DefinedState();
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+
+ if(type == MOTION_BLUR_SNIPER){
+ if(!bJustInitialised)
+ RenderOverlaySniper(cam, red, green, blue, blur);
+ }else switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ break;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn){
+ if(!bJustInitialised)
+ RenderOverlayBlur(cam, red, green, blue, blur);
+ }else{
+ RenderOverlayShader(cam, red, green, blue, blur);
+ }
+ break;
+ case POSTFX_MOBILE:
+ RenderOverlayShader(cam, red, green, blue, blur);
+ break;
+ }
+
+ if(!bJustInitialised)
+ RenderMotionBlur(cam, 175.0f * CMBlur::Drunkness);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ if(NeedFrontBuffer(type)){
+ RwRasterPushContext(pFrontBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+ bJustInitialised = false;
+ }else
+ bJustInitialised = true;
+}
+
+int CPostFX::PrevRed[NUMAVERAGE], CPostFX::AvgRed;
+int CPostFX::PrevGreen[NUMAVERAGE], CPostFX::AvgGreen;
+int CPostFX::PrevBlue[NUMAVERAGE], CPostFX::AvgBlue;
+int CPostFX::PrevAlpha[NUMAVERAGE], CPostFX::AvgAlpha;
+int CPostFX::Next;
+int CPostFX::NumValues;
+
+// This is rather annoying...the blur color can flicker slightly
+// which becomes very visible when amplified by the shader
+void
+CPostFX::SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha)
+{
+ PrevRed[Next] = red;
+ PrevGreen[Next] = green;
+ PrevBlue[Next] = blue;
+ PrevAlpha[Next] = alpha;
+ Next = (Next+1) % NUMAVERAGE;
+ NumValues = Min(NumValues+1, NUMAVERAGE);
+
+ AvgRed = 0;
+ AvgGreen = 0;
+ AvgBlue = 0;
+ AvgAlpha = 0;
+ for(int i = 0; i < NumValues; i++){
+ AvgRed += PrevRed[i];
+ AvgGreen += PrevGreen[i];
+ AvgBlue += PrevBlue[i];
+ AvgAlpha += PrevAlpha[i];
+ }
+ AvgRed /= NumValues;
+ AvgGreen /= NumValues;
+ AvgBlue /= NumValues;
+ AvgAlpha /= NumValues;
+}
+
+#endif
diff --git a/src/extras/postfx.h b/src/extras/postfx.h
new file mode 100644
index 00000000..ace2e4a8
--- /dev/null
+++ b/src/extras/postfx.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#ifdef EXTENDED_COLOURFILTER
+
+class CPostFX
+{
+public:
+ enum {
+ POSTFX_OFF,
+ POSTFX_SIMPLE,
+ POSTFX_NORMAL,
+ POSTFX_MOBILE
+ };
+ static RwRaster *pFrontBuffer;
+ static RwRaster *pBackBuffer;
+ static bool bJustInitialised;
+ static int EffectSwitch;
+ static bool BlurOn; // or use CMblur for that?
+ static bool MotionBlurOn; // or use CMblur for that?
+ static float Intensity;
+
+ // smooth blur color
+ enum { NUMAVERAGE = 20 };
+ static int PrevRed[NUMAVERAGE], AvgRed;
+ static int PrevGreen[NUMAVERAGE], AvgGreen;
+ static int PrevBlue[NUMAVERAGE], AvgBlue;
+ static int PrevAlpha[NUMAVERAGE], AvgAlpha;
+ static int Next;
+ static int NumValues;
+
+ static void InitOnce(void);
+ static void Open(RwCamera *cam);
+ static void Close(void);
+ static void RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderOverlaySniper(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
+ static void RenderMotionBlur(RwCamera *cam, uint32 blur);
+ static void Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha);
+ static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
+ static bool NeedBackBuffer(void);
+ static bool NeedFrontBuffer(int32 type);
+ static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
+};
+
+#endif
diff --git a/src/extras/shaders/Makefile b/src/extras/shaders/Makefile
new file mode 100644
index 00000000..605190c9
--- /dev/null
+++ b/src/extras/shaders/Makefile
@@ -0,0 +1,67 @@
+all: im2d_gl3.inc simple_fs_gl3.inc default_UV2_gl3.inc \
+ colourfilterVC_fs_gl3.inc contrast_fs_gl3.inc \
+ neoRim_gl3.inc neoRimSkin_gl3.inc \
+ neoWorldVC_fs_gl3.inc neoGloss_vs_gl3.inc neoGloss_fs_gl3.inc \
+ neoVehicle_vs_gl3.inc neoVehicle_fs_gl3.inc
+
+im2d_gl3.inc: im2d.vert
+ (echo 'const char *im2d_vert_src =';\
+ sed 's/..*/"&\\n"/' im2d.vert;\
+ echo ';') >im2d_gl3.inc
+
+colourfilterVC_fs_gl3.inc: colourfilterVC.frag
+ (echo 'const char *colourfilterVC_frag_src =';\
+ sed 's/..*/"&\\n"/' colourfilterVC.frag;\
+ echo ';') >colourfilterVC_fs_gl3.inc
+simple_fs_gl3.inc: simple.frag
+ (echo 'const char *simple_frag_src =';\
+ sed 's/..*/"&\\n"/' simple.frag;\
+ echo ';') >simple_fs_gl3.inc
+
+default_UV2_gl3.inc: default_UV2.vert
+ (echo 'const char *default_UV2_vert_src =';\
+ sed 's/..*/"&\\n"/' default_UV2.vert;\
+ echo ';') >default_UV2_gl3.inc
+
+
+
+contrast_fs_gl3.inc: contrast.frag
+ (echo 'const char *contrast_frag_src =';\
+ sed 's/..*/"&\\n"/' contrast.frag;\
+ echo ';') >contrast_fs_gl3.inc
+
+
+neoRim_gl3.inc: neoRim.vert
+ (echo 'const char *neoRim_vert_src =';\
+ sed 's/..*/"&\\n"/' neoRim.vert;\
+ echo ';') >neoRim_gl3.inc
+
+neoRimSkin_gl3.inc: neoRimSkin.vert
+ (echo 'const char *neoRimSkin_vert_src =';\
+ sed 's/..*/"&\\n"/' neoRimSkin.vert;\
+ echo ';') >neoRimSkin_gl3.inc
+
+neoWorldVC_fs_gl3.inc: neoWorldVC.frag
+ (echo 'const char *neoWorldVC_frag_src =';\
+ sed 's/..*/"&\\n"/' neoWorldVC.frag;\
+ echo ';') >neoWorldVC_fs_gl3.inc
+
+neoGloss_fs_gl3.inc: neoGloss.frag
+ (echo 'const char *neoGloss_frag_src =';\
+ sed 's/..*/"&\\n"/' neoGloss.frag;\
+ echo ';') >neoGloss_fs_gl3.inc
+
+neoGloss_vs_gl3.inc: neoGloss.vert
+ (echo 'const char *neoGloss_vert_src =';\
+ sed 's/..*/"&\\n"/' neoGloss.vert;\
+ echo ';') >neoGloss_vs_gl3.inc
+
+neoVehicle_vs_gl3.inc: neoVehicle.vert
+ (echo 'const char *neoVehicle_vert_src =';\
+ sed 's/..*/"&\\n"/' neoVehicle.vert;\
+ echo ';') >neoVehicle_vs_gl3.inc
+
+neoVehicle_fs_gl3.inc: neoVehicle.frag
+ (echo 'const char *neoVehicle_frag_src =';\
+ sed 's/..*/"&\\n"/' neoVehicle.frag;\
+ echo ';') >neoVehicle_fs_gl3.inc
diff --git a/src/extras/shaders/colourfilterVC.frag b/src/extras/shaders/colourfilterVC.frag
new file mode 100644
index 00000000..5069af52
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC.frag
@@ -0,0 +1,26 @@
+uniform sampler2D tex0;
+uniform vec4 u_blurcolor;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ float a = u_blurcolor.a;
+ vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);
+ vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec4 prev = dst;
+ for(int i = 0; i < 5; i++){
+ vec4 tmp = dst*(1.0-a) + prev*doublec*a;
+ tmp += prev*u_blurcolor;
+ tmp += prev*u_blurcolor;
+ prev = clamp(tmp, 0.0, 1.0);
+ }
+ color.rgb = prev.rgb;
+ color.a = 1.0f;
+}
+
diff --git a/src/extras/shaders/colourfilterVC_PS.cso b/src/extras/shaders/colourfilterVC_PS.cso
new file mode 100644
index 00000000..4b0e9f3f
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/colourfilterVC_PS.hlsl b/src/extras/shaders/colourfilterVC_PS.hlsl
new file mode 100644
index 00000000..1e62950b
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.hlsl
@@ -0,0 +1,23 @@
+sampler2D tex : register(s0);
+float4 blurcol : register(c10);
+
+//float4 blurcols[10] : register(c15);
+
+
+float4 main(in float2 texcoord : TEXCOORD0) : COLOR0
+{
+ float a = blurcol.a;
+
+ float4 doublec = saturate(blurcol*2);
+ float4 dst = tex2D(tex, texcoord.xy);
+ float4 prev = dst;
+ for(int i = 0; i < 5; i++){
+// float4 doublec = saturate(blurcol*2);
+ float4 tmp = dst*(1-a) + prev*doublec*a;
+ tmp += prev*blurcol;
+ tmp += prev*blurcol;
+ prev = saturate(tmp);
+ }
+ prev.a = 1.0f;
+ return prev;
+}
diff --git a/src/extras/shaders/colourfilterVC_PS.inc b/src/extras/shaders/colourfilterVC_PS.inc
new file mode 100644
index 00000000..daa18360
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.inc
@@ -0,0 +1,56 @@
+static unsigned char colourfilterVC_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2b, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00,
+ 0x01, 0x00, 0x2a, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x75, 0x72,
+ 0x63, 0x6f, 0x6c, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
+ 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d,
+ 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29,
+ 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72,
+ 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e,
+ 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00,
+ 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xb0,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0,
+ 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0,
+ 0x00, 0x08, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x17, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x0a, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xff, 0xa0,
+ 0x02, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x55, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/colourfilterVC_fs_gl3.inc b/src/extras/shaders/colourfilterVC_fs_gl3.inc
new file mode 100644
index 00000000..d11cdc5a
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_fs_gl3.inc
@@ -0,0 +1,28 @@
+const char *colourfilterVC_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform vec4 u_blurcolor;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" float a = u_blurcolor.a;\n"
+" vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);\n"
+" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec4 prev = dst;\n"
+" for(int i = 0; i < 5; i++){\n"
+" vec4 tmp = dst*(1.0-a) + prev*doublec*a;\n"
+" tmp += prev*u_blurcolor;\n"
+" tmp += prev*u_blurcolor;\n"
+" prev = clamp(tmp, 0.0, 1.0);\n"
+" }\n"
+" color.rgb = prev.rgb;\n"
+" color.a = 1.0f;\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/contrast.frag b/src/extras/shaders/contrast.frag
new file mode 100644
index 00000000..d6dec478
--- /dev/null
+++ b/src/extras/shaders/contrast.frag
@@ -0,0 +1,18 @@
+uniform sampler2D tex0;
+uniform vec3 u_contrastAdd;
+uniform vec3 u_contrastMult;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;
+ color.a = 1.0f;
+}
+
diff --git a/src/extras/shaders/contrastPS.cso b/src/extras/shaders/contrastPS.cso
new file mode 100644
index 00000000..a87c48d7
--- /dev/null
+++ b/src/extras/shaders/contrastPS.cso
Binary files differ
diff --git a/src/extras/shaders/contrastPS.hlsl b/src/extras/shaders/contrastPS.hlsl
new file mode 100644
index 00000000..a1de1d81
--- /dev/null
+++ b/src/extras/shaders/contrastPS.hlsl
@@ -0,0 +1,21 @@
+struct PS_INPUT
+{
+ float4 position : POSITION;
+ float3 texcoord0 : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+uniform float3 contrastMult : register(c10);
+uniform float3 contrastAdd : register(c11);
+
+sampler2D tex : register(s0);
+
+float4
+main(PS_INPUT In) : COLOR
+{
+ float4 dst = tex2D(tex, In.texcoord0.xy);
+
+ dst.rgb = dst.rgb*contrastMult + contrastAdd;
+ dst.a = 1.0;
+ return dst;
+}
diff --git a/src/extras/shaders/contrastPS.inc b/src/extras/shaders/contrastPS.inc
new file mode 100644
index 00000000..5386792f
--- /dev/null
+++ b/src/extras/shaders/contrastPS.inc
@@ -0,0 +1,31 @@
+static unsigned char contrastPS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x35, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x98, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0b, 0x00,
+ 0x01, 0x00, 0x2e, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x2a, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74,
+ 0x41, 0x64, 0x64, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x74,
+ 0x72, 0x61, 0x73, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x00, 0x74, 0x65, 0x78,
+ 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
+ 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
+ 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+ 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
+ 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x0b, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/contrast_fs_gl3.inc b/src/extras/shaders/contrast_fs_gl3.inc
new file mode 100644
index 00000000..58aaf079
--- /dev/null
+++ b/src/extras/shaders/contrast_fs_gl3.inc
@@ -0,0 +1,20 @@
+const char *contrast_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform vec3 u_contrastAdd;\n"
+"uniform vec3 u_contrastMult;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;\n"
+" color.a = 1.0f;\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/default_UV2.vert b/src/extras/shaders/default_UV2.vert
new file mode 100644
index 00000000..3dbad20f
--- /dev/null
+++ b/src/extras/shaders/default_UV2.vert
@@ -0,0 +1,29 @@
+layout(location = 0) in vec3 in_pos;
+layout(location = 1) in vec3 in_normal;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+layout(location = 4) in vec2 in_tex1;
+
+out vec4 v_color;
+out vec2 v_tex0;
+out vec2 v_tex1;
+out float v_fog;
+
+void
+main(void)
+{
+ vec4 Vertex = u_world * vec4(in_pos, 1.0);
+ gl_Position = u_proj * u_view * Vertex;
+ vec3 Normal = mat3(u_world) * in_normal;
+
+ v_tex0 = in_tex0;
+ v_tex1 = in_tex1;
+
+ v_color = in_color;
+ v_color.rgb += u_ambLight.rgb*surfAmbient;
+ v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
+ v_color = clamp(v_color, 0.0, 1.0);
+ v_color *= u_matColor;
+
+ v_fog = DoFog(gl_Position.w);
+}
diff --git a/src/extras/shaders/default_UV2_VS.cso b/src/extras/shaders/default_UV2_VS.cso
new file mode 100644
index 00000000..5a48c663
--- /dev/null
+++ b/src/extras/shaders/default_UV2_VS.cso
Binary files differ
diff --git a/src/extras/shaders/default_UV2_VS.hlsl b/src/extras/shaders/default_UV2_VS.hlsl
new file mode 100644
index 00000000..e78a9907
--- /dev/null
+++ b/src/extras/shaders/default_UV2_VS.hlsl
@@ -0,0 +1,54 @@
+#include "standardConstants.h"
+
+struct VS_in
+{
+ float4 Position : POSITION;
+ float3 Normal : NORMAL;
+ float2 TexCoord : TEXCOORD0;
+ float2 TexCoord1 : TEXCOORD1;
+ float4 Prelight : COLOR0;
+};
+
+struct VS_out {
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0; // also fog
+ float2 TexCoord1 : TEXCOORD1;
+ float4 Color : COLOR0;
+};
+
+
+VS_out main(in VS_in input)
+{
+ VS_out output;
+
+ output.Position = mul(combinedMat, input.Position);
+ float3 Vertex = mul(worldMat, input.Position).xyz;
+ float3 Normal = mul(normalMat, input.Normal);
+
+ output.TexCoord0.xy = input.TexCoord;
+ output.TexCoord1.xy = input.TexCoord1;
+
+ output.Color = input.Prelight;
+ output.Color.rgb += ambientLight.rgb * surfAmbient;
+
+ int i;
+#ifdef DIRECTIONALS
+ for(i = 0; i < numDirLights; i++)
+ output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse;
+#endif
+#ifdef POINTLIGHTS
+ for(i = 0; i < numPointLights; i++)
+ output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse;
+#endif
+#ifdef SPOTLIGHTS
+ for(i = 0; i < numSpotLights; i++)
+ output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse;
+#endif
+ // PS2 clamps before material color
+ output.Color = clamp(output.Color, 0.0, 1.0);
+ output.Color *= matCol;
+
+ output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
+
+ return output;
+}
diff --git a/src/extras/shaders/default_UV2_VS.inc b/src/extras/shaders/default_UV2_VS.inc
new file mode 100644
index 00000000..de832107
--- /dev/null
+++ b/src/extras/shaders/default_UV2_VS.inc
@@ -0,0 +1,55 @@
+static unsigned char default_UV2_VS_cso[] = {
+ 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x45, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
+ 0x05, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xd5, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x00,
+ 0x01, 0x00, 0x3e, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x3a, 0x00, 0x90, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x32, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xcb, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x36, 0x00,
+ 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6d, 0x62, 0x69,
+ 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x00, 0xab, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64,
+ 0x4d, 0x61, 0x74, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x67, 0x44,
+ 0x61, 0x74, 0x61, 0x00, 0x6d, 0x61, 0x74, 0x43, 0x6f, 0x6c, 0x00, 0x73,
+ 0x75, 0x72, 0x66, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x00, 0x76, 0x73, 0x5f,
+ 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
+ 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53,
+ 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
+ 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e,
+ 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05,
+ 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x0a, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x07, 0x80, 0x0f, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x0d, 0x00, 0x00, 0xa0,
+ 0x03, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80,
+ 0x03, 0x00, 0xff, 0x90, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x55, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0xe4, 0x80,
+ 0x0c, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0x55, 0x90, 0x01, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x80, 0x0e, 0x00, 0x55, 0xa1,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x0e, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xff, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x04, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x55, 0xa0,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe0, 0x01, 0x00, 0xe4, 0x90,
+ 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x03, 0xe0, 0x02, 0x00, 0xe4, 0x90,
+ 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/default_UV2_gl3.inc b/src/extras/shaders/default_UV2_gl3.inc
new file mode 100644
index 00000000..14106b29
--- /dev/null
+++ b/src/extras/shaders/default_UV2_gl3.inc
@@ -0,0 +1,31 @@
+const char *default_UV2_vert_src =
+"layout(location = 0) in vec3 in_pos;\n"
+"layout(location = 1) in vec3 in_normal;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+"layout(location = 4) in vec2 in_tex1;\n"
+
+"out vec4 v_color;\n"
+"out vec2 v_tex0;\n"
+"out vec2 v_tex1;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
+" gl_Position = u_proj * u_view * Vertex;\n"
+" vec3 Normal = mat3(u_world) * in_normal;\n"
+
+" v_tex0 = in_tex0;\n"
+" v_tex1 = in_tex1;\n"
+
+" v_color = in_color;\n"
+" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
+" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
+" v_color = clamp(v_color, 0.0, 1.0);\n"
+" v_color *= u_matColor;\n"
+
+" v_fog = DoFog(gl_Position.w);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/im2d.vert b/src/extras/shaders/im2d.vert
new file mode 100644
index 00000000..241593b1
--- /dev/null
+++ b/src/extras/shaders/im2d.vert
@@ -0,0 +1,21 @@
+uniform vec4 u_xform;
+
+layout(location = 0) in vec4 in_pos;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+
+out vec4 v_color;
+out vec2 v_tex0;
+out float v_fog;
+
+void
+main(void)
+{
+ gl_Position = in_pos;
+ gl_Position.w = 1.0;
+ gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
+ v_fog = DoFog(gl_Position.z);
+ gl_Position.xyz *= gl_Position.w;
+ v_color = in_color;
+ v_tex0 = in_tex0;
+}
diff --git a/src/extras/shaders/im2d_gl3.inc b/src/extras/shaders/im2d_gl3.inc
new file mode 100644
index 00000000..68341b39
--- /dev/null
+++ b/src/extras/shaders/im2d_gl3.inc
@@ -0,0 +1,23 @@
+const char *im2d_vert_src =
+"uniform vec4 u_xform;\n"
+
+"layout(location = 0) in vec4 in_pos;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+
+"out vec4 v_color;\n"
+"out vec2 v_tex0;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" gl_Position = in_pos;\n"
+" gl_Position.w = 1.0;\n"
+" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
+" v_fog = DoFog(gl_Position.z);\n"
+" gl_Position.xyz *= gl_Position.w;\n"
+" v_color = in_color;\n"
+" v_tex0 = in_tex0;\n"
+"}\n"
+;
diff --git a/src/extras/shaders/lighting.h b/src/extras/shaders/lighting.h
new file mode 100644
index 00000000..4b081962
--- /dev/null
+++ b/src/extras/shaders/lighting.h
@@ -0,0 +1,44 @@
+struct Light
+{
+ float4 color; // and radius
+ float4 position; // and -cos(angle)
+ float4 direction; // and falloff clamp
+};
+
+float3 DoDirLight(Light L, float3 N)
+{
+ float l = max(0.0, dot(N, -L.direction.xyz));
+ return l*L.color.xyz;
+}
+
+float3 DoDirLightSpec(Light L, float3 N, float3 V, float power)
+{
+ return pow(saturate(dot(N, normalize(V + -L.direction.xyz))), power)*L.color.xyz;
+}
+
+float3 DoPointLight(Light L, float3 V, float3 N)
+{
+ // As on PS2
+ float3 dir = V - L.position.xyz;
+ float dist = length(dir);
+ float atten = max(0.0, (1.0 - dist/L.color.w));
+ float l = max(0.0, dot(N, -normalize(dir)));
+ return l*L.color.xyz*atten;
+}
+
+float3 DoSpotLight(Light L, float3 V, float3 N)
+{
+ // As on PS2
+ float3 dir = V - L.position.xyz;
+ float dist = length(dir);
+ float atten = max(0.0, (1.0 - dist/L.color.w));
+ dir /= dist;
+ float l = max(0.0, dot(N, -dir));
+ float pcos = dot(dir, L.direction.xyz); // cos to point
+ float ccos = -L.position.w; // cos of cone
+ float falloff = (pcos-ccos)/(1.0-ccos);
+ if(falloff < 0) // outside of cone
+ l = 0;
+ l *= max(falloff, L.direction.w); // falloff clamp
+ return l*L.color.xyz*atten;
+}
diff --git a/src/extras/shaders/make.cmd b/src/extras/shaders/make.cmd
new file mode 100644
index 00000000..8404ac6c
--- /dev/null
+++ b/src/extras/shaders/make.cmd
@@ -0,0 +1,3 @@
+@echo off
+for %%f in (*PS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T ps_2_0 /nologo /E main /Fo %%~nf.cso %%f
+for %%f in (*VS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T vs_2_0 /nologo /E main /Fo %%~nf.cso %%f
diff --git a/src/extras/shaders/makeinc.sh b/src/extras/shaders/makeinc.sh
new file mode 100644
index 00000000..a649af33
--- /dev/null
+++ b/src/extras/shaders/makeinc.sh
@@ -0,0 +1,5 @@
+#!sh
+for i in *cso; do
+ (echo -n 'static '
+ xxd -i $i | grep -v '_len = ') > ${i%cso}inc
+done
diff --git a/src/extras/shaders/neoGloss.frag b/src/extras/shaders/neoGloss.frag
new file mode 100644
index 00000000..14ef0e15
--- /dev/null
+++ b/src/extras/shaders/neoGloss.frag
@@ -0,0 +1,26 @@
+uniform sampler2D tex0;
+
+uniform vec4 u_reflProps;
+
+#define glossMult (u_reflProps.x)
+
+in vec3 v_normal;
+in vec3 v_light;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec3 n = 2.0*v_normal-1.0; // unpack
+ vec3 v = 2.0*v_light-1.0; //
+
+ float s = dot(n, v);
+ color = s*s*s*s*s*s*s*s*color*v_fog*glossMult;
+
+ DoAlphaTest(color.a);
+}
+
diff --git a/src/extras/shaders/neoGloss.vert b/src/extras/shaders/neoGloss.vert
new file mode 100644
index 00000000..78dd1b33
--- /dev/null
+++ b/src/extras/shaders/neoGloss.vert
@@ -0,0 +1,29 @@
+uniform vec3 u_eye;
+
+
+layout(location = 0) in vec3 in_pos;
+layout(location = 1) in vec3 in_normal;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+
+out vec3 v_normal;
+out vec3 v_light;
+out vec2 v_tex0;
+out float v_fog;
+
+void
+main(void)
+{
+ vec4 Vertex = u_world * vec4(in_pos, 1.0);
+ gl_Position = u_proj * u_view * Vertex;
+ vec3 Normal = mat3(u_world) * in_normal;
+
+ v_tex0 = in_tex0;
+
+ vec3 viewVec = normalize(u_eye - Vertex.xyz);
+ vec3 Light = normalize(viewVec - u_lightDirection[0].xyz);
+ v_normal = 0.5*(1.0 + vec3(0.0, 0.0, 1.0)); // compress
+ v_light = 0.5*(1.0 + Light); //
+
+ v_fog = DoFog(gl_Position.w);
+}
diff --git a/src/extras/shaders/neoGloss_PS.cso b/src/extras/shaders/neoGloss_PS.cso
new file mode 100644
index 00000000..aa88e450
--- /dev/null
+++ b/src/extras/shaders/neoGloss_PS.cso
Binary files differ
diff --git a/src/extras/shaders/neoGloss_PS.hlsl b/src/extras/shaders/neoGloss_PS.hlsl
new file mode 100644
index 00000000..b3c97639
--- /dev/null
+++ b/src/extras/shaders/neoGloss_PS.hlsl
@@ -0,0 +1,20 @@
+sampler2D tex0 : register(s0);
+float glossMult : register(c1);
+
+struct VS_out
+{
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0;
+ float3 Normal : COLOR0;
+ float3 Light : COLOR1;
+};
+
+float4 main(VS_out input) : COLOR
+{
+ float4 color = tex2D(tex0, input.TexCoord0.xy);
+ float3 n = 2.0*input.Normal-1.0; // unpack
+ float3 v = 2.0*input.Light-1.0; //
+
+ float s = dot(n, v);
+ return s*s*s*s*s*s*s*s*color*input.TexCoord0.z*glossMult;
+}
diff --git a/src/extras/shaders/neoGloss_PS.inc b/src/extras/shaders/neoGloss_PS.inc
new file mode 100644
index 00000000..97e5641d
--- /dev/null
+++ b/src/extras/shaders/neoGloss_PS.inc
@@ -0,0 +1,39 @@
+static unsigned char neoGloss_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2d, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x78, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x06, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x6f, 0x73,
+ 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x00, 0xab, 0xab, 0x00, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x65, 0x78, 0x30, 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f,
+ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53,
+ 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d,
+ 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39,
+ 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0xbf,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x07, 0xb0, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x07, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x07, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x55, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x00, 0x00, 0x00, 0xa0,
+ 0x00, 0x00, 0x55, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xaa, 0xb0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoGloss_VS.cso b/src/extras/shaders/neoGloss_VS.cso
new file mode 100644
index 00000000..9635b8b7
--- /dev/null
+++ b/src/extras/shaders/neoGloss_VS.cso
Binary files differ
diff --git a/src/extras/shaders/neoGloss_VS.hlsl b/src/extras/shaders/neoGloss_VS.hlsl
new file mode 100644
index 00000000..d166171c
--- /dev/null
+++ b/src/extras/shaders/neoGloss_VS.hlsl
@@ -0,0 +1,35 @@
+#include "standardConstants.h"
+
+struct VS_in
+{
+ float4 Position : POSITION;
+ float2 TexCoord : TEXCOORD0;
+};
+
+struct VS_out
+{
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0;
+ float3 Normal : COLOR0;
+ float3 Light : COLOR1;
+};
+
+float3 eye : register(c41);
+
+VS_out main(in VS_in input)
+{
+ VS_out output;
+
+ output.Position = mul(combinedMat, input.Position);
+ float3 Vertex = mul(worldMat, input.Position).xyz;
+ output.TexCoord0.xy = input.TexCoord;
+
+ float3 viewVec = normalize(eye - Vertex);
+ float3 Light = normalize(viewVec - lights[0].direction.xyz);
+ output.Normal = 0.5*(1.0 + float3(0.0, 0.0, 1.0)); // compress
+ output.Light = 0.5*(1.0 + Light); //
+
+ output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
+
+ return output;
+}
diff --git a/src/extras/shaders/neoGloss_VS.inc b/src/extras/shaders/neoGloss_VS.inc
new file mode 100644
index 00000000..1ec03761
--- /dev/null
+++ b/src/extras/shaders/neoGloss_VS.inc
@@ -0,0 +1,66 @@
+static unsigned char neoGloss_VS_cso[] = {
+ 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x5b, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
+ 0x05, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x2d, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x01, 0x00, 0xa6, 0x00,
+ 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x3a, 0x00, 0xb8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00,
+ 0x03, 0x00, 0x4e, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x24, 0x01, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x12, 0x00,
+ 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x62,
+ 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x61, 0x74, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x65, 0x79, 0x65, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x67, 0x44,
+ 0x61, 0x74, 0x61, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x69, 0x67, 0x68,
+ 0x74, 0x73, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x00, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0xab,
+ 0xcf, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
+ 0xd8, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x03, 0x00,
+ 0xfc, 0x00, 0x00, 0x00, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x4d, 0x61, 0x74,
+ 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72,
+ 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c,
+ 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f,
+ 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e,
+ 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab,
+ 0x51, 0x00, 0x00, 0x05, 0x08, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90,
+ 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x55, 0x90,
+ 0x05, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
+ 0x04, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x06, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x07, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80,
+ 0x00, 0x00, 0xe4, 0x81, 0x29, 0x00, 0xe4, 0xa0, 0x24, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x13, 0x00, 0xe4, 0xa1,
+ 0x24, 0x00, 0x00, 0x02, 0x01, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x08, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0xd0,
+ 0x00, 0x00, 0xe4, 0x80, 0x08, 0x00, 0x55, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x90, 0x01, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80,
+ 0x03, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x80,
+ 0x0e, 0x00, 0x55, 0xa1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0,
+ 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xff, 0xa0,
+ 0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xe0, 0x00, 0x00, 0x00, 0x80,
+ 0x08, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe0,
+ 0x01, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x07, 0xd0,
+ 0x08, 0x00, 0xc5, 0xa0, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoGloss_fs_gl3.inc b/src/extras/shaders/neoGloss_fs_gl3.inc
new file mode 100644
index 00000000..736b0c5d
--- /dev/null
+++ b/src/extras/shaders/neoGloss_fs_gl3.inc
@@ -0,0 +1,28 @@
+const char *neoGloss_frag_src =
+"uniform sampler2D tex0;\n"
+
+"uniform vec4 u_reflProps;\n"
+
+"#define glossMult (u_reflProps.x)\n"
+
+"in vec3 v_normal;\n"
+"in vec3 v_light;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec3 n = 2.0*v_normal-1.0; // unpack\n"
+" vec3 v = 2.0*v_light-1.0; //\n"
+
+" float s = dot(n, v);\n"
+" color = s*s*s*s*s*s*s*s*color*v_fog*glossMult;\n"
+
+" DoAlphaTest(color.a);\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/neoGloss_vs_gl3.inc b/src/extras/shaders/neoGloss_vs_gl3.inc
new file mode 100644
index 00000000..4adc9cb2
--- /dev/null
+++ b/src/extras/shaders/neoGloss_vs_gl3.inc
@@ -0,0 +1,31 @@
+const char *neoGloss_vert_src =
+"uniform vec3 u_eye;\n"
+
+
+"layout(location = 0) in vec3 in_pos;\n"
+"layout(location = 1) in vec3 in_normal;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+
+"out vec3 v_normal;\n"
+"out vec3 v_light;\n"
+"out vec2 v_tex0;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
+" gl_Position = u_proj * u_view * Vertex;\n"
+" vec3 Normal = mat3(u_world) * in_normal;\n"
+
+" v_tex0 = in_tex0;\n"
+
+" vec3 viewVec = normalize(u_eye - Vertex.xyz);\n"
+" vec3 Light = normalize(viewVec - u_lightDirection[0].xyz);\n"
+" v_normal = 0.5*(1.0 + vec3(0.0, 0.0, 1.0)); // compress\n"
+" v_light = 0.5*(1.0 + Light); //\n"
+
+" v_fog = DoFog(gl_Position.w);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/neoRim.vert b/src/extras/shaders/neoRim.vert
new file mode 100644
index 00000000..4a2b545f
--- /dev/null
+++ b/src/extras/shaders/neoRim.vert
@@ -0,0 +1,37 @@
+uniform vec3 u_viewVec;
+uniform vec4 u_rampStart;
+uniform vec4 u_rampEnd;
+uniform vec3 u_rimData;
+
+layout(location = 0) in vec3 in_pos;
+layout(location = 1) in vec3 in_normal;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+
+out vec4 v_color;
+out vec2 v_tex0;
+out float v_fog;
+
+void
+main(void)
+{
+ vec4 Vertex = u_world * vec4(in_pos, 1.0);
+ gl_Position = u_proj * u_view * Vertex;
+ vec3 Normal = mat3(u_world) * in_normal;
+
+ v_tex0 = in_tex0;
+
+ v_color = in_color;
+ v_color.rgb += u_ambLight.rgb*surfAmbient;
+ v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
+
+ // rim light
+ float f = u_rimData.x - u_rimData.y*dot(Normal, u_viewVec);
+ vec4 rimlight = clamp(mix(u_rampEnd, u_rampStart, f)*u_rimData.z, 0.0, 1.0);
+ v_color.rgb += rimlight.rgb;
+
+ v_color = clamp(v_color, 0.0, 1.0);
+ v_color *= u_matColor;
+
+ v_fog = DoFog(gl_Position.w);
+}
diff --git a/src/extras/shaders/neoRimSkin.vert b/src/extras/shaders/neoRimSkin.vert
new file mode 100644
index 00000000..f16f2310
--- /dev/null
+++ b/src/extras/shaders/neoRimSkin.vert
@@ -0,0 +1,48 @@
+uniform mat4 u_boneMatrices[64];
+
+uniform vec3 u_viewVec;
+uniform vec4 u_rampStart;
+uniform vec4 u_rampEnd;
+uniform vec3 u_rimData;
+
+layout(location = 0) in vec3 in_pos;
+layout(location = 1) in vec3 in_normal;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+layout(location = 11) in vec4 in_weights;
+layout(location = 12) in vec4 in_indices;
+
+out vec4 v_color;
+out vec2 v_tex0;
+out float v_fog;
+
+void
+main(void)
+{
+ vec3 SkinVertex = vec3(0.0, 0.0, 0.0);
+ vec3 SkinNormal = vec3(0.0, 0.0, 0.0);
+ for(int i = 0; i < 4; i++){
+ SkinVertex += (u_boneMatrices[int(in_indices[i])] * vec4(in_pos, 1.0)).xyz * in_weights[i];
+ SkinNormal += (mat3(u_boneMatrices[int(in_indices[i])]) * in_normal) * in_weights[i];
+ }
+
+ vec4 Vertex = u_world * vec4(SkinVertex, 1.0);
+ gl_Position = u_proj * u_view * Vertex;
+ vec3 Normal = mat3(u_world) * SkinNormal;
+
+ v_tex0 = in_tex0;
+
+ v_color = in_color;
+ v_color.rgb += u_ambLight.rgb*surfAmbient;
+ v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
+
+ // rim light
+ float f = u_rimData.x - u_rimData.y*dot(Normal, u_viewVec);
+ vec4 rimlight = clamp(mix(u_rampEnd, u_rampStart, f)*u_rimData.z, 0.0, 1.0);
+ v_color.rgb += rimlight.rgb;
+
+ v_color = clamp(v_color, 0.0, 1.0);
+ v_color *= u_matColor;
+
+ v_fog = DoFog(gl_Position.z);
+}
diff --git a/src/extras/shaders/neoRimSkin_VS.cso b/src/extras/shaders/neoRimSkin_VS.cso
new file mode 100644
index 00000000..8410504e
--- /dev/null
+++ b/src/extras/shaders/neoRimSkin_VS.cso
Binary files differ
diff --git a/src/extras/shaders/neoRimSkin_VS.hlsl b/src/extras/shaders/neoRimSkin_VS.hlsl
new file mode 100644
index 00000000..87cc0931
--- /dev/null
+++ b/src/extras/shaders/neoRimSkin_VS.hlsl
@@ -0,0 +1,73 @@
+#include "standardConstants.h"
+
+float4x3 boneMatrices[64] : register(c41);
+
+struct VS_in
+{
+ float4 Position : POSITION;
+ float3 Normal : NORMAL;
+ float2 TexCoord : TEXCOORD0;
+ float4 Prelight : COLOR0;
+ float4 Weights : BLENDWEIGHT;
+ int4 Indices : BLENDINDICES;
+};
+
+struct VS_out {
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0; // also fog
+ float4 Color : COLOR0;
+};
+
+float3 viewVec : register(c233);
+float4 rampStart : register(c234);
+float4 rampEnd : register(c235);
+float3 rimData : register(c236);
+
+VS_out main(in VS_in input)
+{
+ VS_out output;
+
+ int j;
+ float3 SkinVertex = float3(0.0, 0.0, 0.0);
+ float3 SkinNormal = float3(0.0, 0.0, 0.0);
+ for(j = 0; j < 4; j++){
+ SkinVertex += mul(input.Position, boneMatrices[input.Indices[j]]).xyz * input.Weights[j];
+ SkinNormal += mul(input.Normal, (float3x3)boneMatrices[input.Indices[j]]).xyz * input.Weights[j];
+ }
+
+ output.Position = mul(combinedMat, float4(SkinVertex, 1.0));
+ float3 Vertex = mul(worldMat, float4(SkinVertex, 1.0)).xyz;
+ float3 Normal = mul(normalMat, SkinNormal);
+
+ output.TexCoord0.xy = input.TexCoord;
+
+ output.Color = input.Prelight;
+ output.Color.rgb += ambientLight.rgb * surfAmbient;
+
+ int i;
+//#ifdef DIRECTIONALS
+ for(i = 0; i < numDirLights; i++)
+ output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse;
+//#endif
+//#ifdef POINTLIGHTS
+// for(i = 0; i < numPointLights; i++)
+// output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse;
+//#endif
+//#ifdef SPOTLIGHTS
+// for(i = 0; i < numSpotLights; i++)
+// output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse;
+//#endif
+
+ // rim light
+ float f = rimData.x - rimData.y*dot(Normal, viewVec);
+ float4 rimlight = saturate(lerp(rampEnd, rampStart, f)*rimData.z);
+ output.Color.xyz += rimlight.xyz;
+
+ // PS2 clamps before material color
+ output.Color = clamp(output.Color, 0.0, 1.0);
+ output.Color *= matCol;
+
+ output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
+
+ return output;
+}
diff --git a/src/extras/shaders/neoRimSkin_VS.inc b/src/extras/shaders/neoRimSkin_VS.inc
new file mode 100644
index 00000000..ac182956
--- /dev/null
+++ b/src/extras/shaders/neoRimSkin_VS.inc
@@ -0,0 +1,203 @@
+static unsigned char neoRimSkin_VS_cso[] = {
+ 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0xb4, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x99, 0x02, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
+ 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x92, 0x02, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x00,
+ 0x01, 0x00, 0x3e, 0x00, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x01, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0xc0, 0x00, 0xa6, 0x00,
+ 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x80, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x42, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xac, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x3a, 0x00,
+ 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x11, 0x00, 0x18, 0x00, 0x46, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x32, 0x00, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x17, 0x02, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x00, 0x22, 0x00,
+ 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x02, 0x00, 0xeb, 0x00,
+ 0x01, 0x00, 0xae, 0x03, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x02, 0x00, 0x00, 0x02, 0x00, 0xea, 0x00, 0x01, 0x00, 0xaa, 0x03,
+ 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0xec, 0x00, 0x01, 0x00, 0xb2, 0x03, 0x70, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x00,
+ 0x01, 0x00, 0x36, 0x00, 0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x8a, 0x02, 0x00, 0x00, 0x02, 0x00, 0xe9, 0x00, 0x01, 0x00, 0xa6, 0x03,
+ 0x70, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6d, 0x62, 0x69,
+ 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x00, 0xab, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0x6f, 0x6e, 0x65, 0x4d, 0x61, 0x74, 0x72,
+ 0x69, 0x63, 0x65, 0x73, 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00,
+ 0x04, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x61, 0x74, 0x00,
+ 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4c, 0x69, 0x67,
+ 0x68, 0x74, 0x00, 0xab, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x67, 0x44,
+ 0x61, 0x74, 0x61, 0x00, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x63,
+ 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x64, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0xab, 0xbb, 0x01, 0x00, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0xd4, 0x01, 0x00, 0x00, 0xc4, 0x01, 0x00, 0x00,
+ 0xdd, 0x01, 0x00, 0x00, 0xc4, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x03, 0x00, 0xe8, 0x01, 0x00, 0x00,
+ 0x6d, 0x61, 0x74, 0x43, 0x6f, 0x6c, 0x00, 0x6e, 0x6f, 0x72, 0x6d, 0x61,
+ 0x6c, 0x4d, 0x61, 0x74, 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00,
+ 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x73,
+ 0x00, 0xab, 0xab, 0xab, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6d, 0x70,
+ 0x45, 0x6e, 0x64, 0x00, 0x72, 0x61, 0x6d, 0x70, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x00, 0x72, 0x69, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x00, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x73, 0x75, 0x72, 0x66, 0x50, 0x72, 0x6f, 0x70,
+ 0x73, 0x00, 0x76, 0x69, 0x65, 0x77, 0x56, 0x65, 0x63, 0x00, 0x76, 0x73,
+ 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
+ 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20,
+ 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69,
+ 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32,
+ 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05,
+ 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x0a, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x02, 0x00, 0x00, 0x80, 0x05, 0x00, 0x0f, 0x90, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x05, 0x00, 0xe4, 0x90, 0x04, 0x00, 0x00, 0xa0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x80,
+ 0x08, 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x80, 0x01, 0x00, 0xe4, 0x90,
+ 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x04, 0x01, 0x00, 0x02, 0x80,
+ 0x01, 0x00, 0xe4, 0x90, 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x55, 0x80,
+ 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x04, 0x80, 0x01, 0x00, 0xe4, 0x90,
+ 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x55, 0x80, 0x08, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x01, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0x55, 0x80, 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x80,
+ 0x01, 0x00, 0xe4, 0x90, 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x90, 0x02, 0x00, 0xe4, 0x80,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xaa, 0x80,
+ 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x04, 0x80, 0x01, 0x00, 0xe4, 0x90,
+ 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xaa, 0x80, 0x08, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x01, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0xaa, 0x80, 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x80,
+ 0x01, 0x00, 0xe4, 0x90, 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0xaa, 0x90, 0x01, 0x00, 0xe4, 0x80, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xff, 0x80, 0x08, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x04, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x2b, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0xff, 0x80, 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xff, 0x80,
+ 0x08, 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x80, 0x01, 0x00, 0xe4, 0x90,
+ 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xff, 0x90,
+ 0x01, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0x55, 0x80, 0x09, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x0b, 0x80, 0x08, 0x00, 0xa4, 0xa0, 0x01, 0x00, 0x00, 0x80,
+ 0x02, 0x00, 0xa4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0xaa, 0x80, 0x01, 0x00, 0xf4, 0x80,
+ 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x08, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0xe9, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x08, 0x80,
+ 0x03, 0x00, 0xff, 0x90, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x01, 0x80,
+ 0x0d, 0x00, 0x00, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80,
+ 0x0f, 0x00, 0xe4, 0xa0, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0xe4, 0x90,
+ 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x07, 0x80, 0x03, 0x00, 0xe4, 0x80,
+ 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x08, 0x80, 0x04, 0x00, 0x55, 0xa0,
+ 0x26, 0x00, 0x00, 0x01, 0x00, 0x00, 0xe4, 0xf0, 0x02, 0x00, 0x00, 0x03,
+ 0x04, 0x00, 0x08, 0x80, 0x03, 0x00, 0xff, 0x80, 0x10, 0x00, 0x00, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x04, 0x00, 0x08, 0x80, 0x04, 0x00, 0xff, 0x80,
+ 0x04, 0x00, 0x00, 0xa0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x04, 0x00, 0xff, 0x80, 0x08, 0x00, 0x00, 0x04, 0x05, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x13, 0x20, 0xe4, 0xa1, 0x00, 0x00, 0xff, 0xb0,
+ 0x0b, 0x00, 0x00, 0x03, 0x05, 0x00, 0x01, 0x80, 0x05, 0x00, 0x00, 0x80,
+ 0x04, 0x00, 0x55, 0xa0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x04, 0x00, 0xff, 0x80, 0x05, 0x00, 0x00, 0x04, 0x05, 0x00, 0x07, 0x80,
+ 0x05, 0x00, 0x00, 0x80, 0x11, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80, 0x05, 0x00, 0xe4, 0x80,
+ 0x0d, 0x00, 0xaa, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x08, 0x80, 0x03, 0x00, 0xff, 0x80, 0x04, 0x00, 0xaa, 0xa0,
+ 0x27, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x01, 0x80,
+ 0xec, 0x00, 0x55, 0xa0, 0x01, 0x00, 0xff, 0x81, 0xec, 0x00, 0x00, 0xa0,
+ 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x07, 0x80, 0xeb, 0x00, 0xe4, 0xa0,
+ 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x0e, 0x80, 0x03, 0x00, 0x90, 0x81,
+ 0xea, 0x00, 0x90, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf9, 0x80, 0xeb, 0x00, 0xe4, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0xec, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x55, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xaa, 0xa0,
+ 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0x00, 0x03, 0x01, 0x00, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x55, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xaa, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x80,
+ 0x0c, 0x00, 0xe4, 0xa0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0x55, 0x80, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x55, 0x80,
+ 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x02, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x55, 0x80, 0x09, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x04, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x2b, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x55, 0x90, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x01, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x80,
+ 0x09, 0x00, 0x00, 0x04, 0x02, 0x00, 0x04, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x90,
+ 0x01, 0x00, 0xe4, 0x80, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0xaa, 0x80, 0x09, 0x00, 0x00, 0x04, 0x02, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x29, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xaa, 0x80,
+ 0x09, 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x2a, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xaa, 0x80, 0x09, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x04, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x2b, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
+ 0x02, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xaa, 0x90, 0x01, 0x00, 0xe4, 0x80,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xff, 0x80,
+ 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x01, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x29, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0xb0, 0x00, 0x00, 0xff, 0x80, 0x09, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x02, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x2a, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0xb0, 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0xb0,
+ 0x00, 0x00, 0xff, 0x80, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0xb0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0xff, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x80, 0x01, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x80, 0x0e, 0x00, 0x55, 0xa1,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x0e, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xff, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x04, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0xaa, 0xa0,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe0, 0x02, 0x00, 0xe4, 0x90,
+ 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoRimSkin_gl3.inc b/src/extras/shaders/neoRimSkin_gl3.inc
new file mode 100644
index 00000000..70948e1f
--- /dev/null
+++ b/src/extras/shaders/neoRimSkin_gl3.inc
@@ -0,0 +1,50 @@
+const char *neoRimSkin_vert_src =
+"uniform mat4 u_boneMatrices[64];\n"
+
+"uniform vec3 u_viewVec;\n"
+"uniform vec4 u_rampStart;\n"
+"uniform vec4 u_rampEnd;\n"
+"uniform vec3 u_rimData;\n"
+
+"layout(location = 0) in vec3 in_pos;\n"
+"layout(location = 1) in vec3 in_normal;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+"layout(location = 11) in vec4 in_weights;\n"
+"layout(location = 12) in vec4 in_indices;\n"
+
+"out vec4 v_color;\n"
+"out vec2 v_tex0;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec3 SkinVertex = vec3(0.0, 0.0, 0.0);\n"
+" vec3 SkinNormal = vec3(0.0, 0.0, 0.0);\n"
+" for(int i = 0; i < 4; i++){\n"
+" SkinVertex += (u_boneMatrices[int(in_indices[i])] * vec4(in_pos, 1.0)).xyz * in_weights[i];\n"
+" SkinNormal += (mat3(u_boneMatrices[int(in_indices[i])]) * in_normal) * in_weights[i];\n"
+" }\n"
+
+" vec4 Vertex = u_world * vec4(SkinVertex, 1.0);\n"
+" gl_Position = u_proj * u_view * Vertex;\n"
+" vec3 Normal = mat3(u_world) * SkinNormal;\n"
+
+" v_tex0 = in_tex0;\n"
+
+" v_color = in_color;\n"
+" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
+" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
+
+" // rim light\n"
+" float f = u_rimData.x - u_rimData.y*dot(Normal, u_viewVec);\n"
+" vec4 rimlight = clamp(mix(u_rampEnd, u_rampStart, f)*u_rimData.z, 0.0, 1.0);\n"
+" v_color.rgb += rimlight.rgb;\n"
+
+" v_color = clamp(v_color, 0.0, 1.0);\n"
+" v_color *= u_matColor;\n"
+
+" v_fog = DoFog(gl_Position.z);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/neoRim_VS.cso b/src/extras/shaders/neoRim_VS.cso
new file mode 100644
index 00000000..4af538b1
--- /dev/null
+++ b/src/extras/shaders/neoRim_VS.cso
Binary files differ
diff --git a/src/extras/shaders/neoRim_VS.hlsl b/src/extras/shaders/neoRim_VS.hlsl
new file mode 100644
index 00000000..7f95166d
--- /dev/null
+++ b/src/extras/shaders/neoRim_VS.hlsl
@@ -0,0 +1,61 @@
+#include "standardConstants.h"
+
+struct VS_in
+{
+ float4 Position : POSITION;
+ float3 Normal : NORMAL;
+ float2 TexCoord : TEXCOORD0;
+ float4 Prelight : COLOR0;
+};
+
+struct VS_out {
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0; // also fog
+ float4 Color : COLOR0;
+};
+
+float3 viewVec : register(c233);
+float4 rampStart : register(c234);
+float4 rampEnd : register(c235);
+float3 rimData : register(c236);
+
+VS_out main(in VS_in input)
+{
+ VS_out output;
+
+ output.Position = mul(combinedMat, input.Position);
+ float3 Vertex = mul(worldMat, input.Position).xyz;
+ float3 Normal = mul(normalMat, input.Normal);
+
+ output.TexCoord0.xy = input.TexCoord;
+
+ output.Color = input.Prelight;
+ output.Color.rgb += ambientLight.rgb * surfAmbient;
+
+ int i;
+//#ifdef DIRECTIONALS
+ for(i = 0; i < numDirLights; i++)
+ output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse;
+//#endif
+//#ifdef POINTLIGHTS
+// for(i = 0; i < numPointLights; i++)
+// output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse;
+//#endif
+//#ifdef SPOTLIGHTS
+// for(i = 0; i < numSpotLights; i++)
+// output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse;
+//#endif
+
+ // rim light
+ float f = rimData.x - rimData.y*dot(Normal, viewVec);
+ float4 rimlight = saturate(lerp(rampEnd, rampStart, f)*rimData.z);
+ output.Color.xyz += rimlight.xyz;
+
+ // PS2 clamps before material color
+ output.Color = clamp(output.Color, 0.0, 1.0);
+ output.Color *= matCol;
+
+ output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
+
+ return output;
+}
diff --git a/src/extras/shaders/neoRim_VS.inc b/src/extras/shaders/neoRim_VS.inc
new file mode 100644
index 00000000..03b044a6
--- /dev/null
+++ b/src/extras/shaders/neoRim_VS.inc
@@ -0,0 +1,118 @@
+static unsigned char neoRim_VS_cso[] = {
+ 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0xa7, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x65, 0x02, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
+ 0x0d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x5e, 0x02, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x00,
+ 0x01, 0x00, 0x3e, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0x42, 0x00, 0x68, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00,
+ 0x01, 0x00, 0x3a, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00, 0x18, 0x00, 0x46, 0x00,
+ 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x32, 0x00, 0x30, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
+ 0x03, 0x00, 0x22, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0xeb, 0x00, 0x01, 0x00, 0xae, 0x03, 0x30, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x02, 0x00, 0xea, 0x00,
+ 0x01, 0x00, 0xaa, 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x32, 0x02, 0x00, 0x00, 0x02, 0x00, 0xec, 0x00, 0x01, 0x00, 0xb2, 0x03,
+ 0x3c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x36, 0x00, 0x30, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x56, 0x02, 0x00, 0x00, 0x02, 0x00, 0xe9, 0x00,
+ 0x01, 0x00, 0xa6, 0x03, 0x3c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74,
+ 0x00, 0xab, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x62,
+ 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x61, 0x74, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x66, 0x69, 0x72, 0x73, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x00, 0xab,
+ 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x00,
+ 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
+ 0x00, 0xab, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x00, 0xab, 0x87, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0xa0, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xa9, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
+ 0x08, 0x00, 0x03, 0x00, 0xb4, 0x01, 0x00, 0x00, 0x6d, 0x61, 0x74, 0x43,
+ 0x6f, 0x6c, 0x00, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74,
+ 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6d, 0x44,
+ 0x69, 0x72, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0xab, 0xab, 0xab,
+ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x72, 0x61, 0x6d, 0x70, 0x45, 0x6e, 0x64, 0x00,
+ 0x72, 0x61, 0x6d, 0x70, 0x53, 0x74, 0x61, 0x72, 0x74, 0x00, 0x72, 0x69,
+ 0x6d, 0x44, 0x61, 0x74, 0x61, 0x00, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x73, 0x75, 0x72, 0x66, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x00, 0x76, 0x69,
+ 0x65, 0x77, 0x56, 0x65, 0x63, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30,
+ 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28,
+ 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64,
+ 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20,
+ 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31,
+ 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80,
+ 0x02, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x80,
+ 0x03, 0x00, 0x0f, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0x55, 0x90, 0x01, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x08, 0x80, 0x03, 0x00, 0xff, 0x90, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0x55, 0x90, 0x09, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x08, 0x00, 0xe4, 0xa0,
+ 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0xaa, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0xe9, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x03, 0x00, 0x01, 0x80, 0x0d, 0x00, 0x00, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x0e, 0x80, 0x0f, 0x00, 0x90, 0xa0, 0x03, 0x00, 0x00, 0x80,
+ 0x03, 0x00, 0x90, 0x90, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x07, 0x80,
+ 0x02, 0x00, 0xf9, 0x80, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x08, 0x80,
+ 0x04, 0x00, 0x00, 0xa0, 0x26, 0x00, 0x00, 0x01, 0x00, 0x00, 0xe4, 0xf0,
+ 0x02, 0x00, 0x00, 0x03, 0x04, 0x00, 0x01, 0x80, 0x03, 0x00, 0xff, 0x80,
+ 0x10, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x04, 0x00, 0x01, 0x80,
+ 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x55, 0xa0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0xb0, 0x04, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x04,
+ 0x04, 0x00, 0x01, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x13, 0x20, 0xe4, 0xa1,
+ 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0x03, 0x04, 0x00, 0x01, 0x80,
+ 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x04,
+ 0x04, 0x00, 0x07, 0x80, 0x04, 0x00, 0x00, 0x80, 0x11, 0x20, 0xe4, 0xa0,
+ 0x00, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80,
+ 0x04, 0x00, 0xe4, 0x80, 0x0d, 0x00, 0xaa, 0xa0, 0x03, 0x00, 0xe4, 0x80,
+ 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x08, 0x80, 0x03, 0x00, 0xff, 0x80,
+ 0x04, 0x00, 0xaa, 0xa0, 0x27, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x01, 0x80, 0xec, 0x00, 0x55, 0xa0, 0x02, 0x00, 0x00, 0x81,
+ 0xec, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x07, 0x80,
+ 0xeb, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80,
+ 0x02, 0x00, 0xe4, 0x81, 0xea, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0xeb, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0xec, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0xa0,
+ 0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0xaa, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0xa0,
+ 0x0a, 0x00, 0x00, 0x03, 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0xaa, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0xd0,
+ 0x01, 0x00, 0xe4, 0x80, 0x0c, 0x00, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x80, 0x0e, 0x00, 0x55, 0xa1,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x0e, 0x00, 0xaa, 0xa0, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xff, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x04, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0xaa, 0xa0,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe0, 0x02, 0x00, 0xe4, 0x90,
+ 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoRim_gl3.inc b/src/extras/shaders/neoRim_gl3.inc
new file mode 100644
index 00000000..7e36e95a
--- /dev/null
+++ b/src/extras/shaders/neoRim_gl3.inc
@@ -0,0 +1,39 @@
+const char *neoRim_vert_src =
+"uniform vec3 u_viewVec;\n"
+"uniform vec4 u_rampStart;\n"
+"uniform vec4 u_rampEnd;\n"
+"uniform vec3 u_rimData;\n"
+
+"layout(location = 0) in vec3 in_pos;\n"
+"layout(location = 1) in vec3 in_normal;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+
+"out vec4 v_color;\n"
+"out vec2 v_tex0;\n"
+"out float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
+" gl_Position = u_proj * u_view * Vertex;\n"
+" vec3 Normal = mat3(u_world) * in_normal;\n"
+
+" v_tex0 = in_tex0;\n"
+
+" v_color = in_color;\n"
+" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
+" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
+
+" // rim light\n"
+" float f = u_rimData.x - u_rimData.y*dot(Normal, u_viewVec);\n"
+" vec4 rimlight = clamp(mix(u_rampEnd, u_rampStart, f)*u_rimData.z, 0.0, 1.0);\n"
+" v_color.rgb += rimlight.rgb;\n"
+
+" v_color = clamp(v_color, 0.0, 1.0);\n"
+" v_color *= u_matColor;\n"
+
+" v_fog = DoFog(gl_Position.w);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/neoVehicle.frag b/src/extras/shaders/neoVehicle.frag
new file mode 100644
index 00000000..96d4a632
--- /dev/null
+++ b/src/extras/shaders/neoVehicle.frag
@@ -0,0 +1,28 @@
+uniform sampler2D tex0;
+uniform sampler2D tex1;
+
+in vec4 v_color;
+in vec4 v_reflcolor;
+in vec2 v_tex0;
+in vec2 v_tex1;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ vec4 pass1 = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec3 envmap = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y)).rgb;
+ pass1.rgb = mix(pass1.rgb, envmap, v_reflcolor.a);
+ pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);
+// pass1.rgb += v_reflcolor.rgb * v_fog;
+
+ vec3 pass2 = v_reflcolor.rgb * v_fog;
+
+ color.rgb = pass1.rgb*pass1.a + pass2;
+ color.a = pass1.a;
+
+// color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
+ DoAlphaTest(color.a);
+}
diff --git a/src/extras/shaders/neoVehicle.vert b/src/extras/shaders/neoVehicle.vert
new file mode 100644
index 00000000..f2f54d6d
--- /dev/null
+++ b/src/extras/shaders/neoVehicle.vert
@@ -0,0 +1,54 @@
+uniform vec3 u_eye;
+uniform vec4 u_reflProps;
+uniform vec4 u_specDir[5];
+uniform vec4 u_specColor[5];
+
+#define fresnel (u_reflProps.x)
+#define lightStrength (u_reflProps.y) // speclight alpha
+#define shininess (u_reflProps.z)
+#define specularity (u_reflProps.w)
+
+layout(location = 0) in vec3 in_pos;
+layout(location = 1) in vec3 in_normal;
+layout(location = 2) in vec4 in_color;
+layout(location = 3) in vec2 in_tex0;
+
+out vec4 v_color;
+out vec4 v_reflcolor;
+out vec2 v_tex0;
+out vec2 v_tex1;
+out float v_fog;
+
+vec3 DoDirLightSpec(vec3 Ldir, vec3 Lcol, vec3 N, vec3 V, float power)
+{
+ return pow(clamp(dot(N, normalize(V + -Ldir)), 0.0, 1.0), power)*Lcol;
+}
+
+void
+main(void)
+{
+ vec4 Vertex = u_world * vec4(in_pos, 1.0);
+ gl_Position = u_proj * u_view * Vertex;
+ vec3 Normal = mat3(u_world) * in_normal;
+ vec3 viewVec = normalize(u_eye - Vertex.xyz);
+
+ v_tex0 = in_tex0;
+
+ v_color = in_color;
+ v_color.rgb += u_ambLight.rgb*surfAmbient;
+ v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse*lightStrength;
+ v_color = clamp(v_color, 0.0, 1.0);
+ v_color *= u_matColor;
+
+ // reflect V along Normal
+ vec3 uv2 = Normal*dot(viewVec, Normal)*2.0 - viewVec;
+ v_tex1 = uv2.xy*0.5 + 0.5;
+ float b = 1.0 - clamp(dot(viewVec, Normal), 0.0, 1.0);
+ v_reflcolor = vec4(0.0, 0.0, 0.0, 1.0);
+ v_reflcolor.a = mix(b*b*b*b*b, 1.0f, fresnel)*shininess;
+
+ for(int i = 0; i < 5; i++)
+ v_reflcolor.rgb += DoDirLightSpec(u_specDir[i].xyz, u_specColor[i].rgb, Normal, viewVec, u_specDir[i].w)*specularity*lightStrength;
+
+ v_fog = DoFog(gl_Position.w);
+}
diff --git a/src/extras/shaders/neoVehicle_PS.cso b/src/extras/shaders/neoVehicle_PS.cso
new file mode 100644
index 00000000..ded01bfb
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_PS.cso
Binary files differ
diff --git a/src/extras/shaders/neoVehicle_PS.hlsl b/src/extras/shaders/neoVehicle_PS.hlsl
new file mode 100644
index 00000000..fa030dd6
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_PS.hlsl
@@ -0,0 +1,34 @@
+struct VS_out {
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0;
+ float2 TexCoord1 : TEXCOORD1;
+ float4 Color : COLOR0;
+ float4 ReflColor : COLOR1;
+};
+
+sampler2D tex0 : register(s0);
+sampler2D tex1 : register(s1);
+
+float4 fogColor : register(c0);
+
+float4 main(VS_out input) : COLOR
+{
+ float4 pass1 = input.Color;
+//#ifdef TEX
+ pass1 *= tex2D(tex0, input.TexCoord0.xy);
+//#endif
+ float3 envmap = tex2D(tex1, input.TexCoord1).rgb;
+ pass1.rgb = lerp(pass1.rgb, envmap, input.ReflColor.a);
+// pass1.rgb = envmap;
+// pass1.rgb *= input.ReflColor.a;
+ pass1.rgb = lerp(fogColor.rgb, pass1.rgb, input.TexCoord0.z);
+// pass1.rgb += input.ReflColor.rgb * input.TexCoord0.z;
+
+ float3 pass2 = input.ReflColor.rgb*input.TexCoord0.z;
+
+ float4 color;
+ color.rgb = pass1.rgb*pass1.a + pass2;
+ color.a = pass1.a;
+
+ return color;
+}
diff --git a/src/extras/shaders/neoVehicle_PS.inc b/src/extras/shaders/neoVehicle_PS.inc
new file mode 100644
index 00000000..8b77cec2
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_PS.inc
@@ -0,0 +1,42 @@
+static unsigned char neoVehicle_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x38, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xa4, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x02, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0x00, 0x94, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
+ 0x00, 0xab, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x30,
+ 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x31,
+ 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
+ 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
+ 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+ 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
+ 0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x07, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x0f, 0xa0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x01, 0x00, 0xe4, 0x81, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x90,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xff, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x12, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xaa, 0xb0, 0x00, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x08, 0x80,
+ 0x00, 0x00, 0xaa, 0xb0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80,
+ 0x02, 0x00, 0xff, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xff, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoVehicle_VS.cso b/src/extras/shaders/neoVehicle_VS.cso
new file mode 100644
index 00000000..6ea47987
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_VS.cso
Binary files differ
diff --git a/src/extras/shaders/neoVehicle_VS.hlsl b/src/extras/shaders/neoVehicle_VS.hlsl
new file mode 100644
index 00000000..de75e745
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_VS.hlsl
@@ -0,0 +1,64 @@
+#include "standardConstants.h"
+
+struct VS_in
+{
+ float4 Position : POSITION;
+ float3 Normal : NORMAL;
+ float2 TexCoord : TEXCOORD0;
+ float4 Prelight : COLOR0;
+};
+
+struct VS_out {
+ float4 Position : POSITION;
+ float3 TexCoord0 : TEXCOORD0; // also fog
+ float2 TexCoord1 : TEXCOORD1;
+ float4 Color : COLOR0;
+ float4 ReflColor : COLOR1;
+};
+
+float3 eye : register(c41);
+float4 reflProps : register(c42);
+Light specLights[5] : register(c43);
+
+
+#define fresnel (reflProps.x)
+#define lightStrength (reflProps.y) // speclight alpha
+#define shininess (reflProps.z)
+#define specularity (reflProps.w)
+
+VS_out main(in VS_in input)
+{
+ VS_out output;
+
+ output.Position = mul(combinedMat, input.Position);
+ float3 Vertex = mul(worldMat, input.Position).xyz;
+ float3 Normal = mul(normalMat, input.Normal);
+ float3 viewVec = normalize(eye - Vertex);
+
+ output.TexCoord0.xy = input.TexCoord;
+
+ output.Color = input.Prelight;
+ output.Color.rgb += ambientLight.rgb * surfAmbient*lightStrength;
+
+ int i;
+ for(i = 0; i < numDirLights; i++)
+ output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse*lightStrength;
+ // PS2 clamps before material color
+ output.Color = clamp(output.Color, 0.0, 1.0);
+ output.Color *= matCol;
+
+ // reflect V along Normal
+ float3 uv2 = Normal*dot(viewVec, Normal)*2.0 - viewVec;
+ output.TexCoord1 = uv2.xy*0.5 + 0.5;
+ float b = 1.0 - saturate(dot(viewVec, Normal));
+ output.ReflColor = float4(0.0, 0.0, 0.0, 1.0);
+ output.ReflColor.a = lerp(b*b*b*b*b, 1.0f, fresnel)*shininess;
+
+ //Light mainLight = lights[0];
+ for(i = 0; i < 5; i++)
+ output.ReflColor.xyz += DoDirLightSpec(specLights[i], Normal, viewVec, specLights[i].direction.w)*specularity*lightStrength;
+
+ output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0);
+
+ return output;
+}
diff --git a/src/extras/shaders/neoVehicle_VS.inc b/src/extras/shaders/neoVehicle_VS.inc
new file mode 100644
index 00000000..37c5858d
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_VS.inc
@@ -0,0 +1,160 @@
+static unsigned char neoVehicle_VS_cso[] = {
+ 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0xab, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x76, 0x02, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
+ 0x0d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x6f, 0x02, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x00,
+ 0x01, 0x00, 0x3e, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x29, 0x00, 0x01, 0x00, 0xa6, 0x00, 0x60, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x42, 0x00, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x8c, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x3a, 0x00,
+ 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00,
+ 0x02, 0x00, 0x11, 0x00, 0x18, 0x00, 0x46, 0x00, 0xe0, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x32, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf7, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x00, 0x22, 0x00,
+ 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x24, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00, 0x00, 0x02, 0x00, 0x2a, 0x00,
+ 0x01, 0x00, 0xaa, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0x02, 0x00, 0x00, 0x02, 0x00, 0x2b, 0x00, 0x0f, 0x00, 0xae, 0x00,
+ 0x4c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x36, 0x00, 0x30, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x02, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x12, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74,
+ 0x00, 0xab, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x62,
+ 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x61, 0x74, 0x00, 0x03, 0x00, 0x03, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x65, 0x79, 0x65, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x69, 0x72, 0x73,
+ 0x74, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x00, 0xab, 0x01, 0x00, 0x02, 0x00,
+ 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x66, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x00, 0x6c, 0x69, 0x67, 0x68,
+ 0x74, 0x73, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x00, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0xab,
+ 0x9b, 0x01, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0xbd, 0x01, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x03, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x6d, 0x61, 0x74, 0x43, 0x6f, 0x6c, 0x00, 0x6e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x00, 0xab, 0xab, 0xab,
+ 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72, 0x4c, 0x69,
+ 0x67, 0x68, 0x74, 0x73, 0x00, 0xab, 0xab, 0xab, 0x00, 0x00, 0x02, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x65, 0x66, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x00, 0x73, 0x70,
+ 0x65, 0x63, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0xab, 0xab, 0xab,
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x03, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x73, 0x75, 0x72, 0x66, 0x50, 0x72, 0x6f, 0x70,
+ 0x73, 0x00, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x4d, 0x61, 0x74, 0x00, 0x76,
+ 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73,
+ 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c,
+ 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70,
+ 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35,
+ 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0x51, 0x00, 0x00, 0x05,
+ 0x0b, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x51, 0x00, 0x00, 0x05,
+ 0x3a, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x05,
+ 0x01, 0x00, 0x0f, 0xf0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02,
+ 0x0a, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0f, 0x90, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x90, 0x01, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80,
+ 0x03, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xff, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0x55, 0x90,
+ 0x09, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
+ 0x08, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xe4, 0xa0,
+ 0x01, 0x00, 0xaa, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x01, 0x80, 0x0d, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0x00, 0x80, 0x0f, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x2a, 0x00, 0x55, 0xa0, 0x03, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02,
+ 0x02, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x08, 0x80, 0x0b, 0x00, 0x00, 0xa0, 0x26, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0xe4, 0xf0, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0xff, 0x80, 0x10, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x01, 0x80, 0x03, 0x00, 0x00, 0x80, 0x0b, 0x00, 0x55, 0xa0,
+ 0x2e, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xb0, 0x03, 0x00, 0x00, 0x80,
+ 0x08, 0x00, 0x00, 0x04, 0x03, 0x00, 0x01, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x13, 0x20, 0xe4, 0xa1, 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x01, 0x80, 0x03, 0x00, 0x00, 0x80, 0x0b, 0x00, 0x00, 0xa0,
+ 0x05, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80, 0x03, 0x00, 0x00, 0x80,
+ 0x11, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x0d, 0x00, 0xaa, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x07, 0x80, 0x03, 0x00, 0xe4, 0x80,
+ 0x2a, 0x00, 0x55, 0xa0, 0x02, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x08, 0x80, 0x01, 0x00, 0xff, 0x80, 0x0b, 0x00, 0xaa, 0xa0,
+ 0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x08, 0x80,
+ 0x03, 0x00, 0xff, 0x90, 0x0b, 0x00, 0x00, 0x03, 0x01, 0x00, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0xaa, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x80,
+ 0x0c, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
+ 0x00, 0x00, 0x55, 0x90, 0x05, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x07, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0x90,
+ 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80,
+ 0x06, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xaa, 0x90, 0x01, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, 0x07, 0x00, 0xe4, 0xa0,
+ 0x00, 0x00, 0xff, 0x90, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x81, 0x29, 0x00, 0xe4, 0xa0,
+ 0x24, 0x00, 0x00, 0x02, 0x02, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x06, 0x80,
+ 0x00, 0x00, 0xd0, 0x80, 0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0xff, 0xa0,
+ 0x02, 0x00, 0xd0, 0x81, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x03, 0xe0,
+ 0x01, 0x00, 0xe9, 0x80, 0x3a, 0x00, 0x00, 0xa0, 0x3a, 0x00, 0x00, 0xa0,
+ 0x0b, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x0b, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x0b, 0x00, 0xaa, 0xa0, 0x02, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x81, 0x0b, 0x00, 0xaa, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x02, 0x80, 0x01, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x02, 0x80,
+ 0x01, 0x00, 0x55, 0x80, 0x01, 0x00, 0x55, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x04, 0x80, 0x01, 0x00, 0x55, 0x80, 0x01, 0x00, 0x00, 0x81,
+ 0x0b, 0x00, 0xaa, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x55, 0x80, 0x04, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x01, 0x80, 0x2a, 0x00, 0x00, 0xa0, 0x01, 0x00, 0xaa, 0x80,
+ 0x01, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x08, 0xd0,
+ 0x01, 0x00, 0x00, 0x80, 0x2a, 0x00, 0xaa, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x01, 0x00, 0x0f, 0x80, 0x0b, 0x00, 0x00, 0xa0, 0x26, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0xe4, 0xf0, 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x08, 0x80,
+ 0x01, 0x00, 0xff, 0x80, 0x0b, 0x00, 0x55, 0xa0, 0x2e, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0xb0, 0x02, 0x00, 0xff, 0x80, 0x02, 0x00, 0x00, 0x04,
+ 0x03, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80, 0x2d, 0x20, 0xe4, 0xa1,
+ 0x00, 0x00, 0x00, 0xb0, 0x24, 0x00, 0x00, 0x02, 0x04, 0x00, 0x07, 0x80,
+ 0x03, 0x00, 0xe4, 0x80, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x08, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0x80, 0x0b, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x08, 0x80, 0x02, 0x00, 0xff, 0x80, 0x0b, 0x00, 0x00, 0xa0,
+ 0x0a, 0x00, 0x00, 0x03, 0x02, 0x00, 0x08, 0x80, 0x02, 0x00, 0xff, 0x80,
+ 0x0b, 0x00, 0xaa, 0xa0, 0x20, 0x00, 0x00, 0x04, 0x03, 0x00, 0x01, 0x80,
+ 0x02, 0x00, 0xff, 0x80, 0x2d, 0x20, 0xff, 0xa0, 0x00, 0x00, 0x00, 0xb0,
+ 0x05, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80, 0x03, 0x00, 0x00, 0x80,
+ 0x2b, 0x20, 0xe4, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x2a, 0x00, 0xff, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x07, 0x80, 0x03, 0x00, 0xe4, 0x80,
+ 0x2a, 0x00, 0x55, 0xa0, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x08, 0x80, 0x01, 0x00, 0xff, 0x80, 0x0b, 0x00, 0xaa, 0xa0,
+ 0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x07, 0xd0,
+ 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80,
+ 0x00, 0x00, 0xff, 0x80, 0x0e, 0x00, 0x55, 0xa1, 0x05, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x00, 0xaa, 0xa0,
+ 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x0e, 0x00, 0xff, 0xa0, 0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xe0,
+ 0x00, 0x00, 0x00, 0x80, 0x0b, 0x00, 0xaa, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x03, 0xe0, 0x02, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoVehicle_fs_gl3.inc b/src/extras/shaders/neoVehicle_fs_gl3.inc
new file mode 100644
index 00000000..c75ba717
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_fs_gl3.inc
@@ -0,0 +1,30 @@
+const char *neoVehicle_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform sampler2D tex1;\n"
+
+"in vec4 v_color;\n"
+"in vec4 v_reflcolor;\n"
+"in vec2 v_tex0;\n"
+"in vec2 v_tex1;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 pass1 = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec3 envmap = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y)).rgb;\n"
+" pass1.rgb = mix(pass1.rgb, envmap, v_reflcolor.a);\n"
+" pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);\n"
+"// pass1.rgb += v_reflcolor.rgb * v_fog;\n"
+
+" vec3 pass2 = v_reflcolor.rgb * v_fog;\n"
+
+" color.rgb = pass1.rgb*pass1.a + pass2;\n"
+" color.a = pass1.a;\n"
+
+"// color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
+" DoAlphaTest(color.a);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/neoVehicle_vs_gl3.inc b/src/extras/shaders/neoVehicle_vs_gl3.inc
new file mode 100644
index 00000000..268180e1
--- /dev/null
+++ b/src/extras/shaders/neoVehicle_vs_gl3.inc
@@ -0,0 +1,56 @@
+const char *neoVehicle_vert_src =
+"uniform vec3 u_eye;\n"
+"uniform vec4 u_reflProps;\n"
+"uniform vec4 u_specDir[5];\n"
+"uniform vec4 u_specColor[5];\n"
+
+"#define fresnel (u_reflProps.x)\n"
+"#define lightStrength (u_reflProps.y) // speclight alpha\n"
+"#define shininess (u_reflProps.z)\n"
+"#define specularity (u_reflProps.w)\n"
+
+"layout(location = 0) in vec3 in_pos;\n"
+"layout(location = 1) in vec3 in_normal;\n"
+"layout(location = 2) in vec4 in_color;\n"
+"layout(location = 3) in vec2 in_tex0;\n"
+
+"out vec4 v_color;\n"
+"out vec4 v_reflcolor;\n"
+"out vec2 v_tex0;\n"
+"out vec2 v_tex1;\n"
+"out float v_fog;\n"
+
+"vec3 DoDirLightSpec(vec3 Ldir, vec3 Lcol, vec3 N, vec3 V, float power)\n"
+"{\n"
+" return pow(clamp(dot(N, normalize(V + -Ldir)), 0.0, 1.0), power)*Lcol;\n"
+"}\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
+" gl_Position = u_proj * u_view * Vertex;\n"
+" vec3 Normal = mat3(u_world) * in_normal;\n"
+" vec3 viewVec = normalize(u_eye - Vertex.xyz);\n"
+
+" v_tex0 = in_tex0;\n"
+
+" v_color = in_color;\n"
+" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
+" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse*lightStrength;\n"
+" v_color = clamp(v_color, 0.0, 1.0);\n"
+" v_color *= u_matColor;\n"
+
+" // reflect V along Normal\n"
+" vec3 uv2 = Normal*dot(viewVec, Normal)*2.0 - viewVec;\n"
+" v_tex1 = uv2.xy*0.5 + 0.5;\n"
+" float b = 1.0 - clamp(dot(viewVec, Normal), 0.0, 1.0);\n"
+" v_reflcolor = vec4(0.0, 0.0, 0.0, 1.0);\n"
+" v_reflcolor.a = mix(b*b*b*b*b, 1.0f, fresnel)*shininess;\n"
+
+" for(int i = 0; i < 5; i++)\n"
+" v_reflcolor.rgb += DoDirLightSpec(u_specDir[i].xyz, u_specColor[i].rgb, Normal, viewVec, u_specDir[i].w)*specularity*lightStrength;\n"
+
+" v_fog = DoFog(gl_Position.w);\n"
+"}\n"
+;
diff --git a/src/extras/shaders/neoWorldVC.frag b/src/extras/shaders/neoWorldVC.frag
new file mode 100644
index 00000000..0270f305
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC.frag
@@ -0,0 +1,25 @@
+uniform sampler2D tex0;
+uniform sampler2D tex1;
+
+uniform vec4 u_lightMap;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in vec2 v_tex1;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ vec4 t0 = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec4 t1 = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
+
+ color = t0*v_color*(1 + u_lightMap*(t1-1));
+ color.a = v_color.a*t0.a*u_lightMap.a;
+
+ color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
+ DoAlphaTest(color.a);
+}
+
diff --git a/src/extras/shaders/neoWorldVC_PS.cso b/src/extras/shaders/neoWorldVC_PS.cso
new file mode 100644
index 00000000..5e8d1696
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/neoWorldVC_PS.hlsl b/src/extras/shaders/neoWorldVC_PS.hlsl
new file mode 100644
index 00000000..fc4f1de9
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC_PS.hlsl
@@ -0,0 +1,25 @@
+sampler2D Diffuse : register(s0);
+sampler2D Light : register(s1);
+float4 fogColor : register(c0);
+float4 lm : register(c1);
+
+struct PS_INPUT
+{
+ float4 Color : COLOR0;
+ float3 Tex0 : TEXCOORD0;
+ float2 Tex1 : TEXCOORD1;
+};
+
+float4
+main(PS_INPUT IN) : COLOR
+{
+ float4 t0 = tex2D(Diffuse, IN.Tex0.xy);
+ float4 t1 = tex2D(Light, IN.Tex1);
+
+ float4 col = t0*IN.Color*(1 + lm*(t1-1));
+ col.a = IN.Color.a*t0.a*lm.a;
+
+ col.rgb = lerp(fogColor.rgb, col.rgb, IN.Tex0.z);
+
+ return col;
+}
diff --git a/src/extras/shaders/neoWorldVC_PS.inc b/src/extras/shaders/neoWorldVC_PS.inc
new file mode 100644
index 00000000..eb8bf2ee
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC_PS.inc
@@ -0,0 +1,46 @@
+static unsigned char neoWorldVC_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x3e, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xbb, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x02, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x84, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0x00,
+ 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x06, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x00, 0x04, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4c, 0x69, 0x67, 0x68, 0x74, 0x00, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x66, 0x6f, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0xab,
+ 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6d, 0x00, 0x70, 0x73, 0x5f, 0x32, 0x5f,
+ 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20,
+ 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61,
+ 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72,
+ 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31,
+ 0x31, 0x31, 0x00, 0xab, 0x51, 0x00, 0x00, 0x05, 0x02, 0x00, 0x0f, 0xa0,
+ 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x07, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x0f, 0xa0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0,
+ 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x02, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80,
+ 0x02, 0x00, 0x55, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xff, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x80,
+ 0x01, 0x00, 0xff, 0x80, 0x00, 0x00, 0xff, 0x90, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0xff, 0x80, 0x01, 0x00, 0xff, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa1, 0x04, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xaa, 0xb0, 0x00, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/neoWorldVC_fs_gl3.inc b/src/extras/shaders/neoWorldVC_fs_gl3.inc
new file mode 100644
index 00000000..c861d334
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC_fs_gl3.inc
@@ -0,0 +1,27 @@
+const char *neoWorldVC_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform sampler2D tex1;\n"
+
+"uniform vec4 u_lightMap;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in vec2 v_tex1;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 t0 = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec4 t1 = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n"
+
+" color = t0*v_color*(1 + u_lightMap*(t1-1));\n"
+" color.a = v_color.a*t0.a*u_lightMap.a;\n"
+
+" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
+" DoAlphaTest(color.a);\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/simple.frag b/src/extras/shaders/simple.frag
new file mode 100644
index 00000000..87157beb
--- /dev/null
+++ b/src/extras/shaders/simple.frag
@@ -0,0 +1,16 @@
+uniform sampler2D tex0;
+
+in vec4 v_color;
+in vec2 v_tex0;
+in float v_fog;
+
+out vec4 color;
+
+void
+main(void)
+{
+ color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
+ DoAlphaTest(color.a);
+}
+
diff --git a/src/extras/shaders/simple_fs_gl3.inc b/src/extras/shaders/simple_fs_gl3.inc
new file mode 100644
index 00000000..47d89971
--- /dev/null
+++ b/src/extras/shaders/simple_fs_gl3.inc
@@ -0,0 +1,18 @@
+const char *simple_frag_src =
+"uniform sampler2D tex0;\n"
+
+"in vec4 v_color;\n"
+"in vec2 v_tex0;\n"
+"in float v_fog;\n"
+
+"out vec4 color;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
+" DoAlphaTest(color.a);\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/standardConstants.h b/src/extras/shaders/standardConstants.h
new file mode 100644
index 00000000..088df7dd
--- /dev/null
+++ b/src/extras/shaders/standardConstants.h
@@ -0,0 +1,28 @@
+float4x4 combinedMat : register(c0);
+float4x4 worldMat : register(c4);
+float3x3 normalMat : register(c8);
+float4 matCol : register(c12);
+float4 surfProps : register(c13);
+float4 fogData : register(c14);
+float4 ambientLight : register(c15);
+
+#define surfAmbient (surfProps.x)
+#define surfSpecular (surfProps.y)
+#define surfDiffuse (surfProps.z)
+
+#define fogStart (fogData.x)
+#define fogEnd (fogData.y)
+#define fogRange (fogData.z)
+#define fogDisable (fogData.w)
+
+#include "lighting.h"
+
+int numDirLights : register(i0);
+int numPointLights : register(i1);
+int numSpotLights : register(i2);
+int4 firstLight : register(c16);
+Light lights[8] : register(c17);
+
+#define firstDirLight (firstLight.x)
+#define firstPointLight (firstLight.y)
+#define firstSpotLight (firstLight.z)
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 8d07737f..e4758a96 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -8,6 +8,7 @@
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
+#include "custompipes.h"
//--MIAMI: file done
@@ -39,6 +40,9 @@ RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[PED_NODE_MAX] = {
void
CPedModelInfo::SetClump(RpClump *clump)
{
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::AttachRimPipe(clump);
+#endif
CClumpModelInfo::SetClump(clump);
SetFrameIds(m_pPedIds); // not needed in VC actually
if(m_hitColModel == nil)
diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp
index a7e6d56c..2e6e557e 100644
--- a/src/modelinfo/SimpleModelInfo.cpp
+++ b/src/modelinfo/SimpleModelInfo.cpp
@@ -4,6 +4,7 @@
#include "Camera.h"
#include "ModelInfo.h"
#include "AnimManager.h"
+#include "custompipes.h"
//--MIAMI: file done
@@ -88,6 +89,13 @@ CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic)
if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS &&
RpGeometryGetNumTriangles(geo) > 200)
debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo));
+
+#ifdef EXTENDED_PIPELINES
+ if(m_wetRoadReflection)
+ CustomPipes::AttachGlossPipe(atomic);
+ else
+ CustomPipes::AttachWorldPipe(atomic);
+#endif
}
void
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 11f78495..5d69a921 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -19,6 +19,7 @@
#include "Bike.h"
#include "ModelIndices.h"
#include "ModelInfo.h"
+#include "custompipes.h"
//--MIAMI: done
@@ -210,7 +211,7 @@ CVehicleModelInfo::CreateInstance(void)
clumpframe = RpClumpGetFrame(clump);
comp1 = ChooseComponent();
- if(comp1 != -1){
+ if(comp1 != -1 && m_comps[comp1]){
atomic = RpAtomicClone(m_comps[comp1]);
f = RwFrameCreate();
RwFrameTransform(f,
@@ -223,7 +224,7 @@ CVehicleModelInfo::CreateInstance(void)
ms_compsUsed[0] = comp1;
comp2 = ChooseSecondComponent();
- if(comp2 != -1){
+ if(comp2 != -1 && m_comps[comp2]){
atomic = RpAtomicClone(m_comps[comp2]);
f = RwFrameCreate();
RwFrameTransform(f,
@@ -1124,6 +1125,10 @@ CVehicleModelInfo::SetEnvironmentMap(void)
for(i = 0; i < wheelmi->m_numAtomics; i++)
SetEnvironmentMapCB(wheelmi->m_atomics[i], nil);
}
+
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::AttachVehiclePipe(m_clump);
+#endif
}
void
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index b2a77bc5..6ed74214 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -124,8 +124,6 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
CParticleObject *pobj = pUnusedListHead;
- ASSERT(pobj != nil);
-
if ( pobj == nil )
{
printf("Error: No particle objects available!\n");
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 4c8a29cc..390c3ccd 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -63,6 +63,7 @@
#include "Debug.h"
#include "GameLogic.h"
#include "Bike.h"
+#include "WindModifiers.h"
#include "CutsceneShadow.h"
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
@@ -438,7 +439,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bCrouchWhenScared = false;
bKnockedOffBike = false;
b158_8 = false;
- b158_10 = false;
+ bCollectBusFare = false;
bBoughtIceCream = false;
b158_40 = false;
@@ -2797,6 +2798,7 @@ CPed::SetModelIndex(uint32 mi)
{
m_pRTShadow = new CCutsceneShadow;
m_pRTShadow->Create(m_rwObject, 10, 1, 1, 1);
+ //m_pRTShadow->Create(m_rwObject, 8, 0, 0, 0);
}
#endif
}
@@ -2999,6 +3001,22 @@ CPed::CanBeDeleted(void)
}
}
+//--MIAMI: done
+bool
+CPed::CanBeDeletedEvenInVehicle(void)
+{
+ switch (CharCreatedBy) {
+ case RANDOM_CHAR:
+ return true;
+ case MISSION_CHAR:
+ return false;
+ case TODO_CHAR:
+ return false;
+ default:
+ return true;
+ }
+}
+
// --MIAMI: Done
bool
CPed::CanPedDriveOff(void)
@@ -3158,6 +3176,8 @@ CPed::SetStoredObjective(void)
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
case OBJECTIVE_HASSLE_CHAR:
+ case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
+ case OBJECTIVE_LEAVE_CAR:
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
@@ -4728,9 +4748,11 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
} else {
CDarkel::RegisterKillNotByPlayer(this, method);
}
- if (method == WEAPONTYPE_DROWNING)
+ if (method == WEAPONTYPE_DROWNING) {
bIsInTheAir = false;
- // TODO(Miami): timesDrowned
+ if (FindPlayerPed() == this)
+ CStats::TimesDrowned++;
+ }
return true;
}
@@ -11804,7 +11826,11 @@ CPed::ProcessControl(void)
CPed::Chat();
break;
case PED_AIM_GUN:
- if (m_pPointGunAt && m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, CAN_SEE_ENTITY_ANGLE_THRESHOLD * 2)) {
+ if (m_pPointGunAt && m_pPointGunAt->IsPed()
+#ifdef FIX_BUGS
+ && !GetWeapon()->IsTypeMelee()
+#endif
+ && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, CAN_SEE_ENTITY_ANGLE_THRESHOLD * 2)) {
((CPed*)m_pPointGunAt)->ReactToPointGun(this);
}
PointGunAt();
@@ -12976,10 +13002,10 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->b157_40 = false;
ped->bRemoveFromWorld = true;
}
- if (ped->b158_10) {
- ped->b158_10 = false;
+ if (ped->bCollectBusFare) {
+ ped->bCollectBusFare = false;
if (FindPlayerPed())
- FindPlayerPed()->m_nPadUpPressedInMilliseconds += 5;
+ FindPlayerPed()->m_nLastBusFareCollected += 5;
}
if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
@@ -14601,7 +14627,7 @@ CPed::ProcessObjective(void)
if (m_pMyVehicle) {
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
} else {
- float closestVehDist = 3600.0f;
+ float closestVehDist = SQR(60.0f);
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
@@ -14614,11 +14640,11 @@ CPed::ProcessObjective(void)
CVector ourSpeed = GetSpeed();
*/
CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
- if (vehDistVec.Magnitude() < closestVehDist
+ if (vehDistVec.MagnitudeSqr() < closestVehDist
&& m_pedInObjective->m_pMyVehicle != nearVeh)
{
foundVeh = nearVeh;
- closestVehDist = vehDistVec.Magnitude();
+ closestVehDist = vehDistVec.MagnitudeSqr();
}
}
m_pMyVehicle = foundVeh;
@@ -15166,7 +15192,7 @@ CPed::ProcessObjective(void)
b157_40 = true;
CPlayerPed *player = FindPlayerPed();
if (pBus->IsPassenger(player) || pBus->IsDriver(player)) {
- b158_10 = true;
+ bCollectBusFare = true;
}
}
}
@@ -16425,6 +16451,77 @@ CPed::PreRender(void)
}
#endif
+ bool bIsWindModifierTurnedOn = false;
+ float fAnyDirectionShift = 1.0f;
+ if (IsPlayer() && CWindModifiers::FindWindModifier(GetPosition(), &fAnyDirectionShift, &fAnyDirectionShift)
+ && !CCullZones::PlayerNoRain() && GetPedState() != PED_DRIVING)
+ bIsWindModifierTurnedOn = true;
+
+ bool bIsPedDrivingBikeOrOpenTopCar = false;
+ if (GetPedState() == PED_DRIVING && m_pMyVehicle) {
+ if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE
+ || (m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR && m_pMyVehicle->IsOpenTopCar()))
+ bIsPedDrivingBikeOrOpenTopCar = true;
+ }
+
+ if (bIsWindModifierTurnedOn || bIsPedDrivingBikeOrOpenTopCar) {
+ float fWindMult = 0.0f;
+ if (bIsPedDrivingBikeOrOpenTopCar) {
+ fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward());
+ if (fWindMult > 0.4f) {
+ float volume = (fWindMult - 0.4f) / 0.6f;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SET_202, volume); //TODO(MIAMI): revise when audio is done
+ }
+ }
+
+ if (bIsWindModifierTurnedOn)
+ fWindMult = Min(fWindMult, Abs(fAnyDirectionShift - 1.0f));
+
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+ float fScaleOffset;
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.1f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLEL));
+ RwMatrix* clavicleL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLER));
+ RwMatrix* clavicleR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+ }
+
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);
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 6b0cc5fb..56244752 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -485,7 +485,7 @@ public:
uint32 bCrouchWhenScared : 1;
uint32 bKnockedOffBike : 1;
uint32 b158_8 : 1;
- uint32 b158_10 : 1;
+ uint32 bCollectBusFare : 1;
uint32 bBoughtIceCream : 1;
uint32 b158_40 : 1;
//uint32 b158_80
@@ -911,6 +911,7 @@ public:
bool IsPedInControl(void);
bool CanPedDriveOff(void);
bool CanBeDeleted(void);
+ bool CanBeDeletedEvenInVehicle(void);
bool CanStrafeOrMouseControl(void);
bool CanPedReturnToState(void);
void SetMoveState(eMoveState);
diff --git a/src/peds/PedChat.cpp b/src/peds/PedChat.cpp
index 4480a8cd..73a8e59c 100644
--- a/src/peds/PedChat.cpp
+++ b/src/peds/PedChat.cpp
@@ -131,9 +131,9 @@ CPed::Say(uint16 audio)
case SOUND_PED_FLEE_SPRINT:
case SOUND_PED_TAXI_WAIT:
case SOUND_PED_EVADE:
- case SOUND_PED_CAR_COLLISION:
- case SOUND_PED_BOAT_COLLISION:
- case SOUND_PED_HORN_ACTIVE:
+ case SOUND_PED_CRASH_VEHICLE:
+ case SOUND_PED_CRASH_CAR:
+ case SOUND_PED_ANNOYED_DRIVER:
break;
default:
return;
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index cba01e31..041fb5e8 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -83,7 +83,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_pMeleeList[i] = nil;
}
m_nCheckPlayersIndex = 0;
- m_nPadUpPressedInMilliseconds = 0;
+ m_nLastBusFareCollected = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
}
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 3b8d8fcb..8a6e7576 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -43,7 +43,7 @@ public:
float m_fGunSpinSpeed; // for minigun
float m_fGunSpinAngle;
unsigned int m_nPadDownPressedInMilliseconds;
- unsigned int m_nPadUpPressedInMilliseconds;
+ unsigned int m_nLastBusFareCollected;
CPlayerPed();
~CPlayerPed();
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index f7e0973f..18c1ce04 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -127,8 +127,7 @@ CPopulation::Initialise()
void
CPopulation::RemovePed(CPed *ent)
{
- // CPed dtor already does that
- // CWorld::Remove((CEntity*)ent);
+ CWorld::Remove((CEntity*)ent);
delete ent;
}
diff --git a/src/render/Antennas.cpp b/src/render/Antennas.cpp
index 452069a0..b9da95cb 100644
--- a/src/render/Antennas.cpp
+++ b/src/render/Antennas.cpp
@@ -2,6 +2,8 @@
#include "Antennas.h"
+//--MIAMI: file done
+
CAntenna CAntennas::aAntennas[NUMANTENNAS];
void
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index c6ba0f10..15bae90b 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -71,6 +71,43 @@ CClouds::Update(void)
#endif
}
+float StarCoorsX[9] = { 0.0f, 0.05f, 0.13f, 0.4f, 0.7f, 0.6f, 0.27f, 0.55f, 0.75f };
+float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
+float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
+
+float LowCloudsX[12] = { 1.0f, 0.7f, 0.0f, -0.7f, -1.0f, -0.7f, 0.0f, 0.7f, 0.8f, -0.8f, 0.4f, -0.4f };
+float LowCloudsY[12] = { 0.0f, -0.7f, -1.0f, -0.7f, 0.0f, 0.7f, 1.0f, 0.7f, 0.4f, 0.4f, -0.8f, -0.8f };
+float LowCloudsZ[12] = { 0.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.3f, 0.9f, 0.4f, 1.3f, 1.4f, 1.2f, 1.7f };
+
+float CoorsOffsetX[37] = {
+ 0.0f, 60.0f, 72.0f, 48.0f, 21.0f, 12.0f,
+ 9.0f, -3.0f, -8.4f, -18.0f, -15.0f, -36.0f,
+ -40.0f, -48.0f, -60.0f, -24.0f, 100.0f, 100.0f,
+ 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
+ 100.0f, 100.0f, -30.0f, -20.0f, 10.0f, 30.0f,
+ 0.0f, -100.0f, -100.0f, -100.0f, -100.0f, -100.0f, -100.0f
+};
+float CoorsOffsetY[37] = {
+ 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
+ 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
+ 100.0f, 100.0f, 100.0f, 100.0f, -30.0f, 10.0f,
+ -25.0f, -5.0f, 28.0f, -10.0f, 10.0f, 0.0f,
+ 15.0f, 40.0f, -100.0f, -100.0f, -100.0f, -100.0f,
+ -100.0f, -40.0f, -20.0f, 0.0f, 10.0f, 30.0f, 35.0f
+};
+float CoorsOffsetZ[37] = {
+ 2.0f, 1.0f, 0.0f, 0.3f, 0.7f, 1.4f,
+ 1.7f, 0.24f, 0.7f, 1.3f, 1.6f, 1.0f,
+ 1.2f, 0.3f, 0.7f, 1.4f, 0.0f, 0.1f,
+ 0.5f, 0.4f, 0.55f, 0.75f, 1.0f, 1.4f,
+ 1.7f, 2.0f, 2.0f, 2.3f, 1.9f, 2.4f,
+ 2.0f, 2.0f, 1.5f, 1.2f, 1.7f, 1.5f, 2.1f
+};
+
+uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
+uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
+uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
+
void
CClouds::Render(void)
{
@@ -94,11 +131,10 @@ CClouds::Render(void)
float minute = CClock::GetHours()*60 + CClock::GetMinutes() + CClock::GetSeconds()/60.0f;
RwV3d campos = *(RwV3d*)&TheCamera.GetPosition();
- float coverage = Max(CWeather::Foggyness, CWeather::Foggyness);
-
// Moon
float moonfadeout = Abs(minute - 180.0f); // fully visible at 3AM
if((int)moonfadeout < 180){ // fade in/out 3 hours
+ float coverage = Max(CWeather::Foggyness, CWeather::CloudCoverage);
int brightness = (1.0f - coverage) * (180 - (int)moonfadeout);
RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos);
@@ -122,11 +158,10 @@ CClouds::Render(void)
else if(CClock::GetHours() == 5)
starintens = 255 * (60 - CClock::GetMinutes())/60.0f;
if(starintens != 0){
- // R
- static float StarCoorsX[9] = { 0.0f, 0.05f, 0.13f, 0.4f, 0.7f, 0.6f, 0.27f, 0.55f, 0.75f };
- static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
- static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
+ float coverage = Max(CWeather::Foggyness, CWeather::CloudCoverage);
int brightness = (1.0f - coverage) * starintens;
+
+ // R
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 11; i++){
RwV3d pos = { 100.0f, 0.0f, 10.0f };
@@ -155,13 +190,7 @@ CClouds::Render(void)
}
// Low clouds
- static float LowCloudsX[12] = { 1.0f, 0.7f, 0.0f, -0.7f, -1.0f, -0.7f,
- 0.0f, 0.7f, 0.8f, -0.8f, 0.4f, -0.4f };
- static float LowCloudsY[12] = { 0.0f, -0.7f, -1.0f, -0.7f, 0.0f, 0.7f,
- 1.0f, 0.7f, 0.4f, 0.4f, -0.8f, -0.8f };
- static float LowCloudsZ[12] = { 0.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.3f,
- 0.9f, 0.4f, 1.3f, 1.4f, 1.2f, 1.7f };
- float lowcloudintensity = 1.0f - Max(coverage, CWeather::ExtraSunnyness);
+ float lowcloudintensity = 1.0f - Max(Max(CWeather::Foggyness, CWeather::CloudCoverage), CWeather::ExtraSunnyness);
int r = CTimeCycle::GetLowCloudsRed() * lowcloudintensity;
int g = CTimeCycle::GetLowCloudsGreen() * lowcloudintensity;
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
@@ -184,30 +213,6 @@ CClouds::Render(void)
float rot_cos = Cos(CloudRotation);
int fluffyalpha = 160 * (1.0f - Max(CWeather::Foggyness, CWeather::ExtraSunnyness));
if(fluffyalpha != 0){
- static float CoorsOffsetX[37] = {
- 0.0f, 60.0f, 72.0f, 48.0f, 21.0f, 12.0f,
- 9.0f, -3.0f, -8.4f, -18.0f, -15.0f, -36.0f,
- -40.0f, -48.0f, -60.0f, -24.0f, 100.0f, 100.0f,
- 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
- 100.0f, 100.0f, -30.0f, -20.0f, 10.0f, 30.0f,
- 0.0f, -100.0f, -100.0f, -100.0f, -100.0f, -100.0f, -100.0f
- };
- static float CoorsOffsetY[37] = {
- 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
- 100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,
- 100.0f, 100.0f, 100.0f, 100.0f, -30.0f, 10.0f,
- -25.0f, -5.0f, 28.0f, -10.0f, 10.0f, 0.0f,
- 15.0f, 40.0f, -100.0f, -100.0f, -100.0f, -100.0f,
- -100.0f, -40.0f, -20.0f, 0.0f, 10.0f, 30.0f, 35.0f
- };
- static float CoorsOffsetZ[37] = {
- 2.0f, 1.0f, 0.0f, 0.3f, 0.7f, 1.4f,
- 1.7f, 0.24f, 0.7f, 1.3f, 1.6f, 1.0f,
- 1.2f, 0.3f, 0.7f, 1.4f, 0.0f, 0.1f,
- 0.5f, 0.4f, 0.55f, 0.75f, 1.0f, 1.4f,
- 1.7f, 2.0f, 2.0f, 2.3f, 1.9f, 2.4f,
- 2.0f, 2.0f, 1.5f, 1.2f, 1.7f, 1.5f, 2.1f
- };
static bool bCloudOnScreen[37];
float sundist, hilight;
@@ -230,7 +235,7 @@ CClouds::Render(void)
int bb = CTimeCycle::GetFluffyCloudsBottomBlue();
int distLimit = (3*SCREEN_WIDTH)/4;
if(sundist < distLimit){
- hilight = (1.0f - coverage) * (1.0f - sundist/(float)distLimit);
+ hilight = (1.0f - Max(CWeather::Foggyness, CWeather::CloudCoverage)) * (1.0f - sundist/(float)distLimit);
tr = tr*(1.0f-hilight) + 255*hilight;
tg = tg*(1.0f-hilight) + 190*hilight;
tb = tb*(1.0f-hilight) + 190*hilight;
@@ -277,9 +282,6 @@ CClouds::Render(void)
// Rainbow
if(CWeather::Rainbow != 0.0f){
- static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
- static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
- static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 6; i++){
RwV3d pos = { i*1.5f, 100.0f, 5.0f };
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index efe486fe..2d621d18 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
+#include "RenderBuffer.h"
#include "TxdStore.h"
#include "Camera.h"
#include "Sprite.h"
@@ -12,6 +13,8 @@
#include "Timecycle.h"
#include "Coronas.h"
+//--MIAMI: file done
+
struct FlareDef
{
float position;
@@ -130,13 +133,21 @@ void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
- bool longDist, float nearDist)
+ bool useNearDist, float nearDist)
{
int i;
if(sq(drawDist) < (TheCamera.GetPosition() - coors).MagnitudeSqr2D())
return;
+ if(useNearDist){
+ float dist = (TheCamera.GetPosition() - coors).Magnitude();
+ if(dist < 35.0f)
+ return;
+ if(dist < 50.0f)
+ alpha *= (dist - 35.0f)/(50.0f - 35.0f);
+ }
+
for(i = 0; i < NUMCORONAS; i++)
if(aCoronas[i].id == id)
break;
@@ -189,17 +200,19 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al
aCoronas[i].reflection = reflection;
aCoronas[i].LOScheck = LOScheck;
aCoronas[i].drawStreak = drawStreak;
+ aCoronas[i].useNearDist = useNearDist;
+ aCoronas[i].nearDist = nearDist;
}
void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, uint8 type,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
- bool longDist, float nearDist)
+ bool useNearDist, float nearDist)
{
RegisterCorona(id, red, green, blue, alpha, coors, size, drawDist,
gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle,
- longDist, nearDist);
+ useNearDist, nearDist);
}
void
@@ -258,7 +271,10 @@ CCoronas::Render(void)
CVector spriteCoors;
float spritew, spriteh;
- if(CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){
+ if(!CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){
+ aCoronas[i].offScreen = true;
+ aCoronas[i].sightClear = false;
+ }else{
aCoronas[i].offScreen = false;
if(spriteCoors.x < 0.0f || spriteCoors.y < 0.0f ||
@@ -292,10 +308,7 @@ CCoronas::Render(void)
}
- if(aCoronas[i].fadeAlpha == 0)
- continue;
-
- if(spriteCoors.z < aCoronas[i].drawDist){
+ if(aCoronas[i].fadeAlpha && spriteCoors.z < aCoronas[i].drawDist){
float recipz = 1.0f/spriteCoors.z;
float fadeDistance = aCoronas[i].drawDist / 2.0f;
float distanceFade = spriteCoors.z < fadeDistance ? 1.0f : 1.0f - (spriteCoors.z - fadeDistance)/fadeDistance;
@@ -312,7 +325,7 @@ CCoronas::Render(void)
if(CCoronas::aCoronas[i].id == SUN_CORE)
spriteCoors.z = 0.95f * RwCameraGetFarClipPlane(Scene.camera);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(aCoronas[i].texture));
- spriteCoors.z -= 1.5f;
+ spriteCoors.z -= aCoronas[i].nearDist;
if(aCoronas[i].texture == gpCoronaTexture[8]){
// what's this?
@@ -370,14 +383,11 @@ CCoronas::Render(void)
recipz, 255);
}
}
- }else{
- aCoronas[i].offScreen = true;
- aCoronas[i].sightClear = false;
}
}
}
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
@@ -393,23 +403,24 @@ CCoronas::Render(void)
if(!aCoronas[i].hasValue[j] || !aCoronas[i].hasValue[j+1])
continue;
- int mod1 = (float)(6 - j) / 6 * 128;
- int mod2 = (float)(6 - (j+1)) / 6 * 128;
+ int alpha1 = (float)(6 - j) / 6 * 128;
+ int alpha2 = (float)(6 - (j+1)) / 6 * 128;
RwIm2DVertexSetScreenX(&vertexbufferX[0], aCoronas[i].prevX[j]);
RwIm2DVertexSetScreenY(&vertexbufferX[0], aCoronas[i].prevY[j]);
- RwIm2DVertexSetIntRGBA(&vertexbufferX[0], aCoronas[i].prevRed[j] * mod1 / 256, aCoronas[i].prevGreen[j] * mod1 / 256, aCoronas[i].prevBlue[j] * mod1 / 256, 255);
+ RwIm2DVertexSetIntRGBA(&vertexbufferX[0], aCoronas[i].prevRed[j] * alpha1 / 256, aCoronas[i].prevGreen[j] * alpha1 / 256, aCoronas[i].prevBlue[j] * alpha1 / 256, 255);
RwIm2DVertexSetScreenX(&vertexbufferX[1], aCoronas[i].prevX[j+1]);
RwIm2DVertexSetScreenY(&vertexbufferX[1], aCoronas[i].prevY[j+1]);
- RwIm2DVertexSetIntRGBA(&vertexbufferX[1], aCoronas[i].prevRed[j+1] * mod2 / 256, aCoronas[i].prevGreen[j+1] * mod2 / 256, aCoronas[i].prevBlue[j+1] * mod2 / 256, 255);
+ RwIm2DVertexSetIntRGBA(&vertexbufferX[1], aCoronas[i].prevRed[j+1] * alpha2 / 256, aCoronas[i].prevGreen[j+1] * alpha2 / 256, aCoronas[i].prevBlue[j+1] * alpha2 / 256, 255);
- // BUG: game doesn't do this
+#ifdef FIX_BUGS
RwIm2DVertexSetScreenZ(&vertexbufferX[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&vertexbufferX[0], RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetRecipCameraZ(&vertexbufferX[0], 1.0f/RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetScreenZ(&vertexbufferX[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&vertexbufferX[1], RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetRecipCameraZ(&vertexbufferX[1], 1.0f/RwCameraGetNearClipPlane(Scene.camera));
+#endif
RwIm2DRenderLine(vertexbufferX, 2, 0, 1);
}
@@ -428,6 +439,8 @@ CCoronas::RenderReflections(void)
CEntity *entity;
if(CWeather::WetRoads > 0.0f){
+ CSprite::InitSpriteBuffer();
+
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
@@ -438,7 +451,8 @@ CCoronas::RenderReflections(void)
for(i = 0; i < NUMCORONAS; i++){
if(aCoronas[i].id == 0 ||
- aCoronas[i].fadeAlpha == 0 && aCoronas[i].alpha == 0)
+ aCoronas[i].fadeAlpha == 0 && aCoronas[i].alpha == 0 ||
+ aCoronas[i].reflection == 0)
continue;
// check if we want a reflection on this corona
@@ -453,11 +467,8 @@ CCoronas::RenderReflections(void)
}
}
- if(!aCoronas[i].renderReflection)
- continue;
-
// Don't draw if reflection is too high
- if(aCoronas[i].heightAboveRoad < 20.0f){
+ if(aCoronas[i].renderReflection && aCoronas[i].heightAboveRoad < 20.0f){
// don't draw if camera is below road
if(CCoronas::aCoronas[i].coors.z - aCoronas[i].heightAboveRoad > TheCamera.GetPosition().z)
continue;
@@ -469,13 +480,14 @@ 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, 55.0f);
if(spriteCoors.z < drawDist){
float fadeDistance = drawDist / 2.0f;
float distanceFade = spriteCoors.z < fadeDistance ? 1.0f : 1.0f - (spriteCoors.z - fadeDistance)/fadeDistance;
distanceFade = clamp(distanceFade, 0.0f, 1.0f);
float recipz = 1.0f/RwCameraGetNearClipPlane(Scene.camera);
- int intensity = (20.0f - aCoronas[i].heightAboveRoad) * 230.0 * distanceFade*CWeather::WetRoads * 0.05f;
+ float heightFade = (20.0f - aCoronas[i].heightAboveRoad)/20.0f;
+ int intensity = distanceFade*heightFade * 230.0 * CWeather::WetRoads;
CSprite::RenderBufferedOneXLUSprite(
spriteCoors.x, spriteCoors.y, RwIm2DGetNearScreenZ(),
@@ -504,6 +516,130 @@ CCoronas::RenderReflections(void)
}
}
+void
+CCoronas::RenderSunReflection(void)
+{
+ float sunZDir = CTimeCycle::GetSunDirection().z;
+ if(sunZDir > -0.05f){
+ float intensity = (0.3f - Abs(sunZDir - 0.25f))/0.3f *
+ (1.0f - CWeather::CloudCoverage) *
+ (1.0f - CWeather::Foggyness) *
+ (1.0f - CWeather::Wind);
+ if(intensity > 0.0f){
+ int r = (CTimeCycle::GetSunCoreRed() + CTimeCycle::GetSunCoronaRed())*intensity*0.25f;
+ int g = (CTimeCycle::GetSunCoreGreen() + CTimeCycle::GetSunCoronaGreen())*intensity*0.25f;
+ int b = (CTimeCycle::GetSunCoreBlue() + CTimeCycle::GetSunCoronaBlue())*intensity*0.25f;
+
+ CVector sunPos = 40.0f*CTimeCycle::GetSunDirection() + TheCamera.GetPosition();
+ sunPos.z = 0.5f*CWeather::Wind + 6.1f;
+ CVector sunDir = CTimeCycle::GetSunDirection();
+ sunDir.z = 0.0;
+ sunDir.Normalise();
+
+ TempBufferIndicesStored = 6;
+ TempBufferRenderIndexList[0] = 2;
+ TempBufferRenderIndexList[1] = 1;
+ TempBufferRenderIndexList[2] = 0;
+ TempBufferRenderIndexList[3] = 2;
+ TempBufferRenderIndexList[4] = 3;
+ TempBufferRenderIndexList[5] = 1;
+
+ // 60 unit square in sun direction
+ TempBufferVerticesStored = 4;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[0],
+ sunPos.x + 30.0f*sunDir.y,
+ sunPos.y - 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[1],
+ sunPos.x - 30.0f*sunDir.y,
+ sunPos.y + 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[2], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[2],
+ sunPos.x + 60.0f*sunDir.x + 30.0f*sunDir.y,
+ sunPos.y + 60.0f*sunDir.y - 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[3], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[3],
+ sunPos.x + 60.0f*sunDir.x - 30.0f*sunDir.y,
+ sunPos.y + 60.0f*sunDir.y + 30.0f*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetU(&TempBufferRenderVertices[0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[0], 1.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[1], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[1], 1.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[2], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[2], 0.5f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[3], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[3], 0.5f);
+
+ int timeInc = 0;
+ int sideInc = 0;
+ int fwdInc = 0;
+ for(int i = 0; i < 20; i++){
+ TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored-1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored-2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored+1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored-1;
+ TempBufferIndicesStored += 6;
+
+ // What a weird way to do it...
+ float fwdLen = fwdInc/20 + 60;
+ float sideLen = sideInc/20 + 30;
+ sideLen += 10.0f*Sin((float)(CTimer::GetTimeInMilliseconds()+timeInc & 0x7FF)/0x800*TWOPI);
+ timeInc += 900;
+ sideInc += 970;
+ fwdInc += 1440;
+
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+0], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+0],
+ sunPos.x + fwdLen*sunDir.x + sideLen*sunDir.y,
+ sunPos.y + fwdLen*sunDir.y - sideLen*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+1], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+1],
+ sunPos.x + fwdLen*sunDir.x - sideLen*sunDir.y,
+ sunPos.y + fwdLen*sunDir.y + sideLen*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.5f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+1], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+1], 0.5f);
+ TempBufferVerticesStored += 2;
+ }
+
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[4]));
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+ }
+}
+
void
CCoronas::DoSunAndMoon(void)
{
@@ -520,7 +656,7 @@ CCoronas::DoSunAndMoon(void)
255, sunCoors, size,
999999.88f, TYPE_STAR, FLARE_NONE, REFLECTION_OFF, LOSCHECK_OFF, STREAK_OFF, 0.0f);
- if(CTimeCycle::GetSunDirection().z > 0.0f)
+ if(CTimeCycle::GetSunDirection().z > 0.0f && !CGame::IsInInterior())
RegisterCorona(SUN_CORONA,
CTimeCycle::GetSunCoronaRed(), CTimeCycle::GetSunCoronaGreen(), CTimeCycle::GetSunCoronaBlue(),
255, sunCoors, 25.0f * CTimeCycle::GetSunSize(),
diff --git a/src/render/Coronas.h b/src/render/Coronas.h
index cb4e8583..45f027d8 100644
--- a/src/render/Coronas.h
+++ b/src/render/Coronas.h
@@ -4,19 +4,21 @@ extern RwTexture *gpCoronaTexture[9];
struct CRegisteredCorona
{
+ CVector coors;
uint32 id;
uint32 lastLOScheck;
RwTexture *texture;
+ float size;
+ float someAngle;
+ float drawDist;
+ float nearDist;
+ float heightAboveRoad;
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha; // alpha when fully visible
uint8 fadeAlpha; // actual value used for rendering, faded
- CVector coors;
- float size;
- float someAngle;
bool registeredThisFrame;
- float drawDist;
int8 flareType;
int8 reflection;
@@ -25,12 +27,11 @@ struct CRegisteredCorona
uint8 firstUpdate : 1;
uint8 drawStreak : 1;
uint8 sightClear : 1;
+ uint8 useNearDist : 1;
+ uint8 renderReflection : 1;
- bool renderReflection;
- float heightAboveRoad;
-
- float prevX[6];
- float prevY[6];
+ int16 prevX[6];
+ int16 prevY[6];
uint8 prevRed[6];
uint8 prevGreen[6];
uint8 prevBlue[6];
@@ -39,7 +40,7 @@ struct CRegisteredCorona
void Update(void);
};
-VALIDATE_SIZE(CRegisteredCorona, 0x80);
+VALIDATE_SIZE(CRegisteredCorona, 0x68);
class CCoronas
{
@@ -91,13 +92,14 @@ public:
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
- bool longDist = false, float nearClip = 1.5f);
+ bool useNearDist = false, float nearDist = 1.5f);
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, uint8 type,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
- bool longDist = false, float nearClip = 1.5f);
+ bool useNearDist = false, float nearDist = 1.5f);
static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle);
static void Render(void);
static void RenderReflections(void);
+ static void RenderSunReflection(void);
static void DoSunAndMoon(void);
};
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index 5d8ccf47..77d2af2a 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -7,6 +7,7 @@
#include "Camera.h"
#include "Sprite.h"
#include "Coronas.h"
+#include "PointLights.h"
#include "Rubbish.h"
#include "Timecycle.h"
#include "General.h"
@@ -391,7 +392,7 @@ void CMovingThings::Init()
CPlaneTrails::Init();
CSmokeTrails::Init();
CPlaneBanners::Init();
- CEscalators::Init();
+ CPointLights::Init();
StartCloseList.m_pNext = &CMovingThings::EndCloseList;
StartCloseList.m_pPrev = nil;
@@ -399,6 +400,8 @@ void CMovingThings::Init()
EndCloseList.m_pPrev = &CMovingThings::StartCloseList;
Num = 0;
+ CEscalators::Init();
+
#ifndef MIAMI // something is still used here actually
// Initialize scroll bars
aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f);
@@ -1517,4 +1520,197 @@ CEscalators::Shutdown(void) {
aEscalators[i].SwitchOff();
}
NumEscalators = 0;
+}
+
+
+CScriptPath CScriptPaths::aArray[3];
+
+void CScriptPath::FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ)
+{
+ int32 i;
+ for (i = 0; m_pNode[i + 1].t < t; i++)
+ if (i == m_numNodes - 1) {
+ // don't go beyond last node
+ *pX = m_pNode[m_numNodes - 1].p.x;
+ *pY = m_pNode[m_numNodes - 1].p.y;
+ *pZ = m_pNode[m_numNodes - 1].p.z;
+ return;
+ }
+ float f = (t - m_pNode[i].t) / (m_pNode[i + 1].t - m_pNode[i].t);
+ *pX = (1.0f - f)*m_pNode[i].p.x + f*m_pNode[i + 1].p.x;
+ *pY = (1.0f - f)*m_pNode[i].p.y + f*m_pNode[i + 1].p.y;
+ *pZ = (1.0f - f)*m_pNode[i].p.z + f*m_pNode[i + 1].p.z;
+}
+
+void CScriptPath::Update(void) {
+ if (m_state != SCRIPT_PATH_ACTIVE)
+ return;
+
+ m_fPosition += m_fSpeed * CTimer::GetTimeStepInSeconds();
+ m_fPosition = clamp(m_fPosition, 0.0f, m_fTotalLength);
+
+ if (m_pObjects[0] || m_pObjects[1] || m_pObjects[2] || m_pObjects[3]
+ || m_pObjects[4] || m_pObjects[5]) {
+
+ float t1, t2;
+ CVector pos1, pos2;
+
+ t1 = Max(m_fPosition - m_fObjectLength / 2.0f, 0.0f);
+ FindCoorsFromDistanceOnPath(t1, &pos1.x, &pos1.y, &pos1.z);
+ t2 = Min(m_fPosition + m_fObjectLength / 2.0f, m_fTotalLength);
+ FindCoorsFromDistanceOnPath(t2, &pos2.x, &pos2.y, &pos2.z);
+
+ CVector newForward, newUp(0.0f, 0.0f, 1.0f), newRight;
+
+ newForward = pos2 - pos1;
+ newForward.Normalise();
+ newRight = CrossProduct(newForward, newUp);
+ newRight.Normalise();
+ newUp = CrossProduct(newRight, newForward);
+
+ for (int i = 0; i < 6; i++) {
+ if (m_pObjects[i]) {
+ CMatrix prevMat(m_pObjects[i]->GetMatrix());
+ CVector prevPosition = m_pObjects[i]->GetPosition();
+
+ m_pObjects[i]->SetPosition((pos1 + pos2) / 2.0f);
+ m_pObjects[i]->GetRight() = newRight;
+ m_pObjects[i]->GetUp() = newUp;
+ m_pObjects[i]->GetForward() = newForward;
+ m_pObjects[i]->GetMatrix().UpdateRW();
+ m_pObjects[i]->UpdateRwFrame();
+
+ if (!m_pObjects[i]->bIsBIGBuilding && prevPosition != m_pObjects[i]->GetPosition())
+ m_pObjects[i]->RemoveAndAdd();
+
+ m_pObjects[i]->GetMatrix().UpdateRW();
+ m_pObjects[i]->UpdateRwFrame();
+
+ m_pObjects[i]->m_vecMoveSpeed = (m_pObjects[i]->GetPosition() - prevMat.GetPosition()) / CTimer::GetTimeStep();
+
+ float deltaAngle = m_pObjects[i]->GetForward().Heading() - prevMat.GetForward().Heading();
+ while (deltaAngle < (float)PI) deltaAngle += (float)TWOPI;
+ while (deltaAngle > (float)PI) deltaAngle -= (float)TWOPI;
+ float zTurnSpeed = deltaAngle / CTimer::GetTimeStep();
+
+ m_pObjects[i]->m_vecTurnSpeed = CVector(0.0f, 0.0f, zTurnSpeed);
+ m_pObjects[i]->m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_pObjects[i]->m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+}
+
+void CScriptPath::Clear(void) {
+ if (m_pNode)
+ delete m_pNode;
+ m_pNode = nil;
+ m_numNodes = 0;
+ for (int i = 0; i < 6; i++)
+ m_pObjects[i] = nil;
+ m_state = SCRIPT_PATH_DISABLED;
+}
+
+void CScriptPath::InitialiseOne(int32 numNodes, float width) {
+ char Dest[32];
+ sprintf(Dest, "data\\paths\\spath%d.dat", numNodes);
+ m_pNode = CPlane::LoadPath(Dest, m_numNodes, m_fTotalLength, false);
+ m_fSpeed = 1.0f;
+ m_fPosition = 0.0f;
+ m_fObjectLength = width;
+ m_state = SCRIPT_PATH_INITIALIZED;
+}
+
+void CScriptPath::SetObjectToControl(CObject *pObj) {
+ int32 i = 0;
+ while (i < 6 && m_pObjects[i])
+ i++;
+ m_pObjects[i] = pObj;
+ pObj->RegisterReference((CEntity**)&m_pObjects[i]);
+ pObj->m_phy_flagA08 = false;
+ m_state = SCRIPT_PATH_ACTIVE;
+}
+
+void CScriptPaths::Init(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Clear();
+}
+
+void CScriptPaths::Shutdown(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Clear();
+}
+
+void CScriptPaths::Update(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Update();
+}
+
+bool CScriptPaths::IsOneActive(void) {
+ for (int i = 0; i < 3; i++)
+ if (aArray[i].m_state == SCRIPT_PATH_ACTIVE && aArray[i].m_fSpeed != 0.0f)
+ return true;
+
+ return false;
+}
+
+void CScriptPaths::Load(uint8 *buf, uint32 size) {
+INITSAVEBUF
+ for (int32 i = 0; i < 3; i++)
+ aArray[i].Clear();
+
+ for (int32 i = 0; i < 3; i++) {
+ aArray[i] = ReadSaveBuf<CScriptPath>(buf);
+
+ for (int32 j = 0; j < 6; j++) {
+ CScriptPath *pPath = &aArray[i];
+ if (pPath->m_pObjects[j] != nil) {
+ pPath->m_pObjects[j] = CPools::GetObjectPool()->GetSlot((uintptr)pPath->m_pObjects[j] - 1);
+ pPath->m_pObjects[j]->m_phy_flagA08 = false;
+ }
+ }
+
+ aArray[i].m_pNode = new CPlaneNode[aArray[i].m_numNodes];
+ for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
+ aArray[i].m_pNode[j] = ReadSaveBuf<CPlaneNode>(buf);
+ }
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CScriptPaths::Save(uint8 *buf, uint32 *size) {
+ *size = sizeof(aArray);
+INITSAVEBUF
+ for (int32 i = 0; i < 3; i++) {
+ CScriptPath *pPath = WriteSaveBuf(buf, aArray[i]);
+
+ for (int32 j = 0; j < 6; j++) {
+ if (pPath->m_pObjects[j] != nil)
+ pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pPath->m_pObjects[j]) + 1);
+ }
+
+ for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
+ WriteSaveBuf(buf, aArray[i].m_pNode[j]);
+ *size += sizeof(aArray[i].m_pNode[j]);
+ }
+ }
+VALIDATESAVEBUF(*size);
+}
+
+CObject* g_pScriptPathObjects[18];
+
+void CScriptPaths::Load_ForReplay(void) {
+ for (int i = 0; i < 3; i++) {
+ for (int32 j = 0; j < 6; j++) {
+ aArray[i].m_pObjects[j] = g_pScriptPathObjects[6 * i + j];
+ }
+ }
+}
+
+void CScriptPaths::Save_ForReplay(void) {
+ for (int i = 0; i < 3; i++) {
+ for (int32 j = 0; j < 6; j++) {
+ g_pScriptPathObjects[6 * i + j] = aArray[i].m_pObjects[j];
+ }
+ }
} \ No newline at end of file
diff --git a/src/render/Fluff.h b/src/render/Fluff.h
index a938a4fe..a31ac335 100644
--- a/src/render/Fluff.h
+++ b/src/render/Fluff.h
@@ -2,17 +2,45 @@
#include "common.h"
#include "Vector.h"
#include "Object.h"
+#include "Plane.h"
+
+enum {
+ SCRIPT_PATH_DISABLED = 0,
+ SCRIPT_PATH_INITIALIZED,
+ SCRIPT_PATH_ACTIVE
+};
-// TODO
class CScriptPath
{
public:
+ int32 m_numNodes;
+ CPlaneNode *m_pNode;
+ float m_fTotalLength;
+ float m_fSpeed;
+ float m_fPosition;
+ float m_fObjectLength;
+ int32 m_state;
+ CObject *m_pObjects[6];
+
+ void Clear(void);
+ void Update(void);
+ void InitialiseOne(int32 numNodes, float width);
+ void FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ);
+ void SetObjectToControl(CObject *pObj);
};
-// TODO
class CScriptPaths
{
public:
+ static CScriptPath aArray[3];
+ static void Init(void);
+ static void Shutdown(void);
+ static void Update(void);
+ static bool IsOneActive(void);
+ static void Save(uint8 *buf, uint32 *size);
+ static void Load(uint8 *buf, uint32 size);
+ static void Save_ForReplay();
+ static void Load_ForReplay();
};
class CPlaneTrail
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index 10408355..cbf3c7f2 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -205,7 +205,8 @@ void CHud::Draw()
rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.6f);
rect.bottom = f3rdY + SCREEN_SCALE_Y(32.0f * 0.6f);
- Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
+ Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
else {
rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.4f);
@@ -213,7 +214,8 @@ void CHud::Draw()
rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.4f);
rect.bottom = f3rdY + SCREEN_SCALE_Y(32.0f * 0.4f);
- Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
+ Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
} else {
if (Mode == CCam::MODE_M16_1STPERSON ||
@@ -223,7 +225,8 @@ void CHud::Draw()
rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f);
rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f);
rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(32.0f);
- Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
+ Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
else if (Mode == CCam::MODE_1STPERSON_RUNABOUT) {
rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f * 0.7f);
@@ -231,7 +234,8 @@ void CHud::Draw()
rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f * 0.7f);
rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(32.0f * 0.7f);
- Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
+ Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
else if (Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
@@ -248,29 +252,33 @@ void CHud::Draw()
// TODO(Miami)
// Sniper
- rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f);
- rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f);
- rect.right = SCREEN_WIDTH / 2;
- rect.bottom = SCREEN_HEIGHT / 2;
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
-
- rect.right = (SCREEN_WIDTH / 2);
- rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f);
- rect.left = SCREEN_SCALE_X(210.0f) + (SCREEN_WIDTH / 2);
- rect.bottom = SCREEN_HEIGHT / 2;
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
-
- rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f);
- rect.bottom = (SCREEN_HEIGHT / 2);
- rect.right = (SCREEN_WIDTH / 2);
- rect.top = SCREEN_SCALE_Y(210.0f) + (SCREEN_HEIGHT / 2);
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
-
- rect.right = (SCREEN_WIDTH / 2);
- rect.bottom = (SCREEN_HEIGHT / 2);
- rect.left = SCREEN_SCALE_X(210.0f) + (SCREEN_WIDTH / 2);
- rect.top = SCREEN_SCALE_Y(210.0f) + (SCREEN_HEIGHT / 2);
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
+ rect.left = SCREEN_WIDTH/2 - SCREEN_SCALE_X(210.0f);
+ rect.top = SCREEN_HEIGHT/2 - SCREEN_SCALE_Y(210.0f);
+ rect.right = SCREEN_WIDTH/2;
+ rect.bottom = SCREEN_HEIGHT/2;
+ Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.01f, 0.01f, 1.0f, 0.0f, 0.01f, 1.0f, 1.0f, 1.0f);
+
+ rect.left = SCREEN_WIDTH/2;
+ rect.top = SCREEN_HEIGHT/2 - SCREEN_SCALE_Y(210.0f);
+ rect.right = SCREEN_WIDTH/2 + SCREEN_SCALE_X(210.0f);
+ rect.bottom = SCREEN_HEIGHT/2;
+ Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.99f, 0.0f, 0.01f, 0.01f, 0.99f, 1.0f, 0.01f, 1.0f);
+
+ rect.left = SCREEN_WIDTH/2 - SCREEN_SCALE_X(210.0f);
+ rect.top = SCREEN_HEIGHT/2;
+ rect.right = SCREEN_WIDTH/2;
+ rect.bottom = SCREEN_HEIGHT/2 + SCREEN_SCALE_Y(210.0f);
+ Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.01f, 0.99f, 1.0f, 0.99f, 0.01f, 0.01f, 1.0f, 0.01f);
+
+ rect.left = SCREEN_WIDTH/2;
+ rect.top = SCREEN_HEIGHT/2;
+ rect.right = SCREEN_WIDTH/2 + SCREEN_SCALE_X(210.0f);
+ rect.bottom = SCREEN_HEIGHT/2 + SCREEN_SCALE_Y(210.0f);
+ Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ 0.99f, 0.99f, 0.01f, 0.99f, 0.99f, 0.01f, 0.1f, 0.01f);
}
}
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index 568a0bc1..08298a1f 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -11,6 +11,7 @@
#include "Camera.h"
#include "MBlur.h"
#include "Timer.h"
+#include "postfx.h"
// Originally taken from RW example 'mblur'
@@ -30,6 +31,10 @@ extern "C" D3DCAPS8 _RwD3D8DeviceCaps;
RwBool
CMBlur::MotionBlurOpen(RwCamera *cam)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Open(cam);
+ return TRUE;
+#else
#ifdef GTA_PS2
RwRect rect = {0, 0, 0, 0};
@@ -130,18 +135,22 @@ CMBlur::MotionBlurOpen(RwCamera *cam)
return TRUE;
#endif
+#endif
}
RwBool
CMBlur::MotionBlurClose(void)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Close();
+#else
if(pFrontBuffer){
RwRasterDestroy(pFrontBuffer);
pFrontBuffer = nil;
return TRUE;
}
-
+#endif
return FALSE;
}
@@ -197,8 +206,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[0], zero);
- RwIm2DVertexSetScreenY(&Vertex2[0], zero);
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -206,8 +215,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[1], zero);
- RwIm2DVertexSetScreenY(&Vertex2[1], ymax);
+ RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -215,8 +224,8 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[2], xmax);
- RwIm2DVertexSetScreenY(&Vertex2[2], ymax);
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
@@ -224,20 +233,22 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
- RwIm2DVertexSetScreenX(&Vertex2[3], xmax);
- RwIm2DVertexSetScreenY(&Vertex2[3], zero);
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f);
RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
-
}
void
CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
{
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Render(cam, red, green, blue, blur, type, bluralpha);
+#else
RwRGBA color = { (RwUInt8)red, (RwUInt8)green, (RwUInt8)blue, (RwUInt8)blur };
#ifdef GTA_PS2
if( pFrontBuffer )
@@ -253,8 +264,14 @@ CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, u
RwRasterPopContext();
}
#endif
+#endif
}
+static uint8 DrunkBlurRed = 128;
+static uint8 DrunkBlurGreen = 128;
+static uint8 DrunkBlurBlue = 128;
+static int32 DrunkBlurIncrement = 1;
+
void
CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha)
{
@@ -367,7 +384,36 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
}
}
- // TODO(MIAMI): drunkness
+ int DrunkBlurAlpha = 175.0f * Drunkness;
+ if(DrunkBlurAlpha != 0){
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ if(BlurOn){
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, DrunkBlurAlpha);
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex[0], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ if(DrunkBlurIncrement){
+ if(DrunkBlurRed < 255) DrunkBlurRed++;
+ if(DrunkBlurGreen < 255) DrunkBlurGreen++;
+ if(DrunkBlurBlue < 255) DrunkBlurBlue++;
+ if(DrunkBlurRed == 255)
+ DrunkBlurIncrement = 0;
+ }else{
+ if(DrunkBlurRed > 128) DrunkBlurRed--;
+ if(DrunkBlurGreen > 128) DrunkBlurGreen--;
+ if(DrunkBlurBlue > 128) DrunkBlurBlue--;
+ if(DrunkBlurRed == 128)
+ DrunkBlurIncrement = 1;
+ }
+ }
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ }
// TODO(MIAMI): OverlayRenderFx
diff --git a/src/render/PlayerSkin.cpp b/src/render/PlayerSkin.cpp
index d66f7ce4..b3e82cd9 100644
--- a/src/render/PlayerSkin.cpp
+++ b/src/render/PlayerSkin.cpp
@@ -15,6 +15,8 @@
#include "Timer.h"
#include "Lights.h"
+//--MIAMI: file done
+
RpClump *gpPlayerClump;
float gOldFov;
@@ -109,9 +111,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
tex = RwTextureCreate(raster);
RwTextureSetName(tex, texName);
-#ifdef FIX_BUGS
- RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
-#endif
+ RwTextureSetFilterMode(tex, rwFILTERLINEAR);
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
RwImageDestroy(image);
@@ -143,8 +143,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
static float rotation = 0.0f;
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
const RwV3d pos = { 1.35f, 0.35f, 7.725f };
- const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
- const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
+ const RwV3d axis = { 0.0f, 1.0f, 0.0f };
static uint32 LastFlash = 0;
RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
@@ -157,8 +156,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
}
RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis, rotation, rwCOMBINEPRECONCAT);
RwFrameUpdateObjects(frame);
SetAmbientColours(&AmbientColor);
RpClumpRender(gpPlayerClump);
diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp
index 88b9aaea..b09b07bd 100644
--- a/src/render/PointLights.cpp
+++ b/src/render/PointLights.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
+#include "CutsceneMgr.h"
#include "Lights.h"
#include "Camera.h"
#include "Weather.h"
@@ -10,8 +11,23 @@
#include "Timer.h"
#include "PointLights.h"
+//--MIAMI: file done
+
int16 CPointLights::NumLights;
CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
+CVector CPointLights::aCachedMapReads[32];
+float CPointLights::aCachedMapReadResults[32];
+int32 CPointLights::NextCachedValue;
+
+void
+CPointLights::Init(void)
+{
+ for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++){
+ aCachedMapReads[i] = CVector(0.0f, 0.0f, 0.0f);
+ aCachedMapReadResults[i] = 0.0f;
+ }
+ NextCachedValue = 0;
+}
void
CPointLights::InitPerFrame(void)
@@ -86,12 +102,11 @@ CPointLights::GenerateLightsAffectingObject(Const CVector *objCoors)
ret *= distNorm;
}else{
float intensity;
+ // distance fade
if(distNorm < 0.5f)
- // near enough
intensity = 1.0f;
else
- // attenuate
- intensity = 1.0f - (distNorm - 0.5f)*2.0f;
+ intensity = 1.0f - (distNorm - 0.5f)/(1.0f - 0.5f);
if(distance != 0.0f){
CVector dir = dist / distance;
@@ -143,17 +158,22 @@ CPointLights::RenderFogEffect(void)
CVector spriteCoors;
float spritew, spriteh;
+ if(CCutsceneMgr::IsRunning())
+ return;
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster);
+ CSprite::InitSpriteBuffer();
+
for(i = 0; i < NumLights; i++){
if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS)
continue;
- fogginess = aLights[i].fogType == FOG_ALWAYS ? 1.0f : CWeather::Foggyness;
+ fogginess = aLights[i].fogType == FOG_NORMAL ? CWeather::Foggyness : 1.0f;
if(fogginess == 0.0f)
continue;
@@ -198,7 +218,7 @@ CPointLights::RenderFogEffect(void)
float distsq = sq(dx) + sq(dy);
float linedistsq = distsq - sq(dot);
if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){
- CVector fogcoors(xi, yi, aLights[i].coors.z + 1.0f);
+ CVector fogcoors(xi, yi, aLights[i].coors.z + 10.0f);
if(CWorld::ProcessVerticalLine(fogcoors, fogcoors.z - 20.0f,
point, entity, true, false, false, false, true, false, nil)){
// Now same check again in xyz
@@ -220,9 +240,9 @@ CPointLights::RenderFogEffect(void)
intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
- float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x1FFF;
+ float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000;
float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@@ -234,9 +254,8 @@ CPointLights::RenderFogEffect(void)
}
}else if(aLights[i].type == LIGHT_POINT || aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS){
- if(CWorld::ProcessVerticalLine(aLights[i].coors, aLights[i].coors.z - 20.0f,
- point, entity, true, false, false, false, true, false, nil)){
-
+ float groundZ;
+ if(ProcessVerticalLineUsingCache(aLights[i].coors, &groundZ)){
xmin = aLights[i].coors.x - FOG_AREA_RADIUS;
ymin = aLights[i].coors.y - FOG_AREA_RADIUS;
xmax = aLights[i].coors.x + FOG_AREA_RADIUS;
@@ -267,11 +286,11 @@ CPointLights::RenderFogEffect(void)
// more intensity the closer to light source
intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
- CVector fogcoors(xi, yi, point.point.z + 1.6f);
+ CVector fogcoors(xi, yi, groundZ + 1.6f);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
- float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x3FFF;
+ float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@@ -283,4 +302,27 @@ CPointLights::RenderFogEffect(void)
}
}
}
+
+ CSprite::FlushSpriteBuffer();
+}
+
+bool
+CPointLights::ProcessVerticalLineUsingCache(CVector coors, float *groundZ)
+{
+ for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++)
+ if(aCachedMapReads[i] == coors){
+ *groundZ = aCachedMapReadResults[i];
+ return true;
+ }
+
+ CColPoint point;
+ CEntity *entity;
+ if(CWorld::ProcessVerticalLine(coors, coors.z - 20.0f, point, entity, true, false, false, false, true, false, nil)){
+ aCachedMapReads[NextCachedValue] = coors;
+ aCachedMapReadResults[NextCachedValue] = point.point.z;
+ NextCachedValue = (NextCachedValue+1) % ARRAY_SIZE(aCachedMapReads);
+ *groundZ = point.point.z;
+ return true;
+ }
+ return false;
}
diff --git a/src/render/PointLights.h b/src/render/PointLights.h
index 9e94328f..827200b9 100644
--- a/src/render/PointLights.h
+++ b/src/render/PointLights.h
@@ -20,6 +20,9 @@ class CPointLights
public:
static int16 NumLights;
static CRegisteredPointLight aLights[NUMPOINTLIGHTS];
+ static CVector aCachedMapReads[32];
+ static float aCachedMapReadResults[32];
+ static int32 NextCachedValue;
enum {
LIGHT_POINT,
@@ -37,9 +40,11 @@ public:
FOG_ALWAYS
};
+ static void Init(void);
static void InitPerFrame(void);
static void AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows);
static float GenerateLightsAffectingObject(Const CVector *objCoors);
static void RemoveLightsAffectingObject(void);
static void RenderFogEffect(void);
+ static bool ProcessVerticalLineUsingCache(CVector coors, float *groundZ);
};
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 03ef1064..3b996b55 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -21,6 +21,7 @@
#include "PointLights.h"
#include "Occlusion.h"
#include "Renderer.h"
+#include "custompipes.h"
//--MIAMI: file done
@@ -243,6 +244,11 @@ CRenderer::RenderEverythingBarRoads(void)
if(IsRoad(e))
continue;
+#ifdef EXTENDED_PIPELINES
+ if(CustomPipes::bRenderingEnvMap && (e->IsPed() || e->IsVehicle()))
+ continue;
+#endif
+
if(e->IsVehicle() ||
e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){
if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){
@@ -883,6 +889,12 @@ CalcNewDelta(RwV2d *a, RwV2d *b)
return (b->x - a->x) / (b->y - a->y);
}
+#ifdef FIX_BUGS
+#define TOINT(x) ((int)Floor(x))
+#else
+#define TOINT(x) ((int)(x))
+#endif
+
void
CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrList *))
{
@@ -908,8 +920,8 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
a2 = i;
}
}
- y = miny;
- yend = maxy;
+ y = TOINT(miny);
+ yend = TOINT(maxy);
// Go left in poly to find first edge b
b2 = a2;
@@ -917,8 +929,8 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
b1 = b2--;
if(b2 < 0) b2 = numVertices-1;
if(poly[b1].x < xstart)
- xstart = poly[b1].x;
- if((int)poly[b1].y != (int)poly[b2].y)
+ xstart = TOINT(poly[b1].x);
+ if(TOINT(poly[b1].y) != TOINT(poly[b2].y))
break;
}
// Go right to find first edge a
@@ -926,8 +938,8 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
a1 = a2++;
if(a2 == numVertices) a2 = 0;
if(poly[a1].x > xend)
- xend = poly[a1].x;
- if((int)poly[a1].y != (int)poly[a2].y)
+ xend = TOINT(poly[a1].x);
+ if(TOINT(poly[a1].y) != TOINT(poly[a2].y))
break;
}
@@ -938,17 +950,17 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
xB = deltaB * (Ceil(poly[b1].y) - poly[b1].y) + poly[b1].x;
if(y != yend){
- if(deltaB < 0.0f && (int)xB < xstart)
- xstart = xB;
- if(deltaA >= 0.0f && (int)xA > xend)
- xend = xA;
+ if(deltaB < 0.0f && TOINT(xB) < xstart)
+ xstart = TOINT(xB);
+ if(deltaA >= 0.0f && TOINT(xA) > xend)
+ xend = TOINT(xA);
}
while(y <= yend && y < NUMSECTORS_Y){
// scan one x-line
if(y >= 0 && xstart < NUMSECTORS_X)
- for(x = xstart; x <= xend; x++)
- if(x >= 0 && x != NUMSECTORS_X)
+ for(x = xstart; x <= xend && x != NUMSECTORS_X; x++)
+ if(x >= 0)
scanfunc(CWorld::GetSector(x, y)->m_lists);
// advance one scan line
@@ -957,74 +969,74 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
xB += deltaB;
// update left side
- if(y == (int)poly[b2].y){
+ if(y == TOINT(poly[b2].y)){
// reached end of edge
if(y == yend){
if(deltaB < 0.0f){
do{
- xstart = poly[b2--].x;
+ xstart = TOINT(poly[b2--].x);
if(b2 < 0) b2 = numVertices-1;
- }while(xstart > (int)poly[b2].x);
+ }while(xstart > TOINT(poly[b2].x));
}else
- xstart = xB - deltaB;
+ xstart = TOINT(xB - deltaB);
}else{
// switch edges
if(deltaB < 0.0f)
- xstart = poly[b2].x;
+ xstart = TOINT(poly[b2].x);
else
- xstart = xB - deltaB;
+ xstart = TOINT(xB - deltaB);
do{
b1 = b2--;
if(b2 < 0) b2 = numVertices-1;
- if((int)poly[b1].x < xstart)
- xstart = poly[b1].x;
- }while(y == (int)poly[b2].y);
+ if(TOINT(poly[b1].x) < xstart)
+ xstart = TOINT(poly[b1].x);
+ }while(y == TOINT(poly[b2].y));
deltaB = CalcNewDelta(&poly[b1], &poly[b2]);
xB = deltaB * (Ceil(poly[b1].y) - poly[b1].y) + poly[b1].x;
- if(deltaB < 0.0f && (int)xB < xstart)
- xstart = xB;
+ if(deltaB < 0.0f && TOINT(xB) < xstart)
+ xstart = TOINT(xB);
}
}else{
if(deltaB < 0.0f)
- xstart = xB;
+ xstart = TOINT(xB);
else
- xstart = xB - deltaB;
+ xstart = TOINT(xB - deltaB);
}
// update right side
- if(y == (int)poly[a2].y){
+ if(y == TOINT(poly[a2].y)){
// reached end of edge
if(y == yend){
if(deltaA < 0.0f)
- xend = xA - deltaA;
+ xend = TOINT(xA - deltaA);
else{
do{
- xend = poly[a2++].x;
+ xend = TOINT(poly[a2++].x);
if(a2 == numVertices) a2 = 0;
- }while(xend < (int)poly[a2].x);
+ }while(xend < TOINT(poly[a2].x));
}
}else{
// switch edges
if(deltaA < 0.0f)
- xend = xA - deltaA;
+ xend = TOINT(xA - deltaA);
else
- xend = poly[a2].x;
+ xend = TOINT(poly[a2].x);
do{
a1 = a2++;
if(a2 == numVertices) a2 = 0;
- if((int)poly[a1].x > xend)
- xend = poly[a1].x;
- }while(y == (int)poly[a2].y);
+ if(TOINT(poly[a1].x) > xend)
+ xend = TOINT(poly[a1].x);
+ }while(y == TOINT(poly[a2].y));
deltaA = CalcNewDelta(&poly[a1], &poly[a2]);
xA = deltaA * (Ceil(poly[a1].y) - poly[a1].y) + poly[a1].x;
- if(deltaA >= 0.0f && (int)xA > xend)
- xend = xA;
+ if(deltaA >= 0.0f && TOINT(xA) > xend)
+ xend = TOINT(xA);
}
}else{
if(deltaA < 0.0f)
- xend = xA - deltaA;
+ xend = TOINT(xA - deltaA);
else
- xend = xA;
+ xend = TOINT(xA);
}
}
}
diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp
index bfd50c07..dada2439 100644
--- a/src/render/Rubbish.cpp
+++ b/src/render/Rubbish.cpp
@@ -8,17 +8,18 @@
#include "World.h"
#include "Vehicle.h"
#include "ZoneCull.h"
+#include "Stats.h"
#include "TxdStore.h"
#include "RenderBuffer.h"
#include "Rubbish.h"
-#define RUBBISH_MAX_DIST (18.0f)
-#define RUBBISH_FADE_DIST (16.5f)
+//--MIAMI: file done
+
+#define RUBBISH_MAX_DIST (23.0f)
+#define RUBBISH_FADE_DIST (20.0f)
RwTexture *gpRubbishTexture[4];
RwImVertexIndex RubbishIndexList[6];
-RwImVertexIndex RubbishIndexList2[6]; // unused
-RwIm3DVertex RubbishVertices[4];
bool CRubbish::bRubbishInvisible;
int CRubbish::RubbishVisibility;
COneSheet CRubbish::aSheets[NUM_RUBBISH_SHEETS];
@@ -52,12 +53,16 @@ CRubbish::Render(void)
{
int type;
+ if(RubbishVisibility == 0)
+ return;
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
for(type = 0; type < 4; type++){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
+ if(type < 3 || CStats::PamphletMissionPassed)
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
@@ -69,7 +74,7 @@ CRubbish::Render(void)
if(sheet->m_state == 0)
continue;
- uint32 alpha = 128;
+ uint32 alpha = 100;
CVector pos;
if(sheet->m_state == 1){
pos = sheet->m_basePos;
@@ -82,7 +87,7 @@ CRubbish::Render(void)
float t = (float)(CTimer::GetTimeInMilliseconds() - sheet->m_moveStart)/sheet->m_moveDuration;
float f1 = sheet->m_isVisible ? 1.0f-t : 0.0f;
float f2 = sheet->m_targetIsVisible ? t : 0.0f;
- alpha = 128 * (f1+f2);
+ alpha = 100 * (f1+f2);
}
}
@@ -92,17 +97,27 @@ CRubbish::Render(void)
alpha -= alpha*(camDist-RUBBISH_FADE_DIST)/(RUBBISH_MAX_DIST-RUBBISH_FADE_DIST);
alpha = (RubbishVisibility*alpha)/256;
- float vx = Sin(sheet->m_angle) * 0.4f;
- float vy = Cos(sheet->m_angle) * 0.4f;
+ float vx1, vy1, vx2, vy2;
+ if(type == 0 || type == 1){
+ vx1 = 0.9f*Sin(sheet->m_angle);
+ vy1 = 0.9f*Cos(sheet->m_angle);
+ vx2 = 0.3f*Cos(sheet->m_angle);
+ vy2 = -0.3f*Sin(sheet->m_angle);
+ }else{
+ vx1 = 0.3f*Sin(sheet->m_angle);
+ vy1 = 0.3f*Cos(sheet->m_angle);
+ vx2 = 0.3f*Cos(sheet->m_angle);
+ vy2 = -0.3f*Sin(sheet->m_angle);
+ }
int v = TempBufferVerticesStored;
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx, pos.y + vy, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx1 + vx2, pos.y + vy1 + vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x + vx1 - vx2, pos.y + vy1 - vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x - vx1 + vx2, pos.y - vy1 + vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx1 - vx2, pos.y - vy1 - vy2, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x - vy, pos.y + vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x + vy, pos.y - vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx, pos.y - vy, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], 255, 255, 255, alpha);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], 0.0f);
@@ -373,24 +388,6 @@ CRubbish::Init(void)
EndMoversList.m_next = nil;
EndMoversList.m_prev = &StartMoversList;
- // unused
- RwIm3DVertexSetU(&RubbishVertices[0], 0.0f);
- RwIm3DVertexSetV(&RubbishVertices[0], 0.0f);
- RwIm3DVertexSetU(&RubbishVertices[1], 1.0f);
- RwIm3DVertexSetV(&RubbishVertices[1], 0.0f);
- RwIm3DVertexSetU(&RubbishVertices[2], 0.0f);
- RwIm3DVertexSetV(&RubbishVertices[2], 1.0f);
- RwIm3DVertexSetU(&RubbishVertices[3], 1.0f);
- RwIm3DVertexSetV(&RubbishVertices[3], 1.0f);
-
- // unused
- RubbishIndexList2[0] = 0;
- RubbishIndexList2[1] = 2;
- RubbishIndexList2[2] = 1;
- RubbishIndexList2[3] = 1;
- RubbishIndexList2[4] = 2;
- RubbishIndexList2[5] = 3;
-
RubbishIndexList[0] = 0;
RubbishIndexList[1] = 1;
RubbishIndexList[2] = 2;
@@ -414,19 +411,11 @@ void
CRubbish::Shutdown(void)
{
RwTextureDestroy(gpRubbishTexture[0]);
-#ifdef GTA3_1_1_PATCH
gpRubbishTexture[0] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[1]);
-#ifdef GTA3_1_1_PATCH
gpRubbishTexture[1] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[2]);
-#ifdef GTA3_1_1_PATCH
gpRubbishTexture[2] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[3]);
-#ifdef GTA3_1_1_PATCH
gpRubbishTexture[3] = nil;
-#endif
}
diff --git a/src/render/ShadowCamera.cpp b/src/render/ShadowCamera.cpp
index ae94f8ac..f69c234f 100644
--- a/src/render/ShadowCamera.cpp
+++ b/src/render/ShadowCamera.cpp
@@ -160,7 +160,7 @@ CShadowCamera::SetCenter(RwV3d *center)
ASSERT(m_pCamera != nil);
RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
- RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
+ RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
*RwMatrixGetPos(camMatrix) = *center;
@@ -188,7 +188,7 @@ CShadowCamera::Update(RpClump *clump)
if ( RwCameraBeginUpdate(m_pCamera) )
{
- geometry = GetFirstAtomic(clump)->geometry;
+ geometry = RpAtomicGetGeometry(GetFirstAtomic(clump));
ASSERT(geometry != nil);
flags = RpGeometryGetFlags(geometry);
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index 5bb6a734..a964ceb6 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -715,7 +715,7 @@ CShadows::StoreShadowForVehicle(CVehicle *pCar, VEH_SHD_TYPE type)
}
void
-CShadows::StoreCarLightShadow(CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn,
+CShadows::StoreCarLightShadow(CVehicle *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fMaxViewAngle)
{
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 94b2981f..937ff4eb 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -159,7 +159,7 @@ public:
static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings);
static void StoreShadowForVehicle (CVehicle *pCar, VEH_SHD_TYPE type);
- static void StoreCarLightShadow (CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
+ static void StoreCarLightShadow (CVehicle *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp
index efd88387..f2a66db1 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/render/Skidmarks.cpp
@@ -6,6 +6,8 @@
#include "Replay.h"
#include "Skidmarks.h"
+//--MIAMI: file done
+
CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
@@ -37,13 +39,6 @@ CSkidmarks::Init(void)
SkidmarkIndexList[i*6+5] = ix+3;
ix += 2;
}
-
- for(i = 0; i < SKIDMARK_LENGTH; i++){
- RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
- RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
- RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
- RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
- }
}
void
@@ -141,8 +136,12 @@ CSkidmarks::Render(void)
p2.y -= aSkidmarks[i].m_sideY[j];
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
+ RwIm3DVertexSetU(&SkidmarkVertices[j*2+0], 0.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[j*2+0], j*5.01f);
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
+ RwIm3DVertexSetU(&SkidmarkVertices[j*2+1], 1.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[j*2+1], j*5.01f);
}
LittleTest();
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 3bc99a4d..fa8379f0 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -21,6 +21,9 @@
#include "Camera.h"
#include "Shadows.h"
#include "main.h"
+#include "ColStore.h"
+#include "Coronas.h"
+#include "Script.h"
RwIm3DVertex StreakVertices[4];
RwImVertexIndex StreakIndexList[12];
@@ -371,6 +374,8 @@ MarkerAtomicCB(RpAtomic *atomic, void *data)
return atomic;
}
+// --MIAMI: C3dMarker and C3dMarkers done
+
bool
C3dMarker::AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
@@ -415,6 +420,7 @@ C3dMarker::DeleteMarkerObject()
m_nIdentifier = 0;
m_nStartTime = 0;
m_bIsUsed = false;
+ m_bFindZOnNextPlacement = false;
m_nType = MARKERTYPE_INVALID;
frame = RpAtomicGetFrame(m_pAtomic);
@@ -458,6 +464,7 @@ C3dMarkers::Init()
m_aMarkerArray[i].m_pAtomic = nil;
m_aMarkerArray[i].m_nType = MARKERTYPE_INVALID;
m_aMarkerArray[i].m_bIsUsed = false;
+ m_aMarkerArray[i].m_bFindZOnNextPlacement = false;
m_aMarkerArray[i].m_nIdentifier = 0;
m_aMarkerArray[i].m_Color.red = 255;
m_aMarkerArray[i].m_Color.green = 255;
@@ -503,8 +510,15 @@ C3dMarkers::Render()
ActivateDirectional();
for (int i = 0; i < NUM3DMARKERS; i++) {
if (m_aMarkerArray[i].m_bIsUsed) {
- if (m_aMarkerArray[i].m_fCameraRange < 120.0f)
+ if (m_aMarkerArray[i].m_fCameraRange < 150.0f) {
m_aMarkerArray[i].Render();
+ if (m_aMarkerArray[i].m_nType == MARKERTYPE_ARROW) {
+ CCoronas::RegisterCorona((uintptr)&m_aMarkerArray[i],
+ SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, 192,
+ m_aMarkerArray[i].m_Matrix.GetPosition(), 1.2f * m_aMarkerArray[i].m_fSize, 50.0f * TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f, false);
+ }
+ }
NumActiveMarkers++;
m_aMarkerArray[i].m_bIsUsed = false;
} else if (m_aMarkerArray[i].m_pAtomic != nil) {
@@ -517,9 +531,9 @@ C3dMarker *
C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
C3dMarker *pMarker;
-
+ CVector2D playerPos = FindPlayerCentreOfWorld(0);
pMarker = nil;
- float dist = Sqrt((pos.x - FindPlayerCentreOfWorld(0).x) * (pos.x - FindPlayerCentreOfWorld(0).x) + (pos.y - FindPlayerCentreOfWorld(0).y) * (pos.y - FindPlayerCentreOfWorld(0).y));
+ float dist = ((CVector2D)pos - playerPos).Magnitude();
if (type != MARKERTYPE_ARROW && type != MARKERTYPE_CYLINDER) return nil;
@@ -592,6 +606,15 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
}
if (type == MARKERTYPE_ARROW)
pMarker->m_Matrix.GetPosition() = pos;
+
+ if (pMarker->m_bFindZOnNextPlacement) {
+ if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) {
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
+ if (z != 0.0f)
+ pMarker->m_Matrix.GetPosition().z = z - 0.05f * size;
+ pMarker->m_bFindZOnNextPlacement = false;
+ }
+ }
pMarker->m_bIsUsed = true;
return pMarker;
}
@@ -601,9 +624,14 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate);
if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) {
- float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
- if (z != 0.0f)
- pos.z = z - 0.05f * size;
+ if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) {
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
+ if (z != 0.0f)
+ pos.z = z - 0.05f * size;
+ pMarker->m_bFindZOnNextPlacement = false;
+ } else {
+ pMarker->m_bFindZOnNextPlacement = true;
+ }
}
pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z);
if (type == MARKERTYPE_2) {
diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h
index 55ad6cb9..8bd0d5e1 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/SpecialFX.h
@@ -87,6 +87,7 @@ public:
RpMaterial *m_pMaterial;
uint16 m_nType;
bool m_bIsUsed;
+ bool m_bFindZOnNextPlacement;
uint32 m_nIdentifier;
RwRGBA m_Color;
uint16 m_nPulsePeriod;
diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp
index f26f8e63..401eebd0 100644
--- a/src/render/Sprite.cpp
+++ b/src/render/Sprite.cpp
@@ -148,10 +148,10 @@ CSprite::RenderOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, fl
// Fade out when too near
// why not in buffered version?
- if(z < 3.0f){
- if(z < 1.5f)
+ if(z < 2.3f){
+ if(z < 1.3f)
return;
- int f = (z - 1.5f)/1.5f * 255;
+ int f = (z - 1.3f)/(2.3f-1.3f) * 255;
r = f*r >> 8;
g = f*g >> 8;
b = f*b >> 8;
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index cba64e7a..0cd0e8bb 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -9,6 +9,7 @@
float CSprite2d::RecipNearClip;
float CSprite2d::NearScreenZ;
+float CSprite2d::NearCamZ;
int CSprite2d::nextBufferVertex;
int CSprite2d::nextBufferIndex;
RwIm2DVertex CSprite2d::maVertices[8];
@@ -26,6 +27,9 @@ CSprite2d::InitPerFrame(void)
nextBufferIndex = 0;
RecipNearClip = 1.0f / RwCameraGetNearClipPlane(Scene.camera);
NearScreenZ = RwIm2DGetNearScreenZ();
+ // not original but you're supposed to set camera z too
+ // wrapping all this in FIX_BUGS is too ugly
+ NearCamZ = RwCameraGetNearClipPlane(Scene.camera);
}
void
CSprite2d::Delete(void)
@@ -71,7 +75,7 @@ CSprite2d::SetRenderState(void)
void
CSprite2d::Draw(float x, float y, float w, float h, const CRGBA &col)
{
- SetVertices(CRect(x, y, x + w, y + h), col, col, col, col, 0);
+ SetVertices(CRect(x, y, x + w, y + h), col, col, col, col);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -79,7 +83,7 @@ CSprite2d::Draw(float x, float y, float w, float h, const CRGBA &col)
void
CSprite2d::Draw(const CRect &rect, const CRGBA &col)
{
- SetVertices(rect, col, col, col, col, 0);
+ SetVertices(rect, col, col, col, col);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -96,7 +100,7 @@ CSprite2d::Draw(const CRect &rect, const CRGBA &col,
void
CSprite2d::Draw(const CRect &rect, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(rect, c0, c1, c2, c3, 0);
+ SetVertices(rect, c0, c1, c2, c3);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -114,18 +118,9 @@ CSprite2d::Draw(float x1, float y1, float x2, float y2, float x3, float y3, floa
// | |
// 0---1
void
-CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, uint32 far)
+CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- float screenz, z, recipz;
-
- if(far){
- screenz = RwIm2DGetFarScreenZ();
- z = RwCameraGetFarClipPlane(Scene.camera);
- }else{
- screenz = NearScreenZ;
- z = 1.0f/RecipNearClip;
- }
- recipz = 1.0f/z;
+ float offset = 1.0f/1024.0f;
// This is what we draw:
// 0---1
@@ -133,159 +128,141 @@ CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
// 3---2
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
RwIm2DVertexSetScreenY(&maVertices[0], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[0], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[0], 0.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], 0.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
RwIm2DVertexSetScreenY(&maVertices[1], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[1], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[1], 1.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], 0.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
RwIm2DVertexSetScreenY(&maVertices[2], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[2], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[2], 1.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], 1.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
RwIm2DVertexSetScreenY(&maVertices[3], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[3], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[3], 0.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], 1.0f+offset, RecipNearClip);
}
void
CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
- float screenz, z, recipz;
-
- screenz = NearScreenZ;
- z = 1.0f/RecipNearClip;
- recipz = 1.0f/z;
-
// This is what we draw:
// 0---1
// | / |
// 3---2
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
RwIm2DVertexSetScreenY(&maVertices[0], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], u0, recipz);
- RwIm2DVertexSetV(&maVertices[0], v0, recipz);
+ RwIm2DVertexSetU(&maVertices[0], u0, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], v0, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
RwIm2DVertexSetScreenY(&maVertices[1], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], u1, recipz);
- RwIm2DVertexSetV(&maVertices[1], v1, recipz);
+ RwIm2DVertexSetU(&maVertices[1], u1, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], v1, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
RwIm2DVertexSetScreenY(&maVertices[2], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], u2, recipz);
- RwIm2DVertexSetV(&maVertices[2], v2, recipz);
+ RwIm2DVertexSetU(&maVertices[2], u2, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], v2, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
RwIm2DVertexSetScreenY(&maVertices[3], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], u3, recipz);
- RwIm2DVertexSetV(&maVertices[3], v3, recipz);
+ RwIm2DVertexSetU(&maVertices[3], u3, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], v3, RecipNearClip);
}
void
CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- float screenz, recipz;
- float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
- screenz = NearScreenZ;
- recipz = RecipNearClip;
-
RwIm2DVertexSetScreenX(&maVertices[0], x3);
RwIm2DVertexSetScreenY(&maVertices[0], y3);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[0], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[0], 0.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], 0.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], x4);
RwIm2DVertexSetScreenY(&maVertices[1], y4);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[1], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[1], 1.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], 0.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], x2);
RwIm2DVertexSetScreenY(&maVertices[2], y2);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[2], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[2], 1.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], 1.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], x1);
RwIm2DVertexSetScreenY(&maVertices[3], y1);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[3], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[3], 0.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], 1.0f, RecipNearClip);
}
void
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
{
int i;
- float screenz, recipz, z;
-
- screenz = NearScreenZ;
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
RwIm2DVertexSetScreenY(&maVertices[i], positions[i*2 + 1]);
- RwIm2DVertexSetScreenZ(&maVertices[i], screenz + 0.0001f);
- RwIm2DVertexSetCameraZ(&maVertices[i], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[i], NearScreenZ + 0.0001f);
+ RwIm2DVertexSetCameraZ(&maVertices[i], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[i], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[i], col.r, col.g, col.b, col.a);
- RwIm2DVertexSetU(&maVertices[i], uvs[i*2 + 0], recipz);
- RwIm2DVertexSetV(&maVertices[i], uvs[i*2 + 1], recipz);
+ RwIm2DVertexSetU(&maVertices[i], uvs[i*2 + 0], RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[i], uvs[i*2 + 1], RecipNearClip);
}
}
@@ -293,18 +270,13 @@ void
CSprite2d::SetMaskVertices(int n, float *positions)
{
int i;
- float screenz, recipz, z;
-
- screenz = NearScreenZ;
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
RwIm2DVertexSetScreenY(&maVertices[i], positions[i*2 + 1]);
- RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[i], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[i], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[i], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[i], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
}
}
@@ -313,53 +285,47 @@ void
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
- float screenz, recipz, z;
-
- screenz = NearScreenZ;
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
RwIm2DVertexSetScreenX(&verts[0], r.left);
RwIm2DVertexSetScreenY(&verts[0], r.top);
- RwIm2DVertexSetScreenZ(&verts[0], screenz);
- RwIm2DVertexSetCameraZ(&verts[0], z);
- RwIm2DVertexSetRecipCameraZ(&verts[0], recipz);
+ RwIm2DVertexSetScreenZ(&verts[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&verts[0], u0, recipz);
- RwIm2DVertexSetV(&verts[0], v0, recipz);
+ RwIm2DVertexSetU(&verts[0], u0, RecipNearClip);
+ RwIm2DVertexSetV(&verts[0], v0, RecipNearClip);
RwIm2DVertexSetScreenX(&verts[1], r.right);
RwIm2DVertexSetScreenY(&verts[1], r.top);
- RwIm2DVertexSetScreenZ(&verts[1], screenz);
- RwIm2DVertexSetCameraZ(&verts[1], z);
- RwIm2DVertexSetRecipCameraZ(&verts[1], recipz);
+ RwIm2DVertexSetScreenZ(&verts[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&verts[1], u1, recipz);
- RwIm2DVertexSetV(&verts[1], v1, recipz);
+ RwIm2DVertexSetU(&verts[1], u1, RecipNearClip);
+ RwIm2DVertexSetV(&verts[1], v1, RecipNearClip);
RwIm2DVertexSetScreenX(&verts[2], r.right);
RwIm2DVertexSetScreenY(&verts[2], r.bottom);
- RwIm2DVertexSetScreenZ(&verts[2], screenz);
- RwIm2DVertexSetCameraZ(&verts[2], z);
- RwIm2DVertexSetRecipCameraZ(&verts[2], recipz);
+ RwIm2DVertexSetScreenZ(&verts[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&verts[2], u2, recipz);
- RwIm2DVertexSetV(&verts[2], v2, recipz);
+ RwIm2DVertexSetU(&verts[2], u2, RecipNearClip);
+ RwIm2DVertexSetV(&verts[2], v2, RecipNearClip);
RwIm2DVertexSetScreenX(&verts[3], r.left);
RwIm2DVertexSetScreenY(&verts[3], r.bottom);
- RwIm2DVertexSetScreenZ(&verts[3], screenz);
- RwIm2DVertexSetCameraZ(&verts[3], z);
- RwIm2DVertexSetRecipCameraZ(&verts[3], recipz);
+ RwIm2DVertexSetScreenZ(&verts[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&verts[3], u3, recipz);
- RwIm2DVertexSetV(&verts[3], v3, recipz);
+ RwIm2DVertexSetU(&verts[3], u3, RecipNearClip);
+ RwIm2DVertexSetV(&verts[3], v3, RecipNearClip);
}
void
CSprite2d::DrawRect(const CRect &r, const CRGBA &col)
{
- SetVertices(r, col, col, col, col, false);
+ SetVertices(r, col, col, col, col);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
@@ -374,7 +340,7 @@ CSprite2d::DrawRect(const CRect &r, const CRGBA &col)
void
CSprite2d::DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(r, c0, c1, c2, c3, false);
+ SetVertices(r, c0, c1, c2, c3);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -387,7 +353,7 @@ CSprite2d::DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGB
void
CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(r, c0, c1, c2, c3, false);
+ SetVertices(r, c0, c1, c2, c3);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
diff --git a/src/render/Sprite2d.h b/src/render/Sprite2d.h
index 1adb5d49..5abd8d71 100644
--- a/src/render/Sprite2d.h
+++ b/src/render/Sprite2d.h
@@ -4,6 +4,7 @@ class CSprite2d
{
static float RecipNearClip;
static float NearScreenZ;
+ static float NearCamZ; // not original
static int nextBufferVertex;
static int nextBufferIndex;
static RwIm2DVertex maVertices[8];
@@ -27,7 +28,7 @@ public:
void Draw(const CRect &rect, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
void Draw(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &col);
- static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, uint32 far);
+ static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2);
static void SetVertices(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp
index fe898412..b20a2443 100644
--- a/src/render/Timecycle.cpp
+++ b/src/render/Timecycle.cpp
@@ -10,60 +10,60 @@
#include "FileMgr.h"
#include "Timecycle.h"
-// TODO(MIAMI): change some of the types here
-
-int CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
-int CTimeCycle::m_nAmbientBlue_Obj_Bl[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_nPoleShadowStrength[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_fWaterRed[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
+//--MIAMI: done
+
+uint8 CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
+int16 CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
+int16 CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fCurrentAmbientRed;
@@ -81,36 +81,36 @@ float CTimeCycle::m_fCurrentAmbientBlue_Obj_Bl;
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;
+int32 CTimeCycle::m_nCurrentSkyTopRed;
+int32 CTimeCycle::m_nCurrentSkyTopGreen;
+int32 CTimeCycle::m_nCurrentSkyTopBlue;
+int32 CTimeCycle::m_nCurrentSkyBottomRed;
+int32 CTimeCycle::m_nCurrentSkyBottomGreen;
+int32 CTimeCycle::m_nCurrentSkyBottomBlue;
+int32 CTimeCycle::m_nCurrentSunCoreRed;
+int32 CTimeCycle::m_nCurrentSunCoreGreen;
+int32 CTimeCycle::m_nCurrentSunCoreBlue;
+int32 CTimeCycle::m_nCurrentSunCoronaRed;
+int32 CTimeCycle::m_nCurrentSunCoronaGreen;
+int32 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_nCurrentPoleShadowStrength;
+int32 CTimeCycle::m_nCurrentShadowStrength;
+int32 CTimeCycle::m_nCurrentLightShadowStrength;
+int32 CTimeCycle::m_nCurrentPoleShadowStrength;
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;
+int32 CTimeCycle::m_nCurrentLowCloudsRed;
+int32 CTimeCycle::m_nCurrentLowCloudsGreen;
+int32 CTimeCycle::m_nCurrentLowCloudsBlue;
+int32 CTimeCycle::m_nCurrentFluffyCloudsTopRed;
+int32 CTimeCycle::m_nCurrentFluffyCloudsTopGreen;
+int32 CTimeCycle::m_nCurrentFluffyCloudsTopBlue;
+int32 CTimeCycle::m_nCurrentFluffyCloudsBottomRed;
+int32 CTimeCycle::m_nCurrentFluffyCloudsBottomGreen;
+int32 CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
float CTimeCycle::m_fCurrentBlurRed;
float CTimeCycle::m_fCurrentBlurGreen;
float CTimeCycle::m_fCurrentBlurBlue;
@@ -118,13 +118,16 @@ float CTimeCycle::m_fCurrentWaterRed;
float CTimeCycle::m_fCurrentWaterGreen;
float CTimeCycle::m_fCurrentWaterBlue;
float CTimeCycle::m_fCurrentWaterAlpha;
-int CTimeCycle::m_nCurrentFogColourRed;
-int CTimeCycle::m_nCurrentFogColourGreen;
-int CTimeCycle::m_nCurrentFogColourBlue;
+int32 CTimeCycle::m_nCurrentFogColourRed;
+int32 CTimeCycle::m_nCurrentFogColourGreen;
+int32 CTimeCycle::m_nCurrentFogColourBlue;
-int CTimeCycle::m_FogReduction;
+int32 CTimeCycle::m_FogReduction;
+int32 CTimeCycle::m_bExtraColourOn;
+int32 CTimeCycle::m_ExtraColour;
+float CTimeCycle::m_ExtraColourInter;
-int CTimeCycle::m_CurrentStoredValue;
+int32 CTimeCycle::m_CurrentStoredValue;
CVector CTimeCycle::m_VectorToSun[16];
float CTimeCycle::m_fShadowFrontX[16];
float CTimeCycle::m_fShadowFrontY[16];
@@ -133,7 +136,6 @@ float CTimeCycle::m_fShadowSideY[16];
float CTimeCycle::m_fShadowDisplacementX[16];
float CTimeCycle::m_fShadowDisplacementY[16];
-
void
CTimeCycle::Initialise(void)
{
@@ -233,15 +235,15 @@ CTimeCycle::Initialise(void)
m_nSunCoronaRed[h][w] = sunCoronaR;
m_nSunCoronaGreen[h][w] = sunCoronaG;
m_nSunCoronaBlue[h][w] = sunCoronaB;
- m_fSunSize[h][w] = sunSz;
- m_fSpriteSize[h][w] = sprSz;
- m_fSpriteBrightness[h][w] = sprBght;
+ m_fSunSize[h][w] = sunSz * 10.0f;
+ m_fSpriteSize[h][w] = sprSz * 10.0f;
+ m_fSpriteBrightness[h][w] = sprBght * 10.0f;
m_nShadowStrength[h][w] = shad;
m_nLightShadowStrength[h][w] = lightShad;
m_nPoleShadowStrength[h][w] = poleShad;
m_fFarClip[h][w] = farClp;
m_fFogStart[h][w] = fogSt;
- m_fLightsOnGroundBrightness[h][w] = lightGnd;
+ m_fLightsOnGroundBrightness[h][w] = lightGnd * 10.0f;
m_nLowCloudsRed[h][w] = cloudR;
m_nLowCloudsGreen[h][w] = cloudG;
m_nLowCloudsBlue[h][w] = cloudB;
@@ -265,6 +267,51 @@ CTimeCycle::Initialise(void)
debug("CTimeCycle ready\n");
}
+static float interp_c0, interp_c1, interp_c2, interp_c3;
+
+float CTimeCycle::Interpolate(int8 *a, int8 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+float CTimeCycle::Interpolate(uint8 *a, uint8 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+float CTimeCycle::Interpolate(int16 *a, int16 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+void
+CTimeCycle::StartExtraColour(int32 c, bool fade)
+{
+ m_bExtraColourOn = true;
+ m_ExtraColour = c;
+ if(fade)
+ m_ExtraColourInter = 0.0f;
+ else
+ m_ExtraColourInter = 1.0f;
+}
+
+void
+CTimeCycle::StopExtraColour(bool fade)
+{
+ m_bExtraColourOn = false;
+ if(!fade)
+ m_ExtraColourInter = 0.0f;
+}
+
void
CTimeCycle::Update(void)
{
@@ -274,12 +321,12 @@ CTimeCycle::Update(void)
int w2 = CWeather::NewWeatherType;
float timeInterp = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
// coefficients for a bilinear interpolation
- float c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
- float c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
- float c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
- float c3 = timeInterp * CWeather::InterpolationValue;
+ interp_c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
+ interp_c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
+ interp_c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
+ interp_c3 = timeInterp * CWeather::InterpolationValue;
-#define INTERP(v) v[h1][w1]*c0 + v[h2][w1]*c1 + v[h1][w2]*c2 + v[h2][w2]*c3;
+#define INTERP(v) Interpolate(v[h1], v[h2])
m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed);
m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen);
@@ -317,15 +364,15 @@ CTimeCycle::Update(void)
m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen);
m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue);
- m_fCurrentSunSize = INTERP(m_fSunSize);
- m_fCurrentSpriteSize = INTERP(m_fSpriteSize);
- m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness);
+ m_fCurrentSunSize = INTERP(m_fSunSize)/10.0f;
+ m_fCurrentSpriteSize = INTERP(m_fSpriteSize)/10.0f;
+ m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness)/10.0f;
m_nCurrentShadowStrength = INTERP(m_nShadowStrength);
m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength);
m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength);
m_fCurrentFarClip = INTERP(m_fFarClip);
m_fCurrentFogStart = INTERP(m_fFogStart);
- m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness);
+ m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness)/10.0f;
m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed);
m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen);
@@ -347,6 +394,7 @@ CTimeCycle::Update(void)
m_fCurrentWaterGreen = INTERP(m_fWaterGreen);
m_fCurrentWaterBlue = INTERP(m_fWaterBlue);
m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha);
+#undef INTERP
if(m_FogReduction != 0)
m_fCurrentFarClip = Max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
@@ -360,7 +408,88 @@ CTimeCycle::Update(void)
sunPos.z = 0.2f - Cos(sunAngle);
sunPos.Normalise();
- // TODO(MIAMI): extra colours
+ if(m_bExtraColourOn)
+ m_ExtraColourInter = Min(1.0f, m_ExtraColourInter + CTimer::GetTimeStep()/120.0f);
+ else
+ m_ExtraColourInter = Max(-.0f, m_ExtraColourInter - CTimer::GetTimeStep()/120.0f);
+ if(m_ExtraColourInter > 0.0f){
+#define INTERP(extra,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS] + (1.0f-m_ExtraColourInter)*cur)
+#define INTERPscl(extra,scl,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS]/scl + (1.0f-m_ExtraColourInter)*cur)
+ if(m_nSkyTopRed[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
+ m_nSkyTopGreen[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
+ m_nSkyTopBlue[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0){
+ m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed,m_nCurrentSkyTopRed);
+ m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen,m_nCurrentSkyTopGreen);
+ m_nCurrentSkyTopBlue = INTERP(m_nSkyTopBlue,m_nCurrentSkyTopBlue);
+
+ m_nCurrentSkyBottomRed = INTERP(m_nSkyBottomRed,m_nCurrentSkyBottomRed);
+ m_nCurrentSkyBottomGreen = INTERP(m_nSkyBottomGreen,m_nCurrentSkyBottomGreen);
+ m_nCurrentSkyBottomBlue = INTERP(m_nSkyBottomBlue,m_nCurrentSkyBottomBlue);
+
+ m_nCurrentSunCoreRed = INTERP(m_nSunCoreRed,m_nCurrentSunCoreRed);
+ m_nCurrentSunCoreGreen = INTERP(m_nSunCoreGreen,m_nCurrentSunCoreGreen);
+ m_nCurrentSunCoreBlue = INTERP(m_nSunCoreBlue,m_nCurrentSunCoreBlue);
+
+ m_nCurrentSunCoronaRed = INTERP(m_nSunCoronaRed,m_nCurrentSunCoronaRed);
+ m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen,m_nCurrentSunCoronaGreen);
+ m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue,m_nCurrentSunCoronaBlue);
+
+ m_fCurrentSunSize = INTERPscl(m_fSunSize,10.0f,m_fCurrentSunSize);
+
+ m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed,m_nCurrentLowCloudsRed);
+ m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen,m_nCurrentLowCloudsGreen);
+ m_nCurrentLowCloudsBlue = INTERP(m_nLowCloudsBlue,m_nCurrentLowCloudsBlue);
+
+ m_nCurrentFluffyCloudsTopRed = INTERP(m_nFluffyCloudsTopRed,m_nCurrentFluffyCloudsTopRed);
+ m_nCurrentFluffyCloudsTopGreen = INTERP(m_nFluffyCloudsTopGreen,m_nCurrentFluffyCloudsTopGreen);
+ m_nCurrentFluffyCloudsTopBlue = INTERP(m_nFluffyCloudsTopBlue,m_nCurrentFluffyCloudsTopBlue);
+
+ m_nCurrentFluffyCloudsBottomRed = INTERP(m_nFluffyCloudsBottomRed,m_nCurrentFluffyCloudsBottomRed);
+ m_nCurrentFluffyCloudsBottomGreen = INTERP(m_nFluffyCloudsBottomGreen,m_nCurrentFluffyCloudsBottomGreen);
+ m_nCurrentFluffyCloudsBottomBlue = INTERP(m_nFluffyCloudsBottomBlue,m_nCurrentFluffyCloudsBottomBlue);
+
+ m_fCurrentWaterRed = INTERP(m_fWaterRed,m_fCurrentWaterRed);
+ m_fCurrentWaterGreen = INTERP(m_fWaterGreen,m_fCurrentWaterGreen);
+ m_fCurrentWaterBlue = INTERP(m_fWaterBlue,m_fCurrentWaterBlue);
+ m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha,m_fCurrentWaterAlpha);
+ }
+
+ m_fCurrentAmbientRed = INTERP(m_nAmbientRed,m_fCurrentAmbientRed);
+ m_fCurrentAmbientGreen = INTERP(m_nAmbientGreen,m_fCurrentAmbientGreen);
+ m_fCurrentAmbientBlue = INTERP(m_nAmbientBlue,m_fCurrentAmbientBlue);
+
+ m_fCurrentAmbientRed_Obj = INTERP(m_nAmbientRed_Obj,m_fCurrentAmbientRed_Obj);
+ m_fCurrentAmbientGreen_Obj = INTERP(m_nAmbientGreen_Obj,m_fCurrentAmbientGreen_Obj);
+ m_fCurrentAmbientBlue_Obj = INTERP(m_nAmbientBlue_Obj,m_fCurrentAmbientBlue_Obj);
+
+ m_fCurrentAmbientRed_Bl = INTERP(m_nAmbientRed_Bl,m_fCurrentAmbientRed_Bl);
+ m_fCurrentAmbientGreen_Bl = INTERP(m_nAmbientGreen_Bl,m_fCurrentAmbientGreen_Bl);
+ m_fCurrentAmbientBlue_Bl = INTERP(m_nAmbientBlue_Bl,m_fCurrentAmbientBlue_Bl);
+
+ m_fCurrentAmbientRed_Obj_Bl = INTERP(m_nAmbientRed_Obj_Bl,m_fCurrentAmbientRed_Obj_Bl);
+ m_fCurrentAmbientGreen_Obj_Bl = INTERP(m_nAmbientGreen_Obj_Bl,m_fCurrentAmbientGreen_Obj_Bl);
+ m_fCurrentAmbientBlue_Obj_Bl = INTERP(m_nAmbientBlue_Obj_Bl,m_fCurrentAmbientBlue_Obj_Bl);
+
+ m_fCurrentDirectionalRed = INTERP(m_nDirectionalRed,m_fCurrentDirectionalRed);
+ m_fCurrentDirectionalGreen = INTERP(m_nDirectionalGreen,m_fCurrentDirectionalGreen);
+ m_fCurrentDirectionalBlue = INTERP(m_nDirectionalBlue,m_fCurrentDirectionalBlue);
+
+ m_fCurrentSpriteSize = INTERPscl(m_fSpriteSize,10.0f,m_fCurrentSpriteSize);
+ m_fCurrentSpriteBrightness = INTERPscl(m_fSpriteBrightness,10.0f,m_fCurrentSpriteBrightness);
+ m_nCurrentShadowStrength = INTERP(m_nShadowStrength,m_nCurrentShadowStrength);
+ m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength,m_nCurrentLightShadowStrength);
+ m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength,m_nCurrentPoleShadowStrength);
+ m_fCurrentFarClip = INTERP(m_fFarClip,m_fCurrentFarClip);
+ m_fCurrentFogStart = INTERP(m_fFogStart,m_fCurrentFogStart);
+ m_fCurrentLightsOnGroundBrightness = INTERPscl(m_fLightsOnGroundBrightness,10.0f,m_fCurrentLightsOnGroundBrightness);
+
+ m_fCurrentBlurRed = INTERP(m_fBlurRed,m_fCurrentBlurRed);
+ m_fCurrentBlurGreen = INTERP(m_fBlurGreen,m_fCurrentBlurGreen);
+ m_fCurrentBlurBlue = INTERP(m_fBlurBlue,m_fCurrentBlurBlue);
+
+#undef INTERP
+#undef INTERPscl
+ }
if(TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE)
TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, 5, MOTION_BLUR_LIGHT_SCENE);
diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h
index 832b36e2..da911b75 100644
--- a/src/render/Timecycle.h
+++ b/src/render/Timecycle.h
@@ -2,58 +2,58 @@
class CTimeCycle
{
- static int m_nAmbientRed[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
- static int m_nAmbientBlue_Obj_Bl[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_nPoleShadowStrength[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_fWaterRed[NUMHOURS][NUMWEATHERS];
- static float m_fWaterGreen[NUMHOURS][NUMWEATHERS];
- static float m_fWaterBlue[NUMHOURS][NUMWEATHERS];
- static float m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSunSize[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
+ static int16 m_fFogStart[NUMHOURS][NUMWEATHERS];
+ static int16 m_fFarClip[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
static float m_fCurrentAmbientRed;
static float m_fCurrentAmbientGreen;
@@ -70,36 +70,36 @@ class CTimeCycle
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 int32 m_nCurrentSkyTopRed;
+ static int32 m_nCurrentSkyTopGreen;
+ static int32 m_nCurrentSkyTopBlue;
+ static int32 m_nCurrentSkyBottomRed;
+ static int32 m_nCurrentSkyBottomGreen;
+ static int32 m_nCurrentSkyBottomBlue;
+ static int32 m_nCurrentSunCoreRed;
+ static int32 m_nCurrentSunCoreGreen;
+ static int32 m_nCurrentSunCoreBlue;
+ static int32 m_nCurrentSunCoronaRed;
+ static int32 m_nCurrentSunCoronaGreen;
+ static int32 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_nCurrentPoleShadowStrength;
+ static int32 m_nCurrentShadowStrength;
+ static int32 m_nCurrentLightShadowStrength;
+ static int32 m_nCurrentPoleShadowStrength;
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 int32 m_nCurrentLowCloudsRed;
+ static int32 m_nCurrentLowCloudsGreen;
+ static int32 m_nCurrentLowCloudsBlue;
+ static int32 m_nCurrentFluffyCloudsTopRed;
+ static int32 m_nCurrentFluffyCloudsTopGreen;
+ static int32 m_nCurrentFluffyCloudsTopBlue;
+ static int32 m_nCurrentFluffyCloudsBottomRed;
+ static int32 m_nCurrentFluffyCloudsBottomGreen;
+ static int32 m_nCurrentFluffyCloudsBottomBlue;
static float m_fCurrentBlurRed;
static float m_fCurrentBlurGreen;
static float m_fCurrentBlurBlue;
@@ -107,14 +107,17 @@ class CTimeCycle
static float m_fCurrentWaterGreen;
static float m_fCurrentWaterBlue;
static float m_fCurrentWaterAlpha;
- static int m_nCurrentFogColourRed;
- static int m_nCurrentFogColourGreen;
- static int m_nCurrentFogColourBlue;
+ static int32 m_nCurrentFogColourRed;
+ static int32 m_nCurrentFogColourGreen;
+ static int32 m_nCurrentFogColourBlue;
- static int m_FogReduction;
+ static int32 m_FogReduction;
public:
- static int m_CurrentStoredValue;
+ static int32 m_bExtraColourOn;
+ static int32 m_ExtraColour;
+ static float m_ExtraColourInter;
+ static int32 m_CurrentStoredValue;
static CVector m_VectorToSun[16];
static float m_fShadowFrontX[16];
static float m_fShadowFrontY[16];
@@ -138,51 +141,56 @@ public:
static float GetDirectionalRed(void) { return m_fCurrentDirectionalRed; }
static float GetDirectionalGreen(void) { return m_fCurrentDirectionalGreen; }
static float GetDirectionalBlue(void) { return m_fCurrentDirectionalBlue; }
- static int GetSkyTopRed(void) { return m_nCurrentSkyTopRed; }
- static int GetSkyTopGreen(void) { return m_nCurrentSkyTopGreen; }
- static int GetSkyTopBlue(void) { return m_nCurrentSkyTopBlue; }
- static int GetSkyBottomRed(void) { return m_nCurrentSkyBottomRed; }
- static int GetSkyBottomGreen(void) { return m_nCurrentSkyBottomGreen; }
- static int GetSkyBottomBlue(void) { return m_nCurrentSkyBottomBlue; }
- static int GetSunCoreRed(void) { return m_nCurrentSunCoreRed; }
- static int GetSunCoreGreen(void) { return m_nCurrentSunCoreGreen; }
- static int GetSunCoreBlue(void) { return m_nCurrentSunCoreBlue; }
- static int GetSunCoronaRed(void) { return m_nCurrentSunCoronaRed; }
- static int GetSunCoronaGreen(void) { return m_nCurrentSunCoronaGreen; }
- static int GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
+ static int32 GetSkyTopRed(void) { return m_nCurrentSkyTopRed; }
+ static int32 GetSkyTopGreen(void) { return m_nCurrentSkyTopGreen; }
+ static int32 GetSkyTopBlue(void) { return m_nCurrentSkyTopBlue; }
+ static int32 GetSkyBottomRed(void) { return m_nCurrentSkyBottomRed; }
+ static int32 GetSkyBottomGreen(void) { return m_nCurrentSkyBottomGreen; }
+ static int32 GetSkyBottomBlue(void) { return m_nCurrentSkyBottomBlue; }
+ static int32 GetSunCoreRed(void) { return m_nCurrentSunCoreRed; }
+ static int32 GetSunCoreGreen(void) { return m_nCurrentSunCoreGreen; }
+ static int32 GetSunCoreBlue(void) { return m_nCurrentSunCoreBlue; }
+ static int32 GetSunCoronaRed(void) { return m_nCurrentSunCoronaRed; }
+ static int32 GetSunCoronaGreen(void) { return m_nCurrentSunCoronaGreen; }
+ static int32 GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
static float GetSunSize(void) { return m_fCurrentSunSize; }
static float GetSpriteBrightness(void) { return m_fCurrentSpriteBrightness; }
static float GetSpriteSize(void) { return m_fCurrentSpriteSize; }
- static int GetShadowStrength(void) { return m_nCurrentShadowStrength; }
- static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
+ static int32 GetShadowStrength(void) { return m_nCurrentShadowStrength; }
+ static int32 GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
static float GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; }
static float GetFarClip(void) { return m_fCurrentFarClip; }
static float GetFogStart(void) { return m_fCurrentFogStart; }
- static int GetLowCloudsRed(void) { return m_nCurrentLowCloudsRed; }
- static int GetLowCloudsGreen(void) { return m_nCurrentLowCloudsGreen; }
- static int GetLowCloudsBlue(void) { return m_nCurrentLowCloudsBlue; }
- static int GetFluffyCloudsTopRed(void) { return m_nCurrentFluffyCloudsTopRed; }
- static int GetFluffyCloudsTopGreen(void) { return m_nCurrentFluffyCloudsTopGreen; }
- static int GetFluffyCloudsTopBlue(void) { return m_nCurrentFluffyCloudsTopBlue; }
- static int GetFluffyCloudsBottomRed(void) { return m_nCurrentFluffyCloudsBottomRed; }
- static int GetFluffyCloudsBottomGreen(void) { return m_nCurrentFluffyCloudsBottomGreen; }
- static int GetFluffyCloudsBottomBlue(void) { return m_nCurrentFluffyCloudsBottomBlue; }
- static int GetFogRed(void) { return m_nCurrentFogColourRed; }
- static int GetFogGreen(void) { return m_nCurrentFogColourGreen; }
- static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
- static int GetFogReduction(void) { return m_FogReduction; }
+ static int32 GetLowCloudsRed(void) { return m_nCurrentLowCloudsRed; }
+ static int32 GetLowCloudsGreen(void) { return m_nCurrentLowCloudsGreen; }
+ static int32 GetLowCloudsBlue(void) { return m_nCurrentLowCloudsBlue; }
+ static int32 GetFluffyCloudsTopRed(void) { return m_nCurrentFluffyCloudsTopRed; }
+ static int32 GetFluffyCloudsTopGreen(void) { return m_nCurrentFluffyCloudsTopGreen; }
+ static int32 GetFluffyCloudsTopBlue(void) { return m_nCurrentFluffyCloudsTopBlue; }
+ static int32 GetFluffyCloudsBottomRed(void) { return m_nCurrentFluffyCloudsBottomRed; }
+ static int32 GetFluffyCloudsBottomGreen(void) { return m_nCurrentFluffyCloudsBottomGreen; }
+ static int32 GetFluffyCloudsBottomBlue(void) { return m_nCurrentFluffyCloudsBottomBlue; }
+ static int32 GetFogRed(void) { return m_nCurrentFogColourRed; }
+ static int32 GetFogGreen(void) { return m_nCurrentFogColourGreen; }
+ static int32 GetFogBlue(void) { return m_nCurrentFogColourBlue; }
+ static int32 GetFogReduction(void) { return m_FogReduction; }
- static int GetBlurRed(void) { return m_fCurrentBlurRed; }
- static int GetBlurGreen(void) { return m_fCurrentBlurGreen; }
- static int GetBlurBlue(void) { return m_fCurrentBlurBlue; }
- static int GetWaterRed(void) { return m_fCurrentWaterRed; }
- static int GetWaterGreen(void) { return m_fCurrentWaterGreen; }
- static int GetWaterBlue(void) { return m_fCurrentWaterBlue; }
- static int GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
+ static int32 GetBlurRed(void) { return m_fCurrentBlurRed; }
+ static int32 GetBlurGreen(void) { return m_fCurrentBlurGreen; }
+ static int32 GetBlurBlue(void) { return m_fCurrentBlurBlue; }
+ static int32 GetWaterRed(void) { return m_fCurrentWaterRed; }
+ static int32 GetWaterGreen(void) { return m_fCurrentWaterGreen; }
+ static int32 GetWaterBlue(void) { return m_fCurrentWaterBlue; }
+ static int32 GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
static void Initialise(void);
static void Update(void);
+ static float Interpolate(int8 *a, int8 *b);
+ static float Interpolate(uint8 *a, uint8 *b);
+ static float Interpolate(int16 *a, int16 *b);
+ static void StartExtraColour(int32 c, bool fade);
+ static void StopExtraColour(bool fade);
static CVector &GetSunDirection(void) { return m_VectorToSun[m_CurrentStoredValue]; }
static float GetShadowFrontX(void) { return m_fShadowFrontX[m_CurrentStoredValue]; }
static float GetShadowFrontY(void) { return m_fShadowFrontY[m_CurrentStoredValue]; }
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index 945e1f5e..3f242362 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -19,6 +19,9 @@
#include "World.h"
#include "ZoneCull.h"
#include "SpecialFX.h"
+#include "Replay.h"
+
+//--MIAMI: file done
int32 CWeather::SoundHandle = -1;
@@ -33,6 +36,7 @@ uint32 CWeather::LightningStart;
uint32 CWeather::LightningFlashLastChange;
uint32 CWeather::WhenToPlayLightningSound;
uint32 CWeather::LightningDuration;
+int32 CWeather::StreamAfterRainTimer;
float CWeather::ExtraSunnyness;
float CWeather::Foggyness;
@@ -88,7 +92,7 @@ const int16 WeatherTypesList_WithHurricanes[] = {
WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY
};
-const float Windiness[] = {
+const float Windyness[] = {
0.25f,// WEATHER_SUNNY
0.7f, // WEATHER_CLOUDY
1.0f, // WEATHER_RAINY
@@ -140,22 +144,27 @@ void CWeather::Init(void)
void CWeather::Update(void)
{
- float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60;
- if (fNewInterpolation < InterpolationValue) {
- // new hour
- OldWeatherType = NewWeatherType;
- if (ForcedWeatherType >= 0)
- NewWeatherType = ForcedWeatherType;
- else {
- WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList);
- NewWeatherType = CStats::NoMoreHurricanes ? WeatherTypesList[WeatherTypeInList] : WeatherTypesList_WithHurricanes[WeatherTypeInList];
+ if(!CReplay::IsPlayingBack()){
+ float fNewInterpolation = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
+ if (fNewInterpolation < InterpolationValue) {
+ // new hour
+ OldWeatherType = NewWeatherType;
+ if (ForcedWeatherType >= 0)
+ NewWeatherType = ForcedWeatherType;
+ else {
+ WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList);
+ NewWeatherType = CStats::NoMoreHurricanes ? WeatherTypesList[WeatherTypeInList] : WeatherTypesList_WithHurricanes[WeatherTypeInList];
+ }
}
+ InterpolationValue = fNewInterpolation;
}
- InterpolationValue = fNewInterpolation;
+
+#ifndef FINAL
if (CPad::GetPad(1)->GetRightShockJustDown()) {
NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL;
OldWeatherType = NewWeatherType;
}
+#endif
// Lightning
if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) {
@@ -227,6 +236,7 @@ void CWeather::Update(void)
// if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s
fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f;
}
+ fNewRain = Max(fNewRain, 0.5f);
}
else
fNewRain = 0.0f;
@@ -257,7 +267,7 @@ void CWeather::Update(void)
ExtraSunnyness += InterpolationValue;
// Rainbow
- if (OldWeatherType == WEATHER_RAINY && (NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) &&
+ if (OldWeatherType == WEATHER_CLOUDY && (NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) &&
InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21)
Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f;
else
@@ -278,18 +288,21 @@ void CWeather::Update(void)
SunGlare *= (1.0f - (CGeneral::GetRandomNumber()&0x1F)*0.007f);
}
- Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType];
+ Wind = InterpolationValue * Windyness[NewWeatherType] + (1.0f - InterpolationValue) * Windyness[OldWeatherType];
WindClipped = Min(1.0f, Wind);
- if (CClock::GetHours() == 20)
+ if (CClock::GetHours() > 20)
+ TrafficLightBrightness = 1.0f;
+ else if (CClock::GetHours() > 19)
TrafficLightBrightness = CClock::GetMinutes() / 60.0f;
- else if (CClock::GetHours() > 6 && CClock::GetHours() < 20)
+ else if (CClock::GetHours() > 6)
TrafficLightBrightness = 0.0f;
- else if (CClock::GetHours() == 6)
+ else if (CClock::GetHours() > 5)
TrafficLightBrightness = 1.0f - CClock::GetMinutes() / 60.0f;
else
TrafficLightBrightness = 1.0f;
TrafficLightBrightness = Max(WetRoads, TrafficLightBrightness);
+ TrafficLightBrightness = Max(Foggyness, TrafficLightBrightness);
TrafficLightBrightness = Max(Rain, TrafficLightBrightness);
AddRain();
@@ -312,12 +325,32 @@ void CWeather::Update(void)
void CWeather::AddHeatHaze()
{
- /* TODO(MIAMI) */
+ if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
+ TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED)
+ return;
+ CVector pos;
+ pos.x = SCREEN_WIDTH*0.5f;
+ if(TheCamera.GetLookingForwardFirstPerson())
+ pos.y = CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT*0.25f, SCREEN_HEIGHT*0.9f);
+ else
+ pos.y = CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT*0.4f, SCREEN_HEIGHT*0.9f);
+ pos.z = 100.0f;
+ CParticle::AddParticle(PARTICLE_HEATHAZE_IN_DIST, pos, CVector(0.0f, 0.0f, 0.0f));
}
void CWeather::AddBeastie()
{
- /* TODO(MIAMI) */
+ if(FindPlayerVehicle() || CTimer::GetFrameCounter()%10 || (CGeneral::GetRandomNumber()&5) == 0)
+ return;
+ CVector pos = TheCamera.GetPosition();
+ float dist = CGeneral::GetRandomNumberInRange(90.0f, 60.0f);
+ int angle = CGeneral::GetRandomNumber() % CParticle::SIN_COS_TABLE_SIZE;
+ float c = CParticle::m_CosTable[angle];
+ float s = CParticle::m_SinTable[angle];
+ pos.x += dist*(c - s);
+ pos.y += dist*(c + s);
+ pos.z += CGeneral::GetRandomNumberInRange(7.5f, 30.0f);
+ CParticle::AddParticle(PARTICLE_BEASTIE, pos, CVector(0.0f, 0.0f, 0.0f));
}
void CWeather::ForceWeather(int16 weather)
@@ -337,6 +370,62 @@ void CWeather::ReleaseWeather()
ForcedWeatherType = -1;
}
+void CWeather::AddSplashesDuringHurricane()
+{
+ RwRGBA colour = { 255, 255, 255, 32 };
+ CVector pos = TheCamera.pTargetEntity ? TheCamera.pTargetEntity->GetPosition() : TheCamera.GetPosition();
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &foundGround) + 0.1f;
+ if(!foundGround)
+ groundZ = pos.z + 0.5f;
+ for(int i = 0; i < 20; i++){
+ float dist = (CGeneral::GetRandomNumber()&0xFF)/255.0f +
+ CGeneral::GetRandomNumberInRange(-10.0f, 30.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
+ pos.z = groundZ;
+ if(foundGround)
+ CParticle::AddParticle(PARTICLE_GROUND_STEAM, pos, CVector(-0.002f, -0.002f, 0.015f), nil, 0.0f, colour);
+ }
+}
+
+static int startStreamAfterRain;
+
+void CWeather::AddStreamAfterRain()
+{
+ if(CClock::GetHours() > 6 && CClock::GetHours() < 18){
+ RwRGBA colour = { 255, 255, 255, 24 };
+ CVector pos = TheCamera.pTargetEntity ? TheCamera.pTargetEntity->GetPosition() : TheCamera.GetPosition();
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &foundGround) + 0.2f;
+ if(!foundGround)
+ groundZ = pos.z + 0.75f;
+ for(int i = 0; i < 20; i++){
+ float dist = (CGeneral::GetRandomNumber()&0xFF)/255.0f +
+ CGeneral::GetRandomNumberInRange(-10.0f, 30.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
+ pos.z = groundZ;
+ CParticle::AddParticle(PARTICLE_GROUND_STEAM, pos, CVector(0.0f, 0.0f, 0.015f), nil, 0.0f, colour);
+ }
+ }else{
+ startStreamAfterRain = 0;
+ StreamAfterRainTimer = 800;
+ }
+}
+
void CWeather::AddRain()
{
if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
@@ -348,104 +437,77 @@ void CWeather::AddRain()
return;
}
}
+
+ if(Rain > 0.0){
+ startStreamAfterRain = 1;
+ StreamAfterRainTimer = 800;
+ }else if(startStreamAfterRain){
+ if(StreamAfterRainTimer > 0){
+ AddStreamAfterRain();
+ StreamAfterRainTimer--;
+ }else{
+ startStreamAfterRain = 0;
+ StreamAfterRainTimer = 800;
+ }
+ }
+
+ if (Wind > 1.1f)
+ AddSplashesDuringHurricane();
+
if (Rain <= 0.1f)
return;
static RwRGBA colour;
- float screen_width = RsGlobal.width;
- float screen_height = RsGlobal.height;
- int cur_frame = (int)(3 * Rain) & 3;
- int num_drops = (int)(2 * Rain) + 2;
- static int STATIC_RAIN_ANGLE = -45;
- static int count = 1500;
- static int add_angle = 1;
- if (--count == 0) {
- count = 1;
- if (add_angle) {
- STATIC_RAIN_ANGLE += 12;
- if (STATIC_RAIN_ANGLE > 45) {
- count = 1500;
- add_angle = !add_angle;
- }
- }
- else {
- STATIC_RAIN_ANGLE -= 12;
- if (STATIC_RAIN_ANGLE < -45) {
- count = 1500;
- add_angle = !add_angle;
- }
- }
- }
- float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0));
- float sin_angle = Sin(rain_angle);
- float cos_angle = Cos(rain_angle);
- float base_x = 0.0f * cos_angle - 1.0f * sin_angle;
- float base_y = 1.0f * cos_angle + 0.0f * sin_angle;
- CVector xpos(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < 2 * num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- xpos.x += screen_width / (2 * num_drops);
- xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- CVector ypos(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- ypos.y += screen_width / num_drops;
- ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- CVector ypos2(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- ypos2.y += screen_width / num_drops;
- ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- for (int i = 0; i < num_drops; i++) {
- CVector pos;
- pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET);
- pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET);
+ int numDrops = 5.0f * Rain;
+ int numSplashes = 2.0f * Rain;
+ CVector pos, dir;
+ for(int i = 0; i < numDrops; i++){
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_HEIGHT/5);
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = CGeneral::GetRandomNumberInRange((int)SCREEN_HEIGHT/5, (int)SCREEN_HEIGHT/2);
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = 0.0f;
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ float dist = CGeneral::GetRandomNumberInRange(0.0f, Max(10.0f*Rain, 40.0f)/2.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
pos.z = 0.0f;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 0);
- }
- int num_splash_attempts = (int)(3 * Rain) + 1;
- int num_splashes = (int)(3 * Rain) + 4;
- CVector splash_points[4];
- splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
- CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4;
- for (int i = 0; i < num_splash_attempts; i++) {
CColPoint point;
- CEntity* entity;
- CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f);
- if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) {
- for (int j = 0; j < num_splashes; j++)
- CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP),
- CVector(
- np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
- np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
- point.point.z + 0.1f),
- CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ CEntity *ent;
+ if(CWorld::ProcessVerticalLine(pos+CVector(0.0f, 0.0f, 40.0f), -40.0f, point, ent, true, false, false, false, true, false, nil)){
+ pos.z = point.point.z;
+ for(int j = 0; j < numSplashes+15; j++){
+ CVector pos2 = pos;
+ pos2.x += CGeneral::GetRandomNumberInRange(-15.0f, 15.0f);
+ pos2.y += CGeneral::GetRandomNumberInRange(-15.0f, 15.0f);
+ if(CGeneral::GetRandomNumber() & 1)
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASH, pos2, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ else
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, pos2, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ }
}
}
}
@@ -470,11 +532,11 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale,
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetRight().z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RAIN_COLOUR_R * intensity / 256, RAIN_COLOUR_G * intensity / 256, RAIN_COLOUR_B * intensity / 256, RAIN_ALPHA);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetRight().z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetUp().x, pos.y - 11.0f * TheCamera.GetUp().y, pos.z - 11.0f * TheCamera.GetUp().z);
float u = STREAK_U;
@@ -493,9 +555,9 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale,
u *= distance_coefficient;
v *= distance_coefficient;
if (!CTimer::GetIsPaused()) {
- RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f;
- RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f;
- RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f;
+ RandomTex = 0.0f;
+ RandomTexX = 0.0f;
+ RandomTexY = 0.0f;
}
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY);
@@ -518,6 +580,8 @@ void CWeather::RenderRainStreaks(void)
int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain);
if (base_intensity == 0)
return;
+ if (TheCamera.m_CameraAverageSpeed > 1.75f)
+ return;
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
for (int i = 0; i < NUM_RAIN_STREAKS; i++) {
@@ -528,11 +592,11 @@ void CWeather::RenderRainStreaks(void)
else{
int intensity;
if (secondsElapsed < STREAK_INTEROLATION_TIME)
- intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME;
+ intensity = base_intensity * 0.25f * secondsElapsed / STREAK_INTEROLATION_TIME;
else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME))
- intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME;
+ intensity = (STREAK_LIFETIME - secondsElapsed) * 0.25f * base_intensity / STREAK_INTEROLATION_TIME;
else
- intensity = base_intensity * 0.5f;
+ intensity = base_intensity * 0.25f;
CVector dir = Streaks[i].direction;
dir.Normalise();
CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction;
@@ -546,7 +610,7 @@ void CWeather::RenderRainStreaks(void)
}
else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){
// 1/16 probability
- Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
+ Streaks[i].direction = CVector(0.0f, 0.0f, -12.0f);
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
if (!CCutsceneMgr::IsRunning()) {
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
@@ -554,8 +618,8 @@ void CWeather::RenderRainStreaks(void)
}
else
Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f;
- Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
- Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
+ Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.04f;
+ Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.04f;
Streaks[i].timer = CTimer::GetTimeInMilliseconds();
}
}
diff --git a/src/render/Weather.h b/src/render/Weather.h
index ae09e5d1..ef62ebb6 100644
--- a/src/render/Weather.h
+++ b/src/render/Weather.h
@@ -6,7 +6,9 @@ enum {
WEATHER_FOGGY,
WEATHER_EXTRA_SUNNY,
WEATHER_HURRICANE,
- WEATHER_TOTAL
+ WEATHER_TOTAL,
+
+ WEATHER_EXTRACOLOURS = 6
};
class CWeather
@@ -25,6 +27,7 @@ public:
static uint32 LightningFlashLastChange;
static uint32 WhenToPlayLightningSound;
static uint32 LightningDuration;
+ static int32 StreamAfterRainTimer;
static float ExtraSunnyness;
static float Foggyness;
@@ -47,6 +50,8 @@ public:
static void ReleaseWeather();
static void ForceWeather(int16);
static void ForceWeatherNow(int16);
+ static void AddSplashesDuringHurricane();
+ static void AddStreamAfterRain();
static void AddRain();
static void AddHeatHaze();
static void AddBeastie();
diff --git a/src/render/WindModifiers.cpp b/src/render/WindModifiers.cpp
index 49e7c96a..2061df6a 100644
--- a/src/render/WindModifiers.cpp
+++ b/src/render/WindModifiers.cpp
@@ -1,13 +1,51 @@
#include "common.h"
#include "WindModifiers.h"
+#include "Camera.h"
+#include "General.h"
+
+#define MAX_HEIGHT_DIST 40.0f
+#define MIN_FADE_DIST 20.0f
+#define MAX_FADE_DIST 50.0f
+
+CWindModifiers Array[16];
+int32 CWindModifiers::Number;
void
-CWindModifiers::RegisterOne(CVector pos, int32 unk)
+CWindModifiers::RegisterOne(CVector pos, int32 type = 1)
{
+ if (CWindModifiers::Number < 16 && (pos - TheCamera.GetPosition()).Magnitude() < 100.0f) {
+ Array[Number].m_pos = pos;
+ Array[Number].m_type = type;
+ Number++;
+ }
}
-int32
+bool
CWindModifiers::FindWindModifier(CVector pos, float *x, float *y)
{
- return 0;
+ bool bWasWindModifierFound = false;
+ CVector2D dir;
+ for (int i = 0; i < Number; i++) {
+ if (Array[i].m_type == 1) {
+ float zDist = Abs(15.0f + pos.z - Array[i].m_pos.z);
+
+ if (zDist < MAX_HEIGHT_DIST) {
+ float dist = (pos - Array[i].m_pos).Magnitude();
+ if (dist < MAX_FADE_DIST) {
+ float distFade = dist < MIN_FADE_DIST ? 1.0f : 1.0f - (dist - MIN_FADE_DIST) / (MAX_FADE_DIST - MIN_FADE_DIST);
+ float heightFade = 1.0f - zDist / MAX_HEIGHT_DIST;
+ dir = (pos - Array[i].m_pos) * heightFade / dist;
+ bWasWindModifierFound = true;
+ }
+ }
+ }
+ }
+
+ if (bWasWindModifierFound) {
+ float directionMult = ((CGeneral::GetRandomNumber() & 0x1F) - 16) * 0.0035f + 1.0f;
+ *x += dir.x * directionMult;
+ *y += dir.y * directionMult;
+ }
+
+ return bWasWindModifierFound;
}
diff --git a/src/render/WindModifiers.h b/src/render/WindModifiers.h
index c42e185d..7c2e57bd 100644
--- a/src/render/WindModifiers.h
+++ b/src/render/WindModifiers.h
@@ -2,7 +2,10 @@
class CWindModifiers
{
+ CVector m_pos;
+ int32 m_type;
public:
- static void RegisterOne(CVector pos, int32 unk);
- static int32 FindWindModifier(CVector pos, float *x, float *y);
+ static int32 Number;
+ static void RegisterOne(CVector pos, int32 windSourceType);
+ static bool FindWindModifier(CVector pos, float *x, float *y);
};
diff --git a/src/rw/ClumpRead.cpp b/src/rw/ClumpRead.cpp
index 5f50f52d..b8d72d23 100644
--- a/src/rw/ClumpRead.cpp
+++ b/src/rw/ClumpRead.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+//--MIAMI: done
struct rpGeometryList
{
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index cd45b81f..3657e2c7 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -10,6 +10,8 @@
#include "Frontend.h"
#include "MBlur.h"
+//--MIAMI: done
+
RpLight *pAmbient;
RpLight *pDirect;
RpLight *pExtraDirectionals[4] = { nil };
@@ -23,7 +25,13 @@ RwRGBAReal DirectionalLightColourForFrame;
RwRGBAReal AmbientLightColour;
RwRGBAReal DirectionalLightColour;
-//--MIAMI: done
+#ifdef EXTENDED_COLOURFILTER
+#include "postfx.h"
+#define USEBLURCOLORS CPostFX::UseBlurColours()
+#else
+#define USEBLURCOLORS CMBlur::BlurOn
+#endif
+
void
SetLightsWithTimeOfDayColour(RpWorld *)
{
@@ -31,7 +39,7 @@ SetLightsWithTimeOfDayColour(RpWorld *)
RwMatrix mat;
if(pAmbient){
- if(CMBlur::BlurOn){
+ if(USEBLURCOLORS){
AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue_Bl() * CCoronas::LightsMult;
@@ -41,7 +49,7 @@ SetLightsWithTimeOfDayColour(RpWorld *)
AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult;
}
- if(CMBlur::BlurOn){
+ if(USEBLURCOLORS){
AmbientLightColourForFrame_PedsCarsAndObjects.red = CTimeCycle::GetAmbientRed_Obj_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame_PedsCarsAndObjects.green = CTimeCycle::GetAmbientGreen_Obj_Bl() * CCoronas::LightsMult;
AmbientLightColourForFrame_PedsCarsAndObjects.blue = CTimeCycle::GetAmbientBlue_Obj_Bl() * CCoronas::LightsMult;
@@ -302,6 +310,14 @@ ActivateDirectional(void)
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
}
+RwRGBAReal FullLight = { 1.0f, 1.0f, 1.0f, 1.0f };
+
+void
+SetFullAmbient(void)
+{
+ RpLightSetColor(pAmbient, &FullLight);
+}
+
void
SetAmbientColours(void)
{
diff --git a/src/rw/Lights.h b/src/rw/Lights.h
index 6fdd51de..b296816b 100644
--- a/src/rw/Lights.h
+++ b/src/rw/Lights.h
@@ -1,5 +1,11 @@
#pragma once
+extern RpLight *pAmbient;
+extern RpLight *pDirect;
+extern RpLight *pExtraDirectionals[4];
+extern int LightStrengths[4];
+extern int NumExtraDirLightsInWorld;
+
void SetLightsWithTimeOfDayColour(RpWorld *);
RpWorld *LightsCreate(RpWorld *world);
void LightsDestroy(RpWorld *world);
diff --git a/src/rw/NodeName.cpp b/src/rw/NodeName.cpp
index ad4acffb..a7185e4f 100644
--- a/src/rw/NodeName.cpp
+++ b/src/rw/NodeName.cpp
@@ -50,8 +50,8 @@ NodeNameStreamWrite(RwStream *stream, RwInt32 binaryLength, const void *object,
RwInt32
NodeNameStreamGetSize(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject)
{
- // game checks for null pointer on node name extension but that really happen
- return (RwInt32)rwstrlen(NODENAMEEXT(object));
+ char *name = NODENAMEEXT(object); // can't be nil
+ return name ? (RwInt32)rwstrlen(name) : 0;
}
bool
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index 58791ce2..9633e56c 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -209,24 +209,11 @@ 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(RpAtomicGetGeometry(atomic)))
- *pAtomic = atomic; // we could just return nil here directly...
- return atomic;
-}
-
-RpAtomic*
+bool
IsClumpSkinned(RpClump *clump)
{
- RpAtomic *atomic = nil;
- RpClumpForAllAtomics(clump, isSkinnedCb, &atomic);
- return atomic;
+ RpAtomic *atomic = GetFirstAtomic(clump);
+ return atomic ? RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)) : nil;
}
static RpAtomic*
@@ -264,17 +251,6 @@ GetAnimHierarchyFromClump(RpClump *clump)
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)
{
@@ -290,8 +266,7 @@ SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable)
if(boneTable == nil)
return;
-// atomic = GetFirstAtomic(clump); // mobile, also VC
- atomic = IsClumpSkinned(clump); // xbox, seems safer
+ atomic = GetFirstAtomic(clump); // mobile, also VC
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
@@ -397,7 +372,6 @@ RenderSkeleton(RpHAnimHierarchy *hier)
par = stack[--sp];
}
}
-#endif
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset)
@@ -560,6 +534,7 @@ CameraSize(RwCamera * camera, RwRect * rect,
}
}
+ // BUG: game just changes camera raster's sizes, but this is a hack
if (( origSize.w != rect->w ) && ( origSize.h != rect->h ))
{
RwRaster *raster;
@@ -844,4 +819,4 @@ RestoreAlphaTest()
RwD3D8SetRenderState(D3DRS_ALPHAREF, saved_alpharef);
#endif
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h
index 3f1a3d19..cbcbb2e0 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -18,16 +18,13 @@ RwObject *GetFirstObject(RwFrame *frame);
RpAtomic *GetFirstAtomic(RpClump *clump);
RwTexture *GetFirstTexture(RwTexDictionary *txd);
-#ifdef PED_SKIN
-RpAtomic *IsClumpSkinned(RpClump *clump);
+bool 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
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset);
RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM);
@@ -38,6 +35,7 @@ RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary
void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&);
bool CheckVideoCardCaps(void);
void WriteVideoCardCapsFile(void);
+bool CanVideoCardDoDXT(void);
void ConvertingTexturesScreen(uint32, uint32, const char*);
void DealWithTxdWriteError(uint32, uint32, const char*);
bool CreateTxdImageForVideoCard();
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index 4087029b..ad7d8fec 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -1,7 +1,13 @@
#pragma warning( push )
#pragma warning( disable : 4005)
#pragma warning( pop )
+#ifndef LIBRW
+#define WITHD3D
+#endif
#include "common.h"
+#ifndef LIBRW
+#include "rpanisot.h"
+#endif
#include "crossplatform.h"
#include "platform.h"
@@ -47,6 +53,15 @@ RwTextureGtaStreamRead(RwStream *stream)
texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1);
texNumLoaded++;
}
+
+ if(tex == nil)
+ return nil;
+
+#ifndef LIBRW
+ if(RpAnisotTextureGetMaxAnisotropy(tex) > 1)
+ RpAnisotTextureSetMaxAnisotropy(tex, RpAnisotTextureGetMaxAnisotropy(tex));
+#endif
+
return tex;
}
@@ -152,6 +167,7 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
#ifdef GTA_PC
#ifdef RWLIBS
extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
+extern "C" RwBool _rwD3D8CheckValidTextureFormat(RwInt32 format);
#else
RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
#endif
@@ -202,8 +218,20 @@ WriteVideoCardCapsFile(void)
}
}
-bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
-void DoRWStuffEndOfFrame(void);
+bool
+CanVideoCardDoDXT(void)
+{
+#ifdef LIBRW
+ // TODO
+#ifdef RW_OPENGL
+ return false;
+#else
+ return true;
+#endif
+#else
+ return _rwD3D8CheckValidTextureFormat(D3DFMT_DXT1) && _rwD3D8CheckValidTextureFormat(D3DFMT_DXT3);
+#endif
+}
void
ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
@@ -229,6 +257,7 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
+ CFont::SetCentreOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 217, 106, 255));
@@ -289,6 +318,11 @@ CreateTxdImageForVideoCard()
ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) {
+#ifdef FIX_BUGS
+ if(strcmp(CTxdStore::GetTxdName(i), "generic") == 0)
+ continue;
+#endif
+
CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY);
CStreaming::RequestModelStream(0);
CStreaming::FlushChannels();
diff --git a/src/rw/TxdStore.cpp b/src/rw/TxdStore.cpp
index 51d018f6..0bd29718 100644
--- a/src/rw/TxdStore.cpp
+++ b/src/rw/TxdStore.cpp
@@ -13,7 +13,7 @@ void
CTxdStore::Initialise(void)
{
if(ms_pTxdPool == nil)
- ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE);
+ ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE, "TexDictionary");
}
void
@@ -58,11 +58,10 @@ CTxdStore::RemoveTxdSlot(int slot)
int
CTxdStore::FindTxdSlot(const char *name)
{
- char *defname;
int size = ms_pTxdPool->GetSize();
for(int i = 0; i < size; i++){
- defname = GetTxdName(i);
- if(defname && !CGeneral::faststricmp(defname, name))
+ TxdDef *def = GetSlot(i);
+ if(def && !CGeneral::faststricmp(def->name, name))
return i;
}
return -1;
@@ -71,8 +70,7 @@ CTxdStore::FindTxdSlot(const char *name)
char*
CTxdStore::GetTxdName(int slot)
{
- TxdDef *def = GetSlot(slot);
- return def ? def->name : nil;
+ return GetSlot(slot)->name;
}
void
@@ -91,9 +89,7 @@ CTxdStore::PopCurrentTxd(void)
void
CTxdStore::SetCurrentTxd(int slot)
{
- TxdDef *def = GetSlot(slot);
- if(def)
- RwTexDictionarySetCurrent(def->texDict);
+ RwTexDictionarySetCurrent(GetSlot(slot)->texDict);
}
void
@@ -118,7 +114,7 @@ void
CTxdStore::RemoveRef(int slot)
{
if(--GetSlot(slot)->refCount <= 0)
- CStreaming::RemoveModel(slot + STREAM_OFFSET_TXD);
+ CStreaming::RemoveTxd(slot);
}
void
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index ac80eff0..36a60117 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -9,6 +9,7 @@
#include "Camera.h"
#include "VisibilityPlugins.h"
#include "World.h"
+#include "custompipes.h"
//--MIAMI: file done
@@ -193,6 +194,10 @@ CVisibilityPlugins::RenderFadingEntities(CLinkList<AlphaObjectInfo> &list)
CEntity *e = node->item.entity;
if(e->m_rwObject == nil)
continue;
+#ifdef EXTENDED_PIPELINES
+ if(CustomPipes::bRenderingEnvMap && (e->IsPed() || e->IsVehicle()))
+ continue;
+#endif
mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex());
if(mi->GetModelType() == MITYPE_SIMPLE && mi->m_noZwrite)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index 52c1aef7..90e7e122 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -37,9 +37,11 @@
#include "Weather.h"
#include "World.h"
#include "Zones.h"
+#include "Timecycle.h"
+#include "Fluff.h"
#define BLOCK_COUNT 20
-#define SIZE_OF_SIMPLEVARS 0xBC
+#define SIZE_OF_SIMPLEVARS 0xD4
const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729;
@@ -56,7 +58,7 @@ wchar SlotSaveDate[SLOT_COUNT][70];
int CheckSum;
eLevelName m_LevelToLoad;
char SaveFileNameJustSaved[260];
-int Slots[SLOT_COUNT+1];
+int Slots[SLOT_COUNT];
CDate CompileDateAndTime;
bool b_FoundRecentSavedGameWantToLoad;
@@ -187,6 +189,14 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif
+ WriteDataToBufferPointer(buf, CGame::currArea);
+ WriteDataToBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+ // TODO(Miami): Pad invert Y
+ bool invertY = 0;
+ WriteDataToBufferPointer(buf, invertY);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColour);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_bExtraColourOn);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColourInter);
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
// Save scripts, block is nested within the same block as simple vars for some reason
@@ -217,6 +227,7 @@ GenericSave(int file)
WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators);
WriteSaveDataBlock(CParticleObject::SaveParticle);
WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects);
+ WriteSaveDataBlock(CScriptPaths::Save);
WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo);
WriteSaveDataBlock(CStats::SaveStats);
WriteSaveDataBlock(CSetPieces::Save);
@@ -315,6 +326,14 @@ GenericLoad()
ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator);
ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif
+ ReadDataFromBufferPointer(buf, CGame::currArea);
+ ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+ // TODO(Miami): Pad invert Y
+ bool invertY = 0;
+ ReadDataFromBufferPointer(buf, invertY);
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour);
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn);
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter);
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
#ifdef MISSION_REPLAY
WaitForSave = 0;
@@ -360,6 +379,8 @@ GenericLoad()
LoadSaveDataBlock();
ReadDataFromBlock("Loading AudioScript Objects \n", cAudioScriptObject::LoadAllAudioScriptObjects);
LoadSaveDataBlock();
+ ReadDataFromBlock("Loading ScriptPaths \n", CScriptPaths::Load);
+ LoadSaveDataBlock();
ReadDataFromBlock("Loading Player Info \n", CWorld::Players[CWorld::PlayerInFocus].LoadPlayerInfo);
LoadSaveDataBlock();
ReadDataFromBlock("Loading Stats \n", CStats::LoadStats);
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index 069ba7cd..630b3b50 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -31,7 +31,7 @@ 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 int Slots[SLOT_COUNT];
extern bool b_FoundRecentSavedGameWantToLoad;
extern bool JustLoadedDontFadeInYet;
diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp
index da8134fc..8514a2b6 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -88,7 +88,7 @@ void
C_PcSave::PopulateSlotInfo()
{
for (int i = 0; i < SLOT_COUNT; i++) {
- Slots[i + 1] = SLOT_EMPTY;
+ Slots[i] = SLOT_EMPTY;
SlotFileName[i][0] = '\0';
SlotSaveDate[i][0] = '\0';
}
@@ -108,14 +108,14 @@ C_PcSave::PopulateSlotInfo()
if (file != 0) {
CFileMgr::Read(file, (char*)&header, sizeof(header));
if (strncmp((char*)&header, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1) != 0) {
- Slots[i + 1] = SLOT_OK;
+ Slots[i] = SLOT_OK;
memcpy(SlotFileName[i], &header.FileName, sizeof(header.FileName));
SlotFileName[i][24] = '\0';
}
CFileMgr::CloseFile(file);
}
- if (Slots[i + 1] == SLOT_OK) {
+ if (Slots[i] == SLOT_OK) {
if (CheckDataNotCorrupt(i, savename)) {
SYSTEMTIME st;
memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME));
@@ -147,7 +147,7 @@ C_PcSave::PopulateSlotInfo()
} else {
CMessages::InsertNumberInString(TheText.Get("FEC_SLC"), i + 1, -1, -1, -1, -1, -1, SlotFileName[i]);
- Slots[i + 1] = SLOT_CORRUPTED;
+ Slots[i] = SLOT_CORRUPTED;
}
}
}
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 9a4f2188..21b5c3c0 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -185,6 +185,22 @@ psCameraShowRaster(RwCamera *camera)
return;
}
+/*
+ *****************************************************************************
+ */
+RwImage *
+psGrabScreen(RwCamera *pCamera)
+{
+#ifndef LIBRW
+ RwRaster *pRaster = RwCameraGetRaster(pCamera);
+ if (RwImage *pImage = RwImageCreate(pRaster->width, pRaster->height, 32)) {
+ RwImageAllocatePixels(pImage);
+ RwImageSetFromRaster(pImage, pRaster);
+ return pImage;
+ }
+#endif
+ return nil;
+}
/*
*****************************************************************************
@@ -213,7 +229,11 @@ double
psTimer(void)
{
struct timespec start;
+#ifdef __linux__
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
+#else
+ clock_gettime(CLOCK_MONOTONIC, &start);
+#endif
return start.tv_sec * 1000.0 + start.tv_nsec/1000000.0;
}
#endif
@@ -1386,7 +1406,7 @@ WinMain(HINSTANCE instance,
RwChar** argv;
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
-#if 0
+#if 1
// TODO: make this an option somewhere
AllocConsole();
freopen("CONIN$", "r", stdin);
diff --git a/src/skel/platform.h b/src/skel/platform.h
index 806c0a73..0475d20a 100644
--- a/src/skel/platform.h
+++ b/src/skel/platform.h
@@ -22,6 +22,7 @@ extern void psTerminate(void);
extern void psCameraShowRaster(RwCamera *camera);
extern RwBool psCameraBeginUpdate(RwCamera *camera);
+extern RwImage *psGrabScreen(RwCamera *camera);
extern void psMouseSetPos(RwV2d *pos);
diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp
index 073155d6..99f44fed 100644
--- a/src/skel/skeleton.cpp
+++ b/src/skel/skeleton.cpp
@@ -53,6 +53,15 @@ RsCameraBeginUpdate(RwCamera * camera)
/*
*****************************************************************************
*/
+RwImage*
+RsGrabScreen(RwCamera *camera)
+{
+ return psGrabScreen(camera);
+}
+
+/*
+ *****************************************************************************
+ */
RwBool
RsRegisterImageLoader(void)
{
diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h
index b5ea5abf..1c468179 100644
--- a/src/skel/skeleton.h
+++ b/src/skel/skeleton.h
@@ -274,6 +274,9 @@ RsCameraBeginUpdate(RwCamera *camera);
//extern void
//RsMouseSetVisibility(RwBool visible);
+extern RwImage*
+RsGrabScreen(RwCamera *camera);
+
extern void
RsMouseSetPos(RwV2d *pos);
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 75a3a7c9..cc106e39 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -245,6 +245,23 @@ psCameraShowRaster(RwCamera *camera)
/*
*****************************************************************************
*/
+RwImage *
+psGrabScreen(RwCamera *pCamera)
+{
+#ifndef LIBRW
+ RwRaster *pRaster = RwCameraGetRaster(pCamera);
+ if (RwImage *pImage = RwImageCreate(pRaster->width, pRaster->height, 32)) {
+ RwImageAllocatePixels(pImage);
+ RwImageSetFromRaster(pImage, pRaster);
+ return pImage;
+ }
+#endif
+ return nil;
+}
+
+/*
+ *****************************************************************************
+ */
RwUInt32
psTimer(void)
{
@@ -1593,7 +1610,9 @@ psSelectDevice()
PSGLOBAL(fullScreen) = FALSE;
#endif
}
-
+#ifdef MULTISAMPLING
+ RwD3D8EngineSetMultiSamplingLevels(1 << FrontEndMenuManager.m_nPrefsMSAALevel);
+#endif
return TRUE;
}
@@ -1863,7 +1882,11 @@ void PlayMovieInWindow(int cmdShow, const char* szFile)
MultiByteToWideChar(CP_ACP, 0, szFile, -1, wFileName, sizeof(wFileName) - 1);
// Initialize COM
+#ifdef FIX_BUGS // will also return S_FALSE if it has already been inited in the same thread
+ CoInitialize(nil);
+#else
JIF(CoInitialize(nil));
+#endif
// Get the interface for DirectShow's GraphBuilder
JIF(CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC,
@@ -2233,9 +2256,10 @@ WinMain(HINSTANCE instance,
case GS_INIT_INTRO_MPEG:
{
+#ifndef NO_MOVIES
CloseClip();
-
CoUninitialize();
+#endif
if ( FrontEndMenuManager.OS_Language == LANG_FRENCH || FrontEndMenuManager.OS_Language == LANG_GERMAN )
PlayMovieInWindow(cmdShow, "movies\\GTAtitlesGER.mpg");
@@ -2269,8 +2293,10 @@ WinMain(HINSTANCE instance,
case GS_INIT_ONCE:
{
+#ifndef NO_MOVIES
CloseClip();
CoUninitialize();
+#endif
#ifdef FIX_BUGS
// draw one frame because otherwise we'll end up looking at black screen for a while if vsync is on
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index e06ce03b..eec44c35 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -49,7 +49,7 @@
#include "Object.h"
#include "Automobile.h"
-//--MIAMI: file done except TODOs
+//--MIAMI: file done
bool bAllCarCheat;
@@ -154,7 +154,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fElasticity = 0.05f;
m_fBuoyancy = pHandling->fBuoyancy;
- m_fOrientation = m_auto_unk4 = 0.0f;
+ m_fOrientation = m_fPlaneSteer = 0.0f;
m_nBusDoorTimerEnd = 0;
m_nBusDoorTimerStart = 0;
@@ -4210,12 +4210,11 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
pDriver &&
m_pDamageEntity && m_pDamageEntity->IsVehicle() &&
(this != FindPlayerVehicle() || ((CVehicle*)m_pDamageEntity)->VehicleCreatedBy == MISSION_VEHICLE) &&
-// TODO(MIAMI): enum
((CVehicle*)m_pDamageEntity)->pDriver){
if(GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR)
- pDriver->Say(145);
+ pDriver->Say(SOUND_PED_CRASH_CAR);
else
- pDriver->Say(144);
+ pDriver->Say(SOUND_PED_CRASH_VEHICLE);
}
int oldHealth = m_fHealth;
@@ -4944,11 +4943,11 @@ CAutomobile::PlayCarHorn(void)
m_nCarHornTimer = 45;
}else if(r < 4){
if(pDriver)
- pDriver->Say(SOUND_PED_CAR_COLLISION);
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
m_nCarHornTimer = 45;
}else{
if(pDriver)
- pDriver->Say(SOUND_PED_CAR_COLLISION);
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
}
}
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index eaceef7b..3dee998d 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -54,7 +54,7 @@ public:
float m_fTraction;
float m_fTireTemperature;
float m_fOrientation; // for heli and plane go-to
- float m_auto_unk4; // related to the above
+ float m_fPlaneSteer; // related to the above
float m_fVelocityChangeForAudio;
float m_randomValues[6]; // used for what?
float m_fFireBlowUpTimer;
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
index c32e72bc..62aeface 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -37,7 +37,7 @@
#include "Bike.h"
#include "Debug.h"
-//--MIAMI: done except for TODOs
+//--MIAMI: file done
// TODO: maybe put this somewhere else
inline void
@@ -1448,16 +1448,13 @@ CBike::PreRender(void)
fwd.Normalise();
float f = headLightPos.y + 6.0f;
pos += CVector(f*fwd.x, f*fwd.y, 2.0f);
-
-// TODO(MIAMI):
-// CShadows::StoreCarLightShadow(this, (uintptr)this + 22, gpShadowExplosionTex, &pos,
-// 7.0f*fwd.x, 7.0f*fwd.y, 3.5f*fwd.y, -3.5f*fwd.x, 45, 45, 45, 7.0f);
+ CShadows::StoreCarLightShadow(this, (uintptr)this + 22, gpShadowExplosionTex, &pos,
+ 7.0f*fwd.x, 7.0f*fwd.y, 3.5f*fwd.y, -3.5f*fwd.x, 45, 45, 45, 7.0f);
f = (tailLightPos.y - 2.5f) - (headLightPos.y + 6.0f);
pos += CVector(f*fwd.x, f*fwd.y, 0.0f);
-// TODO(MIAMI):
-// CShadows::StoreCarLightShadow(this, (uintptr)this + 25, gpShadowExplosionTex, &pos,
-// 3.0f, 0.0f, 0.0f, -3.0f, 35, 0, 0, 4.0f);
+ CShadows::StoreCarLightShadow(this, (uintptr)this + 25, gpShadowExplosionTex, &pos,
+ 3.0f, 0.0f, 0.0f, -3.0f, 35, 0, 0, 4.0f);
}
if(this == FindPlayerVehicle() && !alarmOff){
@@ -2137,8 +2134,7 @@ CBike::VehicleDamage(void)
m_pDamageEntity && m_pDamageEntity->IsVehicle() &&
(this != FindPlayerVehicle() || ((CVehicle*)m_pDamageEntity)->VehicleCreatedBy == MISSION_VEHICLE) &&
((CVehicle*)m_pDamageEntity)->pDriver)
-// TODO(MIAMI): enum
- pDriver->Say(144);
+ pDriver->Say(SOUND_PED_CRASH_VEHICLE);
int oldHealth = m_fHealth;
if(this == FindPlayerVehicle())
@@ -2545,11 +2541,11 @@ CBike::PlayCarHorn(void)
m_nCarHornTimer = 45;
}else if(r < 4){
if(pDriver)
- pDriver->Say(SOUND_PED_CAR_COLLISION);
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
m_nCarHornTimer = 45;
}else{
if(pDriver)
- pDriver->Say(SOUND_PED_CAR_COLLISION);
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
}
}
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index ae437f56..086a5002 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -242,7 +242,7 @@ CBoat::ProcessControl(void)
m_fHealth -= (collisionDamage-25.0f)/2.0f;
}else{
if(collisionDamage > 60.0f && pDriver)
- pDriver->Say(SOUND_PED_CAR_COLLISION);
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
if(bTakeLessDamage)
m_fHealth -= (collisionDamage-25.0f)/12.0f;
else
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index 5287055d..cc994ac6 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -4,6 +4,8 @@
#include "HandlingMgr.h"
#include "Transmission.h"
+//--MIAMI: done
+
void
cTransmission::InitGearRatios(void)
{
@@ -80,59 +82,51 @@ cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, fl
if(fVelocity > pGearRatio->fShiftUpVelocity){
if(gear != 0 || gasPedal > 0.0f){
gear++;
- time = 0.0f;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, false);
}
}else if(fVelocity < pGearRatio->fShiftDownVelocity && gear != 0){
if(gear != 1 || gasPedal < 0.0f){
gear--;
- time = 0.0f;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, false);
}
}
- if(time > 0.0f){
- // changing gears currently, can't accelerate
- fAcceleration = 0.0f;
- time -= CTimer::GetTimeStepInSeconds();
- }else{
- float speedMul, accelMul;
+ float speedMul, accelMul;
- if(gear < 1){
- // going reverse
- accelMul = (Flags & HANDLING_2G_BOOST) ? 2.0f : 1.0f;
- speedMul = -1.0f;
- }else if(nNumberOfGears == 1){
- accelMul = 1.0f;
- speedMul = 1.0f;
- }else{
- // BUG or not? this is 1.0 normally but 0.0 in the highest gear
- float f = 1.0f - (gear-1)/(nNumberOfGears-1);
- speedMul = 3.0f*sq(f) + 1.0f;
- // This is pretty ugly, could be written more clearly
- if(Flags & HANDLING_2G_BOOST){
- if(gear == 1)
- accelMul = (Flags & HANDLING_1G_BOOST) ? 3.0f : 2.0f;
- else if(gear == 2)
- accelMul = 1.3f;
- else
- accelMul = 1.0f;
- }else if(Flags & HANDLING_1G_BOOST && gear == 1){
- accelMul = 3.0f;
- }else
+ if(gear < 1){
+ // going reverse
+ accelMul = (Flags & HANDLING_2G_BOOST) ? 2.0f : 1.0f;
+ speedMul = -1.0f;
+ }else if(nNumberOfGears == 1){
+ accelMul = 1.0f;
+ speedMul = 1.0f;
+ }else{
+ // BUG or not? this is 1.0 normally but 0.0 in the highest gear
+ float f = 1.0f - (gear-1)/(nNumberOfGears-1);
+ speedMul = 3.0f*sq(f) + 1.0f;
+ // This is pretty ugly, could be written more clearly
+ if(Flags & HANDLING_2G_BOOST){
+ if(gear == 1)
+ accelMul = (Flags & HANDLING_1G_BOOST) ? 2.0f : 1.6f;
+ else if(gear == 2)
+ accelMul = 1.3f;
+ else
accelMul = 1.0f;
- }
-
- if(cheat)
- fCheat = 1.2f;
- else
- fCheat = 1.0f;
- float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat;
- float accel = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/Abs(targetVelocity);
- if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat))
- fAcceleration = gasPedal * accel * CTimer::GetTimeStep();
- else
- fAcceleration = 0.0f;
+ }else if(Flags & HANDLING_1G_BOOST && gear == 1){
+ accelMul = 2.0f;
+ }else
+ accelMul = 1.0f;
}
+
+ if(cheat)
+ fCheat = 1.2f;
+ else
+ fCheat = 1.0f;
+ float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat;
+ float accel = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/Abs(targetVelocity);
+ if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat))
+ fAcceleration = gasPedal * accel * CTimer::GetTimeStep();
+ else
+ fAcceleration = 0.0f;
return fAcceleration;
}