CVehicleModelInfo

This commit is contained in:
aap 2021-01-24 22:48:32 +01:00
parent a202e67349
commit ce7f166ba3
11 changed files with 465 additions and 67 deletions

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

@ -366,6 +366,9 @@ bool CGame::Initialise(const char* datFile)
CPools::Initialise();
if(gMakeResources)
CVehicleModelInfo::Load(nil);
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#endif

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

@ -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;
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;
}
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)
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)
}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,6 +750,7 @@ CVehicleModelInfo::PreprocessHierarchy(void)
SetVehicleComponentFlags(assoc.frame, desc[i].flags);
if(!(gMakeResources && gUseResources)){
if(desc[i].flags & VEHICLE_FLAG_ADD_WHEEL){
if(m_wheelId == -1)
RwFrameDestroy(assoc.frame);
@ -605,6 +769,7 @@ CVehicleModelInfo::PreprocessHierarchy(void)
}
}
}
}
}
void
@ -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

@ -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

@ -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);
}