mirror of
https://github.com/kwsch/pkNX.git
synced 2026-03-22 10:14:22 -05:00
272 lines
6.3 KiB
C#
272 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace pkNX.Structures;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class AmxHeader
|
|
{
|
|
// Cell Size magic verification
|
|
public const ushort MAGIC_32 = 0xf1e0;
|
|
public const ushort MAGIC_64 = 0xf1e1;
|
|
public const ushort MAGIC_16 = 0xf1e2;
|
|
|
|
/// <summary> Size of the "file" </summary>
|
|
public int Size; // 0x00
|
|
|
|
/// <summary> Signature </summary>
|
|
public ushort Magic; // 0x04
|
|
|
|
/// <summary> File format version </summary>
|
|
public byte FileVersion; // 0x06
|
|
|
|
/// <summary> Required version of the AMX </summary>
|
|
public byte AMXVersion; // 0x07
|
|
|
|
/// <summary> Feature flags </summary>
|
|
public AmxFlags Flags; // 0x08
|
|
|
|
/// <summary> Size of a definition record </summary>
|
|
public short DefinitionSize; // 0x0A
|
|
|
|
/// <summary> Initial value of COD - code block </summary>
|
|
public int COD; // 0x0C
|
|
|
|
/// <summary> initial value of DAT - data block </summary>
|
|
public int Data; // 0x10
|
|
|
|
/// <summary> Initial value of HEA - start of the heap </summary>
|
|
public int Heap; // 0x14
|
|
|
|
/// <summary> Initial value of STP - stack top </summary>
|
|
public int StackTop; // 0x18
|
|
|
|
/// <summary> Initial value of CIP - the instruction pointer </summary>
|
|
public int CurrentInstructionPointer; // 0x20
|
|
|
|
/// <summary> Offset to the "public functions" table </summary>
|
|
public int Publics; // 0x24
|
|
|
|
/// <summary> Offset to the "native functions" table </summary>
|
|
public int Natives; // 0x28
|
|
|
|
/// <summary> Offset to the table of libraries </summary>
|
|
public int Libraries; // 0x2C
|
|
|
|
/// <summary> Offset to the "public variables" table </summary>
|
|
public int PublicVars; // 0x30
|
|
|
|
/// <summary> Offset to the "public tagnames" table </summary>
|
|
public int Tags; // 0x34
|
|
|
|
/// <summary> Offset to the name table </summary>
|
|
public int NameTable; // 0x38
|
|
|
|
/// <summary> Offset to the overlay table </summary>
|
|
public int Overlays; // 0x3C
|
|
|
|
public int CellSize
|
|
{
|
|
get
|
|
{
|
|
return Magic switch
|
|
{
|
|
MAGIC_16 => 16,
|
|
MAGIC_32 => 32,
|
|
MAGIC_64 => 64,
|
|
_ => throw new ArgumentException("Invalid Magic identifier."),
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
/* File format version
|
|
* 0 original version
|
|
* 1 opcodes JUMP.pri, SWITCH and CASETBL
|
|
* 2 compressed files
|
|
* 3 public variables
|
|
* 4 opcodes SWAP.pri/alt and PUSHADDR
|
|
* 5 tagnames table
|
|
* 6 reformatted header
|
|
* 7 name table, opcodes SYMTAG & SYSREQ.D
|
|
* 8 opcode BREAK, renewed debug interface
|
|
* 9 macro opcodes
|
|
* 10 position-independent code, overlays, packed instructions
|
|
* 11 relocating instructions for the native interface, reorganized instruction set
|
|
*/
|
|
|
|
/// <summary>
|
|
/// Debug data at the end of an amx
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class AmxDebugHeader
|
|
{
|
|
public const ushort MAGIC_DEBUG = 0xf1ef;
|
|
|
|
public int Size;
|
|
public ushort Magic;
|
|
public byte FileVersion;
|
|
public byte AMXVersion;
|
|
public AmxFlags Flags;
|
|
public short Files;
|
|
public short Lines;
|
|
public short Symbols;
|
|
public short Tags;
|
|
public short Automatons;
|
|
public short States;
|
|
|
|
public const int SIZE = 36;
|
|
}
|
|
|
|
public class TableRecord
|
|
{
|
|
public TableRecord(string name, uint address)
|
|
{
|
|
Name = name;
|
|
Address = address;
|
|
}
|
|
|
|
public string Name { get; }
|
|
public uint Address { get; }
|
|
}
|
|
|
|
public class Tag
|
|
{
|
|
public Tag(string name, uint tagID)
|
|
{
|
|
TagID = tagID;
|
|
Name = name;
|
|
}
|
|
|
|
public uint TagID { get; }
|
|
public string Name { get; }
|
|
}
|
|
|
|
public class Dimension
|
|
{
|
|
public Dimension(int tagID, Tag tag, int size)
|
|
{
|
|
TagID = tagID;
|
|
Tag = tag;
|
|
Size = size;
|
|
}
|
|
|
|
public int TagID { get; }
|
|
public Tag Tag { get; }
|
|
public int Size { get; }
|
|
}
|
|
|
|
public class Argument
|
|
{
|
|
public Argument(VariableType type, string name, int tagID, Tag tag, Dimension[] dims)
|
|
{
|
|
Type = type;
|
|
Name = name;
|
|
TagID = tagID;
|
|
Tag = tag;
|
|
Dimensions = dims;
|
|
}
|
|
|
|
public int TagID { get; }
|
|
public VariableType Type { get; }
|
|
public string Name { get; }
|
|
public Tag Tag { get; }
|
|
public Dimension[] Dimensions { get; }
|
|
}
|
|
|
|
public enum Register : uint
|
|
{
|
|
Pri,
|
|
Alt,
|
|
}
|
|
|
|
public enum Scope : uint
|
|
{
|
|
Global,
|
|
Local,
|
|
Static,
|
|
}
|
|
|
|
public class Variable
|
|
{
|
|
public Variable(int addr, int tagID, Tag tag, uint codeStart,
|
|
uint codeEnd, VariableType type, Scope scope,
|
|
string name, Dimension[] dims = null)
|
|
{
|
|
Address = addr;
|
|
TagID = (uint)tagID;
|
|
Tag = tag;
|
|
CodeStart = codeStart;
|
|
CodeEnd = codeEnd;
|
|
Type = type;
|
|
Scope = scope;
|
|
Name = name;
|
|
Dims = dims;
|
|
}
|
|
|
|
public int Address { get; }
|
|
public uint CodeStart { get; }
|
|
public uint CodeEnd { get; }
|
|
public string Name { get; }
|
|
public VariableType Type { get; }
|
|
public Scope Scope { get; }
|
|
public Tag Tag { get; set; }
|
|
public uint TagID { get; }
|
|
public Dimension[] Dims { get; }
|
|
}
|
|
|
|
public class Signature
|
|
{
|
|
public Signature(string name) => Name = name;
|
|
|
|
public Tag ReturnType { get; set; }
|
|
public uint TagID { get; protected set; }
|
|
public string Name { get; }
|
|
|
|
public Argument[] Args { get; protected set; }
|
|
}
|
|
|
|
public class Native : Signature
|
|
{
|
|
public Native(string name, int index) : base(name) => Index = index;
|
|
|
|
public int Index { get; }
|
|
|
|
public void SetDebugInfo(int tagID, Tag tag, Argument[] args)
|
|
{
|
|
TagID = (uint)tagID;
|
|
ReturnType = tag;
|
|
Args = args;
|
|
}
|
|
}
|
|
|
|
public class Function : Signature
|
|
{
|
|
public Function(uint addr, uint codeStart, uint codeEnd, string name, Tag tag)
|
|
: base(name)
|
|
{
|
|
Address = addr;
|
|
CodeStart = codeStart;
|
|
CodeEnd = codeEnd;
|
|
ReturnType = tag;
|
|
}
|
|
|
|
public Function(uint addr, uint codeStart, uint codeEnd, string name, uint tagID)
|
|
: base(name)
|
|
{
|
|
Address = addr;
|
|
CodeStart = codeStart;
|
|
CodeEnd = codeEnd;
|
|
TagID = tagID;
|
|
}
|
|
|
|
public void SetArguments(List<Argument> from) => Args = from.ToArray();
|
|
|
|
public uint Address { get; }
|
|
public uint CodeStart { get; }
|
|
public uint CodeEnd { get; }
|
|
|
|
public bool Within(uint pc) => pc >= CodeStart && pc < CodeEnd;
|
|
}
|