void ReadColor (CFile& cf, tFaceColor *pc, int bFloatData, int bRegisterColor) { pc->index = cf.ReadByte (); if (bFloatData) { tRgbColord c; cf.Read (&c, sizeof (c), 1); pc->color.red = (float) c.red; pc->color.green = (float) c.green; pc->color.blue = (float) c.blue; } else { int c = cf.ReadInt (); pc->color.red = (float) c / (float) 0x7fffffff; c = cf.ReadInt (); pc->color.green = (float) c / (float) 0x7fffffff; c = cf.ReadInt (); pc->color.blue = (float) c / (float) 0x7fffffff; } if (bRegisterColor && (((pc->color.red > 0) && (pc->color.red < 1)) || ((pc->color.green > 0) && (pc->color.green < 1)) || ((pc->color.blue > 0) && (pc->color.blue < 1)))) gameStates.render.bColored = 1; pc->color.alpha = 1; }
int CMovieLib::SetupMVL (CFile& cf) { int nFiles, offset; int i, len; //read movie file header nFiles = cf.ReadInt (); //get number of files if (nFiles > 255) { gameStates.app.bLittleEndian = 0; nFiles = SWAPINT (nFiles); } if (!m_movies.Create (nFiles)) return 0; m_nMovies = nFiles; offset = 4 + 4 + nFiles * (13 + 4); //id + nFiles + nFiles * (filename + size) for (i = 0; i < nFiles; i++) { if (cf.Read (m_movies [i].m_name, 13, 1) != 1) break; //end of file (probably) len = cf.ReadInt (); m_movies [i].m_len = len; m_movies [i].m_offset = offset; offset += m_movies [i].m_len; } cf.Close (); m_flags = 0; return nFiles; }
int ReadHamFile (bool bDefault) { CFile cf; #if 1 char szD1PigFileName [FILENAME_LEN]; #endif int nHAMId; int nSoundOffset = 0; char szFile [FILENAME_LEN]; char* pszFile, * pszFolder; if (bDefault) { pszFile = DefaultHamFile (); pszFolder = gameFolders.szDataDir; } else { if (!*gameFolders.szModName) return 0; sprintf (szFile, "%s.ham", gameFolders.szModName); pszFile = szFile; pszFolder = gameFolders.szModDir [1]; } if (!cf.Open (pszFile, pszFolder, "rb", 0)) { bMustWriteHamFile = 1; return 0; } //make sure ham is valid nType file & is up-to-date nHAMId = cf.ReadInt (); gameData.pig.tex.nHamFileVersion = cf.ReadInt (); if (nHAMId != HAMFILE_ID) Error ("Cannot open ham file %s\n", DefaultHamFile ()); if (gameData.pig.tex.nHamFileVersion < 3) // hamfile contains sound info nSoundOffset = cf.ReadInt (); BMReadAll (cf); /*---*/PrintLog (" Loading bitmap index translation table\n"); gameData.pig.tex.bitmapXlat.Read (cf, MAX_BITMAP_FILES); if (gameData.pig.tex.nHamFileVersion < 3) { cf.Seek (nSoundOffset, SEEK_SET); int nSoundNum = cf.ReadInt (); int nSoundStart = cf.Tell (); /*---*/PrintLog (" Loading %d sounds\n", nSoundNum); SetupSounds (cf, nSoundNum, nSoundStart); } cf.Close (); /*---*/PrintLog (" Looking for Descent 1 data files\n"); strcpy (szD1PigFileName, "descent.pig"); if (cfPiggy [1].File ()) cfPiggy [1].Seek (0, SEEK_SET); else cfPiggy [1].Open (szD1PigFileName, gameFolders.szDataDir, "rb", 0); if (cfPiggy [1].File ()) { gameStates.app.bHaveD1Data = 1; /*---*/PrintLog (" Loading Descent 1 data\n"); BMReadGameDataD1 (cfPiggy [1]); } return 1; }
//------------------------------------------------------------------------------ //initialize a pigfile, reading headers //returns the size of all the bitmap data void PiggyInitPigFile (char *filename) { CFile *cfP = cfPiggy + gameStates.app.bD1Data; char szName [16]; char szNameRead [16]; char szPigName [FILENAME_LEN]; int nHeaderSize, nBitmapNum, nDataSize, nDataStart, i; grsBitmap bmTemp; tPIGBitmapHeader bmh; PiggyCloseFile (); //close old pig if still open strcpy (szPigName, filename); //rename pigfile for shareware if (!stricmp (DEFAULT_PIGFILE, DEFAULT_PIGFILE_SHAREWARE) && !CFile::Exist (szPigName, gameFolders.szDataDir, 0)) strcpy (szPigName, DEFAULT_PIGFILE_SHAREWARE); strlwr (szPigName); if (!cfP->Open (szPigName, gameFolders.szDataDir, "rb", 0)) { #ifdef EDITOR return; //if editor, ok to not have pig, because we'll build one #else if (!CopyPigFileFromCD (*cfP, szPigName)) return; #endif } int pig_id = cfP->ReadInt (); int pigVersion = cfP->ReadInt (); if (pig_id != PIGFILE_ID || pigVersion != PIGFILE_VERSION) { cfP->Close (); //out of date pig return; } strncpy (szCurrentPigFile [0], szPigName, sizeof (szCurrentPigFile [0])); nBitmapNum = cfP->ReadInt (); nHeaderSize = nBitmapNum * sizeof (tPIGBitmapHeader); nDataStart = nHeaderSize + cfP->Tell (); nDataSize = cfP->Length () - nDataStart; gameData.pig.tex.nBitmaps [0] = 1; for (i = 0; i < nBitmapNum; i++) { PIGBitmapHeaderRead (&bmh, *cfP); memcpy (szNameRead, bmh.name, 8); szNameRead [8] = 0; if (bmh.dflags & DBM_FLAG_ABM) sprintf (szName, "%s#%d", szNameRead, bmh.dflags & DBM_NUM_FRAMES); else strcpy (szName, szNameRead); memset (&bmTemp, 0, sizeof (grsBitmap)); bmTemp.bmProps.w = bmTemp.bmProps.rowSize = bmh.width + ((short) (bmh.wh_extra & 0x0f) << 8); bmTemp.bmProps.h = bmh.height + ((short) (bmh.wh_extra & 0xf0) << 4); bmTemp.bmProps.flags |= BM_FLAG_PAGED_OUT; bmTemp.bmAvgColor = bmh.bmAvgColor; gameData.pig.tex.bitmapFlags [0][i+1] = bmh.flags & BM_FLAGS_TO_COPY; bitmapOffsets [0][i+1] = bmh.offset + nDataStart; Assert ((i+1) == gameData.pig.tex.nBitmaps [0]); PiggyRegisterBitmap (&bmTemp, szName, 1); } bPigFileInitialized = 1; }
void ReadReactor (tReactorProps& reactor, CFile& cf) { int i; reactor.nModel = cf.ReadInt (); reactor.nGuns = cf.ReadInt (); for (i = 0; i < MAX_CONTROLCEN_GUNS; i++) cf.ReadVector (reactor.gunPoints [i]); for (i = 0; i < MAX_CONTROLCEN_GUNS; i++) cf.ReadVector (reactor.gunDirs [i]); }
//------------------------------------------------------------------------------ //initialize a pigfile, reading headers //returns the size of all the bitmap data void PiggyInitPigFile (char *filename) { CFile *cfP = cfPiggy + gameStates.app.bD1Data; char szName [16]; char szNameRead [16]; char szPigName [FILENAME_LEN]; int nHeaderSize, nBitmapNum, nDataSize, nDataStart, i; CBitmap bm; tPIGBitmapHeader bmh; PiggyCloseFile (); //close old pig if still open strcpy (szPigName, filename); //rename pigfile for shareware if (!stricmp (DefaultPigFile (), DefaultPigFile (1)) && !CFile::Exist (szPigName, gameFolders.szDataDir, 0)) strcpy (szPigName, DefaultPigFile (1)); strlwr (szPigName); if (!cfP->Open (szPigName, gameFolders.szDataDir, "rb", 0)) { if (!CopyPigFileFromCD (*cfP, szPigName)) return; } int pig_id = cfP->ReadInt (); int pigVersion = cfP->ReadInt (); if (pig_id != PIGFILE_ID || pigVersion != PIGFILE_VERSION) { cfP->Close (); //out of date pig return; } strncpy (szCurrentPigFile [0], szPigName, sizeof (szCurrentPigFile [0])); nBitmapNum = cfP->ReadInt (); nHeaderSize = nBitmapNum * sizeof (tPIGBitmapHeader); nDataStart = nHeaderSize + cfP->Tell (); nDataSize = cfP->Length () - nDataStart; gameData.pig.tex.nBitmaps [0] = 1; for (i = 0; i < nBitmapNum; i++) { PIGBitmapHeaderRead (&bmh, *cfP); memcpy (szNameRead, bmh.name, 8); szNameRead [8] = 0; if (bmh.dflags & DBM_FLAG_ABM) sprintf (szName, "%s#%d", szNameRead, bmh.dflags & DBM_NUM_FRAMES); else strcpy (szName, szNameRead); memset (&bm, 0, sizeof (CBitmap)); bm.SetWidth (bmh.width + ((short) (bmh.wh_extra & 0x0f) << 8)); bm.SetHeight (bmh.height + ((short) (bmh.wh_extra & 0xf0) << 4)); bm.SetBPP (1); bm.SetFlags (BM_FLAG_PAGED_OUT); bm.SetAvgColorIndex (bmh.avgColor); gameData.pig.tex.bitmapFlags [0][i+1] = bmh.flags & BM_FLAGS_TO_COPY; bitmapOffsets [0][i+1] = bmh.offset + nDataStart; Assert ((i+1) == gameData.pig.tex.nBitmaps [0]); PiggyRegisterBitmap (&bm, szName, 1); } bPigFileInitialized = 1; }
void PlayerShipRead (tPlayerShip *ps, CFile& cf) { int i; ps->nModel = cf.ReadInt (); ps->nExplVClip = cf.ReadInt (); ps->mass = cf.ReadFix (); ps->drag = cf.ReadFix (); ps->maxThrust = cf.ReadFix (); ps->reverseThrust = cf.ReadFix (); ps->brakes = cf.ReadFix (); ps->wiggle = cf.ReadFix (); ps->maxRotThrust = cf.ReadFix (); for (i = 0; i < N_PLAYER_GUNS; i++) cf.ReadVector (ps->gunPoints[i]); }
void LoadD1PigHeader (CFile& cf, int *pSoundNum, int *pBmHdrOffs, int *pBmDataOffs, int *pBitmapNum, int bReadTMapNums) { # define D1_PIG_LOAD_FAILED "Failed loading " D1_PIGFILE int nPigDataStart, nHeaderSize, nBmHdrOffs, nBmDataOffs, nSoundNum, nBitmapNum; switch (cf.Length ()) { case D1_SHARE_BIG_PIGSIZE: case D1_SHARE_10_PIGSIZE: case D1_SHARE_PIGSIZE: case D1_10_BIG_PIGSIZE: case D1_10_PIGSIZE: nPigDataStart = 0; Warning ("%s %s. %s", TXT_LOAD_FAILED, D1_PIGFILE, TXT_D1_SUPPORT); return; default: Warning ("%s %s", TXT_UNKNOWN_SIZE, D1_PIGFILE); Int3 (); // fall through case D1_PIGSIZE: case D1_OEM_PIGSIZE: case D1_MAC_PIGSIZE: case D1_MAC_SHARE_PIGSIZE: nPigDataStart = cf.ReadInt (); if (bReadTMapNums) BMReadD1TMapNums (cf); break; } cf.Seek (nPigDataStart, SEEK_SET); nBitmapNum = cf.ReadInt (); nSoundNum = cf.ReadInt (); nHeaderSize = nBitmapNum * PIGBITMAPHEADER_D1_SIZE + nSoundNum * sizeof (tPIGSoundHeader); nBmHdrOffs = nPigDataStart + 2 * sizeof (int); nBmDataOffs = nBmHdrOffs + nHeaderSize; if (pSoundNum) *pSoundNum = nSoundNum; *pBmHdrOffs = nBmHdrOffs; *pBmDataOffs = nBmDataOffs; *pBitmapNum = nBitmapNum; }
int ReadHamFile (void) { CFile cf; #if 1 char szD1PigFileName [FILENAME_LEN]; #endif int nHAMId; int nSoundOffset = 0; if (!cf.Open ((char *) DEFAULT_HAMFILE, gameFolders.szDataDir, "rb", 0)) { bMustWriteHamFile = 1; return 0; } //make sure ham is valid nType file & is up-to-date nHAMId = cf.ReadInt (); gameData.pig.tex.nHamFileVersion = cf.ReadInt (); if (nHAMId != HAMFILE_ID) Error ("Cannot open ham file %s\n", DEFAULT_HAMFILE); if (gameData.pig.tex.nHamFileVersion < 3) // hamfile contains sound info nSoundOffset = cf.ReadInt (); #ifndef EDITOR BMReadAll (cf); /*---*/PrintLog (" Loading bitmap index translation table\n"); cf.Read (gameData.pig.tex.bitmapXlat, sizeof (ushort)*MAX_BITMAP_FILES, 1); #endif if (gameData.pig.tex.nHamFileVersion < 3) { cf.Seek (nSoundOffset, SEEK_SET); int nSoundNum = cf.ReadInt (); int nSoundStart = cf.Tell (); /*---*/PrintLog (" Loading %d sounds\n", nSoundNum); LoadSounds (cf, nSoundNum, nSoundStart); } cf.Close (); /*---*/PrintLog (" Looking for Descent 1 data files\n"); strcpy (szD1PigFileName, "descent.pig"); if (!cfPiggy [1].File ()) cfPiggy [1].Open (szD1PigFileName, gameFolders.szDataDir, "rb", 0); if (cfPiggy [1].File ()) { gameStates.app.bHaveD1Data = 1; /*---*/PrintLog (" Loading Descent 1 data\n"); BMReadGameDataD1 (cfPiggy [1]); } return 1; }
/* * reads a descent 1 tPIGBitmapHeader structure from a CFile */ void PIGBitmapHeaderD1Read (tPIGBitmapHeader *dbh, CFile& cf) { cf.Read (dbh->name, 8, 1); dbh->dflags = cf.ReadByte (); dbh->width = cf.ReadByte (); dbh->height = cf.ReadByte (); dbh->wh_extra = 0; dbh->flags = cf.ReadByte (); dbh->bmAvgColor = cf.ReadByte (); dbh->offset = cf.ReadInt (); }
static int ReadVariableLights (CFile& cf) { int nLights = cf.ReadInt (); if (!nLights) return 0; if (!gameData.render.lights.flicker.Create (nLights)) return -1; for (int i = 0; i < nLights; i++) gameData.render.lights.flicker [i].Read (cf); return nLights; }
CBitmap *PiggyLoadBitmap (const char *pszFile) { CFile cf; CBitmap *bmP; tBitmapFileHeader bfh; tBitmapInfoHeader bih; if (!cf.Open (pszFile, gameFolders.szDataDir, "rb", 0)) return NULL; bfh.bfType = cf.ReadShort (); bfh.bfSize = (uint) cf.ReadInt (); bfh.bfReserved1 = cf.ReadShort (); bfh.bfReserved2 = cf.ReadShort (); bfh.bfOffBits = (uint) cf.ReadInt (); bih.biSize = (uint) cf.ReadInt (); bih.biWidth = (uint) cf.ReadInt (); bih.biHeight = (uint) cf.ReadInt (); bih.biPlanes = cf.ReadShort (); bih.biBitCount = cf.ReadShort (); bih.biCompression = (uint) cf.ReadInt (); bih.biSizeImage = (uint) cf.ReadInt (); bih.biXPelsPerMeter = (uint) cf.ReadInt (); bih.biYPelsPerMeter = (uint) cf.ReadInt (); bih.biClrUsed = (uint) cf.ReadInt (); bih.biClrImportant = (uint) cf.ReadInt (); if (!(bmP = CBitmap::Create (0, bih.biWidth, bih.biHeight, 1))) { cf.Close (); return NULL; } cf.Seek (bfh.bfOffBits, SEEK_SET); if (bmP->Read (cf, bih.biWidth * bih.biHeight) != bih.biWidth * bih.biHeight) { delete bmP; return NULL; } cf.Close (); return bmP; }
grsBitmap *PiggyLoadBitmap (const char *pszFile) { CFile cf; grsBitmap *bmp; tBitmapFileHeader bfh; tBitmapInfoHeader bih; if (!cf.Open (pszFile, gameFolders.szDataDir, "rb", 0)) return NULL; bfh.bfType = cf.ReadShort (); bfh.bfSize = (unsigned int) cf.ReadInt (); bfh.bfReserved1 = cf.ReadShort (); bfh.bfReserved2 = cf.ReadShort (); bfh.bfOffBits = (unsigned int) cf.ReadInt (); bih.biSize = (unsigned int) cf.ReadInt (); bih.biWidth = (unsigned int) cf.ReadInt (); bih.biHeight = (unsigned int) cf.ReadInt (); bih.biPlanes = cf.ReadShort (); bih.biBitCount = cf.ReadShort (); bih.biCompression = (unsigned int) cf.ReadInt (); bih.biSizeImage = (unsigned int) cf.ReadInt (); bih.biXPelsPerMeter = (unsigned int) cf.ReadInt (); bih.biYPelsPerMeter = (unsigned int) cf.ReadInt (); bih.biClrUsed = (unsigned int) cf.ReadInt (); bih.biClrImportant = (unsigned int) cf.ReadInt (); if (!(bmp = GrCreateBitmap (bih.biWidth, bih.biHeight, 1))) { cf.Close (); return NULL; } cf.Seek (bfh.bfOffBits, SEEK_SET); if (cf.Read (bmp->bmTexBuf, bih.biWidth * bih.biHeight, 1) != 1) { GrFreeBitmap (bmp); return NULL; } cf.Close (); return bmp; }
int ReadTMapInfoND1 (tTexMapInfo *ti, int n, CFile& cf) { int i; for (i = 0;i < n;i++) { cf.Seek (13, SEEK_CUR);// skip filename ti [i].flags = cf.ReadByte (); ti [i].lighting = cf.ReadFix (); ti [i].damage = cf.ReadFix (); ti [i].nEffectClip = cf.ReadInt (); } return i; }
void PiggyBitmapReadD1 ( CFile &cf, CBitmap *bmP, /* read into this bmP */ int nBmDataOffs, /* specific to file */ tPIGBitmapHeader *bmh, /* header info for bmP */ ubyte **pNextBmP, /* where to write it (if 0, use reinterpret_cast<ubyte*> (D2_ALLOC) */ ubyte *colorMap) /* how to translate bmP's colors */ { int zSize, bSwap0255; memset (bmP, 0, sizeof (CBitmap)); bmP->SetWidth (bmh->width + ((short) (bmh->wh_extra&0x0f)<<8)); bmP->SetHeight (bmh->height + ((short) (bmh->wh_extra&0xf0)<<4)); bmP->SetBPP (1); bmP->SetAvgColorIndex (bmh->avgColor); bmP->AddFlags (bmh->flags & BM_FLAGS_TO_COPY); cf.Seek (nBmDataOffs + bmh->offset, SEEK_SET); if (bmh->flags & BM_FLAG_RLE) { zSize = cf.ReadInt (); cf.Seek (-4, SEEK_CUR); } else zSize = bmP->Width () * bmP->Width (); if (pNextBmP) { bmP->SetBuffer (*pNextBmP); *pNextBmP += zSize; } else { if (bmP->CreateBuffer ()) UseBitmapCache (bmP, (int) bmP->FrameSize ()); else return; } bmP->Read (cf, zSize); bSwap0255 = 0; switch (cf.Length ()) { case D1_MAC_PIGSIZE: case D1_MAC_SHARE_PIGSIZE: if (bmh->flags & BM_FLAG_RLE) bSwap0255 = 1; else bmP->Swap_0_255 (); } if (bmh->flags & BM_FLAG_RLE) bmP->RLEExpand (NULL, bSwap0255); bmP->Remap (paletteManager.D1 (), TRANSPARENCY_COLOR, -1); }
void ReadEffectClip (tEffectClip& ec, CFile& cf) { ReadVideoClip (ec.vClipInfo, cf); ec.xTimeLeft = cf.ReadFix (); ec.nCurFrame = cf.ReadInt (); ec.changingWallTexture = cf.ReadShort (); ec.changingObjectTexture = cf.ReadShort (); ec.flags = cf.ReadInt (); ec.nCritClip = cf.ReadInt (); ec.nDestBm = cf.ReadInt (); ec.nDestVClip = cf.ReadInt (); ec.nDestEClip = cf.ReadInt (); ec.xDestSize = cf.ReadFix (); ec.nSound = cf.ReadInt (); ec.nSegment = cf.ReadInt (); ec.nSide = cf.ReadInt (); }
int CMovieLib::SetupHF (CFile& cf) { int nFiles = Count (cf); if (nFiles < 1) return 0; if (!m_movies.Create (nFiles)) return 0; for (int i = 0; i < nFiles; i++) { cf.Read (m_movies [i].m_name, 13, 1); m_movies [i].m_len = cf.ReadInt (); m_movies [i].m_offset = cf.Tell (); cf.Seek (m_movies [i].m_len, SEEK_CUR); //skip data } return nFiles; }
int CMovieLib::Count (CFile& cf) { int size = cf.Size (); int nFiles = 0; int fPos = cf.Tell (); for (;;) { if (size < 17) // name + length return 0; cf.Seek (13, SEEK_CUR); cf.Seek (cf.ReadInt (), SEEK_CUR); //skip data nFiles++; } cf.Seek (fPos, SEEK_SET); return nFiles; }
void PiggyBitmapReadD1 ( CFile &cf, grsBitmap *bmP, /* read into this bmP */ int nBmDataOffs, /* specific to file */ tPIGBitmapHeader *bmh, /* header info for bmP */ ubyte **pNextBmP, /* where to write it (if 0, use (ubyte *) D2_ALLOC) */ ubyte *palette, /* what palette the bmP has */ ubyte *colorMap) /* how to translate bmP's colors */ { int zSize, bSwap0255; memset (bmP, 0, sizeof (grsBitmap)); bmP->bmProps.w = bmP->bmProps.rowSize = bmh->width + ((short) (bmh->wh_extra&0x0f)<<8); bmP->bmProps.h = bmh->height + ((short) (bmh->wh_extra&0xf0)<<4); bmP->bmAvgColor = bmh->bmAvgColor; bmP->bmProps.flags |= bmh->flags & BM_FLAGS_TO_COPY; cf.Seek (nBmDataOffs + bmh->offset, SEEK_SET); if (bmh->flags & BM_FLAG_RLE) { zSize = cf.ReadInt (); cf.Seek (-4, SEEK_CUR); } else zSize = bmP->bmProps.h * bmP->bmProps.w; if (pNextBmP) { bmP->bmTexBuf = *pNextBmP; *pNextBmP += zSize; } else { bmP->bmTexBuf = (ubyte *) D2_ALLOC (bmP->bmProps.h * bmP->bmProps.rowSize); UseBitmapCache (bmP, (int) bmP->bmProps.h * (int) bmP->bmProps.rowSize); } cf.Read (bmP->bmTexBuf, 1, zSize); bSwap0255 = 0; switch (cf.Length ()) { case D1_MAC_PIGSIZE: case D1_MAC_SHARE_PIGSIZE: if (bmh->flags & BM_FLAG_RLE) bSwap0255 = 1; else swap_0_255 (bmP); } if (bmh->flags & BM_FLAG_RLE) rle_expand (bmP, NULL, bSwap0255); GrRemapBitmapGood (bmP, d1Palette, TRANSPARENCY_COLOR, -1); }
void BMReadWeaponInfoD1 (CFile& cf) { cf.Seek ( sizeof (int) + sizeof (int) + sizeof (tBitmapIndex) * D1_MAX_TEXTURES + sizeof (D1_tmap_info) * D1_MAX_TEXTURES + sizeof (ubyte) * D1_MAX_SOUNDS + sizeof (ubyte) * D1_MAX_SOUNDS + sizeof (int) + sizeof (tVideoClip) * D1_VCLIP_MAXNUM + sizeof (int) + sizeof (D1_eclip) * D1_MAX_EFFECTS + sizeof (int) + sizeof (tD1WallClip) * D1_MAX_WALL_ANIMS + sizeof (int) + sizeof (D1Robot_info) * D1_MAX_ROBOT_TYPES + sizeof (int) + sizeof (tJointPos) * D1_MAX_ROBOT_JOINTS, SEEK_CUR); gameData.weapons.nTypes [1] = cf.ReadInt (); for (int i = 0; i < gameData.weapons.nTypes [1]; i++) BMReadWeaponInfoD1N (cf, i); }
static int OOF_ReadInt (CFile& cf, const char *pszIdent) { int i = cf.ReadInt (); OOF_PrintLog (" %s = %d\n", pszIdent, i); return i; }
static int ReadGameFileInfo (CFile& cf, int nStartOffset) { gameTopFileInfo.fileinfo_signature = cf.ReadShort (); gameTopFileInfo.fileinfoVersion = cf.ReadShort (); gameTopFileInfo.fileinfo_sizeof = cf.ReadInt (); // Check signature if (gameTopFileInfo.fileinfo_signature != 0x6705) return -1; // Check version number if (gameTopFileInfo.fileinfoVersion < GAME_COMPATIBLE_VERSION) return -1; // Now, Read in the fileinfo if (cf.Seek (nStartOffset, SEEK_SET)) Error ("Error seeking to gameFileInfo in gamesave.c"); gameFileInfo.fileinfo_signature = cf.ReadShort (); gameFileInfo.fileinfoVersion = cf.ReadShort (); gameFileInfo.fileinfo_sizeof = cf.ReadInt (); cf.Read (gameFileInfo.mine_filename, sizeof (char), 15); gameFileInfo.level = cf.ReadInt (); gameFileInfo.player.offset = cf.ReadInt (); // Player info gameFileInfo.player.size = cf.ReadInt (); gameFileInfo.objects.offset = cf.ReadInt (); // Object info gameFileInfo.objects.count = cf.ReadInt (); gameFileInfo.objects.size = cf.ReadInt (); gameFileInfo.walls.offset = cf.ReadInt (); gameFileInfo.walls.count = cf.ReadInt (); gameFileInfo.walls.size = cf.ReadInt (); gameFileInfo.doors.offset = cf.ReadInt (); gameFileInfo.doors.count = cf.ReadInt (); gameFileInfo.doors.size = cf.ReadInt (); gameFileInfo.triggers.offset = cf.ReadInt (); gameFileInfo.triggers.count = cf.ReadInt (); gameFileInfo.triggers.size = cf.ReadInt (); gameFileInfo.links.offset = cf.ReadInt (); gameFileInfo.links.count = cf.ReadInt (); gameFileInfo.links.size = cf.ReadInt (); gameFileInfo.control.offset = cf.ReadInt (); gameFileInfo.control.count = cf.ReadInt (); gameFileInfo.control.size = cf.ReadInt (); gameFileInfo.botGen.offset = cf.ReadInt (); gameFileInfo.botGen.count = cf.ReadInt (); gameFileInfo.botGen.size = cf.ReadInt (); if (gameTopFileInfo.fileinfoVersion >= 29) { gameFileInfo.lightDeltaIndices.offset = cf.ReadInt (); gameFileInfo.lightDeltaIndices.count = cf.ReadInt (); gameFileInfo.lightDeltaIndices.size = cf.ReadInt (); gameFileInfo.lightDeltas.offset = cf.ReadInt (); gameFileInfo.lightDeltas.count = cf.ReadInt (); gameFileInfo.lightDeltas.size = cf.ReadInt (); } if (gameData.segs.nLevelVersion >= 17) { gameFileInfo.equipGen.offset = cf.ReadInt (); gameFileInfo.equipGen.count = cf.ReadInt (); gameFileInfo.equipGen.size = cf.ReadInt (); } return 0; }
void BMReadGameDataD1 (CFile& cf) { int h, i, j, v10DataOffset; #if 1 tD1WallClip w; D1_tmap_info t; //D1Robot_info r; #endif tWallClip *pw; tTexMapInfo *pt; tRobotInfo *pr; CPolyModel model; ubyte tmpSounds [D1_MAX_SOUNDS]; v10DataOffset = cf.ReadInt (); cf.Read (&gameData.pig.tex.nTextures [1], sizeof (int), 1); j = (gameData.pig.tex.nTextures [1] == 70) ? 70 : D1_MAX_TEXTURES; /*---*/PrintLog (" Loading %d texture indices\n", j); //cf.Read (gameData.pig.tex.bmIndex [1], sizeof (tBitmapIndex), D1_MAX_TEXTURES); ReadBitmapIndices (gameData.pig.tex.bmIndex [1], D1_MAX_TEXTURES, cf); BuildTextureIndex (1, D1_MAX_TEXTURES); /*---*/PrintLog (" Loading %d texture descriptions\n", j); for (i = 0, pt = &gameData.pig.tex.tMapInfo [1][0]; i < j; i++, pt++) { #if DBG cf.Read (t.filename, sizeof (t.filename), 1); #else cf.Seek (sizeof (t.filename), SEEK_CUR); #endif pt->flags = (ubyte) cf.ReadByte (); pt->lighting = cf.ReadFix (); pt->damage = cf.ReadFix (); pt->nEffectClip = cf.ReadInt (); pt->slide_u = pt->slide_v = 0; pt->destroyed = -1; } cf.Read (Sounds [1], sizeof (ubyte), D1_MAX_SOUNDS); cf.Read (AltSounds [1], sizeof (ubyte), D1_MAX_SOUNDS); /*---*/PrintLog (" Initializing %d sounds\n", D1_MAX_SOUNDS); if (gameOpts->sound.bUseD1Sounds) { memcpy (Sounds [1] + D1_MAX_SOUNDS, Sounds [0] + D1_MAX_SOUNDS, MAX_SOUNDS - D1_MAX_SOUNDS); memcpy (AltSounds [1] + D1_MAX_SOUNDS, AltSounds [0] + D1_MAX_SOUNDS, MAX_SOUNDS - D1_MAX_SOUNDS); } else { memcpy (Sounds [1], Sounds [0], MAX_SOUNDS); memcpy (AltSounds [1], AltSounds [0], MAX_SOUNDS); } for (i = 0; i < D1_MAX_SOUNDS; i++) { if (Sounds [1][i] == 255) Sounds [1][i] = Sounds [0][i]; if (AltSounds [1][i] == 255) AltSounds [1][i] = AltSounds [0][i]; } gameData.eff.nClips [1] = cf.ReadInt (); /*---*/PrintLog (" Loading %d animation clips\n", gameData.eff.nClips [1]); ReadVideoClips (gameData.eff.vClips [1], D1_VCLIP_MAXNUM, cf); gameData.eff.nEffects [1] = cf.ReadInt (); /*---*/PrintLog (" Loading %d animation descriptions\n", gameData.eff.nClips [1]); ReadEffectClips (gameData.eff.effects [1], D1_MAX_EFFECTS, cf); gameData.walls.nAnims [1] = cf.ReadInt (); /*---*/PrintLog (" Loading %d CWall animations\n", gameData.walls.nAnims [1]); for (i = 0, pw = &gameData.walls.anims [1][0]; i < D1_MAX_WALL_ANIMS; i++, pw++) { //cf.Read (&w, sizeof (w), 1); pw->xTotalTime = cf.ReadFix (); pw->nFrameCount = cf.ReadShort (); for (j = 0; j < D1_MAX_CLIP_FRAMES; j++) pw->frames [j] = cf.ReadShort (); pw->openSound = cf.ReadShort (); pw->closeSound = cf.ReadShort (); pw->flags = cf.ReadShort (); cf.Read (pw->filename, sizeof (w.filename), 1); pw->pad = (char) cf.ReadByte (); } cf.Read (&gameData.bots.nTypes [1], sizeof (int), 1); /*---*/PrintLog (" Loading %d robot descriptions\n", gameData.bots.nTypes [1]); gameData.bots.info [1] = gameData.bots.info [0]; if (!gameOpts->sound.bUseD1Sounds) return; for (i = 0, pr = &gameData.bots.info [1][0]; i < D1_MAX_ROBOT_TYPES; i++, pr++) { //cf.Read (&r, sizeof (r), 1); cf.Seek ( sizeof (int) * 3 + (sizeof (CFixVector) + sizeof (ubyte)) * MAX_GUNS + sizeof (short) * 5 + sizeof (sbyte) * 7 + sizeof (fix) * 4 + sizeof (fix) * 7 * NDL + sizeof (sbyte) * 2 * NDL, SEEK_CUR); pr->seeSound = (ubyte) cf.ReadByte (); pr->attackSound = (ubyte) cf.ReadByte (); pr->clawSound = (ubyte) cf.ReadByte (); cf.Seek ( JOINTLIST_SIZE * (MAX_GUNS + 1) * N_ANIM_STATES + sizeof (int), SEEK_CUR); pr->always_0xabcd = 0xabcd; } cf.Seek ( sizeof (int) + JOINTPOS_SIZE * D1_MAX_ROBOT_JOINTS + sizeof (int) + D1_WEAPON_INFO_SIZE * D1_MAX_WEAPON_TYPES + sizeof (int) + POWERUP_TYPE_INFO_SIZE * MAX_POWERUP_TYPES_D1, SEEK_CUR); i = cf.ReadInt (); /*---*/PrintLog (" Acquiring model data size of %d polymodels\n", i); for (h = 0; i; i--) { cf.Seek (MODEL_DATA_SIZE_OFFS, SEEK_CUR); model.SetDataSize (cf.ReadInt ()); h += model.DataSize (); cf.Seek (POLYMODEL_SIZE - MODEL_DATA_SIZE_OFFS - sizeof (int), SEEK_CUR); } cf.Seek ( h + sizeof (tBitmapIndex) * D1_MAX_GAUGE_BMS + sizeof (int) * 2 * D1_MAX_POLYGON_MODELS + sizeof (tBitmapIndex) * D1_MAX_OBJ_BITMAPS + sizeof (ushort) * D1_MAX_OBJ_BITMAPS + PLAYER_SHIP_SIZE + sizeof (int) + sizeof (tBitmapIndex) * D1_N_COCKPIT_BITMAPS, SEEK_CUR); /*---*/PrintLog (" Loading sound data\n", i); cf.Read (tmpSounds, sizeof (ubyte), D1_MAX_SOUNDS); //for (i = 0, pr = &gameData.bots.info [1][0]; i < gameData.bots.nTypes [1]; i++, pr++) pr = gameData.bots.info [1] + 17; /*---*/PrintLog (" Initializing sound data\n", i); for (i = 0; i < D1_MAX_SOUNDS; i++) { if (Sounds [1][i] == tmpSounds [pr->seeSound]) pr->seeSound = i; if (Sounds [1][i] == tmpSounds [pr->attackSound]) pr->attackSound = i; if (Sounds [1][i] == tmpSounds [pr->clawSound]) pr->clawSound = i; } pr = gameData.bots.info [1] + 23; for (i = 0; i < D1_MAX_SOUNDS; i++) { if (Sounds [1][i] == tmpSounds [pr->seeSound]) pr->seeSound = i; if (Sounds [1][i] == tmpSounds [pr->attackSound]) pr->attackSound = i; if (Sounds [1][i] == tmpSounds [pr->clawSound]) pr->clawSound = i; } cf.Read (tmpSounds, sizeof (ubyte), D1_MAX_SOUNDS); // for (i = 0, pr = &gameData.bots.info [1][0]; i < gameData.bots.nTypes [1]; i++, pr++) { pr = gameData.bots.info [1] + 17; for (i = 0; i < D1_MAX_SOUNDS; i++) { if (AltSounds [1][i] == tmpSounds [pr->seeSound]) pr->seeSound = i; if (AltSounds [1][i] == tmpSounds [pr->attackSound]) pr->attackSound = i; if (AltSounds [1][i] == tmpSounds [pr->clawSound]) pr->clawSound = i; } pr = gameData.bots.info [1] + 23; for (i = 0; i < D1_MAX_SOUNDS; i++) { if (AltSounds [1][i] == tmpSounds [pr->seeSound]) pr->seeSound = i; if (AltSounds [1][i] == tmpSounds [pr->attackSound]) pr->attackSound = i; if (AltSounds [1][i] == tmpSounds [pr->clawSound]) pr->clawSound = i; } #if 0 cf.Seek (v10DataOffset, SEEK_SET); i = cf.ReadInt (); j = cf.ReadInt (); cf.Seek (i * sizeof (tD1TextureHeader), SEEK_CUR); gameStates.app.bD1Mission = 1; for (i = 0; i < j; i++) { cf.Read (&gameData.pig.sound.sounds [1][i].szName, sizeof (gameData.pig.sound.sounds [1][i].szName), 1); cf.Seek (sizeof (tD1SoundHeader) - sizeof (gameData.pig.sound.sounds [1][i].szName), SEEK_CUR); } #endif }
void LoadReplacementBitmaps (const char *pszLevelName) { char szFilename [SHORT_FILENAME_LEN]; CFile cf; int i, j; CBitmap bm; //first, free up data allocated for old bitmaps PrintLog (" loading replacement textures\n"); CFile::ChangeFilenameExtension (szFilename, pszLevelName, ".pog"); if (cf.Open (szFilename, gameFolders.szDataDir, "rb", 0)) { int id, version, nBitmapNum, bTGA; int bmDataSize, bmDataOffset, bmOffset; ushort *indices; tPIGBitmapHeader *bmh; id = cf.ReadInt (); version = cf.ReadInt (); if (id != MAKE_SIG ('G','O','P','D') || version != 1) { cf.Close (); return; } nBitmapNum = cf.ReadInt (); indices = new ushort [nBitmapNum]; bmh = new tPIGBitmapHeader [nBitmapNum]; #if 0 cf.Read (indices, nBitmapNum * sizeof (ushort), 1); cf.Read (bmh, nBitmapNum * sizeof (tPIGBitmapHeader), 1); #else for (i = 0; i < nBitmapNum; i++) indices [i] = cf.ReadShort (); for (i = 0; i < nBitmapNum; i++) PIGBitmapHeaderRead (bmh + i, cf); #endif bmDataOffset = cf.Tell (); bmDataSize = cf.Length () - bmDataOffset; for (i = 0; i < nBitmapNum; i++) { bmOffset = bmh [i].offset; memset (&bm, 0, sizeof (CBitmap)); bm.AddFlags (bmh [i].flags & (BM_FLAGS_TO_COPY | BM_FLAG_TGA)); bm.SetWidth (bmh [i].width + ((short) (bmh [i].wh_extra & 0x0f) << 8)); bm.SetRowSize (bm.Width ()); if ((bTGA = (bm.Flags () & BM_FLAG_TGA)) && (bm.Width () > 256)) bm.SetHeight (bm.Width () * bmh [i].height); else bm.SetHeight (bmh [i].height + ((short) (bmh [i].wh_extra & 0xf0) << 4)); bm.SetBPP (bTGA ? 4 : 1); if (!(bm.Width () * bm.Width ())) continue; bm.SetAvgColorIndex (bmh [i].avgColor); bm.SetType (BM_TYPE_ALT); if (!bm.CreateBuffer ()) break; cf.Seek (bmDataOffset + bmOffset, SEEK_SET); #if DBG if (indices [i] == nDbgTexture) nDbgTexture = nDbgTexture; #endif if (bTGA) { int nFrames = bm.Height () / bm.Width (); tTgaHeader h; h.width = bm.Width (); h.height = bm.Width (); h.bits = 32; if (!ReadTGAImage (cf, &h, &bm, -1, 1.0, 0, 1)) { bm.DestroyBuffer (); break; } bm.SetFrameCount ((ubyte) nFrames); if (nFrames > 1) { tEffectClip *ecP = NULL; tWallClip *wcP; tVideoClip *vcP; while ((ecP = FindEffect (ecP, indices [i]))) { //e->vc.nFrameCount = nFrames; ecP->flags |= EF_ALTFMT | EF_FROMPOG; } if (!ecP) { if ((wcP = FindWallAnim (indices [i]))) { //w->nFrameCount = nFrames; wcP->flags |= WCF_ALTFMT | WCF_FROMPOG; } else if ((vcP = FindVClip (i))) { //v->nFrameCount = nFrames; vcP->flags |= WCF_ALTFMT | WCF_FROMPOG; } } } j = indices [i]; bm.SetId (j); } else { #if DBG if (j == nDbgTexture) nDbgTexture = nDbgTexture; #endif ReadBitmap (&bm, int (bm.Width ()) * int (bm.Height ()), &cf, true, false); j = indices [i]; bm.SetId (j); bm.RLEExpand (NULL, 0); *bm.Props () = *gameData.pig.tex.bitmapP [j].Props (); bm.Remap (paletteManager.Game (), TRANSPARENCY_COLOR, SUPER_TRANSP_COLOR); } #if DBG if (j == nDbgTexture) nDbgTexture = nDbgTexture; #endif gameData.pig.tex.bitmapP [j].Unload (j, 0); bm.SetFromPog (1); char szName [20]; if (*gameData.pig.tex.bitmapP [j].Name ()) sprintf (szName, "[%s]", gameData.pig.tex.bitmapP [j].Name ()); else sprintf (szName, "POG#%04d", j); bm.SetName (szName); gameData.pig.tex.altBitmapP [j] = bm; gameData.pig.tex.altBitmapP [j].SetBuffer (bm.Buffer (), 0, bm.Length ()); bm.SetBuffer (NULL); gameData.pig.tex.bitmapP [j].SetOverride (gameData.pig.tex.altBitmapP + j); CBitmap* bmP = gameData.pig.tex.altBitmapP + j; tRgbColorf color; if (0 <= bmP->AvgColor (&color)) bmP->SetAvgColorIndex (bmP->Palette ()->ClosestColor (&color)); UseBitmapCache (gameData.pig.tex.altBitmapP + j, (int) bm.Width () * (int) bm.RowSize ()); } delete[] indices; delete[] bmh; cf.Close (); paletteManager.SetLastPig (""); TexMergeFlush (); //for re-merging with new textures } }
void CObject::LoadState (CFile& cf) { info.nSignature = cf.ReadInt (); info.nType = (ubyte) cf.ReadByte (); info.nId = (ubyte) cf.ReadByte (); info.nNextInSeg = cf.ReadShort (); info.nPrevInSeg = cf.ReadShort (); info.controlType = (ubyte) cf.ReadByte (); info.movementType = (ubyte) cf.ReadByte (); info.renderType = (ubyte) cf.ReadByte (); info.nFlags = (ubyte) cf.ReadByte (); info.nSegment = cf.ReadShort (); info.nAttachedObj = cf.ReadShort (); cf.ReadVector (info.position.vPos); cf.ReadMatrix (info.position.mOrient); info.xSize = cf.ReadFix (); info.xShields = cf.ReadFix (); cf.ReadVector (info.vLastPos); info.contains.nType = cf.ReadByte (); info.contains.nId = cf.ReadByte (); info.contains.nCount = cf.ReadByte (); info.nCreator = cf.ReadByte (); info.xLifeLeft = cf.ReadFix (); if (info.movementType == MT_PHYSICS) { cf.ReadVector (mType.physInfo.velocity); cf.ReadVector (mType.physInfo.thrust); mType.physInfo.mass = cf.ReadFix (); mType.physInfo.drag = cf.ReadFix (); mType.physInfo.brakes = cf.ReadFix (); cf.ReadVector (mType.physInfo.rotVel); cf.ReadVector (mType.physInfo.rotThrust); mType.physInfo.turnRoll = cf.ReadFixAng (); mType.physInfo.flags = (ushort) cf.ReadShort (); } else if (info.movementType == MT_SPINNING) { cf.ReadVector (mType.spinRate); } switch (info.controlType) { case CT_WEAPON: cType.laserInfo.parent.nType = cf.ReadShort (); cType.laserInfo.parent.nObject = cf.ReadShort (); cType.laserInfo.parent.nSignature = cf.ReadInt (); cType.laserInfo.xCreationTime = cf.ReadFix (); cType.laserInfo.nLastHitObj = cf.ReadShort (); if (cType.laserInfo.nLastHitObj < 0) cType.laserInfo.nLastHitObj = 0; else { gameData.objs.nHitObjects [Index () * MAX_HIT_OBJECTS] = cType.laserInfo.nLastHitObj; cType.laserInfo.nLastHitObj = 1; } cType.laserInfo.nHomingTarget = cf.ReadShort (); cType.laserInfo.xScale = cf.ReadFix (); break; case CT_EXPLOSION: cType.explInfo.nSpawnTime = cf.ReadFix (); cType.explInfo.nDeleteTime = cf.ReadFix (); cType.explInfo.nDeleteObj = cf.ReadShort (); cType.explInfo.attached.nParent = cf.ReadShort (); cType.explInfo.attached.nPrev = cf.ReadShort (); cType.explInfo.attached.nNext = cf.ReadShort (); break; case CT_AI: cType.aiInfo.behavior = (ubyte) cf.ReadByte (); cf.Read (cType.aiInfo.flags, 1, MAX_AI_FLAGS); cType.aiInfo.nHideSegment = cf.ReadShort (); cType.aiInfo.nHideIndex = cf.ReadShort (); cType.aiInfo.nPathLength = cf.ReadShort (); cType.aiInfo.nCurPathIndex = cf.ReadByte (); cType.aiInfo.bDyingSoundPlaying = cf.ReadByte (); cType.aiInfo.nDangerLaser = cf.ReadShort (); cType.aiInfo.nDangerLaserSig = cf.ReadInt (); cType.aiInfo.xDyingStartTime = cf.ReadFix (); break; case CT_LIGHT: cType.lightInfo.intensity = cf.ReadFix (); break; case CT_POWERUP: cType.powerupInfo.nCount = cf.ReadInt (); cType.powerupInfo.xCreationTime = cf.ReadFix (); cType.powerupInfo.nFlags = cf.ReadInt (); break; } switch (info.renderType) { case RT_MORPH: case RT_POLYOBJ: { int i; rType.polyObjInfo.nModel = cf.ReadInt (); for (i = 0; i < MAX_SUBMODELS; i++) cf.ReadAngVec (rType.polyObjInfo.animAngles [i]); rType.polyObjInfo.nSubObjFlags = cf.ReadInt (); rType.polyObjInfo.nTexOverride = cf.ReadInt (); rType.polyObjInfo.nAltTextures = cf.ReadInt (); break; } case RT_WEAPON_VCLIP: case RT_HOSTAGE: case RT_POWERUP: case RT_FIREBALL: case RT_THRUSTER: rType.vClipInfo.nClipIndex = cf.ReadInt (); rType.vClipInfo.xFrameTime = cf.ReadFix (); rType.vClipInfo.nCurFrame = cf.ReadByte (); break; case RT_LASER: break; } }
static int ReadTriggerInfo (CFile& cf) { int h, i, j; CTrigger *trigP; if (gameFileInfo.triggers.count && (gameFileInfo.triggers.offset > -1)) { #if TRACE console.printf(CON_DBG, " loading CTrigger data ...\n"); #endif if (!gameData.trigs.Create (gameFileInfo.triggers.count, false)) { Error ("Not enough memory for trigger data"); return -1; } if (cf.Seek (gameFileInfo.triggers.offset, SEEK_SET)) { Error ("Error seeking to trigger data\n(file damaged or invalid)"); return -1; } for (i = 0, trigP = TRIGGERS.Buffer (); i < gameFileInfo.triggers.count; i++, trigP++) { trigP->m_info.flagsD1 = 0; if (gameTopFileInfo.fileinfoVersion >= 31) trigP->Read (cf, 0); else { tTriggerV30 trig; int t, nType = 0, flags = 0; if (gameTopFileInfo.fileinfoVersion == 30) V30TriggerRead (trig, cf); else { tTriggerV29 trig29; V29TriggerRead (trig29, cf); trigP->m_info.flagsD1 = trig.flags = trig29.flags; trig.nLinks = (char) trig29.nLinks; trig.value = trig29.value; trig.time = trig29.time; for (t = 0; t < trig.nLinks; t++) { trig.segments [t] = trig29.segments [t]; trig.sides [t] = trig29.sides [t]; } } #if 1 if (gameStates.app.bD1Mission) nType = TT_DESCENT1; #else //Assert(trig.flags & TRIGGER_ON); trig.flags &= ~TRIGGER_ON; if (trig.flags & TRIGGER_CONTROL_DOORS) nType = TT_OPEN_DOOR; else if (trig.flags & TRIGGER_SHIELD_DAMAGE) nType = TT_SHIELD_DAMAGE; else if (trig.flags & TRIGGER_ENERGY_DRAIN) nType = TT_ENERGY_DRAIN; else if (trig.flags & TRIGGER_EXIT) nType = TT_EXIT; else if (trig.flags & TRIGGER_MATCEN) nType = TT_MATCEN; else if (trig.flags & TRIGGER_ILLUSION_OFF) nType = TT_ILLUSION_OFF; else if (trig.flags & TRIGGER_SECRET_EXIT) nType = TT_SECRET_EXIT; else if (trig.flags & TRIGGER_ILLUSION_ON) nType = TT_ILLUSION_ON; #endif else if (trig.flags & TRIGGER_UNLOCK_DOORS) nType = TT_UNLOCK_DOOR; else if (trig.flags & TRIGGER_OPEN_WALL) nType = TT_OPEN_WALL; else if (trig.flags & TRIGGER_CLOSE_WALL) nType = TT_CLOSE_WALL; else if (trig.flags & TRIGGER_ILLUSORY_WALL) nType = TT_ILLUSORY_WALL; else Int3(); if (trig.flags & TRIGGER_ONE_SHOT) flags = TF_ONE_SHOT; trigP->m_info.nType = nType; trigP->m_info.flags = flags; trigP->m_info.nLinks = trig.nLinks; trigP->m_info.nLinks = trig.nLinks; trigP->m_info.value = trig.value; trigP->m_info.time = trig.time; for (t = 0; t < trig.nLinks; t++) { trigP->m_info.segments [t] = trig.segments [t]; trigP->m_info.sides [t] = trig.sides [t]; } } if (trigP->m_info.nLinks < 0) trigP->m_info.nLinks = 0; else if (trigP->m_info.nLinks > MAX_TRIGGER_TARGETS) trigP->m_info.nLinks = MAX_TRIGGER_TARGETS; for (h = trigP->m_info.nLinks, j = 0; j < h; ) { if ((trigP->m_info.segments [j] >= 0) && (trigP->m_info.segments [j] < gameData.segs.nSegments) && (trigP->m_info.sides [j] >= 0) && (trigP->m_info.sides [j] < 6)) j++; else if (--h) { trigP->m_info.segments [j] = trigP->m_info.segments [h]; trigP->m_info.sides [j] = trigP->m_info.sides [h]; } } trigP->m_info.nLinks = h; } } if (gameTopFileInfo.fileinfoVersion >= 33) { gameData.trigs.m_nObjTriggers = cf.ReadInt (); if (gameData.trigs.m_nObjTriggers) { if (!gameData.trigs.Create (gameData.trigs.m_nObjTriggers, true)) { Error ("Not enough memory for object trigger data"); return -1; } for (i = 0; i < gameData.trigs.m_nObjTriggers; i++) OBJTRIGGERS [i].Read (cf, 1); for (i = 0; i < gameData.trigs.m_nObjTriggers; i++) { gameData.trigs.objTriggerRefs [i].prev = cf.ReadShort (); gameData.trigs.objTriggerRefs [i].next = cf.ReadShort (); gameData.trigs.objTriggerRefs [i].nObject = cf.ReadShort (); } } if (gameTopFileInfo.fileinfoVersion < 36) { if (!gameData.trigs.firstObjTrigger.Create (700)) { Error ("Not enough memory for object trigger data"); return -1; } for (i = 0; i < 700; i++) gameData.trigs.firstObjTrigger [i] = cf.ReadShort (); } else { gameData.trigs.firstObjTrigger.Clear (0xff); if (!gameData.trigs.firstObjTrigger.Create (LEVEL_OBJECTS)) { Error ("Not enough memory for object trigger data"); return -1; } for (i = cf.ReadShort (); i; i--) { j = cf.ReadShort (); gameData.trigs.firstObjTrigger [j] = cf.ReadShort (); } } } else { gameData.trigs.m_nObjTriggers = 0; OBJTRIGGERS.Clear (); gameData.trigs.objTriggerRefs.Clear (0xff); gameData.trigs.firstObjTrigger.Clear (0xff); } return 0; }
/* * reads n tRobotInfo structs from a CFile */ int ReadRobotInfos (CArray<tRobotInfo>& botInfo, int n, CFile& cf, int o) { int h, i, j; for (i = 0; i < n; i++) { h = i + o; botInfo [h].nModel = cf.ReadInt (); for (j = 0; j < MAX_GUNS; j++) cf.ReadVector (botInfo [h].gunPoints [j]); cf.Read (botInfo [h].gunSubModels, MAX_GUNS, 1); botInfo [h].nExp1VClip = cf.ReadShort (); botInfo [h].nExp1Sound = cf.ReadShort (); botInfo [h].nExp2VClip = cf.ReadShort (); botInfo [h].nExp2Sound = cf.ReadShort (); botInfo [h].nWeaponType = cf.ReadByte (); botInfo [h].nSecWeaponType = cf.ReadByte (); botInfo [h].nGuns = cf.ReadByte (); botInfo [h].containsId = cf.ReadByte (); botInfo [h].containsCount = cf.ReadByte (); botInfo [h].containsProb = cf.ReadByte (); botInfo [h].containsType = cf.ReadByte (); botInfo [h].kamikaze = cf.ReadByte (); botInfo [h].scoreValue = cf.ReadShort (); botInfo [h].badass = cf.ReadByte (); botInfo [h].energyDrain = cf.ReadByte (); botInfo [h].lighting = cf.ReadFix (); botInfo [h].strength = cf.ReadFix (); botInfo [h].mass = cf.ReadFix (); botInfo [h].drag = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].fieldOfView [j] = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].primaryFiringWait [j] = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].secondaryFiringWait [j] = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].turnTime [j] = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].xMaxSpeed [j] = cf.ReadFix (); for (j = 0; j < NDL; j++) botInfo [h].circleDistance [j] = cf.ReadFix (); cf.Read (botInfo [h].nRapidFireCount, NDL, 1); cf.Read (botInfo [h].evadeSpeed, NDL, 1); botInfo [h].cloakType = cf.ReadByte (); botInfo [h].attackType = cf.ReadByte (); botInfo [h].seeSound = cf.ReadByte (); botInfo [h].attackSound = cf.ReadByte (); botInfo [h].clawSound = cf.ReadByte (); botInfo [h].tauntSound = cf.ReadByte (); botInfo [h].bossFlag = cf.ReadByte (); botInfo [h].companion = cf.ReadByte (); botInfo [h].smartBlobs = cf.ReadByte (); botInfo [h].energyBlobs = cf.ReadByte (); botInfo [h].thief = cf.ReadByte (); botInfo [h].pursuit = cf.ReadByte (); botInfo [h].lightcast = cf.ReadByte (); botInfo [h].bDeathRoll = cf.ReadByte (); botInfo [h].flags = cf.ReadByte (); cf.Read(botInfo [h].pad, 3, 1); botInfo [h].deathrollSound = cf.ReadByte (); botInfo [h].glow = cf.ReadByte (); botInfo [h].behavior = cf.ReadByte (); botInfo [h].aim = cf.ReadByte (); for (j = 0; j < MAX_GUNS + 1; j++) ReadJointLists (botInfo [h].animStates [j], N_ANIM_STATES, cf); botInfo [h].always_0xabcd = cf.ReadInt (); } return i; }
/*========================================================= Streaming::LoadArchive Arguments: archive - pointer to the IMG archive entry (probably just filename) imgID - index of the loading IMG archive Purpose: Loads an IMG archive into the streaming management memory. This allocates entries for COL libraries and IPL sectors. Paintjobs are allocated and models validated. Binary offsets: (1.0 US and 1.0 EU): 0x005B6170 =========================================================*/ static void __cdecl LoadArchive( IMGFile& archive, unsigned int imgID ) { CFile *file = OpenGlobalStream( archive.name, "rb" ); // We should always find the IMG container. Do a security check anyway. // NOTE: Rockstar did this too. if ( !file ) return; modelId_t lastID = 0xFFFFFFFF; union { char version[8]; // has to be "VER2" unsigned int checksum; }; memset( version, 0, 5 ); file->Read( version, 1, 4 ); assert( checksum == '2REV' ); int numFiles; bool successful = file->ReadInt( numFiles ); // Bugfix: make sure we read the file entry count properly. if ( successful ) { // Load all files one by one while ( numFiles ) { numFiles--; resourceFileHeader header; file->Read( &header, 1, sizeof(header) ); if ( header.primaryBlockOffset > biggestResourceBlockCount ) biggestResourceBlockCount = header.primaryBlockOffset; // Zero terminated for safety header.name[ sizeof(header.name) - 1 ] = '\0'; char *dot = strchr( header.name, '.' ); if ( !dot || (size_t)( dot - header.name ) > 20 ) { header.name[ sizeof(header.name) - 1 ] = '\0'; goto failureAdd; } const char *ext = dot + 1; *dot = '\0'; modelId_t id; if ( strnicmp( ext, "DFF", 3 ) == 0 ) { if ( !GetModelByName( header.name, &id ) ) { // We found a structure that has no representation in the game configuration files. // Native GTA:SA supports about 550 of such models. // We can still load such data through .SCM there (RequestSpecialModel). // That is done by storing the resourceFileHeader in a special stack. header.offset = Streaming::GetFileHandle( imgID, header.offset ); // Some sort of debug container (*VAR_MissingModelInfo)->Add( header ); goto failureAdd; } } else if ( strnicmp( ext, "TXD", 3 ) == 0 ) { int txdId = pGame->GetTextureManager()->FindTxdEntry( header.name ); if ( txdId == -1 ) { txdId = pGame->GetTextureManager()->CreateTxdEntry( header.name ); // Assign the txd to a vehicle if found a valid one TxdAssignVehiclePaintjob( header.name, txdId ); } id = (modelId_t)( txdId + DATA_TEXTURE_BLOCK ); } else if ( strnicmp( ext, "COL", 3 ) == 0 ) { id = DATA_COLL_BLOCK + RegisterCollision( header.name ); } else if ( strnicmp( ext, "IPL", 3 ) == 0 ) { unsigned int iplIndex = FindIPLFile( header.name ); if ( iplIndex == 0xFFFFFFFF ) { iplIndex = GetIPLEnvironment().RegisterInstance( header.name ); } id = iplIndex + DATA_IPL_BLOCK; } else if ( strnicmp( ext, "DAT", 3 ) == 0 ) { sscanf( header.name + 5, "%d", &id ); id += DATA_PATHFIND_BLOCK; } else if ( strnicmp( ext, "IFP", 3 ) == 0 ) { id = DATA_ANIM_BLOCK + pGame->GetAnimManager()->RegisterAnimBlock( header.name ); } else if ( strnicmp( ext, "RRR", 3 ) == 0 ) { id = DATA_RECORD_BLOCK + pGame->GetRecordings()->Register( header.name ); } else if ( strnicmp( ext, "SCM", 3 ) == 0 ) { // For now we do not need these script files. // If we ever need them, contact midnightStar/Martin. #ifdef _DEBUG OutputDebugString( "found unsupported SCM file: " ); OutputDebugString( header.name ); OutputDebugString( "\n" ); #endif //_DEBUG goto failureAdd; } else { *dot = '.'; goto failureAdd; } // Prepare the loading of this resource by storing its offset and IMG archive index unsigned int offset, count; // If this ID slot is already occupied, skip preparing this resource. CModelLoadInfoSA& info = Streaming::GetModelLoadInfo( id ); if ( info.GetOffset( offset, count ) ) goto failureAdd; info.m_imgID = imgID; if ( header.secondaryBlockOffset != 0 ) header.primaryBlockOffset = header.secondaryBlockOffset; info.SetOffset( header.offset, header.primaryBlockOffset ); info.m_flags = 0; // This id is used to optimize loading from disk. // The streaming system knows which data is next to each other. // It can be loaded in a swipe. if ( lastID != 0xFFFFFFFF ) Streaming::GetModelLoadInfo( lastID ).m_lastID = id; lastID = id; continue; failureAdd: lastID = 0xFFFFFFFF; } } delete file; }
void CObject::Read (CFile& cf) { #if DBG if (OBJ_IDX (this) == nDbgObj) nDbgObj = nDbgObj; #endif info.nType = cf.ReadByte (); info.nId = cf.ReadByte (); info.controlType = cf.ReadByte (); info.movementType = cf.ReadByte (); info.renderType = cf.ReadByte (); info.nFlags = cf.ReadByte (); info.nSegment = cf.ReadShort (); info.nAttachedObj = -1; cf.ReadVector (info.position.vPos); cf.ReadMatrix (info.position.mOrient); info.xSize = cf.ReadFix (); info.xShields = cf.ReadFix (); cf.ReadVector (info.vLastPos); info.contains.nType = cf.ReadByte (); info.contains.nId = cf.ReadByte (); info.contains.nCount = cf.ReadByte (); switch (info.movementType) { case MT_PHYSICS: cf.ReadVector (mType.physInfo.velocity); cf.ReadVector (mType.physInfo.thrust); mType.physInfo.mass = cf.ReadFix (); mType.physInfo.drag = cf.ReadFix (); mType.physInfo.brakes = cf.ReadFix (); cf.ReadVector (mType.physInfo.rotVel); cf.ReadVector (mType.physInfo.rotThrust); mType.physInfo.turnRoll = cf.ReadFixAng (); mType.physInfo.flags = cf.ReadShort (); break; case MT_SPINNING: cf.ReadVector (mType.spinRate); break; case MT_NONE: break; default: Int3(); } int i; switch (info.controlType) { case CT_AI: cType.aiInfo.behavior = cf.ReadByte (); for (i = 0; i < MAX_AI_FLAGS; i++) cType.aiInfo.flags [i] = cf.ReadByte (); cType.aiInfo.nHideSegment = cf.ReadShort (); cType.aiInfo.nHideIndex = cf.ReadShort (); cType.aiInfo.nPathLength = cf.ReadShort (); cType.aiInfo.nCurPathIndex = (char) cf.ReadShort (); if (gameTopFileInfo.fileinfoVersion <= 25) { cf.ReadShort (); // cType.aiInfo.follow_path_start_seg = cf.ReadShort (); // cType.aiInfo.follow_path_end_seg = } break; case CT_EXPLOSION: cType.explInfo.nSpawnTime = cf.ReadFix (); cType.explInfo.nDeleteTime = cf.ReadFix (); cType.explInfo.nDeleteObj = cf.ReadShort (); cType.explInfo.attached.nNext = cType.explInfo.attached.nPrev = cType.explInfo.attached.nParent = -1; break; case CT_WEAPON: //do I really need to read these? Are they even saved to disk? cType.laserInfo.parent.nType = cf.ReadShort (); cType.laserInfo.parent.nObject = cf.ReadShort (); cType.laserInfo.parent.nSignature = cf.ReadInt (); break; case CT_LIGHT: cType.lightInfo.intensity = cf.ReadFix (); break; case CT_POWERUP: if (gameTopFileInfo.fileinfoVersion >= 25) cType.powerupInfo.nCount = cf.ReadInt (); else cType.powerupInfo.nCount = 1; if (info.nId == POW_VULCAN) cType.powerupInfo.nCount = VULCAN_WEAPON_AMMO_AMOUNT; else if (info.nId == POW_GAUSS) cType.powerupInfo.nCount = VULCAN_WEAPON_AMMO_AMOUNT; else if (info.nId == POW_OMEGA) cType.powerupInfo.nCount = MAX_OMEGA_CHARGE; break; case CT_NONE: case CT_FLYING: case CT_DEBRIS: break; case CT_SLEW: //the CPlayerData is generally saved as slew break; case CT_CNTRLCEN: break; case CT_MORPH: case CT_FLYTHROUGH: case CT_REPAIRCEN: default: Int3(); } switch (info.renderType) { case RT_NONE: break; case RT_MORPH: case RT_POLYOBJ: { rType.polyObjInfo.nModel = cf.ReadInt (); for (int i = 0; i <MAX_SUBMODELS; i++) cf.ReadAngVec(rType.polyObjInfo.animAngles [i]); rType.polyObjInfo.nSubObjFlags = cf.ReadInt (); int tmo = cf.ReadInt (); rType.polyObjInfo.nTexOverride = tmo; rType.polyObjInfo.nAltTextures = 0; break; } case RT_WEAPON_VCLIP: case RT_HOSTAGE: case RT_POWERUP: case RT_FIREBALL: rType.vClipInfo.nClipIndex = cf.ReadInt (); rType.vClipInfo.xFrameTime = cf.ReadFix (); rType.vClipInfo.nCurFrame = cf.ReadByte (); break; case RT_THRUSTER: case RT_LASER: break; case RT_SMOKE: rType.particleInfo.nLife = cf.ReadInt (); rType.particleInfo.nSize [0] = cf.ReadInt (); rType.particleInfo.nParts = cf.ReadInt (); rType.particleInfo.nSpeed = cf.ReadInt (); rType.particleInfo.nDrift = cf.ReadInt (); rType.particleInfo.nBrightness = cf.ReadInt (); rType.particleInfo.color.red = cf.ReadByte (); rType.particleInfo.color.green = cf.ReadByte (); rType.particleInfo.color.blue = cf.ReadByte (); rType.particleInfo.color.alpha = cf.ReadByte (); rType.particleInfo.nSide = cf.ReadByte (); if (gameData.segs.nLevelVersion < 18) rType.particleInfo.nType = 0; else rType.particleInfo.nType = cf.ReadByte (); break; case RT_LIGHTNING: rType.lightningInfo.nLife = cf.ReadInt (); rType.lightningInfo.nDelay = cf.ReadInt (); rType.lightningInfo.nLength = cf.ReadInt (); rType.lightningInfo.nAmplitude = cf.ReadInt (); rType.lightningInfo.nOffset = cf.ReadInt (); rType.lightningInfo.nLightnings = cf.ReadShort (); rType.lightningInfo.nId = cf.ReadShort (); rType.lightningInfo.nTarget = cf.ReadShort (); rType.lightningInfo.nNodes = cf.ReadShort (); rType.lightningInfo.nChildren = cf.ReadShort (); rType.lightningInfo.nSteps = cf.ReadShort (); rType.lightningInfo.nAngle = cf.ReadByte (); rType.lightningInfo.nStyle = cf.ReadByte (); rType.lightningInfo.nSmoothe = cf.ReadByte (); rType.lightningInfo.bClamp = cf.ReadByte (); rType.lightningInfo.bPlasma = cf.ReadByte (); rType.lightningInfo.bSound = cf.ReadByte (); rType.lightningInfo.bRandom = cf.ReadByte (); rType.lightningInfo.bInPlane = cf.ReadByte (); rType.lightningInfo.color.red = cf.ReadByte (); rType.lightningInfo.color.green = cf.ReadByte (); rType.lightningInfo.color.blue = cf.ReadByte (); rType.lightningInfo.color.alpha = cf.ReadByte (); break; default: Int3(); } }
// ---------------------------------------------------------------------------- //loads a level (.LVL) file from disk //returns 0 if success, else error code int LoadLevelData (char * pszFilename, int nLevel) { CFile cf; char filename [128]; int sig, nMineDataOffset, nGameDataOffset; int nError; SetDataVersion (-1); gameData.segs.bHaveSlideSegs = 0; if (gameData.app.nGameMode & GM_NETWORK) { gameData.multiplayer.maxPowerupsAllowed.Clear (0); gameData.multiplayer.powerupsInMine.Clear (0); } #if DBG Level_being_loaded = pszFilename; #endif gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality; for (;;) { strcpy (filename, pszFilename); if (!cf.Open (filename, "", "rb", gameStates.app.bD1Mission)) return 1; strcpy(gameData.segs.szLevelFilename, filename); // #ifdef NEWDEMO // if (gameData.demo.nState == ND_STATE_RECORDING) // NDRecordStartDemo(); // #endif sig = cf.ReadInt (); gameData.segs.nLevelVersion = cf.ReadInt (); gameStates.app.bD2XLevel = (gameData.segs.nLevelVersion >= 10); #if TRACE console.printf (CON_DBG, "gameData.segs.nLevelVersion = %d\n", gameData.segs.nLevelVersion); #endif nMineDataOffset = cf.ReadInt (); nGameDataOffset = cf.ReadInt (); Assert(sig == MAKE_SIG('P','L','V','L')); if (gameData.segs.nLevelVersion >= 8) { //read dummy data cf.ReadInt (); cf.ReadShort (); cf.ReadByte (); } if (gameData.segs.nLevelVersion < 5) cf.ReadInt (); //was hostagetext_offset if (gameData.segs.nLevelVersion > 1) { cf.GetS (szCurrentLevelPalette, sizeof (szCurrentLevelPalette)); if (szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] == '\n') szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] = 0; } if ((gameData.segs.nLevelVersion <= 1) || (szCurrentLevelPalette [0] == 0)) // descent 1 level strcpy (szCurrentLevelPalette, DEFAULT_LEVEL_PALETTE); //D1_PALETTE if (gameData.segs.nLevelVersion >= 3) gameStates.app.nBaseCtrlCenExplTime = cf.ReadInt (); else gameStates.app.nBaseCtrlCenExplTime = DEFAULT_CONTROL_CENTER_EXPLOSION_TIME; if (gameData.segs.nLevelVersion >= 4) gameData.reactor.nStrength = cf.ReadInt (); else gameData.reactor.nStrength = -1; //use old defaults if (gameData.segs.nLevelVersion >= 7) { #if TRACE console.printf (CON_DBG, " loading dynamic lights ...\n"); #endif if (0 > ReadVariableLights (cf)) { cf.Close (); return 5; } } if (gameData.segs.nLevelVersion < 6) { gameData.segs.secret.nReturnSegment = 0; gameData.segs.secret.returnOrient = CFixMatrix::IDENTITY; } else { gameData.segs.secret.nReturnSegment = cf.ReadInt (); for (int i = 0; i < 9; i++) gameData.segs.secret.returnOrient [i] = cf.ReadInt (); } //NOTE LINK TO ABOVE!! cf.Seek (nGameDataOffset, SEEK_SET); nError = LoadMineDataCompiled (cf, 1); cf.Seek (nMineDataOffset, SEEK_SET); nError = LoadMineSegmentsCompiled (cf); if (nError == -1) { //error!! cf.Close (); return 2; } cf.Seek (nGameDataOffset, SEEK_SET); gameData.objs.lists.Init (); nError = LoadMineDataCompiled (cf, 0); if (nError == -1) { //error!! cf.Close (); return 3; } cf.Close (); networkData.nSegmentCheckSum = CalcSegmentCheckSum (); if (meshBuilder.Build (nLevel)) break; if (gameStates.render.nMeshQuality <= 0) return 6; gameStates.render.nMeshQuality--; } gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality; #if 0 if (!(gameData.render.lights.Create () && gameData.render.color.Create () && gameData.render.shadows.Create ())) return 7; #endif if (!gameData.render.mine.Create ()) return 4; lightManager.Setup (nLevel); //moved to loadgame.cpp::LoadLevel() SetAmbientSoundFlags (); return 0; }