public fileSoundBankDP(string fileLoc) { valid = false; binfileLoc = fileLoc; tabfileLoc = fileLoc.Replace(".bin", ".tab"); if (!File.Exists(tabfileLoc)) { return; } valid = true; binReader = new BinaryReader(File.Open(fileLoc, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); tabReader = new BinaryReader(File.Open(tabfileLoc, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); //Read the table file and populate the address list; for this specifically, the addresses should be (CTL start, tbl start, tbl end, end of tab) uint curAddress = 0; while (tabReader.BaseStream.Position != tabReader.BaseStream.Length) { curAddress = Endian.SwapUInt32(tabReader.ReadUInt32()); if ((int)curAddress == 0 && addresses.Count > 0) { break; } addresses.Add(curAddress); } tabReader.Close(); //start reading the data from the binary file. beginning should be the magic number, and then ctl //all three audio sample files only have one bank, i think. //TODO: in every seek, if flags = 0 it's an offset from the start of the TBL file? if (Endian.SwapUInt32(binReader.ReadUInt32()) != 0x42310001) { return; //invalid start to the file } bankOffset = Endian.SwapUInt32(binReader.ReadUInt32()); binReader.BaseStream.Seek(bankOffset, SeekOrigin.Begin); bankInstruments = Endian.SwapUInt16(binReader.ReadUInt16()); bankFlags = Endian.SwapUInt16(binReader.ReadUInt16()); bankPad = Endian.SwapUInt16(binReader.ReadUInt16()); bankSampleRate = Endian.SwapUInt16(binReader.ReadUInt16()); percussionOffset = Endian.SwapUInt32(binReader.ReadUInt32()); Console.WriteLine("Bank Offset: {0:X}", bankOffset); Console.WriteLine("Percussion Offset: {0:X}", percussionOffset); if (bankFlags == 0 || bankFlags == 1) //yay standard format! { for (int i = 0; i < bankInstruments; i++) //for each instrument in the bank, add the data to array. { var tempInstrument = new typeInstrument(); binReader.BaseStream.Seek(bankOffset + 0xC + (i * 4), SeekOrigin.Begin); //pull the address and store it UInt32 instrumentAddress = Endian.SwapUInt32(binReader.ReadUInt32()); binReader.BaseStream.Seek(instrumentAddress, SeekOrigin.Begin); //Console.WriteLine("Instrument Address: {0:X}", instrumentAddress); tempInstrument.volume = binReader.ReadByte(); tempInstrument.pan = binReader.ReadByte(); tempInstrument.priority = binReader.ReadByte(); tempInstrument.flags = binReader.ReadByte(); tempInstrument.tremType = binReader.ReadByte(); tempInstrument.tremRate = binReader.ReadByte(); tempInstrument.tremDepth = binReader.ReadByte(); tempInstrument.tremDelay = binReader.ReadByte(); tempInstrument.vibType = binReader.ReadByte(); tempInstrument.vibRate = binReader.ReadByte(); tempInstrument.vibDepth = binReader.ReadByte(); tempInstrument.vibDelay = binReader.ReadByte(); tempInstrument.bendRange = Endian.SwapUInt16(binReader.ReadUInt16()); tempInstrument.soundCount = Endian.SwapUInt16(binReader.ReadUInt16()); for (int j = 0; j < tempInstrument.soundCount; j++)//for each sound in the instrument, add the data to the array. { var tempSound = new typeSound(); tempSound.wavetable.predictors = new List <ushort>(); tempSound.wavetable.state = new List <ushort>(); tempSound.wavetable.waveData = new List <byte>(); binReader.BaseStream.Seek(instrumentAddress + 0x10 + (j * 4), SeekOrigin.Begin); //goto and read sound data UInt32 soundAddress = Endian.SwapUInt32(binReader.ReadUInt32()); //Console.WriteLine("Sound Address #" + j + ": {0:X}", soundAddress); binReader.BaseStream.Seek(soundAddress, SeekOrigin.Begin); tempSound.envelopeAddress = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.keymapAddress = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetableAddress = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.pan = binReader.ReadByte(); tempSound.volume = binReader.ReadByte(); tempSound.flags = binReader.ReadByte(); binReader.BaseStream.Seek(tempSound.envelopeAddress, SeekOrigin.Begin); //goto and read envelope data tempSound.envelope.attackTime = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.envelope.decayTime = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.envelope.releaseTime = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.envelope.attackVolume = Endian.SwapUInt16(binReader.ReadUInt16()); tempSound.envelope.decayVolume = Endian.SwapUInt16(binReader.ReadUInt16()); binReader.BaseStream.Seek(tempSound.keymapAddress, SeekOrigin.Begin); //goto and read keymap data tempSound.keymap.velocityMin = binReader.ReadByte(); tempSound.keymap.velocityMax = binReader.ReadByte(); tempSound.keymap.keyMin = binReader.ReadByte(); tempSound.keymap.keyMax = binReader.ReadByte(); tempSound.keymap.keyBase = binReader.ReadByte(); tempSound.keymap.detune = binReader.ReadByte(); binReader.BaseStream.Seek(tempSound.wavetableAddress, SeekOrigin.Begin);//goto and read wavetable data tempSound.wavetable.waveBase = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.waveLength = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.type = binReader.ReadByte(); tempSound.wavetable.flags = binReader.ReadByte(); binReader.ReadUInt16(); //padding to end of 32-bit chunk tempSound.wavetable.loopAddress = Endian.SwapUInt32(binReader.ReadUInt32()); if (tempSound.wavetable.type == 0) { tempSound.wavetable.predictorAddress = Endian.SwapUInt32(binReader.ReadUInt32()); if (tempSound.wavetable.loopAddress != 0) { binReader.BaseStream.Seek(tempSound.wavetable.loopAddress + (bankOffset * tempSound.wavetable.flags), SeekOrigin.Begin); //goto and read loop data tempSound.wavetable.start = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.end = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.count = Endian.SwapUInt32(binReader.ReadUInt32()); for (int k = 0; k < 16; k++) //fill the state array { tempSound.wavetable.state.Add(Endian.SwapUInt16(binReader.ReadUInt16())); } } if (tempSound.wavetable.predictorAddress != 0) { binReader.BaseStream.Seek(tempSound.wavetable.predictorAddress + (bankOffset * tempSound.wavetable.flags), SeekOrigin.Begin); //goto and read predictor data tempSound.wavetable.order = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.numPredictors = Endian.SwapUInt32(binReader.ReadUInt32()); //tempSound.wavetable.predictors.Add((ushort)(0x00000002)); //THESE ARE HERE CUZ IDK //tempSound.wavetable.predictors.Add((ushort)(0x00000004)); for (int k = 0; k < tempSound.wavetable.order * tempSound.wavetable.numPredictors * 8; k++) { tempSound.wavetable.predictors.Add(Endian.SwapUInt16(binReader.ReadUInt16())); } } } else { if (tempSound.wavetable.loopAddress != 0) { binReader.BaseStream.Seek(tempSound.wavetable.loopAddress + (bankOffset * tempSound.wavetable.flags), SeekOrigin.Begin); //goto and read loop data tempSound.wavetable.start = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.end = Endian.SwapUInt32(binReader.ReadUInt32()); tempSound.wavetable.count = Endian.SwapUInt32(binReader.ReadUInt32()); } } if (i == 52 && j == 0) { Console.WriteLine("WaveData Address: {0:X}", tempSound.wavetable.waveBase + (bankOffset * tempSound.wavetable.flags)); Console.WriteLine("Key Max: {0:X}", tempSound.keymap.keyMax); Console.WriteLine("Order:( should be 2) {0:X}", tempSound.wavetable.order); Console.WriteLine("predictors: (should be 4) {0:X}", tempSound.wavetable.numPredictors); //throw new Exception("time to overview"); //for debugging. } binReader.BaseStream.Seek(tempSound.wavetable.waveBase + (bankOffset /* * tempSound.wavetable.flags*/) + 0x210, SeekOrigin.Begin);//goto and read wave data for (int k = 0; k < tempSound.wavetable.waveLength; k++) { tempSound.wavetable.waveData.Add(binReader.ReadByte()); } tempInstrument.sounds.Add(tempSound); } instruments.Add(tempInstrument); } //Console.WriteLine("Instruments added: " + instruments.Count); } binReader.Close(); }
public fileTextureDB(string fileLoc) { valid = false; binfileLoc = fileLoc; //tabfileLoc = fileLoc.Replace(".bin",".tab"); //if(!File.Exists(tabfileLoc)) //{ // return; //} valid = true; binReader = new BinaryReader(File.Open(fileLoc, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); //tabReader = new BinaryReader(File.Open(tabfileLoc, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); //Read the table file and populate the address list uint curAddress = 0; uint size = Endian.SwapUInt32(binReader.ReadUInt32()); for (int i = 0; i < size; i++) { curAddress = Endian.SwapUInt32(binReader.ReadUInt32()); addresses.Add(curAddress); } System.Console.WriteLine("Addresses found: " + addresses.Count.ToString()); //tabReader.Close(); //read and store images from binary file for (int i = 0; i < addresses.Count; i++) { if (addresses[addresses.Count - 1] == binReader.BaseStream.Position) { return; //trusting the format to save us here } if (addresses[i] == binReader.BaseStream.Length) { return; //just in case our trust is broken } //prepare file reader binReader.BaseStream.Seek(addresses[i], SeekOrigin.Begin); byte width = binReader.ReadByte(); byte height = binReader.ReadByte(); byte format = binReader.ReadByte(); byte unk1 = binReader.ReadByte(); //byte flip = binReader.ReadByte();//unused? binReader.BaseStream.Seek(addresses[i] + 8, SeekOrigin.Begin); Bitmap tempImg = new Bitmap(width, height); //begin comparisons! if (format == 0) { if (unk1 == 0x0) //normal read. RGBA, byte each { for (int y = tempImg.Height - 1; y >= 0; --y) { for (int x = 0; x < tempImg.Width; x++) { uint argb = binReader.ReadUInt32(); Color col = Color.FromArgb((byte)(argb >> 24), (byte)argb, (byte)(argb >> 8), (byte)(argb >> 16)); tempImg.SetPixel(x, y, col); } } } else //every other row is pair-swapped (2,3,0,1 6,7,4,5 etc) { for (int y = 0; y < tempImg.Height; y++) { if ((y % 2) == 0) { for (int x = 0; x < tempImg.Width; x++) { uint argb = binReader.ReadUInt32(); Color col = Color.FromArgb((byte)(argb >> 24), (byte)argb, (byte)(argb >> 8), (byte)(argb >> 16)); tempImg.SetPixel(x, y, col); } } else { for (int x = 0; x < tempImg.Width; x += 4) { for (int xx = 0; xx < 4; xx++) { uint argb = binReader.ReadUInt32(); Color col = Color.FromArgb((byte)(argb >> 24), (byte)argb, (byte)(argb >> 8), (byte)(argb >> 16)); tempImg.SetPixel(x + ((xx + 2) % 4), y, col); } } } } } } else if (format == 0x5 || format == 0x25) { if (unk1 == 0x0) //greyscale image, byte is the brightness, vertically flipped { for (int y = tempImg.Height - 1; y >= 0; --y) { for (int x = 0; x < tempImg.Width; x++) { byte val = binReader.ReadByte(); tempImg.SetPixel(x, y, Color.FromArgb(val, val, val)); } } } else { for (int y = tempImg.Height - 1; y >= 0; --y) { if ((height % 2) != (y % 2)) //if (height is even and row is odd) or vice-versa { for (int x = 0; x < tempImg.Width; x++) { byte val = binReader.ReadByte(); tempImg.SetPixel(x, y, Color.FromArgb(val, val, val)); } } else //each chunk of 8 pixels are reversed in this row { for (int x = 0; x < tempImg.Width; x++) { byte val = binReader.ReadByte(); tempImg.SetPixel(x + 4 - ((((int)x / 4) % 2) * 8), y, Color.FromArgb(val, val, val)); } } } } } else if (format == 0x15) //greyscale image, byte per pixel { for (int y = 0; y < tempImg.Height; y++) { for (int x = 0; x < tempImg.Width; x++) { byte val = binReader.ReadByte(); tempImg.SetPixel(x, y, Color.FromArgb(val, val, val)); } } } else if (format == 0x26) //greyscale image, byte per two pixels { for (int y = 0; y < tempImg.Height; y++) { for (int x = 0; x < tempImg.Width; x += 2) { byte val = binReader.ReadByte(); byte in1 = (byte)(val & 0xf0); byte in2 = (byte)(val << 4); tempImg.SetPixel(x, y, Color.FromArgb(in1, in1, in1)); tempImg.SetPixel(x + 1, y, Color.FromArgb(in2, in2, in2)); } } } //UNSURE FROM HERE ON else if (format == 0x1) { if (unk1 != 0) //5-bit R G B, 1-bit a, every other row gets pair-swapped { for (int y = 0; y < tempImg.Height; y++) { if ((y % 2) == 0) { for (int x = 0; x < tempImg.Width; x++) { ushort val = Endian.SwapUInt16(binReader.ReadUInt16()); byte r = (byte)((val & 0xF800) >> 8); byte g = (byte)((val & 0x07C0) >> 3); byte b = (byte)((val & 0x003E) << 2); byte a = (byte)((val & 0x0001) * 0xFF); tempImg.SetPixel(x, y, Color.FromArgb(a, r, g, b)); } } else { for (int x = 0; x < tempImg.Width; x += 4) { for (int xx = 0; xx < 4; xx++) { if (x + (xx + 2) % 4 >= width) { return; } ushort val = Endian.SwapUInt16(binReader.ReadUInt16()); byte r = (byte)((val & 0xF800) >> 8); byte g = (byte)((val & 0x07C0) >> 3); byte b = (byte)((val & 0x003E) << 2); byte a = (byte)((val & 0x0001) * 0xFF); tempImg.SetPixel(x + ((xx + 2) % 4), y, Color.FromArgb(a, r, g, b)); } } } } } else //5-bit R G B, 1-bit a, vertical flip { for (int y = tempImg.Height - 1; y >= 0; --y) { for (int x = 0; x < tempImg.Width; x++) { ushort val = Endian.SwapUInt16(binReader.ReadUInt16()); byte r = (byte)((val & 0xF800) >> 8); byte g = (byte)((val & 0x07C0) >> 3); byte b = (byte)((val & 0x003E) << 2); byte a = (byte)((val & 0x0001) * 0xFF); tempImg.SetPixel(x, y, Color.FromArgb(a, r, g, b)); } } } } else if (format == 0x4) //4-bit, 2 bytes per pixel { for (int y = 0; y < tempImg.Height; y++) { for (int x = 0; x < tempImg.Width; x++) { ushort val = binReader.ReadUInt16(); byte r = (byte)((val & 0xF) * 0x11); byte g = (byte)(((val >> 4) & 0xF) * 0x11); byte b = (byte)(((val >> 8) & 0xF) * 0x11); byte a = (byte)(((val >> 12) & 0xF) * 0x11); Color col = Color.FromArgb(a, r, g, b); tempImg.SetPixel(x, y, col); } } } else if (format == 0x11) //5-bit R G B, 1-bit a, vertical flip { for (int y = tempImg.Height - 1; y >= 0; --y) { for (int x = 0; x < tempImg.Width; x++) { ushort val = Endian.SwapUInt16(binReader.ReadUInt16()); byte r = (byte)((val & 0xF800) >> 8); byte g = (byte)((val & 0x07C0) >> 3); byte b = (byte)((val & 0x003E) << 2); byte a = (byte)((val & 0x0001) * 0xFF); tempImg.SetPixel(x, y, Color.FromArgb(a, r, g, b)); } } } else { System.Console.WriteLine("Whoops, new format: " + format); continue; } images.Add(tempImg); } System.Console.WriteLine("Finished reading"); binReader.Close(); System.Console.WriteLine("Closed reader"); }