public override void Load(ExtendedBinaryReader reader, bool keepOpen = false) { // Check if file has a signature string sig = reader.ReadSignature(); if (sig == "STSC") { // Newer script format uint headerSize = reader.ReadUInt32(); Version = reader.ReadUInt32(); switch (Version) { case 4: // Date A Live: Twin Edition Rio Reincarnation (PSV) ScriptID = reader.ReadUInt16(); break; case 7: // Date A Live: Rio Reincarnation (PC) ScriptName = reader.ReadNullTerminatedString(); reader.JumpAhead((uint)(0x20 - (ScriptName.Length + 1))); reader.JumpAhead(12); ScriptID = reader.ReadUInt32(); break; } } else { // Older script format // Jump back as older scripts have much smaller headers reader.JumpBehind(4); ScriptID = reader.ReadUInt16(); } // Stupid workaround to find the end of the code segment reader.Offset = (uint)reader.BaseStream.Length; while (true) { byte opcode = reader.ReadByte(); if (opcode >= 0x94) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " There is no opcodes larger than 0x93!"); } // Check if its a known instruction if (STSCInstructions.DALRRInstructions[opcode] == null) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " This opcode is unknown!"); } var instruction = STSCInstructions.DALRRInstructions[opcode].Read(reader); Instructions.Add(instruction); if (reader.BaseStream.Position >= reader.Offset) { break; } } }
public override void Load(Stream fileStream) { ExtendedBinaryReader reader = new ExtendedBinaryReader(fileStream) { Offset = 0x20 }; long pos = 0; NinjaInfo = new NinjaInfo() { NodeName = new string(reader.ReadChars(4)) }; uint NodeLength = reader.ReadUInt32(); uint NodeCount = reader.ReadUInt32(); uint Unknown1 = reader.ReadUInt32(); //Seems to always be 0x20 (at least in XN*s)? uint Unknown2 = reader.ReadUInt32(); //Footer Offset Table Start? uint Unknown3 = reader.ReadUInt32(); //Footer Offset Table Data Start? uint Unknown4 = reader.ReadUInt32(); //Footer Offset Table Length? uint Unknown5 = reader.ReadUInt32(); //Seems to always be 1 (at least in XN*s)? for (int i = 0; i < NodeCount; i++) { //Determine type of node to read string NextNodeName = new string(reader.ReadChars(4)); uint NextNodeLength = reader.ReadUInt32(); reader.JumpBehind(8); switch (NextNodeName) { case "NXTL": case "NZTL": NinjaTextureList = ReadNinjaTextureList(reader, pos); break; case "NXEF": NinjaEffectList = ReadNinjaEffectList(reader, pos); break; case "NXNN": NinjaNodeNameList = ReadNinjaNodeNameList(reader, pos); break; case "NXOB": case "NZOB": NinjaObject = ReadNinjaObject(reader, pos); break; default: reader.JumpAhead(8); reader.JumpAhead(NextNodeLength); //Console.WriteLine($"Block {NextNodeName} Not Implemented!"); break; } } }
public override void Load(Stream fileStream) { ExtendedBinaryReader reader = new ExtendedBinaryReader(fileStream) { Offset = 0x20 }; long pos = 0; // NINJA INFO [N*IF] InfoList = new NXIF() { HeaderInfoNode = new string(reader.ReadChars(4)), NodeLength = reader.ReadUInt32(), NodeCount = reader.ReadUInt32() }; reader.JumpTo(InfoList.NodeLength + 8); for (int i = 0; i < InfoList.NodeCount; i++) { string nodeName = new string(reader.ReadChars(4)); uint nodeLength = reader.ReadUInt32(); reader.JumpBehind(8); switch (nodeName) { case "NXTL": case "NZTL": // NINJA TEXTURE LIST [N*TL] TextureList = ReadTextureList(reader, pos); break; case "NXEF": // NINJA EFFECTS [N*EF] EffectList = ReadEffectList(reader, pos); break; case "NXNN": // NINJA NODE NAMES [N*NN] NodeTree = ReadNodeNames(reader, pos); break; case "NXOB": case "NZOB": ObjectList = ReadNodes(reader, pos); break; default: reader.JumpAhead(8); reader.JumpAhead(nodeLength); Console.WriteLine($"Block {nodeName} Not Implemented!"); break; } } }
// Methods public override void Load(Stream fileStream) { var reader = new ExtendedBinaryReader(fileStream, Encoding.ASCII, false); // Checks the Magic reader.JumpAhead(0x8); // Jump to Magic Magic = reader.ReadUInt32(); // Magic reader.JumpBehind(0xC); // Jump back to the start if (Magic == (uint)Magics.Shadow6 || Magic == (uint)Magics.Shadow5) { LoadShadowArchive(reader); // Shadow the Hedgehog Archive } else { LoadHeroesArchive(reader); // Sonic Heroes Archive } }
public static void Decode(this TEXFile file, Format format, ExtendedBinaryReader reader) { ImageBinary image; var endian = file.UseBigEndian ? Endian.BigEndian : Endian.LittleEndian; if ((format & Format.DXT1) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatDXT1Rgba, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.DXT5) != 0 || (format & Format.Large) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatDXT5, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Luminance8) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatLuminance8, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Luminance4) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatLuminance4, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Unknown) != 0) { throw new InvalidTextureFormatException((int)format); } else if ((format & Format.Raster) != 0) { // Read Colour Palette reader.JumpBehind(256 * 4); var colorpalette = reader.ReadBytes(256 * 4); var indies = file.SheetData; file.SheetData = new byte[file.SheetWidth * file.SheetHeight * 4]; for (int i = 0; i < file.SheetWidth * file.SheetHeight; ++i) { file.SheetData[i * 4 + 0] = colorpalette[indies[i] * 4 + 0]; file.SheetData[i * 4 + 1] = colorpalette[indies[i] * 4 + 1]; file.SheetData[i * 4 + 2] = colorpalette[indies[i] * 4 + 2]; file.SheetData[i * 4 + 3] = colorpalette[indies[i] * 4 + 3]; } } else if ((format & Format.PNG) != 0) { using (var endStream = new MemoryStream()) using (var stream = new MemoryStream(file.SheetData)) { var imagePNG = new Bitmap(Image.FromStream(stream)); var bitmap = imagePNG.LockBits(new Rectangle(0, 0, file.SheetWidth, file.SheetHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); file.SheetData = new byte[file.SheetWidth * file.SheetHeight * 4]; Marshal.Copy(bitmap.Scan0, file.SheetData, 0, file.SheetWidth * file.SheetHeight * 4); // Flip Red and Blue channels as this converter does not support ARGB if (file.UseBigEndian) { ImageTools.FlipColors(file.SheetData); } imagePNG.UnlockBits(bitmap); imagePNG.Dispose(); } } else if ((format & Format.BGRA) != 0) { return; } else { throw new InvalidTextureFormatException((int)format); } }