/* areas (triangles) are formed from spans between nodes */
#include <dos.h>
#include <conio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <alloc.h>
#include <graphics.h>
#define EXTCDECL extern
#include "goh.c"
#define SHOWSPAN 0
unsigned nearedge(unsigned index, unsigned enodes)
{
unsigned enodep;
unsigned x, y, jndex;
unsigned xl, xh, yl, yh;
enodep = enodes;
xy(index, &x, &y);
if (x <= 4) xl = 1; else xl = 0;
if (x >= (nsize-3)) xh = 1; else xh = 0;
if (y <= 4) yl = 1; else yl = 0;
if (y >= (nsize-3)) yh = 1; else yh = 0;
if (xl) {
jndex = fxy(1, y);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 1); /* +x indicate virtual point on edge */
}
if (xh) {
jndex = fxy(nsize, y);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 2); /* -x indicate virtual point on edge */
}
if (yl) {
jndex = fxy(x, 1);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 4); /* +y indicate virtual point on edge */
}
if (yh) {
jndex = fxy(x, nsize);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 8); /* -y indicate virtual point on edge */
}
if (xl && yl) {
jndex = fxy(1, 1);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 5); /* +x+y indicate virtual point at corner */
}
if (xh && yl) {
jndex = fxy(nsize, 1);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 6); /*-x+y indicate virtual point at corner */
}
if (xl && yh) {
jndex = fxy(1, nsize);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 9); /* +x-y indicate virtual point at corner */
}
if (xh && yh) {
jndex = fxy(nsize, nsize);
enodep = xtlocate(jndex, enodep);
enodep = xtinsert(jndex, enodep);
poke(enodep, (LEVEL+4), 10); /* -x-y indicate virtual point at corner */
}
return(enodep);
}
void glonodes()
{
struct link *rootlp;
struct root *rootp;
struct link *stonep;
unsigned nodep;
unsigned enodes, enodep;
unsigned bw, jndex;
for (bw=BLK; bw<=WHT; ++bw) {
xtfreelist(gnodes[bw]);
gnodes[bw] = xtinsert(0, 0);
nodep = gnodes[bw];
rootlp = rootlist->nextl;
if (rootlp) {
do {
rootp = (struct root *) rootlp->loc;
if (rootp->clr == bw) {
stonep = rootp->neighbs->nextl;
do {
jndex = stonep->loc;
nodep = xtlocate(jndex, nodep);
nodep = xtinsert(jndex, nodep);
poke(nodep, (LEVEL+4), 0); /* indicate node is stone */
stonep = stonep->nextl;
} while (stonep);
}
rootlp = rootlp->nextl;
} while (rootlp);
nodep = peek(gnodes[bw], NEXTL);
if (nodep) {
enodes = xtinsert(0, 0);
enodep = enodes;
do {
jndex = peek(nodep, LOC);
enodep = nearedge(jndex, enodep);
nodep = peek(nodep, NEXTL);
} while (nodep);
enodep = peek(enodes, NEXTL);
if (enodep) {
nodep = gnodes[bw];
do {
jndex = peek(enodep, LOC);
nodep = xtlocate(jndex, nodep);
if (!xtmember(jndex, nodep)) {
nodep = xtinsert(jndex, nodep);
poke(nodep, (LEVEL+4), 16); /* indicate vacant node on edge */
}
enodep = peek(enodep, NEXTL);
} while (enodep);
}
xtfreelist(enodes);
}
}
}
}
unsigned oldspan(unsigned p, unsigned q, unsigned bw, unsigned *spas)
{
unsigned allow;
unsigned xp, yp, xq, yq;
unsigned xpqmin, xpqmax, ypqmin, ypqmax;
unsigned a, b;
unsigned pq, ab;
unsigned xa, ya, xb, yb;
unsigned xabmin, xabmax, yabmin, yabmax;
unsigned xap, xbp, xpa, xqa;
unsigned yap, ybp, ypa, yqa;
unsigned apb, aqb, paq, pbq;
unsigned xpq, xab;
unsigned extension, colinear;
int alpha, beta, gamma, delta, c, overlap, dxpa, dypa, x, y, o;
unsigned spap, jndexp;
allow = 1;
xy(p, &xp, &yp);
xy(q, &xq, &yq);
xpqmin = min(xp, xq);
xpqmax = max(xp, xq);
ypqmin = min(yp, yq);
ypqmax = max(yp, yq);
pq = howfar(p, q);
spap = peek(spas[bw], NEXTL);
if (spap) {
do {
a = peek(spap, LOC);
jndexp = peek(spap, LEVEL);
jndexp = peek(jndexp, NEXTL);
if (jndexp) {
do {
b = peek(jndexp, LOC);
/* do not allow if the spa pq already exists */
if ((a == p) && (b == q)) allow = 0;
if (allow) {
ab = howfar(a, b);
xy(a, &xa, &ya);
xy(b, &xb, &yb);
xabmin = min(xa, xb);
xabmax = max(xa, xb);
yabmin = min(ya, yb);
yabmax = max(ya, yb);
/* more details if Manhattan extents of spas pq,ab overlap */
xpa = (xabmin<=xp) && (xp<=xabmax);
ypa = (yabmin<=yp) && (yp<=yabmax);
xqa = (xabmin<=xq) && (xq<=xabmax);
yqa = (yabmin<=yq) && (yq<=yabmax);
xap = (xpqmin<=xa) && (xa<=xpqmax);
yap = (ypqmin<=ya) && (ya<=ypqmax);
xbp = (xpqmin<=xb) && (xb<=xpqmax);
ybp = (ypqmin<=yb) && (yb<=ypqmax);
apb = xpa && ypa;
aqb = xqa && yqa;
paq = xap && yap;
pbq = xbp && ybp;
xpq = xap && xbp && ypa && yqa;
xab = xpa && xqa && yap && ybp;
if (apb || aqb || paq || pbq || xpq || xab) {
/* investigate further if not extension from previous spa */
dxpa = xa - xp;
dypa = yp - ya;
alpha = yb - ya;
beta = xb - xa;
gamma = yq - yp;
delta = xq - xp;
o = alpha * delta - beta * gamma;
#if SHOWSPAN
newline();
coords(p);
coords(q);
coords(a);
coords(b);
printf(" oblique:%d", o);
#endif
c = beta * dypa - alpha * dxpa;
if (!o && !c) colinear = 1;
else colinear = 0;
extension = (a==p) || (a==q) || (b==p) || (b==q);
if (extension && colinear) {
paq = howfar(p, q) - howfar(p, a) - howfar(a, q);
pbq = howfar(p, q) - howfar(p, b) - howfar(b, q);
if (!paq && !pbq) allow = 0;
#if SHOWSPAN
if (!allow) printf(" !allow:ex&ol");
#endif
}
if (!extension && allow) {
if (!o) {
/* pq parallel ab .. do not allow if colinear and overlapping */
if (colinear) {
apb = howfar(a, b) - howfar(a, p) - howfar(p, b);
aqb = howfar(a, b) - howfar(a, q) - howfar(q, b);
paq = howfar(p, q) - howfar(p, a) - howfar(a, q);
pbq = howfar(p, q) - howfar(p, b) - howfar(b, q);
if (!apb || !aqb || !paq || !pbq) allow = 0;
#if SHOWSPAN
if (!allow) printf(" !allow:co&ol");
#endif
}
}
else {
/* not parallel .. do not allow if intersection x,y inside spas */
x = beta*delta*dypa - beta*gamma*xp + alpha*delta*xa;
y = alpha*gamma*dxpa + alpha*delta*yp - gamma*beta*ya;
if (o < 0) {
x = -x;
y = -y;
o = -o;
}
if ((xabmin*o<=x) && (x<=xabmax*o) && (yabmin*o<=y) && (y<=yabmax*o)) {
if ((xpqmin*o<=x) && (x<=xpqmax*o) && (ypqmin*o<=y) && (y<=ypqmax*o)) {
if (pq >= ab) {
allow = 0;
#if SHOWSPAN
printf(" disallow ");
#endif
}
}
}
}
}
}
}
jndexp = peek(jndexp, NEXTL);
} while (jndexp && allow);
}
spap = peek(spap, NEXTL);
} while (spap && allow);
}
return(allow);
}
void glospans()
{
unsigned scale;
unsigned nodep, spanp, chekp;
unsigned bw, jndexes, jndexp, jndex, kndexes, kndexp, kndex;
unsigned nspan, allow;
if (!spanon) return;
glonodes();
for (bw=BLK; bw<=WHT; ++bw) {
spanp = gspans[bw];
spanp = peek(spanp, NEXTL);
if (spanp) {
do {
jndexes = peek(spanp, LEVEL);
if (jndexes) xtfreelist(jndexes);
spanp = peek(spanp, NEXTL);
} while (spanp);
}
xtfreelist(gspans[bw]);
gspans[bw] = xtinsert(0, 0);
spanp = gspans[bw];
for (scale=2; scale<=MAXSCALE; ++scale) {
nodep = gnodes[bw];
nodep = peek(nodep, NEXTL);
if (nodep) {
chekp = nodep;
do {
jndex = peek(nodep, LOC);
kndexes = xtinsert(0, 0);
halfring(jndex, scale, kndexes);
kndexp = peek(kndexes, NEXTL);
if (kndexp) {
do {
kndex = peek(kndexp, LOC);
chekp = xtlocate(kndex, chekp);
if (xtmember(kndex, chekp)) {
allow = oldspan(jndex, kndex, bw, gspans);
if (allow) {
spanp = xtlocate(jndex, spanp);
if (!xtmember(jndex, spanp)) {
spanp = xtinsert(jndex, spanp);
jndexes = xtinsert(0, 0);
poke(spanp, LEVEL, jndexes);
}
jndexes = peek(spanp, LEVEL);
jndexp = xtlocate(kndex, jndexes);
jndexp = xtinsert(kndex, jndexp);
#if SHOWSPAN
if (col80) {
newline();
if (bw == BLK) printf("BLK");
if (bw == WHT) printf("WHT");
coords(jndex);
coords(kndex);
printf(" %d", scale);
}
#endif
}
}
kndexp = peek(kndexp, NEXTL);
} while (kndexp);
}
xtfreelist(kndexes);
nodep = peek(nodep, NEXTL);
} while (nodep);
}
}
}
}
unsigned chkedge(unsigned index, unsigned edgy, unsigned bw)
{
unsigned sup;
unsigned corner, edge, xp, xm, yp, ym, xon, yon, jndex;
int x, y, i, j, xinc, yinc, ysav;
struct root *rootp;
sup = 0;
if (!edgeon) return(sup);
xy(index, &x, &y);
xp = edgy & 1;
xm = edgy & 2;
yp = edgy & 4;
ym = edgy & 8;
xon = xp || xm;
yon = yp || ym;
corner = xon && yon;
edge = xon || yon;
if (corner) edge = 0;
xinc = 0;
yinc = 0;
if (xp) xinc = 1;
if (xm) xinc = -1;
if (yp) yinc = 1;
if (ym) yinc = -1;
if (corner) {
ysav = y;
for (i=1; i<=4; ++i) {
y = ysav;
for (j=1; j<=4; ++j) {
jndex = fxy(x, y);
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) sup = jndex;
}
if (sup) break;
y += yinc;
}
if (sup) break;
x += xinc;
}
}
else if (edge) {
for (i=1; i<=4; ++i) {
jndex = fxy(x, y);
rootp = dir[jndex];
if (rootp) {
if (rootp->clr == bw) sup = jndex;
}
if (sup) break;
if (xon) x += xinc;
else if (yon) y += yinc;
}
}
return(sup);
}
unsigned getnode(unsigned index, unsigned bw)
{
unsigned indexp; /* use node directory to access index in nodes list */
unsigned far *farndirp;
farndirp = farndir;
if (bw == WHT) farndirp += nsize21;
farndirp += index;
indexp = *farndirp;
return(indexp);
}
void setnode(unsigned index, unsigned bw, unsigned indexp)
{ /* put indexp from nodes list in node directory */
unsigned seg, off;
unsigned far *farndirp;
farndirp = farndir;
if (bw == WHT) farndirp += nsize21;
farndirp += index;
seg = FP_SEG(farndirp);
off = FP_OFF(farndirp);
uzxlmod(seg, off, indexp); /* put change in transaction list */
}
unsigned insarea(unsigned areap, unsigned bw, unsigned index, unsigned jndex,
unsigned kndex, unsigned spare, unsigned area)
{
unsigned jndexes, jndexp, nodep, ptr, kndexes, kndexp;
#if SHOWSPAN
newline();
printf(" insarea");
coords(index);
coords(jndex);
coords(kndex);
#endif
areap = xtlocate(index, areap);
if (!xtmember(index, areap)) {
areap = uzinsert(index, areap);
jndexes = uzinsert(0, 0);
poke(areap, LEVEL, jndexes);
}
jndexes = peek(areap, LEVEL);
jndexp = xtlocate(jndex, jndexes);
if (!xtmember(jndex, jndexp)) {
jndexp = uzinsert(jndex, jndexp);
kndexes = uzinsert(0, 0);
poke(jndexp, (LEVEL+2), kndexes);
}
kndexes = peek(jndexp, (LEVEL+2));
kndexp = xtlocate(kndex, kndexes);
if (!xtmember(kndex, kndexp)) {
kndexp = uzinsert(kndex, kndexp);
poke(kndexp, LEVEL, jndex);
poke(kndexp, (LEVEL+2), index);
poke(kndexp, (LEVEL+4), spare);
poke(kndexp, (LEVEL+6), area);
nodep = getnode(index, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
ptr = uzinsert(kndexp, ptr);
nodep = getnode(jndex, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
ptr = uzinsert(kndexp, ptr);
nodep = getnode(kndex, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
ptr = uzinsert(kndexp, ptr);
}
return(areap);
}
void delarea(unsigned kndexp, unsigned bw)
{
unsigned index, jndex, kndex, ptr, jndexp, jndexes;
unsigned nodep, areap;
kndex = peek(kndexp, LOC);
jndex = peek(kndexp, LEVEL);
index = peek(kndexp, (LEVEL+2));
#if SHOWSPAN
newline();
printf(" delarea");
coords(index);
coords(jndex);
coords(kndex);
#endif
nodep = getnode(index, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
if (xtmember(kndexp, ptr)) uzdelink(ptr);
nodep = getnode(jndex, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
if (xtmember(kndexp, ptr)) uzdelink(ptr);
nodep = getnode(kndex, bw);
ptr = peek(nodep, (LEVEL+2));
ptr = xtlocate(kndexp, ptr);
if (xtmember(kndexp, ptr)) uzdelink(ptr);
uzdelink(kndexp);
/*
areap = areas[bw];
areap = xtlocate(index, areap);
if (xtmember(index, areap)) {
jndexes = peek(areap, LEVEL);
jndexp = peek(jndexp, NEXTL);
if (jndexp) {
ptr = peek(jndexp, (LEVEL+2));
if (!peek(ptr, NEXTL)) {
uzdelink(ptr);
uzdelink(jndexp);
}
if (!peek(jndexes, NEXTL)) {
uzdelink(jndexes);
/*uzdelink(areap);*/
}
}
}
*/
}
int howbig(unsigned i, unsigned j, unsigned k)
{
int value;
int xi, yi, xj, yj, xk, yk;
xi = X[i];
yi = Y[i];
xj = X[j] - xi;
yj = Y[j] - yi;
xk = X[k] - xi;
yk = Y[k] - yi;
value = xj * yk - yj * xk;
return(value);
}
unsigned oppvert(unsigned kndex, unsigned index, unsigned kndexp)
{
unsigned jndex;
unsigned i, j, k;
k = peek(kndexp, LOC);
j = peek(kndexp, LEVEL);
i = peek(kndexp, (LEVEL+2));
jndex = i;
if ((jndex == index) || (jndex == kndex)) {
jndex = j;
if ((jndex == index) || (jndex == kndex)) {
jndex = k;
}
}
return(jndex);
}
unsigned canarea(unsigned index, unsigned jndex, unsigned kndex, unsigned bw)
{ /* index,jndex form new span check for other triangles on other spans */
unsigned allow;
unsigned destroy, kndexp;
unsigned i, j, k;
unsigned nodei, nodej, nodek;
int newarea, oldarea;
allow = 1;
destroy = 0;
nodek = getnode(kndex, bw);
nodek = peek(nodek, (LEVEL+2));
nodek = peek(nodek, NEXTL);
if (nodek) {
/* check kndex for area shared by index */
nodei = getnode(index, bw);
nodei = peek(nodei, (LEVEL+2));
newarea = howbig(kndex, index, jndex);
do {
kndexp = peek(nodek, LOC);
nodei = xtlocate(kndexp, nodei);
if (xtmember(kndexp, nodei)) {
j = oppvert(kndex, index, kndexp);
oldarea = howbig(kndex, index, j);
if ((oldarea > 0) && (newarea > 0)) {
if (oldarea <= newarea) allow = 0;
else destroy = kndexp;
}
if ((oldarea < 0) && (newarea < 0)) {
if (oldarea >= newarea) allow = 0;
else destroy = kndexp;
}
}
nodek = peek(nodek, NEXTL);
} while (nodek && !destroy && allow);
if (!destroy && allow) {
/* check kndex for area shared by jndex */
nodek = getnode(kndex, bw);
nodek = peek(nodek, (LEVEL+2));
nodek = peek(nodek, NEXTL);
nodej = getnode(jndex, bw);
nodej = peek(nodej, (LEVEL+2));
newarea = howbig(kndex, jndex, index);
do {
kndexp = peek(nodek, LOC);
nodej = xtlocate(kndexp, nodej);
if (xtmember(kndexp, nodej)) {
i = oppvert(kndex, jndex, kndexp);
oldarea = howbig(kndex, jndex, i);
if ((oldarea > 0) && (newarea > 0)) {
if (oldarea <= newarea) allow = 0;
else destroy = kndexp;
}
if ((oldarea < 0) && (newarea < 0)) {
if (oldarea >= newarea) allow = 0;
else destroy = kndexp;
}
}
nodek = peek(nodek, NEXTL);
} while (nodek && !destroy && allow);
}
if (destroy) delarea(destroy, bw);
}
return(allow);
}
void mkareas(unsigned index, unsigned jndex, unsigned bw)
{ /* make smallest 2 triangles on span index,jndex */
unsigned kndex;
unsigned areap;
unsigned commons, commonp;
unsigned nodei, nodej, nodek;
unsigned is, js, ip, jp;
unsigned ptri, ptrj, ptr;
unsigned i, j, k;
unsigned allow;
int value, minpos, maxneg;
if (!areaon) return;
areap = areas[bw];
nodei = getnode(index, bw);
nodej = getnode(jndex, bw);
ptri = peek(nodei, LEVEL);
ptrj = peek(nodej, LEVEL);
ptri = peek(ptri, NEXTL);
ptrj = peek(ptrj, NEXTL);
if (ptri && ptrj) {
commons = xtinsert(0, 0);
is = xtinsert(0, 0);
js = xtinsert(0, 0);
commonp = commons;
ip = is;
jp = js;
do {
ptr = peek(ptri, LOC);
i = peek(ptr, LEVEL);
if (i == index) i = peek(ptr, LOC);
ip = xtlocate(i, ip);
ip = xtinsert(i, ip);
ptri = peek(ptri, NEXTL);
} while (ptri);
do {
ptr = peek(ptrj, LOC);
j = peek(ptr, LEVEL);
if (j == jndex) j = peek(ptr, LOC);
jp = xtlocate(j, jp);
jp = xtinsert(j, jp);
ptrj = peek(ptrj, NEXTL);
} while (ptrj);
maxneg = -BIAS;
minpos = BIAS;
jp = peek(js, NEXTL);
ip = peek(is, NEXTL);
do {
k = peek(ip, LOC);
jp = xtlocate(k, jp);
if (xtmember(k, jp)) {
commonp = xtlocate(k, commonp);
commonp = xtinsert(k, commonp);
value = howbig(index, jndex, k);
poke(commonp, LEVEL, value+BIAS);
if (value < 0) {
if (value > maxneg) maxneg = value;
}
if (value > 0) {
if (value < minpos) minpos = value;
}
}
ip = peek(ip, NEXTL);
} while (ip);
/* now remove all but the smallest positive area and the largest neg */
commonp = peek(commons, NEXTL);
if (commonp) {
do {
value = peek(commonp, LEVEL) - BIAS;
if ((value != maxneg) && (value != minpos)) commonp = xtdelete(commonp);
commonp = peek(commonp, NEXTL);
} while (commonp);
}
commonp = peek(commons, NEXTL);
if (commonp) {
do {
kndex = peek(commonp, LOC);
value = peek(commonp, LEVEL) - BIAS;
allow = canarea(index, jndex, kndex, bw);
if (allow) {
i = index;
j = kndex;
k = jndex;
if (kndex > jndex) {
j = jndex;
k = kndex;
}
if (kndex < index) {
i = kndex;
j = index;
}
areap = insarea(areap, bw, i, j, k, 0, abs(value));
}
commonp = peek(commonp, NEXTL);
} while (commonp);
}
xtfreelist(js);
xtfreelist(is);
xtfreelist(commons);
}
}
unsigned insspan(unsigned spanp, unsigned bw, unsigned index, unsigned jndex,
unsigned spare, unsigned pcon)
{
unsigned jndexes, jndexp, nodep, ptr;
#if SHOWSPAN
newline();
printf(" insspan");
coords(index);
coords(jndex);
#endif
spanp = xtlocate(index, spanp);
if (!xtmember(index, spanp)) {
spanp = uzinsert(index, spanp);
jndexes = uzinsert(0, 0);
poke(spanp, LEVEL, jndexes);
}
jndexes = peek(spanp, LEVEL);
jndexp = xtlocate(jndex, jndexes);
if (!xtmember(jndex, jndexp)) {
jndexp = uzinsert(jndex, jndexp);
poke(jndexp, LEVEL, index);
poke(jndexp, (LEVEL+4), spare);
poke(jndexp, (LEVEL+6), pcon);
nodep = getnode(index, bw);
ptr = peek(nodep, LEVEL);
ptr = xtlocate(jndexp, ptr);
ptr = uzinsert(jndexp, ptr);
nodep = getnode(jndex, bw);
ptr = peek(nodep, LEVEL);
ptr = xtlocate(jndexp, ptr);
ptr = uzinsert(jndexp, ptr);
}
mkareas(index, jndex, bw);
return(spanp);
}
void delspan(unsigned jndexp, unsigned bw)
{
unsigned index, jndex, ptr;
unsigned nodep, spanp, nodeq;
jndex = peek(jndexp, LOC);
index = peek(jndexp, LEVEL);
#if SHOWSPAN
newline();
printf(" delspan");
coords(index);
coords(jndex);
#endif
nodep = getnode(index, bw);
ptr = peek(nodep, LEVEL);
ptr = xtlocate(jndexp, ptr);
if (xtmember(jndexp, ptr)) uzdelink(ptr);
nodeq = getnode(jndex, bw);
ptr = peek(nodeq, LEVEL);
ptr = xtlocate(jndexp, ptr);
if (xtmember(jndexp, ptr)) uzdelink(ptr);
/* delink areas supported by both index and jndex */
nodep = peek(nodep, (LEVEL+2));
nodeq = peek(nodeq, (LEVEL+2));
nodep = peek(nodep, NEXTL);
if (nodep) {
do {
ptr = peek(nodep, LOC);
nodeq = xtlocate(ptr, nodeq);
if (xtmember(ptr, nodeq)) {
delarea(ptr, bw);
}
nodep = peek(nodep, NEXTL);
} while (nodep);
}
uzdelink(jndexp);
spanp = spans[bw];
spanp = xtlocate(index, spanp);
if (xtmember(index, spanp)) {
ptr = peek(spanp, LEVEL);
if (!peek(ptr, NEXTL)) {
uzdelink(ptr);
uzdelink(spanp);
}
}
}
unsigned insnode(unsigned index, unsigned nodep, unsigned edgy, unsigned da)
{ /* insert node for bw==colour */
nodep = uzinsert(index, nodep); /* insertion of node is a transaction */
poke(nodep, LEVEL, uzinsert(0, 0)); /* make span list a transaction */
poke(nodep, (LEVEL+2), uzinsert(0, 0)); /* make area list too */
poke(nodep, (LEVEL+4), edgy); /* real/virtual */
poke(nodep, (LEVEL+6), da); /* indicate dead/alive */
setnode(index, colour, nodep); /* put nodep in node directory at index */
return(nodep);
}
unsigned delnode(unsigned nodep, unsigned bw)
{
unsigned jndexp, kndexp, spanlp, arealp;
unsigned index;
index = peek(nodep, LOC);
/* first delink all areas in areas list ... no! only delspan calls delarea */
arealp = peek(nodep, (LEVEL+2));
arealp = peek(arealp, NEXTL);
if (arealp) {
do {
kndexp = peek(arealp, LOC);
delarea(kndexp, bw); /* delarea messes with arealp list */
arealp = peek(arealp, NEXTL);
} while (arealp);
}
/* then delink areas list */
uzfreelist(peek(nodep, (LEVEL+2)));
/* then delink all spans in spans list */
spanlp = peek(nodep, LEVEL);
spanlp = peek(spanlp, NEXTL);
if (spanlp) {
do