mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
1159 lines
38 KiB
Plaintext
1159 lines
38 KiB
Plaintext
;
|
|
; File: DrawArc.a
|
|
;
|
|
; Contains: xxx put contents here (or delete the whole line) xxx
|
|
;
|
|
; Written by: xxx put name of writer here (or delete the whole line) xxx
|
|
;
|
|
; Copyright: © 1981-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; This file is used in these builds: Mac32 Bigbang Sys606
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 6/11/92 stb <sm 6/9/92>stb Add comment from QDciPatchROM.a at SKIPSETUP;
|
|
; synched with QDciPatchROM.a.
|
|
; <8> 11/26/90 SMC Fixed the way valid pen mode is checked for. With BAL.
|
|
; <7> 9/26/90 SMC Avoid overflow problem when calculating arc center by using
|
|
; longs instead of words.
|
|
; <6> 9/17/90 BG Removed <3>. 040s are now behaving more reliably.
|
|
; <5> 8/2/90 gbm change LEFTEDGE and RIGHTEDGE in ovalstate record to avoid
|
|
; conflicts with other equates
|
|
; <4> 7/20/90 gbm Change some identifier names to resolve conflicts with interface
|
|
; files
|
|
; <3> 6/25/90 BG Added EclipseNOPs because of flakey 040s.
|
|
; <2> 2/13/90 BAL Calculate initial bit offset as a long.
|
|
; <¥1.6> 7/14/89 BAL For Aurora: Final CQD
|
|
; <1.5> 6/30/89 BAL Cleared runBuf(a6) before calling getSeek to specifiy classic
|
|
; masking.
|
|
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
|
; <¥1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
|
|
; 1/22/89 BAL Made patVPos a long.
|
|
; 10/3/88 BAL Added references to DstRow.
|
|
; 9/22/88 BAL Moved initialization of region state records into GetSeek.
|
|
; 9/19/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
|
; 9/18/88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed
|
|
; references to PIXSRC;
|
|
; 11/8/87 BAL Fixed computation of bufSize for more accurate region clipping
|
|
; at at depths greater than 1. <C954>
|
|
; 11/7/87 BAL Fixed ChkPat to handle new patterns. <C945>
|
|
; 1/3/87 CRC pass color param to stretch
|
|
; 12/12/86 CRC added arithmetic mode support
|
|
; 7/29/86 EHB Allocate EXPAT buffer on stack so long aligned
|
|
; 7/26/86 EHB Added support for expanded patterns
|
|
; 7/22/86 EHB Pass mode to patexpand for colorizing
|
|
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetSeek
|
|
; 6/22/86 EHB Call new patexpand for depths
|
|
; 6/20/86 EHB New params to COLORMAP Added FCOLOR and BCOLOR to stack frame
|
|
; 6/15/86 EHB Make sure stack is longword aligned (for fast buffers) If one
|
|
; 1-bit region, play directly into RGNBUFFER Convert BitsToPix and
|
|
; use pixelSize
|
|
; 6/14/86 EHB Call GetXRtn to set expand routine for SeekMask Added DSTPIX to
|
|
; stack frame
|
|
; 6/13/86 EHB Updated SeekMask to check rgn changed flag Moved SeekMask to
|
|
; another file Rearranged stack frame with SeekMask stuff at top
|
|
; 6/10/86 EHB Modified to use 32-bit DrawSlab
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; --> DRAWARC.TEXT
|
|
;
|
|
; Routine to draw solid or hollow Ovals, RoundRects or Arcs.
|
|
;
|
|
;------------------------------------------------------------------
|
|
|
|
DrawArc PROC EXPORT
|
|
IMPORT InitOval,BumpOval,SlopeFromAngle,SHFTTBL
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DrawArc(dstRect: Rect;
|
|
; hollow: BOOLEAN;
|
|
; ovalWidth,ovalHeight,mode: INTEGER;
|
|
; pat: Pattern;
|
|
; startAngle,arcAngle: INTEGER);
|
|
;
|
|
|
|
|
|
;------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 20 ;TOTAL SIZE OF PARAMETERS
|
|
DSTRECT EQU PARAMSIZE+8-4 ;ADDR OF RECT
|
|
HOLLOW EQU DSTRECT-2 ;BOOLEAN
|
|
OVALWIDTH EQU HOLLOW-2 ;INTEGER
|
|
OVALHEIGHT EQU OVALWIDTH-2 ;INTEGER
|
|
MODE EQU OVALHEIGHT-2 ;INTEGER
|
|
PAT EQU MODE-4 ;LONG, ADDR OF PATTERN
|
|
STARTANGLE EQU PAT-2 ;INTEGER
|
|
ARCANGLE EQU STARTANGLE-2 ;INTEGER
|
|
|
|
|
|
;-------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
|
;
|
|
; STACK FRAME VARS USED BY SEEKMASK (CALLED BY STRETCHBITS, RGNBLT, DRAWARC, DRAWLINE)
|
|
;
|
|
&CurFile SETC 'DRAWARC'
|
|
|
|
INCLUDE 'DrawingVars.a'
|
|
|
|
;-------------------------------------------------
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
|
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
|
|
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
|
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
|
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A0),A4 ;GET CURRENT GRAFPORT
|
|
TST PNVIS(A4) ;IS PNVIS NEG ?
|
|
BLT GOHOME ;YES, QUIT
|
|
MOVE.W MODE(A6),D1 ;get pen mode Start of <8>
|
|
_GetStreamMode ;strip off alpha bits
|
|
BSET #3,D1 ;set the pattern bit in case the user forgot to
|
|
MOVEQ #$10,D0 ;1 past normal mode range
|
|
BTST #5,D1 ;arithmetic mode?
|
|
BEQ.S @noRith
|
|
CMP #$3A,D1 ;hilite?
|
|
BEQ.S @ok
|
|
MOVEQ #$30,D0 ;1 past arithmetic mode range
|
|
@noRith CMP D0,D1 ;greater than defined range?
|
|
BGT GOHOME
|
|
@ok MOVE D1,LOCMODE(A6) ;copy mode for colormap End of <8>
|
|
LEA EXPAT(A6),A0 ;DUMMY PATTERN USED IN ONESLAB
|
|
MOVE.L A0,(A0) ;POINT IT AT ITSELF
|
|
CLR.l PATVPOS(A6) ;INITIALIZE IN CASE NO PATTERN <BAL 22Jan89>
|
|
CLR PATVMASK(A6) ;INITIALIZE IN CASE NO PATTERN
|
|
MOVE #1,PATROW(A6) ;INITIALIZE IN CASE NO PATTERN
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
|
|
;
|
|
MOVE.L SP,D1 ;GET THE STACK POINTER
|
|
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
|
|
MOVE.L D1,SP ;USE IT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CONVERT PORTBITS TO A PIXMAP
|
|
; (A5 must contain global ptr)
|
|
;
|
|
LEA PORTBITS(A4),A1 ;PUSH POINTER TO PORTBITS
|
|
LEA DSTPIX(A6),A2 ;AND COPY INTO DSTPIX
|
|
_BitsToPix ;CONVERT BITMAP
|
|
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
|
|
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CONVERT PIXEL DEPTH TO SHIFT AMOUNT TO AVOID MULTIPLIES
|
|
;
|
|
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
|
|
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
|
|
MOVEQ #0,D1 ;DEFAULT SHIFT = 0
|
|
MOVE.B 0(A0,D0),D1 ;GET SRC SHIFT
|
|
MOVE D1,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
|
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
|
|
;
|
|
MOVE.L PAT(A6),LOCPAT(A6) ;COPY PATTERN POINTER
|
|
TST PORTBITS+ROWBYTES(A4) ;IS THE DST OLD OR NEW?
|
|
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; ADJUST MODE AND PATTERN IF COLOR FILTERING.
|
|
; (A5 must contain global ptr)
|
|
;
|
|
CLR.B multiColor(A6) ;use fg/bg color
|
|
_COLORMAP ;ALTER BY THECOLOR, THEFILTER
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
|
;
|
|
MOVE.L CLIPRGN(A4),A2 ;GET CLIPRGN HANDLE
|
|
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
|
|
MOVE.L VISRGN(A4),A3 ;GET VISRGN HANDLE
|
|
MOVE.L (A3),A3 ;GET VISRGN POINTER
|
|
|
|
|
|
;-----------------------------------------------------------------------
|
|
;
|
|
; CALC MINRECT, THE INTERSECTION OF DSTRECT, BITMAP BOUNDS,
|
|
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
|
|
;
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
PEA DSTPIX+BOUNDS(A6) ;PUSH BITMAP BOUNDS
|
|
PEA RGNBBOX(A2) ;PUSH CLIPRGN BBOX
|
|
PEA RGNBBOX(A3) ;PUSH VISRGN BBOX
|
|
MOVE #4,-(SP) ;PUSH NRECTS=4
|
|
PEA MINRECT(A6) ;PUSH DST ADDR
|
|
_RSECT ;CALC INTERSECTION
|
|
BEQ GOHOME ;QUIT IF NO INTERSECT
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; CHECK FOR BOTH VISRGN AND CLIPRGN RECTANGULAR
|
|
;
|
|
CLR.B FASTFLAG(A6) ;FASTFLAG := FALSE
|
|
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
|
BEQ.S CKPAT ;YES, CONTINUE
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; If only visRgn is non-rectangular, then check if
|
|
; its intersection with minrect would be rectangular.
|
|
; IF TrimRect(visRgn,minRect) then treat as rectangular.
|
|
;
|
|
MOVE.L visRgn(A4),-(SP) ;push rgnHandle
|
|
PEA minRect(A6) ;push addr of minRect
|
|
MOVE.W #-1,-(SP) ;pass Trim = True
|
|
_TrimRect ;call trimRect
|
|
BLT GOHOME ;quit if intersection empty
|
|
BGT.S FLAGOK ;continue if non-rectangular
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; CHECK FOR BLACK OR WHITE PATTERN
|
|
;
|
|
CKPAT BTST #5,LocMode+1(A6) ;an arithmetic mode?
|
|
BNE.S FlagOK ;skip fast case if so
|
|
|
|
MOVE.L LOCPAT(A6),A0 ;POINT TO PATTERN
|
|
TST.B NEWPATTERN(A6) ;is it a new pattern? <C945 07Nov87 BAL>
|
|
BEQ.S @oldPat ;=>yes, skip pixpat fields <C945 07Nov87 BAL>
|
|
|
|
MOVE.L (a0),a0 ;get the pixpat handle <C945 07Nov87 BAL>
|
|
MOVE.L (a0),a0 ;get the pixpat pointer <C945 07Nov87 BAL>
|
|
TST PATTYPE(A0) ;is it an old-style pattern? <C945 07Nov87 BAL>
|
|
BNE.S FLAGOK ;=>no, skip fast case <C945 07Nov87 BAL>
|
|
|
|
MOVE.L patData(a0),a0 ;get handle to pattern data <C945 07Nov87 BAL>
|
|
MOVE.L (a0),a0 ;get pattern ptr <C945 07Nov87 BAL>
|
|
|
|
@oldPat MOVE.L (A0)+,D0 ;GET 1ST HALF OF PATTERN
|
|
CMP.L (A0)+,D0 ;IS IT SAME AS 2ND HALF ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
NOT.L D0 ;IS PATTERN BLACK ?
|
|
BEQ.S YESFLAG ;YES, WE MADE IT
|
|
NOT.L D0 ;IS PATTERN WHITE ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
EOR #4,LOCMODE(A6) ;YES, ALTER MODE AS IF BLACK
|
|
YESFLAG ST FASTFLAG(A6) ;REMEMBER RECT CLIPPED AND BLACK
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; fast case: map mode into black,xor,white, or do-nothing
|
|
;
|
|
MOVEQ #7,D0 ;GET 3 BIT MASK
|
|
AND LOCMODE(A6),D0 ;GET 3 BITS OF MODE
|
|
MOVE.B MODEMAP(D0),D0 ;MAP TO BLACK,XOR,WHITE,NOP
|
|
BMI GOHOME ;QUIT IF DO-NOTHING MODE
|
|
MOVE D0,LOCMODE(A6) ;UPDATE MODE
|
|
BRA.S FLAGOK ;AND CONTINUE
|
|
|
|
MODEMAP DC.B 0,0,1,2,2,255,255,255
|
|
FLAGOK
|
|
|
|
|
|
CLR.B SKIPFLAG(A6) ;INIT TO NOT SKIPPING
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; ADJUST IF ARCANGLE NEGATIVE, QUIT IF ARC = 0
|
|
; NOTE WHETHER FULL CIRCLE OR ARC
|
|
;
|
|
MOVE ARCANGLE(A6),D0 ;GET ARC ANGLE
|
|
BEQ GOHOME ;QUIT IF ARC ANGLE = 0
|
|
BPL.S POSANG ;IS ANGLE NEG ?
|
|
ADD D0,STARTANGLE(A6) ;YES, ADJUST START ANGLE
|
|
NEG D0 ;AND MAKE ARC ANGLE POSITIVE
|
|
MOVE D0,ARCANGLE(A6) ;UPDATE INPUT PARAM
|
|
POSANG CMP #360,D0 ;IS ARC ANGLE < 360 ?
|
|
SLT ARCFLAG(A6) ;REMEMBER FOR LATER
|
|
BGE NOTARC ;NO, SKIP SETUP
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; IF ARCANGLE < 360 THEN SET UP ARC STUFF
|
|
;
|
|
; TREAT STARTANGLE MOD 360
|
|
;
|
|
MOVE STARTANGLE(A6),D0 ;GET STARTANGLE
|
|
EXT.L D0 ;SIGN EXTEND FOR DIVIDE
|
|
DIVS #360,D0 ;TREAT STARTANGLE MOD 360
|
|
SWAP D0 ;GET THE REMAINDER
|
|
TST D0 ;WAS IT NEGATIVE ?
|
|
BPL.S STARTOK ;NO, CONTINUE
|
|
ADD #360,D0 ;YES, PUT IN RANGE 0..359
|
|
STARTOK MOVE D0,STARTANGLE(A6) ;REPLACE INPUT PARAM
|
|
|
|
ADD ARCANGLE(A6),D0 ;CALC STOPANGLE
|
|
CMP #360,D0 ;IS IT >= 360 ?
|
|
BLT.S STOPOK ;NO, CONTINUE
|
|
SUB #360,D0 ;YES, PUT IN RANGE 0..359
|
|
STOPOK MOVE D0,STOPANGLE(A6) ;SAVE STOPANGLE FOR LATER
|
|
|
|
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
MOVE TOP(A0),A1 ;<SMC 26SEP90> <7>
|
|
ADD BOTTOM(A0),A1 ;<SMC 26SEP90> <7>
|
|
MOVE.L A1,D0 ;<SMC 26SEP90> <7>
|
|
ASR.L #1,D0 ;<SMC 26SEP90> <7>
|
|
MOVE D0,MIDVERT(A6) ;MID VERT := (DSTBOT+DSTTOP)/2
|
|
|
|
MOVE LEFT(A0),A1 ;<SMC 26SEP90> <7>
|
|
ADD RIGHT(A0),A1 ;<SMC 26SEP90> <7>
|
|
MOVE.L A1,D0 ;<SMC 26SEP90> <7>
|
|
ASR.L #1,D0 ;<SMC 26SEP90> <7>
|
|
MOVE D0,MIDHORIZ(A6) ;MID HORIZ := (DSTLEFT+DSTRIGHT)/2
|
|
|
|
MOVE RIGHT(A0),D0
|
|
SUB LEFT(A0),D0
|
|
MOVE D0,WIDTH(A6) ;WIDTH := DSTRIGHT - DSTLEFT
|
|
|
|
MOVE BOTTOM(A0),D0
|
|
SUB TOP(A0),D0
|
|
MOVE D0,HEIGHT(A6) ;HEIGHT := DSTBOTTOM -DSTTOP
|
|
|
|
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
|
MOVE WIDTH(A6),-(SP)
|
|
MOVE HEIGHT(A6),-(SP)
|
|
|
|
_FixRatio ;CALC ASPECT RATIO
|
|
MOVE.L (SP)+,D7 ;SAVE RESULT IN D7
|
|
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; CALC SLOPE1 FROM STARTANGLE
|
|
;
|
|
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
|
MOVE STARTANGLE(A6),-(SP) ;PUSH STARTANG
|
|
_SlopeFromAngle ;CALC SLOPE1
|
|
MOVE.L (SP)+,D0 ;POP SLOPE1
|
|
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
|
MOVE.L D0,-(SP) ;PUSH SLOPE1
|
|
MOVE.L D7,-(SP) ;PUSH ASPECT RATIO
|
|
_FixMul ;scale slope1
|
|
MOVE.L (SP)+,SLOPE1(A6) ;SAVE RESULT FOR LATER
|
|
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; CALC SLOPE2 FROM STOPANGLE
|
|
;
|
|
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
|
MOVE STOPANGLE(A6),-(SP) ;PUSH STOPANGLE
|
|
_SlopeFromAngle ;CALC SLOPE2
|
|
MOVE.L (SP)+,D0 ;POP SLOPE2
|
|
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
|
MOVE.L D0,-(SP) ;PUSH SLOPE
|
|
MOVE.L D7,-(SP) ;PUSH ASPECT RATIO
|
|
_FixMul ;SCALE SLOPE2
|
|
MOVE.L (SP)+,SLOPE2(A6) ;SAVE RESULT FOR LATER
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; CALC HORIZ COORDS OF LINE1 AND LINE2 AT TOP OF DSTRECT
|
|
;
|
|
MOVE MIDHORIZ(A6),D6
|
|
SWAP D6
|
|
CLR.W D6 ;CALC MIDHORIZ*64K
|
|
MOVE HEIGHT(A6),D7
|
|
LSR #1,D7 ;CALC HEIGHT DIV 2
|
|
|
|
MOVE SLOPE1+2(A6),D0 ;GET LO WORD OF SLOPE
|
|
MULU D7,D0 ;CALC LO PARTIAL PRODUCT
|
|
MOVE.L D0,LINE1(A6) ;ACCUMULATE IT
|
|
MOVE.W SLOPE1(A6),D0 ;GET HI WORD OF SLOPE
|
|
MULS D7,D0 ;CALC HI PARTIAL PRODUCT
|
|
ADD.W D0,LINE1(A6) ;ADD TO HI WORD OF ACCUMULATOR
|
|
MOVE.L D6,D0 ;COPY MIDHORIZ*64K
|
|
SUB.L LINE1(A6),D0 ;CALC MIDH*64K-SLOPE*(HT DIV 2)
|
|
MOVE.L D0,LINE1(A6) ;STORE AS LINE1 HORIZ AT TOP
|
|
|
|
MOVE SLOPE2+2(A6),D0 ;GET LO WORD OF SLOPE
|
|
MULU D7,D0 ;CALC LO PARTIAL PRODUCT
|
|
MOVE.L D0,LINE2(A6) ;ACCUMULATE IT
|
|
MOVE.W SLOPE2(A6),D0 ;GET HI WORD OF SLOPE
|
|
MULS D7,D0 ;CALC HI PARTIAL PRODUCT
|
|
ADD.W D0,LINE2(A6) ;ADD TO HI WORD OF ACCUMULATOR
|
|
SUB.L LINE2(A6),D6 ;CALC MIDH*64K-SLOPE*(HT DIV 2)
|
|
MOVE.L D6,LINE2(A6) ;STORE AS LINE2 HORIZ AT TOP
|
|
|
|
|
|
;----------------------------------------------------------
|
|
;
|
|
; SET UP FLAG1 AND FLAG2 TO TELL WHICH HALF EACH LINE IS ACTIVE IN:
|
|
; CODE IS: NEG = ACTIVE IN TOP, POS = ACTIVE IN BOTTOM, 0 = HORIZONTAL
|
|
;
|
|
MOVE STARTANGLE(A6),D0
|
|
CMP #180,D0 ;IS STARTANGLE < 180 ?
|
|
BGE.S @1 ;NO, CONTINUE
|
|
SUB #90,D0 ;YES, FLAG1:=STARTANGLE-90
|
|
BRA.S @2 ;CONTINUE
|
|
@1 SUB #270,D0
|
|
NEG D0 ;FLAG1 := 270-STARTANGLE
|
|
@2 MOVE D0,FLAG1(A6) ;SAVE FOR LATER
|
|
|
|
MOVE STOPANGLE(A6),D0
|
|
CMP #180,D0 ;IS STOPANGLE < 180 ?
|
|
BGE.S @3 ;NO, CONTINUE
|
|
SUB #90,D0 ;YES, FLAG2:=STOPANGLE-90
|
|
BRA.S @4 ;CONTINUE
|
|
@3 SUB #270,D0
|
|
NEG D0 ;FLAG2 := 270-STOPANGLE
|
|
@4 MOVE D0,FLAG2(A6) ;SAVE FOR LATER
|
|
|
|
|
|
;----------------------------------------------------------
|
|
;
|
|
; SET UP SKIPFLAG TO SKIP OVER UNUSED ARC PORTIONS
|
|
;
|
|
MOVE ARCANGLE(A6),D0
|
|
CMP #180,D0 ;IS ARC ANGLE > 180 ?
|
|
BGT.S OBTUSE ;SKIP IF ANGLE > 180
|
|
BLT.S ACUTE ;DEAL WITH ACUTE ANGLE
|
|
CMP #90,STARTANGLE(A6) ;OTHERWISE ANGLE=180
|
|
SEQ SKIPFLAG(A6) ;SO SKIP IF START=90
|
|
BRA.S OBTUSE
|
|
ACUTE MOVE FLAG1(A6),D0
|
|
OR FLAG2(A6),D0
|
|
SPL SKIPFLAG(A6) ;SKIP:=FLAG1 AND FLAG2 BOTH >= 0
|
|
OBTUSE
|
|
|
|
|
|
NOTARC
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; INIT OUTER OVAL STATE RECORD
|
|
;
|
|
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
LEA OUTEROVAL(A6),A1 ;POINT TO OUTER OVAL RECORD
|
|
MOVE OVALHEIGHT(A6),D1 ;GET OVALHEIGHT
|
|
MOVE OVALWIDTH(A6),D2 ;GET OVALWIDTH
|
|
JSR INITOVAL ;INITIALIZE OUTER OVAL RECORD
|
|
|
|
MOVE OVALHEIGHT(A6),D0 ;GET OVALHEIGHT
|
|
ASR #1,D0 ;CALC OVAL HEIGHT DIV 2
|
|
ADD OUTEROVAL+OVALTOP(A6),D0 ;ADD OUTEROVAL TOP
|
|
MOVE D0,SKIPTOP(A6) ;SAVE SKIPTOP
|
|
|
|
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
ADD BOTTOM(A0),D0 ;ADD BOTTOM
|
|
SUB TOP(A0),D0 ;SUBTRACT TOP
|
|
SUB OVALHEIGHT(A6),D0 ;SUBTRACT OVALHEIGHT
|
|
MOVE D0,SKIPBOT(A6) ;SAVE SKIPBOT
|
|
|
|
|
|
;---------------------------------------------------
|
|
;
|
|
; IF THIS IS A HOLLOW OVAL, THEN CALC DSTRECT INSET BY PENSIZE,
|
|
; AND INIT INNEROVAL. (IF INNEROVAL EMPTY, SWITCH TO SOLID).
|
|
;
|
|
MOVE #32767,INNEROVAL+OVALTOP(A6);INIT INNEROVAL NOT USED
|
|
TST.B HOLLOW(A6) ;IS HOLLOWFLAG TRUE ?
|
|
BEQ.S SOLID ;NO, SKIP INNER OVAL
|
|
|
|
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
MOVEM.W (A0),D0-D3 ;GET DSTRECT INTO REGS
|
|
MOVE.L PNSIZE(A4),D4 ;GET THEPORT^.PNSIZE
|
|
|
|
ADD D4,D1 ;LEFT := DSTLEFT + PENWIDTH
|
|
SUB D4,D3 ;RIGHT := DSTRIGHT - PENWIDTH
|
|
CMP D3,D1 ;IS LEFT >= TOP ?
|
|
BGE.S SOLID ;YES, EMPTY RECT
|
|
|
|
SWAP D4 ;GET PNSIZE.V
|
|
ADD D4,D0 ;TOP := DSTTOP + PENHEIGHT
|
|
SUB D4,D2 ;BOTTOM := DSTBOTTOM - PENHEIGHT
|
|
CMP D2,D0 ;IS TOP >= BOTTOM ?
|
|
BGE.S SOLID ;YES, EMPTY RECT
|
|
|
|
MOVEM.W D0-D3,TEMPRECTANGLE(A6) ;STORE RESULTS INTO TEMPRECTANGLE
|
|
|
|
LEA TEMPRECTANGLE(A6),A0 ;POINT TO DSTRECT INSET BY PENSIZE
|
|
LEA INNEROVAL(A6),A1 ;POINT TO INNER OVAL RECORD
|
|
MOVE OVALHEIGHT(A6),D1
|
|
SUB D4,D1 ;INNER HEIGHT:=OUTER-2*PENHEIGHT
|
|
SUB D4,D1
|
|
MOVE OVALWIDTH(A6),D2
|
|
SWAP D4 ;GET PEN WIDTH
|
|
SUB D4,D2 ;INNER WIDTH:=OUTER-2*PENWIDTH
|
|
SUB D4,D2
|
|
JSR INITOVAL ;INITIALIZE INNER OVAL RECORD
|
|
SOLID
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT AND DST IS SCREEN.
|
|
;
|
|
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
|
|
BEQ.S NOTSCREEN ;=>NO
|
|
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
|
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
|
|
_SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
|
|
|
NOTSCREEN
|
|
;------------------------------------
|
|
;
|
|
; CALC BUFLEFT
|
|
;
|
|
MOVE DSTSHIFT(A6),D5 ;GET SHIFT FOR PIXEL DEPTH
|
|
MOVE MINRECT+LEFT(A6),D2 ;GET MINRECT LEFT
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL COORDS
|
|
EXT.L D2 ;MAKE IT A LONG
|
|
LSL.L D5,D2 ;CONVERT PIXELS TO BITS
|
|
AND.l #~$1f,D2 ;TRUNC TO MULT OF 32 BITS
|
|
MOVE.L D2,D0 ;GET FOR PATHPOS CALC
|
|
LSR.L #3,D0 ;CONVERT TO BYTES
|
|
MOVE D0,PATHPOS(A6) ;SAVE FOR BIG PATTERNS
|
|
LSR.L D5,D2 ;CONVERT BITS TO PIXELS
|
|
ADD DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BACK TO GLOBAL
|
|
MOVE D2,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
|
;
|
|
; IF FASTFLAG, THEN SKIP REGION SETUP
|
|
;
|
|
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BNE SKIPSETUP ;YES, DON'T WASTE TIME WITH SETUP
|
|
;
|
|
; CALC expansion buffer = [ (minRect.right-minRect.left) div 32 + 1 ] * pixelsize - 1
|
|
; CALC bufSize = [ (minRect.right-minRect.left) * pixelsize - 1 ] div 32 <C954> 08Nov87 BAL
|
|
;
|
|
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
|
SUB D2,D0 ;CALC MAXH-BUFLEFT
|
|
move d0,d1 ;save for expansion scanline buffer <C954>
|
|
|
|
ext.l d1 ;clear out high word <C954>
|
|
lsl.l d5,d1 ;convert to bits <C954>
|
|
subq.l #1,d1 ;force downward round <C954>
|
|
LSR.l #5,D1 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
|
|
MOVE D1,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
|
|
|
|
LSR #5,D0 ;get (pixels in scanbuf)/32 <C954>
|
|
ADDQ #1,D0 ;MAKE IT ONE BASED
|
|
LSL D5,D0 ;CONVERT PIXELS TO BITS
|
|
SUBQ #1,D0 ;MAKE 0 BASED AGAIN
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK
|
|
;
|
|
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR ONE LONG
|
|
DBRA D0,CLRMASK ;LOOP TILL DONE
|
|
MOVE.L SP,RGNBUFFER(A6) ;REMEMBER WHERE RGNBUFFER IS
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
|
|
; GET SEEK ROUTINE INTO SEEKMASK(A6)
|
|
; GET EXPAND ROUTINE INTO EXRTN(A6) FOR SEEK ROUTINE
|
|
; Clobbers: A0-A3, D0-D4
|
|
;
|
|
lea Show,a0 ;get go home routine
|
|
move.l a0,goShow(a6) ;pass to getSeek <BAL 21Mar89>
|
|
move.l maskbc,StackFree(a6) ;pretend lots of stack <BAL 21Mar89>
|
|
|
|
clr.l DstRow(a6) ;flag as seeking down
|
|
clr.l runBuf(a6) ;don't use run clipping <1.5> BAL
|
|
MOVE.L VISRGN(A4),-(SP) ;PUSH THEPORT^.VISRGN
|
|
MOVE.L CLIPRGN(A4),-(SP) ;PUSH THEPORT^.CLIPRGN
|
|
MOVE.L #1,-(SP) ;PUSH HANDLE COUNT - 1
|
|
_GETSEEK ;GET EXPAND ROUTINE INTO EXRTN(A6)
|
|
;AND SEEK ROUTINE INTO SEEKMASK(A6)
|
|
|
|
SKIPSETUP
|
|
;------------------------------------
|
|
;
|
|
; CALC STARTING DSTLEFT
|
|
;
|
|
; as seen in QDciPatchROM.a at TryLineArc <sm 6/9/92>stb
|
|
|
|
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
|
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT TO GLOBAL COORDS
|
|
MOVE DSTPIX+ROWBYTES(A6),D0 ;GET DST ROWBYTES
|
|
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
|
EXT.L D0 ;MAKE IT LONG
|
|
MOVE.L D0,DSTROW(A6) ;SAVE FOR LATER
|
|
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
|
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
|
|
|
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
|
ext.l d2 ;clear out high end <BAL 13Feb90>
|
|
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
|
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
|
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
|
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
|
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
|
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; MAKE ALL HORIZONTAL COORDINATES RELATIVE TO BUFFER
|
|
;
|
|
MOVE BUFLEFT(A6),D1 ;GET LEFT OF BUFFER
|
|
SUB D1,MINRECT+LEFT(A6)
|
|
SUB D1,MINRECT+RIGHT(A6)
|
|
SUB.W D1,OUTEROVAL+LEFTMOSTEDGE(A6) ;ADJUST OUTEROVAL LEFTMOSTEDGE.INT
|
|
SUB.W D1,OUTEROVAL+RIGHTMOSTEDGE(A6) ;ADJUST OUTEROVAL RIGHTMOSTEDGE.INT
|
|
SUB.W D1,INNEROVAL+LEFTMOSTEDGE(A6) ;ADJUST INNEROVAL LEFTMOSTEDGE.INT
|
|
SUB.W D1,INNEROVAL+RIGHTMOSTEDGE(A6) ;ADJUST INNEROVAL RIGHTMOSTEDGE.INT
|
|
SUB.W D1,LINE1(A6) ;ADJUST LINE1
|
|
SUB.W D1,LINE2(A6) ;ADJUST LINE2
|
|
|
|
|
|
;---------------------------------------------------
|
|
;
|
|
; SET UP CASE JUMP BASED ON MODE AND FASTFLAG
|
|
;
|
|
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
TST.B FastFlag(A6) ;Rect clipped and black ?
|
|
BEQ.S @1 ;no, use slow drawslab loop
|
|
_FastSlabMode ;yes, get fast modeCase in A4
|
|
MOVE.L A4,MODECASE(A6) ;SAVE FOR LATER
|
|
BRA.S GOFORIT ;SKIP PATTERN STUFF
|
|
|
|
@1
|
|
;------------------------------------------------------------------
|
|
;
|
|
; ALLOCATE EXPANDED PATTERN BUFFER.
|
|
; EXPAND BYTE PATTERN TO PROPER DEPTH AND INIT PATTERN SELECTOR
|
|
;
|
|
CLR.L D7 ;SAY NOT INVERTED
|
|
MOVE LOCMODE(A6),D2 ;GET MODE
|
|
BTST #5,D2 ;a new arithmetic mode? <BAL 17Jan89>
|
|
BNE.S NOTINV ;if so, no invert bit to test <BAL 17Jan89>
|
|
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
|
BEQ.S NOTINV ;SKIP IF NOT INVERTED
|
|
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
|
|
|
|
NOTINV _PATEXPAND ;EXPAND 8 BYTE PATTERN TO 16 LONGS
|
|
;SET UP PATROW,PATHMASK,PATVMASK
|
|
MOVE PATROW(A6),D1 ;BIG PATTERN USED?
|
|
BNE.S DONEW ;=>YES, GO USE IT
|
|
|
|
MOVEQ #$F,D0 ;ELSE 16 ROWS OF PATTERN
|
|
MOVEQ #4,D1 ;GET PATTERN ROWBYTES
|
|
MOVE D1,PATROW(A6) ;SET PATTERN ROWBYTES
|
|
MOVE #3,PATHMASK(A6) ;HORIZONTAL MASK FOR PATTERN
|
|
MOVE #$3F,PATVMASK(A6) ;VERTICAL MASK FOR PATTERN
|
|
BRA.S DOOLD ;=>GO GET VERTICAL OFFSET
|
|
|
|
; NEW PATTERN. SET STARTING VERT POSITION, SET FLAG.
|
|
|
|
DONEW MOVEQ #0,D0 ;CLEAR HIGH WORD
|
|
MOVE PATVMASK(A6),D0 ;GET VERTICAL MASK
|
|
ADDQ #1,D0 ;CONVERT TO COUNT
|
|
DIVU PATROW(A6),D0 ;DIVIDE BY ROWSIZE
|
|
SUBQ #1,D0 ;CONVERT TO ROW MASK
|
|
|
|
DOOLD AND MINRECT+TOP(A6),D0 ;GET TOP VERT LOCAL COORD
|
|
MULU D1,D0 ;CALC OFFSET INTO PATTERN
|
|
MOVE.l D0,PATVPOS(A6) ;SAVE AS PATVPOS <BAL 22Jan89>
|
|
|
|
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
_SlabMode ;GET SLOW MODECASE IN A4
|
|
;RELIES ON PATROW(A6)
|
|
MOVE.L A4,MODECASE(A6) ;SAVE FOR LATER
|
|
|
|
|
|
GOFORIT
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
;------------------------------------------------------------
|
|
;
|
|
; BUMP OVAL STATE RECORDS UNLESS VERT IS BETWEEN SKIPTOP AND SKIPBOT
|
|
;
|
|
MOVE OUTEROVAL+OVALTOP(A6),D7 ;START VERT:= OUTER OVAL TOP
|
|
MOVE D7,VERT(A6) ;SET UP FOR SEEKMASK
|
|
NEXTROW CMP SKIPTOP(A6),D7 ;IS VERT < SKIPTOP ?
|
|
BLT.S YESBUMP ;YES, OK TO BUMP OVALS
|
|
CMP SKIPBOT(A6),D7 ;IS VERT >= SKIPBOT ?
|
|
BLT.S NOBUMP ;NO, SKIP BUMPING
|
|
YESBUMP MOVE D7,-(SP) ;STASH CURRENT VERT
|
|
MOVE D7,D0 ;COPY CURRENT VERTICAL
|
|
LEA OUTEROVAL(A6),A3 ;POINT TO OUTER OVAL STATE RECORD
|
|
JSR BUMPOVAL ;BUMP IT TO NEXT SCANLINE
|
|
MOVE (SP),D0 ;COPY CURRENT VERT
|
|
LEA INNEROVAL(A6),A3 ;POINT TO INNER OVAL STATE RECORD
|
|
JSR BUMPOVAL ;BUMP IT TO NEXT SCANLINE
|
|
MOVE (SP)+,D7 ;RECOVER SAVED CURRENT VERT
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; ADJUST ARC STUFF AS WE CROSS THE MIDDLE VERTICALLY
|
|
;
|
|
NOBUMP CMP MIDVERT(A6),D7 ;IS CURRENT VERT = MIDVERT ?
|
|
BNE.S NOTMID ;NO, CONTINUE
|
|
TST.B ARCFLAG(A6) ;ARE WE DOING AN ARC ?
|
|
BEQ.S NOTMID ;NO, SKIP
|
|
NEG FLAG1(A6) ;YES, INVERT FLAGS AS WE CROSS
|
|
NEG FLAG2(A6)
|
|
;
|
|
; RE-CALCULATE SKIPFLAG, AND QUIT IF IT BECOMES TRUE
|
|
;
|
|
CLR.B SKIPFLAG(A6)
|
|
MOVE ARCANGLE(A6),D0
|
|
CMP #180,D0 ;IS ARC ANGLE > 180 ?
|
|
BGT.S OBTUSE1 ;SKIP IF ANGLE > 180
|
|
BLT.S ACUTE1 ;DEAL WITH ACUTE ANGLE
|
|
CMP #270,STARTANGLE(A6) ;IS STARTANGLE = 270 ?
|
|
BNE.S OBTUSE1 ;NO, CONTINUE
|
|
BRA DONE ;YES, WE'RE ALL DONE
|
|
ACUTE1 MOVE FLAG1(A6),D0
|
|
OR FLAG2(A6),D0
|
|
BPL DONE ;QUIT IF BOTH FLAG1 AND FLAG2>=0
|
|
OBTUSE1
|
|
|
|
;
|
|
; NOW SWAP THE ROLES OF LINE1 AND LINE2 AS THEY CROSS THE MIDDLE
|
|
;
|
|
MOVE FLAG1(A6),D0 ;SWAP FLAG1 AND FLAG2
|
|
MOVE FLAG2(A6),FLAG1(A6)
|
|
MOVE D0,FLAG2(A6)
|
|
MOVE.L LINE1(A6),D0 ;SWAP LINE1 AND LINE2
|
|
MOVE.L LINE2(A6),LINE1(A6)
|
|
MOVE.L D0,LINE2(A6)
|
|
MOVE.L SLOPE1(A6),D0 ;SWAP SLOPE1 AND SLOPE2
|
|
MOVE.L SLOPE2(A6),SLOPE1(A6)
|
|
MOVE.L D0,SLOPE2(A6)
|
|
|
|
NOTMID CMP MINRECT+TOP(A6),D7 ;IS CURRENT VERT < MINV ?
|
|
BLT NODRAW ;YES, DON'T DRAW
|
|
TST.B SKIPFLAG(A6) ;ARE WE SKIPPING ?
|
|
BNE NEXTPAT ;YES, SKIP
|
|
|
|
|
|
;------------------------------------------------
|
|
;
|
|
; SEEK MASK TO THE CURRENT VERTICAL, AND
|
|
; BRANCH BASED ON SOLID OR HOLLOW OVAL OR ARC.
|
|
;
|
|
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BNE.S NOMASK ;YES, DON'T BOTHER WITH MASK
|
|
JSR ([SEEKMASK,A6]) ;MAKE RGNBUFFER CURRENT
|
|
NOMASK TST.B ARCFLAG(A6) ;ARE WE DOING AN ARC ?
|
|
BNE.S DOARC ;YES, GO TO IT
|
|
CMP INNEROVAL+OVALTOP(A6),D7 ;IS VERT >= INNEROVAL OVALTOP ?
|
|
BLT SOVAL ;NO, TREAT AS SOLID OVAL
|
|
CMP INNEROVAL+OVALBOT(A6),D7 ;IS VERT < INNEROVAL OVALTOP ?
|
|
BGE SOVAL ;NO, TREAT AS SOLID OVAL
|
|
BRA HOVAL ;YES, PROCESS HOLLOW OVAL
|
|
|
|
|
|
;----------------------------------------------
|
|
;
|
|
; SOLID OR HOLLOW ARC: CALC OUTERLEFT AND OUTERRIGHT
|
|
;
|
|
DOARC MOVE.W OUTEROVAL+LEFTMOSTEDGE(A6),D1 ;GET HI WORD OF OUTEROVAL LEFT
|
|
TST FLAG1(A6) ;IS LINE1 ACTIVE ?
|
|
BPL.S @1 ;NO, CONTINUE
|
|
CMP.W LINE1(A6),D1 ;YES, CHECK LINE1 HORIZ COORD
|
|
BGE.S @1
|
|
MOVE.W LINE1(A6),D1 ;CALC MAX(OVALLEFT,LINE1)
|
|
@1 MOVE D1,OUTERLEFT(A6) ;SAVE OUTER LEFT
|
|
|
|
MOVE.W OUTEROVAL+RIGHTMOSTEDGE(A6),D2 ;GET HI WORD OF OUTEROVAL RIGHT
|
|
TST FLAG2(A6) ;IS LINE2 ACTIVE ?
|
|
BPL.S @2 ;NO, CONTINUE
|
|
CMP.W LINE2(A6),D2 ;YES, CHECK LINE2 HORIZ COORD
|
|
BLE.S @2
|
|
MOVE.W LINE2(A6),D2 ;CALC MIN(OVALRIGHT,LINE2)
|
|
@2 MOVE D2,OUTERRIGHT(A6) ;SAVE OUTER RIGHT
|
|
|
|
CMP INNEROVAL+OVALTOP(A6),D7 ;IS VERT >= INNEROVAL OVALTOP ?
|
|
BLT SARC ;NO, PROCESS SOLID ARC
|
|
CMP INNEROVAL+OVALBOT(A6),D7 ;IS VERT < INNEROVAL OVALTOP ?
|
|
BGE SARC ;NO, PROCESS SOLID ARC
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; HOLLOW ARC: CALC INNERLEFT AND INNERRIGHT
|
|
;
|
|
HARC MOVE.W INNEROVAL+LEFTMOSTEDGE(A6),D0 ;GET HI WORD OF INNEROVAL LEFT
|
|
TST FLAG2(A6) ;IS LINE2 ACTIVE ?
|
|
BPL.S @1 ;NO, CONTINUE
|
|
CMP.W LINE2(A6),D0 ;YES, CHECK LINE2 HORIZ COORD
|
|
BLE.S @1
|
|
MOVE.W LINE2(A6),D0 ;CALC MIN(OVALLEFT,LINE2)
|
|
@1 MOVE D0,INNERLEFT(A6) ;SAVE INNER LEFT
|
|
|
|
MOVE.W INNEROVAL+RIGHTMOSTEDGE(A6),D0 ;GET HI WORD OF INNEROVAL RIGHT
|
|
TST FLAG1(A6) ;IS LINE1 ACTIVE ?
|
|
BPL.S @2 ;NO, CONTINUE
|
|
CMP.W LINE1(A6),D0 ;YES, CHECK LINE1 HORIZ COORD
|
|
BGE.S @2
|
|
MOVE.W LINE1(A6),D0 ;CALC MAX(OVALRIGHT,LINE1)
|
|
@2 MOVE D0,INNERRIGHT(A6) ;SAVE INNER RIGHT
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; IF OUTERLEFT < OUTERRIGHT THEN PAINT TWO SLABS
|
|
;
|
|
CMP D2,D1 ;IS OUTERLEFT < OUTERRIGHT ?
|
|
BGE.S @3 ;NO, CONTINUE
|
|
MOVE INNERLEFT(A6),D2
|
|
BSR.S ONESLAB
|
|
MOVE INNERRIGHT(A6),D1
|
|
MOVE OUTERRIGHT(A6),D2
|
|
BRA DOSLAB
|
|
@3
|
|
;
|
|
; ELSE IF BOTH LINES ACTIVE AND ANGLE > 180 THEN PAINT TWO OR THREE SLABS
|
|
;
|
|
MOVE FLAG1(A6),D0
|
|
AND FLAG2(A6),D0 ;ARE BOTH LINES ACTIVE ?
|
|
BPL NEXTPAT ;NO, CONTINUE
|
|
CMP #180,ARCANGLE(A6) ;IS THE ANGLE > 180 ?
|
|
BLE NEXTPAT ;NO, CONTINUE
|
|
|
|
CMP INNERLEFT(A6),D2 ;IS INNERLEFT=OUTERRIGHT?
|
|
BNE.S @4 ;NO, CONTINUE
|
|
MOVE.W INNEROVAL+LEFTMOSTEDGE(A6),D2 ;YES DRAW A THIRD SLAB
|
|
BRA.S @5
|
|
|
|
@4 MOVE OUTERLEFT(A6),D0
|
|
CMP INNERRIGHT(A6),D0 ;IS INNERRIGHT=OUTERLEFT ?
|
|
BNE.S NOT3 ;NO, CONTINUE
|
|
MOVE.W INNEROVAL+RIGHTMOSTEDGE(A6),D1 ;YES, DRAW A THIRD SLAB
|
|
MOVE OUTERRIGHT(A6),D2
|
|
@5 BSR.S ONESLAB
|
|
NOT3
|
|
|
|
MOVE OUTEROVAL+LEFTMOSTEDGE(A6),D1
|
|
MOVE INNERLEFT(A6),D2
|
|
BSR.S ONESLAB
|
|
MOVE INNERRIGHT(A6),D1
|
|
MOVE.W OUTEROVAL+RIGHTMOSTEDGE(A6),D2
|
|
BRA.S DOSLAB
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE TO SET UP AND DRAW ONE SLAB
|
|
;
|
|
ONESLAB MOVE.l PATVPOS(A6),D6 ;GET VERT POS IN PATTERN <BAL 22Jan89>
|
|
LEA ([EXPAT,A6],D6.l),A0 ;GET pointer to THIS ROW'S PATTERN
|
|
MOVE.L (A0),D6 ;set up the pattern
|
|
MOVE.L DSTLEFT(A6),A1 ;INIT DSTPTR TO LEFT
|
|
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR TO LEFT
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
; MOVE.L MODECASE(A6),A4 ;GET MODE CASE JUMP (don't need to reload)
|
|
MOVE DSTSHIFT(A6),D0 ;GET PIXEL TO BIT SHIFT AMOUNT
|
|
MOVE.L FCOLOR(A6),D4 ;PASS FCOLOR
|
|
MOVE.L BCOLOR(A6),D5 ;AND BACKCOLOR
|
|
_DrawSlab
|
|
RTS ;AND RETURN
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; SOLID ARC: IF OUTERLEFT < OUTERRIGHT THEN PAINT ONE SLAB
|
|
;
|
|
SARC CMP D2,D1 ;IS OUTERLEFT < OUTERRIGHT ?
|
|
BLT.S DOSLAB ;YES, DO ONE SLAB BETWEEN THEM
|
|
;
|
|
; ELSE IF BOTH LINES ACTIVE AND ANGLE > 180 THEN PAINT TWO SLABS
|
|
;
|
|
MOVE FLAG1(A6),D0
|
|
AND FLAG2(A6),D0 ;ARE BOTH LINES ACTIVE ?
|
|
BPL.S NEXTPAT ;NO, CONTINUE
|
|
CMP #180,ARCANGLE(A6) ;IS THE ANGLE > 180 ?
|
|
BLE.S NEXTPAT ;NO, CONTINUE
|
|
MOVE OUTEROVAL+LEFTMOSTEDGE(A6),D1
|
|
BSR ONESLAB
|
|
MOVE OUTERLEFT(A6),D1
|
|
MOVE.W OUTEROVAL+RIGHTMOSTEDGE(A6),D2
|
|
BRA.S DOSLAB
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; HOLLOW OVAL: DRAW TWO SLABS BETWEEN OUTER AND INNER OVALS
|
|
;
|
|
HOVAL MOVE.W OUTEROVAL+LEFTMOSTEDGE(A6),D1 ;GET OUTEROVAL LEFTMOSTEDGE.INT
|
|
MOVE.W INNEROVAL+LEFTMOSTEDGE(A6),D2 ;GET INNEROVAL LEFTMOSTEDGE.INT
|
|
BSR ONESLAB ;DRAW HORIZ SLAB BETWEEN THEM
|
|
MOVE.W INNEROVAL+RIGHTMOSTEDGE(A6),D1 ;GET OUTEROVAL RIGHTMOSTEDGE.INT
|
|
MOVE.W OUTEROVAL+RIGHTMOSTEDGE(A6),D2 ;GET INNEROVAL RIGHTMOSTEDGE.INT
|
|
BSR ONESLAB ;DRAW HORIZ SLAB BETWEEN THEM
|
|
BRA.S NEXTPAT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; SOLID OVAL: DRAW ONE SLAB BETWEEN LEFT AND RIGHT EDGES OF OUTER OVAL
|
|
;
|
|
SOVAL MOVE.W OUTEROVAL+LEFTMOSTEDGE(A6),D1 ;GET OUTEROVAL LEFTMOSTEDGE.INT
|
|
MOVE.W OUTEROVAL+RIGHTMOSTEDGE(A6),D2 ;GET OUTEROVAL RIGHTMOSTEDGE.INT
|
|
DOSLAB BSR ONESLAB ;DRAW HORIZ SLAB BETWEEN THEM
|
|
|
|
|
|
;-------------------------------------------------------------------
|
|
;
|
|
; BUMP DESTINATION VERTICALLY AND LOOP FOR ALL SCAN LINES
|
|
;
|
|
NEXTPAT MOVE.l PATVPOS(A6),D0 ;GET PATVPOS <BAL 22Jan89>
|
|
ADD PATROW(A6),D0 ;BUMP TO NEXT SCAN
|
|
AND PATVMASK(A6),D0 ;WRAP AT END OF PATTERN
|
|
MOVE.l D0,PATVPOS(A6) ;SAVE PATVPOS <BAL 22Jan89>
|
|
MOVE.L DSTROW(A6),D0 ;GET DST ROWBYTES
|
|
ADD.L D0,DSTLEFT(A6) ;BUMP DST TO NEXT ROW
|
|
|
|
|
|
NODRAW MOVE.L SLOPE1(A6),D0 ;BUMP LINE1 AND LINE2
|
|
ADD.L D0,LINE1(A6)
|
|
MOVE.L SLOPE2(A6),D0
|
|
ADD.L D0,LINE2(A6)
|
|
ADD #1,D7 ;BUMP CURRENT VERT
|
|
MOVE D7,VERT(A6) ;AND UPDATE PARM FOR SEEKMASK
|
|
CMP MINRECT+BOTTOM(A6),D7 ;HAVE WE REACHED THE BOTTOM YET ?
|
|
BLT NEXTROW ;NO, LOOP FOR MORE
|
|
|
|
DONE move.b MMUsave(a6),d0 ;get previous MMU state in d0
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
SHOW TST.B CRSRFLAG(A6) ;IS SCREEN DST?
|
|
BEQ.S GOHOME ;=>NO, DON'T SHOW CURSOR
|
|
_SHOWCURSOR ;RESTORE CURSOR
|
|
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
|
|
MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
|
MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGISTERS
|
|
UNLINK PARAMSIZE,'DRAWARC '
|
|
|
|
|
|
|
|
|
|
INITOVAL PROC EXPORT
|
|
;------------------------------------------------------------
|
|
;
|
|
; PROCEDURE InitOval(dstRect: Rect; VAR oval: OvalRec;
|
|
; ovalWidth,ovalHeight: INTEGER);
|
|
;
|
|
; initialize an oval state record to fit the given rectangle.
|
|
;
|
|
; INPUTS: A0: dstRect
|
|
; A1: ovalRec
|
|
; D1: ovalHeight
|
|
; D2: ovalWidth
|
|
;
|
|
; CLOBBERS D0,D1,D2
|
|
;
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; INIT OVAL TOP AND BOTTOM TO DSTRECT TOP AND BOTTOM
|
|
;
|
|
MOVE TOP(A0),OVALTOP(A1) ;INIT OVAL TOP
|
|
MOVE BOTTOM(A0),OVALBOT(A1) ;INIT OVAL BOTTOM
|
|
|
|
; CHECK OVALWIDTH AND OVALHEIGHT, PIN AT 0
|
|
|
|
TST D2 ;IS OVALWIDTH NEGATIVE ?
|
|
BPL.S OK1 ;NO, CONTINUE
|
|
CLR D2 ;YES, PIN IT TO 0
|
|
OK1 TST D1 ;IS OVALHEIGHT NEGATIVE ?
|
|
BPL.S OK2 ;NO, CONTINUE
|
|
CLR D1 ;YES, PIN IT TO 0
|
|
OK2
|
|
|
|
; CHECK OVALWIDTH AND OVALHEIGHT, TRIM IF BIGGER THAN DSTRECT
|
|
|
|
MOVE RIGHT(A0),D0
|
|
SUB LEFT(A0),D0 ;CALC DSTRECT WIDTH
|
|
CMP D0,D2 ;IS OVALWIDTH > DSTWIDTH ?
|
|
BLE.S OK3 ;NO,CONTINUE
|
|
MOVE D0,D2 ;YES, OVALWIDTH:= DSTWIDTH
|
|
OK3 MOVE BOTTOM(A0),D0
|
|
SUB TOP(A0),D0 ;CALC DSTRECT HEIGHT
|
|
CMP D0,D1 ;IS OVALHEIGHT > DSTHEIGHT ?
|
|
BLE.S OK4 ;NO,CONTINUE
|
|
MOVE D0,D1 ;YES, OVALHEIGHT:= DSTHEIGHT
|
|
OK4
|
|
; SET UP OVAL LEFT EDGE AND OVAL RIGHT EDGE, FIXED POINT NUMBERS
|
|
|
|
MOVE.W RIGHT(A0),RIGHTMOSTEDGE(A1) ;RIGHTMOSTEDGE.INT := DSTRECT.RIGHT
|
|
CLR.W RIGHTMOSTEDGE+2(A1) ;RIGHTMOSTEDGE.FRACT := 0
|
|
MOVE.W LEFT(A0),LEFTMOSTEDGE(A1) ;LEFTMOSTEDGE.INT := DSTRECT.LEFT
|
|
CLR.W LEFTMOSTEDGE+2(A1) ;LEFTMOSTEDGE.FRACT := 0
|
|
MOVE D2,D0 ;GET OVAL WIDTH
|
|
SWAP D0 ;PUT IN HI WORD
|
|
CLR D0 ;CLEAR LO WORD FOR FIXED POINT
|
|
LSR.L #1,D0 ;CALC OVAL WIDTH DIV 2
|
|
ADD.L D0,LEFTMOSTEDGE(A1) ;ADD OVALWD/2 TO LEFTMOSTEDGE
|
|
SUB.L D0,RIGHTMOSTEDGE(A1) ;SUBTRACT OVALWD/2 FROM LEFTMOSTEDGE
|
|
MOVE.L #$00008000,D0 ;GET FIXED POINT 1/2
|
|
MOVE.L D0,ONEHALF(A1) ;SAVE IN OVAL STATE RECORD
|
|
ADD.L D0,RIGHTMOSTEDGE(A1) ;BIAS RIGHT EDGE +1/2
|
|
|
|
; INIT OVALY TO -OVALHEIGHT + 1 (SCALED BY 2, BIASED 1/2 SCANLINE)
|
|
|
|
MOVEQ #1,D0
|
|
SUB D1,D0
|
|
MOVE D0,OVALY(A1) ;OVALY:=1-HEIGHT
|
|
|
|
; INIT RSQYSQ TO 2*OVALHEIGHT-1
|
|
|
|
MOVE D1,D0 ;GET HEIGHT
|
|
EXT.L D0 ;CLEAR OUT HI WORD
|
|
ADD.L D0,D0 ;CALC 2*HEIGHT
|
|
SUB.L #1,D0 ;CALC 2*HEIGHT - 1
|
|
MOVE.L D0,RSQYSQ(A1) ;RSQYSQ:=2*HEIGHT-1
|
|
|
|
; INIT SQUARE TO 0.0
|
|
|
|
CLR.L SQUARE(A1) ;SQUARE:=0
|
|
CLR.L SQUARE+4(A1) ;FRACT PART := 0 TOO
|
|
|
|
; ODDNUM:= 1 TIMES ASPECT RATIO SQUARED
|
|
|
|
CLR.L -(SP) ;GET READY FOR FUNCTION RESULT
|
|
MOVE D1,-(SP) ;PUSH NUMERATOR=HEIGHT
|
|
MOVE D2,-(SP) ;PUSH DENOMINATOR=WIDTH
|
|
_FixRatio ;CALC FIXED POINT HEIGHT/WIDTH
|
|
MOVE.L (SP),-(SP) ;DUPLICATE RESULT
|
|
PEA ODDNUM(A1) ;PUSH ADDR FOR RESULT
|
|
_LongMul ;CALC 64BIT (HEIGHT/WIDTH) SQUARED
|
|
|
|
; ODDBUMP:= 2 TIMES ASPECT RATIO SQUARED
|
|
|
|
MOVE.L ODDNUM+4(A1),D0 ;GET LO LONG OF RESULT
|
|
ADD.L D0,D0 ;DOUBLE IT
|
|
MOVE.L D0,ODDBUMP+4(A1) ;STORE INTO LO LONG OF ODDBUMP
|
|
MOVE.L ODDNUM(A1),D0
|
|
ADDX.L D0,D0 ;DOUBLE HI LONG WITH CARRY
|
|
MOVE.L D0,ODDBUMP(A1)
|
|
RTS
|
|
|
|
|
|
|
|
|
|
BUMPOVAL PROC EXPORT
|
|
;------------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE BumpOval(VAR oval: OvalRec; vert: INTEGER);
|
|
;
|
|
; bump an oval state record to the next scanline down.
|
|
;
|
|
; INPUTS: A3 POINTS TO OVAL STATE RECORD
|
|
; D0 CONTAINS CURRENT VERT
|
|
;
|
|
; CLOBBERS D0-D7,A0-A3
|
|
;
|
|
;
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; ONLY BUMP IF VERT IS BETWEEN OVALTOP AND OVALBOT
|
|
;
|
|
CMP (A3)+,D0 ;IS VERT < OVAL TOP ?
|
|
BLT.S GOHOME ;YES, IGNORE
|
|
CMP (A3)+,D0 ;IS VERT >= OVAL BOTTOM ?
|
|
BGE.S GOHOME ;YES, IGNORE
|
|
MOVE (A3),D0 ;GET OVALY
|
|
ADD #2,(A3)+ ;ADD 2 TO OVALY FOR NEXT TIME
|
|
MOVEM.L (A3),D1-D7/A0-A2 ;GET REST OF THE OVAL RECORD
|
|
BRA.S WHILE1 ;GO TO LOOP START
|
|
|
|
|
|
;------------------------------------------
|
|
;
|
|
; register usage:
|
|
;
|
|
; D0: vert
|
|
; D1: RSQYSQ
|
|
; D2,D3: SQUARE
|
|
; D4,D5: ODDNUM
|
|
; D6,D7: ODDBUMP
|
|
; A0: LEFTMOSTEDGE
|
|
; A1: RIGHTMOSTEDGE
|
|
; A2: #$00008000
|
|
; A3: modified oval ptr
|
|
;
|
|
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; WHILE SQUARE < RSQYSQ DO MAKE OVAL BIGGER
|
|
;
|
|
MORE1 ADD.L A2,A1 ;RIGHTMOSTEDGE := RIGHTMOSTEDGE + 1/2
|
|
SUB.L A2,A0 ;LEFTMOSTEDGE := LEFTMOSTEDGE - 1/2
|
|
ADD.L D5,D3 ;SQUARE := SQUARE + ODDNUM
|
|
ADDX.L D4,D2 ;ALL 64 BITS OF IT
|
|
ADD.L D7,D5 ;ODDNUM := ODDNUM + ODDBUMP
|
|
ADDX.L D6,D4 ;ALL 64 BITS OF IT
|
|
WHILE1 CMP.L D1,D2 ;IS SQUARE < RSQYSQ ?
|
|
BLT MORE1 ;YES, LOOP
|
|
BRA.S WHILE2 ;NO, GO TO NEXT LOOP START
|
|
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; WHILE SQUARE > RSQYSQ DO MAKE OVAL SMALLER
|
|
;
|
|
MORE2 SUB.L A2,A1 ;RIGHTMOSTEDGE := RIGHTMOSTEDGE - 1/2
|
|
ADD.L A2,A0 ;LEFTMOSTEDGE := LEFTMOSTEDGE + 1/2
|
|
SUB.L D7,D5 ;ODDNUM := ODDNUM - ODDBUMP
|
|
SUBX.L D6,D4 ;ALL 64 BITS OF IT
|
|
SUB.L D5,D3 ;SQUARE := SQUARE + ODDNUM
|
|
SUBX.L D4,D2 ;ALL 64 BITS OF IT
|
|
WHILE2 CMP.L D1,D2 ;IS SQUARE > RSQYSQ ?
|
|
BGT MORE2 ;YES, LOOP
|
|
|
|
ADD #1,D0 ;CALC OVALY+1
|
|
EXT.L D0 ;SIGN EXTEND TO A LONG
|
|
ASL.L #2,D0 ;CALC 4*(OVALY+1)
|
|
SUB.L D0,D1 ;RSQYSQ := RSQYSQ-4*(OVALY+1)
|
|
MOVEM.L D1-D7/A0-A2,(A3) ;UPDATE OVAL RECORD
|
|
GOHOME RTS
|
|
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|