diff options
Diffstat (limited to 'src/modelinfo/VehicleModelInfo.cpp')
-rw-r--r-- | src/modelinfo/VehicleModelInfo.cpp | 278 |
1 files changed, 171 insertions, 107 deletions
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index c0daaead..6dc9e5b0 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -21,9 +21,10 @@ #include "ModelInfo.h" #include "custompipes.h" +//--MIAMI: done + int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 }; int8 CVehicleModelInfo::ms_compsUsed[2]; -RwTexture *CVehicleModelInfo::ms_pEnvironmentMaps[NUM_VEHICLE_ENVMAPS]; RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256]; RwTexture *CVehicleModelInfo::ms_colourTextureTable[256]; @@ -83,9 +84,23 @@ RwObjectNameIdAssocation carIds[] = { }; RwObjectNameIdAssocation boatIds[] = { - { "boat_moving_hi", BOAT_MOVING, VEHICLE_FLAG_COLLAPSE }, - { "boat_rudder_hi", BOAT_RUDDER, VEHICLE_FLAG_COLLAPSE }, - { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_COLLAPSE }, + { "boat_moving_hi", BOAT_MOVING, 0 }, + { "boat_rudder_hi", BOAT_RUDDER, 0 }, + { "boat_flap_left", BOAT_FLAP_LEFT, 0 }, + { "boat_flap_right", BOAT_FLAP_RIGHT, 0 }, + { "boat_rearflap_left", BOAT_REARFLAP_LEFT, 0 }, + { "boat_rearflap_right", BOAT_REARFLAP_RIGHT, 0 }, +#ifdef FIX_BUGS + // let's just accept both + { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST }, + { "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST }, +#else +#ifdef GTA_PS2 + { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST }, +#else + { "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST }, +#endif +#endif { "ped_frontseat", BOAT_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, { nil, 0, 0 } }; @@ -128,7 +143,9 @@ RwObjectNameIdAssocation bikeIds[] = { { "wheel_front", BIKE_WHEEL_FRONT, 0 }, { "wheel_rear", BIKE_WHEEL_REAR, 0 }, { "mudguard", BIKE_MUDGUARD, 0 }, + { "handlebars", BIKE_HANDLEBARS, 0 }, { "ped_frontseat", CAR_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "ped_backseat", CAR_POS_BACKSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, { "headlights", CAR_POS_HEADLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, { "taillights", CAR_POS_TAILLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, { "exhaust", CAR_POS_EXHAUST, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, @@ -150,6 +167,8 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = { bikeIds }; +bool gbBlackCars; +bool gbPinkCars; CVehicleModelInfo::CVehicleModelInfo(void) : CClumpModelInfo(MITYPE_VEHICLE) @@ -161,6 +180,7 @@ CVehicleModelInfo::CVehicleModelInfo(void) m_positions[i].z = 0.0f; } m_numColours = 0; + m_animFileIndex = -1; } void @@ -191,7 +211,7 @@ CVehicleModelInfo::CreateInstance(void) clumpframe = RpClumpGetFrame(clump); comp1 = ChooseComponent(); - if(comp1 != -1){ + if(comp1 != -1 && m_comps[comp1]){ atomic = RpAtomicClone(m_comps[comp1]); f = RwFrameCreate(); RwFrameTransform(f, @@ -204,7 +224,7 @@ CVehicleModelInfo::CreateInstance(void) ms_compsUsed[0] = comp1; comp2 = ChooseSecondComponent(); - if(comp2 != -1){ + if(comp2 != -1 && m_comps[comp2]){ atomic = RpAtomicClone(m_comps[comp2]); f = RwFrameCreate(); RwFrameTransform(f, @@ -230,10 +250,30 @@ CVehicleModelInfo::SetClump(RpClump *clump) SetFrameIds(ms_vehicleDescs[m_vehicleType]); PreprocessHierarchy(); FindEditableMaterialList(); - m_envMap = nil; SetEnvironmentMap(); } +void +CVehicleModelInfo::SetAnimFile(const char *file) +{ + if(strcasecmp(file, "null") == 0) + return; + + m_animFileName = new char[strlen(file)+1]; + strcpy(m_animFileName, file); +} + +void +CVehicleModelInfo::ConvertAnimFileIndex(void) +{ + if(m_animFileIndex != -1){ + // we have a string pointer in that union + int32 index = CAnimManager::GetAnimationBlockIndex(m_animFileName); + delete[] m_animFileName; + m_animFileIndex = index; + } +} + RwFrame* CVehicleModelInfo::CollapseFramesCB(RwFrame *frame, void *data) { @@ -386,30 +426,68 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data) RpAtomic* CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data) { - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); + char *name; + + name = GetFrameNodeName(RpAtomicGetFrame(atomic)); + if(strncmp(name, "toprotor", 8) == 0) + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleRotorAlphaCB); + else if(strncmp(name, "rearrotor", 9) == 0) + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB); + else + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); + return atomic; +} + +RpAtomic* +CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data) +{ + RpClump *clump; + char *name; + bool alpha; + + clump = (RpClump*)data; + name = GetFrameNodeName(RpAtomicGetFrame(atomic)); + alpha = false; + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha); + if(strncmp(name, "toprotor", 8) == 0) + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleRotorAlphaCB); + else if(strncmp(name, "rearrotor", 9) == 0) + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB); + else if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) { + if(alpha || strncmp(name, "windscreen", 10) == 0) + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB); + else + 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::RenderVehicleReallyLowDetailCB); + else + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); + HideDamagedAtomicCB(atomic, nil); return atomic; } void CVehicleModelInfo::SetAtomicRenderCallbacks(void) { - switch(m_vehicleType){ - case VEHICLE_TYPE_TRAIN: +#ifdef GTA_TRAIN + if(m_vehicleType == VEHICLE_TYPE_TRAIN) RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Train, nil); - break; - case VEHICLE_TYPE_HELI: + else +#endif + if(m_vehicleType == VEHICLE_TYPE_HELI) RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Heli, nil); - break; - case VEHICLE_TYPE_PLANE: + else if(m_vehicleType == VEHICLE_TYPE_PLANE) RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_BigVehicle, nil); - break; - case VEHICLE_TYPE_BOAT: + else if(m_vehicleType == VEHICLE_TYPE_BOAT) RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump); - break; - default: + 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); - break; - } } RwObject* @@ -606,6 +684,17 @@ ChooseComponent(int32 rule, int32 comps) // only valid in rain n = CGeneral::GetRandomNumberInRange(0, CountCompsInRule(comps)); return COMPRULE_COMPN(comps, n); + case 3: + n = CGeneral::GetRandomNumberInRange(0, 1+CountCompsInRule(comps)); + if(n != 0) + return COMPRULE_COMPN(comps, n-1); + return -1; + case 4: +#ifdef FIX_BUGS + return CGeneral::GetRandomNumberInRange(0, 6); +#else + return CGeneral::GetRandomNumberInRange(0, 5); +#endif } return -1; } @@ -732,6 +821,9 @@ CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic *atomic, void *data) return atomic; } +static int maxFirstMaterials; +static int maxSecondMaterials; + void CVehicleModelInfo::FindEditableMaterialList(void) { @@ -746,6 +838,8 @@ CVehicleModelInfo::FindEditableMaterialList(void) GetEditableMaterialListCB(m_comps[i], &cbdata); m_materials1[cbdata.numMats1] = nil; m_materials2[cbdata.numMats2] = nil; + maxFirstMaterials = Max(maxFirstMaterials, cbdata.numMats1); + maxSecondMaterials = Max(maxSecondMaterials, cbdata.numMats2); m_currentColour1 = -1; m_currentColour2 = -1; } @@ -754,35 +848,26 @@ void CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2) { RwRGBA col, *colp; - RwTexture *coltex; RpMaterial **matp; if(c1 != m_currentColour1){ col = ms_vehicleColourTable[c1]; - coltex = ms_colourTextureTable[c1]; for(matp = m_materials1; *matp; matp++){ - if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){ - colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const - colp->red = col.red; - colp->green = col.green; - colp->blue = col.blue; - }else - RpMaterialSetTexture(*matp, coltex); + colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const + colp->red = col.red; + colp->green = col.green; + colp->blue = col.blue; } m_currentColour1 = c1; } if(c2 != m_currentColour2){ col = ms_vehicleColourTable[c2]; - coltex = ms_colourTextureTable[c2]; for(matp = m_materials2; *matp; matp++){ - if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){ - colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const - colp->red = col.red; - colp->green = col.green; - colp->blue = col.blue; - }else - RpMaterialSetTexture(*matp, coltex); + colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const + colp->red = col.red; + colp->green = col.green; + colp->blue = col.blue; } m_currentColour2 = c2; } @@ -791,9 +876,12 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2) void CVehicleModelInfo::ChooseVehicleColour(uint8 &col1, uint8 &col2) { - if(m_numColours == 0){ + if(m_numColours == 0 || gbBlackCars){ col1 = 0; col2 = 0; + }else if(gbPinkCars){ + col1 = 68; + col2 = 68; }else{ m_lastColorVariation = (m_lastColorVariation+1) % m_numColours; col1 = m_colours1[m_lastColorVariation]; @@ -816,18 +904,27 @@ CVehicleModelInfo::AvoidSameVehicleColour(uint8 *col1, uint8 *col2) { int i, n; - if(m_numColours > 1) - for(i = 0; i < 8; i++){ - if(*col1 != m_lastColour1 || *col2 != m_lastColour2) - break; - n = CGeneral::GetRandomNumberInRange(0, m_numColours); - *col1 = m_colours1[n]; - *col2 = m_colours2[n]; - } - m_lastColour1 = *col1; - m_lastColour2 = *col2; + if(gbBlackCars){ + *col1 = 0; + *col2 = 0; + }else if(gbPinkCars){ + *col1 = 68; + *col2 = 68; + }else{ + if(m_numColours > 1) + for(i = 0; i < 8; i++){ + if(*col1 != m_lastColour1 || *col2 != m_lastColour2) + break; + n = CGeneral::GetRandomNumberInRange(0, m_numColours); + *col1 = m_colours1[n]; + *col2 = m_colours2[n]; + } + m_lastColour1 = *col1; + m_lastColour2 = *col2; + } } +//--MIAMI: unused RwTexture* CreateCarColourTexture(uint8 r, uint8 g, uint8 b) { @@ -916,7 +1013,7 @@ CVehicleModelInfo::LoadVehicleColours(void) if(section == NONE){ if(line[start] == 'c' && line[start + 1] == 'o' && line[start + 2] == 'l') section = COLOURS; - else if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r') + if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r') section = CARS; }else if(line[start] == 'e' && line[start + 1] == 'n' && line[start + 2] == 'd'){ section = NONE; @@ -927,7 +1024,6 @@ CVehicleModelInfo::LoadVehicleColours(void) ms_vehicleColourTable[numCols].green = g; ms_vehicleColourTable[numCols].blue = b; ms_vehicleColourTable[numCols].alpha = 0xFF; - ms_colourTextureTable[numCols] = CreateCarColourTexture(r, g, b); numCols++; }else if(section == CARS){ n = sscanf(&line[start], // BUG: games doesn't add start @@ -962,63 +1058,49 @@ CVehicleModelInfo::DeleteVehicleColourTextures(void) for(i = 0; i < 256; i++){ if(ms_colourTextureTable[i]){ RwTextureDestroy(ms_colourTextureTable[i]); -#if GTA_VERSION >= GTA3_PC_11 ms_colourTextureTable[i] = nil; -#endif } } } RpMaterial* -CVehicleModelInfo::HasSpecularMaterialCB(RpMaterial *material, void *data) +CVehicleModelInfo::GetMatFXEffectMaterialCB(RpMaterial *material, void *data) { - if(RpMaterialGetSurfaceProperties(material)->specular <= 0.0f) + if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTNULL) return material; - *(bool*)data = true; + *(int*)data = RpMatFXMaterialGetEffects(material); return nil; } RpMaterial* -CVehicleModelInfo::SetEnvironmentMapCB(RpMaterial *material, void *data) +CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data) { - float spec; - - spec = RpMaterialGetSurfaceProperties(material)->specular; - if(spec <= 0.0f) - RpMatFXMaterialSetEffects(material, rpMATFXEFFECTNULL); - else{ + if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTENVMAP){ + RpMatFXMaterialSetEnvMapFrame(material, pMatFxIdentityFrame); if(RpMaterialGetTexture(material) == nil) RpMaterialSetTexture(material, gpWhiteTexture); RpMatFXMaterialSetEffects(material, rpMATFXEFFECTENVMAP); #ifndef PS2_MATFX - spec *= 0.5f; // Tone down a bit for PC + float coef = RpMatFXMaterialGetEnvMapCoefficient(material); + coef *= 0.25f; // Tone down a bit for PC + RpMatFXMaterialSetEnvMapCoefficient(material, coef); #endif - RpMatFXMaterialSetupEnvMap(material, (RwTexture*)data, pMatFxIdentityFrame, false, spec); } return material; } -bool initialised; - RpAtomic* CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data) { - bool hasSpec; + int fx; RpGeometry *geo; geo = RpAtomicGetGeometry(atomic); - hasSpec = 0; - RpGeometryForAllMaterials(geo, HasSpecularMaterialCB, &hasSpec); - if(hasSpec){ - RpGeometryForAllMaterials(geo, SetEnvironmentMapCB, data); - RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) | rpGEOMETRYMODULATEMATERIALCOLOR); + fx = rpMATFXEFFECTNULL; + RpGeometryForAllMaterials(geo, GetMatFXEffectMaterialCB, &fx); + if(fx != rpMATFXEFFECTNULL){ RpMatFXAtomicEnableEffects(atomic); -#ifdef GTA_PS2 - if(!initialised){ - SetupPS2ManagerLightingCallback(RpAtomicGetInstancePipeline(atomic)); - initialised = true; - } -#endif + RpGeometryForAllMaterials(geo, SetDefaultEnvironmentMapCB, data); } return atomic; } @@ -1030,20 +1112,18 @@ CVehicleModelInfo::SetEnvironmentMap(void) int32 i; if(pMatFxIdentityFrame == nil){ + RwV3d axis = { 1.0f, 0.0f, 0.0f }; pMatFxIdentityFrame = RwFrameCreate(); - RwMatrixSetIdentity(RwFrameGetMatrix(pMatFxIdentityFrame)); + RwMatrixRotate(RwFrameGetMatrix(pMatFxIdentityFrame), &axis, 60.0f, rwCOMBINEREPLACE); RwFrameUpdateObjects(pMatFxIdentityFrame); RwFrameGetLTM(pMatFxIdentityFrame); } - if(m_envMap != ms_pEnvironmentMaps[0]){ - m_envMap = ms_pEnvironmentMaps[0]; - RpClumpForAllAtomics(m_clump, SetEnvironmentMapCB, m_envMap); - if(m_wheelId != -1){ - wheelmi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_wheelId); - for(i = 0; i < wheelmi->m_numAtomics; i++) - SetEnvironmentMapCB(wheelmi->m_atomics[i], m_envMap); - } + RpClumpForAllAtomics(m_clump, SetEnvironmentMapCB, nil); + if(m_wheelId != -1){ + wheelmi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_wheelId); + for(i = 0; i < wheelmi->m_numAtomics; i++) + SetEnvironmentMapCB(wheelmi->m_atomics[i], nil); } #ifdef EXTENDED_PIPELINES @@ -1054,24 +1134,11 @@ CVehicleModelInfo::SetEnvironmentMap(void) void CVehicleModelInfo::LoadEnvironmentMaps(void) { - const char *texnames[] = { - "reflection01", // only one used - "reflection02", - "reflection03", - "reflection04", - "reflection05", - "reflection06", - }; int32 txdslot; - int32 i; txdslot = CTxdStore::FindTxdSlot("particle"); CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(txdslot); - for(i = 0; i < NUM_VEHICLE_ENVMAPS; i++){ - ms_pEnvironmentMaps[i] = RwTextureRead(texnames[i], nil); - RwTextureSetFilterMode(ms_pEnvironmentMaps[i], rwFILTERLINEAR); - } if(gpWhiteTexture == nil){ gpWhiteTexture = RwTextureRead("white", nil); RwTextureGetName(gpWhiteTexture)[0] = '@'; @@ -1083,14 +1150,8 @@ CVehicleModelInfo::LoadEnvironmentMaps(void) void CVehicleModelInfo::ShutdownEnvironmentMaps(void) { - int32 i; - - // ignoring "initialised" as that's a PS2 thing only RwTextureDestroy(gpWhiteTexture); gpWhiteTexture = nil; - for(i = 0; i < NUM_VEHICLE_ENVMAPS; i++) - if(ms_pEnvironmentMaps[i]) - RwTextureDestroy(ms_pEnvironmentMaps[i]); RwFrameDestroy(pMatFxIdentityFrame); pMatFxIdentityFrame = nil; } @@ -1107,12 +1168,15 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id) case MI_FIRETRUCK: n = 2; break; + case MI_HUNTER: + n = 1; + break; default: n = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(id))->m_numDoors; } if(n == 0) - return id == MI_RCBANDIT ? 0 : 1; + return id == MI_RCBANDIT || id == MI_PIZZABOY || id == MI_BAGGAGE ? 0 : 1; if(id == MI_COACH) return 8; |