/* * vdibez.c * * Bindings for Bezier curves. * * ++jrb bammi@cadence.com * and Michal Jaegermann, ntomczak@vm.ucs.ulberta.ca * * Some function have alias names in order to maintain a common * set of symbols with compilers which need symbols unique in the * first seven characters. Besides this resolution is required * by "The Standard" :-) * * ++jrb sync up with SpeedoGDOS docs * */ #include "common.h" #ifndef _COMPILER_H # include #endif #include __EXTERN void vdi __PROTO((void)); #ifdef __DEF_ALL__ #define L_v_set_ap #define L_v_bez_co #define L_v_bez_on #define L_v_bez_of #define L_v_bez #define L_v_bez_fi #define L_v_bez_qu #endif /* __DEF_ALL__ */ #ifdef L_v_set_ap /* * Inform GDOS about location and size of a buffer which GDOS * can use for creation of Bezier curves. * buf_p is a pointer to an address of a buffer * size its a buffer size in 16-bytes paragraphs * * If buf_p is NULL, then space for a buffer will be allocated * by GDOS - using Malloc (who knows where to look for this space?) * * "Hand coding" required - function opcode does not fit into 0-255 range */ void v_set_app_buff (void *buf_p, int size) { short *wptr = _intin; *wptr++ = (short) buf_p; /* low word of an address */ *wptr++ = (short)((long)buf_p >> 16); /* high word of an address */ *wptr = (short) size; /* size of buffer in paragraphs */ /* para == 16 bytes */ wptr = (short *)_contrl; *wptr++ = -1; /* 0 - opcode */ *wptr++ = 0; /* 1 */ wptr++; /* 2 */ *wptr++ = 3; /* 3 - # of entries in _intin */ wptr++; /* 4 */ *wptr++ = 6; /* 5 - id */ *wptr = 0; /* 6 - dummy handle - really needed? */ vdi(); /* call vdi */ } #endif /* L_v_set_ap */ #ifdef L_v_bez_co /* * If onoff is 1 then enable Bezier capabilities and * find a number of segments per Bezier curve. * Returns logarithm in a base of 2 from that number * * If onoff is 0 then disable Bezier capabilities and * release memory allocated in v_set_app_buff call. * Returns NOTHING! */ int v_bez_con(int handle, int onoff) { __vdi__(VDI_CONTRL_ENCODE(11, (unsigned short)(onoff), 0, 13), handle); return(_intout[0]); } #endif /* L_v_bez_co */ #ifdef L_v_bez_on /* * v_bez_on (alias v_bezon) * Enable Bezier capabilities. * Returns maximum Bezier depth (a measure of smoothness). The return * value can range from 0-7, and is the exponent of 2, giving the * number of line segments that make up the curve. * 0 == 2**0 == 1 == straight line and * 7 == 2**7 == 128 line segments. */ __asm__(".stabs \"_v_bezon\",5,0,0,_v_bez_on"); /* dept of clean tricks */ int v_bez_on (int handle) { _contrl[4] = 4; /* dont know why, but atari docs say so! */ __vdi__(VDI_CONTRL_ENCODE(11, 1, 0, 13), handle); _contrl[4] = 0; /* clear it back */ return *_intout; } #endif /* L_v_bez_on */ #ifdef L_v_bez_of /* * v_bez_off (alias v_bezoff) * Disable Bezier capabilities. * Free space allocated by GDOS for Bezier curves. * (see v_set_app_buff for memory alloc info) */ __asm__(".stabs \"_v_bezoff\",5,0,0,_v_bez_off"); /* dept of clean tricks */ void v_bez_off (int handle) { __vdi__(VDI_CONTRL_ENCODE(11, 0, 0, 13), handle); } #endif /* L_v_bez_of */ #ifdef L_v_bez /* * Draw an unfilled Bezier curve * xyarr - an array of 'count' pairs of control vertices * bezarr - an array of flags specifying which control points * are jump points * bit 0 off - start of a polyline if not continuation * bit 0 on - start of a Bezier segment * bit 1 on - jump point (move to the next one without draw) * * Returns - a number of points in a Bezier curve */ int v_bez( int handle, /* Device handle we're drawing to */ int count, /* Number of points total... */ int *xyarr, /* The points in x1,y1,x2,y2 format */ char *bezarr, /* Flag array, so that we can set start, jump pts */ int *extent, /* "bounding box coordinates */ int *totpts, /* number of resulting polygon points */ int *totmoves) /* number of resulting moves */ { short *end; char *pbd = bezarr; char *opbd = (char *)_intin; #ifndef __MSHORT__ short *optr; int *iptr = xyarr; #endif int cntrl0 = 6; /* copy entries from bezarr to _intin packing and swaping bytes ???! */ /* this requirement for byte swapping is not documented - if you */ /* discount some old code example, but things seem to work this way */ end = (short *) (pbd + count); while (pbd < (char *)end) { *(opbd + 1) = *pbd++; if (pbd >= (char *)end) break; *opbd = *pbd++; opbd += 2; } #ifdef __MSHORT__ _vdiparams[2] = (void *) xyarr; _vdiparams[4] = (void *) extent; #else /* copy xyarr into an array of shorts */ optr = _ptsin; end = optr + count + count; while (optr < end) *optr++ = *xyarr++; #endif _contrl[2] = 2; /* dont know why, the atari docs say so without */ _contrl[4] = 6; /* any explaination */ __vdi__(VDI_CONTRL_ENCODE(cntrl0, count, ((count + 1) >> 1), 13), handle); _contrl[2] = 0; _contrl[4] = 0; #ifdef __MSHORT__ /* restore standard parameter block */ _vdiparams[2] = (void *) _ptsin; _vdiparams[4] = (void *) _ptsout; #else optr = _ptsout; iptr = extent; *iptr++ = *optr++; *iptr++ = *optr++; *iptr++ = *optr++; *iptr = *optr; #endif *totmoves = _intout[1]; return(*totpts = _intout[0]); /* number of points in Bezier */ } #endif /* L_v_bez */ #ifdef L_v_bez_fi /* * v_bez_fill (alias _v_bezfill) * Draw a filled Bezier curve * xyarr - an array of 'count' pairs of control vertices * bezarr - an array of flags specifying which control points * are jump points * bit 0 off - start of a polyline if not continuation * bit 0 on - start of a Bezier segment * bit 1 on - jump point (move to the next one without draw) * Returns - a number of points in a filled Bezier curve */ __asm__(".stabs \"_v_bezfill\",5,0,0,_v_bez_fill"); /* dept of clean tricks */ int v_bez_fill(int handle, /* Device handle we're drawing to */ int count, /* Number of points total... */ int *xyarr, /* The points in x1,y1,x2,y2 format */ char *bezarr, /* Flag array, so that we can set start, jump pts */ int *extent, /* "bounding box coordinates */ int *totpts, /* number of resulting polygon points */ int *totmoves) /* number of resulting moves */ { short *end; char *pbd = bezarr; char *opbd = (char *)_intin; #ifndef __MSHORT__ short *optr; int *iptr = xyarr; #endif int cntrl0 = 9; /* copy entries from bezarr to _intin packing and swaping bytes ???! */ /* this requirement for byte swapping is not documented - if you */ /* discount some old code example, but things seem to work this way */ end = (short *) (pbd + count); while (pbd < (char *)end) { *(opbd + 1) = *pbd++; if (pbd >= (char *)end) break; *opbd = *pbd++; opbd += 2; } #ifdef __MSHORT__ _vdiparams[2] = (void *) xyarr; _vdiparams[4] = (void *) extent; #else /* copy xyarr into an array of shorts */ optr = _ptsin; end = optr + count + count; while (optr < end) *optr++ = *xyarr++; #endif _contrl[2] = 2; /* dont know why, the atari docs say so without */ _contrl[4] = 6; /* any explaination */ __vdi__(VDI_CONTRL_ENCODE(cntrl0, count, ((count + 1) >> 1), 13), handle); _contrl[2] = 0; _contrl[4] = 0; #ifdef __MSHORT__ /* restore standard parameter block */ _vdiparams[2] = (void *) _ptsin; _vdiparams[4] = (void *) _ptsout; #else optr = _ptsout; iptr = extent; *iptr++ = *optr++; *iptr++ = *optr++; *iptr++ = *optr++; *iptr = *optr; #endif *totmoves = _intout[1]; return(*totpts = _intout[0]); /* number of points in Bezier */ } #endif /* L_v_bez_fi */ #ifdef L_v_bez_qu /* * v_bez_qual (alias v_bezqual) * Set the quality / speed tradeoff when drawing Beizier curve * quality is given in percents * * Returns an actual quality set. * * This function requires "hand coding" since subcode 99 does * not fit into 5 bits required by VDI_CONTRL_ENCODE */ __asm__(".stabs \"_v_bezqual\",5,0,0,_v_bez_qual"); /* dept of clean tricks */ int v_bez_qual (int handle, int percent, int *actual) { short *wptr = _intin; *wptr++ = 32; *wptr++ = 1; *wptr = percent; wptr = (short *)_contrl; *wptr++ = 5; /* 0 - opcode */ *wptr++ = 0; /* 1 */ wptr++; /* 2 */ *wptr++ = 3; /* 3 - # of entries in _intin */ *wptr++ = 1; /* 4 - atari doesnt say why! */ *wptr++ = 99; /* 5 - id */ *wptr = handle; /* 6 - handle */ vdi(); /* call vdi */ _contrl[4] = 0; /* clear it back */ return (*actual = *_intout); } #endif /* L_v_bez_qu */ /* -eof- */