QuickDraw/SeekRgn.a

193 lines
7.7 KiB
Plaintext
Executable File

.INCLUDE GRAFTYPES.TEXT
;------------------------------------------------------------------
;
; --> SEEKRGN.TEXT
;
; Routines to play back a region into a scanline buffer.
;
;
.PROC INITRGN,0
;------------------------------------------------------
;
; INPUTS: A0: RGNPTR
; A1: STATE RECORD
; D0: MINH
; D1: MAXH
; D2: BUFLEFT
;
; OUTPUTS: ALL FIELDS OF STATE RECORD,
; SCANBUF ALLOCATED ON STACK
;
; CLOBBERS: D0,D1,A0
;
MOVE D0,MINH(A1) ;INSTALL MINH
MOVE D1,MAXH(A1) ;INSTALL MAXH
MOVE D2,LEFTH(A1) ;INSTALL LEFTH
MOVE.L A0,RGNPTR(A1) ;INSTALL RGNPTR
MOVE #-32767,THISV(A1) ;THISV := -32767
MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := RGN BBOX TOP
LEA RGNDATA(A0),A0 ;POINT TO FIRST DATA
MOVE.L A0,DATAPTR(A1) ;INIT DATAPTR
MOVE.L (SP)+,A0 ;POP RETURN ADDR
SUB D2,D1 ;CALC BUFFER WIDTH IN DOTS
LSR #5,D1 ;DIV BY 32 FOR #LONGS-1
MOVE D1,SCANSIZE(A1) ;SAVE SCANSIZE FOR LATER
CLRLOOP CLR.L -(SP) ;ALLOCATE AND CLEAR BUFFER
DBRA D1,CLRLOOP
MOVE.L SP,SCANBUF(A1) ;REMEMBER BUFFER START
JMP (A0) ;RETURN
.PROC SEEKRGN,0
.REF MaskTab
;------------------------------------------------------------------
;
; SeekRgn(rgnState,vert);
;
; ROUTINE TO PLAY BACK A REGION FORWARD OR BACKWARD UNTIL ITS SCAN
; BUFFER CONTAINS THE BITMAP FOR THE GIVEN VERTICAL COORDINATE.
;
; INPUTS: A1 POINTS TO A REGION STATE RECORD
; DO CONTAINS THE DESIRED VERTICAL COORD
;
; OUTPUTS: UPDATES THISV, NEXTV, DATAPTR, AND SCANBUF^ OF STATE RECORD
; D1-->1 IF CHANGE, 0 IF NO CHANGE. (Z-FLAG SET IF NO CHANGE)
;
; CLOBBERS: A0,D1.
;
;----------------------------------------------------
;
; RETURN QUICKLY IF SCANBUF IS ALREADY CURRENT.
;
CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ?
BGE.S DOWN ;YES, BUMP DOWNWARD
CMP THISV(A1),D0 ;IS DESIRED VERT < CURRENT VERT ?
BLT.S UP ;YES, BUMP UPWARD
CLR D1 ;ELSE REPORT NO CHANGES
RTS ;AND RETURN
;-----------------------------------------------------
;
; TO MOVE UPWARDS, JUST RESET TO START AND MOVE DOWN.
;
UP MOVE.L SCANBUF(A1),A0 ;POINT TO SCANBUF
MOVE SCANSIZE(A1),D1 ;GET BUFFER SIZE
CLRLP CLR.L (A0)+ ;CLEAR A LONG
DBRA D1,CLRLP ;LOOP ENTIRE SCANBUF
MOVE.L RGNPTR(A1),A0 ;GET RGNPTR
MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := TOP VERT
MOVE #-32767,THISV(A1) ;RESET THISV TO -32767
LEA RGNDATA(A0),A0 ;POINT TO START OF REGION DATA
MOVE.L A0,DATAPTR(A1) ;RESET DATAPTR
CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ?
BLT DONE ;NO, QUIT
;------------------------------------------------------
;
; WHILE DESIRED VERT >= NEXTV DO BUMP DOWN.
;
DOWN MOVEM.L D0-D6/A2-A3,-(SP) ;SAVE REGS
MOVE D0,D2 ;SAVE VERT
MOVE.L DATAPTR(A1),A2 ;POINT TO VERT COORD
DOWN1 MOVE (A2)+,THISV(A1) ;UPDATE CURRENT VERT
;-------------------------------------------------
;
; GET LEFT AND RIGHT HORIZ COORDS
; AND TRIM AGAINST MINH AND MAXH
;
NEXTHOR MOVE (A2)+,D3 ;GET LEFT COORD
CMP #32767,D3 ;IS IT A TERMINATOR ?
BEQ.S DONE1 ;YES, QUIT
MOVE (A2)+,D4 ;GET RIGHT COORD
CMP MINH(A1),D4 ;IS RIGHT <= MINH ?
BLE NEXTHOR ;YES, IGNORE ON LEFT
CMP MAXH(A1),D3 ;IS LEFT >= MAXH ?
BGE NEXTHOR ;YES, IGNORE ON RIGHT
CMP MINH(A1),D3 ;IS LEFT < MINH ?
BGE.S LOK ;NO, CONTINUE
MOVE MINH(A1),D3 ;YES, TRIM LEFT
LOK CMP MAXH(A1),D4 ;IS RIGHT > MAXH ?
BLE.S ROK ;NO, CONTINUE
MOVE MAXH(A1),D4 ;YES, TRIM RIGHT
ROK SUB LEFTH(A1),D3 ;MAKE COORDS REL TO BUFFER
SUB LEFTH(A1),D4
;------------------------------------------
;
; GET LEFTMASK AND RIGHTMASK
;
LEA MASKTAB,A0 ;POINT TO MASK TABLE
MOVEQ #$F,D0 ;GET MASK FOR LO 4 BITS
MOVE D3,D5 ;COPY LEFT COORD
AND D0,D5 ;CALC LEFT MOD 16
ADD D5,D5 ;DOUBLE FOR INDEX
MOVE 0(A0,D5),D5 ;GET MASK FROM TABLE
NOT D5 ;INVERT FOR LEFTMASK
MOVE D4,D6 ;COPY RIGHT COORD
AND D0,D6 ;CALC RIGHT MOD 16
ADD D6,D6 ;DOUBLE FOR INDEX
MOVE 0(A0,D6),D6 ;GET RIGHTMASK IN D6
;------------------------------------------
;
; CALC LEFTWORD, BUFPTR, WORDCOUNT
;
LSR #4,D3 ;CONVERT DOTS TO WORDS
MOVE.L SCANBUF(A1),A3 ;COPY BUFSTART
ADD D3,A3
ADD D3,A3 ;INIT BUFPTR TO LEFTWORD
LSR #4,D4 ;CALC RIGHT DIV 16
SUB D3,D4 ;WORDCOUNT:=RIGHTWORD-LEFTWORD
BGT.S NOTIN1 ;BR IF NOT ALL IN ONE
;------------------------------------------
;
; LEFT AND RIGHT ARE ALL IN ONE WORD
;
AND D5,D6 ;COMBINE LEFT AND RIGHT MASKS
EOR D6,(A3) ;XOR COMBINATION INTO BUFFER
BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN
;------------------------------------------
;
; NOT ALL IN ONE WORD. DO LEFT, MIDDLE IF ANY, THEN RIGHT
;
NOTIN1 EOR D5,(A3)+ ;XOR LEFTMASK INTO BUFFER
BRA.S TEST ;SEE IF ANY FULL WORDS
INVLONG NOT.L (A3)+ ;INVERT 2 WHOLE WORDS
TEST SUBQ #2,D4 ;ANY FULL WORDS LEFT ?
BGT INVLONG ;YES, AT LEAST 2
BLT.S ENDWORD ;NO, FINISH UP LAST WITH MASK
NOT (A3)+ ;YES, DO LAST FULL WORD
ENDWORD EOR D6,(A3) ;XOR RIGHTMASK INTO BUFFER
BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN
DONE1 MOVE.L A2,DATAPTR(A1) ;UPDATE DATAPTR
MOVE (A2),NEXTV(A1) ;UPDATE NEXT VERT
CMP NEXTV(A1),D2 ;IS DESIRED VERT >= NEXTV ?
BGE DOWN1 ;YES, BUMP DOWN SOME MORE
MOVEM.L (SP)+,D0-D6/A2-A3 ;RESTORE REGS
DONE MOVEQ #1,D1 ;REPORT SCANLINE CHANGED
RTS ;AND RETURN
.END