|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5276 (0x149c)
Types: TextFile
Notes: UNIX file
Names: »gline.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »hr/src/smgr/gline.c«
#include "graph.h"
#define BPW 16 /* bits per word */
extern int myfd;
/*
* gkLine(x, y, xf, yf, pat, logop, width)
*
* Draw a straight line from (x,y) to (xf,yf) using the parameters:
* logop: logical operation
* pat: pattern number
* width: pen width
* height: pen height
*
* Return: nothing
*/
void gkLine();
/*
* Local functions.
*/
void lnvector(), /* single line vector: calls lnxfast or lnyfast */
lnxfast(), /* single line: dx > 0, dx > abs(dy) */
lnyfast(); /* single line: dy > 0, dy > abs(dx) */
/*
* Logical operation functions: src logop dst
*/
extern uint _lfalse(),
_land(),
_landn(),
_lsrc(),
_lnand(),
_ldst(),
_lxor(),
_lor(),
_lnandn(),
_lnxor(),
_lndst(),
_lorn(),
_lnsrc(),
_lnor(),
_lnorn(),
_ltrue();
static RECT lnBox; /* vis rect ANDed with gkClip */
static int lnRn, /* #of clipping rects in lnRect */
lnPat; /* pattern number */
static uint (*lnFtn)(), /* ^current logical function */
(*lnFtnTbl[L_BLTMAX])() =
{
_lfalse, _land, _landn, _lsrc,
_lnand, _ldst, _lxor, _lor,
_lnandn, _lnxor, _lndst, _lorn,
_lnsrc, _lnor, _lnorn, _ltrue
};
void
gkLine(x, y, xf, yf, pat, logop)
register int x,
y,
xf,
yf;
int pat,
logop;
{
register SM_REGION *sp;
int mseoff;
if ( (lnPat = pat) >= MAXPAT )
return;
if ( logop >= L_BLTMAX )
return;
lnFtn = lnFtnTbl[logop];
if ( mseoff = (logop != L_NDST && logop != L_XOR && logop != L_NXOR) )
ioctl(myfd, CIOMSEOFF);
for ( sp = gk.wn_Layer->reg; sp < gk.wn_Layer->reg+MAX_LRBUF; sp++ )
{
if ( sp->flag == L_EMPTY )
break;
if ( sp->flag == L_VISIBLE )
{
lnBox = R_Intersection(sp->bm.rect, gkCrect);
if ( !R_null(lnBox) )
lnvector(x, y, xf, yf);
}
}
if ( mseoff )
ioctl(myfd, CIOMSEON);
}
/*
* Clips the endpoints of the vector to the boundaries of lnBox.
* Then does the line.
*/
void
lnvector(x, y, xf, yf)
register int x,
y,
xf,
yf;
{
long e;
register int dx,
dy;
dx = xf - x;
dy = yf - y;
e = (long)yf*(long)x - (long)y*(long)xf;
if (dy >= 0)
{
if ( (y >= lnBox.corner.y) || (yf < lnBox.origin.y) )
return;
if ( y < lnBox.origin.y )
x = ((long)(y = lnBox.origin.y)*(long)dx + e) / dy;
if ( yf >= lnBox.corner.y )
xf = ((long)(yf = lnBox.corner.y-1)*(long)dx + e) / dy;
}
else
{
if ( (yf >= lnBox.corner.y) || (y < lnBox.origin.y) )
return;
if ( yf < lnBox.origin.y )
xf = ((long)(yf = lnBox.origin.y)*(long)dx + e) / dy;
if ( y >= lnBox.corner.y )
x = ((long)(y = lnBox.corner.y-1)*(long)dx + e) / dy;
}
if (dx > 0)
{
if ( (x >= lnBox.corner.x) || (xf < lnBox.origin.x) )
return;
if ( x < lnBox.origin.x )
y = ((long)(x = lnBox.origin.x)*(long)dy - e) / dx;
if ( xf >= lnBox.corner.x )
yf = ((long)(xf = lnBox.corner.x-1)*(long)dy - e) / dx;
if ( dy > 0 )
if ( dx > dy )
lnxfast(x, y, xf, yf);
else
lnyfast(x, y, xf, yf);
else
if ( dx > -dy )
lnxfast(x, y, xf, yf);
else
lnyfast(xf, yf, x, y);
}
else
{
if ( (xf >= lnBox.corner.x) || (x < lnBox.origin.x) )
return;
if ( xf < lnBox.origin.x )
yf = ((long)(xf = lnBox.origin.x)*(long)dy - e) / dx;
if ( x >= lnBox.corner.x )
y = ((long)(x = lnBox.corner.x-1)*(long)dy - e) / dx;
if ( dy > 0 )
if ( -dx > dy )
lnxfast(xf, yf, x, y);
else
lnyfast(x, y, xf, yf);
else
if ( -dx > -dy )
lnxfast(xf, yf, x, y);
else
lnyfast(xf, yf, x, y);
}
}
void
lnxfast(x, y, xf, yf)
register int x,
y;
int xf,
yf;
{
register uint *vp;
register int rem;
register int dx,
dy,
sy;
int *pat;
uint bit;
extern short *xxx();
dx = xf - x;
dy = yf - y;
sy = 1;
if (dy < 0)
{
dy = -dy;
sy = -1;
}
rem = dx/2;
vp = xxx(x, y, &bit);
pat = gkTexture(lnPat) + (y & 0xf);
loop {
*vp = (*lnFtn)(*pat, *vp, bit);
if ( ++x > xf )
break;
bit >>= 1;
if (bit == 0)
{
bit = 0x8000;
++vp;
}
if ( (rem -= dy) < 0 )
{
rem += dx;
y += sy;
if ( sy > 0 )
{
vp = addptr(vp, (ulong)2*XMAX/BPW);
if ( y & 0xf )
pat++;
else
pat -= 15;
}
else
{
vp = subptr(vp, (ulong)2*XMAX/BPW);
if ( (y & 0xf) == 0xf )
pat += 15;
else
pat--;
}
}
}
}
void
lnyfast(x, y, xf, yf)
register int x,
y;
int xf,
yf;
{
register uint *vp;
register int rem;
register int dx,
dy,
sx;
int *pat;
uint bit;
dx = xf - x;
dy = yf - y;
sx = 1;
if ( dx < 0)
{
dx = -dx;
sx = -1;
}
rem = dy/2;
vp = xxx(x, y, &bit);
pat = gkTexture(lnPat) + (y & 0xf);
loop {
*vp = (*lnFtn)(*pat, *vp, bit);
if ( ++y > yf )
break;
if ( y & 0xf )
pat++;
else
pat -= 15;
vp = addptr(vp, (ulong) 2*XMAX/BPW);
if ( (rem -= dx) < 0 )
{
rem += dy;
x += sx;
if ( sx > 0)
{
bit >>= 1;
if (bit == 0)
{
bit = 0x8000;
++vp;
}
}
else
{
bit <<= 1;
if (bit == 0)
{
bit = 1;
--vp;
}
}
}
}
}
/*
* Calculates the word address of the pixel and sets the bit of
* the word mask 'bit' of the pixel of interest.
*/
static short *
xxx(x, y, bit)
register uint x,
y;
uint *bit;
{
int *ip;
*bit = (uint)0x8000 >> (x%BPW);
return addptr(SEG0, (ulong)y*(ulong)(sizeof(int)*XMAX/BPW) + sizeof(int) * x/BPW);
}