public static int aaf_GetSectionSize(JAIInitSection sect, BeBinaryReader br) { switch (sect.type) { default: return(sect.size); } }
private JAIInitSection load2PtSection(BeBinaryReader aafRead) { var NewSect = new JAIInitSection(); var offset = aafRead.ReadInt32(); var size = aafRead.ReadInt32(); NewSect.start = offset; NewSect.size = size; NewSect.flags = 0; return(NewSect); }
public static string GetFileExtension(JAIInitSection sect) { var type = sect.type; switch (type) { default: case JAIInitSectionType.UNKNOWN: case JAIInitSectionType.CUSTOM_DATA: return(".dat"); case JAIInitSectionType.IBNK: return(".bnk"); case JAIInitSectionType.MUSIC_SEQUENCE: return(".bms"); case JAIInitSectionType.SEQUENCE_COLLECTION: return(".arc"); case JAIInitSectionType.SOUND_TABLE: return(".bst"); case JAIInitSectionType.SOUND_TABLE_STRINGS: return(".bstn"); case JAIInitSectionType.STREAM_FILE_TABLE: return(".sft"); case JAIInitSectionType.STREAM_MAP: return(".stm"); case JAIInitSectionType.WSYS: return(".wsy"); case JAIInitSectionType.BDI_DATA: return(".bdi"); } }
public static int baa_GetSectionSize(JAIInitSection sect, BeBinaryReader br) { switch (sect.type) { // The following is true for both V1-Type banks case JAIInitSectionType.IBNK: br.BaseStream.Position = sect.start; br.ReadUInt32(); // Skip IBNK header. return(br.ReadInt32() + 8); // next operator is size case JAIInitSectionType.WSYS: br.BaseStream.Position = sect.start; br.ReadUInt32(); // Skip WSYS header. return(br.ReadInt32() + 8); // next operator is size case JAIInitSectionType.UNKNOWN: br.BaseStream.Position = sect.start; br.ReadInt32(); return(br.ReadInt32()); default: return(sect.size); } }
public JAIInitSection[] load(ref byte[] data) { Stack <JAIInitSection> stk = new Stack <JAIInitSection>(255); var aafRead = new BeBinaryReader(new MemoryStream(data)); byte order = 0; // Parse Header var wsPointerOffset = aafRead.ReadInt32(); var wsPointerCount = aafRead.ReadInt32(); var ibnkPointerOffset = aafRead.ReadInt32(); var ibnkPointerCount = aafRead.ReadInt32(); // load WSYS sections order = 0; // Reset Order aafRead.BaseStream.Position = wsPointerOffset; for (int i = 0; i < wsPointerCount; i++) { var wsOffset = aafRead.ReadInt32(); var wsLength = aafRead.ReadInt32(); if (wsLength > 0) { var nWSJIS = new JAIInitSection() { order = order, start = wsOffset, size = wsLength, number = 0, type = JAIInitSectionType.WSYS, flags = 0, }; stk.Push(nWSJIS); order++; } } // Load IBNK sections order = 0; // reset load order aafRead.BaseStream.Position = ibnkPointerOffset; for (int i = 0; i < ibnkPointerCount; i++) { var ibOffset = aafRead.ReadInt32(); var ibLength = aafRead.ReadInt32(); if (ibLength > 0) { var nWSJIS = new JAIInitSection() { order = order, start = ibOffset, size = ibLength, number = 0, type = JAIInitSectionType.IBNK, flags = 1, }; stk.Push(nWSJIS); order++; } } var stackLen = stk.Count; // Grab how many entries are inside of the stack. JAIInitSection[] sectionData = new JAIInitSection[stackLen]; // Mmake an array of tht size for (int i = stackLen - 1; i > -1; i--) // unroll the stack into an array in reverse (since we stacked it in reverse.) { var obj = stk.Pop(); // Pull the next thing off of the top of the stack. sectionData[i] = obj; // Throw it into the array. } return(sectionData); // Finally, return the array. }
public JAIInitSection[] load(ref byte[] data) { Stack <JAIInitSection> stk = new Stack <JAIInitSection>(255); var aafRead = new BeBinaryReader(new MemoryStream(data)); byte order = 0; if (aafRead.ReadInt32() != BAA_Header) // Check to see if the header is AA_< { throw new InvalidDataException("Data is not BAA"); // If it's not, stop because we're obviously int he wrong spot } while (true) { var ChunkID = aafRead.ReadInt32(); // 0 chunk-id determines end of header. //Console.WriteLine(ChunkID); // Writing the ID of the chunk for testing. if (ChunkID == BAA_Footer) // If the chunk-id is 0, then the array has ended. This means we read >_AA , >_AA being the end of the archive. { break; // stop the while. } order++; // Increment the order for every iteration. switch (ChunkID) { case 0: throw new Exception(@"Tell me, Dr. Freeman, if you can: you have destroyed so much — what is it exactly that you have created? Can you name even one thing?... I thought not."); // Not supposed to get here. case BST: // Matches 'BST ' { var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // Read the start offset newSect.size = aafRead.ReadInt32() - newSect.start; // Read the end offset, subtract by the start offset to get the length. newSect.type = JAIInitSectionType.SOUND_TABLE; // Set the type to a sound table stk.Push(newSect); // Push it to the stack } break; case BSTN: { var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // Read Start offset newSect.size = aafRead.ReadInt32() - newSect.start; // Read end offset, subtract by the start to get the length. newSect.type = JAIInitSectionType.SOUND_TABLE_STRINGS; stk.Push(newSect); } break; case WS: { // WSYS is packed differently. var newSect = new JAIInitSection(); newSect.number = aafRead.ReadInt32(); // First number is the global WSYS ID newSect.start = aafRead.ReadInt32(); // Second number is the base offset of the wsys newSect.flags = aafRead.ReadInt32(); // Third are some sort of flags. I think this is used to tell whether or not it's melodic or not. newSect.type = JAIInitSectionType.WSYS; // Set the type to a wsys stk.Push(newSect); // Push into the stack. } break; case BNK: { // Banks also have unique packing, but are simple var newSect = new JAIInitSection(); newSect.number = aafRead.ReadInt32(); // The global bank ID. newSect.start = aafRead.ReadInt32(); // The base offset. newSect.type = JAIInitSectionType.IBNK; // And of course, it should be an ibnk stk.Push(newSect); } break; case BSC: { // Sequence collection just has a start and end. var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // Read start newSect.size = aafRead.ReadInt32() - newSect.start; // Read end, substract by start to get length. newSect.type = JAIInitSectionType.SEQUENCE_COLLECTION; // And of course BSC type is a sequence collection stk.Push(newSect); // Then push it into the stack. } break; case BMS: { // Embedded BMS are strange. // Their first argument is a number, that starts with 01 then has xx xx xx (at least, from what I can see) // I'm unsure what the purpose of the 01 is, so we'll have to check later to see if it's going to cause issues // (it's probably there for a reason) var newSect = new JAIInitSection(); newSect.number = aafRead.ReadInt32() & 0xFFFF; // For some reason this has 01 as the first byte? Bound to cause issues later. // We're just going to take the last 16 bits of it with an & 0xFFFF to trim off that 01. newSect.start = aafRead.ReadInt32(); // Read the start offset newSect.size = aafRead.ReadInt32() - newSect.start; // Read the end offset newSect.type = JAIInitSectionType.MUSIC_SEQUENCE; // Set the tpye to embedded sequence. stk.Push(newSect); } break; case BSFT: { // Unique packing. Only has a start offset. var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // Read the start offset. newSect.type = JAIInitSectionType.STREAM_FILE_TABLE; stk.Push(newSect); } break; case BFCA: { // Unique packing. Only has a start offset. var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // Read the start offset. newSect.type = JAIInitSectionType.UNKNOWN; stk.Push(newSect); } break; case BAAC: { // This is game-specific data , that we'll have no clue what it does or how it works unless there's some way to detect it -- // I'd advice omitting parsing of this section until more is known about a BAAC section. var newSect = new JAIInitSection(); newSect.start = aafRead.ReadInt32(); // We do know that it has a start offset newSect.size = aafRead.ReadInt32() - newSect.start; // And an end offset newSect.type = JAIInitSectionType.CUSTOM_DATA; // That's about it. stk.Push(newSect); // oh my ghoood. } break; } stk.Peek().order = order; // hacky shit lol // I don't keep a reference to the last object, but i know it's at the top of the stack. So I can just peek the top of the stack to grab the last object. // Then define the order that it was parsed in. } var stackLen = stk.Count; // Grab how many entries are inside of the stack. JAIInitSection[] sectionData = new JAIInitSection[stackLen]; // Mmake an array of tht size for (int i = stackLen - 1; i > -1; i--) // unroll the stack into an array in reverse (since we stacked it in reverse.) { var obj = stk.Pop(); // Pull the next thing off of the top of the stack. sectionData[i] = obj; // Throw it into the array. } return(sectionData); // Finally, return the array. }
public JAIInitSection[] load(ref byte[] data) { Stack <JAIInitSection> stk = new Stack <JAIInitSection>(255); var aafRead = new BeBinaryReader(new MemoryStream(data)); byte order = 0; while (true) { var ChunkID = aafRead.ReadInt32(); // 0 chunk-id determines end of header. // Console.WriteLine(ChunkID); if (ChunkID == 0) // If the chunk-id is 0, then the array has ended. { break; // break loop } switch (ChunkID) // Map chunk id's to types. { case 0: throw new Exception(@"Tell me, Dr. Freeman, if you can: you have destroyed so much — what is it exactly that you have created? Can you name even one thing?... I thought not."); // Not supposed to get here. default: // Is Just a regular section. { var NewSect = loadRegularSection(aafRead); // Load the regular section NewSect.raw_header = ChunkID; NewSect.type = JAIInitSectionType.UNKNOWN; // Don't know what type it is, wasn't in the case NewSect.order = order; // The order it was loaded in (for later reassembly) order++; // Increment Order stk.Push(NewSect); // Push to return stack } break; case 1: { var NewSect = loadRegularSection(aafRead); // Load regular section NewSect.type = JAIInitSectionType.SOUND_TABLE; // Type 1 is the finetune table. NewSect.raw_header = ChunkID; NewSect.order = order; // The order it was loaded in (for later reassembly) order++; // Increment Order stk.Push(NewSect); // Push to return stack break; } case 2: // IBNK case 3: // WSYS are special systemms, they have an indicator, then a table of values, then a terminator, then they continue. { while (true) { var offset = aafRead.ReadInt32(); // Offset will be the determining factor of whether or not to stop, if it's 0, stop, otherwise, that's the offset of your data // Past this, this is just a bunch of typeless "regular" sections squished together. if (offset == 0) { break; // 0-based offset indicates end of seciton. } var size = aafRead.ReadInt32(); // Read size var type = aafRead.ReadInt32(); // Read the type / flags (flags) var NewSect = new JAIInitSection(); // Create new section object NewSect.raw_header = ChunkID; if (ChunkID == 2) // This is just for setting the internal type. 2 is IBNK, 3 is WSYS { NewSect.type = JAIInitSectionType.IBNK; // IBNK } else { NewSect.type = JAIInitSectionType.WSYS; // WSYS } NewSect.start = offset; // Starts at offset NewSect.size = size; // Is of size NewSect.flags = type; // Flags NewSect.order = order; // Order order++; // Increment order after storing. stk.Push(NewSect); // Push to return stack } break; } case 4: { var NewSect = loadRegularSection(aafRead); // Load regular section NewSect.type = JAIInitSectionType.SEQUENCE_COLLECTION; // Type 4 would be the sequence table. NewSect.raw_header = ChunkID; NewSect.order = order; // Store order. order++; // Increment global order stk.Push(NewSect); // Push to return stack break; } case 5: { var NewSect = loadRegularSection(aafRead); // Load regular section NewSect.type = JAIInitSectionType.STREAM_MAP; // Type 5 is stream map NewSect.raw_header = ChunkID; NewSect.order = order; // Store Order order++; // Then incremenet stk.Push(NewSect); // Then push to return stack break; } case 8: { var NewSect = loadRegularSection(aafRead); // Load the regular section NewSect.raw_header = ChunkID; NewSect.type = JAIInitSectionType.BDI_DATA; // Don't know what type it is, wasn't in the case NewSect.order = order; // The order it was loaded in (for later reassembly) order++; // Increment Order stk.Push(NewSect); // Push to return stack break; } } } var stackLen = stk.Count; // Grab how many entries are inside of the stack. JAIInitSection[] sectionData = new JAIInitSection[stackLen]; // Mmake an array of tht size for (int i = stackLen - 1; i > -1; i--) // unroll the stack into an array in reverse (since we stacked it in reverse.) { var obj = stk.Pop(); // Pull the next thing off of the top of the stack. sectionData[i] = obj; // Throw it into the array. } return(sectionData); // Finally, return the array. }