-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add first ideas for addme.script virtual machine
- Loading branch information
Showing
5 changed files
with
447 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System; | ||
using System.IO; | ||
using System.Text; | ||
using SWBF2Admin.Maps.Lua; | ||
|
||
namespace SWBF2Admin.Maps | ||
{ | ||
class AddmeReader | ||
{ | ||
private const string UCFB_HEADER = "ucfb"; | ||
|
||
private BinaryReader reader; | ||
|
||
private uint size; | ||
private string name; | ||
private string info; | ||
private uint bodySize; | ||
|
||
public AddmeReader(Stream fs) | ||
{ | ||
reader = new BinaryReader(fs); | ||
if (ReadChunkIdentifier() != UCFB_HEADER) | ||
{ | ||
throw new Exception("File header mismatch"); | ||
} | ||
size = reader.ReadUInt32(); | ||
|
||
while (NextChunk()) ; | ||
} | ||
|
||
private bool NextChunk() | ||
{ | ||
string ci = ReadChunkIdentifier(); | ||
switch (ci) | ||
{ | ||
case "scr_": | ||
uint scr_ = reader.ReadUInt32(); //todo | ||
break; | ||
case "NAME": | ||
name = ReadString(); | ||
break; | ||
case "INFO": | ||
info = ReadString(); | ||
break; | ||
case "BODY": | ||
ReadBody(); | ||
break; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private void Align() | ||
{ | ||
while (reader.BaseStream.Position % 4 != 0) | ||
{ | ||
long toPad = reader.BaseStream.Position % 4; | ||
reader.BaseStream.Seek(toPad, SeekOrigin.Current); | ||
} | ||
} | ||
|
||
private string ReadString() | ||
{ | ||
int len = (int)reader.ReadUInt32(); | ||
string r = DecodeString(reader.ReadBytes(len)); | ||
Align(); | ||
return r; | ||
} | ||
|
||
private string ReadChunkIdentifier() | ||
{ | ||
return DecodeString(reader.ReadBytes(4)); | ||
} | ||
|
||
private string DecodeString(byte[] b) | ||
{ | ||
return Encoding.ASCII.GetString(b); | ||
} | ||
|
||
private void ReadBody() | ||
{ | ||
bodySize = reader.ReadUInt32(); | ||
var l = new LuaVM(reader.BaseStream); | ||
} | ||
|
||
~AddmeReader() | ||
{ | ||
reader.Close(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SWBF2Admin.Maps.Lua | ||
{ | ||
class LuaFunction | ||
{ | ||
private List<LuaInstruction> luaAssembly = new List<LuaInstruction>(); | ||
|
||
public LuaFunction(string name, int lineDefined, byte nups, byte numParams, byte variadic, byte maxStackSz) | ||
{ | ||
Console.WriteLine("function: n:{0} l:{1} u:{2} p:{3} v:{4} s:{5}", name, lineDefined, nups, numParams, variadic, maxStackSz); | ||
} | ||
|
||
public void PushLine(int line) | ||
{ | ||
Console.WriteLine("line: l:{0}", line); | ||
} | ||
|
||
public void PushLocale(string name, int startpc, int endpc) | ||
{ | ||
Console.WriteLine("locale: n:{0} s:{1} e:{2} p:{3} v:{4} s:{5}", name, startpc, endpc); | ||
} | ||
|
||
public void PushNup(string name) | ||
{ | ||
Console.WriteLine("nup: n:{0}", name); | ||
} | ||
|
||
public void PushConst() | ||
{ | ||
Console.WriteLine("const: nil"); | ||
} | ||
|
||
public void PushConst(string str) | ||
{ | ||
Console.WriteLine("const: s:{0}", str); | ||
} | ||
|
||
public void PushConst(float f) | ||
{ | ||
Console.WriteLine("const: f:{0}", f); | ||
} | ||
|
||
public void PushNested(LuaFunction f) | ||
{ | ||
|
||
} | ||
|
||
public void PushCode(byte[] code) | ||
{ | ||
luaAssembly.Add(new LuaInstruction(code)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
using System; | ||
|
||
namespace SWBF2Admin.Maps.Lua | ||
{ | ||
enum LuaOpcode : byte | ||
{ | ||
MOVE, | ||
LOADK, | ||
LOADBOOL, | ||
LOADNIL, | ||
GETUPVAL, | ||
GETGLOBAL, | ||
GETTABLE, | ||
SETGLOBAL, | ||
SETTABLE, | ||
NEWTABLE, | ||
SELF, | ||
ADD, | ||
SUB, | ||
MUL, | ||
DIV, | ||
POW, | ||
UNM, | ||
NOT, | ||
CONCAT, | ||
JMP, | ||
EQ, | ||
LT, | ||
LE, | ||
TEST, | ||
CALL, | ||
TAILCALL, | ||
RETURN, | ||
FORLOOP, | ||
TFORLOOP, | ||
TFORPREP, | ||
SETLIST, | ||
SETLISTO, | ||
CLOSE, | ||
CLOSURE | ||
} | ||
class LuaInstruction | ||
{ | ||
public LuaOpcode OpCode { get; set; } | ||
public int A { get; set; } | ||
public int B { get; set; } | ||
public int C { get; set; } | ||
|
||
public LuaInstruction(byte[] instr) | ||
{ | ||
OpCode = (LuaOpcode)extract(instr, 0, 6); | ||
A = extract(instr, 6, 8); | ||
C = 0; | ||
|
||
switch (OpCode) | ||
{ | ||
//iABx | ||
case LuaOpcode.LOADK: | ||
case LuaOpcode.GETGLOBAL: | ||
case LuaOpcode.SETGLOBAL: | ||
case LuaOpcode.SETLIST: | ||
case LuaOpcode.SETLISTO: | ||
case LuaOpcode.CLOSURE: | ||
B = extract(instr, 14, 18); | ||
break; | ||
|
||
//iAsBx | ||
case LuaOpcode.JMP: | ||
case LuaOpcode.FORLOOP: | ||
case LuaOpcode.TFORPREP: | ||
B = EvaluateLuaSignBit(extract(instr, 14, 18)); | ||
break; | ||
|
||
//iABC | ||
default: | ||
C = EvaluateLuaSignBit(extract(instr, 14, 9)); | ||
B = EvaluateLuaSignBit(extract(instr, 23, 9)); | ||
|
||
break; | ||
} | ||
Console.WriteLine("{0}\tA:{1} B:{2} C:{3}", OpCode, A, B, C); | ||
} | ||
|
||
private static int EvaluateLuaSignBit(int i) | ||
{ | ||
if ((i & (1 << 9)) != 0) | ||
{ | ||
i ^= (1 << 9); | ||
i *= -1; | ||
} | ||
return i; | ||
} | ||
|
||
private int extract(byte[] instr, int pos, int sz) | ||
{ | ||
int res = 0; | ||
int i = pos; | ||
int ctx = 0; | ||
|
||
while (i < pos + sz) | ||
{ | ||
bool bit = (instr[i / 8] & (1 << (i % 8))) > 0; | ||
res |= ((int)(bit ? 1 : 0) << ctx); | ||
ctx++; | ||
i++; | ||
} | ||
return res; | ||
} | ||
} | ||
} |
Oops, something went wrong.