[comp.sys.m68k.pc] ST OSK Graphics Routines

pete@WLBR.nsc.COM (Pete Lyall) (10/18/88)

I sent this out a while ago as an AR file, and there were some
complaints of truncation. I figured I'd try it as a shell archive.

Pete
====================================================================


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	circle.c
#	crossref.txt
#	cursor.c
#	gfxinit.a
#	line.a
#	linea.d
#	linea.doc
#	linea.h
#	makefile
#	pix.a
#	poly.c
#	rect.a
#	test.c
# This archive created: Mon Oct 17 17:16:28 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'circle.c'
then
	echo shar: "will not over-write existing file 'circle.c'"
else
cat << \SHAR_EOF > 'circle.c'
#include "linea.h"

circle(xcenter, ycenter, radius)
int xcenter, ycenter, radius;
{
	register int x, y, dv, xoffset, yoffset;
	
	xoffset = 0;
	yoffset = radius;
	x = 1;
	y = 2 * radius - 1;
	dv = y - 1;
	
	if (getpix(xcenter - xoffset, ycenter - yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter - xoffset, ycenter - yoffset,BLACK);
	else
		setpix(xcenter - xoffset, ycenter - yoffset,WHITE);
	if (getpix(xcenter + xoffset, ycenter - yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter + xoffset, ycenter - yoffset,BLACK);
	else
		setpix(xcenter + xoffset, ycenter - yoffset,WHITE);
	if (getpix(xcenter + xoffset, ycenter + yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter + xoffset, ycenter + yoffset,BLACK);
	else
		setpix(xcenter + xoffset, ycenter + yoffset,WHITE);
	if (getpix(xcenter - xoffset, ycenter + yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter - xoffset, ycenter + yoffset,BLACK);
	else
		setpix(xcenter - xoffset, ycenter + yoffset,WHITE);
	
	while (y > 0) {
		if (dv >= 0) {
			if (dv * 2 < y) {
				yoffset--;
				dv += (y -= 2);
			}
			xoffset++;
			dv -= (x += 2);
		}
		else {
			if (dv * 2 >= x) {
				xoffset++;
				dv -= (x += 2);
			}
			yoffset--;
			dv += (y -= 2);
		}

	if (getpix(xcenter - xoffset, ycenter - yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter - xoffset, ycenter - yoffset,BLACK);
	else
		setpix(xcenter - xoffset, ycenter - yoffset,WHITE);
	if (getpix(xcenter + xoffset, ycenter - yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter + xoffset, ycenter - yoffset,BLACK);
	else
		setpix(xcenter + xoffset, ycenter - yoffset,WHITE);
	if (getpix(xcenter + xoffset, ycenter + yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter + xoffset, ycenter + yoffset,BLACK);
	else
		setpix(xcenter + xoffset, ycenter + yoffset,WHITE);
	if (getpix(xcenter - xoffset, ycenter + yoffset) == WHITE || getwrtmode() == ABS)
		setpix(xcenter - xoffset, ycenter + yoffset,BLACK);
	else
		setpix(xcenter - xoffset, ycenter + yoffset,WHITE);
	}
}

fillcircle(xcenter, ycenter, radius)
int xcenter, ycenter, radius;
{
	register int x, y, dv, xoffset, yoffset;
	int mode, oldy = 0;
	
	mode = getwrtmode();
	wrtmode(ABS);
	xoffset = 0;
	yoffset = radius;
	x = 1;
	y = 2 * radius - 1;
	dv = y - 1;
	
	horline(xcenter - xoffset, ycenter - yoffset, xcenter + xoffset);
	horline(xcenter - xoffset, ycenter + yoffset, xcenter + xoffset);
	
	while (y > 0) {
		if (dv >= 0) {
			if (dv * 2 < y) {
				yoffset--;
				dv += (y -= 2);
			}
			xoffset++;
			dv -= (x += 2);
		}
		else {
			if (dv * 2 >= x) {
				xoffset++;
				dv -= (x += 2);
			}
			yoffset--;
			dv += (y -= 2);
		}
		if (yoffset != oldy) {
			horline(xcenter - xoffset, ycenter - yoffset, xcenter + xoffset);
			horline(xcenter - xoffset, ycenter + yoffset, xcenter + xoffset);
		}
		oldy = yoffset;
	}
	wrtmode(mode);
}


SHAR_EOF
fi
if test -f 'crossref.txt'
then
	echo shar: "will not over-write existing file 'crossref.txt'"
else
cat << \SHAR_EOF > 'crossref.txt'
				Cross Reference Sheet for Line-A Routine

    File		Call(s) Syntax									Calls
	----		--------------									-----
  gfxinit.a		gfxinit(color)
				- Initialize the graphics data structures,
				  setting the initial color to <color>
				wrtmode(mode)
				- Sets the writing mode to <mode>.
				getwrtmode()
				- Returns the current writing mode.
   				line_type(mask)
   				- Sets the writing mask to <mask>
 
  cursor.c		cls()											write
  				- Clear the screen.
  				curson()/cursoff()
	  			- Enable/disable the cursor.
  				bk_on_wt()/wt_on_bk()
  				- Print text black on white/while on black

     pix.a		setpix(x, y, color)
     			- Plots a point at (x, y) in color <color>.
     			getpix(x, y)
     			- Returns the color of the point (x, y).
     			
	line.a		line(x1, y1, x2, y2)
				- Draws a line with endpoints (x1, y1) and
				  (x2, y2).
				horline(x1, y, x2)
 				- Draw a horizontal line from (x1, y) to
 				  (x2, y)

   rect.a		rect(x1, y1, x2, y2)							line
   				- Draws a rectangle with upper left corner at
   				  (x1, y1) and lower right at (x2, y2)
   				fillrect(x1, y1, x2, y2)
   				- Same as rect, except filled.

  circle.c		circle(xcenter, ycenter, radius)				setpix
				- Draw a circle with center (xcenter, ycenter)
				  and with a radius = radius
				fillcircle(xcenter, ycenter, radius)			horline
				- Draws a filled circle with the same
				  parameters as circle
				
   poly.c		poly(ptsin, num)
   				- Draws a polygon with vetices held in <ptsin>
   				  with <num> sides.
   				fillpoly(ptsin,num)
   				- Draws a filled polygon with same parameters	_fillpoly
   				  as poly
				_fillpoly(ptsin, num, y)
				- Fill the horizontal portion at <y> of the
				  polygon defined by <ptsin> and <num>.

					Structure of the Ptsin Array
	The Ptsin array is an array of words (shorts) with the folling form:
			,------------------,
	0		| X of first point |
			|------------------|
	1		| Y of first point |
			|------------------|
	2		| X of second pt.  |
			`------------------'
    .				.
    .				.
    .				.


SHAR_EOF
fi
if test -f 'cursor.c'
then
	echo shar: "will not over-write existing file 'cursor.c'"
else
cat << \SHAR_EOF > 'cursor.c'
static char  *clrstr = "\x1bE";
static char  *curon  = "\x1be";
static char  *curof  = "\x1bf";
static char  *bowstr = "\x1bb1\x1bc0";
static char  *wobstr = "\x1bb0\x1bc1";


cls()
   {
   write(1, clrstr, 2);
   }


curson()
   {
   write(1, curon, 2);
   }


cursoff()
   {
   write(1, curof, 2);
   }


bk_on_wt()
   {
   write(1, bowstr, 6);
   }


wt_on_bk()
   {
   write(1, wobstr, 6);
   }

SHAR_EOF
fi
if test -f 'gfxinit.a'
then
	echo shar: "will not over-write existing file 'gfxinit.a'"
else
cat << \SHAR_EOF > 'gfxinit.a'

            use      linea.d

            psect    gfxinit_a,0,0,1,0,0

            vsect
_avar:      ds.l     1                 gem aline data struct ptr
_fonts:     ds.l     1                 pointer to font pointers
S_Control:   ds.w     12                control array
S_Intin:     ds.w     128               input parms
S_Ptsin:     ds.w     128               coordinate storage
            ends


gfxinit:    movem.l  d0-d2/a0-a2,-(sp) now save all on stack
            dc.w     INIT              address of variable block in a0

            move.l   a0,_avar(a6)      save gem's variable pointer
            move.l   a1,_fonts(a6)     save font table ptr
            move.w   2(sp),_FG_BP_1(a0) set colors for user
			clr.w    _FG_BP_2(a0)
            clr.w    _FG_BP_3(a0)
            clr.w    _FG_BP_4(a0)
            move.w   #$FFFF,_LSTLIN(a0) they say to do this

            clr.w    _multifill(a0)         for monochrome
            clr.w    _CLIP(a0)          no clipping
            move.w   #2,_WRT_MOD(a0)      default to eor mode
            move.w   #$ffff,_LN_MASK(a0) default to solid lines

            lea      S_Control(a6),a1   get our control array
            move.l   a1,Contrl(a0)     stash it in gem var

            lea      S_Ptsin(a6),a1     get our ptsin array
            move.l   a1,Ptsin(a0)      stash it in gem var

            lea      S_Intin(a6),a1     get our intin array
            move.l   a1,Intin(a0)      stash it in gem var

            movem.l (sp)+,d0-d2/a0-a2  recover my regs
            rts


wrtmode:    move.l  a0,-(sp)           save register
            movea.l _avar(a6),a0       ptr to gem stuff
            move.w  d0,_WRT_MOD(a0)       set new write mode
            move.l  (sp)+,a0           recover resigter
            rts

getwrtmode: move.l  a0,-(sp)           save register
            movea.l _avar(a6),a0       ptr to gem stuff
            move.w  _WRT_MOD(a0),d0    get new write mode
            move.l  (sp)+,a0           recover resigter
            rts

line_type:  move.l  a0,-(sp)           save register
            movea.l _avar(a6),a0       ptr to gem stuff
            move.w  d0,_LN_MASK(a0)      set new line mask
            move.l  (sp)+,a0           recover register
            rts

            ends

SHAR_EOF
fi
if test -f 'line.a'
then
	echo shar: "will not over-write existing file 'line.a'"
else
cat << \SHAR_EOF > 'line.a'

            use      linea.d

            psect    line_a,0,0,1,0,0

line:       movem.l  d2/a0-a2,-(sp)    save registers
            move.l   _avar(a6),a0      get ptr to gem variables
            move.w   d0,_X1(a0)         set in x1 parm
            move.w   d1,_Y1(a0)         set in y1 parm
            move.w   22(sp),_X2(a0)     set in x2 parm
            move.w   26(sp),_Y2(a0)     set in y2 parm
            dc.w     LINE            call tos

            movem.l  (sp)+,d2/a0-a2    recover registers
            rts

horline:	movem.l  d2/a0-a2,-(sp)	save registers
			move.l   _avar(a6),a0	  get ptr to gem variables
			move.w   d0,_X1(a0)		 set in x1 parm
			move.w   d1,_Y1(a0)		 set in y1 parm
			move.w   22(sp),_X2(a0)	 set in x2 parm
			lea _LN_MASK(a0),a1		 load effective address to a1
			move.l a1,_patptr(a0)		set ptr to pattern
			move.w #0,_patmsk(a0)		set # of patterns

			dc.w	 HOR_LINE			call tos

			movem.l  (sp)+,d2/a0-a2	recover registers
			rts

            ends

SHAR_EOF
fi
if test -f 'linea.d'
then
	echo shar: "will not over-write existing file 'linea.d'"
else
cat << \SHAR_EOF > 'linea.d'
* A defs file for the line A routines in the Atari ST

v_planes	equ 0
v_lin_wr	equ 2
Contrl		equ 4
Intin		equ 8
Ptsin		equ 12
Intout		equ 16
Ptsout		equ 20
_FG_BP_1	equ 24
_FG_BP_2	equ 26
_FG_BP_3	equ 28
_FG_BP_4	equ 30
_LSTLIN		equ 32
_LN_MASK	equ 34
_WRT_MOD	equ 36
_X1			equ 38
_Y1			equ 40
_X2			equ 42
_Y2			equ 44
_patptr		equ 46
_patmsk		equ 50
_multifill	equ 52
_CLIP		equ 54
_XMN_CLIP	equ 56
_YMN_CLIP	equ 58
_XMX_CLIP	equ 60
_YMX_CLIP	equ 62
_XACC_DDA	equ 64
_DDA_INC	equ 66
_T_SCLSTS	equ 68
_MONO_STATUS	equ 70
_SOURCEX	equ 72
_SOURCEY	equ 74
_DESTX		equ 76
_DESTY		equ 78
_DELX		equ 80
_DELY		equ 82
_FBASE		equ 84
_FWIDTH		equ 88
_STYLE		equ 90
_LITEMASK	equ 92
_SKEWMASK	equ 94
_WEIGHT		equ 96
_R_OFF		equ 98
_L_OFF		equ 100
_SCALE		equ 102
_CHUP		equ 104
_TEXT_FG	equ 106
_scttchp	equ 108
_scrpt2		equ 112
_TEXT_BG	equ 114
_COPYTRAN	equ 116

INIT		equ $A000
PUT			equ $A001
GET			equ $A002
LINE		equ $A003
HOR_LINE	equ $A004
FILL_REC	equ $A005
FILL_POLY	equ $A006
BITBLT		equ $A007
TEXTBLT		equ $A008
SHOW		equ $A009
HIDE		equ $A00A
TRANSFORM	equ $A00B
UNDRAW		equ $A00C
DRAW		equ $A00D
COPY		equ $A00E
FLOOD		equ $A00F

SHAR_EOF
fi
if test -f 'linea.doc'
then
	echo shar: "will not over-write existing file 'linea.doc'"
else
cat << \SHAR_EOF > 'linea.doc'
This is a small graphics interface to the GEM line A routines for
OSK.  It is a linkable library useful for C or assembler.  I only
have a BW monitor, so none of this has been tested on color.

These are the calls I have implemented:

curson()                /* turn cursor on                          */
cursoff()               /* turn cursor off                         */
cls()                   /* clear screen                            */
bk_on_wt()              /* switches to black letters on white      */
wt_on_bk()              /* switches to white letters on black      */

gfxinit(col0, col1)     /* must be called prior to all other calls */
                        /* color 0 is background for mono          */
wrtmode(mode)           /* sets the write mode - defs in linea.h   */
                        /*  default is EOR                         */
setpix(x, y, color)     /* sets pixel at x, y to 'color'           */
                        /* this is absolute and doesn't honor      */
                        /* other parms - ie set black on black is  */
                        /* not visible                             */
getpix(x, y)            /* gets pixel color at x, y                */
line_type(pattern)      /* pattern for lines - defs in linea.h     */
                        /*  default is solid line                  */
line(x1, y1, x2, y2)    /* draws line from x1, y1 to x2, y2        */

SHAR_EOF
fi
if test -f 'linea.h'
then
	echo shar: "will not over-write existing file 'linea.h'"
else
cat << \SHAR_EOF > 'linea.h'
/*
 * definitions for lineA graphics routines
 * if you need help with this stuff, buy the Abacus book
 */

#define  ABS      0              /* summarily set or clear         */
#define  OR       1              /* set if clear now               */
#define  EOR      2              /* flip the bit there now         */
#define  OREOR    3              /* eor against mask and then or   */

#define  SOLID    0xffff         /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxx  */
#define  DOTTED   0xAAAA         /* x x x x x x x x x x x x x x x  */
#define  SDASH    0xCCCC         /* xx  xx  xx  xx  xx  xx  xx  xx */
#define  LDASH    0xFF00         /* xxxxxxxx        xxxxxxxx       */
#define  MDASH    0XEEEE         /* xxx xxx xxx xxx xxx xxx xxx    */
#define  DASH     0xFCFC         /* xxxxxx  xxxxxx xxxxxx xxxxxx   */

#define  WHITE    0              /* mono colors                    */
#define  BLACK    1

SHAR_EOF
fi
if test -f 'makefile'
then
	echo shar: "will not over-write existing file 'makefile'"
else
cat << \SHAR_EOF > 'makefile'
ODIR = /h0/cmds/ric
RDIR = rels
CFLAGS = -gsqt=/r0
LFLAGS = -gl=rels/stlib.l

STLIB = rels/stlib.l
RFILES = gfxinit.r rect.r circle.r line.r pix.r cursor.r poly.r
OBJ = test

$(OBJ) : $(STLIB)
	cc $(CFLAGS) $@.c -l=$(STLIB)

$(STLIB) : $(RFILES)
	chd rels; merge -b=10 $(RFILES) >-stlib.l


SHAR_EOF
fi
if test -f 'pix.a'
then
	echo shar: "will not over-write existing file 'pix.a'"
else
cat << \SHAR_EOF > 'pix.a'

            use      linea.d

            psect    pix_a,0,0,1,0,0

setpix:     movem.l  d2/a0-a2,-(sp)    save registers
            move.l   _avar(a6),a0      get ptr to gem variables
            move.l   Ptsin(a0),a1      ptr to parm array
            move.w   d0,0(a1)          stash x coord
            move.w   d1,2(a1)          stash y coord
            move.l   Intin(a0),a1      get ptr to intin struct
            move.w   22(sp),0(a1)      set color for lineA
            dc.w     PUT            call gem
            moveq    #0,d0             return ok
            movem.l  (sp)+,d2/a0-a2    recover registers
            rts


getpix:     movem.l  d2/a0-a2,-(sp)    save registers
            move.l   _avar(a6),a0      ptr to gem variables
            move.l   Ptsin(a0),a0      ptr to parm array
            move.w   d0,0(a0)          stash x coord
            move.w   d1,2(a0)          stash y coord
            dc.w     GET            call gem
            andi.l   #7,d0             mask off rest
            movem.l  (sp)+,d2/a0-a2    recover registers
            rts

            ends

SHAR_EOF
fi
if test -f 'poly.c'
then
	echo shar: "will not over-write existing file 'poly.c'"
else
cat << \SHAR_EOF > 'poly.c'
poly(ptsin,num)
register short *ptsin;
register int num;
{
	register int x, temp;
	
	for (x=0; x<num; x++) {
		temp = (x * 2);
		line(ptsin[temp],ptsin[temp+1],ptsin[temp+2],ptsin[temp+3]);
	}
}

fillpoly(ptsin,num)
register short *ptsin;
int num;
{
	register int x,temp,smallest,largest;
	
	for (x=0; x<=num; x++) {
		temp = (x*2)+1;
		if (ptsin[temp] > largest)
			largest = ptsin[temp];
		if (ptsin[temp] < smallest)
			smallest = ptsin[temp];
	}
	for (x=smallest; x<=largest; x++)
		_fillpoly(ptsin,num,x);
}

#asm
			use	  linea.d

_fillpoly:	movem.l  d2/a0-a2,-(sp)	save registers
			move.l   _avar(a6),a0	  get ptr to gem variables
			move.l d0,Ptsin(a0)		  fill ptr to Ptsin
			move.w d1,2+S_Control(a6)			  put num in Contrl[1]
			move.w   22(sp),_Y1(a0)	 set in y1 parm
			lea _LN_MASK(a0),a1		 load effective address to a1
			move.l a1,_patptr(a0)		set ptr to pattern
			move.w #0,_patmsk(a0)		set # of patterns

			dc.w	 FILL_POLY			call tos

			movem.l  (sp)+,d2/a0-a2	recover registers
			rts
#endasm

SHAR_EOF
fi
if test -f 'rect.a'
then
	echo shar: "will not over-write existing file 'rect.a'"
else
cat << \SHAR_EOF > 'rect.a'
			psect rect_a,0,0,0,0,0
			nam rect_a
			ttl rect
rect:		link a5,#0
			movem.l #_1!3,-(sp)
			move.l d0,d4
			move.l d1,d5
			move.l 0+_2(sp),d6
			move.l 4+_2(sp),d7
			move.l d5,-(sp)						
			move.l d6,-(sp) 			
			move.l d5,d1 			
			move.l d4,d0 			
			bsr line
			addq.l #8,sp 			
			move.l d7,-(sp) 			
			move.l d6,-(sp) 			
			move.l d5,d1 			
			move.l d6,d0 			
			bsr line
			addq.l #8,sp 			
			move.l d7,-(sp) 			
			move.l d4,-(sp) 			
			move.l d7,d1 			
			move.l d6,d0 			
			bsr line
			addq.l #8,sp 			
			move.l d5,-(sp) 			
			move.l d4,-(sp) 			
			move.l d7,d1 			
			move.l d4,d0 			
			bsr line
			addq.l #8,sp 			
_3			movem.l -16(a5),#_1
			unlk a5
			rts 			
_1			equ 0x000000f0
_2			equ 0x00000020

			use linea.d

fillrect:	movem.l  d2/a0-a2,-(sp)	save registers
			move.l   _avar(a6),a0	  get ptr to gem variables
			move.w   d0,_X1(a0)		 set in x1 parm
			move.w   d1,_Y1(a0)		 set in y1 parm
			move.w   22(sp),_X2(a0)	 set in x2 parm
			move.w	 26(sp),_Y2(a0)  set in y2 parm
			lea _LN_MASK(a0),a1		 load effective address to a1
			move.l a1,_patptr(a0)		set ptr to pattern
			move.w #0,_patmsk(a0)		set # of patterns

			dc.w	 FILL_REC			call tos

			movem.l  (sp)+,d2/a0-a2	recover registers
			rts

			ends

SHAR_EOF
fi
if test -f 'test.c'
then
	echo shar: "will not over-write existing file 'test.c'"
else
cat << \SHAR_EOF > 'test.c'
#include <stdio.h>
#include "linea.h"

short array[] = { 500, 100, 600, 200, 500, 300, 400, 200, 500, 100 };

main(argc,argv)
int argc;
char **argv;
{
	int x;
	int cx, cy;

	cls();
	cx = 320;
	cy = 320;
	gfxinit(BLACK);
	for (x=639; x>0; x--)
		line(cx,cy,x,0);
	for (x=0; x<400; x++)
		line(cx,cy,0,x);
	for (x=0; x<639; x++)
		line(cx,cy,x,399);
	for (x=399; x>0; x--)
		line(cx,cy,639,x);
	cls();
	for (x=0; x<400; x++) {
		horline(0,x,639);
	}
	cls();
	fillrect(100,100,200,200);
	rect(105,105,195,195);
	sleep(3);
	cls();
	circle(550,150,30);
	fillpoly(array,	4);
	sleep(3);
	cls();
	poly(array, 4);
	sleep(3);
	cls();
	circle(320,200,100);
	fillcircle(320,200,90);
	circle(320,300,100);
	sleep(3);
	for (x=0; x<400; x++) {
		horline(0,x,639);
	}
	sleep(10);
}

SHAR_EOF
fi
exit 0
#	End of shell archive
-- 
Pete Lyall (OS9 Users Group VP)|  DELPHI: OS9UGVP  |  Eaton Corp.(818)-706-5693
Compuserve: 76703,4230 (OS9 Sysop) OS9 (home): (805)-985-0632 (24hr./1200 baud)
Internet: pete@wlbr.eaton.com            UUCP: {hacgate,jplgodo,voder}!wlbr!pete