Clean commit of historical griddle / fred source

This commit is contained in:
Jeremy Penner 2024-01-02 19:43:12 -05:00
parent 8a64fe3496
commit 70f2d0338a
24 changed files with 6287 additions and 0 deletions

View file

@ -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

23
mamelink/griddle/DOC Normal file
View file

@ -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.

84
mamelink/griddle/Makefile Normal file
View file

@ -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

50
mamelink/griddle/alloc.c Normal file
View file

@ -0,0 +1,50 @@
#include <stdio.h>
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]);
}

199
mamelink/griddle/build.c Normal file
View file

@ -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);
}

346
mamelink/griddle/cv.c Normal file
View file

@ -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; i<CLASS_MAX; ++i)
classSize[i] = readWord(classFyle);
for (i=0; i<CLASS_MAX; ++i)
if (classSize[i] == 0xFFFF)
classSize[i] = 0;
else {
fseek(classFyle, classSize[i]+SIZE_OFFSET, 0);
classSize[i] = (readByte(classFyle) & 0x7F) - 6;
}
fclose(classFyle);
}
void
cvNoidClass()
{
int i;
for (i=1; i<objectCount; ++i) {
if (noidArray[i] != NULL) {
cvByte(i);
cvByte(noidArray[i]->class);
}
}
}
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; i<AVATAR_PROPERTY_COUNT; ++i)
cvByte(getWord(buf, PROP_BASE_AVA + i*2));
} else {
container = getLong(buf, CONTAINER_OFFSET_OBJ);
if (container != 0 && (container < -1000-MAXNOID ||
-1000 <= container)) {
error("specified object container out of range\n");
return;
}
cvByte(getWord(buf, STYLE_OFFSET_OBJ));
cvByte(getWord(buf, X_OFFSET_OBJ));
cvByte(getWord(buf, Y_OFFSET_OBJ));
cvByte(getWord(buf, ORIENT_OFFSET_OBJ));
cvByte(getWord(buf, GRSTATE_OFFSET_OBJ));
if (container == 0)
cvByte(0);
else
cvByte(-container-1001);
for (i=0; i<classSize[class]; ++i)
cvByte(getWord(buf, objectBase + i*2));
}
}
void
cvProps()
{
int i;
for (i=1; i<objectCount; ++i)
if (noidArray[i] != NULL)
cvProperties(noidArray[i]->class, 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; i<objectCount; ++i) {
if (noidArray[i] != NULL && noidArray[i]->class == 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; i<AVATAR_PROPERTY_COUNT; ++i)
fillWord(buf, PROP_BASE_AVA + i*2, readByte(cvFyle));
} else {
fillWord(buf, STYLE_OFFSET_OBJ, readByte(cvFyle));
fillWord(buf, X_OFFSET_OBJ, readByte(cvFyle));
fillWord(buf, Y_OFFSET_OBJ, readByte(cvFyle));
fillWord(buf, ORIENT_OFFSET_OBJ, readByte(cvFyle));
fillWord(buf, GRSTATE_OFFSET_OBJ, readByte(cvFyle));
container = getLong(inNoid[readByte(cvFyle)]->stateVector, 0);
fillLong(buf, CONTAINER_OFFSET_OBJ, container);
for (i=0; i<classSize[class]; ++i)
fillWord(buf, objectBase + i*2, readByte(cvFyle));
}
}
void
inputContentsVector(filename)
char *filename;
{
int i;
int noid;
int class;
int highNoid;
int noidBase;
byte noidMap[MAXNOID];
object *initObject();
if ((cvFyle = fopen(filename, "r")) == NULL) {
error("can't open contents vector input file '%s'\n",
filename);
return;
}
for (i=0; i<MAXNOID; ++i)
inNoid[i] = NULL;
noidMap[0] = 0;
inNoid[0] = initObject(0, -globalIdCounter++);
noidBase = 1;
do {
for (highNoid=noidBase; (noid = readByte(cvFyle)) != 0; ++highNoid) {
class = readByte(cvFyle);
noidMap[highNoid] = noid;
inNoid[noid] = initObject(class, -globalIdCounter++);
}
for (i=noidBase; i<highNoid; ++i)
fillFromCvFile(inNoid[noidMap[i]]);
for (i=0; i<highNoid; ++i) {
if (objectCount < MAXNOID)
noidArray[objectCount++] = inNoid[noidMap[i]];
if (griFile != NULL)
dumpObject(inNoid[noidMap[i]]);
if (rawFile != NULL)
outputRawObject(inNoid[noidMap[i]]);
}
noidBase = 0;
} while (readByte(cvFyle) != 0 && !feof(cvFyle));
fclose(cvFyle);
}
int
deCvNoidClass(offset)
int offset;
{
int i;
for (; cv[offset] != 0; offset += 2)
;
return(offset + 1);
}
int
deCvProperties(class, buf, offset)
int class;
byte *buf;
int offset;
{
int i;
if (class == 0) {
fillWord(buf, LIGHTLEVEL_OFFSET_REG, cv[offset + 1]);
fillWord(buf, DEPTH_OFFSET_REG, cv[offset + 2]);
fillWord(buf, CLASSGROUP_OFFSET_REG, cv[offset + 3]);
return(9);
} else if (class == 1) {
fillByte(buf, STYLE_OFFSET_AVA, cv[offset + 0]);
fillWord(buf, X_OFFSET_AVA, cv[offset + 1]);
fillWord(buf, Y_OFFSET_AVA, cv[offset + 2]);
fillWord(buf, ORIENT_OFFSET_AVA, cv[offset + 3]);
fillWord(buf, GRSTATE_OFFSET_AVA, cv[offset + 4]);
if (cv[offset + 5] == 0)
fillLong(buf, CONTAINER_OFFSET_AVA, 0);
else
fillLong(buf, CONTAINER_OFFSET_AVA, -1001-cv[offset+5]);
for (i=0; i<AVATAR_PROPERTY_COUNT; ++i)
fillWord(buf, PROP_BASE_AVA + i*2, cv[offset + 6+i]);
return(6 + AVATAR_PROPERTY_COUNT);
} else {
fillWord(buf, STYLE_OFFSET_OBJ, cv[offset + 0]);
fillWord(buf, X_OFFSET_OBJ, cv[offset + 1]);
fillWord(buf, Y_OFFSET_OBJ, cv[offset + 2]);
fillWord(buf, ORIENT_OFFSET_OBJ, cv[offset + 3]);
fillWord(buf, GRSTATE_OFFSET_OBJ, cv[offset + 4]);
fillLong(buf, CONTAINER_OFFSET_OBJ, -1001-cv[offset + 5]);
for (i=0; i<classSize[class]; ++i)
fillWord(buf, objectBase + i*2, cv[offset + 6 + i]);
return(6 + classSize[class]);
}
}
int
deCvProps(noidOffset, stateOffset)
int noidOffset;
int stateOffset;
{
int noid;
while ((noid = cv[noidOffset]) != 0) {
if (cv[noidOffset + 1] != noidArray[noid]->class) {
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; noid<MAXNOID; ++noid)
noidAlive[noid] = FALSE;
offset = 0;
while ((offset = deCvProps(offset, deCvNoidClass(offset))) != 0)
;
for (noid=1; noid<MAXNOID; ++noid)
if (!noidAlive[noid] && noidArray[noid] != NULL) {
freeObject(noidArray[noid]);
noidArray[noid] = NULL;
}
}

170
mamelink/griddle/debug.c Normal file
View file

@ -0,0 +1,170 @@
#include "griddleDefs.h"
int
getByte(buf, offset)
byte *buf;
int offset;
{
return((char)buf[offset]);
}
int
getWord(buf, offset)
byte *buf;
int offset;
{
return((short)( buf[offset ] * 256 +
buf[offset + 1] ));
}
int
getLong(buf, offset)
byte *buf;
int offset;
{
return( buf[offset ] * 256 * 256 * 256 +
buf[offset + 1] * 256 * 256 +
buf[offset + 2] * 256 +
buf[offset + 3] );
}
char
contCode(ctype)
int ctype;
{
if (ctype == 0) return('r');
else if (ctype == 1) return('a');
else /* if (ctype == 2) */ return('o');
}
void
dumpField(aField, buf)
field *aField;
byte *buf;
{
char str[512];
if (fieldString(aField, buf, str))
fprintf(griFile, " %s\n", str);
}
boolean
fieldString(aField, buf, str)
field *aField;
byte *buf;
char *str;
{
int i;
int offset, bitOffset;
int val;
char *escape();
char temp[80];
if (aField->invisible) {
*str = '\0';
return(FALSE);
}
sprintf(str, "%s: ", aField->name->name);
offset = aField->offset & 0x3FFF;
bitOffset = aField->offset >> 14;
for (i=0; i<aField->dimension; ++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");
}

771
mamelink/griddle/exec.c Normal file
View file

@ -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; i<aField->dimension; ++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 (; i<aField->dimension && string != NULL
&& string[i] != '\0'; ++i)
fillWord(buf, offset + i*2, string[i]);
for (; i<aField->dimension; ++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 (; i<aField->dimension && string != NULL
&& string[i] != '\0'; ++i)
fillByte(buf, offset + i, string[i]);
for (; i<aField->dimension; ++i)
fillByte(buf, offset + i, ' ');
freeValue(string);
Case FIELD_VARSTRING:
string = (*nextString)(&data);
if (string != NULL) {
len = strlen(string);
fillWord(buf, offset, len);
for (; i<aField->dimension && 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; i<aField->dimension; ++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; i<classDefs[class+1]->size; ++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; i<classDefs[obj->class+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; i<aField->dimension; ++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; i<objectCount; ++i)
altNoidArray[i] = noidArray[i];
if (sortObjects)
qsort(altNoidArray, objectCount, sizeof(object *),
cmpObjects);
for (i=0; i<objectCount; ++i)
replaceIndirectArgs(altNoidArray[i], i);
}
sortObjects = FALSE;
#endif
for (i=0; i<objectCount; ++i) {
#ifndef FRED
if (griFile != NULL && indirectPass != 1)
dumpObject(noidArray[i]);
if (rawFile != NULL && indirectPass != 1)
outputRawObject(noidArray[i]);
#endif
freeObject(noidArray[i]);
}
objectCount = 0;
}
freeObject(obj)
object *obj;
{
free(obj->stateVector);
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);
}

252
mamelink/griddle/expr.c Normal file
View file

@ -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; i<len; ++i)
if ('0' <= name[i] && name[i] <= '9')
result = result * 10 + name[i] - '0';
else
return(NULL);
if (name[0] == 'r')
return(buildValue(VAL_REGION, result));
else if (name[0] == 'o')
return(buildValue(VAL_OBJECT, result));
else if (name[0] == 'a')
return(buildValue(VAL_AVATAR, result));
else
return(NULL);
}
#endif
value *
evaluateName(name)
symbol *name;
{
value *buildNumber();
value *buildValue();
value *result;
switch(name->type) {
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);
}
}

900
mamelink/griddle/fred.c Normal file
View file

@ -0,0 +1,900 @@
#include <curses.h>
#include <signal.h>
#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; i<classDefs[class+1]->size; ++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; i<objectCount; ++i)
if (noidArray[i] != NULL) {
mvprintw(line, col, "%3d %s", i,
classDefs[noidArray[i]->class+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<regionSize; ++i)
cv[i] = *p++;
}
boolean
quit()
{
echoLine("quit");
clearDisplay();
refresh();
writeFredStats();
return(FALSE);
}
void
setupFastlinkPort()
{
char *portstr;
portstr = getenv("FASTPORT");
if (portstr != NULL) {
if (strlen(portstr) < 3) {
error("FASTPORT env variable must be of form: c;p\n");
exit(1);
} else {
card = portstr[0] - '0';
port = portstr[2] - '0';
}
}
if (card < 0 || NCARDS <= card) {
error("card number out of range\n");
exit(1);
}
if (port < 0 || 2 < port) {
error("port number out of range\n");
exit(1);
}
if (!testMode && !Init(card, port)) {
error("unable to access device\n");
Finish();
exit(1);
}
}
void
doFredStuff()
{
char *pathstr;
FILE *fyle;
pathname[0] = '\0';
if ((pathstr = getenv("FREDPATH")) != NULL)
strcpy(pathname, pathstr);
readFredStats();
readPathlist();
if (!testMode)
setupFastlinkPort();
setupTerminal();
displayNoid = 0;
undeleteBuffer = NULL;
previousClass = 2;
strcpy(regionName, "/u0/habitat/empty.raw");
echoLine("Fred version 1.0 (%s) -- type 'h' for help", DATE);
while (processCommand())
;
refresh();
endwin();
}
boolean
initC64editor()
{
/* system("down -S < /u0/aric/mic/Gr/all.out");*/
system("down -S < /u0/habitat/reno.out");
/* system("down -S < /u0/chip/reno.out");*/
return(TRUE);
}
boolean
sh()
{
char commandBuf[80];
int y, x;
if (!getString(":", commandBuf)) {
echoLine("aborted");
return(TRUE);
}
getyx(curscr, y, x);
clearDisplay();
move(1, 0);
refresh();
echo(); noraw(); nl();
system(commandBuf);
noecho(); raw(); nonl();
move(1, 47);
refresh();
echoLine("unix command:%s", commandBuf);
refresh();
return(TRUE);
}
boolean
loadRegion()
{
if (!getRegionName())
echoLine("aborted");
else if (readRegion() && generateContentsVector()) {
displayRegion();
echoLine("loaded %s", regionName);
}
return(TRUE);
}
boolean
saveRaw()
{
if (!getRegionName())
echoLine("aborted");
else {
if (!testMode) {
snarfRegion();
degenerateContentsVector();
}
if (writeRegionRaw())
echoLine("saved raw file %s", regionName);
}
return(TRUE);
}
boolean
saveGriddle()
{
if (!getRegionName())
echoLine("aborted");
else {
if (!testMode) {
snarfRegion();
degenerateContentsVector();
}
if (writeRegionGriddle())
echoLine("saved griddle file %s", regionName);
}
return(TRUE);
}
boolean
processCommand()
{
char c;
int i;
static char previousC = '\0';
if (previousC != '\r' && previousC != '\32')
addstr(" -- Next?");
refresh();
c = mygetch();
for (i=0; commandTable[i].commandKey != '\0'; ++i)
if (commandTable[i].commandKey == c) {
if (c != '\r' && c != '\32')
echoLine(commandTable[i].echoName);
fredStats[c]++;
previousC = c;
return (*(commandTable[i].commandFunction))();
}
lineError("'%s' is not a Fred command", keyName(c));
previousC = c;
return(TRUE);
}
boolean
pauseFred()
{
echo(); noraw(); nl();
kill(0, SIGTSTP);
noecho(); raw(); nonl();
move(1, 47);
refresh();
reallyClearScreen();
return(TRUE);
}
boolean
refreshScreen()
{
reallyClearScreen();
c64_key_command('r');
return(TRUE);
}

602
mamelink/griddle/fred2.c Normal file
View file

@ -0,0 +1,602 @@
#include <curses.h>
#include "griddleDefs.h"
#include <sys/types.h>
#include <sys/stat.h>
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; i<objectCount; ++i)
outputRawObject(noidArray[i]);
fclose(rawFile);
rawFile = NULL;
return(TRUE);
} else {
lineError("can't open '%s'", regionFileName);
return(FALSE);
}
}
boolean
writeRegionGriddle()
{
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 ((griFile = fopen(regionFileName, "w")) != NULL) {
for (i=0; i<objectCount; ++i)
dumpObject(noidArray[i]);
fclose(griFile);
griFile = NULL;
return(TRUE);
} else {
lineError("can't open '%s'", regionFileName);
return(FALSE);
}
}
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);
}
int
nextFreeNoid()
{
int noid;
for (noid=0; noid<objectCount; ++noid)
if (noidArray[noid] == NULL)
break;
if (noid == objectCount)
++objectCount;
return(noid);
}
void
announceObject(noid, class)
int noid;
int class;
{
byte createPacket[7];
byte *buf;
void mydown();
if (class == 0)
return;
buf = noidArray[noid]->stateVector;
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);
}

350
mamelink/griddle/fscreen.c Normal file
View file

@ -0,0 +1,350 @@
#include <curses.h>
#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<len; ++i) {
if ((i & 7) == 0) mvprintw(line, 0, "0x%04x: ", i);
printw("0x%02x ", buf[i]);
if ((i & 7) == 7) ++line;
if (line == LINES-1) {
mvprintw(line, 0, "--more--");
refresh();
mygetch();
clearDisplay();
line = 1;
}
}
}
WINDOW *clearWindow;
void
setupTerminal()
{
WINDOW *newwin();
initscr();
noecho();
raw();
nonl();
erase();
refresh();
clearWindow = newwin(0, 0, 0, 0);
}
void
reallyClearScreen()
{
touchwin(clearWindow);
wrefresh(clearWindow);
touchwin(stdscr);
refresh();
}

535
mamelink/griddle/griddle.c Normal file
View file

@ -0,0 +1,535 @@
# line 2 "griddle.y"
#include "griddleDefs.h"
# define Name 257
# define Number 258
# define String 259
# define BitString 260
# define Rawline 261
# define INCLUDE 262
# define DEFINE 263
# define ENDDEFINE 264
# define USE 265
# define AVAID 266
# define BIN15 267
# define BIN31 268
# define BIT 269
# define BYTE 270
# define CHARACTER 271
# define ENTITY 272
# define FATWORD 273
# define OBJID 274
# define REGID 275
# define VARSTRING 276
# define WORDS 277
# define A 278
# define O 279
# define R 280
# define OR 281
# define XOR 282
# define AND 283
# define ADD 284
# define SUB 285
# define MUL 286
# define DIV 287
# define MOD 288
# define UMINUS 289
# define NOT 290
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern short yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
YYSTYPE yylval, yyval;
# define YYERRCODE 256
short yyexca[] ={
-1, 1,
0, -1,
-2, 0,
};
# define YYNPROD 60
# define YYLAST 287
short yyact[]={
21, 73, 29, 36, 37, 35, 30, 31, 32, 33,
34, 95, 37, 35, 30, 31, 32, 33, 34, 62,
32, 33, 34, 15, 36, 37, 35, 30, 31, 32,
33, 34, 35, 30, 31, 32, 33, 34, 30, 31,
32, 33, 34, 85, 79, 80, 81, 88, 78, 87,
86, 84, 83, 89, 82, 8, 52, 52, 96, 12,
9, 10, 74, 11, 67, 53, 27, 46, 102, 93,
77, 46, 65, 92, 94, 14, 99, 66, 76, 72,
16, 51, 50, 45, 28, 97, 2, 48, 13, 7,
6, 38, 39, 40, 41, 42, 43, 71, 5, 4,
54, 55, 56, 57, 58, 59, 60, 61, 3, 1,
0, 0, 0, 0, 0, 0, 64, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 63, 47,
0, 69, 0, 47, 70, 0, 0, 0, 0, 0,
0, 0, 90, 75, 0, 0, 91, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 36,
37, 35, 30, 31, 32, 33, 34, 100, 98, 75,
101, 0, 0, 0, 0, 0, 103, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67, 0, 0, 0, 67, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 17, 18, 19,
20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 24, 25,
26, 0, 0, 0, 0, 22, 0, 0, 0, 0,
23, 36, 37, 35, 30, 31, 32, 33, 34, 36,
37, 35, 30, 31, 32, 33, 34, 44, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 53, 53,
0, 0, 0, 0, 0, 68, 49 };
short yypact[]={
-202,-202,-1000,-1000,-1000,-1000,-1000,-1000, 14,-236,
-40,-191,-1000,-1000, -40,-1000,-257,-1000,-1000,-1000,
-1000, -40, -40, -40, -40, -40, -40, 10,-278, 22,
-40, -40, -40, -40, -40, -40, -40, -40, -22,-1000,
-1000,-278,-278,-278, 6,-1000, -40,-193, 21,-1000,
-1000,-1000,-192, 39,-266,-266,-1000,-1000,-1000,-246,
-270,-251,-1000,-1000,-122, -63,-1000, 20,-1000,-1000,
-1000,-223, -40,-193,-1000,-1000, -40, 13,-1000,-1000,
-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
-30, -67, 41,-278, -40, 18,-1000, -40, 41,-223,
-278, 7, -40, 41 };
short yypgo[]={
0, 109, 86, 108, 99, 98, 90, 89, 69, 87,
82, 81, 70, 73, 83, 72, 77 };
short yyr1[]={
0, 1, 1, 2, 2, 2, 2, 2, 7, 3,
4, 5, 5, 9, 9, 10, 10, 11, 11, 11,
11, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 6, 6, 14, 14, 15, 15, 16,
13, 13, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
short yyr2[]={
0, 1, 2, 1, 1, 1, 1, 1, 1, 3,
2, 5, 4, 1, 2, 1, 2, 3, 6, 5,
8, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 4, 3, 5, 3, 1, 2, 3,
1, 3, 1, 1, 1, 1, 3, 2, 2, 2,
2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
short yychk[]={
-1000, -1, -2, -3, -4, -5, -6, -7, 257, 262,
263, 265, 261, -2, 61, 259, -8, 257, 258, 259,
260, 40, 285, 290, 278, 279, 280, 257, -8, 259,
284, 285, 286, 287, 288, 283, 281, 282, -8, -8,
-8, -8, -8, -8, 257, -14, 61, 123, -9, 264,
-10, -11, 35, 257, -8, -8, -8, -8, -8, -8,
-8, -8, 41, -14, -8, -15, -16, 257, 264, -10,
-11, 58, 40, 123, 125, -16, 58, -12, 271, 267,
268, 269, 277, 275, 274, 266, 273, 272, 270, 276,
-8, -15, -13, -8, 61, 41, 125, 44, -13, 58,
-8, -12, 61, -13 };
short yydef[]={
0, -2, 1, 3, 4, 5, 6, 7, 0, 0,
0, 0, 8, 2, 0, 10, 0, 42, 43, 44,
45, 0, 0, 0, 0, 0, 0, 0, 9, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 47,
48, 49, 50, 51, 0, 34, 0, 0, 0, 12,
13, 15, 0, 0, 52, 53, 54, 55, 56, 57,
58, 59, 46, 33, 0, 0, 37, 0, 11, 14,
16, 0, 0, 0, 36, 38, 0, 17, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
0, 0, 39, 40, 0, 0, 35, 0, 19, 0,
41, 18, 0, 20 };
#ifndef lint
static char yaccpar_sccsid[] = "@(#)yaccpar 1.1 83/07/20 SMI"; /* from UCB 4.1 83/02/11 */
#endif
#
# define YYFLAG -1000
# define YYERROR goto yyerrlab
# define YYACCEPT return(0)
# define YYABORT return(1)
/* parser for yacc output */
#ifdef YYDEBUG
int yydebug = 0; /* 1 for debugging */
#endif
YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
int yychar = -1; /* current input token number */
int yynerrs = 0; /* number of errors */
short yyerrflag = 0; /* error recovery flag */
yyparse() {
short yys[YYMAXDEPTH];
short yyj, yym;
register YYSTYPE *yypvt;
register short yystate, *yyps, yyn;
register YYSTYPE *yypv;
register short *yyxi;
yystate = 0;
yychar = -1;
yynerrs = 0;
yyerrflag = 0;
yyps= &yys[-1];
yypv= &yyv[-1];
yystack: /* put a state and value onto the stack */
#ifdef YYDEBUG
if( yydebug ) printf( "state %d, char 0%o\n", yystate, yychar );
#endif
if( ++yyps> &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 */
}

245
mamelink/griddle/griddle.y Normal file
View file

@ -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);
}
;

View file

@ -0,0 +1,298 @@
#include <stdio.h>
#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;

344
mamelink/griddle/indir.c Normal file
View file

@ -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; i<multiCount; ++i)
(*multiptr)[i] = multiArray[i];
*countptr = multiCount;
}
return(args + 1);
} else {
args = scan_number(args, resultptr);
if (multiOK) {
*multiptr = typeAlloc(int);
(*multiptr)[0] = *resultptr;
*countptr = 1;
}
return(args);
}
}
void
scanIndirectFilePass1()
{
char line[MAXLINE];
char *argptr;
char *iptr;
char *index();
char *skipArg();
boolean stringFlag;
int rot;
indirRegion = 0;
indirectPass = 1;
while (fgets(line, MAXLINE, indirFile) != NULL) {
iptr = indirName;
argptr = line;
while (*argptr != ' ')
*iptr++ = *argptr++;
*iptr = '\0';
argptr += 3;
argptr = scan_number(argptr, &rot);
indirTable[indirRegion].rot = rot;
argptr = scan_connections(argptr + 3, rot == 0,
&indirTable[indirRegion].west,
&indirTable[indirRegion].multi,
&indirTable[indirRegion].multiCount);
argptr = scan_connections(argptr + 3, rot == 1,
&indirTable[indirRegion].north,
&indirTable[indirRegion].multi,
&indirTable[indirRegion].multiCount);
argptr = scan_connections(argptr + 3, rot == 2,
&indirTable[indirRegion].east,
&indirTable[indirRegion].multi,
&indirTable[indirRegion].multiCount);
argptr = scan_connections(argptr + 3, rot == 3,
&indirTable[indirRegion].south,
&indirTable[indirRegion].multi,
&indirTable[indirRegion].multiCount);
argptr = index(argptr, '/') + 1;
indirArgc = 0;
while (argptr != NULL && *argptr != '\0' && *argptr != '\n') {
while (*argptr == ' ')
++argptr;
if (stringFlag = (*argptr == '"'))
++argptr;
indirArgv[indirArgc++] = argptr;
argptr = skipArg(argptr, stringFlag);
if (argptr != NULL)
*argptr++ = '\0';
}
queueInputFile(strcat(indirName, ".gri"));
if (!openFirstFile(FALSE)) {
error("can't continue from here!");
exit(1);
}
globalIdAdjustment = globalIdCounter - 1001;
yyparse();
++indirRegion;
}
}
void
scanIndirectFilePass2()
{
char line[MAXLINE];
char *argptr;
char *iptr;
char *index();
char *skipArg();
boolean stringFlag;
int dummy;
indirRegion = 0;
indirectPass = 2;
globalIdCounter = 1001;
while (fgets(line, MAXLINE, indirFile) != NULL) {
iptr = indirName;
argptr = line;
while (*argptr != ' ')
*iptr++ = *argptr++;
*iptr = '\0';
argptr += 3;
argptr = scan_number(argptr, &dummy);
argptr = scan_connections(argptr, FALSE, &dummy, NULL,&dummy);
argptr = scan_connections(argptr, FALSE, &dummy, NULL,&dummy);
argptr = scan_connections(argptr, FALSE, &dummy, NULL,&dummy);
argptr = scan_connections(argptr, FALSE, &dummy, NULL,&dummy);
argptr = index(argptr, '/') + 1;
indirArgc = 0;
while (argptr != NULL && *argptr != '\0' && *argptr != '\n') {
while (*argptr == ' ')
++argptr;
if (stringFlag = (*argptr == '"'))
++argptr;
indirArgv[indirArgc++] = argptr;
argptr = skipArg(argptr, stringFlag);
if (argptr != NULL)
*argptr++ = '\0';
}
queueInputFile(strcat(indirName, ".gri"));
if (!openFirstFile(FALSE)) {
error("can't continue from here!");
exit(1);
}
globalIdAdjustment = globalIdCounter - 1001;
yyparse();
++indirRegion;
}
}
void
replaceIndirectArgs(obj, index)
object *obj;
int index;
{
int i;
byte *buf;
int reg;
reg = indirRegion - 1;
buf = obj->stateVector;
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<width && *argptr!='\0'; ++i)
*outptr++ = *argptr++;
for (; i<width; ++i)
*outptr++ = ' ';
}
}
} else {
if (*inptr == '\\') {
++inptr;
if (*inptr != '`')
*outptr++ = '\\';
}
*outptr++ = *inptr++;
}
}
*outptr = '\0';
strcpy(line, scratchBuf);
}
int
scanNumber(lineptr)
char **lineptr;
{
int result;
char *line;
result = 0;
line = *lineptr + 1;
while ('0' <= *line && *line <= '9')
result = result * 10 + *line++ - '0';
*lineptr = line;
return(result - 1);
}
void
indirectGriddle()
{
char line[80];
int i;
fgets(line, 80, indirFile);
sscanf(line, "%d", &indirCount);
indirTable = typeAllocMulti(indirectEntry, indirCount);
scanIndirectFilePass1();
rewind(indirFile);
flushNoidArray();
fgets(line, 80, indirFile);
scanIndirectFilePass2();
flushNoidArray();
}

594
mamelink/griddle/lexer.c Normal file
View file

@ -0,0 +1,594 @@
#include "griddleDefs.h"
#include "y.tab.h"
extern int yylval;
int yydebug;
typedef enum {
C_SKIP, C_ZERO, C_DIG, C_ALPH, C_QUOTE, C_APOSTROPHE, C_LIT, C_SLASH,
C_NL
} charType;
static charType char_type[128] = {
/* EOF Soh Stx Etx Eot Enq Ack Bell */
/* 0 */ C_LIT, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP,
/* Backsp HTab Newline VTab Newpage Return So Si */
/* 8 */ C_SKIP, C_SKIP, C_NL, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP,
/* Dle Dc1 Dc2 Dc3 Dc4 Nak Syn Etb */
/* 16 */ C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP,
/* Can Em Sub Escape Fs Gs Rs Us */
/* 24 */ C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP, C_SKIP,
/* Space ! " # $ % & ' */
/* 32 */ C_SKIP, C_SKIP, C_QUOTE, C_LIT, C_SKIP, C_LIT, C_LIT, C_APOSTROPHE,
/* ( ) * + , - . / */
/* 40 */ C_LIT, C_LIT, C_LIT, C_LIT, C_LIT, C_LIT, C_SKIP, C_SLASH,
/* 0 1 2 3 4 5 6 7 */
/* 48 */ C_DIG, C_DIG, C_DIG, C_DIG, C_DIG, C_DIG, C_DIG, C_DIG,
/* 8 9 : ; < = > ? */
/* 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<size; ++i) {
aByte = getHexByte();
if (aByte < 0) break;
buf[i] = aByte;
}
if (aByte < 0) {
error("raw line short\n");
for (; i<size; ++i)
buf[i] = 0;
} else if (getHexByte() >= 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<len; ++i)
str[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 = "<standard input>";
} 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);
}

355
mamelink/griddle/main.c Normal file
View file

@ -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; i<objectCount; ++i) {
if (noidArray[i] != NULL) {
freeObject(noidArray[i]);
noidArray[i] = NULL;
}
}
globalIdCounter = 1001;
objectCount = 0;
rawCount = 0;
useStartCount = 0;
}
boolean
initialize(argc, argv)
int argc;
char *argv[];
{
int i;
int j;
char **args;
char *arg;
boolean inputFilesGiven;
char *defineFileName;
char *fileName;
char *getenv();
void queueInputFile();
boolean openFirstFile();
stringList *buildStringList();
griFile = NULL;
rawFile = NULL;
indirFile = NULL;
cvFile = NULL;
cvInput = NULL;
fredModeLexing = FALSE;
debug = FALSE;
yydebug = FALSE;
testMode = FALSE;
objectBase = 0;
sortObjects = FALSE;
insideDefinition = FALSE;
objectCount = 0;
resetRegionCounters();
inputStack = NULL;
announceIncludes = FALSE;
inputFilesGiven = FALSE;
assignRelativeIds = FALSE;
indirectPass = 0;
setKeywordMinlengths();
for (i=0; i<MAXCLASS+1; ++i)
classDefs[i] = NULL;
args = argv + 1;
if ((defineFileName = getenv("GHUDEFINES")) == NULL)
queueInputFile("/u0/habitat/defines.ghu");
else
queueInputFile(defineFileName);
if ((classFileName = getenv("CLASSINFO")) == NULL)
classFileName = "/u0/habitat/class.dat";
for (i=1; i<argc; i++) {
arg = *args++;
if (*arg != '-') {
#ifndef FRED
queueInputFile(arg);
inputFilesGiven = TRUE;
continue;
#else
error("illegal parameter '%s'\n", arg);
exit(1);
#endif
}
for (j=1; arg[j]!='\0'; j++) switch (arg[j]) {
case 'D':
debug = TRUE;
continue;
case 'I':
announceIncludes = TRUE;
continue;
case 'R':
assignRelativeIds = TRUE;
continue;
#ifndef FRED
case 'c':
argcheck(i, "no cv output file name after -c\n");
argfilew(cvFile, "can't open cv file %s\n");
continue;
case 'v':
argcheck(i, "no cv input file name after -v\n");
cvInput = buildStringList(cvInput, *args++);
continue;
case 'g':
case 'l':
argcheck(i,"no gri file name after -g\n");
argfilew(griFile, "can't open gri output file %s\n");
continue;
case 'i':
argcheck(i, "no indirect file name after -i\n");
argfiler(indirFile, "can't open indirect file %s\n");
continue;
case 'r':
case 'o':
argcheck(i,"no raw file name after -r\n");
argfilew(rawFile, "can't open raw output file %s\n");
continue;
#endif
case 'Y':
yydebug = TRUE;
continue;
case 't':
testMode = TRUE;
continue;
default:
error("bad command line flag -%c\n", arg[j]);
exit(1);
}
}
#ifndef FRED
if(inputFilesGiven && indirFile != NULL) {
error("input files and indirect file given at the same time");
exit(1);
} if (!inputFilesGiven && cvInput == NULL && indirFile == NULL)
queueInputFile("-");
#endif
for (i=0; i<MAXNOID; ++i)
noidArray[i] = NULL;
if (indirFile == NULL)
return(openFirstFile(FALSE));
}
int
hash(s)
char *s;
{
int result;
result = 0;
while (*s != '\0')
result = (result << 1) ^ *s++;
return(result & (HASH_MAX - 1));
}
symbol *
insertSymbol(name)
char *name;
{
symbol *newSymbol;
int hashval;
symbol *mptr;
symbol *oldmptr;
int cmp;
newSymbol = typeAlloc(symbol);
newSymbol->name = 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 = "<standard input>";
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);
}

41
mamelink/griddle/prot.h Normal file
View file

@ -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 }

BIN
mamelink/griddle/reno.out Normal file

Binary file not shown.

View file

@ -0,0 +1,69 @@
#include <stdio.h>
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]);
}

View file

@ -0,0 +1,14 @@
#include <stdio.h>
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");
}

View file

@ -0,0 +1,19 @@
#include <stdio.h>
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;
}
}
}

View file

@ -0,0 +1,19 @@
#include <stdio.h>
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;
}
}