Clean commit of historical griddle / fred source
This commit is contained in:
parent
8a64fe3496
commit
70f2d0338a
7
mamelink/griddle/.dbxinit
Normal file
7
mamelink/griddle/.dbxinit
Normal 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
23
mamelink/griddle/DOC
Normal 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
84
mamelink/griddle/Makefile
Normal 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
50
mamelink/griddle/alloc.c
Normal 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
199
mamelink/griddle/build.c
Normal 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
346
mamelink/griddle/cv.c
Normal 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
170
mamelink/griddle/debug.c
Normal 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
771
mamelink/griddle/exec.c
Normal 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
252
mamelink/griddle/expr.c
Normal 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
900
mamelink/griddle/fred.c
Normal 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
602
mamelink/griddle/fred2.c
Normal 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
350
mamelink/griddle/fscreen.c
Normal 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
535
mamelink/griddle/griddle.c
Normal 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
245
mamelink/griddle/griddle.y
Normal 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);
|
||||||
|
}
|
||||||
|
;
|
298
mamelink/griddle/griddleDefs.h
Normal file
298
mamelink/griddle/griddleDefs.h
Normal 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
344
mamelink/griddle/indir.c
Normal 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
594
mamelink/griddle/lexer.c
Normal 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
355
mamelink/griddle/main.c
Normal 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
41
mamelink/griddle/prot.h
Normal 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
BIN
mamelink/griddle/reno.out
Normal file
Binary file not shown.
69
mamelink/griddle/util/dumpfstats.c
Normal file
69
mamelink/griddle/util/dumpfstats.c
Normal 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]);
|
||||||
|
}
|
14
mamelink/griddle/util/flushfstats.c
Normal file
14
mamelink/griddle/util/flushfstats.c
Normal 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");
|
||||||
|
}
|
19
mamelink/griddle/util/shorten.c
Normal file
19
mamelink/griddle/util/shorten.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
mamelink/griddle/util/trunc.c
Normal file
19
mamelink/griddle/util/trunc.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue