private int ChunkDynamicObject(byte[] data, int nbDynamicObject, int indexDataStart) { byte[] lengthData = new byte[4]; int lengthDataInt; int totalSize = 0; for (int i = 0; i < nbDynamicObject; i++) { // get the length of the dynamic object Array.Copy(data, indexDataStart, lengthData, 0, lengthData.Length); lengthDataInt = CSBF1DynamicObject.GetHeaderLength(CGeneric.ConvertByteArrayToInt(lengthData)); //create the array to add the object byte[] dataDynamicObject = new byte[lengthDataInt]; //create the new dynamicObject item Array.Copy(data, indexDataStart, dataDynamicObject, 0, dataDynamicObject.Length); dynamicObjectList.Add(new CSBF1DynamicObject(dataDynamicObject)); //increment totalSize and indexStart indexDataStart += lengthDataInt; totalSize += lengthDataInt; } return(totalSize); }
private int ChunkTextObject(byte[] data, int nbTextObject, int indexDataStart) { byte[] lengthHeader = new byte[4]; byte[] lengthText = new byte[4]; int lengthHeaderInt; int lengthTextInt; int totalSize = 0; for (int i = 0; i < nbTextObject; i++) { // get the length of the header text object Array.Copy(data, indexDataStart, lengthHeader, 0, lengthHeader.Length); lengthHeaderInt = CSBF1TextObject.GetHeaderLength(CGeneric.ConvertByteArrayToInt(lengthHeader)); //grab the size of the text (add 4 for the header (size text) and determine length of text (multiply per 2)) Array.Copy(data, indexDataStart + lengthHeaderInt, lengthText, 0, lengthText.Length); lengthTextInt = lengthText.Length + CGeneric.ConvertByteArrayToInt(lengthText) * 2; //store the new item byte[] dataTextObject = new byte[lengthHeaderInt + lengthTextInt]; Array.Copy(data, indexDataStart, dataTextObject, 0, dataTextObject.Length); textObjectList.Add(new CSBF1TextObject(dataTextObject, lengthHeaderInt, lengthTextInt)); //increment totalSize and indexStart indexDataStart += lengthHeaderInt + lengthTextInt; totalSize += lengthHeaderInt + lengthTextInt; } return(totalSize); }
public CSBF1(Byte[] rawData, Byte[] ressourceName) : base(rawData, ressourceName) { //grab nb ressources used in scene int nbTextureScene = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, 4, 4)); //grab names of texture used (bif list) bifList = new List <byte[]>(); for (int i = 0; i < nbTextureScene; i++) { byte[] tmpArray = new byte[16]; Array.Copy(rawData, 8 + i * 16, tmpArray, 0, tmpArray.Length); bifList.Add(tmpArray); } //grab index number of scene int headerSize = 12 + bifList.Count * 0x10; int nbScene = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, headerSize - 4, 4)); //send the data without SBF header for chuncking data.. byte[] dataWithoutHeader = new byte[rawData.Length - headerSize]; Array.Copy(rawData, headerSize, dataWithoutHeader, 0, dataWithoutHeader.Length); SetChunk(dataWithoutHeader, nbScene); }
public void Init() { //init header... // take 2 byte : for the fist byte keep only 4 last bit and for the second keep only the 4 first.. byte b1 = rawData[17]; byte b2 = rawData[18]; b1 %= 16; b1 <<= 4; b2 /= 16; b1 += b2; headerBFF2.transparencyPixelIndex = b1; headerBFF2.displayLength = rawData[8]; // check if the data is compressed and if data had indexed color headerBFF2.isCompressedTexture = (rawData[18] % 16 > 7) ? true : false; //copy basic informations.. headerBFF2.textureType = rawData[19]; headerBFF2.nameLength = rawData[35]; headerBFF2.isIndexedColor = (headerBFF2.textureType == 0x32 || headerBFF2.textureType == 0x33) ? true : false; headerBFF2.textureWidth = new byte[2]; headerBFF2.textureHeight = new byte[2]; headerBFF2.name = new byte[headerBFF2.nameLength]; headerBFF2.bytePerPixel = (byte)CTextureManager.GetBytePerPixel((CGeneric.Compression)headerBFF2.textureType); Array.Copy(rawData, 22, headerBFF2.textureWidth, 0, 2); Array.Copy(rawData, 26, headerBFF2.textureHeight, 0, 2); Array.Copy(rawData, 36, headerBFF2.name, 0, headerBFF2.nameLength); //remove last not necessary character if (headerBFF2.name[headerBFF2.nameLength - 1] == 0) { headerBFF2.name = new byte[headerBFF2.nameLength - 1]; Array.Copy(rawData, 36, headerBFF2.name, 0, headerBFF2.nameLength - 1); } headerBFF2.sizeX = CGeneric.ConvertByteArrayToInt(headerBFF2.textureWidth); headerBFF2.sizeY = CGeneric.ConvertByteArrayToInt(headerBFF2.textureHeight); //extract palette int startingData = 0x24 + headerBFF2.nameLength; if (headerBFF2.isIndexedColor) { ExtractPalette(startingData); startingData += headerBFF2.palette.Length + headerBFF2.paletteSize.Length; } headerBFF2.dataCompressed = new Byte[rawData.Length - startingData]; Array.Copy(rawData, startingData, headerBFF2.dataCompressed, 0, headerBFF2.dataCompressed.Length); }
private void ExtractPalette(int indexPalette) { //get palette size headerBFF2.paletteSize = new Byte[4]; Array.Copy(rawData, indexPalette, headerBFF2.paletteSize, 0, headerBFF2.paletteSize.Length); //fill palette data int paletteSize1 = CGeneric.ConvertByteArrayToInt(headerBFF2.paletteSize); headerBFF2.palette = new Byte[paletteSize1 * headerBFF2.bytePerPixel]; Array.Copy(rawData, indexPalette + headerBFF2.paletteSize.Length, headerBFF2.palette, 0, headerBFF2.palette.Length); }
public byte[] GetRawData() { int flags = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, 0, 4)); //set unknown bit values //CGeneric.SetBitInInt(ref flags, 1, true); //Array.Copy(CGeneric.ConvertIntToByteArray(flags), 0, rawData, 0, 4); return(rawData); }
private void ChunkDataToRessources(Byte[] ressourceData) { int generalIndex = 0; // check all the ressources list... for (int i = 0; i < ressourcesList.Count(); i++) { //grab only one item by one int sizeElement = CGeneric.ConvertByteArrayToInt(ressourcesList[i].ressourceSize); Byte[] tmpContainerData = new byte[sizeElement]; Array.Copy(ressourceData, generalIndex, tmpContainerData, 0, tmpContainerData.Length); //determine the type of data and fill in the apropriated list Byte[] dataPattern = new byte[4]; Array.Copy(tmpContainerData, 0, dataPattern, 0, dataPattern.Length); switch (CGeneric.ConvertByteArrayToInt(dataPattern)) { case (int)CGeneric.RessourceType.FIB: fibList.Add(new C3FIB(tmpContainerData, ressourcesList[i].ressourceName)); fibList[fibList.Count - 1].Init(); break; case (int)CGeneric.RessourceType.HVQM: hvqmList.Add(new CHVQM(tmpContainerData, ressourcesList[i].ressourceName)); break; case (int)CGeneric.RessourceType.SBF: sbfList.Add(new CSBF1(tmpContainerData, ressourcesList[i].ressourceName)); break; default: rdfList.Add(new CRDF(tmpContainerData, ressourcesList[i].ressourceName)); break; } generalIndex += sizeElement; if (sizeElement % 2 == 1) { generalIndex += 1; } } }
public CSBF1Scene(byte[] rawData) { this.rawData = rawData; //read sceneNameLength byte[] sceneNameLength = new byte[4]; Array.Copy(rawData, 4, sceneNameLength, 0, sceneNameLength.Length); int sceneLength = CGeneric.ConvertByteArrayToInt(sceneNameLength); //extract sceneName this.sceneName = new byte[sceneLength]; Array.Copy(rawData, 8, sceneName, 0, sceneLength); //decompose scene in 3 parts. byte[] dataWithoutHeader = new Byte[rawData.Length - 8 - sceneLength]; Array.Copy(rawData, 8 + sceneLength, dataWithoutHeader, 0, dataWithoutHeader.Length); this.sceneNameDebug = CGeneric.ConvertByteArrayToString(sceneName); //decompose data of scene ChunkScene(dataWithoutHeader, 8 + sceneLength); //for text, decompose groups of text GroupTextData(); }
private int ChunkTextureManagementObject(byte[] data, int nbTextureManagementObject, int indexDataStart) { byte[] lengthData = new byte[4]; int lengthDataInt; int totalSize = 0; for (int i = 0; i < nbTextureManagementObject; i++) { // get the length of the texture management object Array.Copy(data, indexDataStart, lengthData, 0, lengthData.Length); lengthDataInt = CSBF1TextureManagement.GetHeaderLength(CGeneric.ConvertByteArrayToInt(lengthData)); //create the new texture management item byte[] dataTextureManagementObject = new byte[lengthDataInt]; Array.Copy(data, indexDataStart, dataTextureManagementObject, 0, dataTextureManagementObject.Length); textureManagementObjectList.Add(new CSBF1TextureManagement(dataTextureManagementObject)); indexDataStart += lengthDataInt; totalSize += lengthDataInt; } return(totalSize); }
private void decomposeHeader() { //data grabbed from 4 first bytes (converted to bits) int dataInitial = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, 0, 4)); //set flags transparencybit = CGeneric.GetBitStateFromInt(dataInitial, 22); extra2 = CGeneric.GetBitStateFromInt(dataInitial, 26); //set unknown flags bit19 = CGeneric.GetBitStateFromInt(dataInitial, 19); bit20 = CGeneric.GetBitStateFromInt(dataInitial, 20); bit21 = CGeneric.GetBitStateFromInt(dataInitial, 21); bit23 = CGeneric.GetBitStateFromInt(dataInitial, 23); bit24 = CGeneric.GetBitStateFromInt(dataInitial, 24); bit25 = CGeneric.GetBitStateFromInt(dataInitial, 25); bit27 = CGeneric.GetBitStateFromInt(dataInitial, 27); bit28 = CGeneric.GetBitStateFromInt(dataInitial, 28); bit29 = CGeneric.GetBitStateFromInt(dataInitial, 29); bit30 = CGeneric.GetBitStateFromInt(dataInitial, 30); bit31 = CGeneric.GetBitStateFromInt(dataInitial, 31); bit32 = CGeneric.GetBitStateFromInt(dataInitial, 32); if (transparencybit) { this.transparency = rawData[31]; } if (rawData[3] != 8) { this.isCompressedTexture = true; } this.textureIndex = rawData[27]; this.posX = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, 4, 4)); this.posY = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(rawData, 8, 4)); }
private void ChunkScene(byte[] data, int headerSize) { //separate 3 types of data -> dynamicObject, text and textureManagment int generalIndex = 0; //get the number of dynamic object byte[] nbDynamicArray = new byte[4]; Array.Copy(data, generalIndex, nbDynamicArray, 0, nbDynamicArray.Length); //increment the global index with 4 (the size of nbDynamicArray.Length) generalIndex += nbDynamicArray.Length; //fill dynamic objects this.dynamicObjectList = new List <CSBF1DynamicObject>(); generalIndex += ChunkDynamicObject(data, CGeneric.ConvertByteArrayToInt(nbDynamicArray), generalIndex); //get the number of text object byte[] nbTextArray = new byte[4]; Array.Copy(data, generalIndex, nbTextArray, 0, nbTextArray.Length); //increment the global index with 4 (the size of nbDynamicArray.Length) generalIndex += nbTextArray.Length; //fill text objects this.textObjectList = new List <CSBF1TextObject>(); generalIndex += ChunkTextObject(data, CGeneric.ConvertByteArrayToInt(nbTextArray), generalIndex); //get the number of texture management object byte[] nbTextureArray = new byte[4]; Array.Copy(data, generalIndex, nbTextureArray, 0, nbTextureArray.Length); //increment the global index with 4 (the size of nbDynamicArray.Length) generalIndex += nbTextureArray.Length; //fill texture management object this.textureManagementObjectList = new List <CSBF1TextureManagement>(); generalIndex += ChunkTextureManagementObject(data, CGeneric.ConvertByteArrayToInt(nbTextureArray), generalIndex); //add 4 because 0x00000000 at the end of each scene.. //add specific value for ISO file (the 4th hidden thing in sbf... var hidden4thData = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(data, generalIndex, 4)); generalIndex += 4; if (hidden4thData != 0) { for (int i = 0; i < hidden4thData; i++) { var code4thData = CGeneric.ConvertByteArrayToInt(CGeneric.GiveMeArray(data, generalIndex, 4)); switch (code4thData) { case 0x1E: case 0x9E: generalIndex += 0x20; break; case 0x1F: generalIndex += 0x24; break; default: throw new NotImplementedException(); } } } var a = sceneNameDebug; //with the datasize determinated set the new rawData array byte[] newArrayRawData = new byte[generalIndex + headerSize]; Array.Copy(this.rawData, 0, newArrayRawData, 0, newArrayRawData.Length); this.rawData = newArrayRawData; }
//specific format for BFF header private static byte[] SetHeader(CGeneric.Compression textureType, byte greenAlphaIndex, byte compressedValue, byte[] displayedWidth, byte[] pixelWidth, byte[] displayHeight, byte[] bffName, byte[] colorCount) { //fixedsize = 36 + bffName + 1 if bffName size is not pair + 4 for palette color count byte[] headerBFF2 = new Byte[36 + bffName.Length + bffName.Length % 2 + colorCount.Length]; headerBFF2[8] = 0x8; //write "BFF2" for (int i = 0; i < CGeneric.patternBFF2.Length; i++) { headerBFF2[12 + i] = CGeneric.patternBFF2[i]; } //decompose the next two bytes in nibbles //grab the nibbles of alpha color List <byte> alphaColor = CGeneric.ByteToNibble(greenAlphaIndex); //write two nibbles for the both bytes.. headerBFF2[17] = CGeneric.NibbleToByte(2, alphaColor[0]); headerBFF2[18] = CGeneric.NibbleToByte(alphaColor[1], compressedValue); //write texture type headerBFF2[19] = (byte)textureType; //write displayed width for (int i = 0; i < displayedWidth.Length; i++) { headerBFF2[20 + i] = displayedWidth[i]; } //write pixel width for (int i = 0; i < pixelWidth.Length; i++) { headerBFF2[22 + i] = pixelWidth[i]; } //write display height for (int i = 0; i < displayHeight.Length; i++) { headerBFF2[26 + i] = displayHeight[i]; } //prepare instruction length (depending of the pixelWidth value) double instructionLengthValue = CGeneric.ConvertByteArrayToInt(pixelWidth); switch (textureType) { case CGeneric.Compression.greyscale: instructionLengthValue *= 2; break; case CGeneric.Compression.max16Colors: instructionLengthValue /= 2; break; case CGeneric.Compression.trueColor16Bits: instructionLengthValue *= 2; break; case CGeneric.Compression.trueColor32Bits: instructionLengthValue *= 4; break; } byte[] instructLength = CGeneric.ConvertIntToByteArray((int)Math.Floor(instructionLengthValue)); //write instruction length for (int i = 0; i < instructLength.Length; i++) { headerBFF2[28 + i] = instructLength[i]; } //length of file name if (bffName.Length % 2 == 0) { headerBFF2[35] = (byte)bffName.Length; } else { headerBFF2[35] = (byte)(bffName.Length + 1); } //write bff name for (int i = 0; i < bffName.Length; i++) { headerBFF2[36 + i] = bffName[i]; } for (int i = 0; i < colorCount.Length; i++) { headerBFF2[36 + bffName.Length + bffName.Length % 2 + i] = colorCount[i]; } return(headerBFF2); }