diff options
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 } /* |