first part of CFileLoader
This commit is contained in:
parent
fcc6a8bc55
commit
b5fba778c4
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
936
src/FileLoader.cpp
Normal file
936
src/FileLoader.cpp
Normal file
@ -0,0 +1,936 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "ModelInfo.h"
|
||||||
|
#include "ModelIndices.h"
|
||||||
|
#include "TempColModels.h"
|
||||||
|
#include "HandlingDataMgr.h"
|
||||||
|
#include "CarCtrl.h"
|
||||||
|
#include "PedType.h"
|
||||||
|
#include "PedStats.h"
|
||||||
|
#include "AnimManager.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "RwHelper.h"
|
||||||
|
#include "NodeName.h"
|
||||||
|
#include "TxdStore.h"
|
||||||
|
#include "PathFind.h"
|
||||||
|
#include "VisibilityPlugins.h"
|
||||||
|
#include "FileMgr.h"
|
||||||
|
#include "FileLoader.h"
|
||||||
|
|
||||||
|
char CFileLoader::ms_line[256];
|
||||||
|
|
||||||
|
const char*
|
||||||
|
GetFilename(const char *filename)
|
||||||
|
{
|
||||||
|
char *s = strrchr((char*)filename, '\\');
|
||||||
|
return s ? s+1 : filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LoadingScreenLoadingFile(const char *filename)
|
||||||
|
{
|
||||||
|
sprintf(gString, "Loading %s", GetFilename(filename));
|
||||||
|
LoadingScreen("Loading the Game", gString, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadLevel(const char *filename)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
RwTexDictionary *savedTxd;
|
||||||
|
int savedLevel;
|
||||||
|
bool objectsLoaded;
|
||||||
|
char *line;
|
||||||
|
char txdname[64];
|
||||||
|
|
||||||
|
savedTxd = RwTexDictionaryGetCurrent();
|
||||||
|
objectsLoaded = false;
|
||||||
|
savedLevel = CGame::currLevel;
|
||||||
|
if(savedTxd == nil){
|
||||||
|
savedTxd = RwTexDictionaryCreate();
|
||||||
|
RwTexDictionarySetCurrent(savedTxd);
|
||||||
|
}
|
||||||
|
fd = CFileMgr::OpenFile(filename, "r");
|
||||||
|
assert(fd > 0);
|
||||||
|
|
||||||
|
for(line = LoadLine(fd); line; line = LoadLine(fd)){
|
||||||
|
if(*line == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(strncmp(line, "EXIT", 9) == 0) // BUG: 9?
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(strncmp(line, "IMAGEPATH", 9) == 0){
|
||||||
|
RwImageSetPath(line + 10);
|
||||||
|
}else if(strncmp(line, "TEXDICTION", 10) == 0){
|
||||||
|
strcpy(txdname, line+11);
|
||||||
|
LoadingScreenLoadingFile(txdname);
|
||||||
|
RwTexDictionary *txd = LoadTexDictionary(txdname);
|
||||||
|
AddTexDictionaries(savedTxd, txd);
|
||||||
|
RwTexDictionaryDestroy(txd);
|
||||||
|
}else if(strncmp(line, "COLFILE", 7) == 0){
|
||||||
|
int level;
|
||||||
|
sscanf(line+8, "%d", &level);
|
||||||
|
CGame::currLevel = level;
|
||||||
|
LoadingScreenLoadingFile(line+10);
|
||||||
|
LoadCollisionFile(line+10);
|
||||||
|
CGame::currLevel = savedLevel;
|
||||||
|
}else if(strncmp(line, "MODELFILE", 9) == 0){
|
||||||
|
LoadingScreenLoadingFile(line + 10);
|
||||||
|
LoadModelFile(line + 10);
|
||||||
|
}else if(strncmp(line, "HIERFILE", 8) == 0){
|
||||||
|
LoadingScreenLoadingFile(line + 9);
|
||||||
|
LoadClumpFile(line + 9);
|
||||||
|
}else if(strncmp(line, "IDE", 3) == 0){
|
||||||
|
LoadingScreenLoadingFile(line + 4);
|
||||||
|
LoadObjectTypes(line + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileMgr::CloseFile(fd);
|
||||||
|
RwTexDictionarySetCurrent(savedTxd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadCollisionFromDatFile(int currlevel)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
fd = CFileMgr::OpenFile(CGame::aDatFile, "r");
|
||||||
|
assert(fd > 0);
|
||||||
|
|
||||||
|
for(line = LoadLine(fd); line; line = LoadLine(fd)){
|
||||||
|
if(*line == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(strncmp(line, "COLFILE", 7) == 0){
|
||||||
|
int level;
|
||||||
|
sscanf(line+8, "%d", &level);
|
||||||
|
if(currlevel == level)
|
||||||
|
LoadCollisionFile(line+10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileMgr::CloseFile(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
CFileLoader::LoadLine(int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
if(CFileMgr::ReadLine(fd, ms_line, 256) == nil)
|
||||||
|
return nil;
|
||||||
|
for(i = 0; ms_line[i] != '\0'; i++)
|
||||||
|
if(ms_line[i] < ' ' || ms_line[i] == ',')
|
||||||
|
ms_line[i] = ' ';
|
||||||
|
for(line = ms_line; *line <= ' ' && *line != '\0'; line++);
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
RwTexDictionary*
|
||||||
|
CFileLoader::LoadTexDictionary(const char *filename)
|
||||||
|
{
|
||||||
|
RwTexDictionary *txd;
|
||||||
|
RwStream *stream;
|
||||||
|
|
||||||
|
txd = nil;
|
||||||
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
||||||
|
debug("Loading texture dictionary file %s\n", filename);
|
||||||
|
if(stream){
|
||||||
|
if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil))
|
||||||
|
txd = RwTexDictionaryGtaStreamRead(stream);
|
||||||
|
RwStreamClose(stream, nil);
|
||||||
|
}
|
||||||
|
if(txd == nil)
|
||||||
|
txd = RwTexDictionaryCreate();
|
||||||
|
return txd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadCollisionFile(const char *filename)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char modelname[24];
|
||||||
|
CBaseModelInfo *mi;
|
||||||
|
struct {
|
||||||
|
char ident[4];
|
||||||
|
uint32 size;
|
||||||
|
} header;
|
||||||
|
|
||||||
|
debug("Loading collision file %s\n", filename);
|
||||||
|
fd = CFileMgr::OpenFile(filename, "rb");
|
||||||
|
|
||||||
|
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
|
||||||
|
assert(strncmp(header.ident, "COLL", 4) == 0);
|
||||||
|
CFileMgr::Read(fd, (char*)work_buff, header.size);
|
||||||
|
memcpy(modelname, work_buff, 24);
|
||||||
|
|
||||||
|
mi = CModelInfo::GetModelInfo(modelname, nil);
|
||||||
|
if(mi){
|
||||||
|
if(mi->GetColModel()){
|
||||||
|
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
|
||||||
|
}else{
|
||||||
|
CColModel *model = new CColModel;
|
||||||
|
LoadCollisionModel(work_buff+24, *model, modelname);
|
||||||
|
mi->SetColModel(model, true);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
debug("colmodel %s can't find a modelinfo\n", modelname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileMgr::CloseFile(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
model.boundingSphere.radius = *(float*)(buf);
|
||||||
|
model.boundingSphere.center.x = *(float*)(buf+4);
|
||||||
|
model.boundingSphere.center.y = *(float*)(buf+8);
|
||||||
|
model.boundingSphere.center.z = *(float*)(buf+12);
|
||||||
|
model.boundingBox.min.x = *(float*)(buf+16);
|
||||||
|
model.boundingBox.min.y = *(float*)(buf+20);
|
||||||
|
model.boundingBox.min.z = *(float*)(buf+24);
|
||||||
|
model.boundingBox.max.x = *(float*)(buf+28);
|
||||||
|
model.boundingBox.max.y = *(float*)(buf+32);
|
||||||
|
model.boundingBox.max.z = *(float*)(buf+36);
|
||||||
|
model.numSpheres = *(int16*)(buf+40);
|
||||||
|
buf += 44;
|
||||||
|
if(model.numSpheres > 0){
|
||||||
|
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
|
||||||
|
for(i = 0; i < model.numSpheres; i++){
|
||||||
|
model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]);
|
||||||
|
buf += 20;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
model.spheres = nil;
|
||||||
|
|
||||||
|
model.numLines = *(int16*)buf;
|
||||||
|
buf += 4;
|
||||||
|
if(model.numLines > 0){
|
||||||
|
model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
|
||||||
|
for(i = 0; i < model.numLines; i++){
|
||||||
|
model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
|
||||||
|
buf += 24;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
model.lines = nil;
|
||||||
|
|
||||||
|
model.numBoxes = *(int16*)buf;
|
||||||
|
buf += 4;
|
||||||
|
if(model.numBoxes > 0){
|
||||||
|
model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox));
|
||||||
|
for(i = 0; i < model.numBoxes; i++){
|
||||||
|
model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]);
|
||||||
|
buf += 28;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
model.boxes = nil;
|
||||||
|
|
||||||
|
int32 numVertices = *(int16*)buf;
|
||||||
|
buf += 4;
|
||||||
|
if(numVertices > 0){
|
||||||
|
model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector));
|
||||||
|
for(i = 0; i < numVertices; i++){
|
||||||
|
model.vertices[i] = *(CVector*)buf;
|
||||||
|
if(fabs(model.vertices[i].x) >= 256.0f ||
|
||||||
|
fabs(model.vertices[i].y) >= 256.0f ||
|
||||||
|
fabs(model.vertices[i].z) >= 256.0f)
|
||||||
|
printf("%s:Collision volume too big\n", modelname);
|
||||||
|
buf += 12;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
model.vertices = nil;
|
||||||
|
|
||||||
|
model.numTriangles = *(int16*)buf;
|
||||||
|
buf += 4;
|
||||||
|
if(model.numTriangles > 0){
|
||||||
|
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
|
||||||
|
for(i = 0; i < model.numTriangles; i++){
|
||||||
|
model.triangles[i].Set(model.vertices, *(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12], buf[13]);
|
||||||
|
buf += 16;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
model.triangles = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GetNameAndLOD(char *nodename, char *name, int *n)
|
||||||
|
{
|
||||||
|
char *underscore = nil;
|
||||||
|
for(char *s = nodename; *s != '\0'; s++){
|
||||||
|
if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L'))
|
||||||
|
underscore = s;
|
||||||
|
}
|
||||||
|
if(underscore){
|
||||||
|
strncpy(name, nodename, underscore - nodename);
|
||||||
|
name[underscore - nodename] = '\0';
|
||||||
|
*n = atoi(underscore + 2);
|
||||||
|
}else{
|
||||||
|
strncpy(name, nodename, 24);
|
||||||
|
*n = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RpAtomic*
|
||||||
|
CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
|
||||||
|
{
|
||||||
|
CSimpleModelInfo *mi;
|
||||||
|
char *nodename, name[24];
|
||||||
|
int n;
|
||||||
|
RpClump *clump = (RpClump*)data;
|
||||||
|
|
||||||
|
nodename = GetFrameNodeName(RpClumpGetFrame(atomic));
|
||||||
|
GetNameAndLOD(nodename, name, &n);
|
||||||
|
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, 0);
|
||||||
|
if(mi){
|
||||||
|
assert(mi->IsSimple());
|
||||||
|
mi->SetAtomic(n, atomic);
|
||||||
|
RpClumpRemoveAtomic(clump, atomic);
|
||||||
|
RpAtomicSetFrame(atomic, RwFrameCreate());
|
||||||
|
CVisibilityPlugins::SetAtomicModelInfo(atomic, mi);
|
||||||
|
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
|
||||||
|
}else{
|
||||||
|
debug("Can't find Atomic %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return atomic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadModelFile(const char *filename)
|
||||||
|
{
|
||||||
|
RwStream *stream;
|
||||||
|
RpClump *clump;
|
||||||
|
|
||||||
|
debug("Loading model file %s\n", filename);
|
||||||
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
||||||
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump){
|
||||||
|
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
|
||||||
|
RpClumpDestroy(clump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RwStreamClose(stream, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadClumpFile(const char *filename)
|
||||||
|
{
|
||||||
|
RwStream *stream;
|
||||||
|
RpClump *clump;
|
||||||
|
char *nodename, name[24];
|
||||||
|
int n;
|
||||||
|
CClumpModelInfo *mi;
|
||||||
|
|
||||||
|
debug("Loading model file %s\n", filename);
|
||||||
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
||||||
|
while(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump){
|
||||||
|
nodename = GetFrameNodeName(RpClumpGetFrame(clump));
|
||||||
|
GetNameAndLOD(nodename, name, &n);
|
||||||
|
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, 0);
|
||||||
|
assert(mi->IsClump());
|
||||||
|
if(mi)
|
||||||
|
mi->SetClump(clump);
|
||||||
|
else
|
||||||
|
RpClumpDestroy(clump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RwStreamClose(stream, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
|
||||||
|
{
|
||||||
|
RpClump *clump;
|
||||||
|
CClumpModelInfo *mi;
|
||||||
|
|
||||||
|
if(!RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||||
|
return false;
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump == nil)
|
||||||
|
return false;
|
||||||
|
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
|
mi->SetClump(clump);
|
||||||
|
if(mi->m_type == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
|
// Read LOD ped
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump){
|
||||||
|
((CPedModelInfo*)mi)->SetLowDetailClump(clump);
|
||||||
|
RpClumpDestroy(clump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CFileLoader::StartLoadClumpFile(RwStream *stream, uint32 id)
|
||||||
|
{
|
||||||
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
|
printf("Start loading %s\n", CModelInfo::GetModelInfo(id)->GetName());
|
||||||
|
return RpClumpGtaStreamRead1(stream);
|
||||||
|
}else{
|
||||||
|
printf("FAILED\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
|
||||||
|
{
|
||||||
|
RpClump *clump;
|
||||||
|
CClumpModelInfo *mi;
|
||||||
|
|
||||||
|
printf("Finish loading %s\n", CModelInfo::GetModelInfo(id)->GetName());
|
||||||
|
clump = RpClumpGtaStreamRead2(stream);
|
||||||
|
|
||||||
|
if(clump){
|
||||||
|
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
|
mi->SetClump(clump);
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
printf("FAILED\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSimpleModelInfo *gpRelatedModelInfo;
|
||||||
|
|
||||||
|
bool
|
||||||
|
CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
|
||||||
|
{
|
||||||
|
RpClump *clump;
|
||||||
|
|
||||||
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump == nil)
|
||||||
|
return false;
|
||||||
|
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
|
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
|
||||||
|
RpClumpDestroy(clump);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RpAtomic*
|
||||||
|
CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data)
|
||||||
|
{
|
||||||
|
char *nodename, name[24];
|
||||||
|
int n;
|
||||||
|
RpClump *clump = (RpClump*)data;
|
||||||
|
|
||||||
|
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
|
||||||
|
GetNameAndLOD(nodename, name, &n);
|
||||||
|
gpRelatedModelInfo->SetAtomic(n, atomic);
|
||||||
|
RpClumpRemoveAtomic(clump, atomic);
|
||||||
|
RpAtomicSetFrame(atomic, RwFrameCreate());
|
||||||
|
CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo);
|
||||||
|
CVisibilityPlugins::SetAtomicRenderCallback(atomic, 0);
|
||||||
|
return atomic;
|
||||||
|
}
|
||||||
|
|
||||||
|
RpClump*
|
||||||
|
CFileLoader::LoadAtomicFile2Return(const char *filename)
|
||||||
|
{
|
||||||
|
RwStream *stream;
|
||||||
|
RpClump *clump;
|
||||||
|
|
||||||
|
clump = nil;
|
||||||
|
debug("Loading model file %s\n", filename);
|
||||||
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
||||||
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||||
|
clump = RpClumpStreamRead(stream);
|
||||||
|
RwStreamClose(stream, nil);
|
||||||
|
return clump;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RwTexture*
|
||||||
|
MoveTexturesCB(RwTexture *texture, void *pData)
|
||||||
|
{
|
||||||
|
RwTexDictionaryAddTexture((RwTexDictionary*)pData, texture);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src)
|
||||||
|
{
|
||||||
|
RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadObjectTypes(const char *filename)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
NONE,
|
||||||
|
OBJS,
|
||||||
|
MLO,
|
||||||
|
TOBJ,
|
||||||
|
HIER,
|
||||||
|
CARS,
|
||||||
|
PEDS,
|
||||||
|
PATH,
|
||||||
|
TWO2FX
|
||||||
|
};
|
||||||
|
char *line;
|
||||||
|
int fd;
|
||||||
|
int section;
|
||||||
|
int pathIndex;
|
||||||
|
char pathTypeStr[20];
|
||||||
|
int id, pathType;
|
||||||
|
// int mlo;
|
||||||
|
|
||||||
|
section = 0;
|
||||||
|
pathIndex = -1;
|
||||||
|
// mlo = 0;
|
||||||
|
debug("Loading object types from %s...\n", filename);
|
||||||
|
|
||||||
|
fd = CFileMgr::OpenFile(filename, "rb");
|
||||||
|
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
|
||||||
|
if(*line == '\0' || *line == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(section == NONE){
|
||||||
|
if(strncmp(line, "objs", 4) == 0) section = OBJS;
|
||||||
|
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ;
|
||||||
|
else if(strncmp(line, "hier", 4) == 0) section = HIER;
|
||||||
|
else if(strncmp(line, "cars", 4) == 0) section = CARS;
|
||||||
|
else if(strncmp(line, "peds", 4) == 0) section = PEDS;
|
||||||
|
else if(strncmp(line, "path", 4) == 0) section = PATH;
|
||||||
|
else if(strncmp(line, "2dfx", 4) == 0) section = TWO2FX;
|
||||||
|
}else if(strncmp(line, "end", 3) == 0){
|
||||||
|
section = section == MLO ? OBJS : NONE;
|
||||||
|
}else switch(section){
|
||||||
|
case OBJS:
|
||||||
|
if(strncmp(line, "sta", 3) == 0)
|
||||||
|
assert(0); // LoadMLO
|
||||||
|
else
|
||||||
|
LoadObject(line);
|
||||||
|
break;
|
||||||
|
case MLO:
|
||||||
|
assert(0); // LoadMLOInstance
|
||||||
|
break;
|
||||||
|
case TOBJ:
|
||||||
|
LoadTimeObject(line);
|
||||||
|
break;
|
||||||
|
case HIER:
|
||||||
|
LoadClumpObject(line);
|
||||||
|
break;
|
||||||
|
case CARS:
|
||||||
|
LoadVehicleObject(line);
|
||||||
|
break;
|
||||||
|
case PEDS:
|
||||||
|
LoadPedObject(line);
|
||||||
|
break;
|
||||||
|
case PATH:
|
||||||
|
if(pathIndex == -1){
|
||||||
|
id = LoadPathHeader(line, pathTypeStr);
|
||||||
|
if(strncmp(pathTypeStr, "ped", 4) == 0)
|
||||||
|
pathType = 1;
|
||||||
|
else if(strncmp(pathTypeStr, "car", 4) == 0)
|
||||||
|
pathType = 0;
|
||||||
|
pathIndex = 0;
|
||||||
|
}else{
|
||||||
|
if(pathType == 1)
|
||||||
|
LoadPedPathNode(line, id, pathIndex);
|
||||||
|
else if(pathType == 0)
|
||||||
|
LoadCarPathNode(line, id, pathIndex);
|
||||||
|
pathIndex++;
|
||||||
|
if(pathIndex == 12)
|
||||||
|
pathIndex = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TWO2FX:
|
||||||
|
Load2dEffect(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CFileMgr::CloseFile(fd);
|
||||||
|
|
||||||
|
for(id = 0; id < MODELINFOSIZE; id++){
|
||||||
|
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
|
if(mi && mi->IsSimple())
|
||||||
|
mi->SetupBigBuilding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags)
|
||||||
|
{
|
||||||
|
mi->m_normalCull = !!(flags & 1);
|
||||||
|
mi->m_noFade = !!(flags & 2);
|
||||||
|
mi->m_drawLast = !!(flags & (4|8));
|
||||||
|
mi->m_additive = !!(flags & 8);
|
||||||
|
mi->m_isSubway = !!(flags & 0x10);
|
||||||
|
mi->m_ignoreLight = !!(flags & 0x20);
|
||||||
|
mi->m_noZwrite = !!(flags & 0x40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadObject(const char *line)
|
||||||
|
{
|
||||||
|
int id, numObjs;
|
||||||
|
char model[24], txd[24];
|
||||||
|
float dist[3];
|
||||||
|
uint32 flags;
|
||||||
|
int damaged;
|
||||||
|
CSimpleModelInfo *mi;
|
||||||
|
|
||||||
|
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(numObjs){
|
||||||
|
case 1:
|
||||||
|
sscanf(line, "%d %s %s %d %f %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &flags);
|
||||||
|
damaged = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sscanf(line, "%d %s %s %d %f %f %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &dist[1], &flags);
|
||||||
|
damaged = dist[0] < dist[1] ? // Are distances increasing?
|
||||||
|
0 : // Yes, no damage model
|
||||||
|
1; // No, 1 is damaged
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sscanf(line, "%d %s %s %d %f %f %f %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &dist[1], &dist[2], &flags);
|
||||||
|
damaged = dist[0] < dist[1] ? // Are distances increasing?
|
||||||
|
(dist[1] < dist[2] ? 0 : 2) : // Yes, only 2 can still be a damage model
|
||||||
|
1; // No, 1 and 2 are damaged
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mi = CModelInfo::AddSimpleModel(id);
|
||||||
|
mi->SetName(model);
|
||||||
|
mi->SetNumAtomics(numObjs);
|
||||||
|
mi->SetLodDistances(dist);
|
||||||
|
SetModelInfoFlags(mi, flags);
|
||||||
|
mi->m_firstDamaged = damaged;
|
||||||
|
mi->SetTexDictionary(txd);
|
||||||
|
MatchModelString(model, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadTimeObject(const char *line)
|
||||||
|
{
|
||||||
|
int id, numObjs;
|
||||||
|
char model[24], txd[24];
|
||||||
|
float dist[3];
|
||||||
|
uint32 flags;
|
||||||
|
int timeOn, timeOff;
|
||||||
|
int damaged;
|
||||||
|
CTimeModelInfo *mi, *other;
|
||||||
|
|
||||||
|
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(numObjs){
|
||||||
|
case 1:
|
||||||
|
sscanf(line, "%d %s %s %d %f %d %d %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &flags, &timeOn, &timeOff);
|
||||||
|
damaged = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sscanf(line, "%d %s %s %d %f %f %d %d %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &dist[1], &flags, &timeOn, &timeOff);
|
||||||
|
damaged = dist[0] < dist[1] ? // Are distances increasing?
|
||||||
|
0 : // Yes, no damage model
|
||||||
|
1; // No, 1 is damaged
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sscanf(line, "%d %s %s %d %f %f %f %d %d %d",
|
||||||
|
&id, model, txd, &numObjs, &dist[0], &dist[1], &dist[2], &flags, &timeOn, &timeOff);
|
||||||
|
damaged = dist[0] < dist[1] ? // Are distances increasing?
|
||||||
|
(dist[1] < dist[2] ? 0 : 2) : // Yes, only 2 can still be a damage model
|
||||||
|
1; // No, 1 and 2 are damaged
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mi = CModelInfo::AddTimeModel(id);
|
||||||
|
mi->SetName(model);
|
||||||
|
mi->SetNumAtomics(numObjs);
|
||||||
|
mi->SetLodDistances(dist);
|
||||||
|
SetModelInfoFlags(mi, flags);
|
||||||
|
mi->m_firstDamaged = damaged;
|
||||||
|
mi->SetTimes(timeOn, timeOff);
|
||||||
|
mi->SetTexDictionary(txd);
|
||||||
|
other = mi->FindOtherTimeModel();
|
||||||
|
if(other)
|
||||||
|
other->SetOtherTimeModel(id);
|
||||||
|
MatchModelString(model, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadClumpObject(const char *line)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char model[24], txd[24];
|
||||||
|
CClumpModelInfo *mi;
|
||||||
|
|
||||||
|
if(sscanf(line, "%d %s %s", &id, &model, &txd) == 3){
|
||||||
|
mi = CModelInfo::AddClumpModel(id);
|
||||||
|
mi->SetName(model);
|
||||||
|
mi->SetTexDictionary(txd);
|
||||||
|
mi->SetColModel(&CTempColModels::ms_colModelBBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadVehicleObject(const char *line)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char model[24], txd[24];
|
||||||
|
char type[8], handlingId[16], gamename[32], vehclass[12];
|
||||||
|
uint32 frequency, comprules;
|
||||||
|
int32 level, misc;
|
||||||
|
float wheelScale;
|
||||||
|
CVehicleModelInfo *mi;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f",
|
||||||
|
&id, model, txd,
|
||||||
|
type, handlingId, gamename, vehclass,
|
||||||
|
&frequency, &level, &comprules, &misc, &wheelScale);
|
||||||
|
|
||||||
|
mi = CModelInfo::AddVehicleModel(id);
|
||||||
|
mi->SetName(model);
|
||||||
|
mi->SetTexDictionary(txd);
|
||||||
|
for(p = gamename; *p; p++)
|
||||||
|
if(*p == '_') *p = ' ';
|
||||||
|
strncpy(mi->m_gameName, gamename, 32);
|
||||||
|
mi->m_level = level;
|
||||||
|
mi->m_compRules = comprules;
|
||||||
|
|
||||||
|
if(strncmp(type, "car", 4) == 0){
|
||||||
|
mi->m_wheelId = misc;
|
||||||
|
mi->m_wheelScale = wheelScale;
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_CAR;
|
||||||
|
}else if(strncmp(type, "boat", 5) == 0){
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_BOAT;
|
||||||
|
}else if(strncmp(type, "train", 6) == 0){
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_TRAIN;
|
||||||
|
}else if(strncmp(type, "heli", 5) == 0){
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_HELI;
|
||||||
|
}else if(strncmp(type, "plane", 6) == 0){
|
||||||
|
mi->m_wheelId = misc;
|
||||||
|
mi->m_wheelScale = 1.0f;
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_PLANE;
|
||||||
|
}else if(strncmp(type, "bike", 5) == 0){
|
||||||
|
mi->m_bikeSteerAngle = misc;
|
||||||
|
mi->m_wheelScale = wheelScale;
|
||||||
|
mi->m_vehicleType = VEHICLE_TYPE_BIKE;
|
||||||
|
}else
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
|
||||||
|
|
||||||
|
// Well this is kinda dumb....
|
||||||
|
if(strncmp(vehclass, "poorfamily", 11) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_POOR;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_POOR);
|
||||||
|
}else if(strncmp(vehclass, "richfamily", 11) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_RICH;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_RICH);
|
||||||
|
}else if(strncmp(vehclass, "executive", 10) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_EXECUTIVE;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_EXECUTIVE);
|
||||||
|
}else if(strncmp(vehclass, "worker", 7) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_WORKER;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_WORKER);
|
||||||
|
}else if(strncmp(vehclass, "special", 8) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_SPECIAL;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_SPECIAL);
|
||||||
|
}else if(strncmp(vehclass, "big", 4) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_BIG;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_BIG);
|
||||||
|
}else if(strncmp(vehclass, "taxi", 5) == 0){
|
||||||
|
mi->m_vehicleClass = VEHICLE_CLASS_TAXI;
|
||||||
|
while(frequency-- > 0)
|
||||||
|
CCarCtrl::AddToCarArray(id, VEHICLE_CLASS_TAXI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadPedObject(const char *line)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char model[24], txd[24];
|
||||||
|
char pedType[24], pedStats[24], animGroup[24];
|
||||||
|
int carsCanDrive;
|
||||||
|
CPedModelInfo *mi;
|
||||||
|
int animGroupId;
|
||||||
|
|
||||||
|
if(sscanf(line, "%d %s %s %s %s %s %x",
|
||||||
|
&id, model, txd,
|
||||||
|
pedType, pedStats, animGroup, &carsCanDrive) != 7)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mi = CModelInfo::AddPedModel(id);
|
||||||
|
mi->SetName(model);
|
||||||
|
mi->SetTexDictionary(txd);
|
||||||
|
mi->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
|
mi->m_pedType = CPedType::FindPedType(pedType);
|
||||||
|
mi->m_pedStatType = CPedStats::GetPedStatType(pedStats);
|
||||||
|
for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++)
|
||||||
|
if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0)
|
||||||
|
break;
|
||||||
|
mi->m_animGroup = animGroupId;
|
||||||
|
|
||||||
|
// ???
|
||||||
|
CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CFileLoader::LoadPathHeader(const char *line, char *type)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char modelname[32];
|
||||||
|
|
||||||
|
sscanf(line, "%s %d %s", type, &id, modelname);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadPedPathNode(const char *line, int id, int node)
|
||||||
|
{
|
||||||
|
int type, next, cross;
|
||||||
|
float x, y, z, width;
|
||||||
|
|
||||||
|
sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width);
|
||||||
|
ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::LoadCarPathNode(const char *line, int id, int node)
|
||||||
|
{
|
||||||
|
int type, next, cross, numLeft, numRight;
|
||||||
|
float x, y, z, width;
|
||||||
|
|
||||||
|
sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight);
|
||||||
|
ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFileLoader::Load2dEffect(const char *line)
|
||||||
|
{
|
||||||
|
int id, r, g, b, a, type;
|
||||||
|
float x, y, z;
|
||||||
|
char corona[32], shadow[32];
|
||||||
|
int shadowIntens, flash, roadReflection, flare, flags, probability;
|
||||||
|
CBaseModelInfo *mi;
|
||||||
|
C2dEffect *effect;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
sscanf(line, "%d %f %f %f %d %d %d %d %d", &id, &x, &y, &z, &r, &g, &b, &a, &type);
|
||||||
|
|
||||||
|
CTxdStore::PushCurrentTxd();
|
||||||
|
CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle"));
|
||||||
|
|
||||||
|
mi = CModelInfo::GetModelInfo(id);
|
||||||
|
effect = CModelInfo::Get2dEffectStore().alloc();
|
||||||
|
mi->Add2dEffect(effect);
|
||||||
|
effect->pos = CVector(x, y, z);
|
||||||
|
effect->col = CRGBA(r, g, b, a);
|
||||||
|
effect->type = type;
|
||||||
|
|
||||||
|
switch(effect->type){
|
||||||
|
case EFFECT_LIGHT:
|
||||||
|
while(*line++ != '"');
|
||||||
|
p = corona;
|
||||||
|
while(*line != '"') *p++ = *line++;
|
||||||
|
*p = '\0';
|
||||||
|
line++;
|
||||||
|
|
||||||
|
while(*line++ != '"');
|
||||||
|
p = shadow;
|
||||||
|
while(*line != '"') *p++ = *line++;
|
||||||
|
*p = '\0';
|
||||||
|
line++;
|
||||||
|
|
||||||
|
sscanf(line, "%f %f %f %f %d %d %d %d %d",
|
||||||
|
&effect->light.dist,
|
||||||
|
&effect->light.outerRange,
|
||||||
|
&effect->light.size,
|
||||||
|
&effect->light.innerRange,
|
||||||
|
&shadowIntens, &flash, &roadReflection, &flare, &flags);
|
||||||
|
effect->light.corona = RwTextureRead(corona, nil);
|
||||||
|
effect->light.shadow = RwTextureRead(shadow, nil);
|
||||||
|
effect->light.shadowIntensity = shadowIntens;
|
||||||
|
effect->light.flash = flash;
|
||||||
|
effect->light.roadReflection = roadReflection;
|
||||||
|
effect->light.flareType = flare;
|
||||||
|
// TODO: check out the flags
|
||||||
|
if(flags & 4)
|
||||||
|
flags &= ~2;
|
||||||
|
effect->light.flags = flags;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFFECT_PARTICLE:
|
||||||
|
sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f",
|
||||||
|
&id, &x, &y, &z, &r, &g, &b, &a, &type,
|
||||||
|
&effect->particle.particleType,
|
||||||
|
&effect->particle.dir.x,
|
||||||
|
&effect->particle.dir.y,
|
||||||
|
&effect->particle.dir.z,
|
||||||
|
&effect->particle.scale);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFFECT_ATTRACTOR:
|
||||||
|
sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %d",
|
||||||
|
&id, &x, &y, &z, &r, &g, &b, &a, &type,
|
||||||
|
&flags,
|
||||||
|
&effect->attractor.dir.x,
|
||||||
|
&effect->attractor.dir.y,
|
||||||
|
&effect->attractor.dir.z,
|
||||||
|
&probability);
|
||||||
|
effect->attractor.flags = flags;
|
||||||
|
effect->attractor.probability = probability;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTxdStore::PopCurrentTxd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x476520, CFileLoader::LoadCollisionFromDatFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x4761D0, CFileLoader::LoadLine, PATCH_JUMP);
|
||||||
|
InjectHook(0x4765B0, CFileLoader::LoadTexDictionary, PATCH_JUMP);
|
||||||
|
InjectHook(0x478B20, CFileLoader::LoadCollisionFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x478C20, CFileLoader::LoadCollisionModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x476750, CFileLoader::LoadModelFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x476810, (void (*)(const char*))CFileLoader::LoadClumpFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x476990, (bool (*)(RwStream*,uint32))CFileLoader::LoadClumpFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x476A20, CFileLoader::StartLoadClumpFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x476A70, CFileLoader::FinishLoadClumpFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x476930, CFileLoader::LoadAtomicFile, PATCH_JUMP);
|
||||||
|
InjectHook(0x4767C0, CFileLoader::LoadAtomicFile2Return, PATCH_JUMP);
|
||||||
|
InjectHook(0x476630, CFileLoader::AddTexDictionaries, PATCH_JUMP);
|
||||||
|
|
||||||
|
InjectHook(0x476AC0, CFileLoader::LoadObjectTypes, PATCH_JUMP);
|
||||||
|
InjectHook(0x477040, CFileLoader::LoadObject, PATCH_JUMP);
|
||||||
|
InjectHook(0x4774B0, CFileLoader::LoadTimeObject, PATCH_JUMP);
|
||||||
|
InjectHook(0x477920, CFileLoader::LoadClumpObject, PATCH_JUMP);
|
||||||
|
InjectHook(0x477990, CFileLoader::LoadVehicleObject, PATCH_JUMP);
|
||||||
|
InjectHook(0x477DE0, CFileLoader::LoadPedObject, PATCH_JUMP);
|
||||||
|
InjectHook(0x477ED0, CFileLoader::LoadPathHeader, PATCH_JUMP);
|
||||||
|
InjectHook(0x477FF0, CFileLoader::LoadCarPathNode, PATCH_JUMP);
|
||||||
|
InjectHook(0x477F00, CFileLoader::LoadPedPathNode, PATCH_JUMP);
|
||||||
|
InjectHook(0x4780E0, CFileLoader::Load2dEffect, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
34
src/FileLoader.h
Normal file
34
src/FileLoader.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CFileLoader
|
||||||
|
{
|
||||||
|
static char ms_line[256];
|
||||||
|
public:
|
||||||
|
static void LoadLevel(const char *filename);
|
||||||
|
static void LoadCollisionFromDatFile(int currlevel);
|
||||||
|
static char *LoadLine(int fd);
|
||||||
|
static RwTexDictionary *LoadTexDictionary(const char *filename);
|
||||||
|
static void LoadCollisionFile(const char *filename);
|
||||||
|
static void LoadCollisionModel(uint8 *buf, CColModel &model, char *name);
|
||||||
|
static void LoadModelFile(const char *filename);
|
||||||
|
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||||
|
static void LoadClumpFile(const char *filename);
|
||||||
|
static bool LoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool StartLoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool FinishLoadClumpFile(RwStream *stream, uint32 id);
|
||||||
|
static bool LoadAtomicFile(RwStream *stream, uint32 id);
|
||||||
|
static RpAtomic *SetRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||||
|
static RpClump *LoadAtomicFile2Return(const char *filename);
|
||||||
|
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
|
||||||
|
|
||||||
|
static void LoadObjectTypes(const char *filename);
|
||||||
|
static void LoadObject(const char *line);
|
||||||
|
static void LoadTimeObject(const char *line);
|
||||||
|
static void LoadClumpObject(const char *line);
|
||||||
|
static void LoadVehicleObject(const char *line);
|
||||||
|
static void LoadPedObject(const char *line);
|
||||||
|
static int LoadPathHeader(const char *line, char *type);
|
||||||
|
static void LoadPedPathNode(const char *line, int id, int node);
|
||||||
|
static void LoadCarPathNode(const char *line, int id, int node);
|
||||||
|
static void Load2dEffect(const char *line);
|
||||||
|
};
|
@ -9,6 +9,7 @@ bool &CGame::frenchGame = *(bool*)0x95CDCB;
|
|||||||
bool &CGame::germanGame = *(bool*)0x95CD1E;
|
bool &CGame::germanGame = *(bool*)0x95CD1E;
|
||||||
bool &CGame::noProstitutes = *(bool*)0x95CDCF;
|
bool &CGame::noProstitutes = *(bool*)0x95CDCF;
|
||||||
bool &CGame::playingIntro = *(bool*)0x95CDC2;
|
bool &CGame::playingIntro = *(bool*)0x95CDC2;
|
||||||
|
char *CGame::aDatFile = (char*)0x773A48;
|
||||||
|
|
||||||
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
|
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
|
||||||
WRAPPER bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }
|
WRAPPER bool CGame::InitialiseOnceBeforeRW(void) { EAXJMP(0x48BB80); }
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
static bool &germanGame;
|
static bool &germanGame;
|
||||||
static bool &noProstitutes;
|
static bool &noProstitutes;
|
||||||
static bool &playingIntro;
|
static bool &playingIntro;
|
||||||
|
static char *aDatFile; //[32];
|
||||||
|
|
||||||
static void Process(void);
|
static void Process(void);
|
||||||
static bool InitialiseOnceBeforeRW(void);
|
static bool InitialiseOnceBeforeRW(void);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
#include "Weather.h"
|
#include "Weather.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
11
src/common.h
11
src/common.h
@ -76,13 +76,6 @@ extern void **rwengine;
|
|||||||
#define HUD_FROM_RIGHT(a) (SCREEN_WIDTH - HUD_STRETCH_X(a))
|
#define HUD_FROM_RIGHT(a) (SCREEN_WIDTH - HUD_STRETCH_X(a))
|
||||||
#define HUD_FROM_BOTTOM(a) (SCREEN_HEIGHT - HUD_STRETCH_Y(a))
|
#define HUD_FROM_BOTTOM(a) (SCREEN_HEIGHT - HUD_STRETCH_Y(a))
|
||||||
|
|
||||||
struct GlobalScene
|
|
||||||
{
|
|
||||||
RpWorld *world;
|
|
||||||
RwCamera *camera;
|
|
||||||
};
|
|
||||||
extern GlobalScene &Scene;
|
|
||||||
|
|
||||||
#include "math/Vector.h"
|
#include "math/Vector.h"
|
||||||
#include "math/Vector2D.h"
|
#include "math/Vector2D.h"
|
||||||
#include "math/Matrix.h"
|
#include "math/Matrix.h"
|
||||||
@ -136,10 +129,6 @@ inline float sq(float x) { return x*x; }
|
|||||||
int myrand(void);
|
int myrand(void);
|
||||||
void mysrand(unsigned int seed);
|
void mysrand(unsigned int seed);
|
||||||
|
|
||||||
extern uint8 work_buff[55000];
|
|
||||||
extern char gString[256];
|
|
||||||
extern wchar *gUString;
|
|
||||||
|
|
||||||
void re3_debug(char *format, ...);
|
void re3_debug(char *format, ...);
|
||||||
void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...);
|
void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...);
|
||||||
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
|
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
|
|
||||||
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
||||||
|
WRAPPER void CCarCtrl::AddToCarArray(int id, int vehclass) { EAXJMP(0x4182F0); }
|
||||||
|
@ -6,4 +6,5 @@ class CCarCtrl
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void SwitchVehicleToRealPhysics(CVehicle*);
|
static void SwitchVehicleToRealPhysics(CVehicle*);
|
||||||
|
static void AddToCarArray(int id, int vehclass);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "Garages.h"
|
#include "Garages.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
7
src/control/HandlingDataMgr.cpp
Normal file
7
src/control/HandlingDataMgr.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "HandlingDatamgr.h"
|
||||||
|
|
||||||
|
cHandlingDataMgr &mod_HandlingManager = *(cHandlingDataMgr*)0x728060;
|
||||||
|
|
||||||
|
WRAPPER int32 cHandlingDataMgr::GetHandlingId(const char *name){ EAXJMP(0x546B70); }
|
8
src/control/HandlingDataMgr.h
Normal file
8
src/control/HandlingDataMgr.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class cHandlingDataMgr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int32 GetHandlingId(const char *name);
|
||||||
|
};
|
||||||
|
extern cHandlingDataMgr &mod_HandlingManager;
|
@ -45,6 +45,37 @@ CPathInfoForObject *&InfoForTilePeds = *(CPathInfoForObject**)0x8F1AE4;
|
|||||||
CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824;
|
CTempDetachedNode *&DetachedNodesCars = *(CTempDetachedNode**)0x8E2824;
|
||||||
CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0;
|
CTempDetachedNode *&DetachedNodesPeds = *(CTempDetachedNode**)0x8E28A0;
|
||||||
|
|
||||||
|
void
|
||||||
|
CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = id*12 + node;
|
||||||
|
InfoForTilePeds[i].type = type;
|
||||||
|
InfoForTilePeds[i].next = next;
|
||||||
|
InfoForTilePeds[i].x = x;
|
||||||
|
InfoForTilePeds[i].y = y;
|
||||||
|
InfoForTilePeds[i].z = z;
|
||||||
|
InfoForTilePeds[i].numLeftLanes = 0;
|
||||||
|
InfoForTilePeds[i].numRightLanes = 0;
|
||||||
|
InfoForTilePeds[i].crossing = crossing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = id*12 + node;
|
||||||
|
InfoForTileCars[i].type = type;
|
||||||
|
InfoForTileCars[i].next = next;
|
||||||
|
InfoForTileCars[i].x = x;
|
||||||
|
InfoForTileCars[i].y = y;
|
||||||
|
InfoForTileCars[i].z = z;
|
||||||
|
InfoForTileCars[i].numLeftLanes = numLeft;
|
||||||
|
InfoForTileCars[i].numRightLanes = numRight;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPathFind::PreparePathData(void)
|
CPathFind::PreparePathData(void)
|
||||||
{
|
{
|
||||||
@ -457,8 +488,8 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
// Crosses road
|
// Crosses road
|
||||||
if(objectpathinfo[istart + iseg].next == jseg && objectpathinfo[istart + iseg].flag & 1 ||
|
if(objectpathinfo[istart + iseg].next == jseg && objectpathinfo[istart + iseg].crossing ||
|
||||||
objectpathinfo[jstart + jseg].next == iseg && objectpathinfo[jstart + jseg].flag & 1)
|
objectpathinfo[jstart + jseg].next == iseg && objectpathinfo[jstart + jseg].crossing)
|
||||||
m_connectionFlags[m_numConnections] |= ConnectionCrossRoad;
|
m_connectionFlags[m_numConnections] |= ConnectionCrossRoad;
|
||||||
else
|
else
|
||||||
m_connectionFlags[m_numConnections] &= ~ConnectionCrossRoad;
|
m_connectionFlags[m_numConnections] &= ~ConnectionCrossRoad;
|
||||||
|
@ -65,7 +65,7 @@ struct CPathInfoForObject
|
|||||||
int8 next;
|
int8 next;
|
||||||
int8 numLeftLanes;
|
int8 numLeftLanes;
|
||||||
int8 numRightLanes;
|
int8 numRightLanes;
|
||||||
uint8 flag;
|
uint8 crossing : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CTempNode
|
struct CTempNode
|
||||||
@ -123,6 +123,8 @@ public:
|
|||||||
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
||||||
float unk, CTempDetachedNode *detachednodes, int unused);
|
float unk, CTempDetachedNode *detachednodes, int unused);
|
||||||
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
||||||
|
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
|
||||||
|
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
|
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
|
||||||
|
|
||||||
|
5
src/control/PedStats.cpp
Normal file
5
src/control/PedStats.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "PedStats.h"
|
||||||
|
|
||||||
|
WRAPPER int32 CPedStats::GetPedStatType(char *type) { EAXJMP(0x4EF780); }
|
@ -15,3 +15,9 @@ struct PedStat
|
|||||||
int16 m_flags;
|
int16 m_flags;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PedStat) == 0x34, "PedStat: error");
|
static_assert(sizeof(PedStat) == 0x34, "PedStat: error");
|
||||||
|
|
||||||
|
class CPedStats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int32 GetPedStatType(char *type);
|
||||||
|
};
|
5
src/control/PedType.cpp
Normal file
5
src/control/PedType.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "PedType.h"
|
||||||
|
|
||||||
|
WRAPPER int32 CPedType::FindPedType(char *type) { EAXJMP(0x4EEC10); }
|
7
src/control/PedType.h
Normal file
7
src/control/PedType.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CPedType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int32 FindPedType(char *type);
|
||||||
|
};
|
@ -1,6 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <rpskin.h>
|
#include <rpskin.h>
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "lights.h"
|
#include "lights.h"
|
||||||
#include "PointLights.h"
|
#include "PointLights.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "PedStat.h"
|
|
||||||
#include "DMaudio.h"
|
#include "DMaudio.h"
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "Clouds.h"
|
#include "Clouds.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
@ -55,6 +56,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
GlobalScene &Scene = *(GlobalScene*)0x726768;
|
||||||
|
|
||||||
uint8 work_buff[55000];
|
uint8 work_buff[55000];
|
||||||
char gString[256];
|
char gString[256];
|
||||||
wchar *gUString = (wchar*)0x74B018;
|
wchar *gUString = (wchar*)0x74B018;
|
||||||
|
@ -41,6 +41,9 @@ public:
|
|||||||
virtual RwObject *GetRwObject(void) = 0;
|
virtual RwObject *GetRwObject(void) = 0;
|
||||||
|
|
||||||
bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
|
bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
|
||||||
|
bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE ||
|
||||||
|
m_type == MITYPE_MLO || m_type == MITYPE_XTRACOMPS; // unused but what the heck
|
||||||
|
}
|
||||||
char *GetName(void) { return m_name; }
|
char *GetName(void) { return m_name; }
|
||||||
void SetName(const char *name) { strncpy(m_name, name, 24); }
|
void SetName(const char *name) { strncpy(m_name, name, 24); }
|
||||||
void SetColModel(CColModel *col, bool free = false){
|
void SetColModel(CColModel *col, bool free = false){
|
||||||
|
@ -320,9 +320,12 @@ enum
|
|||||||
MI_CAR_PANEL,
|
MI_CAR_PANEL,
|
||||||
MI_CAR_BONNET,
|
MI_CAR_BONNET,
|
||||||
MI_CAR_BOOT,
|
MI_CAR_BOOT,
|
||||||
MI_CAR_WEEL,
|
MI_CAR_WHEEL,
|
||||||
MI_BODYPARTA,
|
MI_BODYPARTA,
|
||||||
MI_BODYPARTB,
|
MI_BODYPARTB,
|
||||||
|
|
||||||
|
MI_AIRTRAIN_VLO = 198,
|
||||||
|
MI_LOPOLYGUY,
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitModelIndices(void);
|
void InitModelIndices(void);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "TempColModels.h"
|
||||||
|
#include "ModelIndices.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408;
|
CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408;
|
||||||
@ -18,6 +20,8 @@ void
|
|||||||
CModelInfo::Initialise(void)
|
CModelInfo::Initialise(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
CSimpleModelInfo *m;
|
||||||
|
|
||||||
for(i = 0; i < MODELINFOSIZE; i++)
|
for(i = 0; i < MODELINFOSIZE; i++)
|
||||||
ms_modelInfoPtrs[i] = nil;
|
ms_modelInfoPtrs[i] = nil;
|
||||||
ms_2dEffectStore.clear();
|
ms_2dEffectStore.clear();
|
||||||
@ -26,10 +30,58 @@ CModelInfo::Initialise(void)
|
|||||||
ms_clumpModelStore.clear();
|
ms_clumpModelStore.clear();
|
||||||
ms_pedModelStore.clear();
|
ms_pedModelStore.clear();
|
||||||
ms_vehicleModelStore.clear();
|
ms_vehicleModelStore.clear();
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_DOOR);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelDoor1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BUMPER);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBumper1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_PANEL);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelPanel1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BONNET);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBonnet1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_BOOT);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBoot1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_CAR_WHEEL);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelWheel1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_BODYPARTA);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBodyPart1);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
|
|
||||||
|
m = AddSimpleModel(MI_BODYPARTB);
|
||||||
|
m->SetColModel(&CTempColModels::ms_colModelBodyPart2);
|
||||||
|
m->SetTexDictionary("generic");
|
||||||
|
m->SetNumAtomics(1);
|
||||||
|
m->m_lodDistances[0] = 80.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CModelInfo::Shutdown(void)
|
CModelInfo::ShutDown(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < ms_simpleModelStore.allocPtr; i++)
|
for(i = 0; i < ms_simpleModelStore.allocPtr; i++)
|
||||||
@ -42,6 +94,8 @@ CModelInfo::Shutdown(void)
|
|||||||
ms_pedModelStore.store[i].Shutdown();
|
ms_pedModelStore.store[i].Shutdown();
|
||||||
for(i = 0; i < ms_vehicleModelStore.allocPtr; i++)
|
for(i = 0; i < ms_vehicleModelStore.allocPtr; i++)
|
||||||
ms_vehicleModelStore.store[i].Shutdown();
|
ms_vehicleModelStore.store[i].Shutdown();
|
||||||
|
for(i = 0; i < ms_2dEffectStore.allocPtr; i++)
|
||||||
|
ms_2dEffectStore.store[i].Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSimpleModelInfo*
|
CSimpleModelInfo*
|
||||||
@ -115,10 +169,12 @@ CModelInfo::GetModelInfo(const char *name, int *id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
// InjectHook(0x50B920, CModelInfo::AddSimpleModel, PATCH_JUMP);
|
InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP);
|
||||||
// InjectHook(0x50B9C0, CModelInfo::AddTimeModel, PATCH_JUMP);
|
InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP);
|
||||||
// InjectHook(0x50BA10, CModelInfo::AddClumpModel, PATCH_JUMP);
|
InjectHook(0x50B920, CModelInfo::AddSimpleModel, PATCH_JUMP);
|
||||||
// InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
|
InjectHook(0x50B9C0, CModelInfo::AddTimeModel, PATCH_JUMP);
|
||||||
// InjectHook(0x50BA60, CModelInfo::AddPedModel, PATCH_JUMP);
|
InjectHook(0x50BA10, CModelInfo::AddClumpModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x50BAD0, CModelInfo::AddPedModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x50BA60, CModelInfo::AddVehicleModel, PATCH_JUMP);
|
||||||
InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
|
InjectHook(0x50B860, (CBaseModelInfo *(*)(const char*, int*))CModelInfo::GetModelInfo, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -20,7 +20,7 @@ class CModelInfo
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void Initialise(void);
|
static void Initialise(void);
|
||||||
static void Shutdown(void);
|
static void ShutDown(void);
|
||||||
|
|
||||||
static CSimpleModelInfo *AddSimpleModel(int id);
|
static CSimpleModelInfo *AddSimpleModel(int id);
|
||||||
static CTimeModelInfo *AddTimeModel(int id);
|
static CTimeModelInfo *AddTimeModel(int id);
|
||||||
@ -28,6 +28,8 @@ public:
|
|||||||
static CPedModelInfo *AddPedModel(int id);
|
static CPedModelInfo *AddPedModel(int id);
|
||||||
static CVehicleModelInfo *AddVehicleModel(int id);
|
static CVehicleModelInfo *AddVehicleModel(int id);
|
||||||
|
|
||||||
|
static CStore<C2dEffect, TWODFXSIZE> &Get2dEffectStore(void) { return ms_2dEffectStore; }
|
||||||
|
|
||||||
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
|
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
|
||||||
static CBaseModelInfo *GetModelInfo(int id){
|
static CBaseModelInfo *GetModelInfo(int id){
|
||||||
return ms_modelInfoPtrs[id];
|
return ms_modelInfoPtrs[id];
|
||||||
|
@ -21,7 +21,7 @@ enum PedNode {
|
|||||||
class CPedModelInfo : public CClumpModelInfo
|
class CPedModelInfo : public CClumpModelInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void *m_animGroup; // TODO
|
int32 m_animGroup;
|
||||||
int32 m_pedType;
|
int32 m_pedType;
|
||||||
int32 m_pedStatType;
|
int32 m_pedStatType;
|
||||||
uint32 m_carsCanDrive;
|
uint32 m_carsCanDrive;
|
||||||
|
@ -53,7 +53,7 @@ CSimpleModelInfo::Init(void)
|
|||||||
m_atomics[1] = nil;
|
m_atomics[1] = nil;
|
||||||
m_atomics[2] = nil;
|
m_atomics[2] = nil;
|
||||||
m_numAtomics = 0;
|
m_numAtomics = 0;
|
||||||
m_furthest = 0;
|
m_firstDamaged = 0;
|
||||||
m_normalCull = 0;
|
m_normalCull = 0;
|
||||||
m_isDamaged = 0;
|
m_isDamaged = 0;
|
||||||
m_isBigBuilding = 0;
|
m_isBigBuilding = 0;
|
||||||
@ -103,11 +103,10 @@ float
|
|||||||
CSimpleModelInfo::GetLargestLodDistance(void)
|
CSimpleModelInfo::GetLargestLodDistance(void)
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
// TODO: what exactly is going on here?
|
if(m_firstDamaged == 0 || m_isDamaged)
|
||||||
if(m_furthest != 0 && !m_isDamaged)
|
|
||||||
d = m_lodDistances[m_furthest-1];
|
|
||||||
else
|
|
||||||
d = m_lodDistances[m_numAtomics-1];
|
d = m_lodDistances[m_numAtomics-1];
|
||||||
|
else
|
||||||
|
d = m_lodDistances[m_firstDamaged-1];
|
||||||
return d * TheCamera.LODDistMultiplier;
|
return d * TheCamera.LODDistMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +115,8 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
i = 0;
|
i = 0;
|
||||||
// TODO: what exactly is going on here?
|
|
||||||
if(m_isDamaged)
|
if(m_isDamaged)
|
||||||
i = m_furthest;
|
i = m_firstDamaged;
|
||||||
for(; i < m_numAtomics; i++)
|
for(; i < m_numAtomics; i++)
|
||||||
if(dist < m_lodDistances[i] *TheCamera.LODDistMultiplier)
|
if(dist < m_lodDistances[i] *TheCamera.LODDistMultiplier)
|
||||||
return m_atomics[i];
|
return m_atomics[i];
|
||||||
|
@ -11,9 +11,9 @@ public:
|
|||||||
float m_lodDistances[3];
|
float m_lodDistances[3];
|
||||||
uint8 m_numAtomics;
|
uint8 m_numAtomics;
|
||||||
uint8 m_alpha;
|
uint8 m_alpha;
|
||||||
uint16 m_furthest : 2; // 0: numAtomics-1 is furthest visible
|
uint16 m_firstDamaged : 2; // 0: no damage model
|
||||||
// 1: atomic 0 is furthest
|
// 1: 1 and 2 are damage models
|
||||||
// 2: atomic 1 is furthest
|
// 2: 2 is damage model
|
||||||
uint16 m_normalCull : 1;
|
uint16 m_normalCull : 1;
|
||||||
uint16 m_isDamaged : 1;
|
uint16 m_isDamaged : 1;
|
||||||
uint16 m_isBigBuilding : 1;
|
uint16 m_isBigBuilding : 1;
|
||||||
|
@ -12,7 +12,9 @@ public:
|
|||||||
|
|
||||||
int32 GetTimeOn(void) { return m_timeOn; }
|
int32 GetTimeOn(void) { return m_timeOn; }
|
||||||
int32 GetTimeOff(void) { return m_timeOff; }
|
int32 GetTimeOff(void) { return m_timeOff; }
|
||||||
|
void SetTimes(int32 on, int32 off) { m_timeOn = on; m_timeOff = off; }
|
||||||
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
|
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
|
||||||
|
void SetOtherTimeModel(int32 other) { m_otherTimeModelID = other; }
|
||||||
CTimeModelInfo *FindOtherTimeModel(void);
|
CTimeModelInfo *FindOtherTimeModel(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
|
static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
|
||||||
|
@ -35,6 +35,17 @@ enum {
|
|||||||
NUM_VEHICLE_TYPES
|
NUM_VEHICLE_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VEHICLE_CLASS_POOR,
|
||||||
|
VEHICLE_CLASS_RICH,
|
||||||
|
VEHICLE_CLASS_EXECUTIVE,
|
||||||
|
VEHICLE_CLASS_WORKER,
|
||||||
|
VEHICLE_CLASS_SPECIAL,
|
||||||
|
VEHICLE_CLASS_BIG,
|
||||||
|
VEHICLE_CLASS_TAXI,
|
||||||
|
NUM_VEHICLE_CLASSES
|
||||||
|
};
|
||||||
|
|
||||||
class CVehicleModelInfo : public CClumpModelInfo
|
class CVehicleModelInfo : public CClumpModelInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
void **rwengine = *(void***)0x5A10E1;
|
void **rwengine = *(void***)0x5A10E1;
|
||||||
|
|
||||||
GlobalScene &Scene = *(GlobalScene*)0x726768;
|
|
||||||
|
|
||||||
DebugMenuAPI gDebugMenuAPI;
|
DebugMenuAPI gDebugMenuAPI;
|
||||||
|
|
||||||
WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
|
WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
enum {
|
||||||
|
EFFECT_LIGHT,
|
||||||
|
EFFECT_PARTICLE,
|
||||||
|
EFFECT_ATTRACTOR
|
||||||
|
};
|
||||||
|
|
||||||
class C2dEffect
|
class C2dEffect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -7,26 +13,26 @@ public:
|
|||||||
float size;
|
float size;
|
||||||
float innerRange;
|
float innerRange;
|
||||||
uint8 flash;
|
uint8 flash;
|
||||||
uint8 wet;
|
uint8 roadReflection;
|
||||||
uint8 flare;
|
uint8 flareType;
|
||||||
uint8 shadowIntens;
|
uint8 shadowIntensity;
|
||||||
uint8 flag;
|
uint8 flags;
|
||||||
RwTexture *corona;
|
RwTexture *corona;
|
||||||
RwTexture *shadow;
|
RwTexture *shadow;
|
||||||
};
|
};
|
||||||
struct Particle {
|
struct Particle {
|
||||||
int particleType;
|
int particleType;
|
||||||
float dir[3];
|
CVector dir;
|
||||||
float scale;
|
float scale;
|
||||||
};
|
};
|
||||||
struct Attractor {
|
struct Attractor {
|
||||||
CVector dir;
|
CVector dir;
|
||||||
uint8 flag;
|
uint8 flags;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
};
|
};
|
||||||
|
|
||||||
CVector pos;
|
CVector pos;
|
||||||
RwRGBA col;
|
CRGBA col;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
union {
|
union {
|
||||||
Light light;
|
Light light;
|
||||||
@ -35,5 +41,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
C2dEffect(void) {}
|
C2dEffect(void) {}
|
||||||
|
void Shutdown(void){
|
||||||
|
if(type == 0){ // TODO: enum
|
||||||
|
if(light.corona)
|
||||||
|
RwTextureDestroy(light.corona);
|
||||||
|
if(light.shadow)
|
||||||
|
RwTextureDestroy(light.shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(C2dEffect) == 0x34, "C2dEffect: error");
|
static_assert(sizeof(C2dEffect) == 0x34, "C2dEffect: error");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
#include "TxdStore.h"
|
#include "TxdStore.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "ParticleMgr.h"
|
#include "ParticleMgr.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Weather.h"
|
#include "Weather.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
#include "Treadable.h"
|
#include "Treadable.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Sprite.h"
|
#include "Sprite.h"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "Draw.h"
|
#include "Draw.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Sprite2d.h"
|
#include "Sprite2d.h"
|
||||||
|
@ -83,6 +83,7 @@ static psGlobalType &PsGlobal = *(psGlobalType*)0x72CF60;
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
#include "Pad.h"
|
#include "Pad.h"
|
||||||
|
@ -8,8 +8,10 @@ public:
|
|||||||
T store[n];
|
T store[n];
|
||||||
|
|
||||||
T *alloc(void){
|
T *alloc(void){
|
||||||
if(this->allocPtr >= n)
|
if(this->allocPtr >= n){
|
||||||
printf("Size of this thing:%d needs increasing\n", n);
|
printf("Size of this thing:%d needs increasing\n", n);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
return &this->store[this->allocPtr++];
|
return &this->store[this->allocPtr++];
|
||||||
}
|
}
|
||||||
void clear(void){
|
void clear(void){
|
||||||
|
Loading…
Reference in New Issue
Block a user