mirror of
https://github.com/GTAmodding/re3.git
synced 2021-02-19 17:49:54 +01:00
more PS2 stuff; memory movement done
This commit is contained in:
parent
3c24505990
commit
13cefd3293
@ -40,7 +40,7 @@ CTempColModels::Initialise(void)
|
|||||||
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
|
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
|
||||||
colmodel.spheres = sphrs;\
|
colmodel.spheres = sphrs;\
|
||||||
colmodel.level = LEVEL_GENERIC;\
|
colmodel.level = LEVEL_GENERIC;\
|
||||||
colmodel.ownsCollisionVolumes = false;\
|
colmodel.ownsCollisionVolumes = false;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1032,17 +1032,261 @@ void CGame::Process(void)
|
|||||||
|
|
||||||
int32 gNumMemMoved;
|
int32 gNumMemMoved;
|
||||||
|
|
||||||
|
bool
|
||||||
|
MoveMem(void **ptr)
|
||||||
|
{
|
||||||
|
if(*ptr){
|
||||||
|
gNumMemMoved++;
|
||||||
|
void *newPtr = gMainHeap.MoveMemory(*ptr);
|
||||||
|
if(*ptr != newPtr){
|
||||||
|
*ptr = newPtr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _SkyRasterExt _SkyRasterExt;
|
||||||
|
struct _SkyRasterExt
|
||||||
|
{
|
||||||
|
RwInt32 dmaRefCount; /**< Internal use */
|
||||||
|
RwInt32 dmaClrCount; /**< Internal use */
|
||||||
|
|
||||||
|
/* General texture setup register */
|
||||||
|
RwUInt32 lsb; /**< Internal use */
|
||||||
|
RwUInt32 msb; /**< Internal use */
|
||||||
|
RwUInt32 palOffset; /**< Internal use */
|
||||||
|
|
||||||
|
/* K: a 12 bit 8.4 value in bottom bits */
|
||||||
|
/* L: a 2 bit value in 12,13 */
|
||||||
|
RwUInt16 mipmapKL; /**< Internal use */
|
||||||
|
/* NOTE: This is left shifted two */
|
||||||
|
RwUInt8 maxMipLevel; /**< Internal use */
|
||||||
|
/* Is this texture to stay in the cache? */
|
||||||
|
RwUInt8 bLocked; /**< Internal use */
|
||||||
|
|
||||||
|
/* Mipmap addresses */
|
||||||
|
RwUInt32 miptbp1Lsb; /**< Internal use */
|
||||||
|
RwUInt32 miptbp1Msb; /**< Internal use */
|
||||||
|
RwUInt32 miptbp2Lsb; /**< Internal use */
|
||||||
|
RwUInt32 miptbp2Msb; /**< Internal use */
|
||||||
|
|
||||||
|
/* Size in bytes in system memory for pixels */
|
||||||
|
RwUInt32 sysMemSize; /**< Internal use */
|
||||||
|
/* Size in bytes in system memory for palette */
|
||||||
|
RwUInt32 sysMemPalSize; /**< Internal use */
|
||||||
|
|
||||||
|
/* Size in words in video memory for pixels + palette */
|
||||||
|
RwUInt32 nTexCacheSize; /**< Internal use */
|
||||||
|
|
||||||
|
/* Should we cache packets for this raster */
|
||||||
|
RwUInt8 cachePkts; /**< Internal use */
|
||||||
|
RwUInt8 lockedMipLevel; /**< Currently locked mip level */
|
||||||
|
RwUInt8 flags; /**< Bit 0 new format texture */
|
||||||
|
/**< Bit 1 twiddled (->32) */
|
||||||
|
/**< Bit 2 twiddled (->16) */
|
||||||
|
RwUInt8 pad[1]; /**< Internal use */
|
||||||
|
#if defined(GSB) && defined(GSPLUS)
|
||||||
|
RwUInt32 lsb3; /**< Internal use */
|
||||||
|
RwUInt32 msb3; /**< Internal use */
|
||||||
|
RwUInt32 miptbp3Lsb, miptbp3Msb; /**< Internal use */
|
||||||
|
RwUInt32 miptbp4Lsb, miptbp4Msb; /**< Internal use */
|
||||||
|
#endif /* defined(GSB) && defined(GSPLUS) */
|
||||||
|
};
|
||||||
|
uint32 skyRasterExt;
|
||||||
|
#define RASTEREXTFROMRASTER(raster) \
|
||||||
|
((_SkyRasterExt *)(((RwUInt8 *)(raster)) + skyRasterExt))
|
||||||
|
|
||||||
|
|
||||||
|
// Some convenience structs
|
||||||
|
struct SkyDataPrefix
|
||||||
|
{
|
||||||
|
uint32 pktSize1;
|
||||||
|
uint32 data; // pointer to data as read from TXD
|
||||||
|
uint32 pktSize2;
|
||||||
|
uint32 unused;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DMAGIFUpload
|
||||||
|
{
|
||||||
|
uint32 tag1_qwc, tag1_addr; // dmaref
|
||||||
|
uint32 nop1, vif_direct1;
|
||||||
|
|
||||||
|
uint32 giftag[4];
|
||||||
|
uint32 gs_bitbltbuf[4];
|
||||||
|
|
||||||
|
uint32 tag2_qwc, tag2_addr; // dmaref
|
||||||
|
uint32 nop2, vif_direct2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot
|
||||||
RwTexture *
|
RwTexture *
|
||||||
MoveTextureMemoryCB(RwTexture *texture, void *pData)
|
MoveTextureMemoryCB(RwTexture *texture, void *pData)
|
||||||
{
|
{
|
||||||
// TODO
|
#ifdef GTA_PS2
|
||||||
|
bool *pRet = (bool*)pData;
|
||||||
|
RwRaster *raster = RwTextureGetRaster(texture);
|
||||||
|
_SkyRasterExt *rasterExt = RASTEREXTFROMRASTER(raster);
|
||||||
|
if(raster->originalPixels == nil || // the raw data
|
||||||
|
raster->cpPixels == raster->originalPixels || // old format, can't handle it
|
||||||
|
rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0)
|
||||||
|
return texture;
|
||||||
|
|
||||||
|
// this is the allocated pointer we will move
|
||||||
|
SkyDataPrefix *prefix = (SkyDataPrefix*)raster->originalPixels;
|
||||||
|
DMAGIFUpload *uploads = (DMAGIFUpload*)(prefix+1);
|
||||||
|
|
||||||
|
// We have 4qw for each upload,
|
||||||
|
// i.e. for each buffer width of mip levels,
|
||||||
|
// and the palette if there is one.
|
||||||
|
// NB: this code does NOT support mipmaps!
|
||||||
|
// so we assume two uploads (pixels and palette)
|
||||||
|
//
|
||||||
|
// each upload looks like this:
|
||||||
|
// (DMAcnt; NOP; VIF DIRECT(2))
|
||||||
|
// giftag (1, A+D)
|
||||||
|
// GS_BITBLTBUF
|
||||||
|
// (DMAref->pixel data; NOP; VIF DIRECT(5))
|
||||||
|
// the DMArefs are what we have to adjust
|
||||||
|
uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff;
|
||||||
|
dataDiff = prefix->data - (uintptr)raster->originalPixels;
|
||||||
|
upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels;
|
||||||
|
if(raster->palette)
|
||||||
|
upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels;
|
||||||
|
pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels;
|
||||||
|
if(raster->palette)
|
||||||
|
paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels;
|
||||||
|
uint8 *newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels);
|
||||||
|
if(newptr != raster->originalPixels){
|
||||||
|
// adjust everything
|
||||||
|
prefix->data = (uintptr)newptr + dataDiff;
|
||||||
|
uploads[0].tag2_addr = (uintptr)newptr + upload1Diff;
|
||||||
|
if(raster->palette)
|
||||||
|
uploads[1].tag2_addr = (uintptr)newptr + upload2Diff;
|
||||||
|
raster->originalPixels = newptr;
|
||||||
|
raster->cpPixels = newptr + pixelDiff;
|
||||||
|
if(raster->palette)
|
||||||
|
raster->palette = newptr + paletteDiff;
|
||||||
|
|
||||||
|
if(pRet){
|
||||||
|
*pRet = true;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// nothing to do here really, everything should be in videomemory
|
||||||
|
#endif
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TidyUpModelInfo(CBaseModelInfo *,bool)
|
MoveAtomicMemory(RpAtomic *atomic, bool onlyOne)
|
||||||
{
|
{
|
||||||
// TODO
|
RpGeometry *geo = RpAtomicGetGeometry(atomic);
|
||||||
|
|
||||||
|
#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
|
||||||
|
if(MoveMem((void**)&geo->triangles) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&geo->matList.materials) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&geo->preLitLum) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&geo->texCoords[0]) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&geo->texCoords[1]) && onlyOne)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// verts and normals of morph target are allocated together
|
||||||
|
int vertDiff;
|
||||||
|
if(geo->morphTarget->normals)
|
||||||
|
vertDiff = geo->morphTarget->normals - geo->morphTarget->verts;
|
||||||
|
if(MoveMem((void**)&geo->morphTarget->verts)){
|
||||||
|
if(geo->morphTarget->normals)
|
||||||
|
geo->morphTarget->normals = geo->morphTarget->verts + vertDiff;
|
||||||
|
if(onlyOne)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RpMeshHeader *oldmesh = geo->mesh;
|
||||||
|
if(MoveMem((void**)&geo->mesh)){
|
||||||
|
// index pointers are allocated together with meshes,
|
||||||
|
// have to relocate those too
|
||||||
|
RpMesh *mesh = (RpMesh*)(geo->mesh+1);
|
||||||
|
uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh;
|
||||||
|
for(int i = 0; i < geo->mesh->numMeshes; i++)
|
||||||
|
mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc);
|
||||||
|
if(onlyOne)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// we could do something in librw here
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MoveColModelMemory(CColModel &colModel, bool onlyOne)
|
||||||
|
{
|
||||||
|
#if GTA_VERSION >= GTA3_PS2_160
|
||||||
|
// hm...should probably only do this if ownsCollisionVolumes
|
||||||
|
// but it doesn't exist on PS2...
|
||||||
|
if(!colModel.ownsCollisionVolumes)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(MoveMem((void**)&colModel.spheres) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&colModel.lines) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&colModel.boxes) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&colModel.vertices) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&colModel.triangles) && onlyOne)
|
||||||
|
return true;
|
||||||
|
if(MoveMem((void**)&colModel.trianglePlanes) && onlyOne)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RpAtomic*
|
||||||
|
MoveAtomicMemoryCB(RpAtomic *atomic, void *pData)
|
||||||
|
{
|
||||||
|
bool *pRet = (bool*)pData;
|
||||||
|
if(pRet == nil)
|
||||||
|
MoveAtomicMemory(atomic, false);
|
||||||
|
else if(MoveAtomicMemory(atomic, true)){
|
||||||
|
*pRet = true;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return atomic;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TidyUpModelInfo(CBaseModelInfo *modelInfo, bool onlyone)
|
||||||
|
{
|
||||||
|
if(modelInfo->GetColModel() && modelInfo->DoesOwnColModel())
|
||||||
|
if(MoveColModelMemory(*modelInfo->GetColModel(), onlyone))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
RwObject *rwobj = modelInfo->GetRwObject();
|
||||||
|
if(RwObjectGetType(rwobj) == rpATOMIC)
|
||||||
|
if(MoveAtomicMemory((RpAtomic*)rwobj, onlyone))
|
||||||
|
return true;
|
||||||
|
if(RwObjectGetType(rwobj) == rpCLUMP){
|
||||||
|
bool ret = false;
|
||||||
|
if(onlyone)
|
||||||
|
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret);
|
||||||
|
else
|
||||||
|
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil);
|
||||||
|
if(ret)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel)
|
||||||
|
if(MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,24 +922,24 @@ CEntity *
|
|||||||
CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
|
CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
|
||||||
bool ignoreSomeObjects)
|
bool ignoreSomeObjects)
|
||||||
{
|
{
|
||||||
static CColModel sphereCol;
|
static CColModel OurColModel;
|
||||||
|
|
||||||
sphereCol.boundingSphere.center.x = 0.0f;
|
OurColModel.boundingSphere.center.x = 0.0f;
|
||||||
sphereCol.boundingSphere.center.y = 0.0f;
|
OurColModel.boundingSphere.center.y = 0.0f;
|
||||||
sphereCol.boundingSphere.center.z = 0.0f;
|
OurColModel.boundingSphere.center.z = 0.0f;
|
||||||
sphereCol.boundingSphere.radius = radius;
|
OurColModel.boundingSphere.radius = radius;
|
||||||
sphereCol.boundingBox.min.x = -radius;
|
OurColModel.boundingBox.min.x = -radius;
|
||||||
sphereCol.boundingBox.min.y = -radius;
|
OurColModel.boundingBox.min.y = -radius;
|
||||||
sphereCol.boundingBox.min.z = -radius;
|
OurColModel.boundingBox.min.z = -radius;
|
||||||
sphereCol.boundingBox.max.x = radius;
|
OurColModel.boundingBox.max.x = radius;
|
||||||
sphereCol.boundingBox.max.y = radius;
|
OurColModel.boundingBox.max.y = radius;
|
||||||
sphereCol.boundingBox.max.z = radius;
|
OurColModel.boundingBox.max.z = radius;
|
||||||
sphereCol.numSpheres = 1;
|
OurColModel.numSpheres = 1;
|
||||||
sphereCol.spheres = &sphereCol.boundingSphere;
|
OurColModel.spheres = &OurColModel.boundingSphere;
|
||||||
sphereCol.numLines = 0;
|
OurColModel.numLines = 0;
|
||||||
sphereCol.numBoxes = 0;
|
OurColModel.numBoxes = 0;
|
||||||
sphereCol.numTriangles = 0;
|
OurColModel.numTriangles = 0;
|
||||||
sphereCol.ownsCollisionVolumes = false;
|
OurColModel.ownsCollisionVolumes = false;
|
||||||
|
|
||||||
CMatrix sphereMat;
|
CMatrix sphereMat;
|
||||||
sphereMat.SetTranslate(spherePos);
|
sphereMat.SetTranslate(spherePos);
|
||||||
@ -962,7 +962,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
|
|||||||
if(e->GetBoundRadius() + radius > distance) {
|
if(e->GetBoundRadius() + radius > distance) {
|
||||||
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
|
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
|
||||||
int collidedSpheres =
|
int collidedSpheres =
|
||||||
CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol,
|
CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol,
|
||||||
gaTempSphereColPoints, nil, nil);
|
gaTempSphereColPoints, nil, nil);
|
||||||
|
|
||||||
if(collidedSpheres != 0 ||
|
if(collidedSpheres != 0 ||
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
enum Config {
|
enum Config {
|
||||||
NUMPLAYERS = 1,
|
NUMPLAYERS = 1, // 4 on PS2
|
||||||
|
|
||||||
NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
|
NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
|
||||||
MAX_CDIMAGES = 8, // additional cdimages
|
MAX_CDIMAGES = 8, // additional cdimages
|
||||||
MAX_CDCHANNELS = 5,
|
MAX_CDCHANNELS = 5,
|
||||||
|
|
||||||
MODELINFOSIZE = 5500,
|
MODELINFOSIZE = 5500, // 3150 on PS2
|
||||||
// TXDSTORESIZE = 850,
|
// TXDSTORESIZE = 850,
|
||||||
TXDSTORESIZE = 1024, // for Xbox map
|
TXDSTORESIZE = 1024, // for Xbox map
|
||||||
EXTRADIRSIZE = 128,
|
EXTRADIRSIZE = 128,
|
||||||
CUTSCENEDIRSIZE = 512,
|
CUTSCENEDIRSIZE = 512,
|
||||||
|
|
||||||
SIMPLEMODELSIZE = 5000,
|
SIMPLEMODELSIZE = 5000, // 2910 on PS2
|
||||||
MLOMODELSIZE = 1,
|
MLOMODELSIZE = 1,
|
||||||
MLOINSTANCESIZE = 1,
|
MLOINSTANCESIZE = 1,
|
||||||
TIMEMODELSIZE = 30,
|
TIMEMODELSIZE = 30,
|
||||||
CLUMPMODELSIZE = 5,
|
CLUMPMODELSIZE = 5,
|
||||||
PEDMODELSIZE = 90,
|
PEDMODELSIZE = 90,
|
||||||
VEHICLEMODELSIZE = 120,
|
VEHICLEMODELSIZE = 120, // 70 on PS2
|
||||||
XTRACOMPSMODELSIZE = 2,
|
XTRACOMPSMODELSIZE = 2,
|
||||||
TWODFXSIZE = 2000,
|
TWODFXSIZE = 2000, // 1210 on PS2
|
||||||
|
|
||||||
MAXVEHICLESLOADED = 50, // 70 on mobile
|
MAXVEHICLESLOADED = 50, // 70 on mobile
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ public:
|
|||||||
bool DoesOwnColModel(void) { return m_bOwnsColModel; }
|
bool DoesOwnColModel(void) { return m_bOwnsColModel; }
|
||||||
void DeleteCollisionModel(void);
|
void DeleteCollisionModel(void);
|
||||||
void ClearTexDictionary(void) { m_txdSlot = -1; }
|
void ClearTexDictionary(void) { m_txdSlot = -1; }
|
||||||
short GetObjectID(void) { return m_objectId; }
|
int16 GetObjectID(void) { return m_objectId; }
|
||||||
void SetObjectID(int16 id) { m_objectId = id; }
|
void SetObjectID(int16 id) { m_objectId = id; }
|
||||||
short GetTxdSlot(void) { return m_txdSlot; }
|
int16 GetTxdSlot(void) { return m_txdSlot; }
|
||||||
void AddRef(void);
|
void AddRef(void);
|
||||||
void RemoveRef(void);
|
void RemoveRef(void);
|
||||||
void SetTexDictionary(const char *name);
|
void SetTexDictionary(const char *name);
|
||||||
|
@ -11,6 +11,18 @@ public:
|
|||||||
float m_lodDistances[3];
|
float m_lodDistances[3];
|
||||||
uint8 m_numAtomics;
|
uint8 m_numAtomics;
|
||||||
uint8 m_alpha;
|
uint8 m_alpha;
|
||||||
|
/* // For reference, PS2 has:
|
||||||
|
uint8 m_firstDamaged;
|
||||||
|
uint8 m_normalCull : 1;
|
||||||
|
uint8 m_isDamaged : 1;
|
||||||
|
uint8 m_isBigBuilding : 1;
|
||||||
|
uint8 m_noFade : 1;
|
||||||
|
uint8 m_drawLast : 1;
|
||||||
|
uint8 m_additive : 1;
|
||||||
|
uint8 m_isSubway : 1;
|
||||||
|
uint8 m_ignoreLight : 1;
|
||||||
|
// m_noZwrite is missing because not needed
|
||||||
|
*/
|
||||||
uint16 m_firstDamaged : 2; // 0: no damage model
|
uint16 m_firstDamaged : 2; // 0: no damage model
|
||||||
// 1: 1 and 2 are damage models
|
// 1: 1 and 2 are damage models
|
||||||
// 2: 2 is damage model
|
// 2: 2 is damage model
|
||||||
|
@ -778,8 +778,10 @@ CHeli::InitHelis(void)
|
|||||||
for(i = 0; i < NUM_HELIS; i++)
|
for(i = 0; i < NUM_HELIS; i++)
|
||||||
pHelis[i] = nil;
|
pHelis[i] = nil;
|
||||||
|
|
||||||
|
#if GTA_VERSION >= GTA3_PS2_160
|
||||||
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1);
|
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
|
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeli*
|
CHeli*
|
||||||
@ -789,6 +791,13 @@ GenerateHeli(bool catalina)
|
|||||||
CVector heliPos;
|
CVector heliPos;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
#if GTA_VERSION < GTA3_PS2_160
|
||||||
|
if(catalina)
|
||||||
|
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
|
else
|
||||||
|
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(catalina)
|
if(catalina)
|
||||||
heli = new CHeli(MI_ESCAPE, PERMANENT_VEHICLE);
|
heli = new CHeli(MI_ESCAPE, PERMANENT_VEHICLE);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user