the great reorganization

This commit is contained in:
aap
2019-07-07 13:09:11 +02:00
parent 219a65b81a
commit 53023eb65b
150 changed files with 45 additions and 37 deletions

View File

@ -0,0 +1,118 @@
#include "common.h"
#include <rpskin.h>
#include "patcher.h"
#include "main.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

View File

@ -0,0 +1,24 @@
#pragma once
#include "CutsceneObject.h"
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");

View File

@ -0,0 +1,100 @@
#include "common.h"
#include "patcher.h"
#include "main.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;
bStreamingDontDelete = 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(!bHasBlip && lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}
}
return false;
}
void
CCutsceneObject::RemoveLighting(bool reset)
{
CRenderer::RemoveVehiclePedLights(this, reset);
}
STARTPATCHES
InjectHook(0x4BA960, &CCutsceneObject::dtor, PATCH_JUMP);
InjectHook(0x4BA980, &CCutsceneObject::SetModelIndex_, PATCH_JUMP);
InjectHook(0x4BA9C0, &CCutsceneObject::ProcessControl_, PATCH_JUMP);
InjectHook(0x4BAA40, &CCutsceneObject::PreRender_, PATCH_JUMP);
InjectHook(0x4BAAA0, &CCutsceneObject::Render_, PATCH_JUMP);
InjectHook(0x4A7E70, &CCutsceneObject::SetupLighting_, PATCH_JUMP);
InjectHook(0x4A7F00, &CCutsceneObject::RemoveLighting_, PATCH_JUMP);
ENDPATCHES

View File

@ -0,0 +1,25 @@
#pragma once
#include "Object.h"
class CCutsceneObject : public CObject
{
public:
CCutsceneObject(void);
virtual void SetModelIndex(uint32 id);
virtual void ProcessControl(void);
virtual void PreRender(void);
virtual void Render(void);
virtual bool SetupLighting(void);
virtual void RemoveLighting(bool reset);
void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); }
void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); }
void ProcessControl_(void) { CCutsceneObject::ProcessControl(); }
void PreRender_(void) { CCutsceneObject::PreRender(); }
void Render_(void) { CCutsceneObject::Render(); }
bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); }
void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); }
};
static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error");

View File

@ -0,0 +1,17 @@
#include "common.h"
#include "patcher.h"
#include "DummyObject.h"
#include "Pools.h"
CDummyObject::CDummyObject(CObject *obj)
{
SetModelIndexNoCreate(obj->GetModelIndex());
if(obj->m_rwObject)
AttachToRwObject(obj->m_rwObject);
obj->DetachFromRwObject();
m_level = obj->m_level;
}
STARTPATCHES
InjectHook(0x4BAB70, &CDummyObject::dtor, PATCH_JUMP);
ENDPATCHES

14
src/objects/DummyObject.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Dummy.h"
class CObject;
class CDummyObject : public CDummy
{
public:
CDummyObject(void) {}
CDummyObject(CObject *obj);
void dtor(void) { this->CDummyObject::~CDummyObject(); }
};
static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");

93
src/objects/Object.cpp Normal file
View File

@ -0,0 +1,93 @@
#include "common.h"
#include "patcher.h"
#include "main.h"
#include "Lights.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); }
CObject::CObject(void)
{
m_type = ENTITY_TYPE_OBJECT;
m_fUprootLimit = 0.0f;
m_nCollisionDamageEffect = 0;
m_nSpecialCollisionResponseCases = COLLRESPONSE_NONE;
m_bCameraToAvoidThisObject = false;
ObjectCreatedBy = 0;
m_nEndOfLifeTime = 0;
// m_nRefModelIndex = -1; // duplicate
// bUseVehicleColours = false; // duplicate
m_colour2 = 0;
m_colour1 = m_colour2;
field_172 = 0;
bIsPickup = 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();
}
bool
CObject::SetupLighting(void)
{
DeActivateDirectional();
SetAmbientColours();
if(bRenderScorched){
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
return true;
}
return false;
}
void
CObject::RemoveLighting(bool reset)
{
if(reset)
WorldReplaceScorchedLightsWithNormal(Scene.world);
}
WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
STARTPATCHES
InjectHook(0x4BAE00, &CObject::dtor, PATCH_JUMP);
InjectHook(0x4BB1E0, &CObject::Render_, PATCH_JUMP);
ENDPATCHES

81
src/objects/Object.h Normal file
View File

@ -0,0 +1,81 @@
#pragma once
#include "Physical.h"
enum {
GAME_OBJECT = 1,
MISSION_OBJECT = 2,
TEMP_OBJECT = 3,
CUTSCENE_OBJECT = 4,
};
enum {
COLLRESPONSE_NONE,
COLLRESPONSE_CHANGE_MODEL,
COLLRESPONSE_SPLIT_MODEL,
COLLRESPONSE_SMASH_COMPLETELY,
COLLRESPONSE_CHANGE_THEN_SMASH,
COLLRESPONSE_UNKNOWN5,
COLLRESPONSE_SMASH_CARDBOARD_COMPLETELY = 50,
COLLRESPONSE_SMASH_WOODENBOX_COMPLETELY = 60,
COLLRESPONSE_SMASH_TRAFFICCONE_COMPLETELY = 70,
COLLRESPONSE_SMASH_BARPOST_COMPLETELY = 80,
};
class CVehicle;
class CObject : public CPhysical
{
public:
CMatrix m_objectMatrix;
float m_fUprootLimit;
int8 ObjectCreatedBy;
int8 bIsPickup : 1;
int8 m_obj_flag2 : 1;
int8 m_obj_flag4 : 1;
int8 m_obj_flag8 : 1;
int8 m_obj_flag10 : 1;
int8 bHasBeenDamaged : 1;
int8 bUseVehicleColours : 1;
int8 m_obj_flag80 : 1;
int8 field_172;
int8 field_173;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
int8 field_17B;
int8 field_17C;
int8 field_17D;
int8 field_17E;
int8 field_17F;
int32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
int8 field_186;
int8 field_187;
CEntity *m_pCurSurface;
CEntity *m_pCollidingEntity;
int8 m_colour1, m_colour2;
static int16 &nNoTempObjects;
static void *operator new(size_t);
static void operator delete(void*, size_t);
CObject(void);
~CObject(void);
void Render(void);
bool SetupLighting(void);
void RemoveLighting(bool reset);
void ObjectDamage(float amount);
static void DeleteAllTempObjectInArea(CVector, float);
void dtor(void) { this->CObject::~CObject(); }
void Render_(void) { CObject::Render(); }
};
static_assert(sizeof(CObject) == 0x198, "CObject: error");

103
src/objects/ObjectData.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "common.h"
#include "patcher.h"
#include "main.h"
#include "ModelInfo.h"
#include "Object.h"
#include "FileMgr.h"
#include "ObjectData.h"
CObjectInfo CObjectData::ms_aObjectInfo[NUMOBJECTINFO];
// Another ugly file reader
void
CObjectData::Initialise(const char *filename)
{
char *p, *lp;
char line[1024], name[256];
int id;
float percentSubmerged;
int damageEffect, responseCase, camAvoid;
CBaseModelInfo *mi;
CFileMgr::SetDir("");
CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r");
id = 0;
p = (char*)work_buff;
while(*p != '*'){
// skip over white space and comments
while(*p == ' ' || *p == '\n' || *p == '\r' || *p == ';')
if(*p == ';')
while(*p != '\n' && *p != '*')
p++;
else
p++;
if(*p == '*')
break;
// read one line
lp = line;
while(*p != '\n' && *p != '*'){
*lp++ = *p == ',' ? ' ' : *p;
p++;
}
if(*p == '\n')
p++;
*lp = '\0'; // FIX: game wrote '\n' here
assert(id < NUMOBJECTINFO);
sscanf(line, "%s %f %f %f %f %f %f %f %d %d %d", name,
&ms_aObjectInfo[id].m_fMass,
&ms_aObjectInfo[id].m_fTurnMass,
&ms_aObjectInfo[id].m_fAirResistance,
&ms_aObjectInfo[id].m_fElasticity,
&percentSubmerged,
&ms_aObjectInfo[id].m_fUprootLimit,
&ms_aObjectInfo[id].m_fCollisionDamageMultiplier,
&damageEffect, &responseCase, &camAvoid);
ms_aObjectInfo[id].m_fBuoyancy = 100.0f/percentSubmerged * 0.008*ms_aObjectInfo[id].m_fMass;
ms_aObjectInfo[id].m_nCollisionDamageEffect = damageEffect;
ms_aObjectInfo[id].m_nSpecialCollisionResponseCases = responseCase;
ms_aObjectInfo[id].m_bCameraToAvoidThisObject = camAvoid;
mi = CModelInfo::GetModelInfo(name, nil);
if(mi)
mi->SetObjectID(id++);
else
debug("CObjectData: Cannot find object %s\n", name);
}
}
void
CObjectData::SetObjectData(int32 modelId, CObject &object)
{
CObjectInfo *objinfo;
if(CModelInfo::GetModelInfo(modelId)->GetObjectID() == -1)
return;
objinfo = &ms_aObjectInfo[CModelInfo::GetModelInfo(modelId)->GetObjectID()];
object.m_fMass = objinfo->m_fMass;
object.m_fTurnMass = objinfo->m_fTurnMass;
object.m_fAirResistance = objinfo->m_fAirResistance;
object.m_fElasticity = objinfo->m_fElasticity;
object.m_fBuoyancy = objinfo->m_fBuoyancy;
object.m_fUprootLimit = objinfo->m_fUprootLimit;
object.m_fCollisionDamageMultiplier = objinfo->m_fCollisionDamageMultiplier;
object.m_nCollisionDamageEffect = objinfo->m_nCollisionDamageEffect;
object.m_nSpecialCollisionResponseCases = objinfo->m_nSpecialCollisionResponseCases;
object.m_bCameraToAvoidThisObject = objinfo->m_bCameraToAvoidThisObject;
if(object.m_fMass >= 99998.0){
object.bInfiniteMass = true;
object.bAffectedByGravity = false;
object.m_flagB2 = true;
}
}
STARTPATCHES
InjectHook(0x4BC0E0, CObjectData::Initialise, PATCH_JUMP);
InjectHook(0x4BC270, CObjectData::SetObjectData, PATCH_JUMP);
ENDPATCHES

27
src/objects/ObjectData.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
class CObject;
class CObjectInfo
{
public:
float m_fMass;
float m_fTurnMass;
float m_fAirResistance;
float m_fElasticity;
float m_fBuoyancy;
float m_fUprootLimit;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
};
static_assert(sizeof(CObjectInfo) == 0x20, "CObjectInfo: error");
class CObjectData
{
static CObjectInfo ms_aObjectInfo[NUMOBJECTINFO];
public:
static void Initialise(const char *filename);
static void SetObjectData(int32 modelId, CObject &object);
};

View File

@ -0,0 +1,23 @@
#include "common.h"
#include "patcher.h"
#include "ParticleObject.h"
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, bool remove) { EAXJMP(0x4BC4D0); }
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, float size, bool remove) { EAXJMP(0x4BC520); }
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove) { EAXJMP(0x4BC570); }
// Converted from static void __cdecl CParticleObject::Initialise() 0x42C760
void CParticleObject::Initialise()
{
((void (__cdecl *)())0x4BC440)();
}
// Converted from static void __cdecl CParticleObject::UpdateAll() 0x4BCA30
void CParticleObject::UpdateAll()
{
((void (__cdecl *)())0x4BCA30)();
}
STARTPATCHES
InjectHook(0x4BC420, &CParticleObject::dtor, PATCH_JUMP);
ENDPATCHES

View File

@ -0,0 +1,39 @@
#pragma once
#include "Placeable.h"
enum eParticleObjectType
{
POBJECT_PAVEMENT_STEAM,
POBJECT_PAVEMENT_STEAM_SLOWMOTION,
POBJECT_WALL_STEAM,
POBJECT_WALL_STEAM_SLOWMOTION,
POBJECT_DARK_SMOKE,
POBJECT_FIRE_HYDRANT,
POBJECT_CAR_WATER_SPLASH,
POBJECT_PED_WATER_SPLASH,
POBJECT_SPLASHES_AROUND,
POBJECT_SMALL_FIRE,
POBJECT_BIG_FIRE,
POBJECT_DRY_ICE,
POBJECT_DRY_ICE_SLOWMOTION,
POBJECT_FIRE_TRAIL,
POBJECT_SMOKE_TRAIL,
POBJECT_FIREBALL_AND_SMOKE,
POBJECT_ROCKET_TRAIL,
POBJECT_EXPLOSION_ONCE,
POBJECT_CATALINAS_GUNFLASH,
POBJECT_CATALINAS_SHOTGUNFLASH,
};
class CParticleObject : CPlaceable
{
public:
static void AddObject(uint16 type, const CVector &pos, bool remove);
static void AddObject(uint16 type, const CVector &pos, float size, bool remove);
static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove);
static void Initialise();
static void UpdateAll();
void dtor() { this->CParticleObject::~CParticleObject(); }
};

View File

@ -0,0 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "Projectile.h"
STARTPATCHES
InjectHook(0x4BFED0, &CProjectile::dtor, PATCH_JUMP);
ENDPATCHES

11
src/objects/Projectile.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#pragma once
#include "Object.h"
class CProjectile : public CObject
{
public:
void dtor(void) { this->CProjectile::~CProjectile(); }
};