ref: bc96874813d62c86c475df2c6b311848169a30e6
author: Jacob Moody <moody@posixcafe.org>
date: Sun Feb 12 22:10:42 EST 2023
wip acs(1)
--- /dev/null
+++ b/acs.c
@@ -1,0 +1,269 @@
+#include <u.h>
+#include <libc.h>
+
+uvlong
+unpack(uchar *from, int n)
+{
+ uvlong x;
+ int i;
+
+ for(i = x = 0; i < n; i++)
+ x |= (from[i] << (i*8));
+ return x;
+}
+
+struct {
+ char *name;
+ int argc;
+} functab[] = {
+ "NOP", 0,
+ "Terminate", 0,
+ "Suspend", 0,
+ "PushNumber", 1,
+ "LSpec1", 1,
+ "LSpec2", 1,
+ "LSpec3", 1,
+ "LSpec4", 1,
+ "LSpec5", 1,
+ "LSpec1Direct", 2,
+ "LSpec2Direct", 3,
+ "LSpec3Direct", 4,
+ "LSpec4Direct", 5,
+ "LSpec5Direct", 6,
+ "Add", 0,
+ "Subtract", 0,
+ "Multiply", 0,
+ "Divide", 0,
+ "Modulus", 0,
+ "EQ", 0,
+ "NE", 0,
+ "LT", 0,
+ "GT", 0,
+ "LE", 0,
+ "GE", 0,
+ "AssignScriptVar", 1,
+ "AssignMapVar", 1,
+ "AssignWorldVar", 1,
+ "PushScriptVar", 1,
+ "PushMapVar", 1,
+ "PushWorldVar", 1,
+ "AddScriptVar", 1,
+ "AddMapVar", 1,
+ "AddWorldVar", 1,
+ "SubScriptVar", 1,
+ "SubMapVar", 1,
+ "SubWorldVar", 1,
+ "MulScriptVar", 1,
+ "MulMapVar", 1,
+ "MulWorldVar", 1,
+ "DivScriptVar", 1,
+ "DivMapVar", 1,
+ "DivWorldVar", 1,
+ "ModScriptVar", 1,
+ "ModMapVar", 1,
+ "ModWorldVar", 1,
+ "IncScriptVar", 1,
+ "IncMapVar", 1,
+ "IncWorldVar", 1,
+ "DecScriptVar", 1,
+ "DecMapVar", 1,
+ "DecWorldVar", 1,
+ "Goto", 1,
+ "IfGoto", 1,
+ "Drop", 0,
+ "Delay", 0,
+ "DelayDirect", 1,
+ "Random", 0,
+ "RandomDirect", 2,
+ "ThingCount", 0,
+ "ThingCountDirect", 2,
+ "TagWait", 0,
+ "TagWaitDirect", 1,
+ "PolyWait", 0,
+ "PolyWaitDirect", 1,
+ "ChangeFloor", 0,
+ "ChangeFloorDirect", 1,
+ "ChangeCeiling", 0,
+ "ChangeCeilingDirect", 1,
+ "Restart", 0,
+ "AndLogical", 0,
+ "OrLogical", 0,
+ "AndBitwise", 0,
+ "OrBitwise", 0,
+ "EorBitwise", 0,
+ "NegateLogical", 0,
+ "LShift", 0,
+ "RShift", 0,
+ "UnaryMinus", 0,
+ "IfNotGoto", 1,
+ "LineSide", 0,
+ "ScriptWait", 0,
+ "ScriptWaitDirect", 1,
+ "ClearLineSpecial", 0,
+ "CaseGoto", 1,
+ "BeginPrint", 0,
+ "EndPrint", 0,
+ "PrintString", 0,
+ "PrintNumber", 0,
+ "PrintCharacter", 0,
+ "PlayerCount", 0,
+ "GameType", 0,
+ "GameSkill", 0,
+ "Timer", 0,
+ "SectorSound", 0,
+ "AmbientSound", 0,
+ "SoundSequence", 0,
+ "SetLineTexture", 0,
+ "SetLineBlocking", 0,
+ "SetLineSpecial", 0,
+ "ThingSound", 0,
+ "EndPrintBold", 0,
+};
+
+typedef struct {
+ int index;
+ uchar *address;
+ int argc;
+ int state;
+ int wait;
+} Script;
+
+typedef struct {
+ int marker;
+ int off;
+ int code;
+ int count;
+ int nstring;
+ uchar *base;
+ char **strings;
+ Script scripts[];
+} Lump;
+
+Lump*
+parsescript(uchar *b, int)
+{
+ uchar *base;
+ Lump *s;
+ Script *info;
+ Lump s2;
+ int i;
+
+ s2.base = base = b;
+ s2.marker = unpack(b, 4);
+ s2.off = unpack(b + 4, 4);
+ s2.code = unpack(b + 8, 4);
+
+ b += s2.off;
+ s2.count = (int)unpack(b, 4);
+ b += 4;
+
+ s = mallocz(sizeof(Lump) * sizeof(Script)*s2.count, 1);
+ *s = s2;
+ for(i = 0; i < s->count; i++){
+ info = s->scripts + i;
+ info->index = unpack(b, 4);
+ info->address = base + unpack(b + 4, 4);
+ info->argc = unpack(b + 8, 4);
+ b += 12;
+ }
+ s->nstring = unpack(b, 4);
+ b += 4;
+ s->strings = mallocz(sizeof(char*) * s->nstring, 1);
+ for(i = 0; i < s->nstring; i++, b += 4)
+ s->strings[i] = (char*)base + unpack(b, 4);
+ return s;
+}
+
+void
+dump(Lump *s)
+{
+ int i, j, k;
+ int *ip, *ap;
+ int cmd;
+ static uchar *labels[8192];
+ int nlabel;
+ int ctx;
+
+ ctx = 0;
+ for(i = 0; i < s->count; i++){
+ ip = (int*)(s->scripts[i].address);
+ print("script %d {\n", i);
+ nlabel = 0;
+ for(;;){
+ cmd = *ip;
+ if(cmd >= nelem(functab)){
+ break;
+ }
+ print("%.2d\t\t%s(", nlabel, functab[cmd].name);
+ labels[nlabel++] = (uchar*)ip;
+ assert(nlabel != 1024);
+ ap = ip + 1;
+ for(j = 0; j < functab[cmd].argc; j++){
+ ctx = *ap;
+ if(j == functab[cmd].argc-1)
+ print("%d", *ap);
+ else
+ print("%d, ", *ap);
+ ap++;
+ ip++;
+ }
+ ip++;
+
+ if(cmd == 52){
+ for(k = 0; k < nlabel; k++)
+ if(labels[k] == s->base + ctx){
+ print(") //%d\n", k);
+ break;
+ }
+ }
+ print(")\n");
+ if(cmd == 1)
+ break;
+ }
+ print("}\n");
+ }
+}
+
+uchar file[1024*64];
+int nfile;
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s <script>\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ int fd;
+ int w;
+ Lump *s;
+
+ ARGBEGIN{
+ default:
+ usage();
+ return;
+ }ARGEND
+ if(argc)
+ fd = open(argv[0], OREAD);
+ else
+ fd = 0;
+ if(fd < 0)
+ sysfatal("open: %r");
+
+ for(nfile = 0; nfile < sizeof file;){
+ w = read(fd, file + nfile, sizeof file - nfile);
+ if(w <= 0)
+ break;
+ nfile += w;
+ }
+ if(nfile == 0)
+ return;
+ if(nfile == sizeof file)
+ fprint(2, "file truncated\n");
+
+ s = parsescript(file, nfile);
+ dump(s);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,7 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/games
+TARG=\
+ acs\
+
+</sys/src/cmd/mkmany