mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-05 08:30:14 +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.
1155 lines
35 KiB
Plaintext
1155 lines
35 KiB
Plaintext
;
|
|
; File: DrawArc.m.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: © 1988-1990 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <3> 10/10/90 JL Change FixRatio to MFixRatio to avoid conflict with Traps.a
|
|
; <2> 7/20/90 gbm Move stackframe definition inside procs, to avoid global symbol
|
|
; collisions
|
|
; <1.1> 11/11/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <1.2> 10/12/88 CCH Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
;EASE$$$ READ ONLY COPY of file ÒDRAWARC.m.aÓ
|
|
; 1.1 CCH 11/11/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; OLD REVISIONS BELOW
|
|
; 1.2 CCH 10/12/1988 Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
; END EASE MODIFICATION HISTORY
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
INCLUDE 'GRAFTYPES.m.a'
|
|
;-----------------------------------------------------------
|
|
;
|
|
; --> DRAWARC.TEXT
|
|
;
|
|
; Routine to draw solid or hollow Ovals, RoundRects or Arcs.
|
|
;
|
|
|
|
|
|
DrawArc PROC EXPORT
|
|
IMPORT InitOval,BumpOval,SlopeFromAngle
|
|
IMPORT RSect,ShieldCursor,ShowCursor,TrimRect
|
|
IMPORT InitRgn,SeekRgn,PatExpand,ColorMap
|
|
IMPORT XorSlab,DrawSlab,SlabMode,FastSlabMode,MaskTab
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DrawArc(dstRect: Rect;
|
|
; hollow: BOOLEAN;
|
|
; ovalWidth,ovalHeight,mode: INTEGER;
|
|
; pat: Pattern;
|
|
; startAngle,arcAngle: INTEGER);
|
|
;
|
|
|
|
|
|
;------------------------------------------------------
|
|
;
|
|
; OFFSETS IN AN OVAL STATE RECORD:
|
|
;
|
|
OVALTOP EQU 0 ;INTEGER
|
|
OVALBOT EQU OVALTOP+2 ;INTEGER
|
|
OVALY EQU OVALBOT+2 ;INTEGER
|
|
RSQYSQ EQU OVALY+2 ;LONGINT
|
|
SQUARE EQU RSQYSQ+4 ;64 BIT LONGFIX
|
|
ODDNUM EQU SQUARE+8 ;64 BIT LONGFIX
|
|
ODDBUMP EQU ODDNUM+8 ;64 BIT LONGFIX
|
|
LEFTEDGE EQU ODDBUMP+8 ;32 BIT FIXED POINT
|
|
RIGHTEDGE EQU LEFTEDGE+4 ;32 BIT FIXED POINT
|
|
ONEHALF EQU RIGHTEDGE+4 ;32 BIT FIXED POINT
|
|
OVALSIZE EQU ONEHALF+4 ;SIZE OF AN OVALREC
|
|
|
|
;------------------------------------------------
|
|
;
|
|
; 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:
|
|
;
|
|
EXPAT EQU -64 ;16 LONGS
|
|
MINRECT EQU EXPAT-8 ;RECT
|
|
STATEA EQU MINRECT-RGNREC ;RGN STATE RECORD
|
|
STATEB EQU STATEA-RGNREC ;RGN STATE RECORD
|
|
STATEC EQU STATEB-RGNREC ;RGN STATE RECORD
|
|
SAVESTK EQU STATEC-4 ;LONG
|
|
RECTFLAG EQU SAVESTK-2 ;WORD
|
|
MASKBUF EQU RECTFLAG-4 ;LONG
|
|
BUFLEFT EQU MASKBUF-2 ;WORD
|
|
BUFSIZE EQU BUFLEFT-2 ;WORD
|
|
MODECASE EQU BUFSIZE-4 ;LONG
|
|
DSTLEFT EQU MODECASE-4 ;LONG
|
|
SAVEA5 EQU DSTLEFT-4 ;LONG
|
|
PORT EQU SAVEA5-4 ;LONG
|
|
FASTFLAG EQU PORT-2 ;BYTE
|
|
TEMPRECT EQU FASTFLAG-8 ;RECT
|
|
INNEROVAL EQU TEMPRECT-OVALSIZE ;OVAL RECORD
|
|
OUTEROVAL EQU INNEROVAL-OVALSIZE ;OVAL RECORD
|
|
SKIPTOP EQU OUTEROVAL-2 ;WORD
|
|
SKIPBOT EQU SKIPTOP-2 ;WORD
|
|
ARCFLAG EQU SKIPBOT-1 ;BYTE FLAG
|
|
SKIPFLAG EQU ARCFLAG-1 ;BYTE FLAG
|
|
STOPANGLE EQU SKIPFLAG-2 ;INTEGER
|
|
MIDVERT EQU STOPANGLE-2 ;INTEGER
|
|
MIDHORIZ EQU MIDVERT-2 ;INTEGER
|
|
WIDTH EQU MIDHORIZ-2 ;INTEGER
|
|
HEIGHT EQU WIDTH-2 ;INTEGER
|
|
SLOPE1 EQU HEIGHT-4 ;LONG, FIXED POINT
|
|
SLOPE2 EQU SLOPE1-4 ;LONG, FIXED POINT
|
|
LINE1 EQU SLOPE2-4 ;LONG, FIXED POINT
|
|
LINE2 EQU LINE1-4 ;LONG, FIXED POINT
|
|
FLAG1 EQU LINE2-2 ;WORD
|
|
FLAG2 EQU FLAG1-2 ;WORD
|
|
OUTERLEFT EQU FLAG2-2 ;WORD
|
|
OUTERRIGHT EQU OUTERLEFT-2 ;WORD
|
|
INNERLEFT EQU OUTERRIGHT-2 ;WORD
|
|
INNERRIGHT EQU INNERLEFT-2 ;WORD
|
|
PATINDEX EQU INNERRIGHT-2 ;WORD
|
|
VARSIZE EQU PATINDEX ;SIZE OF LOCAL VARIABLES
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
|
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
|
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
|
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A0),A3 ;GET CURRENT GRAFPORT
|
|
TST PNVIS(A3) ;IS PNVIS NEG ?
|
|
BLT GOHOME ;YES, QUIT
|
|
MOVE.L A3,PORT(A6) ;SAVE CURRENT GRAFPORT
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; QUIT IF MODE NOT IN 8..15
|
|
;
|
|
MOVEQ #-8,D0 ;MASK TO KILL BOTTOM 3 BITS
|
|
AND MODE(A6),D0 ;GET ALL BUT 3 BITS OF MODE
|
|
CMP #8,D0 ;IS PEN MODE 8..15 ?
|
|
BNE GOHOME ;NO, QUIT
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; ADJUST MODE AND PATTERN IF COLOR FILTERING.
|
|
;
|
|
TST COLRBIT(A3) ;IS COLORBIT NEG ?
|
|
BMI.S NOCOLOR ;YES, DON'T MAP
|
|
MOVE MODE(A6),-(SP) ;PUSH INPUT MODE
|
|
MOVE.L PAT(A6),-(SP) ;PUSH ADDR OF INPUT PATTERN
|
|
JSR COLORMAP ;ALTER BY THECOLOR, THEFILTER
|
|
MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN
|
|
MOVE (SP)+,MODE(A6) ;GET (ALTERED) MODE
|
|
NOCOLOR MOVE.L A3,A5 ;PUT GRAFPORT IN A5
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
|
;
|
|
MOVE.L CLIPRGN(A5),A2 ;GET CLIPRGN HANDLE
|
|
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
|
|
MOVE.L VISRGN(A5),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 PORTBITS+BOUNDS(A5) ;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
|
|
JSR 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(A5),-(SP) ;push rgnHandle
|
|
PEA minRect(A6) ;push addr of minRect
|
|
JSR TrimRect ;call trimRect
|
|
BLT GOHOME ;quit if intersection empty
|
|
BGT.S FLAGOK ;continue if non-rectangular
|
|
;
|
|
; CHECK FOR BLACK OR WHITE PATTERN
|
|
;
|
|
CKPAT MOVE.L PAT(A6),A0 ;POINT TO PATTERN
|
|
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,MODE(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 MODE(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,MODE(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),D0
|
|
ADD BOTTOM(A0),D0
|
|
ASR #1,D0
|
|
MOVE D0,MIDVERT(A6) ;MID VERT := (DSTBOT+DSTTOP)/2
|
|
|
|
MOVE LEFT(A0),D0
|
|
ADD RIGHT(A0),D0
|
|
ASR #1,D0
|
|
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)
|
|
|
|
_MFixRatio ;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
|
|
JSR 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
|
|
_MFixMul ;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
|
|
JSR 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
|
|
_MFixMul ;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(A5),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,TEMPRECT(A6) ;STORE RESULTS INTO TEMPRECT
|
|
|
|
LEA TEMPRECT(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.
|
|
;
|
|
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
|
MOVE.L PORTBITS+BOUNDS+TOPLEFT(A5),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
|
MOVE.L PORT(A6),A5 ;RESTORE GRAFPORT IN A5
|
|
|
|
|
|
;------------------------------------
|
|
;
|
|
; CALC BUFLEFT
|
|
;
|
|
MOVE MINRECT+LEFT(A6),D2 ;GET MINRECT LEFT
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL COORDS
|
|
AND #$FFF0,D2 ;TRUNC TO MULT OF 16
|
|
ADD PORTBITS+BOUNDS+LEFT(A5),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 BUFSIZE
|
|
;
|
|
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
|
SUB D2,D0 ;CALC MAXH-BUFLEFT
|
|
LSR #5,D0 ;DIV BY 32 FOR LONGS
|
|
MOVE D0,BUFSIZE(A6) ;BUFSIZE = # LONGS - 1
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; 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,MASKBUF(A6) ;REMEMBER WHERE MASKBUF IS
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; INIT STATE RECORDS AND ALLOCATE BUFFERS FOR EACH NON-RECTANGULAR REGION
|
|
;
|
|
CLR D5 ;INIT BOTH ARE RECT
|
|
MOVE #-32767,STATEA+THISV(A6) ;INIT REGION STATEA
|
|
MOVE #32767,STATEA+NEXTV(A6) ;TO HARMLESS IN CASE RECT
|
|
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
|
BEQ.S ARECT ;YES, CONTINUE
|
|
ADD #2,D5 ;NO, SET ITS FLAG
|
|
MOVE.L A2,A0 ;POINT TO CLIPRGN
|
|
LEA STATEA(A6),A1 ;POINT TO STATE RECORD A
|
|
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
|
|
ARECT
|
|
MOVE #-32767,STATEB+THISV(A6) ;INIT REGION STATEB
|
|
MOVE #32767,STATEB+NEXTV(A6) ;TO HARMLESS IN CASE RECT
|
|
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
|
BEQ.S BRECT ;YES, CONTINUE
|
|
ADD #4,D5 ;NO, SET ITS FLAG
|
|
MOVE.L A3,A0 ;POINT TO VISRGN
|
|
LEA STATEB(A6),A1 ;POINT TO STATE RECORD B
|
|
PEA BRECT ;PUSH FAKE RETURN ADDR
|
|
INITONE MOVE MINRECT+LEFT(A6),D0 ;GET MINH
|
|
MOVE MINRECT+RIGHT(A6),D1 ;GET MAXH
|
|
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
|
JMP INITRGN ;INIT STATE, ALLOC BUFFER
|
|
BRECT
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; IF BOTH REGIONS ARE RECTANGULAR, THEN DRAW MINRECT INTO MASK BUFFER
|
|
;
|
|
MOVE.W D5,RECTFLAG(A6) ;ARE ALL RGNS RECT ?
|
|
BNE.S NOTRECT ;NO, CONTNUE
|
|
MOVE.L MASKBUF(A6),A0 ;YES, POINT TO MASK BUFFER
|
|
MOVE MINRECT+LEFT(A6),D3 ;SET UP LEFT
|
|
SUB BUFLEFT(A6),D3 ;MAKE IT BUFFER RELATIVE
|
|
MOVE MINRECT+RIGHT(A6),D4 ;SET UP RIGHT
|
|
SUB BUFLEFT(A6),D4 ;MAKE IT BUFFER RELATIVE
|
|
JSR XorSlab ;AND XOR BETWEEN THEM
|
|
NOTRECT
|
|
|
|
SKIPSETUP
|
|
|
|
|
|
;------------------------------------
|
|
;
|
|
; CALC STARTING DSTLEFT
|
|
;
|
|
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
|
SUB PORTBITS+BOUNDS+TOP(A5),D1 ;CONVERT TO GLOBAL COORDS
|
|
MULU PORTBITS+ROWBYTES(A5),D1 ;MULT BY DST ROWBYTES
|
|
ADD.L PORTBITS+BASEADDR(A5),D1 ;ADD START OF BITMAP
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BUFLEFT TO GLOBAL
|
|
LSR #3,D2 ;CALC BUFLEFT DIV 8
|
|
EXT.L D2 ;CLR HI WORD
|
|
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
|
|
SUB D1,MINRECT+LEFT(A6)
|
|
SUB D1,MINRECT+RIGHT(A6)
|
|
SUB.W D1,OUTEROVAL+LEFTEDGE(A6) ;ADJUST OUTEROVAL LEFTEDGE.INT
|
|
SUB.W D1,OUTEROVAL+RIGHTEDGE(A6) ;ADJUST OUTEROVAL RIGHTEDGE.INT
|
|
SUB.W D1,INNEROVAL+LEFTEDGE(A6) ;ADJUST INNEROVAL LEFTEDGE.INT
|
|
SUB.W D1,INNEROVAL+RIGHTEDGE(A6) ;ADJUST INNEROVAL RIGHTEDGE.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 MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
TST.B FastFlag(A6) ;Rect clipoped and black ?
|
|
BEQ.S @1 ;no, use slow drawslab loop
|
|
JSR FastSlabMode ;yes, get fast modeCase in A4
|
|
MOVE.L A4,MODECASE(A6) ;SAVE FOR LATER
|
|
CLR PATINDEX(A6) ;MAKE UNUSED PATINDEX EVEN
|
|
BRA GOFORIT ;SKIP PATTERN STUFF
|
|
@1 JSR SlabMode ;get slow modeCase in A4
|
|
MOVE.L A4,MODECASE(A6) ;SAVE FOR LATER
|
|
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; EXPAND 8 BYTE PATTERN TO 16 LONGS AND INIT PATTERN SELECTOR
|
|
;
|
|
CLR.L D7 ;SAY NOT INVERTED
|
|
MOVE MODE(A6),D2 ;GET MODE
|
|
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 MOVE PORTBITS+BOUNDS+LEFT(A5),D2 ;GET GLOBAL-LOCAL OFFSET
|
|
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
|
|
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR PATEXPAND ;EXPAND 8 BYTE PATTERN TO 16 LONGS
|
|
MOVE.L PORT(A6),A5 ;RESTORE GRAFPORT IN A5
|
|
MOVEQ #$F,D0 ;TREAT COORD MOD 16
|
|
AND MINRECT+TOP(A6),D0 ;GET TOP VERT LOCAL COORD
|
|
LSL #2,D0 ;QUAD FOR 4 BYTE PATTERNS
|
|
MOVE D0,PATINDEX(A6) ;SET UP PATTERN INDEX
|
|
|
|
|
|
|
|
;------------------------------------------------------------
|
|
;
|
|
; BUMP OVAL STATE RECORDS UNLESS VERT IS BETWEEN SKIPTOP AND SKIPBOT
|
|
;
|
|
GOFORIT MOVE OUTEROVAL+OVALTOP(A6),D7 ;START VERT:= OUTER OVAL TOP
|
|
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
|
|
BSR SEEKMASK ;MAKE MASKBUF 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+LEFTEDGE(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+RIGHTEDGE(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+LEFTEDGE(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+RIGHTEDGE(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+LEFTEDGE(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+RIGHTEDGE(A6),D1 ;YES, DRAW A THIRD SLAB
|
|
MOVE OUTERRIGHT(A6),D2
|
|
@5 BSR.S ONESLAB
|
|
NOT3
|
|
|
|
MOVE OUTEROVAL+LEFTEDGE(A6),D1
|
|
MOVE INNERLEFT(A6),D2
|
|
BSR.S ONESLAB
|
|
MOVE INNERRIGHT(A6),D1
|
|
MOVE.W OUTEROVAL+RIGHTEDGE(A6),D2
|
|
BRA.S DOSLAB
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE TO SET UP AND DRAW ONE SLAB
|
|
;
|
|
ONESLAB MOVEQ #$3F,D6 ;GET WRAP-AROUND MASK
|
|
AND PATINDEX(A6),D6 ;GET PATINDEX MOD 64
|
|
MOVE.L EXPAT(A6,D6),D6 ;GET THIS ROW'S PATTERN
|
|
LEA MaskTab,A0 ;POINT TO MASK TABLE
|
|
MOVE.L DSTLEFT(A6),A1 ;INIT DSTPTR TO LEFT
|
|
MOVE.L MASKBUF(A6),A2 ;INIT MASKPTR TO LEFT
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
MOVE.L MODECASE(A6),A4 ;GET MODE CASE JUMP
|
|
JMP DrawSlab
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; 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+LEFTEDGE(A6),D1
|
|
BSR ONESLAB
|
|
MOVE OUTERLEFT(A6),D1
|
|
MOVE.W OUTEROVAL+RIGHTEDGE(A6),D2
|
|
BRA.S DOSLAB
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; HOLLOW OVAL: DRAW TWO SLABS BETWEEN OUTER AND INNER OVALS
|
|
;
|
|
HOVAL MOVE.W OUTEROVAL+LEFTEDGE(A6),D1 ;GET OUTEROVAL LEFTEDGE.INT
|
|
MOVE.W INNEROVAL+LEFTEDGE(A6),D2 ;GET INNEROVAL LEFTEDGE.INT
|
|
BSR ONESLAB ;DRAW HORIZ SLAB BETWEEN THEM
|
|
MOVE.W INNEROVAL+RIGHTEDGE(A6),D1 ;GET OUTEROVAL RIGHTEDGE.INT
|
|
MOVE.W OUTEROVAL+RIGHTEDGE(A6),D2 ;GET INNEROVAL RIGHTEDGE.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+LEFTEDGE(A6),D1 ;GET OUTEROVAL LEFTEDGE.INT
|
|
MOVE.W OUTEROVAL+RIGHTEDGE(A6),D2 ;GET OUTEROVAL RIGHTEDGE.INT
|
|
DOSLAB BSR ONESLAB ;DRAW HORIZ SLAB BETWEEN THEM
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------
|
|
;
|
|
; BUMP DESTINATION VERTICALLY AND LOOP FOR ALL SCAN LINES
|
|
;
|
|
NEXTPAT ADD #4,PATINDEX(A6) ;BUMP PATTERN INDEX
|
|
MOVE PORTBITS+ROWBYTES(A5),D0 ;GET DST ROWBYTES
|
|
EXT.L D0 ;MAKE IT LONG
|
|
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
|
|
CMP MINRECT+BOTTOM(A6),D7 ;HAVE WE REACHED THE BOTTOM YET ?
|
|
BLT NEXTROW ;NO, LOOP FOR MORE
|
|
|
|
DONE MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR SHOWCURSOR ;RESTORE CURSOR
|
|
GOHOME MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
|
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
|
UNLINK PARAMSIZE,'DRAWARC '
|
|
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
;
|
|
; LOCAL ROUTINE TO UPDATE THE MASK BUFFER
|
|
; BASED ON WHICH REGIONS ARE RECTANGULAR
|
|
;
|
|
SEEKMASK MOVE D7,D0 ;GET CURRENT VERT COORD
|
|
MOVE RECTFLAG(A6),D1 ;GET RECTFLAG = 0,2,4
|
|
MOVE RECTJMP(D1),D1 ;GET OFFSET FROM TABLE
|
|
JMP RECTJMP(D1) ;TAKE CASE JUMP
|
|
|
|
RECTJMP DC.W IGNORE-RECTJMP ;DO NOTHING IF BOTH RECT
|
|
DC.W A-RECTJMP
|
|
DC.W B-RECTJMP
|
|
DC.W AB-RECTJMP
|
|
|
|
;
|
|
; ONLY REGION A IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
|
;
|
|
A LEA STATEA(A6),A1
|
|
JSRSEEK JSR SEEKRGN
|
|
MOVE.L SCANBUF(A1),MASKBUF(A6)
|
|
IGNORE RTS
|
|
|
|
|
|
;
|
|
; ONLY REGION B IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
|
;
|
|
B LEA STATEB(A6),A1
|
|
BRA.S JSRSEEK
|
|
|
|
;
|
|
; REGIONS A AND B ARE NON-RECTANGULAR. UPDATE EACH,
|
|
; THEN FORM INTERSECTION IN THE MASK BUFFER.
|
|
;
|
|
AB LEA STATEA(A6),A1
|
|
JSR SEEKRGN
|
|
LEA STATEB(A6),A1
|
|
JSR SEEKRGN
|
|
MOVE.L STATEA+SCANBUF(A6),A0
|
|
MOVE.L STATEB+SCANBUF(A6),A1
|
|
MOVE.L MASKBUF(A6),A2
|
|
MOVE BUFSIZE(A6),D1
|
|
ABLOOP MOVE.L (A0)+,D0
|
|
AND.L (A1)+,D0
|
|
MOVE.L D0,(A2)+
|
|
DBRA D1,ABLOOP
|
|
RTS
|
|
|
|
|
|
|
|
|
|
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
|
|
;
|
|
|
|
;------------------------------------------------------
|
|
;
|
|
; OFFSETS IN AN OVAL STATE RECORD:
|
|
;
|
|
OVALTOP EQU 0 ;INTEGER
|
|
OVALBOT EQU OVALTOP+2 ;INTEGER
|
|
OVALY EQU OVALBOT+2 ;INTEGER
|
|
RSQYSQ EQU OVALY+2 ;LONGINT
|
|
SQUARE EQU RSQYSQ+4 ;64 BIT LONGFIX
|
|
ODDNUM EQU SQUARE+8 ;64 BIT LONGFIX
|
|
ODDBUMP EQU ODDNUM+8 ;64 BIT LONGFIX
|
|
LEFTEDGE EQU ODDBUMP+8 ;32 BIT FIXED POINT
|
|
RIGHTEDGE EQU LEFTEDGE+4 ;32 BIT FIXED POINT
|
|
ONEHALF EQU RIGHTEDGE+4 ;32 BIT FIXED POINT
|
|
OVALSIZE EQU ONEHALF+4 ;SIZE OF AN OVALREC
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; 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),RIGHTEDGE(A1) ;RIGHTEDGE.INT := DSTRECT.RIGHT
|
|
CLR.W RIGHTEDGE+2(A1) ;RIGHTEDGE.FRACT := 0
|
|
MOVE.W LEFT(A0),LEFTEDGE(A1) ;LEFTEDGE.INT := DSTRECT.LEFT
|
|
CLR.W LEFTEDGE+2(A1) ;LEFTEDGE.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,LEFTEDGE(A1) ;ADD OVALWD/2 TO LEFTEDGE
|
|
SUB.L D0,RIGHTEDGE(A1) ;SUBTRACT OVALWD/2 FROM LEFTEDGE
|
|
MOVE.L #$00008000,D0 ;GET FIXED POINT 1/2
|
|
MOVE.L D0,ONEHALF(A1) ;SAVE IN OVAL STATE RECORD
|
|
ADD.L D0,RIGHTEDGE(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
|
|
_MFixRatio ;CALC FIXED POINT HEIGHT/WIDTH
|
|
MOVE.L (SP),-(SP) ;DUPLICATE RESULT
|
|
PEA ODDNUM(A1) ;PUSH ADDR FOR RESULT
|
|
_MLongMul ;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
|
|
;
|
|
;
|
|
|
|
;------------------------------------------------------
|
|
;
|
|
; OFFSETS IN AN OVAL STATE RECORD:
|
|
;
|
|
OVALTOP EQU 0 ;INTEGER
|
|
OVALBOT EQU OVALTOP+2 ;INTEGER
|
|
OVALY EQU OVALBOT+2 ;INTEGER
|
|
RSQYSQ EQU OVALY+2 ;LONGINT
|
|
SQUARE EQU RSQYSQ+4 ;64 BIT LONGFIX
|
|
ODDNUM EQU SQUARE+8 ;64 BIT LONGFIX
|
|
ODDBUMP EQU ODDNUM+8 ;64 BIT LONGFIX
|
|
LEFTEDGE EQU ODDBUMP+8 ;32 BIT FIXED POINT
|
|
RIGHTEDGE EQU LEFTEDGE+4 ;32 BIT FIXED POINT
|
|
ONEHALF EQU RIGHTEDGE+4 ;32 BIT FIXED POINT
|
|
OVALSIZE EQU ONEHALF+4 ;SIZE OF AN OVALREC
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; 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: LEFTEDGE
|
|
; A1: RIGHTEDGE
|
|
; A2: #$00008000
|
|
; A3: modified oval ptr
|
|
;
|
|
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; WHILE SQUARE < RSQYSQ DO MAKE OVAL BIGGER
|
|
;
|
|
MORE1 ADD.L A2,A1 ;RIGHTEDGE := RIGHTEDGE + 1/2
|
|
SUB.L A2,A0 ;LEFTEDGE := LEFTEDGE - 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 ;RIGHTEDGE := RIGHTEDGE - 1/2
|
|
ADD.L A2,A0 ;LEFTEDGE := LEFTEDGE + 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
|
|
|
|
|
|
|
|
|
|
END
|
|
|
|
|
|
|
|
|