private int back = 0; // utility public void LoadWSYS(BeBinaryReader WSYSReader) { BaseAddress = WSYSReader.BaseStream.Position; waves = new WSYSWave[32768]; // TEMPORARY. Fix WSYS Loading! current_header = WSYSReader.ReadInt32(); if (current_header != WSYS) { Console.WriteLine("Error: Section base at {0} is not WSYS, is instead {1:X}", BaseAddress, current_header); return; } size = WSYSReader.ReadInt32(); id = WSYSReader.ReadInt32(); WSYSReader.ReadUInt32(); // 4 bytes, not used. .. I think // A little messy, but both of these need to be loaded before we can continue. var winfo_offset = WSYSReader.ReadInt32(); // relative offset to wave info offset pointer table. var wbct_offset = WSYSReader.ReadInt32(); // relative offset to wave info offset pointer table. int[] winfOffsets; int[] wbctOffsets; { // Load WINF offsets. WSYSReader.BaseStream.Position = BaseAddress + winfo_offset; current_header = WSYSReader.ReadInt32(); // Should be WINF winfOffsets = new int[WSYSReader.ReadInt32()]; // 4 bytes count for (int i = 0; i < winfOffsets.Length; i++) { winfOffsets[i] = WSYSReader.ReadInt32(); // Int32's following the length. } // Load WBCT data WSYSReader.BaseStream.Position = BaseAddress + wbct_offset; current_header = WSYSReader.ReadInt32(); // Should be WBCT WSYSReader.ReadUInt32(); // 4 bytes unused? wbctOffsets = new int[WSYSReader.ReadInt32()]; // 4 bytes count for (int i = 0; i < wbctOffsets.Length; i++) { wbctOffsets[i] = WSYSReader.ReadInt32(); // Int32's following the length. } } groups = new WSYSGroup[winfOffsets.Length]; for (int i = 0; i < winfOffsets.Length; i++) { /* This is loading the data for a WINF */ WSYSReader.BaseStream.Position = BaseAddress + winfOffsets[i]; var Group = new WSYSGroup(); Group.path = Helpers.readArchiveName(WSYSReader); var fobj = File.OpenRead("./Banks/" + Group.path); // Open the .AW file (AW contains only ADPCM data, nothing else.) var fobj_reader = new BeBinaryReader(fobj); // Create a reader for it. int waveInfoCounts = WSYSReader.ReadInt32(); // 4 byte count int[] info_offsets = new int[waveInfoCounts]; for (int q = 0; q < waveInfoCounts; q++) { info_offsets[q] = WSYSReader.ReadInt32(); } Group.IDMap = new int[UInt16.MaxValue]; // We have to initialize the containers for the wave information Group.Waves = new WSYSWave[waveInfoCounts]; /* Since the count should be equal, we're loading the info for the WBCT in he re as well */ WSYSReader.BaseStream.Position = BaseAddress + wbctOffsets[i]; // The first several bytes of the WBCT are uselss, a WBCT points directly to a SCNE. current_header = WSYSReader.ReadInt32(); // This should be SCNE. WSYSReader.ReadUInt64(); // The next 8 bytes are useless. var cdf_offset = WSYSReader.ReadInt32(); // However, the next 4 contain the pointer to c_DF relative to our base. WSYSReader.BaseStream.Position = BaseAddress + cdf_offset; current_header = WSYSReader.ReadInt32(); // Should be C_DF. int waveid_count = WSYSReader.ReadInt32(); // Count of our WAVE ID int[] waveid_offsets = new int[waveid_count]; // Be ready to store them for (int q = 0; q < waveid_count; q++) { waveid_offsets[q] = WSYSReader.ReadInt32(); // Read each waveid } // Finally, we're going to get our wave data. for (int wav = 0; wav < waveInfoCounts; wav++) { var o_Wave = new WSYSWave(); WSYSReader.BaseStream.Position = BaseAddress + waveid_offsets[wav]; var aw_id = WSYSReader.ReadInt16(); // Strangely enough, it has an AW_ID here. This tells which file it sits in? I guess they're normally loaded separately. o_Wave.id = WSYSReader.ReadInt16(); // This is the waveid for this wave, it's normally globally unique, but some games hot-load banks. WSYSReader.BaseStream.Position = BaseAddress + info_offsets[wav]; // Seek to the offset of the actual wave parameters. WSYSReader.ReadByte(); // I have no clue what the first byte does. o_Wave.format = WSYSReader.ReadByte(); // Tells what format it's in, usually type 5 AFC (ADPCM) o_Wave.key = WSYSReader.ReadByte(); // Tells the base key for this wave (0-127 usually) WSYSReader.ReadByte(); // I have no clue what this byte does. //var srate = WSYSReader.ReadBytes(4); o_Wave.sampleRate = WSYSReader.ReadSingle(); /* * oh. its a float. * oops * if (o_Wave.format == 5) * { * o_Wave.sampleRate = 32000; /// ???? * } * * if (o_Wave.sampleRate == 5666) // What the actual f**k. Broken value, can't figure out why. * { * o_Wave.sampleRate = 44100; // I guess set the srate to 44100? * } */ o_Wave.w_start = WSYSReader.ReadUInt32(); // 4 byte start in AW o_Wave.w_size = WSYSReader.ReadUInt32(); // 4 byte size in AW var b = WSYSReader.ReadUInt32(); o_Wave.loop = b == UInt32.MaxValue ? true : false; // Weird looping flag? o_Wave.loop_start = (int)Math.Floor(((WSYSReader.ReadInt32() / 8f)) * 16f); o_Wave.loop_end = (int)Math.Floor(((WSYSReader.ReadInt32() / 8f)) * 16f); o_Wave.sampleCount = WSYSReader.ReadInt32(); // 4 byte sample cont // Console.WriteLine("L {0:X} (0x{1:X}), LS {2:X} , LE {3:X}, SC {4:X} SZ {5:X}", o_Wave.loop, b, o_Wave.loop_start, o_Wave.loop_end,o_Wave.sampleCount,o_Wave.w_size); //Console.ReadLine(); var name = string.Format("0x{0:X}.wav", o_Wave.id); var name2 = string.Format("0x{0:X}.par", o_Wave.id); if (!Directory.Exists("./WSYS_CACHE")) { Directory.CreateDirectory("./WSYS_CACHE"); } if (!Directory.Exists("./WSYS_CACHE/AW_" + Group.path)) { Directory.CreateDirectory("./WSYS_CACHE/AW_" + Group.path); } o_Wave.pcmpath = "./WSYS_CACHE/AW_" + Group.path + "/" + name; Group.Waves[wav] = o_Wave; // We're done with just about everything except the PCM data now (ADPCM / AFC conversion) Group.IDMap[o_Wave.id] = wav; waves[o_Wave.id] = o_Wave; // TEMPORARY, FIX WSYS LOADING! fobj_reader.BaseStream.Position = o_Wave.w_start; var adpcm = fobj_reader.ReadBytes((int)o_Wave.w_size); if (!File.Exists(o_Wave.pcmpath)) { Helpers.AFCtoPCM16(adpcm, o_Wave.sampleRate, (int)o_Wave.w_size, o_Wave.format, o_Wave.pcmpath); } } } }