mirror of
https://github.com/kwsch/pkNX.git
synced 2026-04-25 23:36:55 -05:00
Update pawn parsing
I get some exceptions when running lgpe stuff in linqpad, but this is getting cleaner
This commit is contained in:
parent
a94d63e615
commit
86018c52aa
|
|
@ -1,4 +1,5 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
|
|
@ -63,6 +64,21 @@ public class AmxHeader
|
|||
|
||||
/// <summary> Offset to the overlay table </summary>
|
||||
public int Overlays; // 0x3C
|
||||
|
||||
public int CellSize
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Magic)
|
||||
{
|
||||
case MAGIC_16: return 16;
|
||||
case MAGIC_32: return 32;
|
||||
case MAGIC_64: return 64;
|
||||
default:
|
||||
throw new ArgumentException("Invalid Magic identifier.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* File format version
|
||||
|
|
|
|||
|
|
@ -547,223 +547,6 @@ internal static string EF(uint c, params uint[] arr)
|
|||
return $"{cmd}({parameters})";
|
||||
}
|
||||
|
||||
internal static readonly Dictionary<uint, string> Commands = new Dictionary<uint, string>
|
||||
{// { 0x00, "$00" }, // Invalid Code
|
||||
{ 0x01, "$01" },
|
||||
{ 0x02, "$02" },
|
||||
{ 0x03, "$03" },
|
||||
{ 0x04, "$04" },
|
||||
{ 0x05, "$05" },
|
||||
{ 0x06, "$06" },
|
||||
{ 0x07, "$07" },
|
||||
{ 0x08, "$08" },
|
||||
{ 0x09, "$09" },
|
||||
{ 0x0A, "$0A" },
|
||||
{ 0x0B, "$0B" },
|
||||
{ 0x0C, "$0C" },
|
||||
{ 0x0D, "$0D" },
|
||||
{ 0x0E, "$0E" },
|
||||
{ 0x0F, "$0F" },
|
||||
{ 0x10, "$10" },
|
||||
{ 0x11, "$11" },
|
||||
{ 0x12, "$12" },
|
||||
{ 0x13, "$13" },
|
||||
{ 0x14, "$14" },
|
||||
{ 0x15, "$15" },
|
||||
{ 0x16, "$16" },
|
||||
{ 0x17, "$17" },
|
||||
{ 0x18, "$18" },
|
||||
{ 0x19, "$19" },
|
||||
{ 0x1A, "$1A" },
|
||||
{ 0x1B, "$1B" },
|
||||
{ 0x1C, "$1C" },
|
||||
{ 0x1D, "$1D" },
|
||||
{ 0x1E, "$1E" },
|
||||
{ 0x1F, "$1F" },
|
||||
{ 0x20, "$20" },
|
||||
{ 0x21, "$21" },
|
||||
{ 0x22, "$22" },
|
||||
{ 0x23, "$23" },
|
||||
{ 0x24, "$24" },
|
||||
{ 0x25, "$25" },
|
||||
{ 0x26, "$26" },
|
||||
{ 0x27, "PushConst" },
|
||||
{ 0x28, "$28" },
|
||||
{ 0x29, "$29" },
|
||||
{ 0x2A, "$2A" },
|
||||
{ 0x2B, "$2B" },
|
||||
{ 0x2C, "$2C" },
|
||||
{ 0x2D, "$2D" },
|
||||
{ 0x2E, "Begin" },
|
||||
{ 0x2F, "$2F" },
|
||||
{ 0x30, "Return" },
|
||||
{ 0x31, "CallFunc" },
|
||||
{ 0x32, "$32" },
|
||||
{ 0x33, "$33" },
|
||||
{ 0x34, "$34" },
|
||||
{ 0x35, "BNE" },
|
||||
{ 0x36, "BEQ" },
|
||||
{ 0x37, "$37" },
|
||||
{ 0x38, "$38" },
|
||||
{ 0x39, "$39" },
|
||||
{ 0x3A, "$3A" },
|
||||
{ 0x3B, "$3B" },
|
||||
{ 0x3C, "$3C" },
|
||||
{ 0x3D, "$3D" },
|
||||
{ 0x3E, "$3E" },
|
||||
{ 0x3F, "$3F" },
|
||||
{ 0x40, "$40" },
|
||||
{ 0x41, "$41" },
|
||||
{ 0x42, "$42" },
|
||||
{ 0x43, "$43" },
|
||||
{ 0x44, "$44" },
|
||||
{ 0x45, "$45" },
|
||||
{ 0x46, "$46" },
|
||||
{ 0x47, "$47" },
|
||||
{ 0x48, "$48" },
|
||||
{ 0x49, "$49" },
|
||||
{ 0x4A, "$4A" },
|
||||
{ 0x4B, "$4B" },
|
||||
{ 0x4C, "$4C" },
|
||||
{ 0x4D, "$4D" },
|
||||
{ 0x4E, "Add?" },
|
||||
{ 0x4F, "$4F" },
|
||||
{ 0x50, "$50" },
|
||||
{ 0x51, "Cmp?" },
|
||||
{ 0x52, "$52" },
|
||||
{ 0x53, "$53" },
|
||||
{ 0x54, "$54" },
|
||||
{ 0x55, "$55" },
|
||||
{ 0x56, "$56" },
|
||||
{ 0x57, "$57" },
|
||||
{ 0x58, "$58" },
|
||||
{ 0x59, "ClearAll" },
|
||||
{ 0x5A, "$5A" },
|
||||
{ 0x5B, "$5B" },
|
||||
{ 0x5C, "$5C" },
|
||||
{ 0x5D, "$5D" },
|
||||
{ 0x5E, "$5E" },
|
||||
{ 0x5F, "$5F" },
|
||||
{ 0x60, "$60" },
|
||||
{ 0x61, "$61" },
|
||||
{ 0x62, "$62" },
|
||||
{ 0x63, "$63" },
|
||||
{ 0x64, "$64" },
|
||||
{ 0x65, "$65" },
|
||||
{ 0x66, "$66" },
|
||||
{ 0x67, "$67" },
|
||||
{ 0x68, "$68" },
|
||||
{ 0x69, "$69" },
|
||||
{ 0x6A, "$6A" },
|
||||
{ 0x6B, "$6B" },
|
||||
{ 0x6C, "$6C" },
|
||||
{ 0x6D, "$6D" },
|
||||
{ 0x6E, "$6E" },
|
||||
{ 0x6F, "$6F" },
|
||||
{ 0x70, "$70" },
|
||||
{ 0x71, "$71" },
|
||||
{ 0x72, "$72" },
|
||||
{ 0x73, "$73" },
|
||||
{ 0x74, "$74" },
|
||||
{ 0x75, "$75" },
|
||||
{ 0x76, "$76" },
|
||||
{ 0x77, "$77" },
|
||||
{ 0x78, "$78" },
|
||||
{ 0x79, "$79" },
|
||||
{ 0x7A, "$7A" },
|
||||
{ 0x7B, "$7B" },
|
||||
// { 0x7C, "$7C" }, // Invalid Code
|
||||
// { 0x7D, "$7D" }, // Invalid Code
|
||||
// { 0x7E, "$7E" }, // Invalid Code
|
||||
// { 0x7F, "$7F" }, // Invalid Code
|
||||
// { 0x80, "$80" }, // Invalid Code
|
||||
{ 0x81, "JMP" },
|
||||
{ 0x82, "switch" },
|
||||
{ 0x83, "$83" },
|
||||
{ 0x84, "$84" },
|
||||
{ 0x85, "$85" },
|
||||
{ 0x86, "$86" },
|
||||
{ 0x87, "DoCommand?" },
|
||||
// { 0x88, "$88" }, // Invalid Code
|
||||
{ 0x89, "LineNo?" },
|
||||
{ 0x8A, "$8A" },
|
||||
{ 0x8B, "$8B" },
|
||||
{ 0x8C, "$8C" },
|
||||
{ 0x8D, "$8D" },
|
||||
{ 0x8E, "$8E" },
|
||||
{ 0x8F, "$8F" },
|
||||
{ 0x90, "$90" },
|
||||
{ 0x91, "$91" },
|
||||
{ 0x92, "$92" },
|
||||
{ 0x93, "$93" },
|
||||
{ 0x94, "$94" },
|
||||
{ 0x95, "$95" },
|
||||
{ 0x96, "$96" },
|
||||
{ 0x97, "$97" },
|
||||
{ 0x98, "$98" },
|
||||
{ 0x99, "$99" },
|
||||
{ 0x9A, "$9A" },
|
||||
{ 0x9B, "Copy" },
|
||||
{ 0x9C, "$9C" },
|
||||
{ 0x9D, "$9D" },
|
||||
{ 0x9E, "$9E" },
|
||||
{ 0x9F, "$9F" },
|
||||
{ 0xA0, "$A0" },
|
||||
{ 0xA1, "$A1" },
|
||||
{ 0xA2, "GetGlobal2" },
|
||||
{ 0xA3, "GetGlobal" },
|
||||
{ 0xA4, "GetGlobal4" },
|
||||
{ 0xA5, "$A5" },
|
||||
{ 0xA6, "$A6" },
|
||||
{ 0xA7, "$A7" },
|
||||
{ 0xA8, "$A8" },
|
||||
{ 0xA9, "$A9" },
|
||||
{ 0xAA, "$AA" },
|
||||
{ 0xAB, "PushConst2" },
|
||||
{ 0xAC, "CmpConst2" },
|
||||
{ 0xAD, "$AD" },
|
||||
{ 0xAE, "$AE" },
|
||||
{ 0xAF, "SetGlobal" },
|
||||
{ 0xB0, "$B0" },
|
||||
{ 0xB1, "SetLocal" },
|
||||
{ 0xB2, "$B2" },
|
||||
{ 0xB3, "$B3" },
|
||||
{ 0xB4, "$B4" },
|
||||
{ 0xB5, "$B5" },
|
||||
{ 0xB6, "$B6" },
|
||||
{ 0xB7, "$B7" },
|
||||
{ 0xB8, "$B8" },
|
||||
{ 0xB9, "$B9" },
|
||||
{ 0xBA, "$BA" },
|
||||
{ 0xBB, "$BB" },
|
||||
{ 0xBC, "PushConst" },
|
||||
{ 0xBD, "GetGlobal3" },
|
||||
{ 0xBE, "GetArg" },
|
||||
{ 0xBF, "AdjustStack" },
|
||||
{ 0xC0, "$C0" },
|
||||
{ 0xC1, "$C1" },
|
||||
{ 0xC2, "$C2" },
|
||||
{ 0xC3, "$C3" },
|
||||
{ 0xC4, "$C4" },
|
||||
{ 0xC5, "$C5" },
|
||||
{ 0xC6, "$C6" },
|
||||
{ 0xC7, "$C7" },
|
||||
{ 0xC8, "CmpLocal" },
|
||||
{ 0xC9, "CmpConst" },
|
||||
{ 0xCA, "$CA" },
|
||||
{ 0xCB, "$CB" },
|
||||
{ 0xCC, "$CC" },
|
||||
{ 0xCD, "$CD" },
|
||||
{ 0xCE, "$CE" },
|
||||
{ 0xCF, "$CF" },
|
||||
{ 0xD0, "$D0" },
|
||||
|
||||
{ 0xD1, "$D1" },
|
||||
{ 0xD2, "$D2" },
|
||||
{ 0xD3, "$D3" },
|
||||
{ 0xD4, "$D4" },
|
||||
{ 0xD5, "Mode1" },
|
||||
{ 0xD6, "Mode2" },
|
||||
};
|
||||
private static readonly string[] Commands = Enum.GetNames(typeof(AmxOpCode));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace pkNX.Structures
|
||||
|
|
@ -9,56 +10,49 @@ namespace pkNX.Structures
|
|||
/// <remarks>https://github.com/compuphase/pawn</remarks>
|
||||
public class Script
|
||||
{
|
||||
public AmxHeader Header;
|
||||
public int Length => Header.Size;
|
||||
public uint Magic => Header.Magic;
|
||||
// case 0x0A0AF1E0: code = read_code_block(f); break;
|
||||
// case 0x0A0AF1EF: debug = read_debug_block(f); break;
|
||||
public bool Debug => Header.Flags.HasFlagFast(AmxFlags.DEBUG);
|
||||
public readonly byte[] Data;
|
||||
public readonly AmxHeader Header;
|
||||
public readonly int CellSize;
|
||||
|
||||
public ushort PtrOffset => BitConverter.ToUInt16(Raw, 0x08);
|
||||
public ushort PtrCount => BitConverter.ToUInt16(Raw, 0x0A);
|
||||
|
||||
public int ScriptInstructionStart => BitConverter.ToInt32(Raw, 0x0C);
|
||||
public int ScriptMovementStart => BitConverter.ToInt32(Raw, 0x10);
|
||||
public int FinalOffset => BitConverter.ToInt32(Raw, 0x14);
|
||||
public int AllocatedMemory => BitConverter.ToInt32(Raw, 0x18);
|
||||
|
||||
// Generated Attributes
|
||||
public int CompressedLength => Length - ScriptInstructionStart;
|
||||
public byte[] CompressedBytes => Raw.Skip(ScriptInstructionStart).ToArray();
|
||||
public int DecompressedLength => FinalOffset - ScriptInstructionStart;
|
||||
public uint[] DecompressedInstructions => PawnUtil.QuickDecompress(CompressedBytes, DecompressedLength / 4);
|
||||
|
||||
public uint[] ScriptCommands => DecompressedInstructions.Take((ScriptMovementStart - ScriptInstructionStart) / 4).ToArray();
|
||||
public uint[] MoveCommands => DecompressedInstructions.Skip((ScriptMovementStart - ScriptInstructionStart) / 4).ToArray();
|
||||
public string[] ParseScript => PawnUtil.ParseScript(ScriptCommands);
|
||||
public string[] ParseMoves => PawnUtil.ParseMovement(MoveCommands);
|
||||
|
||||
public string Info => "Data Start: 0x" + ScriptInstructionStart.ToString("X4")
|
||||
+ Environment.NewLine + "Movement Offset: 0x" + ScriptMovementStart.ToString("X4")
|
||||
+ Environment.NewLine + "Total Used Size: 0x" + FinalOffset.ToString("X4")
|
||||
+ Environment.NewLine + "Reserved Size: 0x" + AllocatedMemory.ToString("X4")
|
||||
+ Environment.NewLine + "Compressed Len: 0x" + CompressedLength.ToString("X4")
|
||||
+ Environment.NewLine + "Decompressed Len: 0x" + DecompressedLength.ToString("X4")
|
||||
+ Environment.NewLine + "Compression Ratio: " +
|
||||
((DecompressedLength - CompressedLength) / (decimal)DecompressedLength).ToString("p1");
|
||||
|
||||
public byte[] Raw;
|
||||
|
||||
public Script(byte[] data = null)
|
||||
public Script(byte[] data)
|
||||
{
|
||||
Raw = data ?? Array.Empty<byte>();
|
||||
Data = data;
|
||||
Header = data.ToClass<AmxHeader>();
|
||||
CellSize = Header.CellSize;
|
||||
|
||||
// sub_51AAFC
|
||||
if (Header.Flags.HasFlagFast(AmxFlags.OVERLAY))
|
||||
throw new ArgumentException("Multi-environment script!?");
|
||||
}
|
||||
|
||||
public byte[] Write()
|
||||
public byte[] Write() => Data;
|
||||
public bool Debug => Header.Flags.HasFlagFast(AmxFlags.DEBUG);
|
||||
|
||||
// Generated Attributes
|
||||
public int CodeLength => Header.Data - Header.COD;
|
||||
public int CompressedLength => Header.Size - Header.COD;
|
||||
public byte[] CompressedBytes => Data.Skip(Header.COD).ToArray();
|
||||
public int DecompressedLength => Header.Heap - Header.COD;
|
||||
public uint[] DecompressedInstructions => PawnUtil.QuickDecompress(CompressedBytes, DecompressedLength / sizeof(uint));
|
||||
|
||||
public uint[] ScriptCommands => DecompressedInstructions.Take(CodeLength / sizeof(uint)).ToArray(); // Code
|
||||
public uint[] DataPayload => DecompressedInstructions.Skip(CodeLength / sizeof(uint)).ToArray(); // Data
|
||||
public string[] ParseScript => PawnUtil.ParseScript(ScriptCommands);
|
||||
public string[] DataChunk => PawnUtil.ParseMovement(DataPayload);
|
||||
|
||||
public string Info => string.Join(Environment.NewLine, SummaryLines);
|
||||
|
||||
public IEnumerable<string> SummaryLines
|
||||
{
|
||||
return Raw;
|
||||
get
|
||||
{
|
||||
yield return $"Code Start: 0x{Header.COD:X4}";
|
||||
yield return $"Data Start: 0x{Header.Data:X4}";
|
||||
yield return $"Total Used Size: 0x{Header.Heap:X4}";
|
||||
yield return $"Reserved Size: 0x{Header.StackTop:X4}";
|
||||
yield return $"Compressed Len: 0x{CompressedLength:X4}";
|
||||
yield return $"Decompressed Len: 0x{DecompressedLength:X4}";
|
||||
yield return $"Compression Ratio: {(DecompressedLength - CompressedLength) / (decimal) DecompressedLength:p1}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user