Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/cs/Executor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,79 @@ public void AddFuncDataACS0(uint code, CallFunc callFunc) {
}
}

const int FixedBits = 16;
const int FixedOne = 1 << FixedBits;
static int ToFixedPoint(double f) => (int)(f * FixedOne);
static double FromFixedPoint(int f) => ((double)f) / FixedOne;

public delegate void CallFuncV(ThreadHandle thread, uint[] args);
public void AddCodeDataACS0V(uint code, string args, uint stackArgC, CallFuncV callFunc) {
AddCodeDataACS0(code, args, stackArgC, (thread, args) => {
callFunc(thread, args);
return CallFuncResult.NextOp;
});
}
public void AddFuncDataACS0V(uint code, CallFuncV callFunc) {
AddFuncDataACS0(code, (thread, args) => {
callFunc(thread, args);
// funcs can actually never really be void, they just return 0 in ZDoom if they should be void
thread.PushStack(0u);
return CallFuncResult.NextOp;
});
}
public delegate int CallFuncI(ThreadHandle thread, uint[] args);
public void AddCodeDataACS0I(uint code, string args, uint stackArgC, CallFuncI callFunc) {
AddCodeDataACS0(code, args, stackArgC, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack((uint)ret);
return CallFuncResult.NextOp;
});
}
public void AddFuncDataACS0I(uint code, CallFuncI callFunc) {
AddFuncDataACS0(code, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack((uint)ret);
return CallFuncResult.NextOp;
});
}
public delegate bool CallFuncB(ThreadHandle thread, uint[] args);
public void AddCodeDataACS0B(uint code, string args, uint stackArgC, CallFuncB callFunc) {
AddCodeDataACS0(code, args, stackArgC, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack(ret ? 1u : 0u);
return CallFuncResult.NextOp;
});
}
public void AddFuncDataACS0B(uint code, CallFuncB callFunc) {
AddFuncDataACS0(code, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack(ret ? 1u : 0u);
return CallFuncResult.NextOp;
});
}
public delegate double CallFuncF(ThreadHandle thread, uint[] args);
public void AddCodeDataACS0F(uint code, string args, uint stackArgC, CallFuncF callFunc) {
AddCodeDataACS0(code, args, stackArgC, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack((uint)ToFixedPoint(ret));
return CallFuncResult.NextOp;
});
}
public void AddFuncDataACS0F(uint code, CallFuncF callFunc) {
AddFuncDataACS0(code, (thread, args) => {
var ret = callFunc(thread, args);
thread.PushStack((uint)ToFixedPoint(ret));
return CallFuncResult.NextOp;
});
}
public delegate string CallFuncS(ThreadHandle thread, uint[] args);
public void AddCodeDataACS0S(uint code, string args, uint stackArgC, CallFuncS callFunc) {
throw new NotImplementedException();
}
public void AddFuncDataACS0S(uint code, CallFuncS callFunc) {
throw new NotImplementedException();
}

public void LoadHubMap(uint hubId, uint mapId, string[] moduleNames) {
var moduleNamesC = Array.ConvertAll(
moduleNames,
Expand Down
30 changes: 13 additions & 17 deletions tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ namespace Tests;

class MyExecutor : HelionACS.Executor {
public MyExecutor() {
AddCodeDataACS0(57, "", 2, CF_Random);
AddCodeDataACS0(58, "WW", 0, CF_Random);
AddCodeDataACS0I(57, "", 2, CF_Random);
AddCodeDataACS0I(58, "WW", 0, CF_Random);
AddCodeDataACS0(61, "", 1, CF_TagWait);
AddCodeDataACS0(62, "W", 0, CF_TagWait);
AddCodeDataACS0(86, "", 0, CF_EndPrint);

AddCodeDataACS0(149, "", 6, CF_Spawn);
AddCodeDataACS0(150, "WSWWWWW", 0, CF_Spawn);

AddFuncDataACS0(9, CF_GetActorVelX);
AddFuncDataACS0F(9, CF_GetActorVelX);
}
public void UseBrokenSpawn() {
AddCodeDataACS0(149, "", 6, CF_SpawnBroken);
Expand Down Expand Up @@ -43,18 +43,15 @@ public override bool CheckTag(uint type, uint tag) {
public List<uint> ranLineSpecials = [];
public List<uint[]> ranLineSpecialArgs = [];

public HelionACS.CallFuncResult CF_Random(HelionACS.ThreadHandle thread, uint[] args) {
public int CF_Random(HelionACS.ThreadHandle thread, uint[] args) {
var min = (int)args[0];
var max = (int)args[1];
thread.PushStack(
(uint)((min, max) switch {
(0, 7) => 5,
(4, 15) => 8,
(-5, 12) => -2,
(_, _) => 0,
})
);
return HelionACS.CallFuncResult.NextOp;
return (min, max) switch {
(0, 7) => 5,
(4, 15) => 8,
(-5, 12) => -2,
(_, _) => 0,
};
}
public HelionACS.CallFuncResult CF_EndPrint(HelionACS.ThreadHandle thread, uint[] args) {
var threadInfo = thread.GetThreadInfo();
Expand All @@ -67,13 +64,12 @@ public HelionACS.CallFuncResult CF_TagWait(HelionACS.ThreadHandle thread, uint[]
thread.MakeTagWait(0, args[0]);
return HelionACS.CallFuncResult.ReevaluateState;
}
public HelionACS.CallFuncResult CF_GetActorVelX(HelionACS.ThreadHandle thread, uint[] args) {
public double CF_GetActorVelX(HelionACS.ThreadHandle thread, uint[] args) {
if (args[0] == 5) {
thread.PushStack((24 << 16) + (1 << 15)); // 24.5 in fixed point
return 24.5;
} else {
thread.PushStack(0);
return 0.0;
}
return HelionACS.CallFuncResult.NextOp;
}
public HelionACS.CallFuncResult CF_Spawn(HelionACS.ThreadHandle thread, uint[] args) {
Assert.Equal("something", thread.GetString(args[0]));
Expand Down
Loading