shithub: raven

Download patch

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