public void endianSwap() { mHeaderMagic = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderMagic); mHeaderSize = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderSize); mHeaderAdler32 = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderAdler32); mFileSize = (uint)Xbox_EndianSwap.endSwapI32((int)mFileSize);// totalheaderSize; mNumChunks = (ushort)Xbox_EndianSwap.endSwapI16((ushort)mNumChunks); mFlags = (ushort)Xbox_EndianSwap.endSwapI16((ushort)mFlags); mID = (uint)Xbox_EndianSwap.endSwapI32((int)mID); mChunkExtraDataSize = 0; }
public void endianSwap() { mID = Xbox_EndianSwap.endSwapI64(mID); mOfs = Xbox_EndianSwap.endSwapI32(mOfs); mSize = Xbox_EndianSwap.endSwapI32(mSize); mAdler32 = Xbox_EndianSwap.endSwapI32(mAdler32); //public byte mFlags; //public byte mAlignmentLog2; //public Int16 mPad0; }
public unsafe bool writeToFile(string filename) { if (File.Exists(filename)) { File.Delete(filename); } FileStream s = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite); BinaryWriter f = new BinaryWriter(s); BinaryReader r = new BinaryReader(s); //open reading from our temp file.. mTempChunkFile.Position = 0; BinaryReader tbr = new BinaryReader(mTempChunkFile); //WRITE OUR HEADER mHeader = new ECFHeader(); mHeader.mHeaderMagic = cECFHeaderMagic; mHeader.mHeaderSize = (uint)sizeof(ECFHeader); //THIS IS JUST THE SIZE OF THIS HEADER f.Write(StructToByteArray(mHeader)); ///////////////////////////////////////// //WRITE OUR CHUNK HEADERS (Dummies!) BECFChunkHeader[] headers = new BECFChunkHeader[mChunks.Count]; ushort padVal = 0; Int32 padVal32 = 0; BECFChunkHeader ch = new BECFChunkHeader(); for (int i = 0; i < mChunks.Count; i++) { headers[i].mID = mChunks[i].mID; headers[i].mOfs = (int)f.BaseStream.Position; headers[i].mSize = (int)mChunks[i].mLength; headers[i].mAdler32 = (int)mChunks[i].mHeaderAdler32;//THIS IS THE ADLER FOR THE ACTUAL CHUNK DATA WE REPRESENT (Post endiean converted!) headers[i].mFlags = 0; headers[i].mAlignmentLog2 = 2; headers[i].mPad0 = (short)padVal; //headers[i].endianSwap();//not yet.... f.Write(StructToByteArray(headers[i])); } //////////////////////////////////////////////// //WRITE OUR CHUNK BLOCKS for (int i = 0; i < mChunks.Count; i++) { //CLM [03.13.07] ECF Changes //we need to ensure each chunk is aligned to the boundry defined by ch.mAlignmentLog2 //so check to see if our position pointer is a multiple of 4 (2^2) //if it's not, write the number of bytes required to MAKE it that multiple. long pos = f.BaseStream.Position; long modPos = pos & 3; if (modPos != 0) { long numBytesToWrite = 4 - modPos; byte[] b = new byte[numBytesToWrite]; f.Write(b); } long streampos = f.BaseStream.Length; f.Write(tbr.ReadBytes((int)mChunks[i].mLength)); //fill in our header data headers[i].mOfs = (int)streampos; //seek back to our header and update our position pointer //f.Seek(sizeof(ECFHeader) + (sizeof(BECFChunkHeader) * i) + sizeof(Int64), SeekOrigin.Begin); //f.Write(Xbox_EndianSwap.endSwapI32((int)streampos)); //f.Seek(0, SeekOrigin.End); } //REWRITE OUR HEADER WITH THE PROPER DATA //write our actual file length back to the header mHeader.mFileSize = (uint)f.BaseStream.Length; // totalheaderSize; mHeader.mNumChunks = (ushort)mChunks.Count; mHeader.mFlags = 0; // mFlags; mHeader.mID = cXTD_ECFFileID; mHeader.mChunkExtraDataSize = 0; mHeader.endianSwap(); //CLM we have to calculate the adler of the endianswapped data, then endian swap ourselves mHeader.mHeaderAdler32 = calcAdler32(StructToByteArray(mHeader), (uint)(sizeof(Int32) * cECFAdler32DWORDsToSkip), (uint)(sizeof(ECFHeader) - sizeof(Int32) * cECFAdler32DWORDsToSkip)); mHeader.mHeaderAdler32 = (uint)Xbox_EndianSwap.endSwapI32((int)mHeader.mHeaderAdler32); f.Seek(0, SeekOrigin.Begin); f.Write(StructToByteArray(mHeader)); // f.Seek(0, SeekOrigin.End); ///////////////////////////////////////// //WRITE OUR CHUNK HEADERS (Real!) for (int i = 0; i < mChunks.Count; i++) { headers[i].endianSwap(); f.Write(StructToByteArray(headers[i])); } headers = null; f.Close(); f = null; s.Close(); s = null; tbr.Close(); tbr = null; clear(); return(true); }
void calculateXTTMemory() { ECFReader ecfR = new ECFReader(); string XTDName = Path.ChangeExtension(gameDirectory + @"\scenario\" + scnName, ".XTT"); if (!ecfR.openForRead(XTDName)) { return; } for (uint i = 0; i < ecfR.getNumChunks(); i++) { ECF.BECFChunkHeader chunkHeader = ecfR.getChunkHeader(i); eXTT_ChunkID id = (eXTT_ChunkID)chunkHeader.mID; switch (id) { case eXTT_ChunkID.cXTT_XTTHeader: //CACHES //add in our 360 cache data int cacheMemCount = 0; const int numCachePages = 20; const int cachePageSize = 512; const int numMips = 2; bool albedoCache = true; bool normalCache = true; bool specCache = false; bool selfCache = false; bool envCache = false; //find our textures in the list int version = ecfR.readInt32(); int numActiveTextures = Xbox_EndianSwap.endSwapI32(ecfR.readInt32()); int numActiveDecals = Xbox_EndianSwap.endSwapI32(ecfR.readInt32()); int numActiveDecalInstances = ecfR.readInt32(); System.Text.Encoding enc = System.Text.Encoding.ASCII; int totalArtistTextureMem = 0; for (int k = 0; k < numActiveTextures; k++) { byte[] fName = ecfR.readBytes(256); string textureName = enc.GetString(fName); textureName = textureName.TrimEnd('\0'); textureName = textureName.TrimStart('\0'); totalArtistTextureMem += giveDependentTextureMemoryFootprint(textureName, ref specCache, ref selfCache, ref envCache); int b = ecfR.readInt32(); b = ecfR.readInt32(); b = ecfR.readInt32(); } for (int k = 0; k < numActiveDecals; k++) { byte[] fName = ecfR.readBytes(256); string textureName = enc.GetString(fName); textureName = textureName.TrimEnd('\0'); textureName = textureName.TrimStart('\0'); totalArtistTextureMem += giveDependentTextureMemoryFootprint(textureName, ref specCache, ref selfCache, ref envCache); } mMemEst.setOrAddMemoryElement("Terrain Artist Texture", totalArtistTextureMem, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); if (albedoCache) { cacheMemCount += giveTextureCacheMemoryRequirement(numCachePages, cachePageSize, numMips, 0); //DXT1 * numCachePages (mip0 & mip1) } if (normalCache) { cacheMemCount += giveTextureCacheMemoryRequirement(numCachePages, cachePageSize, numMips, 1); } ; //DXN if (specCache) { cacheMemCount += giveTextureCacheMemoryRequirement(numCachePages, cachePageSize, numMips, 0); //DXT1 } if (envCache) { cacheMemCount += giveTextureCacheMemoryRequirement(numCachePages, cachePageSize, numMips, 0); //DXT1 } if (selfCache) { cacheMemCount += giveTextureCacheMemoryRequirement(numCachePages, cachePageSize, numMips, 1); //DXT5 } mMemEst.setOrAddMemoryElement("Terrain Texture Cache", cacheMemCount, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); //cache calculation break; case eXTT_ChunkID.cXTT_AtlasChunkAlbedo: mMemEst.setOrAddMemoryElement("Terrain Skirt Texture", chunkHeader.mSize, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); break; case eXTT_ChunkID.cXTT_RoadsChunk: mMemEst.setOrAddMemoryElement("Terrain Roads", chunkHeader.mSize, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); break; case eXTT_ChunkID.cXTT_FoliageQNChunk: mMemEst.setOrAddMemoryElement("Terrain Foliage", chunkHeader.mSize, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); break; case eXTT_ChunkID.cXTT_TerrainAtlasLinkChunk: mMemEst.setOrAddMemoryElement("Terrain Blends", chunkHeader.mSize, ScnMemoryEstimate.eMainCatagory.eCat_Terrain); break; } } ecfR.close(); ecfR = null; }