|
|
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: 13568 (0x3500)
Types: TextFile
Notes: UNIX file
Names: »bitblt.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »hr/src/smgr/bitblt.c«
#include <stdio.h>
#include "smgr.h"
#define lessptr(w1,b1,w2,b2) (w1<w2 || (w1==w2 && b1<b2))
#define BOTTOM_UP (0)
#define TOP_DOWN (1)
extern int myfd;
extern POINT SM_Mouse_Pos;
extern bool R_point_in();
int spao, ds, ss, spat[16];
long mask2;
extern int *texture[]; /* global array of pointers to stippling patterns */
extern int *addptr(), *subptr();
extern lf0(), lf1(), lf2(), lf3(), lf4(), lf5(), lf6(), lf7();
extern lf8(), lf9(), lf10(), lf11(), lf12(), lf13(), lf14(), lf15();
int (*logical)();
int (*logtab[16])() = { lf0, lf1, lf2, lf3, lf4, lf5, lf6, lf7,
lf8, lf9, lf10, lf11, lf12, lf13, lf14, lf15 };
unsigned sw;
unsigned *sp;
int snb;
int *BLT_sptrw; /* src ^ */
int BLT_sptrb; /* bit position within source */
int BLT_sinc; /* # of bytes to increment src ^ for next raster */
int *BLT_dptrw; /* dst ^ */
int BLT_dptrb; /* bit position within destination */
int BLT_dinc; /* # of bytes to increment dst ^ for next raster */
int BLT_lmask; /* BLT_left mask */
int BLT_rmask; /* right mask */
int BLT_left; /* true(1) if BLT_left partial word */
int BLT_right; /* true(1) if right partial word */
int BLT_words; /* # of whole words in raster line */
int BLT_height; /* height ( # of rasters ) to be done */
int BLT_width; /* # of pixels per raster */
int *BLT_pat_ptr; /* ^ to the stippling pattern */
int BLT_pat_index; /* index into the stippling pattern */
int (*BLT_function)(); /* function to execute */
int BLT_op; /* the logical operation index (0-15) */
int BLT_direction; /* top-down (1) or bottom-up(0) */
int BLTtrue[64] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};
int BLTfalse[64] = { 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,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
int BLT_tbl1[] = { 0x0,
0x0001, 0x0003, 0x0007, 0x000f,
0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff,
0x1fff, 0x3fff, 0x7fff, 0xffff
};
int BLT_tbl2[] = { 0x0,
0x8000, 0xc000, 0xe000, 0xf000,
0xf800, 0xfc00, 0xfe00, 0xff00,
0xff80, 0xffc0, 0xffe0, 0xfff0,
0xfff8, 0xfffc, 0xfffe, 0xffff
};
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* */
/* bitblt - */
/* */
/* NOTE: this version may! not handle small overlap within */
/* the same raster line */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
bitblt(blt, clip, mouse)
BLTSTRUCT *blt;
int clip, /* 1 == yes, 0 == no */
mouse; /* 1 = worry about, 0 == hands off */
{
BLTSTRUCT b;
register int i; /* an oft used integer variable */
uint lbits,
rbits,
*dst,
db1,
db2,
w,
dw;
RECT srect, /* local rectangle for the src bitmap */
drect; /* local rectangle for the dst bitmap */
RECT mrect;
uint mouse_off;
long long_inc;
b = *blt;
#ifdef DEBUG
printf("\nBITBLT--------\n");
printf("\tb.src(handle) : 0x%lx, (%d,%d)(%d,%d) w = %d\n", b.src->base,
b.src->rect.origin.x, b.src->rect.origin.y,
b.src->rect.corner.x, b.src->rect.corner.y,
b.src->width);
printf("\tb.dst(handle) : 0x%lx, (%d,%d)(%d,%d) w = %d\n", b.dst->base,
b.dst->rect.origin.x, b.dst->rect.origin.y,
b.dst->rect.corner.x, b.dst->rect.corner.y,
b.dst->width);
printf("\tb.dr = (%d,%d)(%d,%d), point = (%d,%d) ",
b.dr.origin.x, b.dr.origin.y,
b.dr.corner.x, b.dr.corner.y,
b.sp.x, b.sp.y);
printf("OP = %d\n", b.op);
#endif
srect = b.src->rect;
drect = b.dst->rect;
/* if illegal b.op, bail out */
if ( b.op > L_BLTMAX ) /* replace this with L_BLTMAX */
#ifdef DEBUG
{
printf("bitblt returns with bad op\n");
#endif
return;
#ifdef DEBUG
}
#endif
mouse_off = 0;
/* clip the x coordinates ... see SIGGRAPH '84 vol 6 */
if ( clip )
{
i = b.sp.x - srect.origin.x;
if ( i < 0 )
{
b.sp.x -= i;
b.dr.origin.x -= i;
}
i = b.dr.origin.x - drect.origin.x;
if ( i < 0 )
{
b.sp.x -= i;
b.dr.origin.x -= i;
}
i = b.dr.corner.x - drect.corner.x;
if ( i > 0 )
b.dr.corner.x -= i;
i = b.sp.x + (b.dr.corner.x - b.dr.origin.x) - srect.corner.x;
if ( i > 0 )
b.dr.corner.x -= i;
/* clip the y coordinates...see SIGGRAPH '84 vol 6 */
i = b.sp.y - srect.origin.y;
if ( i < 0 )
{
b.sp.y -= i;
b.dr.origin.y -= i;
}
i = b.dr.origin.y - drect.origin.y;
if ( i < 0 )
{
b.sp.y -= i;
b.dr.origin.y -= i;
}
i = b.dr.corner.y - drect.corner.y;
if ( i > 0 )
b.dr.corner.y -= i;
i = b.sp.y + (b.dr.corner.y - b.dr.origin.y) - srect.corner.y;
if ( i > 0 )
b.dr.corner.y -= i;
}
BLT_width = b.dr.corner.x - b.dr.origin.x;
BLT_height = b.dr.corner.y - b.dr.origin.y;
/* if there is nothing left after clipping, return */
if ( BLT_width <= 0 || BLT_height <= 0 )
return;
#ifdef DEBUG
printf("\tafter clip : b.dr = (%d,%d)(%d,%d), point = (%d,%d)\n",
b.dr.origin.x, b.dr.origin.y,
b.dr.corner.x, b.dr.corner.y,
b.sp.x, b.sp.y);
printf("\theight = %d, width = %d\n", BLT_height, BLT_width);
#endif
BLT_sptrw = b.src->base;
BLT_sptrb = srect.origin.x & 15; /* &15 == %16 */
BLT_dptrw = b.dst->base;
BLT_dptrb = drect.origin.x & 15; /* &15 == %16 */
long_inc = b.sp.x - srect.origin.x +
b.src->width*(long)(b.sp.y-srect.origin.y);
if ( long_inc != 0L )
incptr(&BLT_sptrw ,&BLT_sptrb, long_inc );
long_inc = b.dr.origin.x - drect.origin.x +
b.dst->width*(long)(b.dr.origin.y - drect.origin.y);
if ( long_inc != 0L )
incptr(&BLT_dptrw , &BLT_dptrb, long_inc );
BLT_sinc = (int) (b.src->width >> 3 );
BLT_dinc = (int) (b.dst->width >> 3 );
spao = ( b.pat == texture[0]);
BLT_op = b.op;
BLT_direction = TOP_DOWN;
BLT_pat_ptr = (int*)b.pat;
BLT_pat_index = b.dr.origin.y & 15;
if ( BLT_width <= 16 )
{
if ( (b.op != L_CHAR) &&
(lessptr(BLT_sptrw, BLT_sptrb, BLT_dptrw, BLT_dptrb) ) )
{
BLT_direction = BOTTOM_UP;
long_inc = (long)BLT_height;
long_inc -= (long)1;
long_inc *= (long)BLT_sinc;
BLT_sptrw = addptr(BLT_sptrw, long_inc);
long_inc = (long)BLT_height;
long_inc -= (long)1;
long_inc *= (long)BLT_dinc;
BLT_dptrw = addptr(BLT_dptrw, long_inc);
BLT_pat_index = (BLT_pat_index + BLT_height) & 15;
if (lessptr(BLT_dptrw,BLT_dptrb,BLT_sptrw,BLT_sptrb) )
return;
}
BLT_pat_index *= 2;
#ifdef DEBUG
printf("\t\tSMALL\n");
#endif
if ( mouse )
if ( b.op == L_XOR || b.op == L_NXOR || b.op == L_NDST)
;
else
{
mrect = b.dr;
mrect.origin.x -= 64;
mrect.origin.y -= 64;
mrect.corner.x += 64;
mrect.corner.y += 64;
if ( R_point_in(mrect, SM_Mouse_Pos))
{
mouse_off = 1;
ioctl(myfd, CIOMSEOFF, (char*)NULL);
}
}
if ( b.op == L_CHAR )
BLT_op = L_SRC;
BLT_small();
#ifdef DEBUG
printf("bitblt returns\n");
#endif
if ( mouse_off )
ioctl(myfd, CIOMSEON, (char*)NULL);
return;
}
db1 = 15 - (BLT_dptrb & 15);
db2 = 15 - ((BLT_width + BLT_dptrb - 1) & 15);
BLT_words = ((BLT_width+BLT_dptrb-1) >> 4) - (BLT_dptrb >> 4) +
1 - (db1!=15?1:0) - (db2?1:0);
if ( BLT_words < 0 )
BLT_words = 0;
BLT_lmask = ( 2 << db1) - 1 -
( BLT_width < db1+1 ? (2 << (db1-BLT_width)) -1 : 0);
BLT_left = (db1 != 15) && (db1 < BLT_width-1);
if ( db2 || BLT_width < 16 - db2 )
{
BLT_right = 1;
BLT_rmask = ~((1 << db2) - 1 );
if ( BLT_width < 16 - db2 )
BLT_rmask -= ~((2 << db1) - 1 );
}
else
BLT_right = 0;
if ( BLT_dptrb == BLT_sptrb || b.op == 0 || b.op == 15 )
{
if ( b.op == 0 || b.op == 15 )
{
BLT_pat_index *= 2;
if ( mouse )
{
mouse_off = 1;
ioctl(myfd, CIOMSEOFF, (char*)NULL);
}
BLT_block();
#ifdef DEBUG
printf("bitblt returns\n");
#endif
if ( mouse_off )
ioctl(myfd, CIOMSEON, (char*)NULL);
return;
}
if ( lessptr(BLT_sptrw, BLT_sptrb, BLT_dptrw, BLT_dptrb) )
{
BLT_direction = BOTTOM_UP;
/* 'i' represents the increment to the last word */
i = BLT_left + BLT_words + BLT_right - 1;
if ( i < 0 )
i = 0;
else
i *= 2;
long_inc = (long)BLT_height;
long_inc -= (long)1;
long_inc *= (long)BLT_sinc;
long_inc += (long)i;
BLT_sptrw=addptr(BLT_sptrw, long_inc);
long_inc = (long)BLT_height;
long_inc -= (long)1;
long_inc *= (long)BLT_dinc;
long_inc += (long)i;
BLT_dptrw=addptr(BLT_dptrw, long_inc);
BLT_pat_index = (BLT_pat_index + BLT_height) & 15;
if (lessptr(BLT_dptrw,BLT_dptrb,BLT_sptrw,BLT_sptrb) )
return;
}
BLT_pat_index *= 2;
#ifdef DEBUG
printf("\t\tgoing to full block, sptrw = 0x%lx, ", BLT_sptrw);
printf("and dptrw = 0x%lx\n", BLT_dptrw);
printf("\t\tBLOCK\n");
#endif
if ( mouse )
if ( b.op==L_XOR||b.op==L_NXOR||b.op==L_NDST)
;
else
{
mouse_off = 1;
ioctl(myfd, CIOMSEOFF, (char*)NULL);
}
BLT_block();
#ifdef DEBUG
printf("bitblt returns\n");
#endif
if ( mouse_off )
ioctl(myfd, CIOMSEON, (char *)NULL);
return;
}
#ifdef DEBUG
printf("\t\tWORST CASE\n");
#endif
logical = logtab[b.op];
lbits = 15 - (BLT_sptrb & 15);
if ( BLT_right )
if ( BLT_width < 16 - db2 )
rbits = db1 + 1 - db2;
else
rbits = 16 - db2;
BLT_direction = TOP_DOWN;
if ( lessptr( BLT_sptrw, BLT_sptrb, BLT_dptrw, BLT_dptrb) )
{
BLT_direction = BOTTOM_UP;
long_inc = (long)BLT_height;
long_inc -= (long) 1;
long_inc *= (long)BLT_sinc;
BLT_sptrw = addptr(BLT_sptrw, long_inc);
long_inc = (long)BLT_height;
long_inc -= (long) 1;
long_inc *= (long) BLT_dinc;
BLT_dptrw = addptr(BLT_dptrw, long_inc);
BLT_pat_index = (BLT_pat_index + BLT_height) & 15;
if ( lessptr(BLT_dptrw, BLT_dptrb, BLT_sptrw, BLT_sptrb) )
return;
}
if ( mouse )
if ( b.op==L_XOR||b.op==L_NXOR||b.op==L_NDST)
;
else
{
mouse_off = 1;
ioctl(myfd, CIOMSEOFF, (char*)NULL);
}
while (--BLT_height >= 0 )
{
sp = (unsigned *)BLT_sptrw;
snb = lbits;
sw = (*sp) << (15 - lbits);
dst = (unsigned *)BLT_dptrw;
i = BLT_words;
if ( BLT_left )
{
dw = (w = *dst) & ~BLT_lmask;
*dst = dw + ( (BLT_lmask & (*logical)(db1+1, w, 0))
& b.pat[BLT_pat_index] & BLT_lmask);
dst++;
}
while (i-- > 0 )
{
*dst = (*logical)(16,*dst,0) & b.pat[BLT_pat_index];
dst++;
}
if (BLT_right)
{
dw = ( w = *dst ) & ~BLT_rmask;
*dst = dw + ( (BLT_rmask & (*logical)(rbits, w, db2))
& b.pat[BLT_pat_index] & BLT_rmask);
}
if ( BLT_direction == TOP_DOWN )
{
long_inc = (long) BLT_sinc;
BLT_sptrw = addptr(BLT_sptrw, long_inc);
long_inc = (long) BLT_dinc;
BLT_dptrw = addptr(BLT_dptrw, long_inc);
BLT_pat_index = (BLT_pat_index + 1 ) & 15;
}
else
{
long_inc = (long)BLT_sinc;
BLT_sptrw = subptr(BLT_sptrw, long_inc);
long_inc = (long)BLT_dinc;
BLT_dptrw = subptr(BLT_dptrw, long_inc);
BLT_pat_index = (BLT_pat_index - 1 ) & 15;
}
}
if ( mouse_off )
ioctl(myfd, CIOMSEON, (char *)NULL);
#ifdef DEBUG
printf("bitblt returns\n");
#endif
}
/*
\f
** Logical functions for the stupidest bitblt
*/
int lf0()
{
return 0;
}
int lf1(bits, op1, shift)
int bits, op1, shift;
{
return (getbits(bits) << shift) & op1;
}
int lf2(bits, op1, shift)
int bits, op1, shift;
{
return (getbits(bits) << shift) & (~op1);
}
int lf3(bits, op1, shift)
int bits, op1, shift;
{
return getbits(bits) << shift;
}
int lf4(bits, op1, shift)
int bits, op1, shift;
{
return (~(getbits(bits) << shift)) & op1;
}
int lf5(bits, op1, shift)
int bits, op1, shift;
{
return op1;
}
int lf6(bits, op1, shift)
int bits, op1, shift;
{
return (getbits(bits) << shift) ^ op1;
}
int lf7(bits, op1, shift)
int bits, op1, shift;
{
return (getbits(bits) << shift) | op1;
}
int lf8(bits, op1, shift)
int bits, op1, shift;
{
return (~(getbits(bits) << shift)) & (~op1);
}
int lf9(bits, op1, shift)
int bits, op1, shift;
{
return (~(getbits(bits) << shift)) ^ op1;
}
int lf10(bits, op1, shift)
int bits, op1, shift;
{
return ~op1;
}
int lf11(bits, op1, shift)
int bits, op1, shift;
{
return (getbits(bits) << shift) | (~op1);
}
int lf12(bits, op1, shift)
int bits, op1, shift;
{
return ~(getbits(bits) << shift);
}
int lf13(bits, op1, shift)
int bits, op1, shift;
{
return (~(getbits(bits) << shift)) | op1;
}
int lf14(bits,op1,shift)
int bits,op1,shift;
{
return (~(getbits(bits) << shift)) | (~op1);
}
int lf15()
{
return 0xffff;
}