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 0000000..42e07c4 Binary files /dev/null and b/mamelink/griddle/reno.out differ 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; + } +}