using System.IO; using FSO.Files.Utils; namespace FSO.Files.Formats.IFF.Chunks { /// /// This chunk type holds Behavior code in SimAntics. /// public class BHAV : IffChunk { public TREE RuntimeTree; public BHAVInstruction[] Instructions = new BHAVInstruction[0]; public byte Type; public byte Args; public ushort Locals; public ushort Flags; public uint RuntimeVer; /// /// Reads a BHAV from a stream. /// /// Iff instance. /// A Stream instance holding a BHAV chunk. public override void Read(IffFile iff, System.IO.Stream stream) { using (var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { var version = io.ReadUInt16(); uint count = 0; if (version == 0x8000) { count = io.ReadUInt16(); io.Skip(8); } else if (version == 0x8001) { count = io.ReadUInt16(); var unknown = io.ReadBytes(8); } else if (version == 0x8002) { count = io.ReadUInt16(); this.Type = io.ReadByte(); this.Args = io.ReadByte(); this.Locals = io.ReadUInt16(); this.Flags = io.ReadUInt16(); io.Skip(2); } else if (version == 0x8003) { this.Type = io.ReadByte(); this.Args = io.ReadByte(); this.Locals = io.ReadByte(); io.Skip(2); this.Flags = io.ReadUInt16(); count = io.ReadUInt32(); } Instructions = new BHAVInstruction[count]; for (var i = 0; i < count; i++) { var instruction = new BHAVInstruction(); instruction.Opcode = io.ReadUInt16(); instruction.TruePointer = io.ReadByte(); instruction.FalsePointer = io.ReadByte(); instruction.Operand = io.ReadBytes(8); Instructions[i] = instruction; } } } public override bool Write(IffFile iff, Stream stream) { using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN)) { if (IffFile.TargetTS1) { //version 0x8002 io.WriteUInt16(0x8002); io.WriteUInt16((ushort)Instructions.Length); io.WriteByte(Type); io.WriteByte(Args); io.WriteUInt16(Locals); io.WriteUInt16(Flags); io.WriteBytes(new byte[] { 0, 0 }); foreach (var inst in Instructions) { io.WriteUInt16(inst.Opcode); io.WriteByte(inst.TruePointer); io.WriteByte(inst.FalsePointer); io.WriteBytes(inst.Operand); } } else { io.WriteUInt16(0x8003); io.WriteByte(Type); io.WriteByte(Args); io.WriteByte((byte)Locals); io.WriteBytes(new byte[] { 0, 0 }); io.WriteUInt16(Flags); io.WriteUInt32((ushort)Instructions.Length); foreach (var inst in Instructions) { io.WriteUInt16(inst.Opcode); io.WriteByte(inst.TruePointer); io.WriteByte(inst.FalsePointer); io.WriteBytes(inst.Operand); } } } return true; } } public class BHAVInstruction { public ushort Opcode; public byte TruePointer; public byte FalsePointer; public byte[] Operand; public bool Breakpoint; //only used at runtime } }