summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Camera.h2
-rw-r--r--src/CutsceneMgr.cpp2
-rw-r--r--src/CutsceneMgr.h4
-rw-r--r--src/Directory.cpp2
-rw-r--r--src/FileMgr.cpp18
-rw-r--r--src/FileMgr.h2
-rw-r--r--src/Radar.cpp5
-rw-r--r--src/Radar.h17
-rw-r--r--src/RwHelper.cpp38
-rw-r--r--src/RwHelper.h18
-rw-r--r--src/Streaming.cpp18
-rw-r--r--src/Streaming.h4
-rw-r--r--src/Timecycle.cpp2
-rw-r--r--src/Timer.h1
-rw-r--r--src/animation/AnimBlendClumpData.cpp2
-rw-r--r--src/animation/AnimBlendClumpData.h2
-rw-r--r--src/animation/FrameUpdate.cpp14
-rw-r--r--src/common.h3
-rw-r--r--src/config.h1
-rw-r--r--src/entities/CutsceneHead.cpp115
-rw-r--r--src/entities/CutsceneHead.h14
-rw-r--r--src/entities/CutsceneObject.cpp96
-rw-r--r--src/entities/CutsceneObject.h16
-rw-r--r--src/entities/Entity.h2
-rw-r--r--src/entities/Object.cpp63
-rw-r--r--src/entities/Object.h13
-rw-r--r--src/entities/Physical.cpp54
-rw-r--r--src/entities/Physical.h2
-rw-r--r--src/main.cpp1
-rw-r--r--src/math/Matrix.h12
-rw-r--r--src/modelinfo/ModelIndices.h6
-rw-r--r--src/re3.cpp11
-rw-r--r--src/render/Renderer.cpp13
-rw-r--r--src/render/Renderer.h2
-rw-r--r--src/render/Shadows.cpp3
-rw-r--r--src/render/Shadows.h2
-rw-r--r--src/render/Sprite2d.cpp2
-rw-r--r--src/skel/win/win.cpp7
38 files changed, 534 insertions, 55 deletions
diff --git a/src/Camera.h b/src/Camera.h
index c2e63876..73fce616 100644
--- a/src/Camera.h
+++ b/src/Camera.h
@@ -220,7 +220,7 @@ enum
FADE_1, // mid fade
FADE_2,
- FADE_OUT,
+ FADE_OUT = 0,
FADE_IN,
};
diff --git a/src/CutsceneMgr.cpp b/src/CutsceneMgr.cpp
index 0e54ff34..744ef53d 100644
--- a/src/CutsceneMgr.cpp
+++ b/src/CutsceneMgr.cpp
@@ -4,4 +4,4 @@
bool &CCutsceneMgr::ms_running = *(bool*)0x95CCF5;
bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F;
-Bool &CCutsceneMgr::ms_running = *(Bool*)0x95CCF5;
+CDirectory *&CCutsceneMgr::ms_pCutsceneDir = *(CDirectory**)0x8F5F88;
diff --git a/src/CutsceneMgr.h b/src/CutsceneMgr.h
index 9cafad8b..87aef03a 100644
--- a/src/CutsceneMgr.h
+++ b/src/CutsceneMgr.h
@@ -1,11 +1,15 @@
#pragma once
+class CDirectory;
+
class CCutsceneMgr
{
static bool &ms_running;
static bool &ms_cutsceneProcessing;
public:
+ static CDirectory *&ms_pCutsceneDir;
+
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
diff --git a/src/Directory.cpp b/src/Directory.cpp
index 553dd539..3e0d5382 100644
--- a/src/Directory.cpp
+++ b/src/Directory.cpp
@@ -23,7 +23,7 @@ CDirectory::ReadDirFile(const char *filename)
fd = CFileMgr::OpenFile(filename, "rb");
while(CFileMgr::Read(fd, (char*)&dirinfo, sizeof(dirinfo)))
AddItem(dirinfo);
- return CFileMgr::CloseFile(fd);
+ CFileMgr::CloseFile(fd);
}
bool
diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp
index 3aad9794..02c797ba 100644
--- a/src/FileMgr.cpp
+++ b/src/FileMgr.cpp
@@ -5,6 +5,8 @@
#include "patcher.h"
#include "FileMgr.h"
+const char *_psGetUserFilesFolder();
+
/*
* Windows FILE is BROKEN for GTA.
*
@@ -49,14 +51,17 @@ found:
return fd;
}
-static void
+static int
myfclose(int fd)
{
+ int ret;
assert(fd < NUMFILES);
if(myfiles[fd].file){
- fclose(myfiles[fd].file);
+ ret = fclose(myfiles[fd].file);
myfiles[fd].file = nil;
+ return ret;
}
+ return EOF;
}
static int
@@ -158,7 +163,8 @@ myfseek(int fd, long offset, int whence)
static int
myfeof(int fd)
{
- return feof(myfiles[fd].file);
+// return feof(myfiles[fd].file);
+ return ferror(myfiles[fd].file);
}
@@ -205,7 +211,7 @@ void
CFileMgr::SetDirMyDocuments(void)
{
SetDir(""); // better start at the root if user directory is relative
- chdir(GetUserDirectory());
+ chdir(_psGetUserFilesFolder());
}
int
@@ -265,10 +271,10 @@ CFileMgr::ReadLine(int fd, char *buf, int len)
return myfgets(buf, len, fd);
}
-void
+int
CFileMgr::CloseFile(int fd)
{
- myfclose(fd);
+ return myfclose(fd);
}
int
diff --git a/src/FileMgr.h b/src/FileMgr.h
index a77ae6fa..f67056f1 100644
--- a/src/FileMgr.h
+++ b/src/FileMgr.h
@@ -16,6 +16,6 @@ public:
static int Write(int fd, char *buf, int len);
static bool Seek(int fd, int offset, int whence);
static char *ReadLine(int fd, char *buf, int len);
- static void CloseFile(int fd);
+ static int CloseFile(int fd);
static int GetErrorReadWrite(int fd);
};
diff --git a/src/Radar.cpp b/src/Radar.cpp
new file mode 100644
index 00000000..a84d5b91
--- /dev/null
+++ b/src/Radar.cpp
@@ -0,0 +1,5 @@
+#include "common.h"
+#include "patcher.h"
+#include "Radar.h"
+
+WRAPPER void CRadar::ClearBlipForEntity(eBlipType type, int32 id) { EAXJMP(0x4A56C0); }
diff --git a/src/Radar.h b/src/Radar.h
new file mode 100644
index 00000000..123cffb1
--- /dev/null
+++ b/src/Radar.h
@@ -0,0 +1,17 @@
+#pragma once
+
+enum eBlipType
+{
+ BLIP_NONE,
+ BLIP_CAR,
+ BLIP_CHAR,
+ BLIP_OBJECT,
+ BLIP_COORD,
+ BLIP_CONTACT_POINT
+};
+
+class CRadar
+{
+public:
+ static void ClearBlipForEntity(eBlipType type, int32 id);
+};
diff --git a/src/RwHelper.cpp b/src/RwHelper.cpp
index cb0c1a4e..2ff58393 100644
--- a/src/RwHelper.cpp
+++ b/src/RwHelper.cpp
@@ -29,6 +29,23 @@ DefinedState(void)
RwD3D8SetRenderState(D3DRS_ALPHAREF, 2);
}
+RwFrame*
+GetFirstFrameCallback(RwFrame *child, void *data)
+{
+ *(RwFrame**)data = child;
+ return nil;
+}
+
+RwFrame*
+GetFirstChild(RwFrame *frame)
+{
+ RwFrame *child;
+
+ child = nil;
+ RwFrameForAllChildren(frame, GetFirstFrameCallback, &child);
+ return child;
+}
+
RwObject*
GetFirstObjectCallback(RwObject *object, void *data)
{
@@ -46,6 +63,23 @@ GetFirstObject(RwFrame *frame)
return obj;
}
+RpAtomic*
+GetFirstAtomicCallback(RpAtomic *atm, void *data)
+{
+ *(RpAtomic**)data = atm;
+ return nil;
+}
+
+RpAtomic*
+GetFirstAtomic(RpClump *clump)
+{
+ RpAtomic *atm;
+
+ atm = nil;
+ RpClumpForAllAtomics(clump, GetFirstAtomicCallback, &atm);
+ return atm;
+}
+
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)
@@ -135,7 +169,7 @@ CameraSize(RwCamera * camera, RwRect * rect,
rect->x = origSize.x;
rect->y = origSize.y;
- rect->w = origSize.w;
+ rect->w = origSize.w;
rect->h = origSize.h;
/*
@@ -274,4 +308,4 @@ STARTPATCHES
InjectHook(0x527170, CameraSize, PATCH_JUMP);
InjectHook(0x527340, CameraDestroy, PATCH_JUMP);
InjectHook(0x5273B0, CameraCreate, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+ENDPATCHES
diff --git a/src/RwHelper.h b/src/RwHelper.h
index 6112f72d..75525d25 100644
--- a/src/RwHelper.h
+++ b/src/RwHelper.h
@@ -1,13 +1,15 @@
#pragma once
void DefinedState(void);
+RwFrame *GetFirstChild(RwFrame *frame);
RwObject *GetFirstObject(RwFrame *frame);
+RpAtomic *GetFirstAtomic(RpClump *clump);
-extern void CameraSize(RwCamera *camera,
- RwRect *rect,
- RwReal viewWindow,
- RwReal aspectRatio);
-extern void CameraDestroy(RwCamera *camera);
-extern RwCamera *CameraCreate(RwInt32 width,
- RwInt32 height,
- RwBool zBuffer); \ No newline at end of file
+void CameraSize(RwCamera *camera,
+ RwRect *rect,
+ RwReal viewWindow,
+ RwReal aspectRatio);
+void CameraDestroy(RwCamera *camera);
+RwCamera *CameraCreate(RwInt32 width,
+ RwInt32 height,
+ RwBool zBuffer);
diff --git a/src/Streaming.cpp b/src/Streaming.cpp
index 47258c9d..c090ef82 100644
--- a/src/Streaming.cpp
+++ b/src/Streaming.cpp
@@ -8,3 +8,21 @@ CStreamingInfo *CStreaming::ms_aInfoForModel = (CStreamingInfo*)0x6C7088;
WRAPPER void CStreaming::RemoveModel(int32 id) { EAXJMP(0x408830); }
WRAPPER void CStreaming::RequestModel(int32 model, int32 flags) { EAXJMP(0x407EA0); }
+
+WRAPPER void CStreaming::MakeSpaceFor(int32 size) { EAXJMP(0x409B70); }
+
+void
+CStreaming::ImGonnaUseStreamingMemory(void)
+{
+}
+
+void
+CStreaming::IHaveUsedStreamingMemory(void)
+{
+ UpdateMemoryUsed();
+}
+
+void
+CStreaming::UpdateMemoryUsed(void)
+{
+}
diff --git a/src/Streaming.h b/src/Streaming.h
index 1acfc261..18128cff 100644
--- a/src/Streaming.h
+++ b/src/Streaming.h
@@ -51,4 +51,8 @@ public:
static void RemoveModel(int32 id);
static void RequestModel(int32 model, int32 flags);
+ static void MakeSpaceFor(int32 size);
+ static void ImGonnaUseStreamingMemory(void);
+ static void IHaveUsedStreamingMemory(void);
+ static void UpdateMemoryUsed(void);
};
diff --git a/src/Timecycle.cpp b/src/Timecycle.cpp
index 501691c3..56341e32 100644
--- a/src/Timecycle.cpp
+++ b/src/Timecycle.cpp
@@ -289,7 +289,7 @@ CTimeCycle::Update(void)
TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, m_fCurrentBlurAlpha, MBLUR_NORMAL);
if(m_FogReduction != 0)
- m_fCurrentFarClip = max(m_fCurrentFarClip, m_FogReduction/64 * 650.0f);
+ m_fCurrentFarClip = max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
diff --git a/src/Timer.h b/src/Timer.h
index fdd21144..fa93a65e 100644
--- a/src/Timer.h
+++ b/src/Timer.h
@@ -14,6 +14,7 @@ class CTimer
static bool &m_CodePause;
public:
static float GetTimeStep(void) { return ms_fTimeStep; }
+ static float GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
static uint32 GetFrameCounter(void) { return m_FrameCounter; }
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp
index 57985533..73e71246 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -9,7 +9,7 @@
CAnimBlendClumpData::CAnimBlendClumpData(void)
{
numFrames = 0;
- pedPosition = nil;
+ velocity = nil;
frames = nil;
link.Init();
}
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 955578f0..df2fbc56 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -38,7 +38,7 @@ public:
#ifdef PED_SKIN
int32 modelNumber; // doesn't seem to be used
#endif
- CVector *pedPosition;
+ CVector *velocity;
// order of frames is determined by RW hierarchy
AnimBlendFrameData *frames;
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index 1533897e..62300527 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -23,7 +23,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
- gpAnimBlendClump->pedPosition){
+ gpAnimBlendClump->velocity){
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION_3D)
FrameUpdateCallBackWith3dVelocityExtraction(frame, arg);
else
@@ -132,11 +132,11 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
- gpAnimBlendClump->pedPosition->x = transx - curx;
- gpAnimBlendClump->pedPosition->y = transy - cury;
+ gpAnimBlendClump->velocity->x = transx - curx;
+ gpAnimBlendClump->velocity->y = transy - cury;
if(looped){
- gpAnimBlendClump->pedPosition->x += endx;
- gpAnimBlendClump->pedPosition->y += endy;
+ gpAnimBlendClump->velocity->x += endx;
+ gpAnimBlendClump->velocity->y += endy;
}
mat->pos.x = pos.x - transx;
mat->pos.y = pos.y - transy;
@@ -211,9 +211,9 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
- *gpAnimBlendClump->pedPosition = trans - cur;
+ *gpAnimBlendClump->velocity = trans - cur;
if(looped)
- *gpAnimBlendClump->pedPosition += end;
+ *gpAnimBlendClump->velocity += end;
mat->pos.x = (pos - trans).x + frame->resetPos.x;
mat->pos.y = (pos - trans).y + frame->resetPos.y;
mat->pos.z = (pos - trans).z + frame->resetPos.z;
diff --git a/src/common.h b/src/common.h
index d5223b6f..4187e0c3 100644
--- a/src/common.h
+++ b/src/common.h
@@ -72,8 +72,6 @@ extern void **rwengine;
#define SCREEN_FROM_RIGHT(a) Float(SCREEN_WIDTH - SCREEN_STRETCH_X(a))
#define SCREEN_FROM_BOTTOM(a) Float(SCREEN_HEIGHT - SCREEN_STRETCH_Y(a))
-char *GetUserDirectory(void);
-
struct GlobalScene
{
RpWorld *world;
@@ -135,6 +133,7 @@ int myrand(void);
void mysrand(unsigned int seed);
extern uint8 work_buff[55000];
+extern char gString[256];
void re3_debug(char *format, ...);
void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...);
diff --git a/src/config.h b/src/config.h
index 8ef51871..71689778 100644
--- a/src/config.h
+++ b/src/config.h
@@ -65,3 +65,4 @@ enum Config {
//#define FIX_BUGS
//#define NO_CDCHECK
#define NO_MOVIES
+//#define USE_MY_DOCUMENTS
diff --git a/src/entities/CutsceneHead.cpp b/src/entities/CutsceneHead.cpp
index 6a8874f5..766befb0 100644
--- a/src/entities/CutsceneHead.cpp
+++ b/src/entities/CutsceneHead.cpp
@@ -1,2 +1,117 @@
#include "common.h"
+#include <rpskin.h>
+#include "patcher.h"
+#include "RwHelper.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendClumpData.h"
+#include "Directory.h"
+#include "CutsceneMgr.h"
+#include "Streaming.h"
#include "CutsceneHead.h"
+
+
+CCutsceneHead::CCutsceneHead(CObject *obj)
+{
+ RpAtomic *atm;
+
+ assert(RwObjectGetType(obj->m_rwObject) == rpCLUMP);
+ m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
+ atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
+ if(atm){
+ assert(RwObjectGetType(atm) == rpATOMIC);
+ RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
+ }
+}
+
+void
+CCutsceneHead::CreateRwObject(void)
+{
+ RpAtomic *atm;
+
+ CEntity::CreateRwObject();
+ assert(RwObjectGetType(m_rwObject) == rpCLUMP);
+ atm = GetFirstAtomic((RpClump*)m_rwObject);
+ RpSkinAtomicSetHAnimHierarchy(atm, RpHAnimFrameGetHierarchy(GetFirstChild(RpClumpGetFrame((RpClump*)m_rwObject))));
+}
+
+void
+CCutsceneHead::DeleteRwObject(void)
+{
+ CEntity::DeleteRwObject();
+}
+
+void
+CCutsceneHead::ProcessControl(void)
+{
+ RpAtomic *atm;
+ RpHAnimHierarchy *hier;
+
+ CPhysical::ProcessControl();
+
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
+ UpdateRwFrame();
+
+ assert(RwObjectGetType(m_rwObject) == rpCLUMP);
+ atm = GetFirstAtomic((RpClump*)m_rwObject);
+ hier = RpSkinAtomicGetHAnimHierarchy(atm);
+ RpHAnimHierarchyAddAnimTime(hier, CTimer::GetTimeStepNonClipped()/50.0f);
+}
+
+void
+CCutsceneHead::Render(void)
+{
+ RpAtomic *atm;
+
+ m_matrix.SetRotateY(PI/2);
+ m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
+ UpdateRwFrame();
+
+ assert(RwObjectGetType(m_rwObject) == rpCLUMP);
+ atm = GetFirstAtomic((RpClump*)m_rwObject);
+ RpHAnimHierarchyUpdateMatrices(RpSkinAtomicGetHAnimHierarchy(atm));
+
+ CObject::Render();
+}
+
+void
+CCutsceneHead::PlayAnimation(const char *animName)
+{
+ RpAtomic *atm;
+ RpHAnimHierarchy *hier;
+ RpHAnimAnimation *anim;
+ uint32 offset, size;
+ RwStream *stream;
+
+ assert(RwObjectGetType(m_rwObject) == rpCLUMP);
+ atm = GetFirstAtomic((RpClump*)m_rwObject);
+ hier = RpSkinAtomicGetHAnimHierarchy(atm);
+
+ sprintf(gString, "%s.anm", animName);
+
+ if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
+ stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
+ assert(stream);
+
+ CStreaming::MakeSpaceFor(size*2048);
+ CStreaming::ImGonnaUseStreamingMemory();
+
+ RwStreamSkip(stream, offset*2048);
+ if(RwStreamFindChunk(stream, rwID_HANIMANIMATION, nil, nil)){
+ anim = RpHAnimAnimationStreamRead(stream);
+ RpHAnimHierarchySetCurrentAnim(hier, anim);
+ }
+
+ CStreaming::IHaveUsedStreamingMemory();
+
+ RwStreamClose(stream, nil);
+ }
+}
+
+STARTPATCHES
+ InjectHook(0x4BA650, &CCutsceneHead::CreateRwObject_, PATCH_JUMP);
+ InjectHook(0x4BA690, &CCutsceneHead::DeleteRwObject_, PATCH_JUMP);
+ InjectHook(0x4BA760, &CCutsceneHead::ProcessControl_, PATCH_JUMP);
+ InjectHook(0x4BA800, &CCutsceneHead::Render_, PATCH_JUMP);
+ InjectHook(0x4BA6A0, &CCutsceneHead::PlayAnimation, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/entities/CutsceneHead.h b/src/entities/CutsceneHead.h
index 5784ffc9..de4f011f 100644
--- a/src/entities/CutsceneHead.h
+++ b/src/entities/CutsceneHead.h
@@ -6,5 +6,19 @@ class CCutsceneHead : public CCutsceneObject
{
public:
RwFrame *m_pHeadNode;
+
+ CCutsceneHead(CObject *obj);
+
+ void CreateRwObject(void);
+ void DeleteRwObject(void);
+ void ProcessControl(void);
+ void Render(void);
+
+ void PlayAnimation(const char *animName);
+
+ void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); }
+ void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); }
+ void ProcessControl_(void) { CCutsceneHead::ProcessControl(); }
+ void Render_(void) { CCutsceneHead::Render(); }
};
static_assert(sizeof(CCutsceneHead) == 0x19C, "CCutsceneHead: error");
diff --git a/src/entities/CutsceneObject.cpp b/src/entities/CutsceneObject.cpp
index 6aa0f4b3..d00a668b 100644
--- a/src/entities/CutsceneObject.cpp
+++ b/src/entities/CutsceneObject.cpp
@@ -1,2 +1,98 @@
#include "common.h"
+#include "patcher.h"
+#include "lights.h"
+#include "PointLights.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendClumpData.h"
+#include "Renderer.h"
+#include "ModelIndices.h"
+#include "Shadows.h"
+#include "TimeCycle.h"
#include "CutsceneObject.h"
+
+CCutsceneObject::CCutsceneObject(void)
+{
+ m_status = STATUS_SIMPLE;
+ bUsesCollision = false;
+ m_flagC20 = true;
+ ObjectCreatedBy = CUTSCENE_OBJECT;
+ m_fMass = 1.0f;
+ m_fTurnMass = 1.0f;
+}
+
+void
+CCutsceneObject::SetModelIndex(uint32 id)
+{
+ CEntity::SetModelIndex(id);
+ assert(RwObjectGetType(m_rwObject) == rpCLUMP);
+ RpAnimBlendClumpInit((RpClump*)m_rwObject);
+ (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = &m_vecMoveSpeed;
+ (*RPANIMBLENDCLUMPDATA(m_rwObject))->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION_3D;
+}
+
+void
+CCutsceneObject::ProcessControl(void)
+{
+ CPhysical::ProcessControl();
+
+ if(CTimer::GetTimeStep() < 1/100.0f)
+ m_vecMoveSpeed *= 100.0f;
+ else
+ m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
+
+ ApplyMoveSpeed();
+}
+
+void
+CCutsceneObject::PreRender(void)
+{
+ if(IsPedModel(GetModelIndex()))
+ CShadows::StoreShadowForPedObject(this,
+ CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+}
+
+void
+CCutsceneObject::Render(void)
+{
+ CObject::Render();
+}
+
+bool
+CCutsceneObject::SetupLighting(void)
+{
+ ActivateDirectional();
+ SetAmbientColoursForPedsCarsAndObjects();
+
+ if(bRenderScorched){
+ WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
+ }else{
+ CVector coors = GetPosition();
+ float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
+ if(!m_flagB20 && lighting != 1.0f){
+ SetAmbientAndDirectionalColours(lighting);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+CCutsceneObject::RemoveLighting(bool reset)
+{
+ CRenderer::RemoveVehiclePedLights(this, reset);
+}
+
+STARTPATCHES
+ InjectHook(0x4BA980, &CCutsceneObject::SetModelIndex_, PATCH_JUMP);
+ InjectHook(0x4BA9C0, &CCutsceneObject::ProcessControl_, PATCH_JUMP);
+ InjectHook(0x4BAA40, &CCutsceneObject::PreRender_, PATCH_JUMP);
+ InjectHook(0x4BAAA0, &CCutsceneObject::Render_, PATCH_JUMP);
+ InjectHook(0x4A7E70, &CCutsceneObject::SetupLighting_, PATCH_JUMP);
+ InjectHook(0x4A7F00, &CCutsceneObject::RemoveLighting_, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/entities/CutsceneObject.h b/src/entities/CutsceneObject.h
index c5cbf83f..182d8612 100644
--- a/src/entities/CutsceneObject.h
+++ b/src/entities/CutsceneObject.h
@@ -5,5 +5,21 @@
class CCutsceneObject : public CObject
{
public:
+ CCutsceneObject(void);
+
+ void SetModelIndex(uint32 id);
+ void ProcessControl(void);
+ void PreRender(void);
+ void Render(void);
+ bool SetupLighting(void);
+ void RemoveLighting(bool reset);
+
+
+ void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); }
+ void ProcessControl_(void) { CCutsceneObject::ProcessControl(); }
+ void PreRender_(void) { CCutsceneObject::PreRender(); }
+ void Render_(void) { CCutsceneObject::Render(); }
+ bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); }
+ void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); }
};
static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error");
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index c4a5c467..73a2c668 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -82,7 +82,7 @@ public:
uint32 m_flagD10 : 1;
uint32 bDrawLast : 1;
uint32 m_flagD40 : 1;
- uint32 m_flagD80 : 1;
+ uint32 m_flagD80 : 1; // CObject visibility?
// flagsE
uint32 bDistanceFade : 1;
diff --git a/src/entities/Object.cpp b/src/entities/Object.cpp
index 8ce1250f..2b068d49 100644
--- a/src/entities/Object.cpp
+++ b/src/entities/Object.cpp
@@ -1,9 +1,68 @@
#include "common.h"
#include "patcher.h"
-#include "Object.h"
#include "Pools.h"
+#include "Radar.h"
+#include "Object.h"
+
+WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); }
+
+int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2;
void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); }
void CObject::operator delete(void *p, size_t sz) { CPools::GetObjectPool()->Delete((CObject*)p); }
-WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); }
+CObject::CObject(void)
+{
+ m_type = ENTITY_TYPE_OBJECT;
+ m_fUprootLimit = 0.0f;
+ m_nCollisionDamageEffect = 0;
+ m_bSpecialCollisionResponseCases = 0;
+ m_bCameraToAvoidThisObject = 0;
+ ObjectCreatedBy = 0;
+ m_nEndOfLifeTime = 0;
+// m_nRefModelIndex = -1; // duplicate
+// bUseVehicleColours = false; // duplicate
+ m_colour2 = 0;
+ m_colour1 = m_colour2;
+ field_172 = 0;
+ m_obj_flag1 = false;
+ m_obj_flag2 = false;
+ m_obj_flag4 = false;
+ m_obj_flag8 = false;
+ m_obj_flag10 = false;
+ bHasBeenDamaged = false;
+ m_nRefModelIndex = -1;
+ bUseVehicleColours = false;
+ m_pCurSurface = nil;
+ m_pCollidingEntity = nil;
+}
+
+CObject::~CObject(void)
+{
+ CRadar::ClearBlipForEntity(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(this));
+
+ if(m_nRefModelIndex != -1)
+ CModelInfo::GetModelInfo(m_nRefModelIndex)->RemoveRef();
+
+ if(ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0)
+ nNoTempObjects--;
+}
+
+void
+CObject::Render(void)
+{
+ if(m_flagD80)
+ return;
+
+ if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nRefModelIndex);
+ assert(mi->m_type == MITYPE_VEHICLE);
+ mi->SetVehicleColour(m_colour1, m_colour2);
+ }
+
+ CEntity::Render();
+}
+
+STARTPATCHES
+ InjectHook(0x4BB1E0, &CObject::Render_, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/entities/Object.h b/src/entities/Object.h
index d71b155e..c9800e20 100644
--- a/src/entities/Object.h
+++ b/src/entities/Object.h
@@ -6,6 +6,7 @@ enum {
GAME_OBJECT = 1,
MISSION_OBJECT = 2,
TEMP_OBJECT = 3,
+ CUTSCENE_OBJECT = 4,
};
class CVehicle;
@@ -22,7 +23,7 @@ public:
int8 m_obj_flag8 : 1;
int8 m_obj_flag10 : 1;
int8 bHasBeenDamaged : 1;
- int8 m_obj_flag40 : 1;
+ int8 bUseVehicleColours : 1;
int8 m_obj_flag80 : 1;
int8 field_172;
int8 field_173;
@@ -43,9 +44,19 @@ public:
CEntity *m_pCollidingEntity;
int8 m_colour1, m_colour2;
+ static int16 &nNoTempObjects;
+
static void *operator new(size_t);
static void operator delete(void*, size_t);
+ CObject(void);
+ ~CObject(void);
+
+ void Render(void);
+
void ObjectDamage(float amount);
+
+
+ void Render_(void) { CObject::Render(); }
};
static_assert(sizeof(CObject) == 0x198, "CObject: error");
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 9cd36070..33e2deff 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -15,6 +15,60 @@
#include "Automobile.h"
#include "Physical.h"
+CPhysical::CPhysical(void)
+{
+ int i;
+
+ fForceMultiplier = 1.0f;
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_vecMoveSpeedAvg = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeedAvg = CVector(0.0f, 0.0f, 0.0f);
+
+ m_movingListNode = nil;
+ m_nStaticFrames = 0;
+
+ m_nCollisionRecords = 0;
+ for(i = 0; i < 6; i++)
+ m_aCollisionRecords[0] = nil;
+
+ field_EF = false;
+
+ m_nDamagePieceType = 0;
+ m_fDamageImpulse = 0.0f;
+ m_pDamageEntity = nil;
+ m_vecDamageNormal = CVector(0.0f, 0.0f, 0.0f);
+
+ bUsesCollision = true;
+ uAudioEntityId = -5;
+ unk1 = 100.0f;
+ m_vecCentreOfMass = CVector(0.0f, 0.0f, 0.0f);
+ field_EC = 0;
+
+ bIsHeavy = false;
+ bAffectedByGravity = true;
+ bInfiniteMass = false;
+ bIsInWater = false;
+ bHitByTrain = false;
+ m_phy_flagA80 = false;
+
+ m_fDistanceTravelled = 0.0f;
+ m_pedTreadable = nil;
+ m_carTreadable = nil;
+
+ m_phy_flagA10 = false;
+ m_phy_flagA20 = false;
+
+ m_nLastCollType = 0;
+}
+
+CPhysical::~CPhysical(void)
+{
+ m_entryInfoList.Flush();
+}
+
void
CPhysical::Add(void)
{
diff --git a/src/entities/Physical.h b/src/entities/Physical.h
index c6944b76..6b5bd1f6 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -62,6 +62,8 @@ public:
uint8 m_nZoneLevel;
uint8 pad[3];
+ CPhysical(void);
+ ~CPhysical(void);
// from CEntity
void Add(void);
diff --git a/src/main.cpp b/src/main.cpp
index 87cf586c..9b8fc145 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,6 +56,7 @@
uint8 work_buff[55000];
+char gString[256];
bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index cc15da09..10255af1 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -16,26 +16,26 @@ public:
m_hasRwMatrix = false;
*this = m;
}
- CMatrix(RwMatrix *matrix, bool attach){
+ CMatrix(RwMatrix *matrix, bool owner = false){
m_attachment = nil;
- Attach(matrix, attach);
+ Attach(matrix, owner);
}
~CMatrix(void){
if(m_hasRwMatrix && m_attachment)
RwMatrixDestroy(m_attachment);
}
- void Attach(RwMatrix *matrix, bool attach){
+ void Attach(RwMatrix *matrix, bool owner = false){
if(m_hasRwMatrix && m_attachment)
RwMatrixDestroy(m_attachment);
m_attachment = matrix;
- m_hasRwMatrix = attach;
+ m_hasRwMatrix = owner;
Update();
}
- void AttachRW(RwMatrix *matrix, bool attach){
+ void AttachRW(RwMatrix *matrix, bool owner = false){
if(m_hasRwMatrix && m_attachment)
RwMatrixDestroy(m_attachment);
m_attachment = matrix;
- m_hasRwMatrix = attach;
+ m_hasRwMatrix = owner;
UpdateRW();
}
void Detach(void){
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index 8b188345..bbf1a58b 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -264,3 +264,9 @@ IsBoatModel(int16 id)
id == MI_SPEEDER ||
id == MI_GHOST;
}
+
+inline bool
+IsPedModel(int16 id)
+{
+ return id >= 0 && id <= 89;
+}
diff --git a/src/re3.cpp b/src/re3.cpp
index 55ce5699..905aa992 100644
--- a/src/re3.cpp
+++ b/src/re3.cpp
@@ -47,17 +47,6 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
-// platform stuff
-char*
-GetUserDirectory(void)
-{
- static char path[MAX_PATH];
- strcpy(path, "userfiles");
- mkdir(path);
- return path;
-}
-
-
int (*open_script_orig)(const char *path, const char *mode);
int
open_script(const char *path, const char *mode)
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index c2b341dc..5a27ab32 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -16,6 +16,7 @@
#include "ModelIndices.h"
#include "Streaming.h"
#include "Shadows.h"
+#include "PointLights.h"
#include "Renderer.h"
bool gbShowPedRoadGroups;
@@ -1153,6 +1154,16 @@ CRenderer::IsVehicleCullZoneVisible(CEntity *ent)
return true;
}
+void
+CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset)
+{
+ if(ent->bRenderScorched)
+ WorldReplaceScorchedLightsWithNormal(Scene.world);
+ CPointLights::RemoveLightsAffectingObject();
+ if(reset)
+ ReSetAmbientAndDirectionalColours();
+}
+
STARTPATCHES
InjectHook(0x4A7680, CRenderer::Init, PATCH_JUMP);
@@ -1185,4 +1196,6 @@ STARTPATCHES
InjectHook(0x4A9840, CRenderer::ShouldModelBeStreamed, PATCH_JUMP);
InjectHook(0x4AAA00, CRenderer::IsEntityCullZoneVisible, PATCH_JUMP);
InjectHook(0x4AAAA0, CRenderer::IsVehicleCullZoneVisible, PATCH_JUMP);
+
+ InjectHook(0x4A7CF0, CRenderer::RemoveVehiclePedLights, PATCH_JUMP);
ENDPATCHES
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 38f2b6f7..e9e056c6 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -56,4 +56,6 @@ public:
static bool ShouldModelBeStreamed(CEntity *ent);
static bool IsEntityCullZoneVisible(CEntity *ent);
static bool IsVehicleCullZoneVisible(CEntity *ent);
+
+ static void RemoveVehiclePedLights(CEntity *ent, bool reset);
};
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index 498df6e9..d89338c1 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -6,4 +6,5 @@ WRAPPER void CShadows::AddPermanentShadow(unsigned char ShadowType, RwTexture* p
WRAPPER void CShadows::RenderStaticShadows(void) { EAXJMP(0x5145F0); }
WRAPPER void CShadows::RenderStoredShadows(void) { EAXJMP(0x514010); }
WRAPPER void CShadows::RenderExtraPlayerShadows(void) { EAXJMP(0x516F90); }
-WRAPPER void CShadows::CalcPedShadowValues(CVector light, float *frontX, float *frontY, float *sideX, float *sideY, float *dispX, float *dispY) { EAXJMP(0x516EB0); } \ No newline at end of file
+WRAPPER void CShadows::CalcPedShadowValues(CVector light, float *frontX, float *frontY, float *sideX, float *sideY, float *dispX, float *dispY) { EAXJMP(0x516EB0); }
+WRAPPER void CShadows::StoreShadowForPedObject(CEntity *ent, float dispX, float dispY, float frontX, float frontY, float sideX, float sideY) { EAXJMP(0x513CB0); }
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 1efe6507..be3ec0c4 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -1,6 +1,7 @@
#pragma once
struct RwTexture;
+class CEntity;
class CShadows
{
@@ -10,4 +11,5 @@ public:
static void RenderStoredShadows(void);
static void RenderExtraPlayerShadows(void);
static void CalcPedShadowValues(CVector light, float *frontX, float *frontY, float *sideX, float *sideY, float *dispX, float *dispY);
+ static void StoreShadowForPedObject(CEntity *ent, float dispX, float dispY, float frontX, float frontY, float sideX, float sideY);
};
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index fd5900b8..3dc1d989 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -145,7 +145,7 @@ CSprite2d::Draw(const CRect &rect, const CRGBA &c0, const CRGBA &c1, const CRGBA
void
CSprite2d::Draw(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &col)
{
- SetVertices(x1, y2, x2, y2, x3, y3, x4, y4, col, col, col, col);
+ SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, col, col, col, col);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 627bdb0f..81fe109b 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -191,6 +191,7 @@ void _psCreateFolder(LPCSTR path)
*/
const char *_psGetUserFilesFolder()
{
+#ifdef USE_MY_DOCUMENTS
HKEY hKey = NULL;
static CHAR szUserFiles[256];
@@ -221,6 +222,12 @@ const char *_psGetUserFilesFolder()
strcpy(szUserFiles, "data");
return szUserFiles;
+#else
+ static CHAR szUserFiles[256];
+ strcpy(szUserFiles, "userfiles");
+ _psCreateFolder(szUserFiles);
+ return szUserFiles;
+#endif
}
/*