Merge pull request #984 from aap/lcs

modelinfos
This commit is contained in:
aap 2021-01-25 10:30:34 +01:00 committed by GitHub
commit d6544933aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1181 additions and 193 deletions

View File

@ -204,3 +204,10 @@ CColModel::operator=(const CColModel &other)
}
return *this;
}
bool
CColModel::Write(base::cRelocatableChunkWriter &writer, bool allocSpace)
{
assert(0 && "TODO(LCS)");
return 1;
}

View File

@ -36,4 +36,6 @@ struct CColModel
void *operator new(size_t);
void operator delete(void *p, size_t);
CColModel& operator=(const CColModel& other);
bool Write(base::cRelocatableChunkWriter &writer, bool allocSpace);
};

View File

@ -1,11 +1,12 @@
#include "common.h"
#include "main.h"
#include "TempColModels.h"
#include "Game.h"
CColModel CTempColModels::ms_colModelPed1;
// LCS: haven't yet checked the numbers but they probably haven't changed
CColModel CTempColModels::ms_colModelPed2;
CColModel CTempColModels::ms_colModelBBox;
CColModel CTempColModels::ms_colModelBumper1;
CColModel CTempColModels::ms_colModelWheel1;
CColModel CTempColModels::ms_colModelPanel1;
@ -16,7 +17,9 @@ CColModel CTempColModels::ms_colModelPedGroundHit;
CColModel CTempColModels::ms_colModelBoot1;
CColModel CTempColModels::ms_colModelDoor1;
CColModel CTempColModels::ms_colModelBonnet1;
CColModel CTempColModels::ms_colModelWeapon;
CColModel CTempColModels::ms_colModelFerryDocked;
CTempColModels *gpTempColModels;
CColSphere s_aPedSpheres[3];
@ -34,6 +37,7 @@ CColSphere s_aBootSpheres[4];
CColSphere s_aWheelSpheres[2];
CColSphere s_aBodyPartSpheres1[2];
CColSphere s_aBodyPartSpheres2[2];
CColBox S_aFerryDockedBoxes[1];
void
CTempColModels::Initialise(void)
@ -44,11 +48,26 @@ CTempColModels::Initialise(void)
colmodel.level = LEVEL_GENERIC;\
colmodel.ownsCollisionVolumes = false;
int i;
if(gMakeResources){
if(gpTempColModels == nil){
gpTempColModels = new CTempColModels;
gpTempColModels->Initialise();
return;
}
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelBBox.level = LEVEL_GENERIC;
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelBBox.level = LEVEL_GENERIC;
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25f, -0.25f), CVector(0.25f, 0.25f, 0.25f));
}
int i;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
@ -74,10 +93,6 @@ CTempColModels::Initialise(void)
s_aPedSpheres[i].piece = 0;
}
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
// Ped 2 Spheres
s_aPed2Spheres[0].radius = 0.3f;
@ -294,13 +309,47 @@ CTempColModels::Initialise(void)
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
ms_colModelWeapon.boundingSphere.radius = 0.25f;
ms_colModelWeapon.boundingBox.min.x = -0.25f;
ms_colModelWeapon.boundingBox.min.y = -0.25f;
ms_colModelWeapon.boundingBox.min.z = -0.25f;
ms_colModelWeapon.boundingBox.max.x = 0.25f;
ms_colModelWeapon.boundingBox.max.y = 0.25f;
ms_colModelWeapon.boundingBox.max.z = 0.25f;
// Ferry Docked
S_aFerryDockedBoxes[0].Set(CVector(-6.3f, -22.78f, -2.0f), CVector(6.3f, 22.78f, 2.8f), SURFACE_THICK_METAL_PLATE, SURFACE_DEFAULT);
ms_colModelFerryDocked.boundingSphere.Set(35.0f, CVector(0.0f, -0.0f, 0.0f));
ms_colModelFerryDocked.boundingBox.Set(S_aFerryDockedBoxes[0].min, S_aFerryDockedBoxes[0].max);
ms_colModelFerryDocked.spheres = nil;
ms_colModelFerryDocked.numSpheres = 0;
ms_colModelFerryDocked.boxes = S_aFerryDockedBoxes;
ms_colModelFerryDocked.numBoxes = ARRAY_SIZE(S_aFerryDockedBoxes);
ms_colModelFerryDocked.level = LEVEL_GENERIC;
#undef SET_COLMODEL_SPHERES
}
void
CTempColModels::Write(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
ms_colModelBBox.Write(writer, false);
writer.AddPatch(&ms_colModelBBox);
ms_colModelPed1.Write(writer, false);
writer.AddPatch(&ms_colModelPed1);
ms_colModelWeapon.Write(writer, false);
writer.AddPatch(&ms_colModelWeapon);
for(int i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++)
ms_colModelCutObj[i].Write(writer, true);
ms_colModelPed2.Write(writer, true);
ms_colModelPedGroundHit.Write(writer, true);
ms_colModelDoor1.Write(writer, true);
ms_colModelBumper1.Write(writer, true);
ms_colModelPanel1.Write(writer, true);
ms_colModelBonnet1.Write(writer, true);
ms_colModelBoot1.Write(writer, true);
ms_colModelWheel1.Write(writer, true);
ms_colModelBodyPart1.Write(writer, true);
ms_colModelBodyPart2.Write(writer, true);
ms_colModelFerryDocked.Write(writer, true);
}

View File

@ -5,9 +5,11 @@
class CTempColModels
{
public:
static CColModel ms_colModelPed1;
CColModel ms_colModelPed1;
CColModel ms_colModelBBox;
CColModel ms_colModelWeapon;
static CColModel ms_colModelPed2;
static CColModel ms_colModelBBox;
static CColModel ms_colModelBumper1;
static CColModel ms_colModelWheel1;
static CColModel ms_colModelPanel1;
@ -18,7 +20,10 @@ public:
static CColModel ms_colModelBoot1;
static CColModel ms_colModelDoor1;
static CColModel ms_colModelBonnet1;
static CColModel ms_colModelWeapon;
static CColModel ms_colModelFerryDocked;
static void Initialise(void);
void Initialise(void);
void Write(base::cRelocatableChunkWriter &writer);
};
extern CTempColModels *gpTempColModels;

View File

@ -502,7 +502,7 @@ void CGarage::Update()
pos.x = CGeneral::GetRandomNumberInRange(m_fInfX + 0.5f, m_fSupX - 0.5f);
pos.y = CGeneral::GetRandomNumberInRange(m_fInfY + 0.5f, m_fSupY - 0.5f);
pos.z = CGeneral::GetRandomNumberInRange(m_fDoor1Z - 3.0f, m_fDoor1Z + 1.0f);
CParticle::AddParticle(PARTICLE_GARAGEPAINT_SPRAY, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, CVehicleModelInfo::ms_vehicleColourTable[colour1]);
CParticle::AddParticle(PARTICLE_GARAGEPAINT_SPRAY, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, CVehicleModelInfo::mspInfo->ms_vehicleColourTable[colour1]);
}
}
}

View File

@ -81,7 +81,7 @@ CAnimViewer::Initialise(void) {
CCollision::Init();
CWorld::Initialise();
mod_HandlingManager.Initialise();
CTempColModels::Initialise();
gpTempColModels->Initialise();
CAnimManager::Initialise();
CModelInfo::Initialise();
CParticle::Initialise();

View File

@ -607,11 +607,14 @@ CFileLoader::LoadObjectTypes(const char *filename)
int section;
int pathIndex;
int id, pathType;
int minID, maxID;
//int minID, maxID;
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
m_sTempIdeData[i].id = -1;
section = NONE;
minID = INT32_MAX;
maxID = -1;
//minID = INT32_MAX;
//maxID = -1;
pathIndex = -1;
debug("Loading object types from %s...\n", filename);
@ -635,13 +638,13 @@ CFileLoader::LoadObjectTypes(const char *filename)
}else switch(section){
case OBJS:
id = LoadObject(line);
if(id > maxID) maxID = id;
if(id < minID) minID = id;
//if(id > maxID) maxID = id;
//if(id < minID) minID = id;
break;
case TOBJ:
id = LoadTimeObject(line);
if(id > maxID) maxID = id;
if(id < minID) minID = id;
//if(id > maxID) maxID = id;
//if(id < minID) minID = id;
break;
case WEAP:
LoadWeaponObject(line);
@ -678,10 +681,10 @@ CFileLoader::LoadObjectTypes(const char *filename)
}
CFileMgr::CloseFile(fd);
for(id = minID; id <= maxID; id++){
for(id = 0; id < MODELINFOSIZE; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi && mi->IsBuilding())
mi->SetupBigBuilding(minID, maxID);
mi->SetupBigBuilding();
}
}
@ -714,6 +717,13 @@ CFileLoader::LoadObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
if(m_sTempIdeData[i].id == -1){
m_sTempIdeData[i].id = id;
strcpy(m_sTempIdeData[i].name, model);
break;
}
switch(numObjs){
case 1:
sscanf(line, "%d %s %s %d %f %d",
@ -762,6 +772,13 @@ CFileLoader::LoadTimeObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
if(m_sTempIdeData[i].id < 0){
m_sTempIdeData[i].id = id;
strcpy(m_sTempIdeData[i].name, model);
break;
}
switch(numObjs){
case 1:
sscanf(line, "%d %s %s %d %f %d %d %d",
@ -792,7 +809,7 @@ CFileLoader::LoadTimeObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTimes(timeOn, timeOff);
mi->SetTexDictionary(txd);
other = mi->FindOtherTimeModel();
other = mi->FindOtherTimeModel(model);
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
@ -816,7 +833,7 @@ CFileLoader::LoadWeaponObject(const char *line)
mi->m_lodDistances[0] = dist;
mi->SetTexDictionary(txd);
mi->SetAnimFile(animFile);
mi->SetColModel(&CTempColModels::ms_colModelWeapon);
mi->SetColModel(&gpTempColModels->ms_colModelWeapon);
MatchModelString(model, id);
return id;
}
@ -832,7 +849,7 @@ CFileLoader::LoadClumpObject(const char *line)
mi = CModelInfo::AddClumpModel(id);
mi->SetModelName(model);
mi->SetTexDictionary(txd);
mi->SetColModel(&CTempColModels::ms_colModelBBox);
mi->SetColModel(&gpTempColModels->ms_colModelBBox);
}
}
@ -939,7 +956,7 @@ CFileLoader::LoadPedObject(const char *line)
mi->SetModelName(model);
mi->SetTexDictionary(txd);
mi->SetAnimFile(animFile);
mi->SetColModel(&CTempColModels::ms_colModelPed1);
mi->SetColModel(&gpTempColModels->ms_colModelPed1);
mi->m_pedType = CPedType::FindPedType(pedType);
mi->m_pedStatType = CPedStats::GetPedStatType(pedStats);
for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++)

View File

@ -316,7 +316,7 @@ bool CGame::InitialiseOnceAfterRW(void)
{
TheText.Load();
CTimer::Initialise();
CTempColModels::Initialise();
gpTempColModels->Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
@ -366,6 +366,9 @@ bool CGame::Initialise(const char* datFile)
CPools::Initialise();
if(gMakeResources)
CVehicleModelInfo::Load(nil);
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#endif

14
src/core/Leeds.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "common.h"
#include "Leeds.h"
void LoadResource(RpAtomic *atomic) {}
void LoadResource(RpClump *clump) {}
void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer) {}

36
src/core/Leeds.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
/*
PatchElementModelInfo(RslElement *,void *)
ChunkName(char const*)
DestroyAndFreeResourceImage(void)
WriteOrder(char const*)
UnpatchTextures(void)
IsChunked(int)
SaveResourceImage(void)
LoadResourceImage(void)
SaveResource(RslNode *,base::cRelocatableChunkWriter &)
SaveResource(RslTAnimTree *,base::cRelocatableChunkWriter &)
SaveResource(RslSkin *,base::cRelocatableChunkWriter &)
SaveResource(CAnimBlendTree *,base::cRelocatableChunkWriter &)
PatchElementTextures(RslElement *)
PatchElementGroupTextures(RslElementGroup *)
*/
void LoadResource(RpAtomic *atomic);
void LoadResource(RpClump *clump);
/*
cRelocatableChunkWriterGTA::Save(char const*,uint,uint,bool)
cRelocatableChunkGTA::cRelocatableChunkGTA(char const*,uint,uint,bool)
SaveAnimBlock(int)
SaveModel(int,bool)
*/
void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer);
void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer);
void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer);
void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer);
void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer);
void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer);
void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer);

View File

@ -85,6 +85,9 @@ wchar gUString2[256];
// leeds
bool gMakeResources = true;
bool gUseChunkFiles = false;
bool gSecondExportPass;
bool gUseModelResources;
bool gUseResources;
float FramesPerSecond = 30.0f;

View File

@ -27,6 +27,9 @@ extern bool gbPrintMemoryUsage;
// leeds
extern bool gMakeResources;
extern bool gUseChunkFiles;
extern bool gSecondExportPass;
extern bool gUseModelResources;
extern bool gUseResources;
class CSprite2d;

View File

@ -22,7 +22,8 @@
#error "Need librw for EXTENDED_PIPELINES"
#endif
extern RwTexture *gpWhiteTexture; // from vehicle model info
//extern RwTexture *gpWhiteTexture; // from vehicle model info
static RwTexture *gpWhiteTexture; // nil works as white in librw currently
namespace CustomPipes {

View File

@ -13,6 +13,7 @@
//struct RpMaterial;
typedef rw::Material RpMaterial;
typedef rw::MaterialList RpMaterialList;
typedef RpMaterial *(*RpMaterialCallBack)(RpMaterial *material, void *data);

View File

@ -19,6 +19,8 @@ namespace base
void* Shrink(void* data);
};
#define VTABLE_ADDR(obj) ((void*)obj) // TODO: make this portable
class cRelocatableChunkClassInfo
{
public:

View File

@ -7,6 +7,9 @@
#include "BaseModelInfo.h"
#include "ModelInfo.h"
#include "KeyGen.h"
#include "Streaming.h"
#include "smallHeap.h"
#include "TempColModels.h"
CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
{
@ -18,7 +21,11 @@ CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
m_type = type;
m_num2dEffects = 0;
m_bOwnsColModel = false;
m_nameKey = 0;
m_unk1 = 0;
m_unk2 = 0;
m_name = new char[MAX_MODEL_NAME];
*(int32*)m_name = 0;
}
void
@ -26,6 +33,7 @@ CBaseModelInfo::Shutdown(void)
{
DeleteCollisionModel();
DeleteRwObject();
DeleteChunk();
m_2dEffectsID = -1;
m_num2dEffects = 0;
m_txdSlot = -1;
@ -34,11 +42,11 @@ CBaseModelInfo::Shutdown(void)
void
CBaseModelInfo::DeleteCollisionModel(void)
{
if(m_colModel && m_bOwnsColModel){
if(!gUseChunkFiles && m_colModel && m_bOwnsColModel){
if(m_colModel)
delete m_colModel;
m_colModel = nil;
}
m_colModel = nil;
}
void
@ -51,15 +59,17 @@ CBaseModelInfo::AddRef(void)
void
CBaseModelInfo::RemoveRef(void)
{
m_refCount--;
RemoveTexDictionaryRef();
if(m_refCount > 0){
m_refCount--;
RemoveTexDictionaryRef();
}
}
void
CBaseModelInfo::SetTexDictionary(const char *name)
{
int slot = CTxdStore::FindTxdSlot(name);
if(slot < 0)
if(slot == -1)
slot = CTxdStore::AddTxdSlot(name);
m_txdSlot = slot;
}
@ -70,12 +80,24 @@ CBaseModelInfo::AddTexDictionaryRef(void)
CTxdStore::AddRef(m_txdSlot);
}
void
CBaseModelInfo::AddTexDictionaryRefGu(void)
{
CTxdStore::AddRefGu(m_txdSlot);
}
void
CBaseModelInfo::RemoveTexDictionaryRef(void)
{
CTxdStore::RemoveRef(m_txdSlot);
}
void
CBaseModelInfo::RemoveTexDictionaryRefGu(void)
{
CTxdStore::RemoveRefGu(m_txdSlot);
}
void
CBaseModelInfo::Init2dEffects(void)
{
@ -110,4 +132,52 @@ CBaseModelInfo::SetModelName(const char *name)
m_nameKey = CKeyGen::GetUppercaseKey(name);
if (!gUseChunkFiles)
strcpy(m_name, name);
}
}
void
CBaseModelInfo::DeleteChunk(void)
{
// BUG? what if we're not using chunks?
if(m_chunk){
CStreaming::UnregisterPointer(&m_chunk, 2);
cSmallHeap::msInstance.Free(m_chunk);
m_chunk = nil;
}
}
inline int
GetColmodelID(CColModel *model)
{
int colModelid = 0;
if(model == &gpTempColModels->ms_colModelBBox) colModelid = 1;
if(model == &gpTempColModels->ms_colModelPed1) colModelid = 2;
if(model == &gpTempColModels->ms_colModelWeapon) colModelid = 3;
if(model == &CTempColModels::ms_colModelPed2) colModelid = 4;
if(model == &CTempColModels::ms_colModelPedGroundHit) colModelid = 5;
if(model == &CTempColModels::ms_colModelDoor1) colModelid = 6;
if(model == &CTempColModels::ms_colModelBumper1) colModelid = 7;
if(model == &CTempColModels::ms_colModelPanel1) colModelid = 8;
if(model == &CTempColModels::ms_colModelBonnet1) colModelid = 9;
if(model == &CTempColModels::ms_colModelBoot1) colModelid = 10;
if(model == &CTempColModels::ms_colModelWheel1) colModelid = 11;
if(model == &CTempColModels::ms_colModelBodyPart1) colModelid = 12;
if(model == &CTempColModels::ms_colModelBodyPart2) colModelid = 13;
if(model == &CTempColModels::ms_colModelCutObj[0]) colModelid = 14;
if(model == &CTempColModels::ms_colModelCutObj[1]) colModelid = 15;
if(model == &CTempColModels::ms_colModelCutObj[2]) colModelid = 16;
if(model == &CTempColModels::ms_colModelCutObj[3]) colModelid = 17;
if(model == &CTempColModels::ms_colModelCutObj[4]) colModelid = 18;
return colModelid;
}
void
CBaseModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
m_chunk = nil;
RcWriteThis(writer);
if(m_colModel){
if(m_bOwnsColModel || GetColmodelID(m_colModel) != 0)
m_colModel->Write(writer, true);
writer.AddPatch(&m_colModel);
}
}

View File

@ -2,7 +2,7 @@
struct CColModel;
#define MAX_MODEL_NAME (21)
#define MAX_MODEL_NAME (24)
enum ModelInfoType
{
@ -23,9 +23,13 @@ class C2dEffect;
class CBaseModelInfo
{
protected:
char *m_name;
uint32 m_unk1;
uint32 m_unk2;
uint32 m_nameKey;
RwObject *m_object;
union {
char *m_name; // if not using chunks
void *m_chunk; // else
};
uint8 m_type;
uint8 m_num2dEffects;
bool m_bOwnsColModel;
@ -53,6 +57,16 @@ public:
virtual void ConvertAnimFileIndex(void) {}
virtual int GetAnimFileIndex(void) { return -1; }
virtual void LoadModel(void *model, const void *chunk) = 0;
virtual void DeleteChunk(void);
// this writes the modelinfo struct, possibly including actual RW models
virtual void Write(base::cRelocatableChunkWriter &writer);
// this writes the RW models
virtual void *WriteModel(base::cRelocatableChunkWriter &writer) { return nil; } // = 0; // this is not in the vtable for some reason???
// these allocate the space for a modelinfo struct and patch the vtable pointer
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer) = 0;
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer) = 0;
// one day it becomes virtual
uint8 GetModelType() const { return m_type; }
bool IsBuilding(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
@ -74,7 +88,9 @@ public:
void RemoveRef(void);
void SetTexDictionary(const char *name);
void AddTexDictionaryRef(void);
void AddTexDictionaryRefGu(void);
void RemoveTexDictionaryRef(void);
void RemoveTexDictionaryRefGu(void);
void Init2dEffects(void);
void Add2dEffect(C2dEffect *fx);
C2dEffect *Get2dEffect(int n);

View File

@ -1,17 +1,30 @@
#include "common.h"
#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "Streaming.h"
#include "Leeds.h"
base::cRelocatableChunkClassInfo CClumpModelInfo::msClassInfo("CElementGroupModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance)); // the real name
CClumpModelInfo CClumpModelInfo::msClassInstance;
void
CClumpModelInfo::DeleteRwObject(void)
{
if(m_clump){
RpClumpDestroy(m_clump);
if(!gUseChunkFiles)
RpClumpDestroy(m_clump);
else{
CStreaming::UnregisterClump(m_clump);
CStreaming::UnregisterPointer(&m_clump, 2);
DeleteChunk();
}
m_clump = nil;
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
@ -52,6 +65,7 @@ CClumpModelInfo::CreateInstance(RwMatrix *m)
if(m_clump){
RpClump *clump = (RpClump*)CreateInstance();
*RwFrameGetMatrix(RpClumpGetFrame(clump)) = *m;
CStreaming::RegisterInstance(clump);
return (RwObject*)clump;
}
return nil;
@ -73,14 +87,15 @@ CClumpModelInfo::SetClump(RpClump *clump)
if(GetAnimFileIndex() != -1)
CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
if(IsClumpSkinned(clump)){
int i;
//int i;
RpHAnimHierarchy *hier;
RpAtomic *skinAtomic;
RpSkin *skin;
//RpAtomic *skinAtomic;
//RpSkin *skin;
hier = GetAnimHierarchyFromClump(clump);
assert(hier);
RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
/*
skinAtomic = GetFirstAtomic(clump);
assert(skinAtomic);
@ -94,6 +109,7 @@ CClumpModelInfo::SetClump(RpClump *clump)
weights->w2 /= sum;
weights->w3 /= sum;
}
*/
RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
}
}
@ -203,3 +219,47 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id)
RwFrameForAllChildren(RpClumpGetFrame(clump), FindFrameFromIdCB, &assoc);
return assoc.frame;
}
void
CClumpModelInfo::LoadModel(void *clump, const void *chunk)
{
m_chunk = (void*)chunk;
m_clump = (RpClump*)clump;
LoadResource(m_clump);
CStreaming::RegisterPointer(&m_chunk, 2, true);
CStreaming::RegisterClump(m_clump);
CStreaming::RegisterPointer(&m_clump, 2, true);
}
void
CClumpModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
CBaseModelInfo::Write(writer);
if(m_clump){
writer.AddPatch(&m_clump);
SaveResource(m_clump, writer);
}
}
void*
CClumpModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
{
if(m_clump)
SaveResource(m_clump, writer);
return m_clump;
}
void
CClumpModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CClumpModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -35,6 +35,9 @@ public:
char *m_animFileName;
};
static base::cRelocatableChunkClassInfo msClassInfo;
static CClumpModelInfo msClassInstance;
CClumpModelInfo(void) : CBaseModelInfo(MITYPE_CLUMP) { m_animFileIndex = -1; }
CClumpModelInfo(ModelInfoType id) : CBaseModelInfo(id) { m_animFileIndex = -1; }
~CClumpModelInfo() {}
@ -48,6 +51,12 @@ public:
virtual void ConvertAnimFileIndex(void);
virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
virtual void LoadModel(void *model, const void *chunk);
virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
void SetFrameIds(RwObjectNameIdAssocation *assocs);
static RwFrame *FindFrameFromNameCB(RwFrame *frame, void *data);

View File

@ -1,5 +1,6 @@
#include "common.h"
#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "Bones.h"
@ -9,12 +10,19 @@
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
#include "custompipes.h"
#include "Streaming.h"
#include "Leeds.h"
#include "TempColModels.h"
base::cRelocatableChunkClassInfo CPedModelInfo::msClassInfo("CPedModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CPedModelInfo CPedModelInfo::msClassInstance;
void
CPedModelInfo::DeleteRwObject(void)
{
CStreaming::UnregisterPointer(&m_hitColModel, 2);
CClumpModelInfo::DeleteRwObject();
if(m_hitColModel)
if(!gUseChunkFiles && m_hitColModel)
delete m_hitColModel;
m_hitColModel = nil;
}
@ -41,13 +49,15 @@ CPedModelInfo::SetClump(RpClump *clump)
#ifdef EXTENDED_PIPELINES
CustomPipes::AttachRimPipe(clump);
#endif
if(!IsClumpSkinned(clump))
return;
CClumpModelInfo::SetClump(clump);
SetFrameIds(m_pPedIds); // not needed in VC actually
if(m_hitColModel == nil)
CreateHitColModelSkinned(clump);
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
if(strcmp(GetModelName(), "player") == 0)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
//if(strcmp(GetModelName(), "player") == 0)
// RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
}
struct ColNodeInfo
@ -73,40 +83,27 @@ ColNodeInfo m_pColNodeInfos[NUMPEDINFONODES] = {
{ nil, PED_FOOTR, PEDPIECE_RIGHTLEG, 0.0f, 0.15f, 0.15f },
};
void
bool
CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
{
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
CColModel *colmodel = new CColModel;
CColSphere *spheres = (CColSphere*)RwMalloc(NUMPEDINFONODES*sizeof(CColSphere));
RwFrame *root = RpClumpGetFrame(m_clump);
RwMatrix *invmat = RwMatrixCreate();
RwMatrix *mat = RwMatrixCreate();
RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
for(int i = 0; i < NUMPEDINFONODES; i++){
*mat = *invmat;
int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode); // this is wrong, wtf R* ???
int idx = RpHAnimIDGetIndex(hier, id);
// This doesn't really work as the positions are not initialized yet
RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
RwV3d pos = { 0.0f, 0.0f, 0.0f };
RwV3dTransformPoints(&pos, &pos, 1, mat);
spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
spheres[i].center.x = 0.0f;
spheres[i].center.y = 0.0f;
spheres[i].center.z = 0.0f;
spheres[i].radius = m_pColNodeInfos[i].radius;
spheres[i].surface = SURFACE_PED;
spheres[i].piece = m_pColNodeInfos[i].pieceType;
}
RwMatrixDestroy(invmat);
RwMatrixDestroy(mat);
colmodel->spheres = spheres;
colmodel->numSpheres = NUMPEDINFONODES;
colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f));
colmodel->level = LEVEL_GENERIC;
m_hitColModel = colmodel;
return true;
}
CColModel*
@ -114,28 +111,27 @@ CPedModelInfo::AnimatePedColModelSkinned(RpClump *clump)
{
if(m_hitColModel == nil){
CreateHitColModelSkinned(clump);
#ifndef FIX_BUGS
return m_hitColModel;
#endif
// we should really animate this now
}
RwMatrix *invmat, *mat;
RwMatrix invmat, mat;
CColSphere *spheres = m_hitColModel->spheres;
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
invmat = RwMatrixCreate();
mat = RwMatrixCreate();
RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
RwMatrixInvert(&invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
for(int i = 0; i < NUMPEDINFONODES; i++){
*mat = *invmat;
mat = invmat;
int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode);
int idx = RpHAnimIDGetIndex(hier, id);
RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
RwV3d pos = { 0.0f, 0.0f, 0.0f };
RwV3dTransformPoints(&pos, &pos, 1, mat);
RwMatrixTransform(&mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
RwV3d pos = { 0.0f, 0.0f, 0.0f }; // actually CVector
RwV3dTransformPoints(&pos, &pos, 1, &mat);
spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
}
RwMatrixDestroy(invmat);
RwMatrixDestroy(mat);
return m_hitColModel;
}
@ -153,10 +149,71 @@ CPedModelInfo::AnimatePedColModelSkinnedWorld(RpClump *clump)
int idx = RpHAnimIDGetIndex(hier, id);
mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
RwV3d pos = { 0.0f, 0.0f, 0.0f };
RwV3d pos = { 0.0f, 0.0f, 0.0f }; // actually CVector
RwV3dTransformPoints(&pos, &pos, 1, mat);
spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
}
return m_hitColModel;
}
struct PedChunk
{
CColModel *colmodel;
RpClump *clump;
};
void
CPedModelInfo::LoadModel(void *data, const void *chunk)
{
PedChunk *chk = (PedChunk*)data;
m_hitColModel = chk->colmodel;
CStreaming::RegisterPointer(&m_hitColModel, 2, true);
CClumpModelInfo::LoadModel(chk->clump, chunk);
}
void
CPedModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
SetColModel(&gpTempColModels->ms_colModelPed1);
CClumpModelInfo::Write(writer);
if(m_hitColModel){
writer.AddPatch(&m_hitColModel);
m_hitColModel->Write(writer, true);
}
}
void*
CPedModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
{
PedChunk *chunk = new PedChunk; // LEAK
chunk->colmodel = nil;
chunk->clump = nil;
writer.AllocateRaw(chunk, sizeof(*chunk), sizeof(void*), false, true);
chunk->clump = (RpClump*)CClumpModelInfo::WriteModel(writer);
if(chunk->clump)
writer.AddPatch(&chunk->clump);
chunk->colmodel = m_hitColModel;
if(chunk->colmodel){
writer.AddPatch(&chunk->colmodel);
chunk->colmodel->Write(writer, true);
}
return nil;
}
void
CPedModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CPedModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -38,6 +38,8 @@ public:
CColModel *m_hitColModel;
int8 radio1, radio2;
static base::cRelocatableChunkClassInfo msClassInfo;
static CPedModelInfo msClassInstance;
static RwObjectNameIdAssocation m_pPedIds[PED_NODE_MAX];
CPedModelInfo(void) : CClumpModelInfo(MITYPE_PED) { m_hitColModel = nil; }
@ -45,7 +47,13 @@ public:
void DeleteRwObject(void);
void SetClump(RpClump *);
void CreateHitColModelSkinned(RpClump *clump);
virtual void LoadModel(void *model, const void *chunk);
virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
bool CreateHitColModelSkinned(RpClump *clump);
CColModel *GetHitColModel(void) { return m_hitColModel; }
CColModel *AnimatePedColModelSkinned(RpClump *clump);
CColModel *AnimatePedColModelSkinnedWorld(RpClump *clump);

View File

@ -1,38 +1,60 @@
#include "common.h"
#include "main.h"
#include "General.h"
#include "Renderer.h"
#include "Camera.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "custompipes.h"
#include "Streaming.h"
#include "smallHeap.h"
#include "Leeds.h"
#define LOD_DISTANCE (300.0f)
TempIdeData m_sTempIdeData[800];
base::cRelocatableChunkClassInfo CSimpleModelInfo::msClassInfo("CSimpleModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CSimpleModelInfo CSimpleModelInfo::msClassInstance;
void
CSimpleModelInfo::DeleteRwObject(void)
{
int i;
RwFrame *f;
for(i = 0; i < m_numAtomics; i++)
if(m_atomics[i]){
f = RpAtomicGetFrame(m_atomics[i]);
RpAtomicDestroy(m_atomics[i]);
RwFrameDestroy(f);
m_atomics[i] = nil;
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
if(m_atomics == nil)
return;
if(!gUseChunkFiles){
for(i = 0; i < m_numAtomics; i++)
if(m_atomics[i]){
f = RpAtomicGetFrame(m_atomics[i]);
RpAtomicDestroy(m_atomics[i]);
RwFrameDestroy(f);
m_atomics[i] = nil;
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
}else if(m_chunk){
CStreaming::UnregisterPointer(&m_atomics, 2);
for(i = 0; i < m_numAtomics; i++)
CStreaming::UnregisterAtomic(m_atomics[i], nil);
DeleteChunk();
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
m_atomics = nil;
}
RwObject*
CSimpleModelInfo::CreateInstance(void)
{
RpAtomic *atomic;
if(m_atomics[0] == nil)
if(m_atomics && m_atomics[0] == nil)
return nil;
atomic = RpAtomicClone(m_atomics[0]);
RpAtomicSetFrame(atomic, RwFrameCreate());
CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic;
}
@ -42,21 +64,20 @@ CSimpleModelInfo::CreateInstance(RwMatrix *matrix)
RpAtomic *atomic;
RwFrame *frame;
if(m_atomics[0] == nil)
if(m_atomics && m_atomics[0] == nil)
return nil;
atomic = RpAtomicClone(m_atomics[0]);
frame = RwFrameCreate();
*RwFrameGetMatrix(frame) = *matrix;
RpAtomicSetFrame(atomic, frame);
CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic;
}
void
CSimpleModelInfo::Init(void)
{
m_atomics[0] = nil;
m_atomics[1] = nil;
m_atomics[2] = nil;
m_atomics = new RpAtomic*[3];
m_numAtomics = 0;
m_firstDamaged = 0;
m_wetRoadReflection = 0;
@ -72,21 +93,30 @@ CSimpleModelInfo::Init(void)
m_ignoreDrawDist = 0;
m_isCodeGlass = 0;
m_isArtistGlass = 0;
m_relatedModel = nil;
}
void
CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic)
{
AddTexDictionaryRef();
if(m_atomics == nil){
m_atomics = new RpAtomic*[3];
m_atomics[0] = nil;
m_atomics[1] = nil;
m_atomics[2] = nil;
}
m_atomics[n] = atomic;
AddTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
RpGeometry *geo = RpAtomicGetGeometry(atomic);
if(m_ignoreLight)
RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) & ~rpGEOMETRYLIGHT);
/*
if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS &&
RpGeometryGetNumTriangles(geo) > 200)
debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo));
*/
#ifdef EXTENDED_PIPELINES
if(m_wetRoadReflection)
@ -136,6 +166,40 @@ CSimpleModelInfo::GetLargestLodDistance(void)
return d * TheCamera.LODDistMultiplier;
}
RpAtomic*
CSimpleModelInfo::GetLodAtomic(int n)
{
if(m_atomics == nil || n >= m_numAtomics)
return nil;
return m_atomics[n];
}
RpAtomic*
CSimpleModelInfo::GetLastAtomic(void)
{
if(m_atomics == nil)
return nil;
if(m_firstDamaged == 0 || m_isDamaged)
return m_atomics[m_numAtomics-1];
else
return m_atomics[m_firstDamaged-1];
}
RpAtomic*
CSimpleModelInfo::GetLastAtomic(float dist)
{
int n;
if(m_atomics == nil)
return nil;
if(m_firstDamaged == 0 || m_isDamaged)
n = m_numAtomics-1;
else
n = m_firstDamaged-1;
if(dist < m_lodDistances[n] * TheCamera.LODDistMultiplier)
return m_atomics[n];
return nil;
}
RpAtomic*
CSimpleModelInfo::GetAtomicFromDistance(float dist)
{
@ -152,20 +216,40 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
RpAtomic*
CSimpleModelInfo::GetFirstAtomicFromDistance(float dist)
{
// HACk until we figure out what's going on
if(m_atomics == nil) return nil;
if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier)
return m_atomics[0];
return nil;
}
void
CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
CSimpleModelInfo::FindRelatedModel(void)
{
int i;
CBaseModelInfo *mi;
for(i = minID; i <= maxID; i++){
mi = CModelInfo::GetModelInfo(i);
int thisIndex, otherIndex;
// find our own index in temp data
for(thisIndex = 0; thisIndex < ARRAY_SIZE(m_sTempIdeData); thisIndex++){
if(m_sTempIdeData[thisIndex].id == -1)
break;
if(this == CModelInfo::GetModelInfo(m_sTempIdeData[thisIndex].id))
goto found;
}
thisIndex = -1;
found:
#ifdef FIX_BUGS
if(thisIndex == -1)
return;
#endif
for(otherIndex = 0; otherIndex < ARRAY_SIZE(m_sTempIdeData); otherIndex++){
if(m_sTempIdeData[otherIndex].id == -1)
break;
mi = CModelInfo::GetModelInfo(m_sTempIdeData[otherIndex].id);
if(mi && mi != this &&
!CGeneral::faststrcmp(GetModelName()+3, mi->GetModelName()+3)){
!CGeneral::faststrcmp(m_sTempIdeData[thisIndex].name+3, m_sTempIdeData[otherIndex].name+3)){
assert(mi->IsSimple());
this->SetRelatedModel((CSimpleModelInfo*)mi);
return;
@ -176,12 +260,14 @@ CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
#define NEAR_DRAW_DIST 100.0f // 0.0f in vice city
void
CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
CSimpleModelInfo::SetupBigBuilding(void)
{
CSimpleModelInfo *related;
if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
if(m_lodDistances[0] < 0.0f)
m_lodDistances[0] = -m_lodDistances[0]; // what?
else if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
m_isBigBuilding = 1;
FindRelatedModel(minID, maxID);
FindRelatedModel();
related = GetRelatedModel();
if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
@ -193,3 +279,79 @@ CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
m_lodDistances[2] = NEAR_DRAW_DIST;
}
}
void
CSimpleModelInfo::LoadModel(void *atomics, const void *chunk)
{
int i;
m_chunk = (void*)chunk;
m_atomics = (RpAtomic**)atomics;
CStreaming::RegisterPointer(m_chunk, 2, true);
CStreaming::RegisterPointer(m_atomics, 2, true);
for(i = 0; i < m_numAtomics; i++){
LoadResource(m_atomics[i]);
CStreaming::RegisterAtomic(m_atomics[i], nil);
}
}
void
CSimpleModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
CBaseModelInfo::Write(writer);
if(WriteModel(writer))
writer.AddPatch(&m_atomics);
else
m_atomics = nil;
if(m_isBigBuilding)
writer.AddPatch(&m_relatedModel);
}
void*
CSimpleModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
{
int i;
if(m_atomics == nil || m_atomics[0] == nil)
return nil;
// remove empty atomics
int numAtomics = 0;
for(i = 0; i < m_numAtomics; i++)
if(m_atomics[i]){
m_atomics[numAtomics] = m_atomics[i];
#ifdef FIX_BUGS
m_lodDistances[numAtomics] = m_lodDistances[i];
#endif
numAtomics++;
}
if(m_firstDamaged){
int firstDam = m_firstDamaged - m_numAtomics + numAtomics;
if(firstDam < numAtomics)
m_firstDamaged = firstDam;
else
m_firstDamaged = 0;
}
m_numAtomics = numAtomics;
// write the actual models
writer.AllocateRaw(m_atomics, m_numAtomics*sizeof(void*), sizeof(void*), false, true);
for(i = 0; m_numAtomics; i++){
writer.AddPatch(&m_atomics[i]);
SaveResource(m_atomics[i], writer);
}
return m_atomics;
}
void
CSimpleModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CSimpleModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -2,11 +2,18 @@
#include "BaseModelInfo.h"
// For linking up models by name
struct TempIdeData
{
char name[24];
int16 id;
};
extern TempIdeData m_sTempIdeData[800];
class CSimpleModelInfo : public CBaseModelInfo
{
public:
// atomics[2] is often a pointer to the non-LOD modelinfo
RpAtomic *m_atomics[3];
RpAtomic **m_atomics;
// m_lodDistances[2] holds the near distance for LODs
float m_lodDistances[3];
uint8 m_numAtomics;
@ -31,15 +38,26 @@ public:
uint16 m_isCodeGlass : 1;
uint16 m_isArtistGlass : 1;
CSimpleModelInfo *m_relatedModel;
static base::cRelocatableChunkClassInfo msClassInfo;
static CSimpleModelInfo msClassInstance;
CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {}
CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}
~CSimpleModelInfo() {}
void DeleteRwObject(void);
RwObject *CreateInstance(void);
RwObject *CreateInstance(RwMatrix *);
RwObject *GetRwObject(void) { return (RwObject*)m_atomics[0]; }
RwObject *GetRwObject(void) { return m_atomics ? (RwObject*)m_atomics[0] : nil; }
virtual void SetAtomic(int n, RpAtomic *atomic);
virtual void LoadModel(void *atomics, const void *chunk);
virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
/*virtual*/ void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void IncreaseAlpha(void);
@ -47,15 +65,18 @@ public:
float GetLodDistance(int i);
float GetNearDistance(void);
float GetLargestLodDistance(void);
RpAtomic *GetLodAtomic(int n);
RpAtomic *GetLastAtomic(void);
RpAtomic *GetLastAtomic(float dist);
RpAtomic *GetAtomicFromDistance(float dist);
RpAtomic *GetFirstAtomicFromDistance(float dist);
void FindRelatedModel(int32 minID, int32 maxID);
void SetupBigBuilding(int32 minID, int32 maxID);
void FindRelatedModel(void);
void SetupBigBuilding(void);
void SetNumAtomics(int n) { m_numAtomics = n; }
CSimpleModelInfo *GetRelatedModel(void){
return (CSimpleModelInfo*)m_atomics[2]; }
return m_relatedModel; }
void SetRelatedModel(CSimpleModelInfo *m){
m_atomics[2] = (RpAtomic*)m; }
m_relatedModel = m; }
};
//static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error");

View File

@ -3,15 +3,20 @@
#include "Camera.h"
#include "ModelInfo.h"
#include "General.h"
#include "KeyGen.h"
base::cRelocatableChunkClassInfo CTimeModelInfo::msClassInfo("CTimeModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CTimeModelInfo CTimeModelInfo::msClassInstance;
CTimeModelInfo*
CTimeModelInfo::FindOtherTimeModel(void)
CTimeModelInfo::FindOtherTimeModel(const char *modelname)
{
char name[40];
char *p;
int i;
strcpy(name, GetModelName());
strcpy(name, modelname);
// change _nt to _dy
if(p = strstr(name, "_nt"))
strncpy(p, "_dy", 4);
@ -21,13 +26,29 @@ CTimeModelInfo::FindOtherTimeModel(void)
else
return nil;
uint32 nameKey = CKeyGen::GetUppercaseKey(name);
for(i = 0; i < MODELINFOSIZE; i++){
CBaseModelInfo *mi = CModelInfo::GetModelInfo(i);
if (mi && mi->GetModelType() == MITYPE_TIME &&
!CGeneral::faststrncmp(name, mi->GetModelName(), MAX_MODEL_NAME)){
if (mi && mi->GetModelType() == MITYPE_TIME && nameKey == mi->GetNameHashKey()){
m_otherTimeModelID = i;
return (CTimeModelInfo*)mi;
}
}
return nil;
}
void
CTimeModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CTimeModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -7,14 +7,21 @@ class CTimeModelInfo : public CSimpleModelInfo
int32 m_timeOn;
int32 m_timeOff;
int32 m_otherTimeModelID;
static base::cRelocatableChunkClassInfo msClassInfo;
static CTimeModelInfo msClassInstance;
public:
CTimeModelInfo(void) : CSimpleModelInfo(MITYPE_TIME) { m_otherTimeModelID = -1; }
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
int32 GetTimeOn(void) { return m_timeOn; }
int32 GetTimeOff(void) { return m_timeOff; }
void SetTimes(int32 on, int32 off) { m_timeOn = on; m_timeOff = off; }
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
void SetOtherTimeModel(int32 other) { m_otherTimeModelID = other; }
CTimeModelInfo *FindOtherTimeModel(void);
CTimeModelInfo *FindOtherTimeModel(const char *name);
};
//static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");

View File

@ -1,6 +1,7 @@
#include "common.h"
#include <rpmatfx.h>
#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
@ -20,14 +21,21 @@
#include "ModelIndices.h"
#include "ModelInfo.h"
#include "custompipes.h"
#include "Streaming.h"
#include "Leeds.h"
int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
int8 CVehicleModelInfo::ms_compsUsed[2];
RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
base::cRelocatableChunkClassInfo CVehicleModelInfo::msClassInfo("CVehicleModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CVehicleModelInfo CVehicleModelInfo::msClassInstance;
RwTexture *gpWhiteTexture;
RwFrame *pMatFxIdentityFrame;
//int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
//int8 CVehicleModelInfo::ms_compsUsed[2];
//RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
CVehicleModelInfo::Statics *CVehicleModelInfo::mspInfo;
//RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
//RwTexture *gpWhiteTexture;
//RwFrame *pMatFxIdentityFrame;
enum {
VEHICLE_FLAG_COLLAPSE = 0x2,
@ -168,6 +176,29 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = {
bool gbBlackCars;
bool gbPinkCars;
void
CVehicleModelInfo::Load(void *inst)
{
if(inst)
mspInfo = (CVehicleModelInfo::Statics*)inst;
else{
mspInfo = new CVehicleModelInfo::Statics;
memset(mspInfo, 0, sizeof(*mspInfo));
mspInfo->ms_compsToUse[0] = -2;
mspInfo->ms_compsToUse[1] = -2;
}
}
void*
CVehicleModelInfo::WriteStaticInfo(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(mspInfo, sizeof(*mspInfo), sizeof(void*), false, true);
if(mspInfo->unknown)
writer.AddPatch(&mspInfo->unknown);
return mspInfo;
}
CVehicleModelInfo::CVehicleModelInfo(void)
: CClumpModelInfo(MITYPE_VEHICLE)
{
@ -178,7 +209,12 @@ CVehicleModelInfo::CVehicleModelInfo(void)
m_positions[i].z = 0.0f;
}
m_numColours = 0;
CClumpModelInfo::m_animFileIndex = -1;
memset(m_materials1, 0, sizeof(m_materials1));
memset(m_materials2, 0, sizeof(m_materials2));
m_animFileIndex = -1;
m_normalSplay = 0.3f;
}
void
@ -187,15 +223,73 @@ CVehicleModelInfo::DeleteRwObject(void)
int32 i;
RwFrame *f;
for(i = 0; i < m_numComps; i++){
f = RpAtomicGetFrame(m_comps[i]);
RpAtomicDestroy(m_comps[i]);
RwFrameDestroy(f);
if(!gUseChunkFiles){
for(i = 0; i < m_numComps; i++){
f = RpAtomicGetFrame(m_comps[i]);
RpAtomicDestroy(m_comps[i]);
RwFrameDestroy(f);
}
#ifdef FIX_BUGS
delete[] m_comps;
m_comps = nil;
#endif
m_numComps = 0;
}
m_numComps = 0;
RemoveWheels();
for(i = 0; i < ARRAY_SIZE(m_materials1); i++)
CStreaming::UnregisterPointer(&m_materials1[i], 2);
for(i = 0; i < ARRAY_SIZE(m_materials2); i++)
CStreaming::UnregisterPointer(&m_materials2[i], 2);
if(m_numComps > 0){
CStreaming::UnregisterPointer(&m_comps, 2);
for(i = 0; i < m_numComps; i++)
CStreaming::UnregisterAtomic(m_comps[i], nil);
m_comps = nil;
}
CClumpModelInfo::DeleteRwObject();
}
RwObject*
RemoveWheelCB(RwObject *object, void *arg)
{
RpAtomic *atomic = (RpAtomic*)object;
if(RwObjectGetType(object) == rpATOMIC){
RpClumpRemoveAtomic((RpClump*)arg, atomic);
#ifdef LIBRW
CStreaming::UnregisterPointer(&atomic->inClump.next, 2);
CStreaming::UnregisterPointer(&atomic->inClump.prev, 2);
CStreaming::UnregisterPointer(&atomic->object.object.parent, 2);
CStreaming::UnregisterPointer(&atomic->object.inFrame.next, 2);
CStreaming::UnregisterPointer(&atomic->object.inFrame.prev, 2);
CStreaming::UnregisterPointer(&atomic->clump, 2);
#endif
RpAtomicDestroy(atomic);
}
return object;
}
void
CVehicleModelInfo::RemoveWheels(void)
{
RwObjectNameIdAssocation *desc = ms_vehicleDescs[m_vehicleType];
for(int i = 0; desc[i].name; i++){
RwObjectIdAssociation assoc;
if(desc[i].flags & (VEHICLE_FLAG_COMP|VEHICLE_FLAG_POS))
continue;
assoc.frame = nil;
assoc.id = desc[i].hierId;
RwFrameForAllChildren(RpClumpGetFrame(m_clump),
FindFrameFromIdCB, &assoc);
if(assoc.frame && desc[i].flags & VEHICLE_FLAG_ADD_WHEEL && m_wheelId != -1)
RwFrameForAllObjects(assoc.frame, RemoveWheelCB, m_clump);
}
}
RwObject*
CVehicleModelInfo::CreateInstance(void)
{
@ -205,7 +299,7 @@ CVehicleModelInfo::CreateInstance(void)
int32 comp1, comp2;
clump = (RpClump*)CClumpModelInfo::CreateInstance();
if(m_numComps != 0){
if(clump && m_numComps != 0 && strcmp(m_gameName, "POLICAR") != 0){
clumpframe = RpClumpGetFrame(clump);
comp1 = ChooseComponent();
@ -219,7 +313,7 @@ CVehicleModelInfo::CreateInstance(void)
RpClumpAddAtomic(clump, atomic);
RwFrameAddChild(clumpframe, f);
}
ms_compsUsed[0] = comp1;
mspInfo->ms_compsUsed[0] = comp1;
comp2 = ChooseSecondComponent();
if(comp2 != -1 && m_comps[comp2]){
@ -232,18 +326,27 @@ CVehicleModelInfo::CreateInstance(void)
RpClumpAddAtomic(clump, atomic);
RwFrameAddChild(clumpframe, f);
}
ms_compsUsed[1] = comp2;
mspInfo->ms_compsUsed[1] = comp2;
}else{
ms_compsUsed[0] = -1;
ms_compsUsed[1] = -1;
mspInfo->ms_compsUsed[0] = -1;
mspInfo->ms_compsUsed[1] = -1;
}
CStreaming::RegisterInstance(clump);
return (RwObject*)clump;
}
RpAtomic*
SplayNormals(RpAtomic *atomic, void *arg)
{
// PSP only?
return atomic;
}
void
CVehicleModelInfo::SetClump(RpClump *clump)
{
CClumpModelInfo::SetClump(clump);
RpClumpForAllAtomics((RpClump*)GetRwObject(), SplayNormals, this);
SetAtomicRenderCallbacks();
SetFrameIds(ms_vehicleDescs[m_vehicleType]);
PreprocessHierarchy();
@ -339,7 +442,7 @@ CVehicleModelInfo::SetAtomicRendererCB(RpAtomic *atomic, void *data)
}else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
return atomic; // BUG: nil in gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
else
@ -397,6 +500,33 @@ CVehicleModelInfo::SetAtomicRendererCB_Train(RpAtomic *atomic, void *data)
return atomic;
}
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Ferry(RpAtomic *atomic, void *data)
{
char *name;
bool alpha;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
alpha = false;
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
if(strstr(name, "_hi")){
if(alpha)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderTrainHiDetailAlphaCB);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderTrainHiDetailCB);
}else if(strstr(name, "_lo")){
if(alpha)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle);
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
HideDamagedAtomicCB(atomic, nil);
return atomic;
}
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
{
@ -414,7 +544,31 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLoDetailCB_Boat);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
HideDamagedAtomicCB(atomic, nil);
return atomic;
}
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Boat_Far(RpAtomic *atomic, void *data)
{
RpClump *clump;
char *name;
clump = (RpClump*)data;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat_Far);
else if(strstr(name, "_hi"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLoDetailCB_Boat_Far);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
HideDamagedAtomicCB(atomic, nil);
@ -424,6 +578,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data)
{
/* // LCS: gone, may be better to keep it though
char *name;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
@ -432,6 +587,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data)
else if(strncmp(name, "rearrotor", 9) == 0)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB);
else
*/
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
return atomic;
}
@ -459,7 +615,7 @@ CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data)
}else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
return atomic; // BUG: nil in gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
else
@ -476,13 +632,18 @@ CVehicleModelInfo::SetAtomicRenderCallbacks(void)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Train, nil);
else
#endif
if(m_vehicleType == VEHICLE_TYPE_HELI)
if(m_vehicleType == VEHICLE_TYPE_FERRY)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Ferry, nil);
else if(m_vehicleType == VEHICLE_TYPE_HELI)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Heli, nil);
else if(m_vehicleType == VEHICLE_TYPE_PLANE)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_BigVehicle, nil);
else if(m_vehicleType == VEHICLE_TYPE_BOAT)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
else if(mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId)->Flags & HANDLING_IS_HELI)
else if(m_vehicleType == VEHICLE_TYPE_BOAT){
if(strcmp(m_gameName, "REEFER") == 0)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat_Far, m_clump);
else
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
}else if(mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId)->Flags & HANDLING_IS_HELI)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_RealHeli, m_clump);
else
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, m_clump);
@ -530,6 +691,8 @@ CVehicleModelInfo::PreprocessHierarchy(void)
m_numDoors = 0;
m_numComps = 0;
m_comps = new RpAtomic*[7];
for(i = 0; desc[i].name; i++){
RwObjectNameAssociation assoc;
@ -587,21 +750,23 @@ CVehicleModelInfo::PreprocessHierarchy(void)
SetVehicleComponentFlags(assoc.frame, desc[i].flags);
if(desc[i].flags & VEHICLE_FLAG_ADD_WHEEL){
if(m_wheelId == -1)
RwFrameDestroy(assoc.frame);
else{
RwV3d scale;
atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
RwFrameDestroy(RpAtomicGetFrame(atomic));
RpAtomicSetFrame(atomic, assoc.frame);
RpClumpAddAtomic(m_clump, atomic);
CVisibilityPlugins::SetAtomicRenderCallback(atomic,
CVisibilityPlugins::RenderWheelAtomicCB);
scale.x = m_wheelScale;
scale.y = m_wheelScale;
scale.z = m_wheelScale;
RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
if(!(gMakeResources && gUseResources)){
if(desc[i].flags & VEHICLE_FLAG_ADD_WHEEL){
if(m_wheelId == -1)
RwFrameDestroy(assoc.frame);
else{
RwV3d scale;
atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
RwFrameDestroy(RpAtomicGetFrame(atomic));
RpAtomicSetFrame(atomic, assoc.frame);
RpClumpAddAtomic(m_clump, atomic);
CVisibilityPlugins::SetAtomicRenderCallback(atomic,
CVisibilityPlugins::RenderWheelAtomicCB);
scale.x = m_wheelScale;
scale.y = m_wheelScale;
scale.z = m_wheelScale;
RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
}
}
}
}
@ -629,9 +794,9 @@ CVehicleModelInfo::SetVehicleComponentFlags(RwFrame *frame, uint32 flags)
SETFLAGS(ATOMIC_FLAG_FRONT);
else if(flags & VEHICLE_FLAG_REAR && (handling->Flags & HANDLING_IS_VAN || (flags & (VEHICLE_FLAG_LEFT|VEHICLE_FLAG_RIGHT)) == 0))
SETFLAGS(ATOMIC_FLAG_REAR);
if(flags & VEHICLE_FLAG_LEFT)
else if(flags & VEHICLE_FLAG_LEFT)
SETFLAGS(ATOMIC_FLAG_LEFT);
if(flags & VEHICLE_FLAG_RIGHT)
else if(flags & VEHICLE_FLAG_RIGHT)
SETFLAGS(ATOMIC_FLAG_RIGHT);
if(flags & VEHICLE_FLAG_REARDOOR)
@ -746,7 +911,7 @@ CVehicleModelInfo::ChooseComponent(void)
int32 n;
comp = -1;
if(ms_compsToUse[0] == -2){
if(mspInfo->ms_compsToUse[0] == -2){
if(COMPRULE_RULE(m_compRules) && IsValidCompRule(COMPRULE_RULE(m_compRules)))
comp = ::ChooseComponent(COMPRULE_RULE(m_compRules), COMPRULE_COMPS(m_compRules));
else if(CGeneral::GetRandomNumberInRange(0, 3) < 2){
@ -755,8 +920,8 @@ CVehicleModelInfo::ChooseComponent(void)
comp = comps[(int)CGeneral::GetRandomNumberInRange(0, n)];
}
}else{
comp = ms_compsToUse[0];
ms_compsToUse[0] = -2;
comp = mspInfo->ms_compsToUse[0];
mspInfo->ms_compsToUse[0] = -2;
}
return comp;
}
@ -769,7 +934,7 @@ CVehicleModelInfo::ChooseSecondComponent(void)
int32 n;
comp = -1;
if(ms_compsToUse[1] == -2){
if(mspInfo->ms_compsToUse[1] == -2){
if(COMPRULE2_RULE(m_compRules) && IsValidCompRule(COMPRULE2_RULE(m_compRules)))
comp = ::ChooseComponent(COMPRULE2_RULE(m_compRules), COMPRULE2_COMPS(m_compRules));
else if(COMPRULE_RULE(m_compRules) && IsValidCompRule(COMPRULE_RULE(m_compRules)) &&
@ -780,8 +945,8 @@ CVehicleModelInfo::ChooseSecondComponent(void)
comp = comps[(int)CGeneral::GetRandomNumberInRange(0, n)];
}
}else{
comp = ms_compsToUse[1];
ms_compsToUse[1] = -2;
comp = mspInfo->ms_compsToUse[1];
mspInfo->ms_compsToUse[1] = -2;
}
return comp;
}
@ -796,7 +961,7 @@ struct editableMatCBData
RpMaterial*
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
{
static RwRGBA white = { 255, 255, 255, 255 };
RwRGBA white = { 255, 255, 255, 255 };
const RwRGBA *col;
editableMatCBData *cbdata;
@ -849,7 +1014,7 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
RpMaterial **matp;
if(c1 != m_currentColour1){
col = ms_vehicleColourTable[c1];
col = mspInfo->ms_vehicleColourTable[c1];
for(matp = m_materials1; *matp; matp++){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
@ -860,7 +1025,7 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
}
if(c2 != m_currentColour2){
col = ms_vehicleColourTable[c2];
col = mspInfo->ms_vehicleColourTable[c2];
for(matp = m_materials2; *matp; matp++){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
@ -985,8 +1150,8 @@ CVehicleModelInfo::LoadVehicleColours(void)
fd = CFileMgr::OpenFile("CARCOLS.DAT", "r");
CFileMgr::ChangeDir("\\");
for(i = 0; i < 256; i++)
ms_colourTextureTable[i] = nil;
//for(i = 0; i < 256; i++)
// ms_colourTextureTable[i] = nil;
section = 0;
numCols = 0;
@ -1018,10 +1183,10 @@ CVehicleModelInfo::LoadVehicleColours(void)
}else if(section == COLOURS){
sscanf(&line[start], // BUG: games doesn't add start
"%d %d %d", &r, &g, &b);
ms_vehicleColourTable[numCols].red = r;
ms_vehicleColourTable[numCols].green = g;
ms_vehicleColourTable[numCols].blue = b;
ms_vehicleColourTable[numCols].alpha = 0xFF;
mspInfo->ms_vehicleColourTable[numCols].red = r;
mspInfo->ms_vehicleColourTable[numCols].green = g;
mspInfo->ms_vehicleColourTable[numCols].blue = b;
mspInfo->ms_vehicleColourTable[numCols].alpha = 0xFF;
numCols++;
}else if(section == CARS){
n = sscanf(&line[start], // BUG: games doesn't add start
@ -1051,6 +1216,7 @@ CVehicleModelInfo::LoadVehicleColours(void)
void
CVehicleModelInfo::DeleteVehicleColourTextures(void)
{
/*
int i;
for(i = 0; i < 256; i++){
@ -1059,6 +1225,7 @@ CVehicleModelInfo::DeleteVehicleColourTextures(void)
ms_colourTextureTable[i] = nil;
}
}
*/
}
RpMaterial*
@ -1070,6 +1237,7 @@ CVehicleModelInfo::GetMatFXEffectMaterialCB(RpMaterial *material, void *data)
return nil;
}
/*
RpMaterial*
CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data)
{
@ -1086,7 +1254,9 @@ CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data)
}
return material;
}
*/
/*
RpAtomic*
CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
{
@ -1102,6 +1272,7 @@ CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
}
return atomic;
}
*/
void
CVehicleModelInfo::SetEnvironmentMap(void)
@ -1178,10 +1349,162 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
}
if(n == 0)
return id == MI_RCBANDIT || id == MI_PIZZABOY || id == MI_BAGGAGE ? 0 : 1;
return id == MI_RCBANDIT /*|| id == MI_PIZZABOY || id == MI_BAGGAGE*/ ? 0 : 1;
if(id == MI_COACH)
return 8;
return n - 1;
}
struct VehicleChunk
{
RpClump *clump;
int32 numComps;
RpAtomic **comp;
RpMaterial *materials1[NUM_FIRST_MATERIALS];
RpMaterial *materials2[NUM_SECOND_MATERIALS];
};
void
CVehicleModelInfo::LoadModel(void *data, const void *chunk)
{
int i;
VehicleChunk *chk = (VehicleChunk*)data;
CClumpModelInfo::LoadModel(chk->clump, chunk);
// editable materials
for(i = 0; i < NUM_FIRST_MATERIALS; i++){
m_materials1[i] = chk->materials1[i];
if(m_materials1[i])
CStreaming::RegisterPointer(&m_materials1[i], 2, true);
}
for(i = 0; i < NUM_SECOND_MATERIALS; i++){
m_materials2[i] = chk->materials2[i];
if(m_materials2[i])
CStreaming::RegisterPointer(&m_materials2[i], 2, true);
}
// extra components
m_numComps = chk->numComps;
if(m_numComps > 0){
m_comps = chk->comp;
CStreaming::RegisterPointer(&m_comps, 2, true);
for(i = 0; i < m_numComps; i++){
LoadResource(m_comps[i]);
CStreaming::RegisterAtomic(m_comps[i], nil);
}
}else
m_comps = nil;
m_currentColour1 = -1;
m_currentColour2 = -1;
// add wheels
RwObjectNameIdAssocation *desc = ms_vehicleDescs[m_vehicleType];
for(i = 0; desc[i].name; i++){
RwObjectIdAssociation assoc;
if(desc[i].flags & (VEHICLE_FLAG_COMP|VEHICLE_FLAG_POS))
continue;
assoc.frame = nil;
assoc.id = desc[i].hierId;
RwFrameForAllChildren(RpClumpGetFrame(m_clump),
FindFrameFromIdCB, &assoc);
if(assoc.frame && desc[i].flags & VEHICLE_FLAG_ADD_WHEEL && m_wheelId != -1){
RwV3d scale;
RpAtomic *atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
RwFrameDestroy(RpAtomicGetFrame(atomic));
RpAtomicSetFrame(atomic, assoc.frame);
RpClumpAddAtomic(m_clump, atomic);
CVisibilityPlugins::SetAtomicRenderCallback(atomic,
CVisibilityPlugins::RenderWheelAtomicCB);
scale.x = m_wheelScale;
scale.y = m_wheelScale;
scale.z = m_wheelScale;
RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
#ifdef LIBRW
CStreaming::RegisterPointer(&atomic->inClump.next, 2, true);
CStreaming::RegisterPointer(&atomic->inClump.prev, 2, true);
CStreaming::RegisterPointer(&atomic->object.object.parent, 2, true);
CStreaming::RegisterPointer(&atomic->object.inFrame.next, 2, true);
CStreaming::RegisterPointer(&atomic->object.inFrame.prev, 2, true);
CStreaming::RegisterPointer(&atomic->clump, 2, true);
#endif
}
}
}
void
CVehicleModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
CClumpModelInfo::Write(writer);
}
void*
CVehicleModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
{
if(GetRwObject() == nil)
return nil;
int i;
VehicleChunk *chk = new VehicleChunk;
memset(chk, 0, sizeof(*chk));
writer.AllocateRaw(chk, sizeof(*chk), sizeof(void*), false, true);
// clump
chk->clump = (RpClump*)CClumpModelInfo::WriteModel(writer);
if(chk->clump)
writer.AddPatch(&chk->clump);
// materials
for(i = 0; i < NUM_FIRST_MATERIALS; i++){
if(m_materials1[i] == nil || m_vehicleType == VEHICLE_TYPE_FERRY)
chk->materials1[i] = nil;
else{
SaveResource(m_materials1[i], writer);
chk->materials1[i] = m_materials1[i];
writer.AddPatch(&chk->materials1[i]);
}
}
for(i = 0; i < NUM_SECOND_MATERIALS; i++){
if(m_materials2[i] == nil || m_vehicleType == VEHICLE_TYPE_FERRY)
chk->materials2[i] = nil;
else{
SaveResource(m_materials2[i], writer);
chk->materials2[i] = m_materials2[i];
writer.AddPatch(&chk->materials2[i]);
}
}
// extra components
chk->numComps = m_numComps;
chk->comp = nil;
if(m_numComps > 0){
chk->comp = m_comps;
writer.AddPatch(&chk->comp);
writer.AllocateRaw(m_comps, m_numComps*sizeof(void*), sizeof(void*), false, true);
for(i = 0; i < m_numComps; i++)
if(m_comps[i]){
SaveResource(m_comps[i], writer);
writer.AddPatch(&m_comps[i]);
}
}
return chk;
}
void
CVehicleModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CVehicleModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -98,19 +98,30 @@ public:
uint8 m_lastColorVariation;
uint8 m_currentColour1;
uint8 m_currentColour2;
RpAtomic *m_comps[6]; // LCS(TODO): pointer
RpAtomic **m_comps;
float m_normalSplay;
// This is stupid, CClumpModelInfo already has it!
union {
int32 m_animFileIndex;
char *m_animFileName;
};
static int8 ms_compsToUse[2];
static int8 ms_compsUsed[2];
static RwRGBA ms_vehicleColourTable[256];
static RwTexture *ms_colourTextureTable[256];
static base::cRelocatableChunkClassInfo msClassInfo;
static CVehicleModelInfo msClassInstance;
struct Statics {
void *unknown; // unused too it seems
RwRGBA ms_vehicleColourTable[256];
int8 ms_compsUsed[2];
int8 ms_compsToUse[2];
};
//static RwTexture *ms_colourTextureTable[256];
static Statics *mspInfo;
static RwObjectNameIdAssocation *ms_vehicleDescs[NUM_VEHICLE_TYPES];
static void Load(void *inst);
static void *WriteStaticInfo(base::cRelocatableChunkWriter &writer);
CVehicleModelInfo(void);
void DeleteRwObject(void);
RwObject *CreateInstance(void);
@ -119,6 +130,12 @@ public:
void ConvertAnimFileIndex(void);
int GetAnimFileIndex(void) { return m_animFileIndex; }
virtual void LoadModel(void *model, const void *chunk);
virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
static RwFrame *CollapseFramesCB(RwFrame *frame, void *data);
static RwObject *MoveObjectsCB(RwObject *object, void *data);
static RpAtomic *HideDamagedAtomicCB(RpAtomic *atomic, void *data);
@ -128,13 +145,16 @@ public:
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_BigVehicle(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Train(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Ferry(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Boat_Far(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data);
void SetAtomicRenderCallbacks(void);
static RwObject *SetAtomicFlagCB(RwObject *object, void *data);
static RwObject *ClearAtomicFlagCB(RwObject *atomic, void *data);
void RemoveWheels(void);
void SetVehicleComponentFlags(RwFrame *frame, uint32 flags);
void PreprocessHierarchy(void);
void GetWheelPosn(int32 n, CVector &pos);
@ -160,7 +180,7 @@ public:
static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
static void SetComponentsToUse(int8 c1, int8 c2) { ms_compsToUse[0] = c1; ms_compsToUse[1] = c2; }
static void SetComponentsToUse(int8 c1, int8 c2) { mspInfo->ms_compsToUse[0] = c1; mspInfo->ms_compsToUse[1] = c2; }
};
extern bool gbBlackCars;

View File

@ -4,6 +4,9 @@
#include "AnimManager.h"
#include "VisibilityPlugins.h"
base::cRelocatableChunkClassInfo CWeaponModelInfo::msClassInfo("CWeaponModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CWeaponModelInfo CWeaponModelInfo::msClassInstance;
void
CWeaponModelInfo::SetAnimFile(const char *file)
{
@ -35,19 +38,34 @@ CWeaponModelInfo::Init(void)
void
CWeaponModelInfo::SetWeaponInfo(int32 weaponId)
{
m_atomics[2] = (RpAtomic*)weaponId;
m_relatedModel = (CSimpleModelInfo*)weaponId;
}
eWeaponType
CWeaponModelInfo::GetWeaponInfo(void)
{
return (eWeaponType)(uintptr)m_atomics[2];
return (eWeaponType)(uintptr)m_relatedModel;
}
/*
void
CWeaponModelInfo::SetAtomic(int n, RpAtomic *atomic)
{
CSimpleModelInfo::SetAtomic(n, atomic);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderWeaponCB);
}
*/
void
CWeaponModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CWeaponModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View File

@ -9,13 +9,21 @@ class CWeaponModelInfo : public CSimpleModelInfo
int32 m_animFileIndex;
char *m_animFileName;
};
static base::cRelocatableChunkClassInfo msClassInfo;
static CWeaponModelInfo msClassInstance;
public:
CWeaponModelInfo(void) : CSimpleModelInfo(MITYPE_WEAPON) { m_animFileIndex = -1; }
virtual void SetAnimFile(const char *file);
virtual void ConvertAnimFileIndex(void);
virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
virtual void SetAtomic(int n, RpAtomic *atomic);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
//virtual void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void SetWeaponInfo(int32 weaponId);

View File

@ -454,6 +454,14 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
{
if(DistToCameraSq < ms_vehicleLod0Dist)
RENDERCALLBACK(atomic);
return atomic;
}
RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat_Far(RpAtomic *atomic)
{
if(DistToCameraSq < ms_bigVehicleLod1Dist)
RENDERCALLBACK(atomic);
@ -473,6 +481,40 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic)
return atomic;
}
RpAtomic*
CVisibilityPlugins::RenderVehicleLoDetailCB_Boat(RpAtomic *atomic)
{
RpClump *clump;
int32 alpha;
clump = RpAtomicGetClump(atomic);
if(DistToCameraSq >= ms_vehicleLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
return atomic;
}
RpAtomic*
CVisibilityPlugins::RenderVehicleLoDetailCB_Boat_Far(RpAtomic *atomic)
{
RpClump *clump;
int32 alpha;
clump = RpAtomicGetClump(atomic);
if(DistToCameraSq >= ms_bigVehicleLod1Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
return atomic;
}
RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
{

View File

@ -61,6 +61,9 @@ public:
static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailCB_Boat_Far(RpAtomic *atomic);
static RpAtomic *RenderVehicleLoDetailCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleLoDetailCB_Boat_Far(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic);

View File

@ -4174,7 +4174,7 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
CGeneral::GetRandomNumberInRange(0.1f, 0.25f)),
nil,
CGeneral::GetRandomNumberInRange(0.02f, 0.08f),
CVehicleModelInfo::ms_vehicleColourTable[m_currentColour1],
CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1],
CGeneral::GetRandomNumberInRange(-40.0f, 40.0f),
0,
CGeneral::GetRandomNumberInRange(0.0f, 4.0f));

View File

@ -756,7 +756,7 @@ CHeli::InitHelis(void)
for(i = 0; i < NUM_HELIS; i++)
pHelis[i] = nil;
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&gpTempColModels->ms_colModelPed1);
}
CHeli*

View File

@ -217,8 +217,8 @@ void
CVehicle::SetModelIndex(uint32 id)
{
CEntity::SetModelIndex(id);
m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0];
m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1];
m_aExtras[0] = CVehicleModelInfo::mspInfo->ms_compsUsed[0];
m_aExtras[1] = CVehicleModelInfo::mspInfo->ms_compsUsed[1];
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id);
}

View File

@ -513,7 +513,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
if ( SQR(victimPedRadius) > (victimPedPos-fireSource).MagnitudeSqr() )
{
CVector collisionDist;
CColModel* victimPedCol = &CTempColModels::ms_colModelPed1;
CColModel* victimPedCol = &gpTempColModels->ms_colModelPed1;
bool useLocalPos = false;
if (victimPed->m_nPedState == PED_FALL
|| victimPed->m_nPedState == PED_DIE && victimPed->bIsPedDieAnimPlaying