From 70f2d0338ab22fb9b687aa78d16d0a9a8e1e2aa1 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Tue, 2 Jan 2024 19:43:12 -0500 Subject: [PATCH] Clean commit of historical griddle / fred source --- mamelink/griddle/.dbxinit | 7 + mamelink/griddle/DOC | 23 + mamelink/griddle/Makefile | 84 +++ mamelink/griddle/alloc.c | 50 ++ mamelink/griddle/build.c | 199 ++++++ mamelink/griddle/cv.c | 346 +++++++++++ mamelink/griddle/debug.c | 170 ++++++ mamelink/griddle/exec.c | 771 ++++++++++++++++++++++++ mamelink/griddle/expr.c | 252 ++++++++ mamelink/griddle/fred.c | 900 ++++++++++++++++++++++++++++ mamelink/griddle/fred2.c | 602 +++++++++++++++++++ mamelink/griddle/fscreen.c | 350 +++++++++++ mamelink/griddle/griddle.c | 535 +++++++++++++++++ mamelink/griddle/griddle.y | 245 ++++++++ mamelink/griddle/griddleDefs.h | 298 +++++++++ mamelink/griddle/indir.c | 344 +++++++++++ mamelink/griddle/lexer.c | 594 ++++++++++++++++++ mamelink/griddle/main.c | 355 +++++++++++ mamelink/griddle/prot.h | 41 ++ mamelink/griddle/reno.out | Bin 0 -> 32028 bytes mamelink/griddle/util/dumpfstats.c | 69 +++ mamelink/griddle/util/flushfstats.c | 14 + mamelink/griddle/util/shorten.c | 19 + mamelink/griddle/util/trunc.c | 19 + 24 files changed, 6287 insertions(+) create mode 100644 mamelink/griddle/.dbxinit create mode 100644 mamelink/griddle/DOC create mode 100644 mamelink/griddle/Makefile create mode 100644 mamelink/griddle/alloc.c create mode 100644 mamelink/griddle/build.c create mode 100644 mamelink/griddle/cv.c create mode 100644 mamelink/griddle/debug.c create mode 100644 mamelink/griddle/exec.c create mode 100644 mamelink/griddle/expr.c create mode 100644 mamelink/griddle/fred.c create mode 100644 mamelink/griddle/fred2.c create mode 100644 mamelink/griddle/fscreen.c create mode 100644 mamelink/griddle/griddle.c create mode 100644 mamelink/griddle/griddle.y create mode 100644 mamelink/griddle/griddleDefs.h create mode 100644 mamelink/griddle/indir.c create mode 100644 mamelink/griddle/lexer.c create mode 100644 mamelink/griddle/main.c create mode 100644 mamelink/griddle/prot.h create mode 100644 mamelink/griddle/reno.out create mode 100644 mamelink/griddle/util/dumpfstats.c create mode 100644 mamelink/griddle/util/flushfstats.c create mode 100644 mamelink/griddle/util/shorten.c create mode 100644 mamelink/griddle/util/trunc.c diff --git a/mamelink/griddle/.dbxinit b/mamelink/griddle/.dbxinit new file mode 100644 index 0000000..dd15dbc --- /dev/null +++ b/mamelink/griddle/.dbxinit @@ -0,0 +1,7 @@ +alias r run -i test.i -g test.gri +alias c cont +alias n next +alias s step +alias p print +alias l list +alias q quit diff --git a/mamelink/griddle/DOC b/mamelink/griddle/DOC new file mode 100644 index 0000000..ade7f8c --- /dev/null +++ b/mamelink/griddle/DOC @@ -0,0 +1,23 @@ +/u0/chip/habitat/griddle: + This directory contains the Griddle and Fred utilities. They share +most of their source, since they are mostly the same program, so they are both +together here. Fred uses Fastlink, so some stuff for it is elsewhere. + +These are the files here: +DOC - This file +regiontools.t - Documentation for Fred and Griddle + +Makefile - Makefile to compile everything +*.c, *.y, *.h - Source files + +fred - Executable for Fred +griddle - Executable for Griddle + +reno.out - Binary for C64 half of Fred (gets uploaded through Fastlink) + +util - A directory containing some minor utilities that work with + Fred. Fred keeps a stat file of what commands are used so + We can collect frequency info for improving the command + interface. These utilities deal with this stat file. The + utilities are all short and their source is their + documentation. diff --git a/mamelink/griddle/Makefile b/mamelink/griddle/Makefile new file mode 100644 index 0000000..9265159 --- /dev/null +++ b/mamelink/griddle/Makefile @@ -0,0 +1,84 @@ +.SUFFIXES: .o .c .h .run .y .l + +GOBJ = griddle.o gmain.o glexer.o build.o cv.o gexpr.o gexec.o debug.o indir.o +FOBJ = griddle.o fmain.o flexer.o build.o cv.o fexpr.o fexec.o debug.o fred.o fred2.o fscreen.o sun.o map.o + +.c.o: + cc -c -g -DYYDEBUG $*.c + +.y.c: + yacc -vd $*.y + mv y.tab.c $*.c + +.l.c: + lex $*.l + mv lex.yy.c $*.c + +.c.run: + cc -o $* $*.c + +griddle: $(GOBJ) + cc -g $(GOBJ) -o griddle + +fred: $(FOBJ) + cc -g $(FOBJ) -o fred -lcurses -ltermlib + +all: griddle fred + +dumpfstats: dumpfstats.c + cc -g dumpfstats.c -o dumpfstats + +flushfstats: flushfstats.c + cc -g flushfstats.c -o flushfstats + +griddle.o: griddle.c griddleDefs.h +#griddle.c: griddle.y + +alloc.o: alloc.c + +build.o: build.c griddleDefs.h + +gmain.o: main.c griddleDefs.h + cc -c -g -DYYDEBUG main.c + mv main.o gmain.o + +fmain.o: main.c griddleDefs.h + cc -c -g -DYYDEBUG -DFRED main.c + mv main.o fmain.o + +gexec.o: exec.c griddleDefs.h + cc -c -g -DYYDEBUG exec.c + mv exec.o gexec.o + +fexec.o: exec.c griddleDefs.h + cc -c -g -DYYDEBUG -DFRED exec.c + mv exec.o fexec.o + +debug.o: debug.c griddleDefs.h + +cv.o: cv.c griddleDefs.h + +glexer.o: lexer.c griddleDefs.h y.tab.h + cc -c -g -DYYDEBUG lexer.c + mv lexer.o glexer.o + +flexer.o: lexer.c griddleDefs.h y.tab.h + cc -c -g -DYYDEBUG -DFRED lexer.c + mv lexer.o flexer.o + +gexpr.o: expr.c griddleDefs.h y.tab.h + cc -c -g -DYYDEBUG expr.c + mv expr.o gexpr.o + +fexpr.o: expr.c griddleDefs.h y.tab.h + cc -c -g -DYYDEBUG -DFRED expr.c + mv expr.o fexpr.o + +indir.o: indir.c griddleDefs.h + +fred.o: fred.c griddleDefs.h prot.h + cc -c -g -DDATE=\""`date`\"" fred.c + +fred2.o: fred2.c griddleDefs.h + +fscreen.o: fscreen.c griddleDefs.h diff --git a/mamelink/griddle/alloc.c b/mamelink/griddle/alloc.c new file mode 100644 index 0000000..63236ea --- /dev/null +++ b/mamelink/griddle/alloc.c @@ -0,0 +1,50 @@ +#include + +typedef struct { + int tag; +} alloc; + +#define MAXTAG 40; +static int allocCount[MAXTAG] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static int freeCount[MAXTAG] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static int highTag = 0; + + char * +mymalloc(size, tag) + int size; + int tag; +{ + alloc *result; + + result = (alloc *) malloc(size + sizeof(alloc)); + if (tag > highTag) + highTag = tag; + allocCount[tag]++; + result->tag = tag; + ++result; + return((char *) result); +} + + void +myfree(ptr) + alloc *ptr; +{ + --ptr; + freeCount[ptr->tag]--; + free(ptr); +} + + void +dumpAllocOrphans() +{ + int i; + + for (i=0; i<=highTag; ++i) + printf("%d %d/%d\n", i, allocCount[i], freeCount[i]); +} diff --git a/mamelink/griddle/build.c b/mamelink/griddle/build.c new file mode 100644 index 0000000..176640d --- /dev/null +++ b/mamelink/griddle/build.c @@ -0,0 +1,199 @@ +#include "griddleDefs.h" + +value *evaluate(); + + genericListHead * +buildGenericList(list, new) + genericListHead *list; + int *new; +{ + genericListHead *result; + genericList *newList; + + if (list == NULL) { + result = typeAlloc(genericListHead); + result->thing = new; + result->next = NULL; + result->last = (genericList *)result; + } else { + newList = typeAlloc(genericList); + newList->thing = new; + newList->next = NULL; + list->last->next = newList; + list->last = newList; + result = list; + } + return(result); +} + + fieldList * +buildFieldList(list, new) + fieldList *list; + field *new; +{ + return((fieldList *)buildGenericList(list, new)); +} + + valueList * +buildValueList(list, new) + valueList *list; + value *new; +{ + return((valueList *)buildGenericList(list, new)); +} + + objectList * +buildObjectList(list, new) + objectList *list; + object *new; +{ + return((objectList *)buildGenericList(list, new)); +} + + exprList * +buildExprList(list, new) + exprList *list; + expression *new; +{ + return((exprList *)buildGenericList(list, new)); +} + + propertyList * +buildPropertyList(list, new) + propertyList *list; + property *new; +{ + return((propertyList *)buildGenericList(list, new)); +} + + stringList * +buildStringList(list, new) + stringList *list; + char *new; +{ + return((stringList *)buildGenericList(list, new)); +} + + expression * +buildExpr(type, arg1, arg2, arg3) + exprType type; + int arg1; + int arg2; + int arg3; +{ + expression *result; + + result = typeAlloc(expression); + result->type = type; + result->part1 = arg1; + result->part2 = arg2; + result->part3 = arg3; + return(result); +} + + property * +buildProperty(fieldName, data) + symbol *fieldName; + exprList *data; +{ + property *result; + + result = typeAlloc(property); + result->fieldName = fieldName; + result->data = data; + return(result); +} + + value * +buildValue(vtype, val) + valueType vtype; + int val; +{ + value *result; + + result = typeAlloc(value); + result->value = val; + result->dataType = vtype; + return(result); +} + + value * +buildNumber(val) + int val; +{ + return(buildValue(VAL_INTEGER, val)); +} + + value * +buildString(val) + char *val; +{ + return(buildValue(VAL_STRING, (int)val)); +} + + value * +buildBitString(val) + byte *val; +{ + return(buildValue(VAL_BITSTRING, (int)val)); +} + + field * +buildField(name, dimension, type, initList) + symbol *name; + expression *dimension; + fieldType type; + exprList *initList; +{ + field *result; + value *val; + + result = typeAlloc(field); + result->name = name; + result->type = type; + result->offset = 0; + result->invisible = FALSE; + val = evaluate(dimension); + if (isInteger(val) && val->value > 0) + result->dimension = val->value; + else { + error("illegal data type for field dimension\n"); + result->dimension = 1; + } + freeValue(val); + result->initValues = initList; + return(result); +} + + field * +invisifyField(aField) + field *aField; +{ + aField->invisible = TRUE; + return(aField); +} + + objectTail * +buildObjectTail(idExpr, propList) + expression *idExpr; + propertyList *propList; +{ + objectTail *result; + + result = typeAlloc(objectTail); + result->idExpr = idExpr; + result->properties = propList; + return(result); +} + + objectStub * +buildObjectStub(obj) + object *obj; +{ + objectStub *result; + + result = typeAlloc(objectStub); + result->class = obj->class; + result->id = getLong(obj->stateVector, 0); + return(result); +} diff --git a/mamelink/griddle/cv.c b/mamelink/griddle/cv.c new file mode 100644 index 0000000..1288dbe --- /dev/null +++ b/mamelink/griddle/cv.c @@ -0,0 +1,346 @@ +#include "griddleDefs.h" + +#define CLASS_MAX 256 +#define SIZE_OFFSET 12 +int classSize[CLASS_MAX]; + +byte cv[512]; +int cvLength; + +static FILE *cvFyle; +static object *inNoid[MAXNOID]; + + void +cvByte(n) + byte n; +{ + cv[cvLength++] = n; +} + + byte +readByte(fyle) + FILE *fyle; +{ + return((byte)getc(fyle)); +} + + word +readWord(fyle) + FILE *fyle; +{ + byte lo; + byte hi; + + lo = readByte(fyle); + hi = readByte(fyle); + return((hi << 8) + lo); +} + + void +readClassFile() +{ + int i; + FILE *classFyle; + + + if ((classFyle = fopen(classFileName, "r")) == NULL) + systemError("can't open class file '%s'\n", classFileName); + for (i=0; iclass); + } + } +} + + void +cvProperties(class, buf) + int class; + byte *buf; +{ + int container; + int i; + + if (class == 0) { + cvByte(0); /* style */ + cvByte(getWord(buf, LIGHTLEVEL_OFFSET_REG)); + cvByte(getWord(buf, DEPTH_OFFSET_REG)); + cvByte(getWord(buf, CLASSGROUP_OFFSET_REG)); + cvByte(0); /* who am I? */ + cvByte(0); /* bank balance */ + cvByte(0); + cvByte(0); + cvByte(0); + } else if (class == 1) { + container = getLong(buf, CONTAINER_OFFSET_AVA); + if (container != 0 && (container < -1000-MAXNOID || + -1000 <= container)) { + error("specified avatar container out of range\n"); + return; + } + cvByte(getByte(buf, STYLE_OFFSET_AVA)); + cvByte(getWord(buf, X_OFFSET_AVA)); + cvByte(getWord(buf, Y_OFFSET_AVA)); + cvByte(getWord(buf, ORIENT_OFFSET_AVA)); + cvByte(getWord(buf, GRSTATE_OFFSET_AVA)); + if (container == 0) + cvByte(0); + else + cvByte(-container-1001); + for (i=0; iclass, noidArray[i]->stateVector); +} + + boolean +generateContentsVector() +{ + int i; + + cvLength = 0; + if (noidArray[0] == NULL || noidArray[0]->class != 0) { + error("first object is not a region\n"); + return(FALSE); + } else for (i=1; iclass == 0) { + error("more than one region given\n"); + return(FALSE); + } + } +/* cvProperties(0, noidArray[0]->stateVector);*/ + cvNoidClass(); + cvByte(0); + cvProps(); + cvByte(0); + return(TRUE); +} + + void +outputContentsVector() +{ + if (generateContentsVector()) + fwrite(cv, 1, cvLength, cvFile); +} + + void +fillFromCvFile(obj) + object *obj; +{ + byte *buf; + int class; + int container; + int i; + + buf = obj->stateVector; + class = obj->class; + if (class == 0) { + readByte(cvFyle); /* skip style */ + fillWord(buf, LIGHTLEVEL_OFFSET_REG, readByte(cvFyle)); + fillWord(buf, DEPTH_OFFSET_REG, readByte(cvFyle)); + fillWord(buf, CLASSGROUP_OFFSET_REG, readByte(cvFyle)); + readByte(cvFyle); /* skip who am i */ + for (i=0; i<4; ++i) + readByte(cvFyle); /* skip bank balance */ + } else if (class == 1) { + fillByte(buf, STYLE_OFFSET_AVA, readByte(cvFyle)); + fillWord(buf, X_OFFSET_AVA, readByte(cvFyle)); + fillWord(buf, Y_OFFSET_AVA, readByte(cvFyle)); + fillWord(buf, ORIENT_OFFSET_AVA, readByte(cvFyle)); + fillWord(buf, GRSTATE_OFFSET_AVA, readByte(cvFyle)); + container = getLong(inNoid[readByte(cvFyle)]->stateVector, 0); + fillLong(buf, CONTAINER_OFFSET_AVA, container); + for (i=0; istateVector, 0); + fillLong(buf, CONTAINER_OFFSET_OBJ, container); + for (i=0; iclass) { + error("class mismatch: cv says %d, we say %d\n", + cv[noidOffset + 1], noidArray[noid]->class); + return(0); + } + stateOffset += deCvProperties(noidArray[noid]->class, + noidArray[noid]->stateVector, stateOffset); + noidOffset += 2; + noidAlive[noid] = TRUE; + } + if (cv[stateOffset] == 0) + return(0); + else + return(stateOffset + 1); +} + + void +degenerateContentsVector() +{ + int offset; + int noid; + + noidAlive[0] = TRUE; + for (noid=1; noidinvisible) { + *str = '\0'; + return(FALSE); + } + sprintf(str, "%s: ", aField->name->name); + offset = aField->offset & 0x3FFF; + bitOffset = aField->offset >> 14; + for (i=0; idimension; ++i) { + switch (aField->type) { + Case FIELD_ENTITY: + sprintf(temp, "%c %d", + contCode(getWord(buf, offset + 6*i + 4)), + getLong(buf, offset + 6*i)); + + Case FIELD_BIN31: + val = getLong(buf, offset + 4*i); + sprintf(temp, "%d", val); + + Case FIELD_AVAID: + val = getLong(buf, offset + 4*i); + sprintf(temp, "a %d", val); + + Case FIELD_OBJID: + val = getLong(buf, offset + 4*i); + sprintf(temp, "o %d", val); + + Case FIELD_REGID: + val = getLong(buf, offset + 4*i); + sprintf(temp, "r %d", val); + + Case FIELD_FATWORD: + val = getWord(buf, offset + 4*i) + + getWord(buf, offset + 4*i + 2) * 256; + sprintf(temp, "%d", val); + + Case FIELD_BIN15: + val = getWord(buf, offset + 2*i); + sprintf(temp, "%d", val); + + Case FIELD_WORDS: + val = getWord(buf, offset + 2*i); + sprintf(temp, "%s%s%s", + (i == 0) ? "\"" : "", + escape(val), + (i == aField->dimension-1) ? "\"" : "" + ); + + Case FIELD_BYTE: + val = getByte(buf, offset); + sprintf(temp, "%d", val); + + Case FIELD_VARSTRING: + val = getWord(buf, offset); + strcpy(temp, "\""); + strncat(temp, buf + offset + 2, val); + strcat(temp, "\""); + i = aField->dimension - 1; + + Case FIELD_CHARACTER: + val = getByte(buf, offset + i); + sprintf(temp, "%s%s%s", + (i == 0) ? "\"" : "", + escape(val), + (i == aField->dimension-1) ? "\"" : "" + ); + + Case FIELD_BIT: + val = getByte(buf, offset + ((i+bitOffset)>>3)); + val &= 1 << (7 - ((i+bitOffset)&7)); + sprintf(temp, "%s%c%s", + (i == 0) ? "'" : "" , + (val) ? '1' : '0', + (i == aField->dimension-1) ? "'b" : "" + ); + } + strcat(str, temp); + if (aField->type != FIELD_WORDS && aField->type != + FIELD_BIT && aField->type != FIELD_CHARACTER && + i != aField->dimension-1) + strcat(str, ", "); + } + return(TRUE); +} + + void +dumpObject(obj) + object *obj; +{ + fieldList *fields; + + if (obj == NULL) + return; + fprintf(griFile, "use %s {\n", classDefs[obj->class+1]->className-> + name); + if (obj->class > 1) { + fields = classDefs[0]->fields; + while (fields != NULL) { + dumpField(fields->field, obj->stateVector); + fields = fields->nextField; + } + } + fields = classDefs[obj->class+1]->fields; + while (fields != NULL) { + dumpField(fields->field, obj->stateVector); + fields = fields->nextField; + } + fprintf(griFile, "}\n"); +} diff --git a/mamelink/griddle/exec.c b/mamelink/griddle/exec.c new file mode 100644 index 0000000..c10f9f0 --- /dev/null +++ b/mamelink/griddle/exec.c @@ -0,0 +1,771 @@ +#include "griddleDefs.h" + + void +executeInclude(filename) + char *filename; +{ + fileList *newFile; + + if (announceIncludes) { + fprintf(stderr, "->%s\n", filename); + fflush(stderr); + } + newFile = typeAlloc(fileList); + newFile->next = inputStack; + newFile->saveName = currentFileName; + newFile->saveLine = currentLineNumber; + newFile->fyle = currentInput; + inputStack = newFile; + if ((currentInput = fopen(filename, "r")) == NULL) { + error("unable to open include file '%s'\n", filename); + exit(1); + } + currentFileName = filename; + currentLineNumber = 1; + free(filename); +} + + void +executeAssignment(name, expr) + symbol *name; + expression *expr; +{ + value *evaluate(); + + if (name->type != NON_SYM && name->type != VARIABLE_SYM) { + error("illegal assignment to '%s'\n", name->name); + } else { + if (name->type == VARIABLE_SYM) + freeValue(name->def.value); + name->type = VARIABLE_SYM; + name->def.value = evaluate(expr); + } +} + + void +fillByte(buf, offset, value) + byte *buf; + int offset; + int value; +{ + buf[offset] = value & 0xFF; +} + + void +fillWord(buf, offset, value) + byte *buf; + int offset; + int value; +{ + buf[offset ] = (value >> 8) & 0xFF; + buf[offset + 1] = value & 0xFF; +} + + void +fillLong(buf, offset, value) + byte *buf; + int offset; + long value; +{ + buf[offset ] = (value >> 24) & 0xFF; + buf[offset + 1] = (value >> 16) & 0xFF; + buf[offset + 2] = (value >> 8) & 0xFF; + buf[offset + 3] = value & 0xFF; +} + + value * +nextValue(dataptr) + exprList **dataptr; +{ + exprList *data; + value *val; + value *buildNumber(); + + if (dataptr == NULL || *dataptr == NULL) + return(buildNumber(0)); + data = *dataptr; + val = evaluate(data->expr); + *dataptr = data->nextExpr; + return(val); +} + + value * +nextIntValue(dataptr) + exprList **dataptr; +{ + value *val; + + val = nextValue(dataptr); + if (!isInteger(val)) + val = buildNumber(0); + return(val); +} + + char * +nextStringValue(dataptr) + exprList **dataptr; +{ + value *val; + char *result; + + if (dataptr == NULL || *dataptr == NULL) + return(NULL); + val = nextValue(dataptr); + if (isString(val)) + result = (char *)(val->value); + else + result = NULL; + freeValue(val); + return(result); +} + + int +contNum(vtype) + valueType vtype; +{ + if (vtype == VAL_AVATAR) return (1); + else if (vtype == VAL_OBJECT) return (2); + else return (0); +} + + void +adjustValue(val) + value *val; +{ + if (indirFile != NULL && val->value < -1000) + val->value -= globalIdAdjustment; +} + + void +fillField(buf, data, aField, nextInt, nextString, nextBit) + byte *buf; + exprList *data; + field *aField; + value *(*nextInt)(); + char *(*nextString)(); + value *(*nextBit)(); +{ + int i, j; + int offset, bitOffset; + int len; + value *val; + char *string; + byte *bitString; + int bitLength; + int bufIndex; + byte theBit; + + offset = aField->offset & 0x3FFF; + if (indirFile != NULL && offset == IDENT_OFFSET) + return; + bitOffset = aField->offset >> 14; + + for (i=0; idimension; ++i) { + switch (aField->type) { + Case FIELD_ENTITY: + val = (*nextInt)(&data); + adjustValue(val); + fillLong(buf, offset + 6*i, val->value); + fillWord(buf, offset + 6*i + 4, contNum(val->dataType)); + freeValue(val); + + Case FIELD_AVAID: + val = (*nextInt)(&data); + if (val->dataType != VAL_AVATAR && val->dataType != + VAL_INTEGER) + error("illegal avatar id value\n"); + adjustValue(val); + fillLong(buf, offset + 4*i, val->value); + freeValue(val); + + Case FIELD_OBJID: + val = (*nextInt)(&data); + if (val->dataType != VAL_OBJECT && val->dataType != + VAL_INTEGER) + error("illegal object id value\n"); + adjustValue(val); + fillLong(buf, offset + 4*i, val->value); + freeValue(val); + + Case FIELD_REGID: + val = (*nextInt)(&data); + if (val->dataType != VAL_REGION && val->dataType != + VAL_INTEGER) + error("illegal region id value\n"); + adjustValue(val); + fillLong(buf, offset + 4*i, val->value); + freeValue(val); + + Case FIELD_BIN31: + val = (*nextInt)(&data); + fillLong(buf, offset + 4*i, val->value); + freeValue(val); + + Case FIELD_FATWORD: + val = (*nextInt)(&data); + fillWord(buf, offset + 4*i, val->value & 0xFF); + fillWord(buf, offset + 4*i + 2, (val->value >> 8) & + 0xFF); + freeValue(val); + + Case FIELD_BIN15: + val = (*nextInt)(&data); + fillWord(buf, offset + 2*i, val->value); + freeValue(val); + + Case FIELD_WORDS: + string = (*nextString)(&data); + if (string != NULL) + for (; idimension && string != NULL + && string[i] != '\0'; ++i) + fillWord(buf, offset + i*2, string[i]); + for (; idimension; ++i) + fillWord(buf, offset + i*2, ' '); + free(string); + + Case FIELD_BYTE: + val = (*nextInt)(&data); + fillByte(buf, offset + i, val->value); + freeValue(val); + + Case FIELD_CHARACTER: + string = (*nextString)(&data); + if (string != NULL) + for (; idimension && string != NULL + && string[i] != '\0'; ++i) + fillByte(buf, offset + i, string[i]); + for (; idimension; ++i) + fillByte(buf, offset + i, ' '); + freeValue(string); + + Case FIELD_VARSTRING: + string = (*nextString)(&data); + if (string != NULL) { + len = strlen(string); + fillWord(buf, offset, len); + for (; idimension && string != NULL + && string[i] != '\0'; ++i) + fillByte(buf, offset+2+i, string[i]); + free(string); + } else + fillWord(buf, offset, 0); + i = aField->dimension; + + Case FIELD_BIT: + val = (*nextBit)(&data); + if (isInteger(val)) { + bufIndex = offset + ((i+bitOffset)>>3); + theBit = 1 << (7 - ((i+bitOffset)&7)); + if (val->value & 1) + buf[bufIndex] |= theBit; + else + buf[bufIndex] &= ~theBit; + } else if (val->dataType == VAL_BITSTRING) { + bitString = (byte *)val->value; + bitLength = *bitString++; + for (j=0; j < bitLength && i+j < + aField->dimension; ++j) { + bufIndex = offset + ((i+j+bitOffset)>>3); + theBit = 1 << (7 - ((i+j+bitOffset)&7)); + if ((bitString[j>>3] >> (7-(j&7))) & 1) + buf[bufIndex] |= theBit; + else + buf[bufIndex] &= ~theBit; + } + for (i+=bitLength; idimension; ++i) { + bufIndex = offset + ((i+bitOffset)>>3); + theBit = 1 << (7 - ((i+bitOffset)&7)); + buf[bufIndex] &= ~theBit; + } + } else + error("invalid data type for bit field\n"); + freeValue(val); + } + } + if (data != NULL) + error("too many initialization values\n"); +} + + void +fillPrototype(buf, fields, class) + byte *buf; + fieldList *fields; + int class; +{ + while (fields != NULL) { + fillField(buf, fields->field->initValues, fields->field, + nextIntValue, nextStringValue, nextValue); + fields = fields->nextField; + } +} + + void +fillProperty(buf, prop, fields, class) + byte *buf; + property *prop; + fieldList *fields; + int class; +{ + while (fields != NULL) { + if (fields->field->name == prop->fieldName) { + fillField(buf, prop->data, fields->field, + nextIntValue, nextStringValue, nextValue); + return; + } else { + fields = fields->nextField; + } + } + if (class > 1) + fillProperty(buf, prop, classDefs[0]->fields, -1); + else + error("no match for field '%s'\n", prop->fieldName->name); +} + + void +fillData(buf, fields, properties, class) + byte *buf; + fieldList *fields; + propertyList *properties; + int class; +{ + while (properties != NULL) { + fillProperty(buf, properties->property, fields, class); + properties = properties->nextProp; + } +} + + object * +initObject(class, globalId) + int class; + int globalId; +{ + object *result; + objectList *buildObjectList(); + int i; + + if (indirectPass == 1) { + if (class == CLASS_REGION) + indirTable[indirRegion].region = globalId; + result = NULL; + } else { + result = typeAlloc(object); + result->class = class; + result->stateVector = byteAlloc(classDefs[class+1]->size); + for (i=0; isize; ++i) + result->stateVector[i] = classDefs[class+1]->prototype[i]; + if (class > 1) + fillLong(result->stateVector, 4, class); + fillLong(result->stateVector, 0, globalId); + } + return(result); +} + + object * +generateObject(class, tail) + int class; + objectTail *tail; +{ + value *val; + int globalId; + object *result; + + if (tail->idExpr == NULL || indirFile != NULL) { + globalId = -globalIdCounter++; + } else { + val = evaluate(tail->idExpr); + if (!isInteger(val) || val->value <= 0) { + error("illegal global id number\n"); + return(NULL); + } + globalId = val->value; + freeValue(val); + } + result = initObject(class, globalId); + if (indirectPass != 1) + fillData(result->stateVector, classDefs[class+1]->fields, + tail->properties, class); + return(result); +} + + void +outputRawObject(obj) + object *obj; +{ + int i; + + if (obj == NULL) + return; + fprintf(rawFile, "/%d ", obj->class); + for (i=0; iclass+1]->size; ++i) { + if ((i & 31) == 31) + fprintf(rawFile, "\\\n"); + fprintf(rawFile, "%02x", obj->stateVector[i]); + } + fprintf(rawFile, "\n"); +} + + int +fieldCode(ftype) + fieldType ftype; +{ + if (ftype == FIELD_REGID) + return(0); + else if (ftype == FIELD_AVAID) + return(1); + else if (ftype == FIELD_OBJID) + return(2); + else + return(-1); +} + + int +relativeId(id, contnum) + int id; + int contnum; +{ + char scratchName[15]; + symbol *scratchSymbol; + symbol *lookupSymbol(); + + sprintf(scratchName, "%c_%d", contCode(contnum), id); + scratchSymbol = lookupSymbol(scratchName); + if (scratchSymbol->type != VARIABLE_SYM) { + if (id < -1000 || 0 < id) { + error("undefined %c %d\n", contCode(contnum), id); + return(0); + } else + return(id); + } else + return(scratchSymbol->def.value->value); +} + + void +shiftField(aField, buf, adjust) + field *aField; + byte *buf; + int adjust; +{ + int i; + int offset; + int val; + + offset = aField->offset & 0x3FFF; + for (i=0; idimension; ++i) { + if (aField->type == FIELD_ENTITY) { + val = getLong(buf, offset + 6*i); + if (val < -1000) + fillLong(buf, offset + 6*i, val - adjust); + else if (assignRelativeIds) + fillLong(buf, offset + 6*i, + relativeId(val, getWord(buf, offset + + 6*i + 4))); + } else if (aField->type == FIELD_AVAID || aField->type == + FIELD_OBJID || aField->type == FIELD_REGID) { + val = getLong(buf, offset + 4*i); + if (val < -1000) + fillLong(buf, offset + 4*i, val - adjust); + else if (assignRelativeIds) + fillLong(buf, offset + 4*i, relativeId(val, + fieldCode(aField->type))); + } + } +} + + void +shiftRelativeGlobalIds(obj, adjust) + object *obj; + int adjust; +{ + fieldList *fields; + + if (obj->class > 1) { + fields = classDefs[0]->fields; + while (fields != NULL) { + shiftField(fields->field, obj->stateVector, adjust); + fields = fields->nextField; + } + } + fields = classDefs[obj->class+1]->fields; + while (fields != NULL) { + shiftField(fields->field, obj->stateVector, adjust); + fields = fields->nextField; + } +} + + void +generateScratchId(class, id, relativeId) + int class; + int id; + int relativeId; +{ + char scratchName[15]; + symbol *scratchSymbol; + valueType vtype; + value *buildValue(); + symbol *lookupSymbol(); + + sprintf(scratchName, "%c_%d", contCode(class), id); + scratchSymbol = lookupSymbol(scratchName); + scratchSymbol->type = VARIABLE_SYM; + if (class == 0) + vtype = VAL_REGION; + else if (class == 1) + vtype = VAL_AVATAR; + else + vtype = VAL_OBJECT; + scratchSymbol->def.value = buildValue(vtype, relativeId); +} + + void +executeRawline(obj) + object *obj; +{ + if (assignRelativeIds) + generateScratchId(obj->class, getLong(obj->stateVector, 0), + -1001 - objectCount); + shiftRelativeGlobalIds(obj, objectCount - rawCount++); + if (objectCount < MAXNOID) + noidArray[objectCount++] = obj; +} + + void +freeObjectTail(tail) + objectTail *tail; +{ + propertyList *properties; + propertyList *oldProperties; + exprList *expr; + exprList *oldExpr; + + properties = tail->properties; + while (properties != NULL) { + expr = properties->property->data; + while (expr != NULL) { + if (indirectPass == 1) + freeExpr(expr->expr); + oldExpr = expr; + expr = expr->nextExpr; + free(oldExpr); + } + free(properties->property); + oldProperties = properties; + properties = properties->nextProp; + free(oldProperties); + } + free(tail); +} + + void +executeUse(className, tagName, tail) + symbol *className; + symbol *tagName; + objectTail *tail; +{ + object *ultimate; + objectStub *buildObjectStub(); + + if (className->type != CLASS_SYM) + error("non-class identifier %s used for class name\n", + className->name); + else { + ultimate = generateObject(className->def.class, tail); + freeObjectTail(tail); + if (ultimate != NULL && tagName != NULL) { + if (ultimate->class == 0) + globalIdAdjustment = 0; + if (tagName->type == OBJECT_SYM) + free(tagName->def.object); + else if(tagName->type == VARIABLE_SYM) + freeValue(tagName->def.value); + tagName->type = OBJECT_SYM; + tagName->def.object = buildObjectStub(ultimate); + } +/*#ifndef FRED*/ + if (ultimate != NULL) { + if (ultimate->class == CLASS_DOOR || + ultimate->class == CLASS_BUILDING) + sortObjects = TRUE; + else if (ultimate->class == CLASS_REGION) + flushNoidArray(); + if (objectCount < MAXNOID && indirectPass != 1) + noidArray[objectCount++] = ultimate; + else if (indirectPass != 0) + error("more than 256 objects in region\n"); + } +/*#endif*/ + } +} + +cmpObjects(ob1, ob2) + object **ob1; + object **ob2; +{ + int class1, class2; + + class1 = (*ob1)->class; + class2 = (*ob2)->class; + if (class1 == CLASS_REGION) + return(-1); + else if (class2 == CLASS_REGION) + return(1); + else if (class1 != CLASS_DOOR && class1 != CLASS_BUILDING && + class2 != CLASS_DOOR && class2 != CLASS_BUILDING) + return(0); + else if (class1 != CLASS_DOOR && class1 != CLASS_BUILDING) + return(1); + else if (class2 != CLASS_DOOR && class2 != CLASS_BUILDING) + return(-1); + return(getLong((*ob1)->stateVector, X_OFFSET_OBJ) - + getLong((*ob2)->stateVector, X_OFFSET_OBJ)); +} + +flushNoidArray() +{ + int i; + +#ifndef FRED + if (indirectPass == 2) { + for (i=0; istateVector); + free(obj); +} + +freeValue(val) + value *val; +{ + if (val != NULL) { + if (val->dataType == VAL_STRING || + val->dataType == VAL_BITSTRING) + free(val->value); + free(val); + } +} + + void +executeDefine(classExpr, name, fields) + expression *classExpr; + char *name; + fieldList *fields; +{ + value *val; + int class; + symbol *symb; + symbol *lookupSymbol(); + int size; + + val = evaluate(classExpr); + class = val->value; + if (!isInteger(val)) + error("non-integer value used for class number\n"); + else if (class < -1 || MAXCLASS <= class) + error("class value %d out of range\n", class); + else if (classDefs[class+1] != NULL) + error("class %d already defined\n", class); + else { + translate(name, ' ', '_'); + symb = lookupSymbol(name); + symb->type = CLASS_SYM; + symb->def.class = class; + classDefs[class+1] = typeAlloc(classDescriptor); + size = computeFieldOffsets(fields, class); + classDefs[class+1]->size = size; + classDefs[class+1]->fields = fields; + classDefs[class+1]->className = symb; + classDefs[class+1]->prototype = (byte *)malloc(size); + fillPrototype(classDefs[class+1]->prototype, fields, class); + } + freeValue(val); + free(name); +} + + int +computeFieldOffsets(fields, class) + fieldList *fields; + int class; +{ + int offset; + int bitOffset; + field *aField; + + if (class > 1) + offset = objectBase; + else + offset = 0; + if (fields == NULL) + return(offset); + + bitOffset = 0; + while (fields != NULL) { + aField = fields->field; + aField->offset = offset + (bitOffset << 14); + + if (class == -1) + objectBase = offset; + + switch (aField->type) { + Case FIELD_ENTITY: + offset += 6 * aField->dimension; + + Case FIELD_AVAID: + case FIELD_BIN31: + case FIELD_OBJID: + case FIELD_REGID: + case FIELD_FATWORD: + offset += 4 * aField->dimension; + + Case FIELD_BIN15: + case FIELD_WORDS: + offset += 2 * aField->dimension; + + Case FIELD_BYTE: + case FIELD_CHARACTER: + offset += aField->dimension; + + Case FIELD_VARSTRING: + offset += aField->dimension + 2; + + Case FIELD_BIT: + bitOffset += aField->dimension; + if (bitOffset > 15) { + offset += 2 * (bitOffset >> 4); + bitOffset -= (bitOffset & ~0xF); + } + } + + if (aField->type != FIELD_BIT && bitOffset > 0) { + bitOffset = 0; + offset += 2; + } else if (aField->type != FIELD_CHARACTER && + aField->type != FIELD_BYTE && (offset & 1) == 1) + ++offset; + + fields = fields->nextField; + } + if (bitOffset > 0) + offset += 2; + return(offset); +} diff --git a/mamelink/griddle/expr.c b/mamelink/griddle/expr.c new file mode 100644 index 0000000..2d7a537 --- /dev/null +++ b/mamelink/griddle/expr.c @@ -0,0 +1,252 @@ +#include "y.tab.h" +#include "griddleDefs.h" + + value * +integerize(val) + value *val; +{ + char *string; + int i; + value *buildNumber(); + + if (val == NULL) { + val = buildNumber(0); + } else if (val->dataType == VAL_UNDEFINED) { + val->value = 0; + val->dataType = VAL_INTEGER; + } else if (val->dataType == VAL_STRING) { + string = (char *)val->value; + val->value = 0; + for (i=0; i < 4 && string[i] != '\0'; ++i) + val->value = val->value * 256 + string[i]; + val->dataType = VAL_INTEGER; + } else if (val->dataType == VAL_BITSTRING) { + /* do something */ + val->value = 0; + val->dataType = VAL_INTEGER; + } + return(val); +} + + boolean +isInteger(val) + value *val; +{ + return(val != NULL && + (val->dataType == VAL_INTEGER || val->dataType == VAL_AVATAR || + val->dataType == VAL_OBJECT || val->dataType == VAL_REGION)); +} + + boolean +isString(val) + value *val; +{ + return(val->dataType == VAL_STRING); +} + + value * +evaluate(expr) + expression *expr; +{ + value *result; + value *evaluateName(); + value *evaluateUnop(); + value *evaluateBin(); + value *buildNumber(); + value *buildString(); + value *buildBitString(); + + switch (expr->type) { + Case ID_EXPR: + result = evaluateName(expr->part1); + Case NUM_EXPR: + result = buildNumber((int) expr->part1); + Case EXPR_EXPR: + result = evaluate(expr->part1); + Case UNOP_EXPR: + result = evaluateUnop(expr->part1, evaluate(expr->part2)); + Case BIN_EXPR: + result = evaluateBin(evaluate(expr->part1), expr->part2, + evaluate(expr->part3)); + Case STRING_EXPR: + result = buildString((char *) expr->part1); + Case BITSTRING_EXPR: + result = buildBitString((byte *) expr->part1); + Default: + printf("bad expr type leaked thru!\n"); + exit(1); + } + free(expr); + return(result); +} + + void +freeExpr(expr) + expression *expr; +{ + switch (expr->type) { + Case EXPR_EXPR: + freeExpr(expr->part1); + Case UNOP_EXPR: + freeExpr(expr->part2); + Case BIN_EXPR: + freeExpr(expr->part1); + freeExpr(expr->part3); + Case STRING_EXPR: + free(expr->part1); + Case BITSTRING_EXPR: + free(expr->part1); + } + free(expr); +} + + value * +evaluateUnop(oper, opnd) + int oper; + value *opnd; +{ + opnd = integerize(opnd); + switch(oper) { + Case NOT: + opnd->value = ~opnd->value; + + Case UMINUS: + opnd->value = -opnd->value; + + Case A: + if (opnd->dataType == VAL_OBJECT || + opnd->dataType == VAL_REGION) + error("incompatible type coercion\n"); + opnd->dataType = VAL_AVATAR; + + Case O: + if (opnd->dataType == VAL_AVATAR || + opnd->dataType == VAL_REGION) + error("incompatible type coercion\n"); + opnd->dataType = VAL_OBJECT; + + Case R: + if (opnd->dataType == VAL_OBJECT || + opnd->dataType == VAL_AVATAR) + error("incompatible type coercion\n"); + opnd->dataType = VAL_REGION; + + Default: + printf("bad unop leaked thru!\n"); + exit(1); + } + return(opnd); +} + + value * +evaluateBin(opnd1, oper, opnd2) + value *opnd1; + int oper; + value *opnd2; +{ + opnd1 = integerize(opnd1); + opnd2 = integerize(opnd2); + switch(oper) { + case ADD: + opnd1->value += opnd2->value; + break; + case SUB: + opnd1->value -= opnd2->value; + break; + case MUL: + opnd1->value *= opnd2->value; + break; + case DIV: + opnd1->value /= opnd2->value; + break; + case MOD: + opnd1->value %= opnd2->value; + break; + case AND: + opnd1->value &= opnd2->value; + break; + case OR: + opnd1->value |= opnd2->value; + break; + case XOR: + opnd1->value ^= opnd2->value; + break; + default: + printf("bad binop leaked thru!\n"); + exit(1); + } + if (opnd1->dataType != opnd2->dataType) { + if (opnd1->dataType == VAL_INTEGER) + opnd1->dataType = opnd2->dataType; + else if (opnd2->dataType != VAL_INTEGER) + error("incompatible type combination"); + } + free(opnd2); + return(opnd1); +} + +#ifdef FRED + value * +valueFromName(name) + char *name; +{ + int len; + int i; + int result; + value *buildValue(); + + if ((len = strlen(name)) < 3 || name[1] != '_') + return(NULL); + result = 0; + for (i=2; itype) { + case VARIABLE_SYM: + return(buildValue(name->def.value->dataType, + name->def.value->value)); + case MACRO_SYM: + return(evaluate(name->def.expr)); + case OBJECT_SYM: + result = buildNumber(name->def.object->id); + if (name->def.object->class == 0) + result->dataType = VAL_REGION; + else if (name->def.object->class == 1) + result->dataType = VAL_AVATAR; + else + result->dataType = VAL_OBJECT; + return(result); + case NON_SYM: +#ifdef FRED + if ((result = valueFromName(name->name)) != NULL) + return(result); +#endif + printf("symbol %s undefined\n", name->name); + return(buildNumber(0)); + + default: + printf("bad symbol type leaked thru!\n"); + exit(1); + } +} diff --git a/mamelink/griddle/fred.c b/mamelink/griddle/fred.c new file mode 100644 index 0000000..662f73f --- /dev/null +++ b/mamelink/griddle/fred.c @@ -0,0 +1,900 @@ +#include +#include +#include "griddleDefs.h" +#include "prot.h" +#include "y.tab.h" + +static int selectedField = 0; +static int selectedPath = 0; +static int editX = 0; +static int editY = 0; +static char *editPath; +static field *editField = NULL; +static boolean changedFlag = FALSE; + +static char paths[10][80]; +static char pathFileName[80]; + +int fredStats[128]; + +typedef struct { + char commandKey; + char *echoName; + boolean (*commandFunction)(); + char *helpInfo; +} command; + +void echoLine(); +void lineError(); +boolean getString(); +boolean processCommand(); +void displayOneObject(); + +boolean saveGriddle(), initC64editor(), loadRegion(), quit(), saveRaw(), sh(); +boolean refreshScreen(), showNoids(), displayObject(), incDisplayObject(); +boolean decDisplayObject(), createObject(), help(), touch(), undeleteObject(); +boolean deleteObject(), foreground(), background(), incX_4(), decX_4(); +boolean incY_1(), decY_1(), incY_10(), decY_10(), zeroGrState(), incGrState(); +boolean toggleOrient(), editObject(), nightMode(), walkto(), showFlatTypes(); +boolean eraseBackground(), incPattern(), decPattern(), flatChange(); +boolean twinObject(), peekContainer(), changeContainer(), trapEdit(); +boolean borderToggle(), containerOffsetRight(), containerOffsetLeft(); +boolean containerOffsetUp(), containerOffsetDown(), changeHold(), pauseFred(); +boolean editPathlist(), displayPathlist(); + +command commandTable[] = { + 'b', "background object", background, "move object to background", + 'B', "background display suppression", eraseBackground, + "display without background", + ctrl(B), "border/unborder trapezoid trap", borderToggle, + "border/unborder trapezoid", + 'c', "create new object", createObject, "create a new object", + 'C', "container peek", peekContainer, "look inside container", + 'd', "display object", displayObject, "display an object", + 'D', "drop into container", changeContainer, + "drop object into container", + ctrl(D), "display pathlist", displayPathlist, + "display current pathlist", + 'e', "edit object", editObject, "edit an object's state info", + 'E', "edit trapezoid", trapEdit, "edit a trapezoid's corner info", + 'f', "foreground object", foreground, "move object to foreground", + 'F', "flat type change", flatChange, "change type of flat", + 'g', "griddle format save", saveGriddle, "save in griddle format", + 'G', "show flat types", showFlatTypes, "show flat types", + 'h', "help", help, "display help info", + 'H', "offset left", containerOffsetLeft, NULL, + 'i', "initialize region editor", initC64editor, "init Reno", + 'I', "change how held", changeHold, NULL, + 'J', "offset up", containerOffsetUp, NULL, + 'K', "offset down", containerOffsetDown, NULL, + 'L', "offset right", containerOffsetRight, NULL, + 'n', "night mode", nightMode, "switch display to night mode", + 'o', "object noid list", showNoids, "show noids and classes", + 'O', "orientation flip", toggleOrient, "toggle object's orientation", + 'p', "inc color/pattern", incPattern, "inc object's color/pattern", + 'P', "dec color/pattern", decPattern, "dec object's color/pattern", + ctrl(P), "path list edit", editPathlist, "edit path list", + 'q', "quit", quit, "exit Fred", + 'r', "read region from file", loadRegion, "read region from a file", + 's', "set grState to 0", zeroGrState, "set object's grState to 0", + 'S', "inc grState", incGrState, "inc object's grState", + 't', "touch object under cursor", touch, "touch object under cursor", + 'T', "twin object", twinObject, "twin object", + 'u', "undelete deleted object", undeleteObject, + "undo object deletion", + 'w', "walk to indicated object", walkto, "walk avatar to object", + 'x', "delete object", deleteObject, "delete an object", + 'z', "raw format save", saveRaw, "save in raw format", + '+', "display object", incDisplayObject, "inc display noid", + '-', "display object", decDisplayObject, "dec display noid", + '!', "unix command", sh, "execute a Unix command", + '.', "inc X", incX_4, "inc object's X coordinate", + ',', "dec X", decX_4, "dec object's X coordinate", + '?', "inc Y", incY_1, "inc object's Y coordinate", + '/', "dec Y", decY_1, "dec object's Y coordinate", + '>', "inc Y by 10", incY_10, "inc object's Y coordinate by 10", + '<', "dec Y by 10", decY_10, "dec object's Y coordinate by 10", + '\r', "refresh Fred screen", refreshScreen, "refresh screen", + ctrl(Z), "pause Fred", pauseFred, "pause Fred", + '\0', NULL, NULL, NULL +}; + +extern char *getenv(); + +/* flags */ +#define NCARDS 3 +int card = 0; +int port = 0; + + void +c64_override_command(cmd) + byte cmd; +{ + if (!testMode) { + down(&cmd, (word) 1, KEYBOARD_OVERRIDE); + Cont(); + sleep(1); + } +} + + void +c64_key_command(cmd) + byte cmd; +{ + byte buf; + + buf = cmd; + if (!testMode) { + down(&buf, (word) 1, KEYBOARD_KEYPRESS); + Cont(); + sleep(1); + } +} + + void +c64_touch_command(arg) + byte arg; +{ + byte buf; + + buf = arg; + if (!testMode) { + down(&buf, (word) 1, TOUCH_SLOT); + Cont(); + } +} + + void +readFredStats() +{ + FILE *statFyle; + int i; + + if ((statFyle = fopen("/u0/habitat/fredStats", "r")) != NULL) { + for (i=0; i<128; ++i) + fredStats[i] = getw(statFyle); + fclose(statFyle); + } + if (statFyle == NULL || feof(statFyle)) { + for (i=0; i<128; ++i) + fredStats[i] = 0; + } +} + + void +writeFredStats() +{ + FILE *statFyle; + int i; + + if ((statFyle = fopen("/u0/habitat/fredStats", "w")) != NULL) { + for (i=0; i<128; ++i) + putw(fredStats[i], statFyle); + fclose(statFyle); + } +} + + int +touchObject() +{ + char buf; + + if (!testMode) { + c64_key_command('t'); + up(&buf, (word) 1, TOUCHED_OBJECT); + Cont(); + return(buf); + } else + return(displayNoid); +} + + boolean +touch() +{ + displayNoid = touchObject(); + displayOneObject(displayNoid); + return(TRUE); +} + + boolean +help() +{ + int i; + int y, x; + int line, col; + + line = 1; + col = 0; + getyx(curscr, y, x); + clearDisplay(); + for (i=0; commandTable[i].commandKey!='\0'; ++i) { + if (commandTable[i].helpInfo != NULL) { + mvprintw(line, col, "%s -- %s", + keyName(commandTable[i].commandKey), + commandTable[i].helpInfo); + nextlc(line, col, 40); + } + } + move(y, x); + return(TRUE); +} + + boolean +displayField(line, col, aField, buf, highlight) + int line; + int col; + field *aField; + byte *buf; + boolean highlight; +{ + char str[512]; + + if (fieldString(aField, buf, str)) { + if (highlight) { + editX = col; + editY = line; + editField = aField; + } + mvaddstr(line, col, " "); + if (highlight) + standout(); + addstr(str); + if (highlight) + standend(); + return(TRUE); + } else + return(FALSE); +} + + int +displayFieldList(fields, buf, lineptr, colptr, fieldNum) + fieldList *fields; + byte *buf; + int *lineptr; + int *colptr; + int fieldNum; +{ + while (fields != NULL) { + if (displayField(*lineptr, *colptr, fields->field, buf, + fieldNum == selectedField)) { + nextlc(*lineptr, *colptr, 40); + ++fieldNum; + } + fields = fields->nextField; + } + return(fieldNum); +} + + void +revalueField(firstc, buf) + char firstc; + byte *buf; +{ + ungetch(firstc); + fredModeLexingOn(); + fillFieldPrompt(editY, editX, editField, buf, TRUE); + fredModeLexingOff(); +} + + bool +showObject(noid) + int noid; +{ + object *obj; + int line, col; + int y, x; + int fieldNum; + + line = 1; + col = 0; + fieldNum = 1; + obj = noidArray[noid]; + getyx(curscr, y, x); + clearDisplay(); + if (obj->class > 1) + fieldNum = displayFieldList(classDefs[0]->fields, + obj->stateVector, &line, &col, fieldNum); + fieldNum = displayFieldList(classDefs[obj->class+1]->fields, + obj->stateVector, &line, &col, fieldNum); + move(y, x); + refresh(); + return(fieldNum - 1 == selectedField); +} + + void +editOneObject(noid) + int noid; +{ + char c; + boolean lastField; + + showObject(noid); + selectedField = 1; + changedFlag = FALSE; + do { + lastField = showObject(noid); + c = mygetch(); + if (c == DEL) + break; + else if (c == '\b') { + selectedField = selectedField < 2 ? + 0 : selectedField - 2; + lastField = FALSE; + } else if (c != '\r' && c != '\n' && c != ' ') + revalueField(c, noidArray[noid]->stateVector); + ++selectedField; + } while (!lastField); + selectedField = 0; + showObject(noid); +} + + boolean +editObject() +{ + int y, x; + + echoLine("editing object %d (%s)", displayNoid, + classDefs[noidArray[displayNoid]->class+1]->className->name); + getyx(curscr, y, x); + editOneObject(displayNoid); + if (changedFlag) + uploadRegion(); + move(y, x); + return(TRUE); +} + + void +displayOneObject(noid) + int noid; +{ + echoLine("object %d (%s)", noid, + classDefs[noidArray[noid]->class+1]->className->name); + showObject(noid); +} + + boolean +displayObject() +{ + int noid; + + noid = promptInt("noid #", displayNoid); + if (noid == -1) + echoLine("aborted"); + else if (noid < 0 || MAXNOID <= noid) + lineError("noid out of range"); + else if (noidArray[noid] == NULL) + lineError("there is no object #%d", noid); + else { + displayNoid = noid; + if (noid != 0) + c64_touch_command(noid); + displayOneObject(noid); + } + return(TRUE); +} + + boolean +incDisplayObject() +{ + int count; + + count = 0; + if (displayNoid == MAXNOID - 1) displayNoid = -1; + while (noidArray[++displayNoid] == NULL && ++count < MAXNOID) + if (displayNoid == MAXNOID - 1) displayNoid = -1; + if (noidArray[displayNoid] != NULL) { + if (displayNoid != 0) + c64_touch_command(displayNoid); + displayOneObject(displayNoid); + } else + lineError("no objects to display!"); + return(TRUE); +} + + boolean +decDisplayObject() +{ + int count; + + count = 0; + if (displayNoid == 0) displayNoid = MAXNOID; + while (noidArray[--displayNoid] == NULL && ++count < MAXNOID) + if (displayNoid == 0) displayNoid = MAXNOID; + if (noidArray[displayNoid] != NULL) { + if (displayNoid != 0) + c64_touch_command(displayNoid); + displayOneObject(displayNoid); + } else + lineError("no objects to display!"); + return(TRUE); +} + + boolean +deleteObject() +{ + if (displayNoid == 0) + lineError("can't delete the region!"); + else { + if (undeleteBuffer != NULL) + freeObject(undeleteBuffer); + undeleteBuffer = noidArray[displayNoid]; + noidArray[displayNoid] = NULL; + if (displayNoid == objectCount) + --objectCount; + echoLine("object %d is gone", displayNoid); + incDisplayObject(); + uploadRegion(); + } + return(TRUE); +} + + boolean +undeleteObject() +{ + int noid; + + if (undeleteBuffer == NULL) + lineError("no deleted object to restore"); + else { + noid = nextFreeNoid(); + noidArray[noid] = undeleteBuffer; + undeleteBuffer = NULL; + echoLine("object restored to noid %d", noid); + uploadRegion(); + } + return(TRUE); +} + + boolean +fillFieldPrompt(line, col, aField, buf, editMode) + int line; + int col; + field *aField; + byte *buf; + boolean editMode; +{ + char temp[80]; + value *parseBit(); + value *parseInt(); + char *parseString(); + + if (aField->invisible) + return(FALSE); + + fieldPrompt(line, col, aField, buf, editMode); + if (mygetstr(temp) && temp[0] != '\0') { + fillField(buf, temp, aField, parseInt, parseString, parseBit); + changedFlag = TRUE; + } + return(TRUE); +} + + void +fillDataPrompt(lineptr, colptr, buf, fields, class) + int *lineptr; + int *colptr; + byte *buf; + fieldList *fields; + int class; +{ + fredModeLexingOn(); + while (fields != NULL) { + if (fillFieldPrompt(*lineptr, *colptr, fields->field, buf, + FALSE)) + nextlc(*lineptr, *colptr, 40); + fields = fields->nextField; + } + fredModeLexingOff(); +} + + void +generateFredObject(class, twinFlag) + int class; + boolean twinFlag; +{ + object *obj; + object *initObject(); + int noid; + int i; + + obj = initObject(class, -globalIdCounter++); + if (twinFlag) + for (i=4; isize; ++i) + obj->stateVector[i] = + noidArray[displayNoid]->stateVector[i]; + noid = nextFreeNoid(); + displayNoid = noid; + noidArray[noid] = obj; + clearDisplay(); + if (twinFlag) + displayOneObject(noid); + else + editOneObject(noid); +} + + boolean +createObject() +{ + int class; + void displayRegion(); + + class = promptInt("-- class", previousClass); + if (class == -1) + echoLine("aborted"); + else if (class < 1 || MAXCLASS <= class) + lineError("class value %d is out of range", class); + else { + echoLine("creating class %d (%s)", class, + classDefs[class+1]->className->name); + previousClass = class; + generateFredObject(class, FALSE); + uploadRegion(); + echoLine("created object %d, class %d (%s)", displayNoid, + class, classDefs[class+1]->className->name); + c64_touch_command(displayNoid); + } + return(TRUE); +} + + boolean +twinObject() +{ + int class; + + if (displayNoid == 0) + lineError("can't twin region"); + else { + class = noidArray[displayNoid]->class; + previousClass = class; + generateFredObject(class, TRUE); +/* announceObject(displayNoid, class);*/ + uploadRegion(); + echoLine("created object %d, class %d (%s)", displayNoid, + class, classDefs[class+1]->className->name); + c64_touch_command(displayNoid); + } + return(TRUE); +} + + boolean +showNoids() +{ + int line, col; + int y, x; + int i; + + line = 1; + col = 0; + getyx(curscr, y, x); + clearDisplay(); + for (i=0; iclass+1]->className->name); + nextlc(line, col, 20); + } + move(y, x); + refresh(); + return(TRUE); +} + + void +readPathlist() +{ + char *pathstr; + FILE *fyle; + int i; + + sprintf(pathFileName, "%s/.fredpaths", getenv("HOME")); + if ((fyle = fopen(pathFileName,"r")) != NULL) { + for (i=1; i<10; i++) + fscanf(fyle, "%s\n", paths[i]); + fclose(fyle); + } else { + for (i=1; i<10; i++) + strcpy(paths[i], "./"); + } + if ((pathstr = getenv("FREDPATH")) != NULL) + strcpy(paths[0], pathstr); + else + strcpy(paths[0], "./"); +} + + void +writePathlist() +{ + FILE *fyle; + int i; + + if ((fyle = fopen(pathFileName, "w")) != NULL) { + for (i=1; i<10; i++) + fprintf(fyle, "%s\n", paths[i]); + fclose(fyle); + } else + lineError("can't write to pathlist file %s", pathFileName); +} + + void +showPathlist() +{ + int i; + int y, x; + + getyx(curscr, y, x); + clearDisplay(); + for (i=0; i<10; ++i) { + mvaddstr(i + 1, 0, " "); + if (i == selectedPath) { + editX = 0; + editY = i + 1; + editPath = paths[i]; + standout(); + } + addstr(paths[i]); + if (i == selectedPath) standend(); + clrtoeol(); + } + move(y, x); + refresh(); +} + + boolean +displayPathlist() +{ + showPathlist(); + return(TRUE); +} + + void +revaluePath(firstc) + char firstc; +{ + char temp[80]; + + ungetch(firstc); + mvaddstr(selectedPath + 1, 0, " "); + clrtoeol(); + refresh(); + if (mygetstr(temp) && temp[0] != '\0') { + strcpy(editPath, temp); + changedFlag = TRUE; + } +} + + boolean +editPathlist() +{ + int y, x; + char c; + + echoLine("editing pathlist"); + getyx(curscr, y, x); + showPathlist(); + changedFlag = FALSE; + for (;;) { + c = mygetch(); + if (c == DEL) + break; + else if (c == '\b') { + if (selectedPath > 0) + --selectedPath; + } else if (c == '\r' || c == '\n' || c == ' ') { + if (selectedPath < 9) + ++selectedPath; + } else + revaluePath(c); + showPathlist(); + } + if (changedFlag) + writePathlist(); + move(y, x); + strcpy(pathname, paths[selectedPath]); + return(TRUE); +} + + void +snarfRegion() +{ + int i; + byte *p; + byte buf[10000]; + int regionSize; + FILE *fyle; + + c64_override_command(CMD_SAVE_CV); + up(buf, (word) 2, CV_SIZE_SLOT); + regionSize = buf[0] + buf[1]*256; + up(buf, (word)(regionSize), CV_DATA_SLOT); + Cont(); + p = buf; + for (i=0; i +#include "griddleDefs.h" +#include +#include + + void +mydown(buf, len, addr) + byte *buf; + word len; + word addr; +{ + if (!testMode) + down(buf, len, addr); +} + + void +displayRegion() +{ + mydown(cv, (word)(cvLength), CV_DATA_SLOT); + c64_override_command(CMD_LOAD_CV); +} + + boolean +incColorPattern(dp, cmd) + int dp; + byte cmd; +{ + byte *buf; + + if (displayNoid == 0) + lineError("region has no color/pattern!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, ORIENT_OFFSET_AVA, + (getWord(buf, ORIENT_OFFSET_AVA) + dp) & 0xFF); + else + fillWord(buf, ORIENT_OFFSET_OBJ, + (getWord(buf, ORIENT_OFFSET_OBJ) + dp) & 0xFF); + c64_key_command(cmd); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +incPattern() +{ + return(incColorPattern(8, 'p')); +} + + boolean +decPattern() +{ + return(incColorPattern(-8, 'P')); +} + + boolean +incX(dx, cmd) + int dx; + byte cmd; +{ + byte *buf; + + if (displayNoid == 0) + lineError("region has no X-coordinate!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, X_OFFSET_AVA, + (getWord(buf, X_OFFSET_AVA) + dx) & 0xFF); + else + fillWord(buf, X_OFFSET_OBJ, + (getWord(buf, X_OFFSET_OBJ) + dx) & 0xFF); + c64_key_command(cmd); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +incY(dy, cmd) + int dy; + byte cmd; +{ + byte *buf; + + if (displayNoid == 0) + lineError("region has no Y-coordinate!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, Y_OFFSET_AVA, + (getWord(buf, Y_OFFSET_AVA) + dy) & 0xFF); + else + fillWord(buf, Y_OFFSET_OBJ, + (getWord(buf, Y_OFFSET_OBJ) + dy) & 0xFF); + c64_key_command(cmd); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +incX_4() +{ + return(incX(4, '.')); +} + + boolean +decX_4() +{ + return(incX(-4, ',')); +} + + boolean +incY_1() +{ + return(incY(1, '?')); +} + + boolean +incY_10() +{ + return(incY(10, '>')); +} + + boolean +decY_1() +{ + return(incY(-1, '/')); +} + + boolean +decY_10() +{ + return(incY(-10, '<')); +} + + boolean +zeroGrState() +{ + byte *buf; + + if (displayNoid == 0) + lineError("region does not have grState!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, GRSTATE_OFFSET_AVA, 0); + else + fillWord(buf, GRSTATE_OFFSET_OBJ, 0); + c64_key_command('s'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +incGrState() +{ + byte *buf; + + if (displayNoid == 0) + lineError("region does not have grState!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, GRSTATE_OFFSET_AVA, + getWord(buf, GRSTATE_OFFSET_AVA) + 1); + else + fillWord(buf, GRSTATE_OFFSET_OBJ, + getWord(buf, GRSTATE_OFFSET_OBJ) + 1); + c64_key_command('S'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +toggleOrient() +{ + byte *buf; + + if (displayNoid == 0) + lineError("region does not have displayed orientation!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, ORIENT_OFFSET_AVA, + getWord(buf, ORIENT_OFFSET_AVA) ^ 0x01); + else + fillWord(buf, ORIENT_OFFSET_OBJ, + getWord(buf, ORIENT_OFFSET_OBJ) ^ 0x01); + c64_key_command('o'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +borderToggle() +{ + byte *buf; + + if (noidArray[displayNoid]->class != CLASS_TRAP && + noidArray[displayNoid]->class != CLASS_SUPER_TRAP) + lineError("current object is not a trapezoid!"); + else { + buf = noidArray[displayNoid]->stateVector; + fillWord(buf, HEIGHT_OFFSET_TRAP, + getWord(buf, HEIGHT_OFFSET_TRAP) ^ 0x80); + c64_key_command('B'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +flatChange() +{ + byte *buf; + int class; + + class = noidArray[displayNoid]->class; + if (class != CLASS_FLAT && class != CLASS_TRAP && class != + CLASS_SUPER_TRAP) + lineError("inappropriate object for flat type change!"); + else { + buf = noidArray[displayNoid]->stateVector; + fillWord(buf, TYPE_OFFSET_FLAT, + (getWord(buf, TYPE_OFFSET_FLAT) + 1) & 3); + c64_key_command('m'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +foreground() +{ + byte *buf; + + if (displayNoid == 0) + lineError("region does not have foreground/background!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, Y_OFFSET_AVA, + getWord(buf, Y_OFFSET_AVA) | 0x80); + else + fillWord(buf, Y_OFFSET_OBJ, + getWord(buf, Y_OFFSET_OBJ) | 0x80); + c64_key_command('f'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + boolean +background() +{ + byte *buf; + + if (displayNoid == 0) + lineError("region does not have foreground/background!"); + else { + buf = noidArray[displayNoid]->stateVector; + if (isAvatar(displayNoid)) + fillWord(buf, Y_OFFSET_AVA, + getWord(buf, Y_OFFSET_AVA) & 0x7F); + else + fillWord(buf, Y_OFFSET_OBJ, + getWord(buf, Y_OFFSET_OBJ) & 0x7F); + c64_key_command('b'); + displayOneObject(displayNoid); + } + return(TRUE); +} + + void +uploadRegion() +{ + generateContentsVector(); + displayRegion(); +} + + void +homogenize(filename) + char *filename; +{ + char tempstr[80]; + char *tildeptr; + char *index(); + + if ((tildeptr = index(filename, '~')) != NULL) { + strncpy(tempstr, filename, tildeptr - filename); + sprintf(tempstr + (tildeptr - filename), "%s%s", + getenv("HOME"), tildeptr + 1); + strcpy(filename, tempstr); + } +} + + boolean +readRegion() +{ + char regionFileName[80]; + + sprintf(regionFileName, "%s%s", pathname, regionName); + homogenize(regionFileName); + queueInputFile(saveString(regionFileName)); + if (openFirstFile(TRUE)) { + resetRegionCounters(); + yyparse(); + echoLine("reading %d objects", objectCount); + globalIdCounter += objectCount; + displayNoid = 0; + if (objectCount > 127) + lineError("too many objects in region"); + return(TRUE); + } else { + lineError("can't open '%s'", regionFileName); + return(FALSE); + } +} + + boolean +writeRegionRaw() +{ + char regionFileName[80]; + int i; + struct stat statBuf; + + sprintf(regionFileName, "%s%s", pathname, regionName); + homogenize(regionFileName); + if (!promptDefault) + if (stat(regionFileName, &statBuf) == 0) + if (!promptYN("file already exists; replace? ")) { + echoLine("write aborted"); + return(FALSE); + } + if ((rawFile = fopen(regionFileName, "w")) != NULL) { + for (i=0; istateVector; + createPacket[0] = class; + createPacket[1] = 0; + if (class == 1) { + createPacket[2] = getByte(buf, STYLE_OFFSET_AVA); + createPacket[3] = getWord(buf, X_OFFSET_AVA); + createPacket[4] = getWord(buf, Y_OFFSET_AVA); + createPacket[5] = getWord(buf, ORIENT_OFFSET_AVA); + createPacket[6] = getWord(buf, GRSTATE_OFFSET_AVA); + } else { + createPacket[2] = getWord(buf, STYLE_OFFSET_OBJ); + createPacket[3] = getWord(buf, X_OFFSET_OBJ); + createPacket[4] = getWord(buf, Y_OFFSET_OBJ); + createPacket[5] = getWord(buf, ORIENT_OFFSET_OBJ); + createPacket[6] = getWord(buf, GRSTATE_OFFSET_OBJ); + } + mydown(createPacket, (word) 7, CREATE_DATA_SLOT); + c64_override_command(CMD_CREATE); +} + + boolean +nightMode() +{ + c64_key_command('n'); + return(TRUE); +} + + boolean +eraseBackground() +{ + c64_key_command('e'); + return(TRUE); +} + + boolean +walkto() +{ + c64_key_command('w'); + return(TRUE); +} + + boolean +showFlatTypes() +{ + c64_key_command('g'); + return(TRUE); +} + + boolean +peekContainer() +{ + c64_key_command('l'); + return(TRUE); +} + + boolean +containerOffsetRight() +{ + c64_key_command('+'); + return(TRUE); +} + + boolean +containerOffsetLeft() +{ + c64_key_command('-'); + return(TRUE); +} + + boolean +containerOffsetUp() +{ + c64_key_command('@'); + return(TRUE); +} + + boolean +containerOffsetDown() +{ + c64_key_command('*'); + return(TRUE); +} + + boolean +changeHold() +{ + c64_key_command('='); + return(TRUE); +} + + boolean +changeContainer() +{ + int newContainer; + int contCode; + byte *cbuf; + byte *obuf; + + newContainer = touchObject(); + c64_touch_command(displayNoid); + c64_key_command('C'); + c64_key_command('r'); + obuf = noidArray[displayNoid]->stateVector; + cbuf = noidArray[newContainer]->stateVector; + if (noidArray[newContainer]->class == 0) + contCode = 0; + else if (noidArray[newContainer]->class == 1) + contCode = 1; + else + contCode = 2; + if (isAvatar(displayNoid)) { + if (contCode == 1) + lineError("can't put avatar in another avatar!"); + else if (contCode == 0) + fillLong(obuf, CONTAINER_OFFSET_AVA, 0); + else + fillLong(obuf, CONTAINER_OFFSET_AVA, + getLong(cbuf, IDENT_OFFSET_OBJ)); + } else { + fillLong(obuf, CONTAINER_OFFSET_OBJ, + getLong(cbuf, IDENT_OFFSET_OBJ)); + fillWord(obuf, CONTAINER_TYPE_OFFSET_OBJ, contCode); + } +} + + boolean +trapEdit() +{ + char c; + + if (noidArray[displayNoid]->class != CLASS_TRAP && + noidArray[displayNoid]->class != CLASS_SUPER_TRAP) { + lineError("current object is not a trapezoid!"); + return(TRUE); + } + clearDisplay(); + mvprintw(1, 0, "L -- upper left corner"); + mvprintw(2, 0, "l -- lower left corner"); + mvprintw(3, 0, "R -- upper right corner"); + mvprintw(4, 0, "r -- lower right corner"); + mvprintw(5, 0, "x -- exit trapezoid edit mode"); + refresh(); + c64_key_command(TRAP_EDIT_KEY); + while ((c = mygetch()) != 'x') { + if (c == 'L') { + echoLine("upper left"); + c64_key_command(UPPER_LEFT_KEY); + } else if (c == 'l') { + echoLine("lower left"); + c64_key_command(LOWER_LEFT_KEY); + } else if (c == 'R') { + echoLine("upper right"); + c64_key_command(UPPER_RIGHT_KEY); + } else if (c == 'r') { + echoLine("lower right"); + c64_key_command(LOWER_RIGHT_KEY); + } else { + lineError("not a trapezoid edit command!"); + } + } + echoLine("done editing trapezoid"); + c64_key_command(TRAP_EDIT_KEY); + snarfRegion(); + degenerateContentsVector(); + displayOneObject(displayNoid); + return(TRUE); +} diff --git a/mamelink/griddle/fscreen.c b/mamelink/griddle/fscreen.c new file mode 100644 index 0000000..8948d32 --- /dev/null +++ b/mamelink/griddle/fscreen.c @@ -0,0 +1,350 @@ +#include +#include "griddleDefs.h" +#include "y.tab.h" + +static boolean unsavedFlag = FALSE; +static char unsavedChar; + +extern int yylval; + + void +echoLine(fmt, arg1, arg2, arg3) + char *fmt; + int arg1; + int arg2; + int arg3; +{ + move(0, 0); + refresh(); + clrtoeol(); + printw(fmt, arg1, arg2, arg3); + refresh(); +} + + void +lineError(fmt, arg1, arg2, arg3) + char *fmt; + int arg1; + int arg2; + int arg3; +{ + echoLine(fmt, arg1, arg2, arg3); + putchar('\7'); +} + + char +mygetch() +{ + if (unsavedFlag) { + unsavedFlag = FALSE; + return(unsavedChar); + } else + return(getch()); +} + + void +ungetch(c) + char c; +{ + unsavedChar = c; + unsavedFlag = TRUE; +} + + boolean +mygetstr(buf) + char *buf; +{ + char c; + char *originalBuf; + int x, y; + int originalX; + + originalBuf = buf; + getyx(curscr, y, originalX); + x = originalX; + for (;;) { + c = mygetch(); + if (c == CTRL_C || c == ESCAPE) + return(FALSE); + else if (c == '\n' || c == '\r' || c == EOF) { + addch('\r'); + refresh(); + *buf = '\0'; + return(TRUE); + } else if (c == '\b' || c == DEL) { + if (buf > originalBuf) { + mvclrtoeol(y, --x); + --buf; + } + } else if (c == CTRL_U) { + mvclrtoeol(y, x = originalX); + buf = originalBuf; + } else { + addch(c); + *buf++ = c; + ++x; + } + refresh(); + } +} + + boolean +getString(prompt, buf) + char *prompt; + char *buf; +{ + addstr(prompt); + refresh(); + return(mygetstr(buf)); +} + + int +promptInt(prompt, defval) + char *prompt; + int defval; +{ + char answer[80]; + char newPrompt[80]; + symbol *symb; + symbol *lookupSymbol(); + + sprintf(newPrompt, " %s [%d] ? ", prompt, defval); + if (!getString(newPrompt, answer)) + return(0); + if (answer[0] == '\0') + return(defval); + else if (answer[0] == ESCAPE || answer[0] == CTRL_C) + return(-1); + else if ('0' <= answer[0] && answer[0] <= '9') + return(atoi(answer)); + else { + symb = lookupSymbol(answer); + if (symb->type != CLASS_SYM) { + lineError("not a class name!"); + return(-1); + } + return(symb->def.class); + } +} + + boolean +promptStr(prompt, defval, resultBuf) + char *prompt; + char *defval; + char *resultBuf; +{ + char answer[80]; + char newPrompt[80]; + + sprintf(newPrompt, " %s [\"%s\"] ? ", prompt, defval); + if (!getString(newPrompt, answer)) + return(FALSE); + if (answer[0] == '\0') { + promptDefault = TRUE; + if (defval != resultBuf) + strcpy(resultBuf, defval); + } else { + promptDefault = FALSE; + strcpy(resultBuf, answer); + } + return(TRUE); +} + + boolean +promptYN(prompt) + char *prompt; +{ + char answer[80]; + + mvclrtoeol(0, 0); + for (;;) { + if (getString(prompt, answer)) { + if (answer[0] == 'Y' || answer[0] == 'y') + return(TRUE); + else if (answer[0] == 'N' || answer[0] == 'n') + return(FALSE); + } + lineError("please answer yes or no!"); + } +} + + void +fieldPrompt(line, col, aField, buf, highlight) + int line; + int col; + field *aField; + byte *buf; + boolean highlight; +{ + mvaddstr(line, col, " "); + if (highlight) + standout(); + printw("%s:", aField->name->name); + if (highlight) + standend(); + addstr(" "); + clrtoeol(); + refresh(); +} + + value * +parseValue(dataptr) + char **dataptr; +{ + char *data; + value *val; + value *buildValue(); + valueType resultType, newType; + boolean typeTest; + int sign; + + if (dataptr == NULL || *dataptr == NULL) + return(buildValue(VAL_INTEGER, 0)); + fredLexString = *dataptr; + resultType = newType = VAL_INTEGER; + val = NULL; + sign = 1; + for (;;) { + typeTest = FALSE; + switch (yylex()) { + Case Number: + val = buildValue(resultType, yylval*sign); + Case String: + val = buildValue(VAL_STRING, yylval); + typeTest = TRUE; + Case BitString: + val = buildValue(VAL_BITSTRING, yylval); + typeTest = TRUE; + Case '-': + sign = -sign; + Case A: + newType = VAL_AVATAR; + typeTest = TRUE; + Case O: + newType = VAL_OBJECT; + typeTest = TRUE; + Case R: + newType = VAL_REGION; + typeTest = TRUE; + Case ',': + if (resultType != VAL_INTEGER) + lineError("dangling type!"); + *dataptr = fredLexString; + return(val); + Case 0: + if (resultType != VAL_INTEGER) + lineError("dangling type!"); + *dataptr = NULL; + return(val); + Default: + lineError("syntax error!"); + if (val == NULL) + val = buildValue(VAL_INTEGER, 0); + } + if (typeTest && resultType != VAL_INTEGER) + lineError("type mismatch!"); + else + resultType = newType; + } +} + + value * +parseInt(dataptr) + char **dataptr; +{ + value *val; + value *buildNumber(); + + val = parseValue(dataptr); + if (val != NULL && !isInteger(val)) { + lineError("invalid data type for integer value!"); + val = buildNumber(0); + } + return(val); +} + + value * +parseBit(dataptr) + char **dataptr; +{ + value *val; + value *buildNumber(); + + val = parseValue(dataptr); + if (val != NULL && !isInteger(val) && val->dataType != VAL_BITSTRING){ + lineError("invalid data type for bitstring value!"); + val = buildNumber(0); + } + return(val); +} + + char * +parseString(dataptr) + char **dataptr; +{ + value *val; + + if (dataptr == NULL || *dataptr == NULL) + return(NULL); + val = parseValue(dataptr); + if (isString(val)) + return((char *)(val->value)); + else { + lineError("invalid data type for string value!"); + return(NULL); + } +} + + boolean +getRegionName() +{ + return(promptStr("name", regionName, regionName)); +} + + void +hexDump(buf, len) + byte *buf; + int len; +{ + int i; + int line; + + clearDisplay(); + for (i=0, line=1; i &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); } + *yyps = yystate; + ++yypv; + *yypv = yyval; + + yynewstate: + + yyn = yypact[yystate]; + + if( yyn<= YYFLAG ) goto yydefault; /* simple state */ + + if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0; + if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault; + + if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */ + yychar = -1; + yyval = yylval; + yystate = yyn; + if( yyerrflag > 0 ) --yyerrflag; + goto yystack; + } + + yydefault: + /* default state action */ + + if( (yyn=yydef[yystate]) == -2 ) { + if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0; + /* look through exception table */ + + for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */ + + while( *(yyxi+=2) >= 0 ){ + if( *yyxi == yychar ) break; + } + if( (yyn = yyxi[1]) < 0 ) return(0); /* accept */ + } + + if( yyn == 0 ){ /* error */ + /* error ... attempt to resume parsing */ + + switch( yyerrflag ){ + + case 0: /* brand new error */ + + yyerror( "syntax error" ); + yyerrlab: + ++yynerrs; + + case 1: + case 2: /* incompletely recovered error ... try again */ + + yyerrflag = 3; + + /* find a state where "error" is a legal shift action */ + + while ( yyps >= yys ) { + yyn = yypact[*yyps] + YYERRCODE; + if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){ + yystate = yyact[yyn]; /* simulate a shift of "error" */ + goto yystack; + } + yyn = yypact[*yyps]; + + /* the current yyps has no shift onn "error", pop stack */ + +#ifdef YYDEBUG + if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); +#endif + --yyps; + --yypv; + } + + /* there is no state on the stack with an error shift ... abort */ + + yyabort: + return(1); + + + case 3: /* no shift yet; clobber input char */ + +#ifdef YYDEBUG + if( yydebug ) printf( "error recovery discards char %d\n", yychar ); +#endif + + if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */ + yychar = -1; + goto yynewstate; /* try again in the same state */ + + } + + } + + /* reduction by production yyn */ + +#ifdef YYDEBUG + if( yydebug ) printf("reduce %d\n",yyn); +#endif + yyps -= yyr2[yyn]; + yypvt = yypv; + yypv -= yyr2[yyn]; + yyval = yypv[1]; + yym=yyn; + /* consult goto table to find next state */ + yyn = yyr1[yyn]; + yyj = yypgo[yyn] + *yyps + 1; + if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; + switch(yym){ + +case 8: +# line 35 "griddle.y" +{ + executeRawline(yypvt[-0]); +} break; +case 9: +# line 42 "griddle.y" +{ + executeAssignment(yypvt[-2], yypvt[-0]); +} break; +case 10: +# line 49 "griddle.y" +{ + executeInclude(yypvt[-0]); +} break; +case 11: +# line 56 "griddle.y" +{ + yyval = executeDefine(yypvt[-3], yypvt[-2], yypvt[-1]); +} break; +case 12: +# line 60 "griddle.y" +{ + yyval = executeDefine(yypvt[-2], yypvt[-1], NULL); +} break; +case 13: +# line 67 "griddle.y" +{ + yyval = buildFieldList(NULL, yypvt[-0]); +} break; +case 14: +# line 71 "griddle.y" +{ + yyval = buildFieldList(yypvt[-1], yypvt[-0]); +} break; +case 15: +# line 78 "griddle.y" +{ + yyval = yypvt[-0]; +} break; +case 16: +# line 82 "griddle.y" +{ + yyval = invisifyField(yypvt[-0]); +} break; +case 17: +# line 89 "griddle.y" +{ + yyval = buildField(yypvt[-2], buildExpr(NUM_EXPR, 1), yypvt[-0], NULL); +} break; +case 18: +# line 93 "griddle.y" +{ + yyval = buildField(yypvt[-5], yypvt[-3], yypvt[-0], NULL); +} break; +case 19: +# line 97 "griddle.y" +{ + yyval = buildField(yypvt[-4], buildExpr(NUM_EXPR, 1), yypvt[-2], yypvt[-0]); +} break; +case 20: +# line 101 "griddle.y" +{ + yyval = buildField(yypvt[-7], yypvt[-5], yypvt[-2], yypvt[-0]); +} break; +case 21: +# line 107 "griddle.y" +{ yyval = (int) FIELD_CHARACTER; } break; +case 22: +# line 108 "griddle.y" +{ yyval = (int) FIELD_BIN15; } break; +case 23: +# line 109 "griddle.y" +{ yyval = (int) FIELD_BIN31; } break; +case 24: +# line 110 "griddle.y" +{ yyval = (int) FIELD_BIT; } break; +case 25: +# line 111 "griddle.y" +{ yyval = (int) FIELD_WORDS; } break; +case 26: +# line 112 "griddle.y" +{ yyval = (int) FIELD_REGID; } break; +case 27: +# line 113 "griddle.y" +{ yyval = (int) FIELD_OBJID; } break; +case 28: +# line 114 "griddle.y" +{ yyval = (int) FIELD_AVAID; } break; +case 29: +# line 115 "griddle.y" +{ yyval = (int) FIELD_FATWORD; } break; +case 30: +# line 116 "griddle.y" +{ yyval = (int) FIELD_ENTITY; } break; +case 31: +# line 117 "griddle.y" +{ yyval = (int) FIELD_BYTE; } break; +case 32: +# line 118 "griddle.y" +{ yyval = (int) FIELD_VARSTRING; } break; +case 33: +# line 123 "griddle.y" +{ + executeUse(yypvt[-2], yypvt[-1], yypvt[-0]); +} break; +case 34: +# line 127 "griddle.y" +{ + executeUse(yypvt[-1], NULL, yypvt[-0]); +} break; +case 35: +# line 134 "griddle.y" +{ + yyval = buildObjectTail(yypvt[-3], yypvt[-1]); +} break; +case 36: +# line 138 "griddle.y" +{ + yyval = buildObjectTail(NULL, yypvt[-1]); +} break; +case 37: +# line 145 "griddle.y" +{ + yyval = buildPropertyList(NULL, yypvt[-0]); +} break; +case 38: +# line 149 "griddle.y" +{ + yyval = buildPropertyList(yypvt[-1], yypvt[-0]); +} break; +case 39: +# line 156 "griddle.y" +{ + yyval = buildProperty(yypvt[-2], yypvt[-0]); +} break; +case 40: +# line 163 "griddle.y" +{ + yyval = buildExprList(NULL, yypvt[-0]); +} break; +case 41: +# line 167 "griddle.y" +{ + yyval = buildExprList(yypvt[-2], yypvt[-0]); +} break; +case 42: +# line 174 "griddle.y" +{ + yyval = buildExpr(ID_EXPR, yypvt[-0]); +} break; +case 43: +# line 178 "griddle.y" +{ + yyval = buildExpr(NUM_EXPR, yypvt[-0]); +} break; +case 44: +# line 182 "griddle.y" +{ + yyval = buildExpr(STRING_EXPR, yypvt[-0]); +} break; +case 45: +# line 186 "griddle.y" +{ + yyval = buildExpr(BITSTRING_EXPR, yypvt[-0]); +} break; +case 46: +# line 190 "griddle.y" +{ + yyval = buildExpr(EXPR_EXPR, yypvt[-1]); +} break; +case 47: +# line 194 "griddle.y" +{ + yyval = buildExpr(UNOP_EXPR, UMINUS, yypvt[-0]); +} break; +case 48: +# line 198 "griddle.y" +{ + yyval = buildExpr(UNOP_EXPR, NOT, yypvt[-0]); +} break; +case 49: +# line 202 "griddle.y" +{ + yyval = buildExpr(UNOP_EXPR, A, yypvt[-0]); +} break; +case 50: +# line 206 "griddle.y" +{ + yyval = buildExpr(UNOP_EXPR, O, yypvt[-0]); +} break; +case 51: +# line 210 "griddle.y" +{ + yyval = buildExpr(UNOP_EXPR, R, yypvt[-0]); +} break; +case 52: +# line 214 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], ADD, yypvt[-0]); +} break; +case 53: +# line 218 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], SUB, yypvt[-0]); +} break; +case 54: +# line 222 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], MUL, yypvt[-0]); +} break; +case 55: +# line 226 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], DIV, yypvt[-0]); +} break; +case 56: +# line 230 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], MOD, yypvt[-0]); +} break; +case 57: +# line 234 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], AND, yypvt[-0]); +} break; +case 58: +# line 238 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], OR, yypvt[-0]); +} break; +case 59: +# line 242 "griddle.y" +{ + yyval = buildExpr(BIN_EXPR, yypvt[-2], XOR, yypvt[-0]); +} break; + } + goto yystack; /* stack new state and value */ + + } diff --git a/mamelink/griddle/griddle.y b/mamelink/griddle/griddle.y new file mode 100644 index 0000000..4100211 --- /dev/null +++ b/mamelink/griddle/griddle.y @@ -0,0 +1,245 @@ +%{ +#include "griddleDefs.h" +%} + +%token Name Number String BitString Rawline +%token INCLUDE DEFINE ENDDEFINE USE +%token AVAID BIN15 BIN31 BIT BYTE CHARACTER ENTITY FATWORD OBJID REGID +%token VARSTRING WORDS + +%left A O R +%left OR +%left XOR +%left AND +%left ADD SUB +%left MUL DIV MOD +%right UMINUS NOT + +%% + +statementList: + statement /* na */ + | statementList statement /* na */ + ; + +statement: + assignmentStatement /* na */ + | includeStatement /* na */ + | defineStatement /* na */ + | objectUseStatement /* na */ + | rawStatement /* na */ + ; + +rawStatement: + Rawline +{ + executeRawline($1); +} + ; + +assignmentStatement: + Name '=' expr +{ + executeAssignment($1, $3); +} + ; + +includeStatement: + INCLUDE String +{ + executeInclude($2); +} + ; + +defineStatement: + DEFINE expr String fieldList ENDDEFINE +{ + $$ = executeDefine($2, $3, $4); +} + | DEFINE expr String ENDDEFINE +{ + $$ = executeDefine($2, $3, NULL); +} + ; + +fieldList: + field +{ + $$ = buildFieldList(NULL, $1); +} + | fieldList field +{ + $$ = buildFieldList($1, $2); +} + ; + +field: + basicField +{ + $$ = $1; +} + | '#' basicField +{ + $$ = invisifyField($2); +} + ; + +basicField: + Name ':' fieldType +{ + $$ = buildField($1, buildExpr(NUM_EXPR, 1), $3, NULL); +} + | Name '(' expr ')' ':' fieldType +{ + $$ = buildField($1, $3, $6, NULL); +} + | Name ':' fieldType '=' exprList +{ + $$ = buildField($1, buildExpr(NUM_EXPR, 1), $3, $5); +} + | Name '(' expr ')' ':' fieldType '=' exprList +{ + $$ = buildField($1, $3, $6, $8); +} + ; + +fieldType: + CHARACTER { $$ = (int) FIELD_CHARACTER; } + | BIN15 { $$ = (int) FIELD_BIN15; } + | BIN31 { $$ = (int) FIELD_BIN31; } + | BIT { $$ = (int) FIELD_BIT; } + | WORDS { $$ = (int) FIELD_WORDS; } + | REGID { $$ = (int) FIELD_REGID; } + | OBJID { $$ = (int) FIELD_OBJID; } + | AVAID { $$ = (int) FIELD_AVAID; } + | FATWORD { $$ = (int) FIELD_FATWORD; } + | ENTITY { $$ = (int) FIELD_ENTITY; } + | BYTE { $$ = (int) FIELD_BYTE; } + | VARSTRING { $$ = (int) FIELD_VARSTRING; } + ; + +objectUseStatement: + USE Name Name objectTail +{ + executeUse($2, $3, $4); +} + | USE Name objectTail +{ + executeUse($2, NULL, $3); +} + ; + +objectTail: + '=' expr '{' properties '}' +{ + $$ = buildObjectTail($2, $4); +} + | '{' properties '}' +{ + $$ = buildObjectTail(NULL, $2); +} + ; + +properties: + property +{ + $$ = buildPropertyList(NULL, $1); +} + | properties property +{ + $$ = buildPropertyList($1, $2); +} + ; + +property: + Name ':' exprList +{ + $$ = buildProperty($1, $3); +} + ; + +exprList: + expr +{ + $$ = buildExprList(NULL, $1); +} + | exprList ',' expr +{ + $$ = buildExprList($1, $3); +} + ; + +expr: + Name +{ + $$ = buildExpr(ID_EXPR, $1); +} + | Number +{ + $$ = buildExpr(NUM_EXPR, $1); +} + | String +{ + $$ = buildExpr(STRING_EXPR, $1); +} + | BitString +{ + $$ = buildExpr(BITSTRING_EXPR, $1); +} + | '(' expr ')' +{ + $$ = buildExpr(EXPR_EXPR, $2); +} + | SUB expr %prec UMINUS +{ + $$ = buildExpr(UNOP_EXPR, UMINUS, $2); +} + | NOT expr +{ + $$ = buildExpr(UNOP_EXPR, NOT, $2); +} + | A expr +{ + $$ = buildExpr(UNOP_EXPR, A, $2); +} + | O expr +{ + $$ = buildExpr(UNOP_EXPR, O, $2); +} + | R expr +{ + $$ = buildExpr(UNOP_EXPR, R, $2); +} + | expr ADD expr +{ + $$ = buildExpr(BIN_EXPR, $1, ADD, $3); +} + | expr SUB expr +{ + $$ = buildExpr(BIN_EXPR, $1, SUB, $3); +} + | expr MUL expr +{ + $$ = buildExpr(BIN_EXPR, $1, MUL, $3); +} + | expr DIV expr +{ + $$ = buildExpr(BIN_EXPR, $1, DIV, $3); +} + | expr MOD expr +{ + $$ = buildExpr(BIN_EXPR, $1, MOD, $3); +} + | expr AND expr +{ + $$ = buildExpr(BIN_EXPR, $1, AND, $3); +} + | expr OR expr +{ + $$ = buildExpr(BIN_EXPR, $1, OR, $3); +} + | expr XOR expr +{ + $$ = buildExpr(BIN_EXPR, $1, XOR, $3); +} + ; diff --git a/mamelink/griddle/griddleDefs.h b/mamelink/griddle/griddleDefs.h new file mode 100644 index 0000000..924f905 --- /dev/null +++ b/mamelink/griddle/griddleDefs.h @@ -0,0 +1,298 @@ +#include + +#define Case break; case +#define Default break; default + +typedef unsigned char byte; +typedef unsigned short word; +typedef int boolean; +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define CLASS_REGION 0 +#define CLASS_DOOR 23 +#define CLASS_BUILDING 132 +#define CLASS_FLAT 93 +#define CLASS_TRAP 87 +#define CLASS_SUPER_TRAP 92 + +/* These constants ought to be extracted from the defines, but they're not. + Anytime the definition for the base object changes, these may have to be + changed also. */ +#define IDENT_OFFSET 0 +#define IDENT_OFFSET_OBJ IDENT_OFFSET +#define CONTAINER_OFFSET_OBJ 8 +#define CONTAINER_TYPE_OFFSET_OBJ 12 +#define X_OFFSET_OBJ 14 +#define Y_OFFSET_OBJ 16 +#define STYLE_OFFSET_OBJ 18 +#define GRSTATE_OFFSET_OBJ 20 +#define ORIENT_OFFSET_OBJ 22 + +#define TYPE_OFFSET_FLAT 42 +#define HEIGHT_OFFSET_TRAP 52 +#define CONNECTION_OFFSET_DOOR 48 + +#define CONTAINER_OFFSET_AVA 8 +#define X_OFFSET_AVA 12 +#define Y_OFFSET_AVA 14 +#define GRSTATE_OFFSET_AVA 20 +#define ORIENT_OFFSET_AVA 28 +#define STYLE_OFFSET_AVA 32 +#define PROP_BASE_AVA 80 +#define AVATAR_PROPERTY_COUNT 6 + +#define IDENT_OFFSET_REG IDENT_OFFSET +#define LIGHTLEVEL_OFFSET_REG 8 +#define DEPTH_OFFSET_REG 10 +#define EAST_OFFSET_REG 12 +#define WEST_OFFSET_REG 16 +#define NORTH_OFFSET_REG 20 +#define SOUTH_OFFSET_REG 24 +#define CLASSGROUP_OFFSET_REG 28 +#define ORIENT_OFFSET_REG 30 + +typedef enum { + VARIABLE_SYM, MACRO_SYM, OBJECT_SYM, NON_SYM, CLASS_SYM +} symbolType; + +typedef enum { + ID_EXPR, NUM_EXPR, EXPR_EXPR, UNOP_EXPR, BIN_EXPR, STRING_EXPR, + BITSTRING_EXPR +} exprType; + +typedef enum { + FIELD_AVAID, FIELD_BIN15, FIELD_BIN31, FIELD_BIT, FIELD_BYTE, + FIELD_CHARACTER, FIELD_ENTITY, FIELD_FATWORD, FIELD_OBJID, + FIELD_REGID, FIELD_WORDS, FIELD_VARSTRING +} fieldType; + +typedef enum { + VAL_UNDEFINED, VAL_INTEGER, VAL_STRING, VAL_AVATAR, VAL_OBJECT, + VAL_REGION, VAL_BITSTRING +} valueType; + +typedef struct { + exprType type; + int part1; + int part2; + int part3; +} expression; + +typedef struct exprListStruct { + expression *expr; + struct exprListStruct *nextExpr; +} exprList; + +typedef struct stringListStruct { + char *string; + struct stringListStruct *nextString; +} stringList; + +typedef struct { + int value; + valueType dataType; +} value; + +typedef struct valueListStruct { + value *value; + struct valueListStruct *nextValue; +} valueList; + +typedef struct genericListStruct { + int *thing; + struct genericListStruct *next; +} genericList; + +typedef struct { + int *thing; + genericList *next; + genericList *last; +} genericListHead; + +typedef struct { + int class; + byte *stateVector; +} object; + +typedef struct { + int class; + int id; +} objectStub; + +typedef struct objectListStruct { + object *object; + struct objectListStruct *nextObject; +} objectList; + +typedef struct symbolStruct { + char *name; + int codeNumber; + symbolType type; + union { + value *value; + expression *expr; + objectStub *object; + int class; + } def; + struct symbolStruct *next; +} symbol; + +typedef struct { + symbol *fieldName; + exprList *data; +} property; + +typedef struct propertyListStruct { + property *property; + struct propertyListStruct *nextProp; +} propertyList; + +typedef struct { + expression *idExpr; + propertyList *properties; +} objectTail; + +typedef struct { + symbol *name; + int dimension; + fieldType type; + int offset; + boolean invisible; + exprList *initValues; +} field; + +typedef struct fieldListStruct { + field *field; + struct fieldListStruct *nextField; +} fieldList; + +typedef struct { + fieldList *fields; + int size; + symbol *className; + byte *prototype; +} classDescriptor; + +#define HASH_MAX 512 +symbol *symbolTable[HASH_MAX]; + +char *malloc(); + +#define typeAlloc(t) ((t *)malloc(sizeof(t))) +#define typeAllocMulti(t,n) ((t *)malloc((n)*sizeof(t))) +#define byteAlloc(n) ((byte *)malloc(n)) + +typedef struct fileListStruct { + FILE *fyle; + struct fileListStruct *next; + int saveLine; + char *saveName; +} fileList; + +fileList *inputStack; +fileList *bottomOfInputStack; +FILE *currentInput; +int currentLineNumber; +char *currentFileName; +int globalIdCounter; +int globalIdAdjustment; +int objectBase; + +FILE *griFile; +FILE *rawFile; +FILE *cvFile; +FILE *indirFile; +int indirectPass; +stringList *cvInput; +char *classFileName; +boolean debug; +boolean testMode; +boolean assignRelativeIds; +int useStartCount; +boolean insideDefinition; +boolean announceIncludes; + +#define MAXCLASS 256 +classDescriptor *classDefs[MAXCLASS+1]; + +#define MAXNOID 256 +int objectCount; +int rawCount; +object *noidArray[MAXNOID]; +object *altNoidArray[MAXNOID]; +boolean noidAlive[MAXNOID]; +boolean fredModeLexing; +char *fredLexString; + +boolean promptDefault; +char pathname[80]; +char regionName[80]; +byte cv[512]; +int cvLength; +int displayNoid; +object *undeleteBuffer; +int previousClass; + + +/* C64 locations */ +#define KEYBOARD_OVERRIDE (word)0x0010 +#define KEYBOARD_KEYPRESS (word)0x0011 +#define TOUCH_SLOT (word)0x0012 +#define TOUCHED_OBJECT (word)0x0013 +#define TOUCHED_ADDRES (word)0x0014 +#define CREATE_DATA_SLOT (word)0x0801 +#define CV_SIZE_SLOT (word)0xea07 +#define CV_DATA_SLOT (word)0xea09 + +/* C64 override commands */ +#define CMD_CREATE 1 +#define CMD_SAVE_CV 2 +#define CMD_LOAD_CV 3 + +#define TRAP_EDIT_KEY 141 +#define UPPER_LEFT_KEY 18 +#define UPPER_RIGHT_KEY 19 +#define LOWER_LEFT_KEY 20 +#define LOWER_RIGHT_KEY 21 + +#define DEL '\177' +#define ESCAPE '\033' +#define ctrl(c) ('c'&0x1F) +#define CTRL_C ctrl(C) +#define CTRL_U ctrl(U) + +#define mvclrtobot(y,x) { move((y),(x)); clrtobot(); } +#define mvclrtoeol(y,x) { move((y),(x)); clrtoeol(); } +#define clearDisplay() mvclrtobot(1,0) +#define nextlc(line,col,dy) {++(line);if((line)>LINES-1){\ + (line)=1;(col)+=(dy);}} + +#define myCont() if (!testMode) Cont(); + +#define fredModeLexingOn() fredModeLexing = TRUE; +#define fredModeLexingOff() { strcpy(fredLexString, "\n"); \ + yylex(); fredModeLexing = FALSE; } + +#define isAvatar(n) (noidArray[(n)]->class == 0) + +typedef struct { + int west; + int north; + int east; + int south; + int rot; + int *multi; + int multiCount; + int region; +} indirectEntry; + +indirectEntry *indirTable; +int indirCount; +char indirName[80]; +int indirArgc; +char *indirArgv[50]; +int indirRegion; +boolean sortObjects; diff --git a/mamelink/griddle/indir.c b/mamelink/griddle/indir.c new file mode 100644 index 0000000..93cb612 --- /dev/null +++ b/mamelink/griddle/indir.c @@ -0,0 +1,344 @@ +#include "griddleDefs.h" + +#define MAXLINE 500 + + char * +scan_number(args, resultptr) + char *args; + int *resultptr; +{ + *resultptr = 0; + while ('0' <= *args && *args <= '9') + *resultptr = *resultptr * 10 + *args++ - '0'; + return(args); +} + + char * +scan_connections(args, multiOK, resultptr, multiptr, countptr) + char *args; + boolean multiOK; + int *resultptr; + int **multiptr; + int *countptr; +{ + int multiArray[20]; + int multiCount; + int dummy; + int i; + + if (*args == '(') { + *args = ' '; + multiCount = 0; + while (*args == ' ') + args = scan_number(args+1, &multiArray[multiCount++]); + *resultptr = multiArray[multiCount - 1]; + if (multiOK) { + *multiptr = typeAllocMulti(int, multiCount); + for (i=0; istateVector; + if (obj->class == CLASS_REGION) { + fillLong(buf, WEST_OFFSET_REG, + getIdent(indirTable[reg].west)); + fillLong(buf, NORTH_OFFSET_REG, + getIdent(indirTable[reg].north)); + fillLong(buf, EAST_OFFSET_REG, + getIdent(indirTable[reg].east)); + fillLong(buf, SOUTH_OFFSET_REG, + getIdent(indirTable[reg].south)); + fillWord(buf, ORIENT_OFFSET_REG, indirTable[reg].rot); + } else if (obj->class == CLASS_DOOR || obj->class == CLASS_BUILDING) { + if (index <= indirTable[reg].multiCount) { + fillLong(buf, CONNECTION_OFFSET_DOOR, + getIdent(indirTable[reg].multi[index-1])); + if (index == indirTable[reg].multiCount) { + buf = altNoidArray[0]->stateVector; + switch (indirTable[reg].rot) { + Case 0: fillLong(buf, WEST_OFFSET_REG, -1); + Case 1: fillLong(buf, NORTH_OFFSET_REG, -1); + Case 2: fillLong(buf, EAST_OFFSET_REG, -1); + Case 3: fillLong(buf, SOUTH_OFFSET_REG, -1); + } + } + } else + fillLong(buf, CONNECTION_OFFSET_DOOR, -1); + } +} + + int +getIdent(num) + int num; +{ + if (num == 0) + return(-1); + else + return(indirTable[num - 1].region); +} + + char * +skipArg(line, stringFlag) + char *line; + boolean stringFlag; +{ + char *index(); + + if (stringFlag) { + while ((line = index(line+1, '"')) != NULL) + if (*(line - 1) != '\\') + return(line); + } else for (; *line != ' ' && *line != '\n' && *line != '\0'; ++line) + ; + return(line); +} + + void +replaceParams(line) + char *line; +{ + char scratchBuf[500]; + char *outptr; + char *argptr; + char *inptr; + int offset; + enum { LEFT, CENTER, RIGHT, NONE } format; + int width; + int i; + int len; + + outptr = scratchBuf; + inptr = line; + while (*inptr != '\0') { + if (*inptr == '`') { + offset = scanNumber(&inptr); + if (*inptr == 'l' || *inptr == 'r' || *inptr == 'c') { + format = (*inptr == 'l') ? LEFT : + ((*inptr == 'r') ? RIGHT : CENTER); + width = scanNumber(&inptr) + 1; + } else + format = NONE; + if (indirArgc < offset) + error("parameter offset %d out of range\n", + offset); + else if (offset == -1) + *outptr++ = '`'; + else { + len = strlen(indirArgv[offset]); + switch (format) { + Case NONE: + for (argptr=indirArgv[offset]; + *argptr != '\0'; ) + *outptr++ = *argptr++; + Case LEFT: + for (argptr=indirArgv[offset], i=0; + *argptr != '\0' && + i < width; ++i) + *outptr++ = *argptr++; + for (; i < width; ++i) + *outptr++ = ' '; + + Case RIGHT: + argptr = indirArgv[offset]; + if (len < width) + for (i=width-len; i > 0; --i) + *outptr++ = ' '; + else + argptr += len - width; + while (*argptr != '\0') + *outptr++ = *argptr++; + + Case CENTER: + argptr = indirArgv[offset]; + i = 0; + if (len < width) + for (; i < (width-len)/2; ++i) + *outptr++ = ' '; + else + argptr += (len - width) / 2; + for (; i ? */ +/* 56 */ C_DIG, C_DIG, C_LIT, C_SKIP, C_SKIP, C_LIT, C_SKIP, C_SKIP, +/* @ A B C D E F G */ +/* 64 */ C_SKIP, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* H I J J L M N O */ +/* 72 */ C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* P Q R S T U V W */ +/* 80 */ C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* X Y Z [ \ ] ^ _ */ +/* 88 */ C_ALPH, C_ALPH, C_ALPH, C_SKIP, C_SKIP, C_SKIP, C_LIT, C_ALPH, +/* ` a b c d e f g */ +/* 96 */ C_SKIP, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* h i j k l m n o */ +/*104 */ C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* p q r s t u v w */ +/*112 */ C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, C_ALPH, +/* x y z { | } ` Del */ +/*120 */ C_ALPH, C_ALPH, C_ALPH, C_LIT, C_LIT, C_LIT, C_SKIP, C_SKIP +}; + +static int litCode[128] = { +/* EOF Soh Stx Etx Eot Enq Ack Bell */ +/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* Backsp HTab Newline VTab Newpage Return So Si */ +/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* Dle Dc1 Dc2 Dc3 Dc4 Nak Syn Etb */ +/* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* Can Em Sub Escape Fs Gs Rs Us */ +/* 24 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* Space ! " # $ % & ' */ +/* 32 */ 0, 0, 0, '#', 0, MOD, AND, 0, +/* ( ) * + , - . / */ +/* 40 */ '(', ')', MUL, ADD, ',', SUB, 0, 0, +/* 0 1 2 3 4 5 6 7 */ +/* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 9 : ; < = > ? */ +/* 56 */ 0, 0, ':', 0, 0, '=', 0, 0, +/* @ A B C D E F G */ +/* 64 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* H I J J L M N O */ +/* 72 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* P Q R S T U V W */ +/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* X Y Z [ \ ] ^ _ */ +/* 88 */ 0, 0, 0, 0, 0, 0, XOR, 0, +/* ` a b c d e f g */ +/* 96 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* h i j k l m n o */ +/*104 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* p q r s t u v w */ +/*112 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* x y z { | } ` Del */ +/*120 */ 0, 0, 0, '{', OR, '}', 0, 0 +}; + +static boolean newline = TRUE; +static boolean oldnewline; + +char yytext[256]; + +yylex() +{ + char c; + + for (;;) { + c = input(); + oldnewline = newline; + newline = FALSE; + switch (char_type[c]) { + Case C_SLASH: + if (oldnewline) { + parseRawline(); + return(Rawline); + } + c = input(); + if (c == '*') + comment(); + else { + unput(c); + return(DIV); + } + + Case C_ZERO: + c = input(); + if (c == 'x' || c == 'X') + parseNumber(16, input()); + else if (c == 'b' || c == 'B') + parseNumber(2, input()); + else if (c == 'q' || c == 'Q') + parseNumber(4, input()); + else + parseNumber(8, c); + return(Number); + + Case C_DIG: + parseNumber(10, c); + return(Number); + + Case C_ALPH: + parseName(c); + if ((yylval = matchKeyword(yytext)) != 0) + return(yylval); + yylval = lookupSymbol(yytext); +/* if (debug) + printf("lexer: Name '%s'\n", yytext);*/ + return(Name); + + Case C_QUOTE: + lexString('"'); + string(); + return(String); + + Case C_APOSTROPHE: + lexString('\''); + c = input(); + if (c == 'b' || c == 'B') { + bitString(); + return(BitString); + } else { + string(); + unput(c); + return(String); + } + + Case C_LIT: + return(litCode[c]); + + Case C_NL: + newline = TRUE; + } + } +} + +parseName(c) + char c; +{ + char *cptr; + + cptr = yytext; + while (char_type[c] == C_DIG || char_type[c] == C_ALPH) { + *cptr++ = c; + c = input(); + } + *cptr = '\0'; + unput(c); +} + +comment() +{ + char c, c1; + +loop: + while ((c = input()) != '*' && c != 0) + ; + + if ((c1 = input()) != '/' && c != 0) + { + unput(c1); + goto loop; + } +} + +parseNumber(base, c) + int base; + char c; +{ + yylval = 0; + while (isDigit(c, base)) { + yylval = yylval * base + digitValue(c); + c = input(); + } + unput(c); +/* if (debug) + printf("lexer: Number (%d) = %d\n", base, yylval);*/ +} + +skipToEol() +{ + char c; + + while ((c = input()) != '\n' && c != 0) + ; + unput(c); +} + + int +getHexByte() +{ + char c1, c2; + + while ((c1 = input()) == '\\' || c1 == ' ') + if (c1 == '\\') + c1 = input(); + if (c1 == '\n' || c1 == 0) { + unput(c1); + return(-1); + } else if (!isDigit(c1, 16)) { + error("illegal hex digit '%c'\n", c1); + skipToEol(); + return(-2); + } + c2 = input(); + if (c2 == '\n' || c2 == 0) { + unput(c1); + error("bad hex digit parity\n"); + return(-2); + } else if (!isDigit(c2, 16)) { + error("illegal hex digit '%c'\n", c2); + skipToEol(); + return(-2); + } + return(digitValue(c1) * 16 + digitValue(c2)); +} + +getHexString(buf, size) + byte *buf; + int size; +{ + int i; + int aByte; + char c; + + for (i=0; i= 0) { + error("raw line long\n"); + skipToEol(); + } +} + +parseRawline() +{ + object *result; + char hexString[1500]; + int length; + + result = typeAlloc(object); + parseNumber(10, input()); + result->class = yylval; + result->stateVector = (byte *)malloc(classDefs[yylval+1]->size); + getHexString(result->stateVector, classDefs[yylval+1]->size); + yylval = (int)result; +/* if (debug) + printf("lexer: Rawline class=%d addr=%x\n", result->class, result);*/ +} + + boolean +isDigit(c, base) + char c; + int base; +{ + if (base <= 10) + return('0' <= c && c <= '0' - 1 + base); + else + return( ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F') ); +} + + int +digitValue(c) + char c; +{ + if ('0'<=c && c<='9') + return(c - '0'); + else if ('a'<=c && c<='f') + return(c - 'a' + 10); + else + return(c - 'A' + 10); +} + +#define FORMFEED 12 +#define HALF_SPACE 128 +#define DOUBLE_SPACE 143 +#define INC_WIDTH 129 +#define DEC_WIDTH 130 +#define INC_HEIGHT 131 +#define DEC_HEIGHT 132 +#define HALF_SIZE 133 +#define CHAR_RETURN 134 +#define DN_HALF_CHAR 139 +#define INVERSE 140 +#define CURSOR_RIGHT 135 +#define CURSOR_LEFT 136 +#define CURSOR_UP 137 +#define CURSOR_DOWN 138 + +static struct { + char inChar; + char outChar; +} escapes[] = { + 'n', '\n', 't', '\t', 'b', '\b', + 'r', '\r', 'f', FORMFEED, 'e', ESCAPE, + '\\', '\\', '\'', '\'', '"', '"', + ' ', HALF_SPACE, '#', DOUBLE_SPACE, '+', INC_WIDTH, + '-', DEC_WIDTH, '(', INC_HEIGHT, ')', DEC_HEIGHT, + 'h', HALF_SIZE, 'd', DN_HALF_CHAR, 'i', INVERSE, + '>', CURSOR_LEFT, '<', CURSOR_RIGHT, '^', CURSOR_UP, + 'v', CURSOR_DOWN, 'R', CHAR_RETURN, '\0', 0 +}; + + char +unescape() +{ + int i; + char result; + char c; + + c = input(); + if (c == '^') { + result = input() & 0x3F; + } else if (c == 'x') { + result = 0; + for (i=0; i<2; ++i) { + c = input(); + if (isDigit(c, 16)) + result = result * 16 + digitValue(c); + else + unput(c); + } + } else if ('0' <= c && c <= '7') { + result = digitValue(c); + for (i=0; i<2; ++i) { + c = input(); + if ('0' <= c && c <= '7') + result = result * 8 + digitValue(c); + else + unput(c); + } + } else for (i=0; escapes[i].inChar!='\0'; ++i) { + result = c; + if (c == escapes[i].inChar) { + result = escapes[i].outChar; + break; + } + } + return(result); +} + + char * +escape(c) + char c; +{ + int i; + static char result[5]; + + if (' ' <= c && c <= '~') + sprintf(result, "%c", c); + else if (c == 0) + sprintf(result, "\\0"); + else { + sprintf(result, "\\%o", (byte)c); + for (i=0; escapes[i].outChar!='\0'; ++i) + if (c == escapes[i].outChar) { + sprintf(result, "\\%c", escapes[i].inChar); + break; + } + } + return(result); +} + +lexString(end) + char end; +{ + char *str; + char c; + + str = yytext; + for (c = input(); c != end; c = input()) + if (c == '\\') + *str++ = unescape(); + else + *str++ = c; + *str = '\0'; +} + +string() +{ + int len; + char *str; + char *inptr; + + str = malloc(strlen(yytext) + 1); + yylval = (int)str; + strcpy(str, yytext); +/* if (debug) + printf("lexer: String '%s'\n", yylval);*/ +} + +bitString() +{ + int len; + byte *str; + int i; + + len = strlen(yytext); + str = (byte *)malloc(((len+7) >> 3) + 1); + yylval = (int)str; + *str++ = len; + for (i=0; i<((len+7) >> 3); ++i) + str[i] = 0; + for (i=0; i>3] |= (yytext[i] == '0' ? 0 : 1) << (7 - (i&7)); +/* if (debug) + printf("lexer: BitString, length=%d\n", len);*/ +} + +static char lineBuf[500] = ""; +static char *inptr = lineBuf; +static char ungot; +static boolean ungetFlag = FALSE; + +purgeUnget() +{ + ungetFlag = FALSE; +} + +input() +{ + char result; + fileList *oldInputStack; + + if (fredModeLexing) + return(*fredLexString++); + else if (ungetFlag) { + ungetFlag = FALSE; + return(ungot); + } + result = *inptr++; + if (result == '\0') { + if (fgets(lineBuf, 500, currentInput) == NULL) { + result = EOF; + --inptr; + } else { + inptr = lineBuf; +#ifndef FRED + if (indirFile != NULL) + replaceParams(lineBuf); +#endif + result = *inptr++; + } + } + if (result == '\n') + ++currentLineNumber; + else if (result == EOF) { + oldInputStack = inputStack; + inputStack = inputStack->next; + free(oldInputStack); + ungetFlag = FALSE; + if (announceIncludes) { + fprintf(stderr, "<-\n"); + fflush(stderr); + } + fclose(currentInput); + if (inputStack == NULL) { +/* if (debug) printf("in(EOF)\n");*/ + return(0); + } else { + currentInput = inputStack->fyle; + currentFileName = inputStack->saveName; + if (currentInput == NULL) { + if (strcmp(inputStack->saveName, "-") == 0) { + currentInput = stdin; + currentFileName = ""; + } else if ((currentInput = fopen(inputStack-> + saveName, "r")) == NULL) { + systemError("can't open input file %s\n", + inputStack->saveName); + } + inputStack->fyle = currentInput; + } + currentLineNumber = inputStack->saveLine; + return(input()); + } + } +/* if (debug) printf("in(%c)\n", result);*/ + return(result); +} + +unput(c) + char c; +{ +/* if (debug) printf("un(%c)\n", c);*/ + if (fredModeLexing) + --fredLexString; + else { + ungetFlag = TRUE; + ungot = c; + } +} + +static struct { + char *string; + int token; + int minlength; +} keywords[] = { +/*0*/ "a", A, 0, "ava/id", AVAID, 0, +/*2*/ "bin15", BIN15, 0, "bin31", BIN31, 0, +/*4*/ "bit", BIT, 0, "byte", BYTE, 0, +/*6*/ "ch/aracter", CHARACTER, 0, "de/fine", DEFINE, 0, +/*8*/ "endd/efine", ENDDEFINE, 0, "ent/ity", ENTITY, 0, +/*10*/ "fat/word", FATWORD, 0, "include", INCLUDE, 0, +/*12*/ "int/eger", BIN15, 0, "lo/ng", BIN31, 0, +/*14*/ "o", O, 0, "obj/id", OBJID, 0, +/*16*/ "r", R, 0, "reg/id", REGID, 0, +/*18*/ "use", USE, 0, "var/string", VARSTRING, 0, +/*20*/ "wo/rds", WORDS, 0, NULL, 0, 0 +}; + +static int keystart[26] = { + /* a */ 0, /* b */ 2, /* c */ 6, /* d */ 7, /* e */ 8, + /* f */ 10, /* g */ -1, /* h */ -1, /* i */ 11, /* j */ -1, + /* k */ -1, /* l */ 13, /* m */ -1, /* n */ -1, /* o */ 14, + /* p */ -1, /* q */ -1, /* r */ 16, /* s */ -1, /* t */ -1, + /* u */ 18, /* v */ 19, /* w */ 20, /* x */ -1, /* y */ -1, + /* z */ -1 }; +static int keyend[26] = { + /* a */ 1, /* b */ 5, /* c */ 6, /* d */ 7, /* e */ 9, + /* f */ 10, /* g */ -1, /* h */ -1, /* i */ 12, /* j */ -1, + /* k */ -1, /* l */ 13, /* m */ -1, /* n */ -1, /* o */ 15, + /* p */ -1, /* q */ -1, /* r */ 17, /* s */ -1, /* t */ -1, + /* u */ 18, /* v */ 19, /* w */ 20, /* x */ -1, /* y */ -1, + /* z */ -1 }; + + +setKeywordMinlengths() +{ + char *trailer; + char *index(); + int i; + + for (i = 0; keywords[i].string != NULL; ++i) { + trailer = index(keywords[i].string, '/'); + if (trailer == NULL) { + keywords[i].minlength = strlen(keywords[i].string); + } else { + keywords[i].minlength = trailer - keywords[i].string; + strcpy(trailer, trailer + 1); + } + } +} + + int +matchKeyword(s) + char *s; +{ + register int i; + register int firstc; + int len; + + firstc = *s - 'a'; + if (firstc < 0 || 25 < firstc || keystart[firstc] == -1) + return(0); + len = strlen(s); + for (i = keystart[firstc]; i <= keyend[firstc]; ++i) { + if (len >= keywords[i].minlength && + strncmp(s, keywords[i].string, len) == 0) + return(keywords[i].token); + } + return(0); +} diff --git a/mamelink/griddle/main.c b/mamelink/griddle/main.c new file mode 100644 index 0000000..e77d3fd --- /dev/null +++ b/mamelink/griddle/main.c @@ -0,0 +1,355 @@ +/* + griddle -- Ghu's Region Internal Database Description LanguagE + */ + +#include "griddleDefs.h" +int yydebug; + +#define argcheck(i,m) if (++i >= argc) { error(m); exit(1); } +#define argfile(fd,m,t) { \ + fileName = *args++; \ + if (strcmp(fileName, "-") == 0) \ + fd = stdout; \ + else if ((fd = fopen(fileName, t)) == NULL) \ + systemError(m, fileName); \ + } +#define argfiler(fd,m) argfile(fd,m,"r") +#define argfilew(fd,m) argfile(fd,m,"w") + +main(argc, argv) + int argc; + char *argv[]; +{ + int i; + int yyparse(); + boolean initialize(); + + if (!initialize(argc, argv)) + exit(1); +#ifndef FRED + if (indirFile == NULL) + yyparse(); + else + indirectGriddle(); +#else + yyparse(); +#endif + readClassFile(); +#ifndef FRED + while (cvInput != NULL) { + inputContentsVector(cvInput->string); + cvInput = cvInput->nextString; + } + if (cvFile != NULL) + outputContentsVector(); +#else + doFredStuff(); +#endif +} + + void +resetRegionCounters() +{ + int i; + + for (i=0; iname = malloc(strlen(name) + 1); + newSymbol->type = NON_SYM; + newSymbol->codeNumber = 0; + strcpy(newSymbol->name, name); + hashval = hash(name); + mptr = symbolTable[hashval]; + oldmptr = NULL; + while (mptr != NULL) { + if ((cmp = strcmp(name, mptr->name)) == 0) { + error("Hey, symbol %s already in table!", name); + exit(1); + } else if (cmp > 0) { + break; + } else { + oldmptr = mptr; + mptr = mptr->next; + } + } + if (oldmptr == NULL) + symbolTable[hashval] = newSymbol; + else + oldmptr->next = newSymbol; + newSymbol->next = mptr; + return(newSymbol); +} + + symbol * +lookupSymbol(name) + char *name; +{ + symbol *result; + int cmp; + + result = symbolTable[hash(name)]; + while (result != NULL) { + if ((cmp = strcmp(name, result->name)) == 0) + return(result); + else if (cmp > 0) + result = NULL; + else + result = result->next; + } + return(insertSymbol(name)); +} + + void +yyerror(s) + char *s; +{ + error("\"%s\", line %d: %s\n", currentFileName, currentLineNumber, s); +} + + + void +queueInputFile(name) + char *name; +{ + fileList *newFileName; + + newFileName = typeAlloc(fileList); + newFileName->saveName = name; + newFileName->fyle = NULL; + newFileName->next = NULL; + newFileName->saveLine = 1; + if (inputStack == NULL) { + inputStack = bottomOfInputStack = newFileName; + } else { + bottomOfInputStack->next = newFileName; + bottomOfInputStack = newFileName; + } +} + + boolean +openFirstFile(fredMode) + boolean fredMode; +{ + if (inputStack == NULL || strcmp(inputStack->saveName, "-") == 0) { + inputStack = typeAlloc(fileList); + inputStack->saveName = ""; + inputStack->fyle = stdin; + inputStack->saveLine = 1; + inputStack->next = NULL; + } else { + if ((inputStack->fyle = fopen(inputStack->saveName, + "r")) == NULL) { + if (!fredMode) + error("can't open input file %s\n", + inputStack->saveName); + free(inputStack); + inputStack = NULL; + return(FALSE); + } + } + currentInput = inputStack->fyle; + currentLineNumber = inputStack->saveLine; + currentFileName = inputStack->saveName; + purgeUnget(); + return(TRUE); +} + +error(msg, arg1, arg2, arg3) + char *msg; + int arg1, arg2, arg3; +{ + fprintf(stderr, "error: "); + fprintf(stderr, msg, arg1, arg2, arg3); +} + +systemError(msg, arg1, arg2, arg3) + char *msg; + int arg1, arg2, arg3; +{ + error(msg, arg1, arg2, arg3); + perror("Unix says"); + exit(1); +} + + void +translate(s, c1, c2) + char *s; + char c1; + char c2; +{ + for (; *s != '\0'; ++s) + if (*s == c1) + *s = c2; +} + + char * +saveString(s) + char *s; +{ + char *result; + + result = (char *)malloc(strlen(s) + 1); + strcpy(result, s); + return(result); +} diff --git a/mamelink/griddle/prot.h b/mamelink/griddle/prot.h new file mode 100644 index 0000000..05fa69f --- /dev/null +++ b/mamelink/griddle/prot.h @@ -0,0 +1,41 @@ + +extern char readc(); +#define SC 033 +#define REPLY 0 +#define STORE 1 +#define LOW 2 +#define HIGH 3 +#define JUMP 4 +#define LOAD 5 +#define BADREPLY 6 +#define CONT 7 +#define HALTMAIN 8 +#define HALTALL 9 +#define HALTCONT 10 +#define JUMPSUB 11 +#define RESET 12 + +typedef int Boolean; +typedef struct +{ + byte portB; + byte portA; + byte control; + byte portC; +} Port; + +extern Port *portopen(); +#define CLOWIN 1 +#define CLOWOUT 0 +#define BIN 02 +#define BOUT 0 +#define AIN 0x10 +#define AOUT 0 +#define CUPOUT 0 +#define CUPIN 08 +#define BMODE0 0 +#define AMODE0 0 +#define MODESET 0x80 + +#define NCARDS 3 +#define PADDR { 0x70l, 0x60l } diff --git a/mamelink/griddle/reno.out b/mamelink/griddle/reno.out new file mode 100644 index 0000000000000000000000000000000000000000..42e07c4b3f0d280e6b04e71e6cb06889a3e7ead7 GIT binary patch literal 32028 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 VNZ=O<{33y0B=Cy_{ufH%{{eC?%3%Ni literal 0 HcmV?d00001 diff --git a/mamelink/griddle/util/dumpfstats.c b/mamelink/griddle/util/dumpfstats.c new file mode 100644 index 0000000..81657dc --- /dev/null +++ b/mamelink/griddle/util/dumpfstats.c @@ -0,0 +1,69 @@ +#include + +int fredStats[128]; + + char * +keyName(key) + char key; +{ + static char result[10]; + int i; + static struct { + char key; + char *name; + } keyList[] = { + ' ', "SPACE", '\b', "BACKSPACE", + '\t', "TAB", '\n', "LINE FEED", + '\r', "RETURN", '\33', "ESC", + '\177', "DEL" + }; + + if ('!' <= key && key <= '~') { + sprintf(result, "%c", key); + return(result); + } + for (i=0; keyList[i].key != '\0'; ++i) + if (keyList[i].key == key) + return(keyList[i].name); + if (key < ' ') { + sprintf(result, "^%c", key + 0x40); + return(result); + } + sprintf(result, "\\%o", key); + return(result); +} + + void +readFredStats(argc, argv) + int argc; + char *argv[]; +{ + FILE *statFyle; + int i; + char temp[256]; + + if (argc > 1) + sprintf(temp, "%s/u0/habitat/fredStats", argv[1]); + else + strcpy(temp, "/u0/habitat/fredStats"); + if ((statFyle = fopen(temp, "r")) != NULL) { + for (i=0; i<128; ++i) + fredStats[i] = getw(statFyle); + fclose(statFyle); + } + if (statFyle == NULL || feof(statFyle)) { + for (i=0; i<128; ++i) + fredStats[i] = 0; + } +} + +main(argc, argv) + int argc; + char *argv[]; +{ + int i; + + readFredStats(argc, argv); + for (i=0; i<128; ++i) + printf("%s -- %d\n", keyName(i), fredStats[i]); +} diff --git a/mamelink/griddle/util/flushfstats.c b/mamelink/griddle/util/flushfstats.c new file mode 100644 index 0000000..23b3584 --- /dev/null +++ b/mamelink/griddle/util/flushfstats.c @@ -0,0 +1,14 @@ +#include + +main() +{ + FILE *statFyle; + int i; + + if ((statFyle = fopen("/u0/habitat/fredStats", "w")) != NULL) { + for (i=0; i<128; ++i) + putw(0, statFyle); + fclose(statFyle); + } else + fprintf(stderr, "couldn't open stat file!\n"); +} diff --git a/mamelink/griddle/util/shorten.c b/mamelink/griddle/util/shorten.c new file mode 100644 index 0000000..e740114 --- /dev/null +++ b/mamelink/griddle/util/shorten.c @@ -0,0 +1,19 @@ +#include + +main() +{ + char c; + int i; + + i = 0; + while ((c = getchar()) != EOF) { + putchar(c); + if (c == '\n') + i = 0; + else if (++i > 78) { + putchar('\\'); + putchar('\n'); + i = 0; + } + } +} diff --git a/mamelink/griddle/util/trunc.c b/mamelink/griddle/util/trunc.c new file mode 100644 index 0000000..3b8184b --- /dev/null +++ b/mamelink/griddle/util/trunc.c @@ -0,0 +1,19 @@ +#include + +main(argc, argv) + int argc; + char *argv[]; +{ + int limit; + int count; + char c; + + limit = atoi(argv[1]); + count = 0; + while ((c = getchar()) != EOF) { + if (count++ < limit || c == '\n') + putchar(c); + if (c == '\n') + count = 0; + } +}