mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-14 02:30:24 +00:00
1780 lines
56 KiB
Plaintext
1780 lines
56 KiB
Plaintext
;
|
||
; File: DrawLine.a
|
||
;
|
||
; Copyright: © 1981-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM2> 6/11/92 stb <sm 6/9/92>stb Synched with QDciPatchROM.a; added comments to
|
||
; DrawLine, SkipSetup, FASTLINE, HTOGL, VLINE, FASTSLANT.
|
||
; <8> 12/13/90 SMC Refixed <7>. With KON.
|
||
; <7> 11/26/90 SMC Fixed call to StretchBits to use locmode with pattern bit
|
||
; forced. PnMode was being used. With BAL.
|
||
; <6> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
||
; <5> 9/17/90 BG Removed <3>. 040s are now behaving more reliably.
|
||
; <4> 7/20/90 gbm Change some identifiers to cease conflicting with interface
|
||
; files
|
||
; <3> 6/26/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <2> 2/13/90 BAL Ensure that the initial bit offset is calculated in a long
|
||
; instead of a word so that lines drawn into really wide pixmaps
|
||
; don't freak out.
|
||
; <•1.6> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.5> 6/30/89 BAL Cleared runBuf(a6) before calling getSeek
|
||
; <•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.
|
||
; 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>
|
||
; 6/4/87 CRC preserve hilite mode across calls to colormap; set patmode in
|
||
; case user forgot
|
||
; 1/3/87 CRC pass color param to stretch
|
||
; 12/12/86 CRC Added support for arithmetic modes
|
||
; 10/9/86 EHB Added mask parameters to stretchbits calls
|
||
; 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
|
||
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetMask
|
||
; 6/20/86 EHB New params to COLORMAP; Added FCOLOR and BCOLOR to stack frame
|
||
; 6/18/86 EHB Call StretchBits instead of RgnBlt
|
||
; 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
|
||
; 6/5/86 EHB Clear flag bits from all references to rowBytes
|
||
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
MACHINE MC68020
|
||
|
||
;-----------------------------------------------------------------
|
||
;
|
||
; --> DRAWLINE.TEXT
|
||
;
|
||
;------------------------------------------------------------------
|
||
|
||
DrawLine PROC EXPORT
|
||
IMPORT SHFTTBL
|
||
Export steepBlitTab,shallowBlitTab,FastLine,FastSlant
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DRAWLINE(P1,P2: POINT);
|
||
;
|
||
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
|
||
;
|
||
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
|
||
;
|
||
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 8 ;SIZE OF PARAMETERS
|
||
P1 EQU PARAMSIZE+8-4 ;POINT
|
||
P2 EQU P1-4 ;POINT
|
||
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACK FRAME VARS USED BY SEEKMASK (CALLED BY STRETCHBITS, RGNBLT, DRAWARC, DRAWLINE)
|
||
;
|
||
&CurFile SETC 'DRAWLINE'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
;-------------------------------------------------
|
||
; includes fixes as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
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
|
||
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
|
||
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
|
||
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
|
||
BLT GOHOME ;YES, QUIT
|
||
MOVE.W PNMODE(A3),D1 ;get pen mode Start of <7>
|
||
_GetStreamMode ;strip off alpha bits
|
||
;this code moved up here from below at SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
||
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 <7>
|
||
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; 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 DSTBITS TO PIXMAP
|
||
; (A5 must contain global ptr)
|
||
;
|
||
LEA PORTBITS(A3),A1 ;GET POINTER TO DSTBITS
|
||
LEA DSTPIX(A6),A2 ;USE DSTPIX IN ITS PLACE
|
||
_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 ;TO CONVERT DEPTH TO SHIFT
|
||
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)
|
||
;
|
||
LEA PNPAT(A3),A0 ;POINT TO THE PATTERN
|
||
MOVE.L A0,LOCPAT(A6) ;COPY PATTERN POINTER
|
||
TST PORTBITS+ROWBYTES(A3) ;IS THE DST OLD OR NEW?
|
||
;ciDrawLine from QDciPatchROM.a used to be right here
|
||
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; Check for color filtering. Alter mode and pattern accordingly.
|
||
;
|
||
MOVE.B HiliteMode,-(SP) ;preserve the hilite mode
|
||
CLR.B multiColor(A6) ;use fg/bg color
|
||
_COLORMAP ;CHECK AGAINST THECOLOR, THEFILTER
|
||
MOVE.B (SP)+,HiliteMode ;since stretch (and thus ColorMap) may be called later
|
||
|
||
;---------------------------------------------------------
|
||
;
|
||
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
||
;
|
||
MOVE.L A3,A5 ;PUT GRAFPTR IN A5
|
||
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
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; SET UP LINERECT, THE RECTANGLE BOUNDING THE LINE AND PEN
|
||
;
|
||
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V1, D2=H1, D3=V2, D4=H2
|
||
CMP D3,D1 ;IS V1 > V2 ?
|
||
BLE.S VOK2 ;NO, CONTINUE
|
||
EXG D1,D3 ;YES, SWAP VERT
|
||
VOK2 CMP D4,D2 ;IS H1 > H2 ?
|
||
BLE.S HOK2 ;NO, CONTINUE
|
||
EXG D2,D4 ;NO SWAP HORIZ
|
||
HOK2 ADD PNSIZE+H(A5),D4 ;ADD PEN WIDTH TO RIGHT
|
||
ADD PNSIZE+V(A5),D3 ;ADD PEN HEIGHT TO BOTTOM
|
||
MOVEM.W D1/D2/D3/D4,LINERECT(A6) ;STORE TOP, LEFT, BOTTOM, RIGHT
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; CALC MINRECT, THE INTERSECTION OF LINERECT, BITMAP BOUNDS,
|
||
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
|
||
;
|
||
PEA LINERECT(A6) ;PUSH LINE RECT
|
||
PEA DSTPIX+BOUNDS(A6) ;PUSH PIXMAP 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
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT AND DST IS SCREEN.
|
||
; (A5 must contain global ptr)
|
||
;
|
||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
|
||
BEQ.S NOTSCRN ;=>NO
|
||
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
||
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
|
||
_SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
||
NOTSCRN MOVE.L PORT(A6),A5 ;GET BACK THEPORT
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; 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
|
||
MOVE.W #-1,-(SP) ;pass Trim = True
|
||
_TrimRect ;call trimRect
|
||
BLT show ;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 ;=>no, 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) ;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 show ;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
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; GET THE TWO LINE ENDPOINTS INTO REGISTERS
|
||
; AND CHECK FOR HORIZONTAL OR VERTICAL LINE
|
||
;
|
||
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V2, D2=H2, D3=V1, D4=H1
|
||
CMP D2,D4 ;H1=H2 ?
|
||
BEQ.S HVLINE ;YES, DO VERTICAL LINE
|
||
CMP D1,D3 ;NO, IS V2 > V1 ?
|
||
BGT.S SLANTED ;YES, DRAW SLANTED LINE
|
||
BLT.S VSWAP ;SWAP POINTS AND DRAW SLANTED
|
||
;ELSE V1=V2, DO HORIZONTAL
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; LINE IS EITHER HORIZONTAL OR VERTICAL.
|
||
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND
|
||
; CLIPRGN AND VISRGN BOTH RECTANGULAR. IF SO, OPTIMIZE FAST LINES.
|
||
;
|
||
HVLINE TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
||
BEQ.S NOTFAST ;NO, CONTINUE
|
||
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
||
bne.s NotFast ;NO, CONTINUE
|
||
_FastLineJmp ;YES, DO IT FAST !
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
;
|
||
; NOT FASTLINE. PUSH PARAMS AND CALL STRETCHBITS FOR HORIZ OR VERT LINE.
|
||
;
|
||
NOTFAST PEA PORTBITS(A5) ;PUSH SRCBITS = PORTBITS
|
||
CLR.L -(SP) ;NO MASKBITS
|
||
PEA PORTBITS(A5) ;PUSH DSTPIX
|
||
PEA MINRECT(A6) ;PUSH SRCRECT = DSTRECT
|
||
CLR.L -(SP) ;NO MASKRECT
|
||
PEA MINRECT(A6) ;PUSH DSTRECT
|
||
MOVE PNMODE(A5),D0 ;GET MODE <8>
|
||
AND #$FCFF,D0 ;STRIP SOME BITS <8>
|
||
BSET #3,D0 ;set the pattern bit in case the user forgot to <8>
|
||
MOVE D0,-(SP) ;PUSH CLEANED MODE <8>
|
||
PEA PNPAT(A5) ;PUSH PATTERN
|
||
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIPRGN HANDLE
|
||
MOVE.L VISRGN(A5),-(SP) ;PUSH VISRGN HANDLE
|
||
MOVE.L BIGRGN(A6),-(SP) ;PUSH SAVED WIDEOPEN
|
||
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||
CLR -(SP) ;pass multicolor flag false
|
||
_STRETCHBITS ;DRAW THE HORIZ OR VERT LINE
|
||
BRA show ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; THE LINE IS SLANTED. SORT VERTICALLY
|
||
; AND DRAW TOP TO BOTTOM AS HORIZONTAL SLABS.
|
||
;
|
||
VSWAP EXG D1,D3 ;SORT POINTS BY VERTICAL
|
||
EXG D2,D4 ;SWAP HORIZ TO MATCH
|
||
SLANTED MOVE D3,D0 ;COPY LINE BOTTOM
|
||
ADD PNSIZE+V(A5),D0 ;ADD PEN HEIGHT
|
||
CMP minRect+TOP(A6),D0 ;IS RESULT <= minRect TOP ? <07Jul89>
|
||
BLE show ;YES, RESTORE CURSOR AND QUIT
|
||
CMP minRect+BOTTOM(A6),D1 ;IS TOP >= minRect BOTTOM ? <07Jul89>
|
||
BGE show ;YES, RESTORE CURSOR AND QUIT
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; SET UP INITIAL FIXED POINT LEFTEDGE AND RIGHTEDGE
|
||
; AND CHECK FOR ZERO PENSIZE.
|
||
;
|
||
MOVE.W D2,LEFTEDGE(A6) ;LEFTEDGE.INT := TOP HORIZ
|
||
MOVE.W #$8000,LEFTEDGE+2(A6) ;LEFTEDGE.FRACT := 1/2
|
||
MOVE.L LEFTEDGE(A6),RIGHTEDGE(A6) ;RIGHTEDGE:=LEFTEDGE
|
||
MOVE PNSIZE+H(A5),D0 ;GET PEN WIDTH
|
||
BLE show ;QUIT IF PENWIDTH <= 0
|
||
ADD.W D0,RIGHTEDGE(A6) ;ADD TO RIGHTEDGE.INT
|
||
MOVE PNSIZE+V(A5),D6 ;GET PEN HEIGHT
|
||
BLE show ;QUIT IF PEN HEIGHT <= 0
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CALC FIXED POINT SLOPE = FixRatio(dh,dv);
|
||
;
|
||
SUB D2,D4 ;CALC DH
|
||
SUB D1,D3 ;CALC DV
|
||
ext.l D3
|
||
moveq #0,d7 ;clear out high word
|
||
move.w d4,d7 ;copy DH to d7
|
||
swap D7
|
||
DIVS.l D3,D7 ;CALC FIXED POINT SLOPE DH/DV
|
||
MOVE.L D7,SLOPE(A6) ;SAVE FOR LATER
|
||
|
||
;
|
||
; CALC adjust := pen height * slope
|
||
;
|
||
move.l d7,d5 ;assume height is 1
|
||
cmp.w #1,d6 ;is pen height 1
|
||
beq.s @gotAdjust
|
||
ext.l d6
|
||
MULS.L d6,d5 ;CALC FixMul(pnSize.v,slope)
|
||
|
||
|
||
@gotAdjust
|
||
;
|
||
; ADJUST LEFTEDGE AND RIGHTEDGE DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
|
||
; Set steepFlag in A2: 0->shallow; 1->down&right; -1->down&left
|
||
|
||
sub.l a2,a2 ;assume shallow
|
||
MOVE.L D7,D0 ;COPY SLOPE
|
||
ASR.L #1,D0 ;CALC SLOPE/2
|
||
ADD.L D0,LEFTEDGE(A6) ;ADD SLOPE/2 TO LEFT EDGE
|
||
ADD.L D0,RIGHTEDGE(A6) ;ADD SLOPE/2 TO RIGHT EDGE
|
||
|
||
TST.L D7 ;IS SLOPE NEGATIVE ?
|
||
BMI.S NEGSLOPE ;YES, CONTINUE
|
||
SUB.L D5,LEFTEDGE(A6) ;SUBTRACT ADJUST FROM LEFTEDGE
|
||
CMP.L #$00010000,D7 ;IS SLOPE < ONE ?
|
||
BGT.S LESSV1 ;NO, BRANCH
|
||
BEQ.S Pos45 ;NO, BRANCH
|
||
|
||
MOREV1 ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFTEDGE
|
||
addq #1,a2 ;remember steep and to right
|
||
BRA.S SLOPEOK ;CONTINUE
|
||
|
||
Pos45 addq #1,a2 ;remember 45°
|
||
LESSV1 SUB.W #1,RIGHTEDGE(A6) ;RIGHTEDGE := RIGHTEDGE - 1
|
||
BRA.S SLOPEOK ;CONTINUE
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; SLOPE IS NEGATIVE
|
||
;
|
||
NEGSLOPE SUB.L D5,RIGHTEDGE(A6) ;SUBTRACT ADJUST FROM RIGHTEDGE
|
||
CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
|
||
BLT.S LESSV2 ;NO, CONTINUE
|
||
|
||
MOREV2 ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHTEDGE
|
||
subq #1,a2 ;remember steep and to left
|
||
BRA.S SLOPEOK
|
||
|
||
LESSV2 ADD.W #1,LEFTEDGE(A6) ;LEFTEDGE := LEFTEDGE + 1
|
||
|
||
|
||
|
||
SLOPEOK MOVEM.W MINRECT(A6),D1/D2/D3/D4 ;GET MINRECT TOP,LEFT,BOTTOM,RIGHT
|
||
;
|
||
; ADJUST LEFTEDGE AND RIGHTEDGE IF LINE WAS CLIPPED VERTICALLY
|
||
;
|
||
CMP LINERECT+TOP(A6),D1 ;DID TOP GET CLIPPED ?
|
||
BEQ.S TOPOK ;NO, CONTINUE
|
||
MOVE D1,D0
|
||
SUB LINERECT+TOP(A6),D0 ;CALC DISCARD AMOUNT
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE.L D7,D5 ;GET 32 BIT SLOPE
|
||
MULS.L D0,D5 ;SLOPE * SCANS CLIPPED
|
||
ADD.L D5,LEFTEDGE(A6) ;BUMP LEFTEDGE TO NEW TOP
|
||
ADD.L D5,RIGHTEDGE(A6) ;BUMP RIGHTEDGE TO NEW TOP
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; LINE IS SLANTED. IF |SLOPE| <= 1 THEN
|
||
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND CLIPRGN
|
||
; AND VISRGN BOTH RECTANGULAR. IF SO THEN OPTIMIZE.
|
||
;
|
||
TOPOK
|
||
; bchg #0,0 ;debugging code
|
||
; beq.s CalcBufLeft
|
||
|
||
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
||
BEQ.S CalcBufLeft ;NO, CONTINUE
|
||
cmp.w LINERECT+left(a6),D2 ;is MinRect.Left>Line's left edge?
|
||
bgt.s CalcBufLeft ;horizontally clipped!
|
||
cmp.w LINERECT+right(a6),D4 ;is MinRect.Right<Line's right edge?
|
||
blt.s CalcBufLeft ;horizontally clipped!
|
||
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
||
bne.s CalcBufLeft ;no, continue
|
||
_FastSlantJmp ;YES, DO IT FAST !
|
||
;Assumes: D1,D2,D3,D4 = MinRect T,L,B,R
|
||
; D7 = slope (16.16)
|
||
CalcBufLeft
|
||
;-----------------------------------------------------------
|
||
;
|
||
; CALC BUFLEFT
|
||
;
|
||
;D2 = MINRECT LEFT
|
||
MOVE DSTSHIFT(A6),D5 ;GET SHIFT FOR PIXEL DEPTH
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL COORDS
|
||
ext.l d2 ;make it a long <BAL 17Jan89>
|
||
LSL.l D5,D2 ;CONVERT PIXELS TO BITS
|
||
AND.l #~$1f,D2 ;TRUNC TO MULT OF 32 BITS
|
||
MOVE.l D2,D1 ;GET BUFLEFT IN BITS
|
||
LSR.l #3,D1 ;CONVERT BITS TO BYTES
|
||
MOVE D1,PATHPOS(A6) ;AND SAVE AS HORIZONTAL PATTERN BASE
|
||
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
|
||
;
|
||
;D4 = MINRECT RIGHT
|
||
SUB D2,D4 ;CALC MAXH-BUFLEFT
|
||
move d4,d0 ;save for expansion scanline buffer <C954>
|
||
|
||
ext.l d4 ;clear out high word <C954>
|
||
lsl.l d5,d4 ;convert to bits <C954>
|
||
subq.l #1,d4 ;force downward round <C954>
|
||
LSR.l #5,D4 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
|
||
MOVE D4,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(A5),-(SP) ;PUSH VIS RGNHANDLE
|
||
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIP RGNHANDLE
|
||
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 TryLine, fixes both patches on _FastSlabMode and _GetSeek <sm 6/9/92>stb
|
||
|
||
MOVE MINRECT+TOP(A6),D1
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT MINV TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;get dst rowbytes
|
||
AND #nuRBMask,D0 ;clear off flag bits
|
||
MOVE 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 LEFTEDGE,RIGHTEDGE,MINRECT RELATIVE TO BUFFER LEFT
|
||
;
|
||
MOVE BUFLEFT(A6),D1
|
||
SUB.W D1,LEFTEDGE(A6) ;ADJUST LEFTEDGE.INT
|
||
SUB.W D1,RIGHTEDGE(A6) ;ADJUST RIGHTEDGE.INT
|
||
SUB D1,MINRECT+LEFT(A6)
|
||
SUB D1,MINRECT+RIGHT(A6)
|
||
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; TAKE FAST OR SLOW OUTER CONTROL LOOP FOR SLANTED LINES:
|
||
;
|
||
TST.B fastFlag(A6) ;ARE WE RECT CLIPPED BLACK ?
|
||
BEQ.S GOSLOW ;NO, CONTINUE
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
_FastSlabMode ;Get fast case jump in A4
|
||
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
||
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
||
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
||
MOVE.L FCOLOR(A6),D4 ;PASS FCOLOR
|
||
MOVE.L BCOLOR(A6),D5 ;AND BACKCOLOR
|
||
MOVE MINRECT+BOTTOM(A6),D6 ;GET MINRECT BOTTOM
|
||
SUB MINRECT+TOP(A6),D6 ;CALC HEIGHT
|
||
SUB #1,D6 ;MINUS 1 FOR DBRA COUNT
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; 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
|
||
|
||
NXTFAST MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
||
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
||
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
||
MOVE.W DSTSHIFT(A6),D0 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
_DrawSlab ;DRAW ONE SLAB IN PENMODE
|
||
ADD DSTROW(A6),A5 ;BUMP DST TO NEXT ROW
|
||
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
||
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
||
DBRA D6,NXTFAST ;LOOP FOR ALL SCANLINES
|
||
BRA DONE ;AND QUIT
|
||
|
||
|
||
GOSLOW
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SET INVERSE FLAG AND CALL PATEXPAND TO EXPAND PATTERN
|
||
;
|
||
CLR.L D7 ;SAY NOT INVERTED
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
BTST #5,D2 ;a new arithmetic mode?
|
||
BNE.S NOTINV ;if so, no invert bit to test
|
||
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.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||
_PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
||
;SETUP PATROW,PATHMASK,PATVMASK
|
||
MOVE PATROW(A6),D1 ;GET THE PATTERN ROWBYTES
|
||
BNE.S DONEW ;=>NON-ZERO, IT'S A NEW PATTERN
|
||
|
||
MOVEQ #$F,D6 ;ELSE 16 ROWS OF PATTERN
|
||
MOVEQ #$4,D1 ;GET PATTERN ROWBYTES INTO D1
|
||
MOVE D1,PATROW(A6) ;AND SET PATTERN ROWBYTES
|
||
MOVE #$3,PATHMASK(A6) ;HORIZONTAL MASK FOR PATTERN
|
||
MOVE #$3F,PATVMASK(A6) ;VERTICAL MASK FOR PATTERN
|
||
BRA.S DOOLD ;=>GO GET STARTING OFFSET INTO PATTERN
|
||
|
||
; NEW PATTERN. SET STARTING VERT POSITION.
|
||
|
||
DONEW MOVEQ #0,D6 ;CLEAR HIGH WORD
|
||
MOVE PATVMASK(A6),D6 ;GET VERTICAL MASK
|
||
ADDQ #1,D6 ;CONVERT TO COUNT
|
||
DIVU PATROW(A6),D6 ;DIVIDE BY ROWSIZE
|
||
SUBQ #1,D6 ;GET ROWS OF PATTERN
|
||
|
||
DOOLD AND MINRECT+TOP(A6),D6 ;GET TOP VERT LOCAL COORD
|
||
MULU D1,D6 ;CALC OFFSET INTO PATTERN
|
||
MOVE.l D6,PATVPOS(A6) ;SAVE AS PATVPOS <BAL 22Jan89>
|
||
|
||
; GET SLOW SLABMODE IN A4 (RELIES ON PATROW, SET UP BY PATEXPAND)
|
||
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
_SlabMode ;GET DrawSlab CASE JUMP IN A4
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; 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
|
||
|
||
; FOR EACH SLAB, MAKE MASK BUFFER CURRENT AND DRAW SLAB
|
||
|
||
MOVE MINRECT+TOP(A6),VERT(A6) ;INIT CURRENT VERT:=MINV
|
||
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
||
MOVE.L FCOLOR(A6),D4 ;PASS FCOLOR
|
||
MOVE.L BCOLOR(A6),D5 ;AND BACKCOLOR
|
||
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
||
NXTMASK JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
||
LEA ([EXPAT,A6],D6.l),A0 ;GET pointer to THIS ROW'S PATTERN
|
||
MOVE.L (A0),D6 ;set up the pattern
|
||
MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
||
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
||
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
||
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR TO LEFT
|
||
MOVE.W DSTSHIFT(A6),D0 ;GET SHIFT FOR PIXEL DEPTH
|
||
_DrawSlab ;DRAW ONE SLAB IN PENMODE
|
||
MOVE.l PATVPOS(A6),D6 ;GET PATVPOS <BAL 22Jan89>
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;WRAP AT END OF PATTERN
|
||
MOVE.l D6,PATVPOS(A6) ;SAVE PATVPOS FOR DRAWSLAB <BAL 22Jan89>
|
||
ADD DSTROW(A6),A5 ;BUMP DST TO NEXT ROW
|
||
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
||
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
||
ADD #1,VERT(A6) ;BUMP CURRENT VERT FOR SEEKMASK
|
||
MOVE VERT(A6),D0 ;GET CURRENT VERT
|
||
CMP MINRECT+BOTTOM(A6),D0 ;AT BOTTOM YET ?
|
||
BLT NXTMASK ;NO, LOOP ALL SCAN LINES
|
||
|
||
|
||
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 MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
||
TST.B CRSRFLAG(A6) ;DRAWING TO SCREEN?
|
||
BEQ.S GOHOME ;=>NO, JUST RETURN
|
||
_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-A5 ;RESTORE REGISTERS
|
||
UNLINK PARAMSIZE,'DRAWLINE'
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
|
||
;
|
||
|
||
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
FASTLINE
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; Switch to 32 bit addressing mode
|
||
;
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
move.w d1,-(sp) ;save a register
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.w (sp)+,d1 ;restore d1
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
|
||
MOVE.L alphaMask(A6),D4 ;get alpha mask <6>
|
||
CMP D1,D3 ;IS LINE HORIZONTAL ?
|
||
BNE VLINE ;NO, MUST BE VERTICAL
|
||
BSR HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||
MOVEQ #-1,D6 ;GET ONES IN D6
|
||
LSR.L D0,D6 ;CONVERT TO LEFTMASK
|
||
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL
|
||
EXT.L D2 ;MAKE IT LONG
|
||
LSL.L D3,D2 ;CONVERT PIXELS TO BITS
|
||
MOVEQ #$1F,D0 ;NEED RIGHT MOD 32
|
||
AND.L D2,D0 ;MAKE A COPY OF RIGHT
|
||
MOVEQ #-1,D3 ;GET ONES IN D3
|
||
LSR.L D0,D3 ;SHIFT IN 0'S FOR LEFTMASK
|
||
NOT.L D3 ;CONVERT TO RIGHTMASK
|
||
AND.L D4,D6 ;clip left mask with alpha mask <6>
|
||
AND.L D4,D3 ;clip right mask with alpha mask <6>
|
||
LSR.L #5,D2 ;CONVERT BITS TO LONGS
|
||
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
||
BLT.S HSET ;BR IF FOREGROUND
|
||
BEQ.S HTOGL ;BR IF XOR
|
||
;ELSE BACKGROUND
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; DRAW A HORIZONTAL LINE IN THE BACKGROUND COLOR (NORMALLY WHITE)
|
||
;
|
||
MOVE.L BCOLOR(A6),D5 ;GET THE COLOR
|
||
BRA.S HDRAW
|
||
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; DRAW A HORIZONTAL LINE IN THE FOREGROUND COLOR (NORMALLY BLACK)
|
||
;
|
||
HSET MOVE.L FCOLOR(A6),D5 ;GET THE FOREGROUND COLOR
|
||
HDRAW SUB D1,D2 ;CALC LONG COUNT
|
||
BEQ.S ALLONE ;BR IF ALL IN ONE LONG
|
||
|
||
MOVE.L D5,D1 ;COPY COLOR
|
||
AND.L D6,D1 ;MASK COLOR FOR LEFT EDGE
|
||
NOT.L D6 ;GET NOT LEFTMASK
|
||
AND.L (A4),D6 ;PUNCH HOLE IN DEST
|
||
OR.L D1,D6 ;COMBINE SRC AND DST
|
||
MOVE.L D6,(A4)+ ;AND DROP COLOR IN
|
||
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ.S DOEND ;BR IF NO UNMASKED LONG
|
||
|
||
NOT.L D4 ;reverse alpha mask <6>
|
||
BEQ.S DOONE ;use normal loops if all ones <6>
|
||
;
|
||
; <6> Draw horizontal line using alpha mask
|
||
;
|
||
ALPHALINE
|
||
MOVE.L (A4),D0 ;get long of dst
|
||
EOR.L D5,D0 ;apply color
|
||
AND.L D4,D0 ;mask with alpha mask
|
||
EOR.L D5,D0 ;reapply color
|
||
MOVE.L D0,(A4)+ ;put result to dst
|
||
DBRA D2,ALPHALINE ;do another long
|
||
BRA.S DOEND ;all done
|
||
|
||
DOTWO MOVE.L D5,(A4)+ ;FILL A LONG WITH COLOR
|
||
DOONE MOVE.L D5,(A4)+ ;FILL ANOTHER LONG
|
||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||
DOMORE BGT DOTWO ;YES, AT LEAST TWO LONGS
|
||
BEQ DOONE ;YES, FINISH UP LAST LONG
|
||
DOEND AND.L D3,D5 ;MASK SOURCE FOR RIGHT EDGE
|
||
NOT.L D3 ;GET NOTMASK
|
||
AND.L (A4),D3 ;PUNCH HOLE IN DST DATA
|
||
OR.L D5,D3 ;COMBINE SRC AND DST
|
||
MOVE.L D3,(A4) ;AND DROP COLOR IN
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ALIGN Alignment
|
||
|
||
ALLONE AND.L D3,D6 ;COMBINE LEFT AND RIGHT MASKS
|
||
AND.L D6,D5 ;GET MASKED COLOR
|
||
NOT.L D6 ;GET NOTMASK
|
||
AND.L (A4),D6 ;PUNCH OUT DESTINATION
|
||
OR.L D5,D6 ;COMBINE SRC AND DST
|
||
MOVE.L D6,(A4) ;DRAW LINE
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
;--------------------------------------------------
|
||
;
|
||
; DRAW AN XOR HORIZONTAL LINE
|
||
;
|
||
HTOGL SUB D1,D2 ;CALC LONGCOUNT
|
||
BEQ.S ONETOGL ;BR IF ALL IN ONE LONG
|
||
EOR.L D6,(A4)+ ;DO LEFT LONG WITH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ.S ENDTOGL ;BR IF NO UNMASKED LONGS
|
||
BRA.S TOGLONE ;SEE IF ANY LONGS LEFT TO DO
|
||
TOGLTWO EOR.L D4,(A4)+ ;INVERT A LONG <6>
|
||
TOGLONE EOR.L D4,(A4)+ ;INVERT ANOTHER LONG <6>
|
||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
|
||
BEQ TOGLONE ;YES, FINISH UP LAST LONG
|
||
ENDTOGL EOR.L D3,(A4) ;DRAW LINE
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ONETOGL AND.L D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
||
EOR.L D6,(A4) ;DRAW LINE
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
;-------------------------------------------------------
|
||
;
|
||
; DRAW A ONE PIXEL WIDE VERTICAL LINE.
|
||
;
|
||
VLINE BSR.S HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||
MOVEQ #-1,D2 ;GET ONES IN D2
|
||
LSR.L D0,D2 ;CONVERT TO LEFTMASK (LEFT MOD 32 IN D0)
|
||
MOVE.L D2,D0 ;GET LEFTMASK
|
||
MOVE DSTPIX+PIXELSIZE(A6),D1 ;GET PIXEL SIZE
|
||
LSR.L D1,D0 ;SHIFT BY PIXEL SIZE FOR RIGHT EDGE
|
||
NOT.L D0 ;MAKE IT A RIGHTMASK
|
||
AND.L D0,D2 ;AND RIGHTMASK INTO LEFTMASK
|
||
AND.L D4,D2 ;MASK WITH ALPHA MASK <6>
|
||
MOVE MINRECT+BOTTOM(A6),D1 ;GET BOTTOM
|
||
SUB MINRECT+TOP(A6),D1 ;CALC HEIGHT
|
||
SUB #1,D1 ;INIT HEIGHT COUNT
|
||
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
||
BLT.S VSET ;BR IF FOREGROUND
|
||
BEQ.S VTOGL ;BR IF XOR
|
||
|
||
VCLR MOVE.L BCOLOR(A6),D5 ;GET BACKGROUND COLOR
|
||
BRA.S VDRAW ;=>AND DO LINE
|
||
|
||
VSET MOVE.L FCOLOR(A6),D5 ;GET FOREGROUND COLOR
|
||
VDRAW BEQ.S VAND ;COLOR IS ALL 0's SO JUST AND
|
||
MOVE.L D5,D0 ;COPY COLOR
|
||
NOT.L D0 ;WAS IT ALL 1's?
|
||
BEQ.S VOR ;YES, JUST NEED TO OR
|
||
AND.L D2,D5 ;GET DATA TO WRITE
|
||
NOT.L D2 ;MAKE NOTMASK
|
||
|
||
NXTV MOVE.L D2,D3 ;GET NOTMASK
|
||
AND.L (A4),D3 ;PUNCH A HOLE IN THE DST
|
||
OR.L D5,D3 ;COMBINE SRC AND DST
|
||
MOVE.L D3,(A4) ;AND PUT TO DST
|
||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||
DBRA D1,NXTV ;LOOP ALL DOTS
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ALIGN Alignment
|
||
|
||
VTOGL EOR.L D2,(A4) ;TOGGLE ONE DOT
|
||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||
DBRA D1,VTOGL ;LOOP ALL DOTS
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ALIGN Alignment
|
||
|
||
VOR OR.L D2,(A4) ;TOGGLE ONE DOT
|
||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||
DBRA D1,VOR ;LOOP ALL DOTS
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ALIGN Alignment
|
||
|
||
VAND NOT.L D2 ;MAKE INTO CLEARING MASK
|
||
@AND AND.L D2,(A4) ;TOGGLE ONE DOT
|
||
ADD D7,A4 ;BUMP TO NEXT ROW
|
||
DBRA D1,@AND ;LOOP ALL DOTS
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------------------
|
||
;
|
||
; LOCAL ROUTINE TO SET UP POINTER TO FIRST WORD, BIT INDEX, AND ROWBYTES
|
||
;
|
||
; INPUTS: MINRECT
|
||
; A5: thePort
|
||
;
|
||
; OUTPUTS: D0: LEFT MOD 32 (for getting mask)
|
||
; D1: LEFT DIV 32 (for long position)
|
||
; D3: DSTSHIFT
|
||
; D7: ROWBYTES
|
||
; A4: POINTER TO FIRST WORD
|
||
;
|
||
; CLOBBERS: D0,D1,D7,A0,A4
|
||
;
|
||
HVSETUP MOVE.L DSTPIX+BASEADDR(A6),A4 ;GET BITMAP START
|
||
MOVE MINRECT+TOP(A6),D0 ;GET STARTING VERT
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL
|
||
MOVE DSTPIX+ROWBYTES(A6),D7 ;GET ROWBYTES
|
||
AND #nuRBMask,D7 ;clear off flag bits
|
||
MULS D7,D0 ;MULT TOP BY ROWBYTES; BAL 02Dec88
|
||
ADD.L D0,A4 ;ADD TO BASEADDR
|
||
MOVE MINRECT+LEFT(A6),D0 ;GET STARTING HORIZ
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D0 ;CONVERT TO GLOBAL
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
||
EXT.L D3 ;MAKE IT LONG
|
||
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
||
MOVE.L D0,D1 ;MAKE A COPY
|
||
LSR.L #5,D1 ;CONVERT BITS TO LONGS
|
||
LEA (A4,D1*4),A4 ;add in byte cnt
|
||
AND #$1F,D0 ;TREAT LEFT MOD 32
|
||
RTS
|
||
|
||
ALIGN 4
|
||
|
||
;-------------------------------------------------------
|
||
|
||
SteepBlitTab
|
||
DC.L steepCopy1-SteepBlitTab
|
||
DC.L steepCopy2-SteepBlitTab
|
||
DC.L steepCopy4-SteepBlitTab
|
||
DC.L steepCopy8-SteepBlitTab
|
||
DC.L steepCopy16-SteepBlitTab
|
||
DC.L steepCopy32-SteepBlitTab
|
||
|
||
SteepBlitXorTab
|
||
DC.L steepXor1-SteepBlitTab
|
||
DC.L steepXor2-SteepBlitTab
|
||
DC.L steepXor4-SteepBlitTab
|
||
DC.L steepXor8-SteepBlitTab
|
||
DC.L steepXor16-SteepBlitTab
|
||
DC.L steepXor32-SteepBlitTab
|
||
|
||
;-------------------------------------------------------
|
||
|
||
ShallowBlitTab
|
||
DC.L shallowCopy1-ShallowBlitTab
|
||
DC.L shallowCopy2-ShallowBlitTab
|
||
DC.L shallowCopyN-ShallowBlitTab
|
||
DC.L shallowCopyN-ShallowBlitTab
|
||
DC.L shallowCopyN-ShallowBlitTab
|
||
DC.L done-ShallowBlitTab ;never used
|
||
|
||
ShallowBlitXorTab
|
||
DC.L shallowXor1-ShallowBlitTab
|
||
DC.L shallowXor2-ShallowBlitTab
|
||
DC.L shallowXorN-ShallowBlitTab
|
||
DC.L shallowXorN-ShallowBlitTab
|
||
DC.L shallowXorN-ShallowBlitTab
|
||
DC.L done-ShallowBlitTab ;never used
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; SET UP AND DRAW A FAST SLANTED LINE.
|
||
; Only steep lines are currently implemented: (45°<=ø<=135°)
|
||
;
|
||
; Assumes: D1,D2,D3,D4 = MinRect top,left,bottom,right
|
||
; D7 = slope (16.16)
|
||
|
||
FASTSLANT
|
||
|
||
;------------------------------------------------------------------------
|
||
;
|
||
; SET UP REGISTERS FOR FAST SLANT LOOPS
|
||
;
|
||
; INPUTS: MINRECT, DSTPIX, SLOPE
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 =
|
||
; a1 = d1 = fgColor/bkColor
|
||
; a2 = d2 = dst pixel size (bit width)
|
||
; a3 = rowBytes d3 = dstShift
|
||
; a4 = dstPtr d4 = bit offset to pixel left
|
||
; a5 = d5 = leftEdge (16.16)
|
||
; a6 = locals d6 = scan count (zero based)
|
||
; a7^= d7 = slope (16.16)
|
||
;-------------------------------------------------------
|
||
; includes fix as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
SLANTSETUP
|
||
TST.B alphaMode(A6) ;if alphamode == 0, stay in all cases <6>
|
||
BEQ.S @stay ; <6>
|
||
TST A2 ;leave if shallow and alphamode != 0 <6>
|
||
BEQ goBack ; <6>
|
||
MOVE LOCMODE(A6),D0 ;get the local mode <6>
|
||
ADDQ #1,D0 ;convert from xor=1 to xor=srcXor <6>
|
||
CMP #srcXor,D0 ; <6>
|
||
BNE goBack ;if copying, leave because alphamode != 0
|
||
@stay MOVE.L DSTPIX+BASEADDR(A6),A4 ;GET BITMAP START
|
||
MOVE D1,D0 ;GET STARTING VERT
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL
|
||
MOVE DSTPIX+ROWBYTES(A6),D6 ;GET ROWBYTES
|
||
AND #nuRBMask,D6 ;clear off flag bits
|
||
MULS D6,D0 ;MULT TOP BY ROWBYTES
|
||
MOVE D6,A3 ;REMEMBER ROWBYTES
|
||
ADD.L D0,A4 ;ADD TO BASEADDR
|
||
tst.w a2 ;taller or wider?
|
||
beq Shallow
|
||
SUB D1,D3 ;CALC HEIGHT
|
||
MOVEQ #-1,D6 ;
|
||
ADD D3,D6 ;D6 IS HEIGHT-1
|
||
MOVE.L LEFTEDGE(A6),D5 ;GET LEFTEDGE
|
||
|
||
MOVE.L D5,D2 ;Get LeftEdge.int
|
||
SWAP D2
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL
|
||
EXT.L D2 ;MAKE IT LONG
|
||
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
||
LSL.L D3,D2 ;CONVERT PIXELS TO BITS
|
||
MOVE.L D2,D4 ;MAKE A COPY
|
||
LSR.L #5,D2 ;CONVERT BITS TO LONGS
|
||
LSL.L #2,D2 ;Convert back to bytes
|
||
ADD.L D2,A4 ;ADD TO RUNNING TOTAL
|
||
AND #$1F,D4 ;TREAT LEFT MOD 32
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; Switch to 32 bit addressing mode
|
||
;
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
_rSwapMMUMode ;(can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
|
||
tst.l d7 ;are we going right to left
|
||
bpl.s @toRight ;fractions ok
|
||
neg.w d7 ;make fraction positive
|
||
not.w d5 ;measure distance from right
|
||
;(plus one for boundary cases)
|
||
@toRight
|
||
tst.w d7 ;are we ± 45°?
|
||
bne.s @not45 ;FOR REED:
|
||
not.w d7 ;hack slope and fraction so that
|
||
move.w d7,d5 ;every scanline generates a carry
|
||
@not45
|
||
MOVE DSTPIX+PIXELSIZE(A6),D2 ;GET DST PIXEL SIZE
|
||
MOVE.L FCOLOR(A6),D1 ;ASSUME FOREGROUND COLOR
|
||
moveq #0,d0 ;init zero register for loops
|
||
LEA SteepBlitTab,a0 ;point to mode table
|
||
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
||
BLT.S @useFG ;BR IF FOREGROUND
|
||
BEQ.S @doXor ;BR IF XOR
|
||
;ELSE BACKGROUND
|
||
MOVE.L BCOLOR(A6),D1 ;GET THE COLOR
|
||
@useFG ADD.L (A0,D3*4),A0 ;GET MODECASE
|
||
JMP (A0) ;GO THERE
|
||
|
||
@doXor MOVE.L alphaMask(A6),D1 ;get xoring mask
|
||
ADD.L SteepBlitXorTab-SteepBlitTab(A0,D3*4),A0 ;Adjusted modecase
|
||
JMP (A0) ;GO THERE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; DRAW ONE PIXEL WIDE STEEP SLANTED LINES
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = zero
|
||
; a1 = d1 = fgColor/bkColor/(-1 for xor)
|
||
; a2 = d2 = dst pixel size (bit width)
|
||
; a3 = rowBytes d3 = dstShift
|
||
; a4 = dstPtr d4 = bit offset to pixel left
|
||
; a5 = d5 = leftEdge (16.16)
|
||
; a6 = locals d6 = scan count (zero based)
|
||
; a7^= d7 = slope (16.16)
|
||
;-------------------------------------------------------
|
||
steepCopy1
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfins d1,(a4){d4:d2} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfins d1,(a4){d4:d2} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepCopy2
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfins d1,(a4){d4:2} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2 ;get a one or zero
|
||
add.l d2,d4 ;bump a bit
|
||
add.l d2,d4 ;bump a bit
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfins d1,(a4){d4:2} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2
|
||
sub.l d2,d4 ;bump a bit
|
||
sub.l d2,d4 ;bump a bit
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepCopy4
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfins d1,(a4){d4:4} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2 ;get a one or zero
|
||
lsl.l #2,d2 ;scale up by bit depth
|
||
add.l d2,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfins d1,(a4){d4:4} ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2
|
||
lsl.l #2,d2 ;scale up by bit depth
|
||
sub.l d2,d4 ;bump a pixel
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepCopy8
|
||
lsr.l #3,d4 ;convert bit offset to byte offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
move.b d1,(a4,d4) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
move.b d1,(a4,d4) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepCopy16
|
||
lsr.l #4,d4 ;convert bit offset to word offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
move.w d1,(a4,d4*2) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
move.w d1,(a4,d4*2) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepCopy32
|
||
lsr.l #5,d4 ;convert bit offset to long offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
move.l d1,(a4,d4*4) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
move.l d1,(a4,d4*4) ;blit one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; XOR ONE PIXEL WIDE STEEP SLANTED LINES
|
||
;
|
||
;-------------------------------------------------------
|
||
steepXor1
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfchg (a4){d4:d2} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfchg (a4){d4:d2} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepXor2
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfchg (a4){d4:2} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2 ;get a one or zero
|
||
add.l d2,d4 ;bump a bit
|
||
add.l d2,d4 ;bump a bit
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfchg (a4){d4:2} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2
|
||
sub.l d2,d4 ;bump a bit
|
||
sub.l d2,d4 ;bump a bit
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepXor4
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
bfchg (a4){d4:4} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2 ;get a one or zero
|
||
lsl.l #2,d2 ;scale up by bit depth
|
||
add.l d2,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
bfchg (a4){d4:4} ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d0,d2 ;start with zero
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d2
|
||
lsl.l #2,d2 ;scale up by bit depth
|
||
sub.l d2,d4 ;bump a pixel
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepXor8
|
||
lsr.l #3,d4 ;convert bit offset to byte offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
eor.b d1,(a4,d4) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
eor.b d1,(a4,d4) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepXor16
|
||
lsr.l #4,d4 ;convert bit offset to word offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
eor.w d1,(a4,d4*2) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
eor.w d1,(a4,d4*2) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
steepXor32
|
||
lsr.l #5,d4 ;convert bit offset to long offset
|
||
tst.l d7 ;are we backwards
|
||
bmi.s @toLeft
|
||
|
||
@toRight
|
||
eor.l d1,(a4,d4*4) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
addx.l d0,d4 ;bump a pixel
|
||
dbra d6,@toRight
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft
|
||
eor.l d1,(a4,d4*4) ;toggle one pixel
|
||
add.l a3,a4 ;bump to next row
|
||
add.w d7,d5 ;add fractions
|
||
subx.l d0,d4
|
||
dbra d6,@toLeft
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; DRAW ONE PIXEL WIDE Shallow SLANTED LINES
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = actual slab width
|
||
; a1 = d1 = fgColor/bkColor/(-1 for xor)
|
||
; a2 = |dx/dy| d2 = zero
|
||
; a3 = rowBytes d3 = dstShift
|
||
; a4 = dstPtr d4 = bit offset to pixel left
|
||
; a5 = bits to right d5 = integer slab width
|
||
; a6 = locals d6 = scan count (zero based)
|
||
; a7^= d7 = (high)slope,(low)rightEdge
|
||
;-------------------------------------------------------
|
||
goBack
|
||
; move.w minRect+left(a6),d2 ;restore minRect left
|
||
; move.w minRect+right(a6),d4 ;restore minRect right
|
||
bra CalcBufLeft
|
||
|
||
Shallow
|
||
cmp.w lineRect+top(a6),d1 ;was top clipped?
|
||
bgt.s goBack ;yes, take slow case
|
||
cmp.w lineRect+bottom(a6),d3 ;is bottom clipped?
|
||
blt.s goBack ;yes, take slow case
|
||
SUB D1,D3 ;CALC HEIGHT
|
||
MOVEQ #-2,D6 ;
|
||
ADD D3,D6 ;D6 IS HEIGHT-2
|
||
|
||
move.w d2,d0 ;assume left to right
|
||
tst.l d7 ;dx/dy < 0?
|
||
bpl.s @useLeft ;yes, left to right
|
||
move.w d4,d0 ;no, MinRect.right instead
|
||
@useLeft
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D0 ;CONVERT MinRect.Left TO GLOBAL
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
||
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
||
MOVE.L D0,D1 ;MAKE A COPY
|
||
LSR.L #5,D0 ;CONVERT BITS TO LONGS
|
||
LSL.L #2,D0 ;Convert back to bytes
|
||
ADD.L D0,A4 ;ADD TO RUNNING TOTAL
|
||
AND #$1F,D1 ;TREAT LEFT MOD 32
|
||
|
||
move.l d7,d5 ;copy slope
|
||
bpl.s @notNeg
|
||
neg.l d5 ;get |slope|
|
||
@notNeg move.l d5,a2 ;copy |slope| for later
|
||
cmp.l #$10800,d5 ;is it nearly 45°?
|
||
blt.s goBack ;yes, can't be as inaccurate as before
|
||
clr.w d5
|
||
swap d5 ;|slope|.int
|
||
lsl.l d3,d5 ;|slope|.int * pixelSize
|
||
cmp.w #32,d5 ;does max slab fit in a long?
|
||
bge.s goBack ;no, punt for now
|
||
|
||
SUB D2,D4 ;get pixel width
|
||
move.w rightEdge+2(a6),d7 ;get rightEdge.frac
|
||
LSL.L D3,D4 ;CONVERT PIXELS TO BITS
|
||
ADD D1,D4 ;D4 is bit offset to rightedge of last slab
|
||
MOVE.W D4,A5 ;save for later
|
||
MOVE.L D1,D4 ;save initial bit offset
|
||
tst.l d7 ;right to left?
|
||
bpl.s @widthOK
|
||
SUB D1,A5 ;undo the damage
|
||
SUB D1,A5 ;do it right
|
||
|
||
@widthOK
|
||
;
|
||
; Switch to 32 bit addressing mode
|
||
;
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
_rSwapMMUMode ;(can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
|
||
moveq #0,d0 ;compute first (clipped) slab width in d0
|
||
move.w minrect+right(a6),d0 ;get right clip
|
||
sub.w leftEdge(a6),d0 ;get initial slab width
|
||
tst.l d7 ;right to left?
|
||
bmi.s @yesNeg ;yes, all ok
|
||
move.w rightEdge(a6),d0 ;get rightEdge.int
|
||
sub.w minrect+left(a6),d0 ;get initial slab width
|
||
@yesNeg LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
||
moveq #0,d2 ;get a useful constant
|
||
MOVE.L FCOLOR(A6),D1 ;ASSUME FOREGROUND COLOR
|
||
LEA ShallowBlitTab,a0 ;point to mode table
|
||
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
||
BLT.S @useFG ;BR IF FOREGROUND
|
||
BEQ.S @doXor ;BR IF XOR
|
||
;ELSE BACKGROUND
|
||
MOVE.L BCOLOR(A6),D1 ;GET THE COLOR
|
||
@useFG ADD.L (A0,D3*4),A0 ;GET MODECASE
|
||
JMP (A0) ;GO THERE
|
||
|
||
@doXor ;Use alternate table
|
||
ADD.L ShallowBlitXorTab-ShallowBlitTab(A0,D3*4),A0 ;Adjusted modecase
|
||
JMP (A0) ;GO THERE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowCopy1 ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.w d5,d0 ;prime slab width with slope.int
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add one
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.w d5,d0 ;prime slab width with slope.int
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add one
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowCopy2 ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
add.l d0,d0 ;double it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
add.l d0,d0 ;double it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowCopyN ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
lsl.l d3,d0 ;quad it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
lsl.l d3,d0 ;quad it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfins d1,(a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowXor1 ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.w d5,d0 ;prime slab width with slope.int
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add one
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.w d5,d0 ;prime slab width with slope.int
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add one
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowXor2 ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
add.l d0,d0 ;double it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
add.l d0,d0 ;double it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
|
||
shallowXorN ;start with first clipped slab
|
||
tst.l d7 ;slope negative?
|
||
bmi.s @toLeft ;draw from right to left
|
||
|
||
@midR bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
add.l d0,d4 ;bump offset by slab width
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
lsl.l d3,d0 ;quad it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midR
|
||
sub d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
ALIGN Alignment
|
||
|
||
@toLeft ;start with first clipped slab
|
||
@midL sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit a slab
|
||
add.l a3,a4 ;bump to next row
|
||
move.l d2,d0 ;zero working register
|
||
add.w a2,d7 ;add fractions
|
||
addx.l d2,d0 ;conditionally add 1
|
||
lsl.l d3,d0 ;quad it
|
||
add.l d5,d0 ;add in base slab width (slope.int)
|
||
dbra d6,@midL
|
||
add d4,a5 ;compute width of last slab
|
||
move a5,d0
|
||
sub.l d0,d4 ;bump offset by slab width
|
||
bfchg (a4){d4:d0} ;blit last slab
|
||
bra done
|
||
|
||
;-------------------------------------------------------
|
||
|
||
ENDPROC
|
||
|
||
|