RasMol2
|
Announce,
ChangeLog,
ChangeLog.1,
ChangeLog.2,
ChangeLog.3,
ChangeLog.4,
ChangeLog.5,
ChangeLog.6,
INSTALL,
Imakefile,
Makefile,
Makefile.bak,
Makefile.in,
Makefile.nt,
Makefile.pc,
PROJECTS,
README,
TODO,
abstree.c,
abstree.h,
abstree.o,
applemac.c,
bitmaps.h,
cexio.c,
command.c,
command.h,
command.o,
data,
doc,
font.h,
graphics.h,
infile.c,
infile.h,
infile.o,
mac,
molecule.c,
molecule.h,
molecule.o,
mswin,
mswin31.c,
outfile.c,
outfile.h,
outfile.o,
pixutils.c,
pixutils.h,
pixutils.o,
rasmac.c,
rasmol.c,
rasmol.h,
rasmol.hlp,
rasmol.o,
rasmol.sh,
raswin.c,
render.c,
render.h,
render.o,
repres.c,
repres.h,
repres.o,
script.c,
script.h,
script.o,
tokens.h,
transfor.c,
transfor.h,
transfor.o,
vms,
x11win.c,
x11win.o,
|
|
|
/* render.c
* RasMol2 Molecular Graphics
* Roger Sayle, August 1995
* Version 2.6
*/
#include "rasmol.h"
#ifdef IBMPC
#include
#include
#endif
#ifdef APPLEMAC
#include
#include
#ifdef __CONDITIONALMACROS__
#include
#else
#include
#endif
#endif
#ifndef sun386
#include
#endif
#include
#include
#include
#include
#define RENDER
#include "molecule.h"
#include "graphics.h"
#include "render.h"
#include "repres.h"
#include "abstree.h"
#include "transfor.h"
#include "command.h"
#include "pixutils.h"
/* Avoid PowerPC Errors! */
#ifdef INFINITY
#undef INFINITY
#endif
#define PoolSize 16
#define RootSix 2.4494897427831780
#define OneOverRootSix 0.4082482904638630
#define TwoOverRootSix 0.8164965809277260
#define ApproxZero 1.0E-3
#define INFINITY 200000
#define FUDGEFACTOR 1000
#if !defined(IBMPC) && !defined(APPLEMAC)
Card ColConstTable[MAXRAD];
#endif
typedef struct { Real h,l; } Interval;
static Atom __far * __far *YBucket;
static Atom __far * __far *IBuffer;
static int BuckY,ItemX;
static int FBufX,FBufY;
static int DBClear;
static Atom __far *SBuffer;
static Atom __far *Exclude;
static Real ShadowI, ShadowJ, ShadowK;
static int ShadowX, ShadowY, ShadowZ;
static int deltax, deltay, deltaz;
static int xcord, ycord, zcord;
static int xflag, yflag, zflag;
static int xhash, yhash, zhash;
static int RayCount;
static Item __far *FreeItem;
static Real VoxRatio;
static int VoxelCount,InVoxCount;
static int ProbeCount;
static int VoxelsDone;
/* Identified Atom Info */
static AtomRef PickHist[4];
static Long IdentDist;
static int IdentFound;
static int IdentDepth;
static int PickCount;
static int PickMode;
/* Macros for commonly used loops */
#define ForEachAtom for(chain=Database->clist;chain;chain=chain->cnext) \
for(group=chain->glist;group;group=group->gnext) \
for(aptr=group->alist;aptr;aptr=aptr->anext)
#define ForEachBond for(bptr=Database->blist;bptr;bptr=bptr->bnext)
#define ForEachBack for(chain=Database->clist;chain;chain=chain->cnext) \
for(bptr=chain->blist;bptr;bptr=bptr->bnext)
static void FatalRenderError(ptr)
char *ptr;
{
char buffer[80];
sprintf(buffer,"Renderer Error: Unable to allocate %s!",ptr);
RasMolFatalExit(buffer);
}
int isqrt( val )
Card val;
{
#ifndef sun386
register int i,result;
register Card temp;
register Card rem;
i = 16;
while( !(val&((Card)3<<30)) && i )
{ val <<= 2;
i--;
}
if( i )
{ rem = (val>>30)-1;
val <<= 2;
result = 1;
i--;
while( i )
{ rem = (rem<<2) | (val>>30);
result <<= 1;
val <<= 2;
temp = result<<1;
if( rem > temp )
{ rem -= temp|1;
result |= 1;
}
i--;
}
return( result );
} else return( 0 );
#else
return( (int)sqrt((double)val) );
#endif
}
/*=============================*/
/* ClearBuffers Subroutines! */
/*=============================*/
#ifdef IBMPC
/* Windows NT vs Microsoft C vs Borland Turbo C */
static void ClearMemory( register char __huge*, register long );
static void ClearMemory( ptr, count )
register char __huge *ptr;
register long count;
{
#ifndef _WIN32
#ifdef __TURBOC__
register long left;
register int off;
off = OFFSETOF(ptr);
if( off )
{ left = 65536 - off;
if( count < left )
{ _fmemset(ptr,0,(size_t)count);
return;
} else
{ _fmemset(ptr,0,(size_t)left);
count -= left;
ptr += left;
}
}
while( count > 65535 )
{ _fmemset(ptr,0,(size_t)65535);
count -= 65536;
ptr += 65535;
*ptr++ = '\0';
}
if( count )
_fmemset(ptr,0,(size_t)count);
#else /* Microsoft C/C++ */
while( count > 65534 )
{ _fmemset(ptr,0,(size_t)65534);
count -= 65534;
ptr += 65534;
}
if( count )
_fmemset(ptr,0,(size_t)count);
#endif
#else /* Windows NT */
memset(ptr,0,(size_t)count);
#endif /* Windows NT */
}
void ClearBuffers()
{
register char __huge *ptr;
if( !FBClear )
{ FBClear = True;
ptr = (Pixel __huge*)GlobalLock(FBufHandle);
ClearMemory(ptr,(Long)XRange*YRange);
GlobalUnlock(FBufHandle);
}
if( !DBClear )
{ DBClear = True;
ptr = (char __huge*)GlobalLock(DBufHandle);
ClearMemory(ptr,(Long)XRange*YRange*sizeof(short));
GlobalUnlock(DBufHandle);
}
}
#else
#if defined(VMS) || defined(__sgi) /* memset */
void ClearBuffers()
{
#ifndef EIGHTBIT
register Long *ptr;
register Long *end;
register Long fill;
if( !FBClear )
{ FBClear = True;
fill = Lut[BackCol];
ptr = (Long*)FBuffer;
end = (Long*)(FBuffer+(Long)XRange*YRange);
do { *ptr++=fill; *ptr++=fill;
*ptr++=fill; *ptr++=fill;
} while( ptr>2; iptr = IBuffer;
for( index=0; index<=len; index++ )
{ *iptr++ = (void __far*)0; *iptr++ = (void __far*)0;
*iptr++ = (void __far*)0; *iptr++ = (void __far*)0;
}
ItemX = XRange;
}
}
void ReSizeScreen()
{
register Real orig;
if( Range != ZoomRange )
{ orig = MaxZoom;
MaxZoom = 0.236*(WorldSize+1000)/Range;
ZoomRange = Range; MaxZoom -= 1.0;
/* Handle Change in MaxZoom */
if( DialValue[3]>0.0 )
{ DialValue[3] *= orig/MaxZoom;
if( DialValue[3]>1.0 )
DialValue[3] = 1.0;
}
}
#ifdef IBMPC
if( !FBufHandle || (FBufX!=XRange) || (FBufY!=YRange) )
#else /* UNIX */
if( !FBuffer || (FBufX!=XRange) || (FBufY!=YRange) )
#endif
{ if( !CreateImage() )
FatalRenderError("frame buffer");
BucketFlag = False;
FBufX=XRange; FBufY=YRange; FBClear = False;
ReAllocBuffers();
ClearBuffers();
}
}
static void PrepareYBucket()
{
register Atom __far * __far *temp;
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
register int scan;
register int rad;
temp = YBucket;
for( scan=0; scanflag&SphereFlag )
{ rad = aptr->irad;
if( (aptr->x-rad>=XRange) ||
(aptr->x+rad<0) || (aptr->y+rad<0) )
continue;
if( (scan=aptr->y-rad) > BuckY ) continue;
if( scan>0 )
{ aptr->bucket = YBucket[scan];
YBucket[scan] = aptr;
} else
{ aptr->bucket = *YBucket;
*YBucket = aptr;
}
}
} else
ForEachAtom
if( aptr->flag&SphereFlag )
{ scan = aptr->y-aptr->irad;
aptr->bucket = YBucket[scan];
YBucket[scan] = aptr;
}
BucketFlag = True;
}
#ifdef FUNCPROTO
/* Function Prototypes */
static void SqrInterval( Interval __far* );
static void VoxelInsert( Atom __far*, int );
static int AtomInter( Atom __far* );
#endif
static void SqrInterval( ival )
Interval __far *ival;
{ register Real l,h;
l = ival->l;
h = ival->h;
if( l>=0.0 )
{ ival->l = l*l;
ival->h = h*h;
} else if( h<0.0 )
{ ival->l = h*h;
ival->h = l*l;
} else
{ ival->h = (-l>h)? l*l : h*h;
ival->l = 0.0;
}
}
static void VoxelInsert( ptr, ref )
Atom __far *ptr;
int ref;
{
register Item __far *datum;
register int i;
if( !FreeItem )
{ datum = (Item __far*)_fmalloc( PoolSize*sizeof(Item) );
if( !datum ) FatalRenderError("voxel item");
for( i=1; ilist = FreeItem;
FreeItem = datum++;
}
} else
{ datum = FreeItem;
FreeItem = datum->list;
}
datum->data = ptr;
InVoxCount++;
if( !HashTable[ref] ) VoxelCount++;
datum->list = (Item __far*)HashTable[ref];
HashTable[ref] = (void __far*)datum;
}
void ResetVoxelData()
{
register Item __far *datum;
register int i;
if( VoxelsDone )
{ for( i=0; ilist ) datum = datum->list;
datum->list = FreeItem;
FreeItem = (Item __far*)HashTable[i];
HashTable[i] = (void __far*)0;
}
VoxelsDone = False;
} else for( i=0; iflag & flag )
{ mx = aptr->xorg+Offset;
my = aptr->yorg+Offset;
mz = aptr->zorg+Offset;
if( flag != SphereFlag )
{ if( SolventDots || !ProbeRadius )
{ rad = ElemVDWRadius(aptr->elemno);
} else rad = ProbeRadius;
} else rad = aptr->radius;
radius2 = (Long)rad*rad;
lvx = (int)((mx-rad)*IVoxRatio); hvx = (int)((mx+rad)*IVoxRatio);
lvy = (int)((my-rad)*IVoxRatio); hvy = (int)((my+rad)*IVoxRatio);
lvz = (int)((mz-rad)*IVoxRatio); hvz = (int)((mz+rad)*IVoxRatio);
for( px=lvx; px<=hvx; px++ )
{ ix.l=px*VoxRatio-mx;
ix.h=ix.l+VoxRatio;
SqrInterval(&ix);
i = VOXORDER2*px + VOXORDER*lvy;
for( py=lvy; py<=hvy; py++ )
{ iy.l=py*VoxRatio-my;
iy.h=iy.l+VoxRatio;
SqrInterval(&iy);
for( pz=lvz; pz<=hvz; pz++ )
{ iz.l=pz*VoxRatio-mz;
iz.h=iz.l+VoxRatio;
SqrInterval(&iz);
#ifdef ORIG
/* Test for surface voxels */
if( ((ix.l+iy.l+iz.l)radius2) )
VoxelInsert( aptr, i+pz );
#else
/* Test for contained voxels */
if( ix.l+iy.l+iz.l < radius2 )
VoxelInsert( aptr, i+pz );
#endif
} /*pz*/
i += VOXORDER;
} /*py*/
} /*px*/
}
}
void ShadowTransform()
{
ShadowI = OneOverRootSix*(RotX[0]-RotY[0]+RotZ[0]+RotZ[0]);
ShadowK = OneOverRootSix*(RotX[2]-RotY[2]+RotZ[2]+RotZ[2]);
#ifdef INVERT
ShadowJ = -OneOverRootSix*(RotX[1]-RotY[1]+RotZ[1]+RotZ[1]);
#else
ShadowJ = OneOverRootSix*(RotX[1]-RotY[1]+RotZ[1]+RotZ[1]);
#endif
if( ShadowI>ApproxZero )
{ deltax = (int)(FUDGEFACTOR/ShadowI); xhash = VOXORDER2; xflag = 1;
} else if( ShadowI<-ApproxZero )
{ deltax = -(int)(FUDGEFACTOR/ShadowI); xhash = -VOXORDER2; xflag = -1;
} else xflag = 0;
if( ShadowJ>ApproxZero )
{ deltay = (int)(FUDGEFACTOR/ShadowJ); yhash = VOXORDER; yflag = 1;
} else if( ShadowJ<-ApproxZero )
{ deltay = -(int)(FUDGEFACTOR/ShadowJ); yhash = -VOXORDER; yflag = -1;
} else yflag = 0;
if( ShadowK>ApproxZero )
{ deltaz = (int)(FUDGEFACTOR/ShadowK); zhash = zflag = 1;
} else if( ShadowK<-ApproxZero )
{ deltaz = -(int)(FUDGEFACTOR/ShadowK); zhash = zflag = -1;
} else zflag = 0;
}
static int AtomInter( ptr )
Atom __far *ptr;
{
register Long modv,radius2;
register int vx, vy, vz;
register Real tca;
if( ptr->mbox == RayCount )
return( False );
ptr->mbox = RayCount;
vx = (int)ptr->xorg-ShadowX;
vy = (int)ptr->yorg-ShadowY;
vz = (int)ptr->zorg-ShadowZ;
tca = vx*ShadowI + vy*ShadowJ + vz*ShadowK;
if( tca<0.0 ) return( False );
radius2 = ptr->radius+10; radius2 = radius2*radius2;
modv = (Long)vx*vx + (Long)vy*vy + (Long)vz*vz - radius2;
return( modvlist )
if( (ptr->data!=Exclude) && AtomInter(ptr->data) )
{ SBuffer = ptr->data;
return( True );
}
if( (dx<=dy) && (dx<=dz) )
{ xcord += xflag;
if( (xcord<0) || (xcord>=VOXORDER) ) return( False );
ident += xhash; dx += deltax;
} else if( dy<=dz ) /*(dy<=dx)*/
{ ycord += yflag;
if( (ycord<0) || (ycord>=VOXORDER) ) return( False );
ident += yhash; dy += deltay;
} else /* (dz<=dx) && (dz<=dy) */
{ zcord += zflag;
if( (zcord<0) || (zcord>=VOXORDER) ) return( False );
ident += zhash; dz += deltaz;
}
}
}
#define UpdateScanAcross \
if( depth>*dptr ) \
{ *dptr = depth; \
iptr[dx] = ptr; \
} dptr++; dx++;
/* ScanLine for Shadows! */
static void ScanLine()
{
static Atom __far *list;
register Atom __far *ptr;
register Atom __far * __far *iptr;
register Atom __far * __far *prev;
register short __huge *dbase;
register short __huge *dptr;
register Pixel __huge *fptr;
register Byte __far *tptr;
register int pos,depth,inten;
register int lastx,wide,scan;
register int dx,dy,dz;
fptr = FBuffer;
dbase = DBuffer;
list = (void __far*)0;
wide = XRange>>2; iptr = IBuffer;
for( pos=0; pos<=wide; pos++ )
{ *iptr++ = (void __far*)0; *iptr++ = (void __far*)0;
*iptr++ = (void __far*)0; *iptr++ = (void __far*)0;
}
for( scan=0; scanbucket )
{ ptr->next = list; list = ptr; }
prev = &list;
for( ptr=list; ptr; ptr=ptr->next )
{ dy = scan - ptr->y;
wide = LookUp[ptr->irad][AbsFun(dy)];
lastx = (XRange-1)-ptr->x;
if( widex);
iptr = IBuffer+ptr->x;
tptr = LookUp[wide];
dptr = dbase+ptr->x+dx;
while( dx<=lastx )
{ depth = tptr[AbsFun(dx)]+ptr->z;
UpdateScanAcross;
}
/* Remove completed atoms */
if( dy == ptr->irad )
{ *prev = ptr->next;
} else prev = &ptr->next;
} /*ptr*/
/* Process visible scanline */
prev = (Atom __far* __far*)IBuffer;
SBuffer = (void __far*)0;
dptr = dbase;
for( pos=0; posz;
#ifdef INVERT
inten = (dz<<1)+(pos-ptr->x)+(scan-ptr->y);
#else
inten = (dz<<1)+(pos-ptr->x)-(scan-ptr->y);
#endif
if( inten>0 )
{ inten = (int)( (inten*ColConst[ptr->irad])>>ColBits);
dz = *dptr-ZOffset;
dx = pos-XOffset;
dy = scan-YOffset;
ShadowX = (int)(dx*InvX[0]+dy*InvX[1]+dz*InvX[2]);
ShadowY = (int)(dx*InvY[0]+dy*InvY[1]+dz*InvY[2]);
ShadowZ = (int)(dx*InvZ[0]+dy*InvZ[1]+dz*InvZ[2]);
Exclude = ptr;
if( ShadowRay() )
{ *fptr = Lut[ptr->col+(inten>>2)];
} else *fptr = Lut[ptr->col+inten];
} else *fptr = Lut[ptr->col];
*prev = (void __far*)0;
}
dptr++; fptr++; prev++;
}
dbase = dptr;
} /*scan*/
}
#ifdef FUNCPROTO
/* Function Prototype */
static void DisplayHBonds( HBond __far *, int );
#endif
static void DisplaySpaceFill()
{
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
if( UseShadow )
{ if( !BucketFlag )
PrepareYBucket();
ScanLine();
} else if( UseClipping )
{ ForEachAtom
if( aptr->flag&SphereFlag )
ClipSphere(aptr->x,aptr->y,aptr->z,aptr->irad,aptr->col);
} else
ForEachAtom
if( aptr->flag&SphereFlag )
DrawSphere(aptr->x,aptr->y,aptr->z,aptr->irad,aptr->col);
}
static void DisplayWireframe()
{
register Bond __far *bptr;
register Atom __far *s;
register Atom __far *d;
register int sc,dc;
if( UseClipping )
{ ForEachBond
if( bptr->flag & DrawBondFlag )
{ s = bptr->srcatom; d = bptr->dstatom;
if( !bptr->col )
{ sc = s->col; dc = d->col;
} else sc = dc = bptr->col;
if( bptr->flag&WireFlag )
{ ClipTwinVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
} else if( bptr->flag&CylinderFlag )
{ if( bptr->irad>0 )
{ ClipCylinder(s->x,s->y,s->z,d->x,d->y,d->z,
sc,dc,bptr->irad);
} else ClipTwinLine(s->x,s->y,s->z,d->x,d->y,d->z,
sc+ColourMask,dc+ColourMask);
} else /* bptr->flag & DashFlag */
ClipDashVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
}
} else
ForEachBond
if( bptr->flag & DrawBondFlag )
{ s = bptr->srcatom; d = bptr->dstatom;
if( !bptr->col )
{ sc = s->col; dc = d->col;
} else sc = dc = bptr->col;
if( bptr->flag&WireFlag )
{ DrawTwinVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
} else if( bptr->flag&CylinderFlag )
{ if( bptr->irad>0 )
{ DrawCylinder(s->x,s->y,s->z,d->x,d->y,d->z,
sc,dc,bptr->irad);
} else DrawTwinLine(s->x,s->y,s->z,d->x,d->y,d->z,
sc+ColourMask,dc+ColourMask);
} else ClipDashVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
}
}
/* Used by DisplayDoubleBonds! */
static void DisplayCylinder(x1,y1,z1,x2,y2,z2,c1,c2,rad)
int x1,y1,z1,x2,y2,z2,c1,c2,rad;
{
if( UseClipping )
{ if( rad == 0 )
{ ClipTwinLine(x1,y1,z1,x2,y2,z2,c1+ColourMask,c2+ColourMask);
} else ClipCylinder(x1,y1,z1,x2,y2,z2,c1,c2,rad);
} else
{ if( rad == 0 )
{ DrawTwinLine(x1,y1,z1,x2,y2,z2,c1+ColourMask,c2+ColourMask);
} else DrawCylinder(x1,y1,z1,x2,y2,z2,c1,c2,rad);
}
}
static void DisplayDoubleBonds()
{
register Atom __far *s;
register Atom __far *d;
register Bond __far *bptr;
register int dx,dy,ix,iy;
register int ax,ay,sc,dc;
register int k,flag;
ForEachBond
if( bptr->flag & DrawBondFlag )
{ s = bptr->srcatom; d = bptr->dstatom;
if( !bptr->col )
{ sc = s->col; dc = d->col;
} else sc = dc = bptr->col;
flag = (bptr->flag&CylinderFlag) && (bptr->irad>4);
if( !(bptr->flag & DoubBondFlag) || flag )
{ if( bptr->flag&WireFlag )
{ ClipTwinVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
} else if( bptr->flag&CylinderFlag )
{ DisplayCylinder(s->x,s->y,s->z,d->x,d->y,d->z,
sc,dc,bptr->irad);
} else /* bptr->flag & DashFlag */
ClipDashVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
}
if( (bptr->flag & (DoubBondFlag|TripBondFlag)) && !flag )
{ if( s->x > d->x )
{ ax = s->x - d->x; dx = 1;
} else
{ ax = d->x - s->x; dx = 0;
}
if( s->y > d->y )
{ ay = s->y - d->y; dy = 1;
} else
{ ay = d->y - s->y; dy = 0;
}
/* Determine Bond Separation */
if( (bptr->flag&CylinderFlag) && bptr->irad )
{ if( bptr->flag & DoubBondFlag )
{ k = (3*bptr->irad+1)>>1;
} else k = 3*bptr->irad;
} else k = (bptr->flag&TripBondFlag)?3:2;
if( ax > (ay<<1) )
{ ix = 0; iy = k;
} else if( ay > (ax<<1) )
{ iy = 0; ix = k;
} else /* diagonal */
{ k = (3*k)>>2;
if( dx == dy )
{ ix = k; iy = -k;
} else
{ ix = k; iy = k;
}
}
if( bptr->flag&WireFlag )
{ ClipTwinVector(s->x+ix,s->y+iy,s->z,
d->x+ix,d->y+iy,d->z,sc,dc);
ClipTwinVector(s->x-ix,s->y-iy,s->z,
d->x-ix,d->y-iy,d->z,sc,dc);
} else if( bptr->flag&CylinderFlag )
{ DisplayCylinder(s->x+ix,s->y+iy,s->z,
d->x+ix,d->y+iy,d->z,
sc,dc,bptr->irad);
DisplayCylinder(s->x-ix,s->y-iy,s->z,
d->x-ix,d->y-iy,d->z,
sc,dc,bptr->irad);
} else /* bptr->flag & DashFlag */
{ ClipDashVector(s->x+ix,s->y+iy,s->z,
d->x+ix,d->y+iy,d->z,sc,dc);
ClipDashVector(s->x+ix,s->y+iy,s->z,
d->x+ix,d->y+iy,d->z,sc,dc);
}
}
}
}
static void DisplayBackbone()
{
register Chain __far *chain;
register Bond __far *bptr;
register Atom __far *s;
register Atom __far *d;
register int sc,dc;
ForEachBack
if( bptr->flag&DrawBondFlag )
{ s = bptr->srcatom; d = bptr->dstatom;
if( !bptr->col )
{ sc = s->col; dc = d->col;
} else sc = dc = bptr->col;
if( bptr->flag&CylinderFlag )
{ if( bptr->irad>0 )
{ ClipCylinder(s->x,s->y,s->z,d->x,d->y,d->z,
sc,dc,bptr->irad);
} else ClipTwinLine(s->x,s->y,s->z,d->x,d->y,d->z,
sc+ColourMask,dc+ColourMask);
} else if( bptr->flag & WireFlag )
{ ClipTwinVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
} else ClipDashVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
}
}
static void DisplayHBonds( list, mode )
HBond __far *list;
int mode;
{
register HBond __far *ptr;
register Atom __far *s;
register Atom __far *d;
register int sc,dc;
for( ptr=list; ptr; ptr=ptr->hnext )
if( ptr->flag & DrawBondFlag )
{ if( mode )
{ s = ptr->srcCA; d = ptr->dstCA;
if( !s || !d ) continue;
} else
{ d = ptr->src;
s = ptr->dst;
}
if( !ptr->col )
{ sc = s->col; dc = d->col;
} else sc = dc = ptr->col;
if( ptr->flag & CylinderFlag )
{ if( ptr->irad>0 )
{ ClipCylinder(s->x,s->y,s->z,d->x,d->y,d->z,
sc,dc,ptr->irad);
} else ClipTwinLine(s->x,s->y,s->z,d->x,d->y,d->z,
sc+ColourMask,dc+ColourMask);
} else ClipDashVector(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc);
}
}
static void DisplayBoxes()
{
register Real lena, lenb, lenc;
register Real tmpx, tmpy, tmpz;
register Real cosa, cosb, cosg;
register Real temp, sing;
register int xorg, yorg, zorg;
register int dxx,dxy,dxz;
register int dyx,dyy,dyz;
register int dzx,dzy,dzz;
register int x, y, z;
if( DrawAxes || DrawBoundBox )
{ dxx = (int)(MaxX*MatX[0]);
dxy = (int)(MaxX*MatY[0]);
dxz = (int)(MaxX*MatZ[0]);
dyx = (int)(MaxY*MatX[1]);
dyy = (int)(MaxY*MatY[1]);
dyz = (int)(MaxY*MatZ[1]);
dzx = (int)(MaxZ*MatX[2]);
dzy = (int)(MaxZ*MatY[2]);
dzz = (int)(MaxZ*MatZ[2]);
if( DrawAxes )
{ /* Line (MinX,0,0) to (MaxX,0,0) */
x = XOffset+dxx; y = YOffset+dxy; z = ZOffset+dxz;
if( ZValid(z) ) DisplayString(x+2,y,z,"X",BoxCol);
ClipTwinLine(XOffset-dxx,YOffset-dxy,ZOffset-dxz,
x,y,z,BoxCol,BoxCol);
/* Line (0,MinY,0) to (0,MaxY,0) */
x = XOffset+dyx; y = YOffset+dyy; z = ZOffset+dyz;
if( ZValid(z) ) DisplayString(x+2,y,z,"Y",BoxCol);
ClipTwinLine(XOffset-dyx,YOffset-dyy,ZOffset-dyz,
x,y,z,BoxCol,BoxCol);
/* Line (0,0,MinZ) to (0,0,MaxZ) */
x = XOffset-dzx; y = YOffset-dzy; z = ZOffset-dzz;
if( ZValid(z) ) DisplayString(x+2,y,z,"Z",BoxCol);
ClipTwinLine(XOffset+dzx,YOffset+dzy,ZOffset+dzz,
x,y,z,BoxCol,BoxCol);
}
if( DrawBoundBox )
{ /* Line (MinX,MinY,MinZ) to (MaxX,MinY,MinZ) */
x=XOffset-dyx-dzx; y=YOffset-dyy-dzy; z=ZOffset-dyz-dzz;
ClipTwinLine(x-dxx,y-dxy,z-dxz,x+dxx,y+dxy,z+dxz,BoxCol,BoxCol);
/* Line (MaxX,MinY,MinZ) to (MaxX,MaxY,MinZ) */
x=XOffset+dxx-dzx; y=YOffset+dxy-dzy; z=ZOffset+dxz-dzz;
ClipTwinLine(x-dyx,y-dyy,z-dyz,x+dyx,y+dyy,z+dyz,BoxCol,BoxCol);
/* Line (MaxX,MaxY,MinZ) to (MinX,MaxY,MinZ) */
x=XOffset+dyx-dzx; y=YOffset+dyy-dzy; z=ZOffset+dyz-dzz;
ClipTwinLine(x+dxx,y+dxy,z+dxz,x-dxx,y-dxy,z-dxz,BoxCol,BoxCol);
/* Line (MinX,MaxY,MinZ) to (MinX,MinY,MinZ) */
x=XOffset-dxx-dzx; y=YOffset-dxy-dzy; z=ZOffset-dxz-dzz;
ClipTwinLine(x+dyx,y+dyy,z+dyz,x-dyx,y-dyy,z-dyz,BoxCol,BoxCol);
/* Line (MinX,MinY,MinZ) to (MinX,MinY,MaxZ) */
x=XOffset-dxx-dyx; y=YOffset-dxy-dyy; z=ZOffset-dxz-dyz;
ClipTwinLine(x-dzx,y-dzy,z-dzz,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
/* Line (MaxX,MinY,MinZ) to (MaxX,MinY,MaxZ) */
x=XOffset+dxx-dyx; y=YOffset+dxy-dyy; z=ZOffset+dxz-dyz;
ClipTwinLine(x-dzx,y-dzy,z-dzz,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
/* Line (MaxX,MaxY,MinZ) to (MaxX,MaxY,MaxZ) */
x=XOffset+dxx+dyx; y=YOffset+dxy+dyy; z=ZOffset+dxz+dyz;
ClipTwinLine(x-dzx,y-dzy,z-dzz,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
/* Line (MinX,MaxY,MinZ) to (MinX,MaxY,MaxZ) */
x=XOffset-dxx+dyx; y=YOffset-dxy+dyy; z=ZOffset-dxz+dyz;
ClipTwinLine(x-dzx,y-dzy,z-dzz,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
/* Line (MinX,MinY,MaxZ) to (MaxX,MinY,MaxZ) */
x=XOffset-dyx+dzx; y=YOffset-dyy+dzy; z=ZOffset-dyz+dzz;
ClipTwinLine(x-dxx,y-dxy,z-dxz,x+dxx,y+dxy,z+dxz,BoxCol,BoxCol);
/* Line (MaxX,MinY,MaxZ) to (MaxX,MaxY,MaxZ) */
x=XOffset+dxx+dzx; y=YOffset+dxy+dzy; z=ZOffset+dxz+dzz;
ClipTwinLine(x-dyx,y-dyy,z-dyz,x+dyx,y+dyy,z+dyz,BoxCol,BoxCol);
/* Line (MaxX,MaxY,MaxZ) to (MinX,MaxY,MaxZ) */
x=XOffset+dyx+dzx; y=YOffset+dyy+dzy; z=ZOffset+dyz+dzz;
ClipTwinLine(x+dxx,y+dxy,z+dxz,x-dxx,y-dxy,z-dxz,BoxCol,BoxCol);
/* Line (MinX,MaxY,MaxZ) to (MinX,MinY,MaxZ) */
x=XOffset-dxx+dzx; y=YOffset-dxy+dzy; z=ZOffset-dxz+dzz;
ClipTwinLine(x+dyx,y+dyy,z+dyz,x-dyx,y-dyy,z-dyz,BoxCol,BoxCol);
}
}
if( DrawUnitCell && *InfoSpaceGroup )
{ /* Calculate Unit Cell! */
lena = 250.0*InfoCellA;
lenb = 250.0*InfoCellB;
lenc = -250.0*InfoCellC;
cosa = cos(InfoCellAlpha);
cosb = cos(InfoCellBeta);
cosg = cos(InfoCellGamma);
sing = sin(InfoCellGamma);
temp = cosa*cosa + cosb*cosb + cosg*cosg - 2.0*cosa*cosb*cosg;
tmpx = cosb;
tmpy = (cosa - cosb*cosg)/sing;
tmpz = sqrt(1.0-temp)/sing;
dxx = (int)(lena*MatX[0]);
dxy = (int)(lena*MatY[0]);
dxz = (int)(lena*MatZ[0]);
dyx = (int)(lenb*(cosg*MatX[0] + sing*MatX[1]));
dyy = (int)(lenb*(cosg*MatY[0] + sing*MatY[1]));
dyz = (int)(lenb*(cosg*MatZ[0] + sing*MatZ[1]));
dzx = (int)(lenc*(tmpx*MatX[0] + tmpy*MatX[1] + tmpz*MatX[2]));
dzy = (int)(lenc*(tmpx*MatY[0] + tmpy*MatY[1] + tmpz*MatY[2]));
dzz = (int)(lenc*(tmpx*MatZ[0] + tmpy*MatZ[1] + tmpz*MatZ[2]));
xorg = XOffset - (int)(OrigCX*MatX[0]+OrigCY*MatX[1]+OrigCZ*MatX[2]);
yorg = YOffset - (int)(OrigCX*MatY[0]+OrigCY*MatY[1]+OrigCZ*MatY[2]);
zorg = ZOffset + (int)(OrigCX*MatZ[0]+OrigCY*MatZ[1]+OrigCZ*MatZ[2]);
/* Draw Unit Cell! */
x = xorg;
y = yorg;
z = zorg;
ClipTwinLine(x,y,z,x+dxx,y+dxy,z+dxz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x+dyx,y+dyy,z+dyz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
x = xorg + dxx + dyx;
y = yorg + dxy + dyy;
z = zorg + dxz + dyz;
ClipTwinLine(x,y,z,x-dxx,y-dxy,z-dxz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x-dyx,y-dyy,z-dyz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x+dzx,y+dzy,z+dzz,BoxCol,BoxCol);
x = xorg + dxx + dzx;
y = yorg + dxy + dzy;
z = zorg + dxz + dyz;
ClipTwinLine(x,y,z,x-dxx,y-dxy,z-dxz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x+dyx,y+dyy,z+dyz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x-dzx,y-dzy,z-dzz,BoxCol,BoxCol);
x = xorg + dyx + dzx;
y = yorg + dyy + dzy;
z = zorg + dyz + dzz;
ClipTwinLine(x,y,z,x+dxx,y+dxy,z+dxz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x-dyx,y-dyy,z-dyz,BoxCol,BoxCol);
ClipTwinLine(x,y,z,x-dzx,y-dzy,z-dzz,BoxCol,BoxCol);
}
}
static void DisplaySelected()
{
register Atom __far *s, __far *d;
register Chain __far *chain;
register Group __far *group;
register Bond __far *bptr;
register Atom __far *aptr;
register int irad,sc,dc;
register int col;
irad = (int)(Scale*20);
if( irad>0 )
{ ForEachBond
{ s = bptr->srcatom;
col = (s->flag&SelectFlag)? 1 : 0;
sc = Shade2Colour(col);
d = bptr->dstatom;
col = (d->flag&SelectFlag)? 1 : 0;
dc = Shade2Colour(col);
ClipCylinder(s->x,s->y,s->z,d->x,d->y,d->z,sc,dc,irad);
}
} else ForEachBond
{ s = bptr->srcatom;
col = (s->flag&SelectFlag)? 1 : 0;
sc = Shade2Colour(col);
d = bptr->dstatom;
col = (d->flag&SelectFlag)? 1 : 0;
dc = Shade2Colour(col);
ClipTwinLine(s->x,s->y,s->z,d->x,d->y,d->z,
sc+ColourMask,dc+ColourMask);
}
irad = (int)(Scale*50);
ForEachAtom
if( aptr->flag&NonBondFlag )
{ col = Shade2Colour( (aptr->flag&SelectFlag)? 1 : 0 );
ClipSphere(aptr->x,aptr->y,aptr->z,irad,col);
}
}
static void RenderFrame()
{
register Chain __far *chain;
if( !DisplayMode )
{ if( DrawAtoms )
DisplaySpaceFill();
if( !UseSlabPlane || (SlabMode != SlabSection) )
{ if( DrawBonds )
{ if( DrawDoubleBonds )
{ DisplayDoubleBonds();
} else DisplayWireframe();
}
if( DrawRibbon )
for( chain=Database->clist; chain; chain=chain->cnext )
if( chain->glist )
DisplayRibbon( chain );
if( DrawDots ) DisplaySurface();
if( DrawLabels ) DisplayLabels();
if( MonitList ) DisplayMonitors();
DisplayHBonds( Database->slist, SSBondMode );
DisplayHBonds( Database->hlist, HBondMode );
DisplayBackbone();
}
} else DisplaySelected();
DisplayBoxes();
}
void DrawFrame()
{
register double temp;
register int wide;
if( !Database )
return;
ClearBuffers();
if( !DisplayMode )
{ if( UseShadow && DrawAtoms )
if( !VoxelsClean )
CreateVoxelData( SphereFlag );
}
if( UseSlabPlane )
{ SlabValue = (int)(DialValue[7]*ImageRadius)+ZOffset;
SlabInten = (int)(ColourMask*TwoOverRootSix);
SliceValue = SlabValue+16;
UseClipping = True;
} else UseClipping = UseScreenClip;
#ifdef IBMPC
/* Lock Buffers into Memory */
FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
DBuffer = (short __huge*)GlobalLock(DBufHandle);
#endif
/* Common View Elements */
View.yskip = XRange;
View.ymax = YRange;
if( UseStereo )
{ temp = StereoAngle/180.0;
wide = XRange>>1;
/* Create 'Left' View structure */
View.fbuf = FBuffer;
View.dbuf = DBuffer;
View.xmax = wide;
DialValue[1] -= temp;
ReDrawFlag |= RFRotateY;
ApplyTransform();
RenderFrame();
/* Create 'Right' View structure */
View.fbuf = FBuffer+wide;
View.dbuf = DBuffer+wide;
View.xmax = wide;
DialValue[1] += temp;
ReDrawFlag |= RFRotateY;
ApplyTransform();
RenderFrame();
} else /* Mono */
{ /* Create 'Mono' View structure */
View.fbuf = FBuffer;
View.dbuf = DBuffer;
View.xmax = XRange;
RenderFrame();
}
#ifdef IBMPC
/* Unlock Buffers */
GlobalUnlock(FBufHandle);
GlobalUnlock(DBufHandle);
#endif
DBClear = False;
FBClear = False;
}
#ifdef FUNCPROTO
/* Function Prototype */
static void TestAtomProximity( Atom __far *, int, int );
#endif
static void TestAtomProximity( ptr, xpos, ypos )
Atom __far *ptr;
int xpos, ypos;
{
register Long dist;
register int dx,dy;
if( UseSlabPlane && (ptr->z>SlabValue) )
return;
dx = ptr->x - xpos;
dy = ptr->y - ypos;
dist = (Long)dx*dx + (Long)dy*dy;
if( IdentFound )
{ if( dist==IdentDist )
{ if( ptr->zIdentDist )
return;
}
IdentDepth = ptr->z;
IdentFound = True;
IdentDist = dist;
QAtom = ptr;
}
static void IdentifyAtom( xpos, ypos )
int xpos, ypos;
{
register int rad, wide, dpth;
register int new, dx, dy, dz;
register Chain __far *chain;
register Group __far *group;
register HBond __far *hptr;
register Atom __far *aptr;
register Bond __far *bptr;
/* Reset Search */
QChain = (void __far*)0;
QGroup = (void __far*)0;
QAtom = (void __far*)0;
IdentFound = False;
if( !DisplayMode )
{ if( !UseSlabPlane || (SlabMode != SlabSection) )
{ if( DrawBonds )
ForEachBond
if( bptr->flag&DrawBondFlag )
{ TestAtomProximity(bptr->srcatom,xpos,ypos);
TestAtomProximity(bptr->dstatom,xpos,ypos);
}
ForEachBack
if( bptr->flag&DrawBondFlag )
{ TestAtomProximity(bptr->srcatom,xpos,ypos);
TestAtomProximity(bptr->dstatom,xpos,ypos);
}
for( hptr=Database->hlist; hptr; hptr=hptr->hnext )
if( hptr->flag )
{ if( HBondMode )
{ TestAtomProximity(hptr->srcCA,xpos,ypos);
TestAtomProximity(hptr->dstCA,xpos,ypos);
} else
{ TestAtomProximity(hptr->src,xpos,ypos);
TestAtomProximity(hptr->dst,xpos,ypos);
}
}
for( hptr=Database->slist; hptr; hptr=hptr->hnext )
if( hptr->flag )
{ if( HBondMode )
{ TestAtomProximity(hptr->srcCA,xpos,ypos);
TestAtomProximity(hptr->dstCA,xpos,ypos);
} else
{ TestAtomProximity(hptr->src,xpos,ypos);
TestAtomProximity(hptr->dst,xpos,ypos);
}
}
}
ForEachAtom
{ /* Identify bond! */
if( aptr == QAtom )
{ QChain = chain;
QGroup = group;
}
if( aptr->flag & SphereFlag )
{ dy = AbsFun(aptr->y-ypos);
if( dy>aptr->irad ) continue;
rad = LookUp[aptr->irad][dy];
dx = AbsFun(aptr->x-xpos);
if( dx>rad ) continue;
new = False;
dpth = aptr->z+LookUp[rad][dx];
if( UseSlabPlane && (aptr->z+rad>=SlabValue) )
{ dz = SlabValue-aptr->z;
if( SlabMode && (dz >= -rad) )
{ wide = LookUp[aptr->irad][AbsFun(dz)];
if( (dy<=wide) && (dx<=(int)(LookUp[wide][dy])) )
{ if( SlabMode == SlabFinal )
{ dpth = SliceValue;
new = True;
} else if( SlabMode == SlabHollow )
{ dpth = aptr->z-LookUp[rad][dx];
new = !IdentFound || (dpth>IdentDepth);
} else if( SlabMode != SlabHalf )
{ /* SlabClose, SlabSection */
dpth = dx*dx+dy*dy+dz*dz+SliceValue;
if( IdentFound )
{ new = (IdentDepth0) && (SlabMode!=SlabSection) )
new = !IdentFound || (dpth>IdentDepth);
}
} else if( !UseSlabPlane || (SlabMode != SlabSection) )
new = !IdentFound || IdentDist || (dpth>IdentDepth);
if( new )
{ IdentFound = True;
IdentDepth = dpth;
IdentDist = 0;
QChain = chain;
QGroup = group;
QAtom = aptr;
}
}
}
} else /* Display Mode */
{ ForEachAtom
{ TestAtomProximity(aptr,xpos,ypos);
/* Identify bond! */
if( aptr == QAtom )
{ QChain = chain;
QGroup = group;
}
}
}
if( !IdentFound || (IdentDist>=50) )
{ /* Reset Pick Atom! */
QChain = (void __far*)0;
QGroup = (void __far*)0;
QAtom = (void __far*)0;
}
}
void SetPickMode( mode )
int mode;
{
PickMode = mode;
PickCount = 0;
}
static void DescribeAtom( ptr, flag )
AtomRef *ptr; int flag;
{
register char *str;
register int i,ch;
char buffer[40];
str = Residue[ptr->grp->refno];
for( i=0; i<3; i++ )
if( str[i]!=' ' )
WriteChar(str[i]);
sprintf(buffer,"%d",ptr->grp->serno);
WriteString(buffer);
ch = ptr->chn->ident;
if( ch != ' ' )
{ if( isdigit(ch) )
WriteChar(':');
WriteChar(ch);
}
WriteChar('.');
str = ElemDesc[ptr->atm->refno];
for( i=0; i<3; i++ )
if( str[i]!=' ' )
WriteChar(str[i]);
if( flag )
{ sprintf(buffer," (%d)",ptr->atm->serno);
WriteString(buffer);
}
}
void PickAtom( shift, xpos, ypos )
int shift, xpos, ypos;
{
register AtomRef *ptr;
register Label *label;
register float temp;
register char *str;
register int len;
char buffer[40];
AtomRef ref;
if( PickMode == PickNone )
return;
IdentifyAtom(xpos,ypos);
if( QAtom )
{ if( PickMode == PickIdent )
{ if( CommandActive )
WriteChar('\n');
CommandActive = False;
WriteString("Atom: ");
str = ElemDesc[QAtom->refno];
if( str[0]!=' ' ) WriteChar(str[0]);
WriteChar(str[1]); WriteChar(str[2]);
if( str[3]!=' ' ) WriteChar(str[3]);
sprintf(buffer," %d ",QAtom->serno);
WriteString(buffer);
str = Residue[QGroup->refno];
if( QAtom->flag&HeteroFlag )
{ WriteString("Hetero: ");
} else WriteString("Group: ");
if( str[0]!=' ' ) WriteChar(str[0]);
WriteChar(str[1]); WriteChar(str[2]);
sprintf(buffer," %d",QGroup->serno);
WriteString(buffer);
if( QChain->ident!=' ' )
{ WriteString(" Chain: ");
WriteChar(QChain->ident);
}
WriteChar('\n');
} else if( PickMode == PickLabel )
{ if( !QAtom->label )
{ if( MainGroupCount > 1 )
{ strcpy(buffer,"%n%r");
str = buffer+4;
if( InfoChainCount > 1 )
{ if( isdigit(QChain->ident) )
*str++ = ':';
*str++ = '%';
*str++ = 'c';
}
strcpy(str,".%a");
len = (str-buffer) + 3;
label = CreateLabel(buffer,len);
} else label = CreateLabel("%e%i",4);
QAtom->label = label;
label->refcount++;
} else
{ DeleteLabel( (Label*)QAtom->label );
QAtom->label = (void*)0;
}
DrawLabels = LabelList? True : False;
ReDrawFlag |= RFRefresh;
} else if( PickMode == PickCentr )
{ CenX = QAtom->xorg;
CenY = QAtom->yorg;
CenZ = QAtom->zorg;
ref.chn = QChain;
ref.grp = QGroup;
ref.atm = QAtom;
if( CommandActive )
WriteChar('\n');
CommandActive = False;
WriteString("Rotating about ");
DescribeAtom(&ref,True);
WriteChar('\n');
} else if( PickMode == PickMonit )
{ /* State Machine Implementation */
if( PickCount == 0 )
{ PickHist[0].atm = QAtom;
PickCount = 1;
} else if( PickCount == 1 )
{ if( !shift )
{ if( PickHist[0].atm != QAtom )
{ AddMonitors(PickHist[0].atm,QAtom);
ReDrawFlag |= RFRefresh;
}
PickCount = 2;
} else PickHist[0].atm = QAtom;
} else /* PickCount == 2 */
if( !shift )
{ PickHist[0].atm = QAtom;
PickCount = 1;
} else if( PickHist[0].atm != QAtom )
{ AddMonitors(PickHist[0].atm,QAtom);
ReDrawFlag |= RFRefresh;
}
} else /* Distance, Angle or Torsion! */
{ if( PickCount )
{ if( shift )
{ PickCount--;
} else if( PickCount == PickMode )
PickCount = 0;
}
ptr = PickHist+PickCount;
ptr->chn = QChain;
ptr->grp = QGroup;
ptr->atm = QAtom;
PickCount++;
if( CommandActive )
WriteChar('\n');
CommandActive = False;
WriteString("Atom #");
WriteChar(PickCount+'0');
WriteString(": ");
DescribeAtom(ptr,True);
WriteChar('\n');
if( PickCount == PickMode )
{ if( PickMode == PickDist )
{ temp = (float)CalcDistance(PickHist[0].atm,
PickHist[1].atm);
WriteString("Distance ");
DescribeAtom(PickHist,False);
WriteChar('-');
DescribeAtom(PickHist+1,False);
sprintf(buffer,": %.3f\n\n",temp);
WriteString(buffer);
} else if( PickMode == PickAngle )
{ temp = (float)CalcAngle(PickHist[0].atm,
PickHist[1].atm,
PickHist[2].atm);
WriteString("Angle ");
DescribeAtom(PickHist,False);
WriteChar('-');
DescribeAtom(PickHist+1,False);
WriteChar('-');
DescribeAtom(PickHist+2,False);
sprintf(buffer,": %.1f\n\n",temp);
WriteString(buffer);
} else /* PickMode == PickTorsn */
{ temp = (float)CalcTorsion(PickHist[0].atm,
PickHist[1].atm,
PickHist[2].atm,
PickHist[3].atm);
WriteString("Torsion ");
DescribeAtom(PickHist,False);
WriteChar('-');
DescribeAtom(PickHist+1,False);
WriteChar('-');
DescribeAtom(PickHist+2,False);
WriteChar('-');
DescribeAtom(PickHist+3,False);
sprintf(buffer,": %.1f\n\n",temp);
WriteString(buffer);
}
}
}
}
}
void SetStereoMode( enable )
int enable;
{
StereoView = ViewLeft;
UseStereo = enable;
DetermineClipping();
}
void ResetRenderer()
{
DrawAtoms = False; MaxAtomRadius = 0;
DrawBonds = False; MaxBondRadius = 0;
DrawRibbon = False; DrawDots = False;
SlabMode = SlabClose;
UseSlabPlane = False;
UseLabelCol = False;
UseShadow = False;
UseDepthCue = False;
SSBondMode = False;
HBondMode = False;
DisplayMode = 0;
DrawDoubleBonds = False;
DrawBoundBox = False;
DrawUnitCell = False;
DrawAxes = False;
SetStereoMode(False);
StereoAngle = 6.0;
}
static void InitialiseTables()
{
register Byte __far *ptr;
register unsigned int root,root2;
register unsigned int i,rad,arg;
ptr = Array;
LookUp[0] = ptr; *ptr++ = 0;
LookUp[1] = ptr; *ptr++ = 1; *ptr++ = 0;
for( rad=2; rad
|