mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-03-19 08:21:22 +00:00
129 lines
4.3 KiB
C#
129 lines
4.3 KiB
C#
|
using System.IO;
|
|||
|
using FSO.Files.Utils;
|
|||
|
|
|||
|
namespace FSO.Files.Formats.IFF.Chunks
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// This chunk type holds Behavior code in SimAntics.
|
|||
|
/// </summary>
|
|||
|
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;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Reads a BHAV from a stream.
|
|||
|
/// </summary>
|
|||
|
/// <param name="iff">Iff instance.</param>
|
|||
|
/// <param name="stream">A Stream instance holding a BHAV chunk.</param>
|
|||
|
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
|
|||
|
}
|
|||
|
}
|