├── Angles.a ├── Arcs.a ├── BitBlt.a ├── Bitmaps.a ├── COPYRIGHT.TXT ├── DrawArc.a ├── DrawLine.a ├── DrawText.a ├── FixMove.p ├── Graf3D.p ├── GrafAsm.a ├── GrafTypes.a ├── GrafUtil.p ├── LCursor.a ├── Lines.a ├── Ovals.a ├── PackRgn.a ├── PicFormat.txt ├── Pictures.a ├── Polygons.a ├── PutLine.a ├── PutOval.a ├── PutRgn.a ├── QDPatch.a ├── QuickDraw.p ├── QuickDraw2.p ├── QuickGlue.a ├── README.md ├── RRects.a ├── Rects.a ├── Regions.a ├── RgnBlt.a ├── RgnOp.a ├── SeekRgn.a ├── SortPoints.a ├── Stretch.a ├── TestGraf.p ├── Text.a └── Util.a /Angles.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GrafTypes.text 2 | 3 | .FUNC AngleFromSlope,1 4 | .DEF SlopeFromAngle 5 | ;----------------------------------------------------- 6 | ; 7 | ; FUNCTION AngleFromSlope(slope: Fixed): INTEGER; 8 | ; 9 | ; Scans slope table for angle and returns angle 0..180 10 | ; 11 | MOVE.L 4(SP),D0 ;GET SLOPE 12 | SMI D2 ;REMEMBER IF IT WAS NEGATIVE 13 | BPL.S NOTNEG ;CONTINUE IF POSITIVE 14 | NEG.L D0 ;ELSE MAKE SLOPE POS 15 | NOTNEG SUB.L #500,D0 ;BIAS THE COMPARE 16 | MOVE.L D0,4(SP) 17 | LEA CONTINUE,A0 ;POINT TO TABLE OF SLOPES 18 | MOVEQ #-1,D1 ;INIT ANGLE COUNT 19 | SCAN ADD.W #1,D1 20 | MOVE.W D1,D0 21 | CLR.L -(SP) 22 | BRA.S A2SLOPE 23 | CONTINUE 24 | MOVE.L 8(SP),D0 ;GET SLOPE 25 | CMP.L (SP)+,D0 ;SCAN THRU SLOPE TABLE 26 | BGT.S SCAN 27 | MOVE #180,D0 28 | SUB D1,D0 ;CALC 180-ANGLE = 90..180 29 | TST.B D2 ;WAS DH POS ? 30 | BPL.S DONE ;NO, RETURN 90..180 31 | MOVE D1,D0 ;YES, RETURN 0..90 32 | DONE MOVE.L (SP)+,(SP) ;STRIP PARAM 33 | MOVE.W D0,4(SP) ;RETURN FUNCTION RESULT 34 | RTS 35 | 36 | 37 | 38 | ;---------------------------------------------------------------- 39 | ; 40 | ; FUNCTION SlopeFromAngle(angle: INTEGER): Fixed; 41 | ; 42 | ; calculate the fixed point slope of a line, DH/DV = -65536 * Tan(angle). 43 | ; Input angle is treated MOD 180. 44 | ; 45 | SlopeFromAngle 46 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 47 | MOVE (SP)+,D0 ;GET INTEGER ANGLE 48 | EXT.L D0 ;SIGN EXTEND FOR DIVIDE 49 | DIVS #180,D0 ;TREAT ANGLE MOD 180 50 | SWAP D0 ;GET THE REMAINDER 51 | TST D0 ;WAS IT NEGATIVE ? 52 | BPL.S OK1 ;NO, CONTINUE 53 | ADD #180,D0 ;YES, PUT IN RANGE 0..179 54 | OK1 MOVE #$8000,(SP) 55 | A2SLOPE CMP #90,D0 56 | BLE.S OK2 57 | CLR.W (SP) 58 | SUB #180,D0 59 | NEG D0 60 | OK2 CMP #45,D0 61 | BLT.S SHARE 62 | ADD #1,(SP) 63 | CMP #64,D0 64 | BLT.S SHARE 65 | MOVE.B SLOPE-91(D0),1(SP) 66 | BPL.S SHARE 67 | OR.B #$7F,(SP) 68 | SHARE ADD D0,D0 69 | MOVE.W SLOPE(D0),2(SP) 70 | CHECK BCLR #7,(SP) 71 | BEQ.S OK3 72 | NEG.L (SP) 73 | OK3 JMP (A0) 74 | 75 | 76 | 77 | ; .BYTE $01 ;45 78 | ; .BYTE $01 79 | ; .BYTE $01 80 | ; .BYTE $01 81 | ; .BYTE $01 82 | ; .BYTE $01 ;50 83 | ; .BYTE $01 84 | ; .BYTE $01 85 | ; .BYTE $01 86 | ; .BYTE $01 87 | ; .BYTE $01 ;55 88 | ; .BYTE $01 89 | ; .BYTE $01 90 | ; .BYTE $01 91 | ; .BYTE $01 92 | ; .BYTE $01 ;60 93 | ; .BYTE $01 94 | ; .BYTE $01 95 | .BYTE $01 96 | .BYTE $02 97 | .BYTE $02 ;65 98 | .BYTE $02 99 | .BYTE $02 100 | .BYTE $02 101 | .BYTE $02 102 | .BYTE $02 ;70 103 | .BYTE $02 104 | .BYTE $03 105 | .BYTE $03 106 | .BYTE $03 107 | .BYTE $03 ;75 108 | .BYTE $04 109 | .BYTE $04 110 | .BYTE $04 111 | .BYTE $05 112 | .BYTE $05 ;80 113 | .BYTE $06 114 | .BYTE $07 115 | .BYTE $08 116 | .BYTE $09 117 | .BYTE $0B ;85 118 | .BYTE $0E 119 | .BYTE $13 120 | .BYTE $1C 121 | .BYTE $39 122 | .BYTE $FF ;90 123 | SLOPE 124 | .WORD $0000 ;0 125 | .WORD $0478 126 | .WORD $08F1 127 | .WORD $0D6B 128 | .WORD $11E7 129 | .WORD $1666 ;5 130 | .WORD $1AE8 131 | .WORD $1F6F 132 | .WORD $23FA 133 | .WORD $288C 134 | .WORD $2D24 ;10 135 | .WORD $31C3 136 | .WORD $366A 137 | .WORD $3B1A 138 | .WORD $3FD4 139 | .WORD $4498 ;15 140 | .WORD $4968 141 | .WORD $4E44 142 | .WORD $532E 143 | .WORD $5826 144 | .WORD $5D2D ;20 145 | .WORD $6245 146 | .WORD $676E 147 | .WORD $6CAA 148 | .WORD $71FB 149 | .WORD $7760 ;25 150 | .WORD $7CDC 151 | .WORD $8270 152 | .WORD $881E 153 | .WORD $8DE7 154 | .WORD $93CD ;30 155 | .WORD $99D2 156 | .WORD $9FF7 157 | .WORD $A640 158 | .WORD $ACAD 159 | .WORD $B341 ;35 160 | .WORD $B9FF 161 | .WORD $C0E9 162 | .WORD $C802 163 | .WORD $CF4E 164 | .WORD $D6CF ;40 165 | .WORD $DE8A 166 | .WORD $E681 167 | .WORD $EEB9 168 | .WORD $F737 169 | .WORD $0000 ;45 170 | .WORD $0919 171 | .WORD $1287 172 | .WORD $1C51 173 | .WORD $267F 174 | .WORD $3117 ;50 175 | .WORD $3C22 176 | .WORD $47AA 177 | .WORD $53B9 178 | .WORD $605B 179 | .WORD $6D9B ;55 180 | .WORD $7B89 181 | .WORD $8A35 182 | .WORD $99AF 183 | .WORD $AA0E 184 | .WORD $BB68 ;60 185 | .WORD $CDD6 186 | .WORD $E177 187 | .WORD $F66E 188 | .WORD $0CE1 189 | .WORD $24FE ;65 190 | .WORD $3EFC 191 | .WORD $5B19 192 | .WORD $799F 193 | .WORD $9AE7 194 | .WORD $BF5B ;70 195 | .WORD $E77A 196 | .WORD $13E3 197 | .WORD $4556 198 | .WORD $7CC7 199 | .WORD $BB68 ;75 200 | .WORD $02C2 201 | .WORD $54DB 202 | .WORD $B462 203 | .WORD $2501 204 | .WORD $ABD9 ;80 205 | .WORD $5051 206 | .WORD $1D88 207 | .WORD $24F3 208 | .WORD $83AD 209 | .WORD $6E17 ;85 210 | .WORD $4CF5 211 | .WORD $14BD 212 | .WORD $A2D7 213 | .WORD $4A30 214 | .WORD $FFFF ;90 215 | 216 | 217 | .PROC PtToAngle,3 218 | .REF AngleFromSlope 219 | ;-------------------------------------------------------------- 220 | ; 221 | ; PROCEDURE PtToAngle(r: Rect; pt: Point; VAR angle: INTEGER); 222 | ; 223 | ; Given a rectangle and a point, return the angle subtended by pt. 224 | ; 225 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 226 | ; 227 | PARAMSIZE .EQU 12 ;TOTAL BYTES OF PARAMS 228 | RECT .EQU PARAMSIZE+8-4 ;ADDR OF RECT 229 | PT .EQU RECT-4 ;POINT 230 | ANGLE .EQU PT-4 ;ADDR OF INTEGER; 231 | 232 | LINK A6,#0 ;NO LOCALS 233 | MOVEM.L D6-D7/A4,-(SP) ;SAVE REGS 234 | MOVE.L RECT(A6),A4 ;POINT TO RECT 235 | 236 | MOVE BOTTOM(A4),D0 237 | ADD TOP(A4),D0 238 | ASR #1,D0 ;CENTER.V := (TOP+BOTTOM)/2 239 | MOVE PT+V(A6),D1 240 | SUB D0,D1 ;DV := PT.V - CENTER.V 241 | 242 | MOVE RIGHT(A4),D0 243 | ADD LEFT(A4),D0 244 | ASR #1,D0 ;CENTER.H := (LEFT+RIGHT)/2 245 | MOVE PT+H(A6),D7 246 | SUB D0,D7 ;DH := PT.H - CENTER.H 247 | BNE.S DHOK ;CONTINUE IF DH <> 0 248 | TST D1 ;WAS DV > 0 ? 249 | BLE.S ZERO ;NO, RETURN ANGLE = 0 250 | MOVE #180,D0 ;YES, RETURN ANGLE = 180 251 | BRA.S DONE 252 | 253 | DHOK CLR.L -(SP) ;ROOM FOR FCN RESULT 254 | MOVE D7,-(SP) ;PUSH DH 255 | MOVE D1,-(SP) ;PUSH DV 256 | _FixRatio ;CALC SLOPE := DH/DV 257 | MOVE.L (SP)+,D6 ;GET SLOPE RESULT 258 | 259 | CLR.L -(SP) ;ROOM FOR FCN RESULT 260 | MOVE BOTTOM(A4),D0 261 | SUB TOP(A4),D0 262 | MOVE D0,-(SP) ;PUSH HEIGHT 263 | MOVE RIGHT(A4),D0 264 | SUB LEFT(A4),D0 265 | MOVE D0,-(SP) ;PUSH WIDTH 266 | _FixRatio ;CALC ASPECT := HT/WD 267 | MOVE.L (SP)+,D0 ;GET ASPECT RESULT 268 | 269 | CLR.L -(SP) ;ROOM FOR FCN RESULT 270 | MOVE.L D6,-(SP) ;PUSH SLOPE 271 | MOVE.L D0,-(SP) ;PUSH ASPECT 272 | _FixMul ;CALC SLOPE*ASPECT 273 | MOVE.L (SP)+,D0 ;GET RESULT SLOPE2 274 | 275 | CLR.W -(SP) ;ROOM FOR FCN RESULT 276 | MOVE.L D0,-(SP) ;PUSH SLOPE2 277 | JSR AngleFromSlope ;SCAN FOR ARCTAN 278 | MOVE (SP)+,D0 ;GET RESULT ANGLE 279 | 280 | TST D7 ;WAS DH POSITIVE ? 281 | BPL.S DONE ;YES, CONTINUE 282 | ADD #180,D0 ;NO, ADD 180 TO ANG 283 | CMP #360,D0 ;IS RESULT = 360 ? 284 | BNE.S DONE ;NO, CONTINUE 285 | ZERO CLR D0 ;YES, ANGLE := 0 286 | DONE MOVE.L ANGLE(A6),A0 ;GET VAR ADDR 287 | MOVE D0,(A0) ;STORE INTO ANGLE 288 | MOVEM.L (SP)+,D6-D7/A4 ;RESTORE REGS 289 | UNLINK PARAMSIZE,'PTTOANGL' 290 | 291 | 292 | 293 | .END 294 | -------------------------------------------------------------------------------- /Arcs.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;----------------------------------------------------------- 3 | ; 4 | ; 5 | ; * ***** *** *** 6 | ; * * * * * * * * 7 | ; * * * * * * 8 | ; * * ***** * *** 9 | ; ***** * * * * 10 | ; * * * * * * * * 11 | ; * * * * *** *** 12 | ; 13 | ; Procedures for drawing Arcs: 14 | ; 15 | 16 | 17 | .PROC StdArc,4 18 | .REF CheckPic,PutPicVerb,PutPicWord,PutPicRect 19 | .REF PushVerb,DrawArc 20 | ;--------------------------------------------------------------- 21 | ; 22 | ; PROCEDURE StdArc(verb: GrafVerb; r: Rect; startAngle,arcAngle: INTEGER); 23 | ; 24 | ; A6 OFFSETS OF PARAMS AFTER LINK: 25 | ; 26 | PARAMSIZE .EQU 10 27 | VERB .EQU PARAMSIZE+8-2 ;GRAFVERB 28 | RECT .EQU VERB-4 ;LONG, ADDR OF RECT 29 | STARTANG .EQU RECT-2 ;WORD 30 | ARCANG .EQU STARTANG-2 ;WORD 31 | 32 | OVWD .EQU -2 ;WORD 33 | OVHT .EQU OVWD-2 ;WORD 34 | VARSIZE .EQU OVHT ;TOTAL BYTES OF LOCALS 35 | 36 | 37 | LINK A6,#VARSIZE ;ALLOCATE STACK FRAME 38 | MOVEM.L D4/D7/A3-A4,-(SP) ;SAVE REGS 39 | MOVE.B VERB(A6),D7 ;GET VERB 40 | JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE 41 | BLE.S NOTPIC ;BRANCH IF NOT PICSAVE 42 | 43 | MOVE.B D7,-(SP) 44 | JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC 45 | MOVEQ #$60,D0 ;PUT ARCNOUN IN HI NIBBLE 46 | ADD D7,D0 ;PUT VERB IN LO NIBBLE 47 | MOVE.B D0,-(SP) ;PUSH OPCODE 48 | MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT 49 | JSR PutPicRect ;PUT OPCODE AND RECTANGLE 50 | MOVE STARTANG(A6),-(SP) 51 | JSR PutPicWord ;PUT STARTANGLE 52 | MOVE ARCANG(A6),-(SP) 53 | JSR PutPicWord ;PUT ARCANGLE 54 | 55 | NOTPIC MOVE.L RECT(A6),A0 ;POINT TO RECT 56 | MOVE RIGHT(A0),D0 57 | SUB LEFT(A0),D0 58 | MOVE D0,OVWD(A6) ;OVWD := R.RIGHT - R.LEFT 59 | MOVE BOTTOM(A0),D0 60 | SUB TOP(A0),D0 61 | MOVE D0,OVHT(A6) ;OVHT := R.BOTTOM - R.TOP 62 | 63 | MOVE.L A0,-(SP) ;PUSH ADDR OF RECT 64 | CLR.B -(SP) ;PUSH HOLLOW = FALSE 65 | TST.B D7 ;IS VERB FRAME ? 66 | BNE.S DOIT ;NO, CONTINUE 67 | ; 68 | ; Currently, FrameArc does not put inversion points to theRgn. 69 | ; If this changes, add test and call to PutArc here. 70 | ; 71 | MOVE.B #1,(SP) ;REPLACE, PUSH HOLLOW = TRUE 72 | DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT 73 | JSR PushVerb ;PUSH MODE AND PATTERN 74 | MOVE STARTANG(A6),-(SP) ;PUSH STARTANGLE 75 | MOVE ARCANG(A6),-(SP) ;PUSH ARCANGLE 76 | 77 | ; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng); 78 | 79 | JSR DrawArc 80 | MOVEM.L (SP)+,D4/D7/A3-A4 ;RESTORE REGS 81 | UNLINK PARAMSIZE,'STDARC ' 82 | 83 | 84 | 85 | .PROC FrameArc,3 86 | .DEF CallArc,PaintArc,EraseArc,InvertArc,FillArc 87 | .REF STDARC 88 | ;----------------------------------------------------- 89 | ; 90 | ; PROCEDURE FrameArc(* r: Rect; startAngle,arcAngle: INTEGER *); 91 | ; 92 | MOVEQ #FRAME,D0 ;VERB = FRAME 93 | BRA.S CallArc ;SHARE COMMON CODE 94 | 95 | 96 | ;----------------------------------------------------- 97 | ; 98 | ; PROCEDURE PaintArc(* r: Rect; startAngle,arcAngle: INTEGER *); 99 | ; 100 | PaintArc 101 | MOVEQ #PAINT,D0 ;VERB = PAINT 102 | BRA.S CallArc ;SHARE COMMON CODE 103 | 104 | 105 | ;-------------------------------------------------------- 106 | ; 107 | ; PROCEDURE EraseArc(* r: Rect; startAngle,arcAngle: INTEGER *); 108 | ; 109 | EraseArc 110 | MOVEQ #ERASE,D0 ;VERB = ERASE 111 | BRA.S CallArc ;SHARE COMMON CODE 112 | 113 | 114 | ;-------------------------------------------------------- 115 | ; 116 | ; PROCEDURE InvertArc(* r: Rect; startAngle,arcAngle: INTEGER *); 117 | ; 118 | InvertArc 119 | MOVEQ #INVERT,D0 ;VERB = INVERT 120 | BRA.S CallArc ;SHARE COMMON CODE 121 | 122 | 123 | ;-------------------------------------------------------- 124 | ; 125 | ; PROCEDURE FillArc(* r: Rect; startAngle,arcAngle: INTEGER; pat: Pattern *); 126 | ; 127 | FillArc MOVE.L (SP)+,A0 ;POP RETURN ADDR 128 | MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN 129 | MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK 130 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 131 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 132 | LEA FILLPAT(A0),A0 ;POINT TO FILLPAT 133 | MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT 134 | MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES 135 | MOVEQ #FILL,D0 ;VERB = FILL 136 | BRA.S CallArc ;SHARE COMMON CODE 137 | 138 | 139 | ;--------------------------------------------------------------- 140 | ; 141 | ; PROCEDURE CallArc(r: Rect; startAngle,arcAngle: INTEGER); 142 | ; 143 | ; code shared by FrameArc, PaintArc, EraseArc, InvertArc, and FillArc. 144 | ; enter with verb in D0. 145 | ; 146 | CallArc MOVE.L (SP)+,A0 ;POP RETURN ADDR 147 | MOVE.L (SP)+,D1 ;POP BOTH ANGLES 148 | MOVE.L (SP)+,A1 ;POP ADDR OF RECT 149 | MOVE.B D0,-(SP) ;PUSH VERB 150 | MOVE.L A1,-(SP) ;PUSH ADDR OF RECT 151 | MOVE.L D1,-(SP) ;PUSH BOTH ANGLES 152 | MOVE.L A0,-(SP) ;PUSH RETURN ADDR 153 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 154 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 155 | MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ? 156 | LEA STDARC,A0 157 | BEQ.S USESTD ;YES, USE STD PROC 158 | MOVE.L D0,A0 159 | MOVE.L ARCPROC(A0),A0 ;NO, GET PROC PTR 160 | USESTD JMP (A0) ;GO TO IT 161 | 162 | 163 | 164 | .END 165 | -------------------------------------------------------------------------------- /COPYRIGHT.TXT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrk/QuickDraw/6377ec5d89735a11b3f6e1ae728f555936c7583f/COPYRIGHT.TXT -------------------------------------------------------------------------------- /FixMove.p: -------------------------------------------------------------------------------- 1 | PROGRAM FixMove; 2 | 3 | { Assembler restrictions require procedure Move to assembled as MQVE. } 4 | { This program back patches the object file replacing 'MQVE' with 'MOVE' } 5 | 6 | VAR f: FILE; 7 | fileName: String[30]; 8 | buffer: PACKED ARRAY[0..1023] OF CHAR; 9 | i,hitCount: INTEGER; 10 | 11 | BEGIN 12 | 13 | REPEAT 14 | WRITE('file to patch:'); 15 | READLN(fileName); 16 | RESET(f,fileName); 17 | UNTIL IORESULT = 0; 18 | 19 | i := BlockRead(f,buffer,2,0); 20 | 21 | hitCount := 0; 22 | FOR i := 0 TO 1020 DO 23 | BEGIN 24 | IF (buffer[i ] = 'M') 25 | AND (buffer[i+1] = 'Q') 26 | AND (buffer[i+2] = 'V') 27 | AND (buffer[i+3] = 'E') 28 | THEN 29 | BEGIN 30 | buffer[i+1] := 'O'; 31 | hitCount := hitCount + 1; 32 | END; 33 | END; 34 | 35 | WRITE(hitCount:1,' matches found.'); 36 | IF hitCount = 0 THEN WRITELN(CHR(7)) 37 | ELSE 38 | BEGIN 39 | i := BlockWrite(f,buffer,2,0); 40 | IF IORESULT <> 0 THEN WRITELN('Oops, trouble writing'); 41 | END; 42 | 43 | CLOSE(f,lock); 44 | 45 | END. 46 | -------------------------------------------------------------------------------- /Graf3D.p: -------------------------------------------------------------------------------- 1 | {$S Graf } 2 | 3 | UNIT Graf3D; 4 | 5 | { three-dimensional graphics routines layered on top of QuickDraw } 6 | 7 | INTERFACE 8 | 9 | USES {$U obj:QuickDraw } QuickDraw; 10 | 11 | CONST radConst=57.29578; 12 | 13 | TYPE Point3D=RECORD 14 | x: REAL; 15 | y: REAL; 16 | z: REAL; 17 | END; 18 | 19 | Point2D=RECORD 20 | x: REAL; 21 | y: REAL; 22 | END; 23 | 24 | XfMatrix = ARRAY[0..3,0..3] OF REAL; 25 | Port3DPtr = ^Port3D; 26 | Port3D = RECORD 27 | GPort: GrafPtr; 28 | viewRect: Rect; 29 | xLeft,yTop,xRight,yBottom: REAL; 30 | pen,penPrime,eye: Point3D; 31 | hSize,vSize: REAL; 32 | hCenter,vCenter: REAL; 33 | xCotan,yCotan: REAL; 34 | ident: BOOLEAN; 35 | xForm: XfMatrix; 36 | END; 37 | 38 | 39 | VAR thePort3D: Port3DPtr; 40 | 41 | 42 | PROCEDURE Open3DPort (port: Port3DPtr); 43 | PROCEDURE SetPort3D (port: Port3DPtr); 44 | PROCEDURE GetPort3D (VAR port: Port3DPtr); 45 | 46 | PROCEDURE MoveTo2D(x,y: REAL); PROCEDURE MoveTo3D(x,y,z: REAL); 47 | PROCEDURE LineTo2D(x,y: REAL); PROCEDURE LineTo3D(x,y,z: REAL); 48 | PROCEDURE Move2D(dx,dy: REAL); PROCEDURE Move3D(dx,dy,dz: REAL); 49 | PROCEDURE Line2D(dx,dy: REAL); PROCEDURE Line3D(dx,dy,dz: REAL); 50 | 51 | PROCEDURE ViewPort (r: Rect); 52 | PROCEDURE LookAt (left,top,right,bottom: REAL); 53 | PROCEDURE ViewAngle (angle: REAL); 54 | PROCEDURE Identity; 55 | PROCEDURE Scale (xFactor,yFactor,zFactor: REAL); 56 | PROCEDURE Translate (dx,dy,dz: REAL); 57 | PROCEDURE Pitch (xAngle: REAL); 58 | PROCEDURE Yaw (yAngle: REAL); 59 | PROCEDURE Roll (zAngle: REAL); 60 | PROCEDURE Skew (zAngle: REAL); 61 | PROCEDURE TransForm (src: Point3D; VAR dst: Point3D); 62 | FUNCTION Clip3D (src1,src2: Point3D; VAR dst1,dst2: POINT): BOOLEAN; 63 | 64 | PROCEDURE SetPt3D (VAR pt3D: Point3D; x,y,z: REAL); 65 | PROCEDURE SetPt2D (VAR pt2D: Point2D; x,y: REAL); 66 | 67 | 68 | 69 | IMPLEMENTATION 70 | 71 | 72 | 73 | PROCEDURE Open3DPort(* port: Port3DPtr *); 74 | { initialize all values in port^ to their defaults } 75 | BEGIN 76 | thePort3D:=port; 77 | port^.GPort:=thePort; 78 | ViewPort(thePort^.portRect); 79 | WITH thePort^.portRect DO LookAt(left,top,right,bottom); 80 | ViewAngle(0); 81 | Identity; 82 | MoveTo3D(0,0,0); 83 | END; 84 | 85 | 86 | PROCEDURE SetPort3D(* port: Port3DPtr *); 87 | { change to another Port3D } 88 | BEGIN 89 | thePort3D:=port; 90 | SetPort(port^.GPort); 91 | END; 92 | 93 | 94 | PROCEDURE GetPort3D(* VAR port: Port3DPtr *); 95 | { inquire the current Port3D } 96 | BEGIN 97 | port:=thePort3D; 98 | END; 99 | 100 | 101 | PROCEDURE MoveTo3D(* x,y,z: REAL *); 102 | { Move from current position to x,y,z without drawing. } 103 | VAR pt1,pt2: POINT; 104 | oldPrime: Point3D; 105 | BEGIN 106 | WITH thePort3D^ DO 107 | BEGIN 108 | oldPrime:=penPrime; 109 | pen.x:=x; 110 | pen.y:=y; 111 | pen.z:=z; 112 | TransForm(pen,penPrime); 113 | IF Clip3D(oldPrime,penPrime,pt1,pt2) THEN MoveTo(pt2.H,pt2.V); 114 | END; 115 | END; 116 | 117 | 118 | PROCEDURE LineTo3D(* x,y,z: REAL *); 119 | { draw a 3-D line from current position to x,y,z. } 120 | VAR oldPrime: Point3D; 121 | pt1,pt2: POINT; 122 | BEGIN 123 | WITH thePort3D^ DO 124 | BEGIN 125 | oldPrime:=penPrime; 126 | pen.x:=x; 127 | pen.y:=y; 128 | pen.z:=z; 129 | TransForm(pen,penPrime); 130 | IF Clip3D(oldPrime,penPrime,pt1,pt2) THEN 131 | BEGIN 132 | MoveTo(pt1.h,pt1.v); 133 | LineTo(pt2.H,pt2.V); 134 | END; 135 | END; 136 | END; 137 | 138 | 139 | PROCEDURE Move3D(* dx,dy,dz: REAL *); 140 | BEGIN 141 | WITH thePort3D^ DO MoveTo3D(pen.x+dx,pen.y+dy,pen.z+dz); 142 | END; 143 | 144 | 145 | PROCEDURE Line3D(* dx,dy,dz: REAL *); 146 | BEGIN 147 | WITH thePort3D^ DO LineTo3D(pen.x+dx,pen.y+dy,pen.z+dz); 148 | END; 149 | 150 | 151 | PROCEDURE MoveTo2D(* x,y: REAL *); 152 | BEGIN 153 | MoveTo3D(x,y,thePort3D^.pen.z); 154 | END; 155 | 156 | 157 | PROCEDURE Move2D(* dx,dy: REAL *); 158 | BEGIN 159 | Move3D(dx,dy,0.0); 160 | END; 161 | 162 | 163 | PROCEDURE LineTo2D(* x,y: REAL *); 164 | BEGIN 165 | LineTo3D(x,y,thePort3D^.pen.z); 166 | END; 167 | 168 | 169 | PROCEDURE Line2D(* dx,dy: REAL *); 170 | BEGIN 171 | Line3D(dx,dy,0.0); 172 | END; 173 | 174 | 175 | PROCEDURE ViewLook; 176 | { re-calculate offsets and scales after LookAt or ViewPort } 177 | BEGIN 178 | WITH thePort3D^ DO 179 | WITH viewRect DO 180 | BEGIN 181 | hSize:=(right-left)/2.0; 182 | vSize:=(bottom-top)/(-2.0); { vert pos down, y pos up } 183 | hCenter:=left + hSize; 184 | vCenter:=top - vSize; 185 | END; 186 | END; 187 | 188 | 189 | PROCEDURE ViewPort(* r: Rect *); 190 | { specify what portion of the folder to map onto } 191 | BEGIN 192 | thePort3D^.viewRect:=r; 193 | ViewLook; { re-calculate scales and offsets } 194 | END; 195 | 196 | 197 | PROCEDURE LookAt(* left,top,right,bottom: REAL *); 198 | { specify the real number coordinates of the portRect } 199 | BEGIN 200 | WITH thePort3D^ DO 201 | BEGIN 202 | xLeft:=left; 203 | xRight:=right; 204 | yBottom:=bottom; 205 | yTop:=top; 206 | eye.x:=(left+right)/2.0; 207 | eye.y:=(top+bottom)/2.0; 208 | END; 209 | ViewLook; { re-calculate scales and offsets } 210 | END; 211 | 212 | 213 | PROCEDURE ViewAngle(* angle: REAL *); 214 | { specify the horizontal angle subtended by the viewing pyramid } 215 | BEGIN 216 | WITH thePort3D^ DO 217 | BEGIN 218 | IF angle < 0.1 THEN angle:=0.1; 219 | angle:=angle/(2.0*radConst); { halve angle & convert to rad } 220 | xCotan:=COS(angle)/SIN(angle); { remember for perspective calc } 221 | yCotan:=xCotan * (xRight-xLeft)/(yTop-yBottom); 222 | eye.z:=xCotan * (xRight-xLeft)/2; 223 | END; 224 | END; 225 | 226 | 227 | PROCEDURE TransForm(* src: Point3D; VAR dst: Point3D *); 228 | { use the current xForm matrix to transform } 229 | { a 3D source point into a 3D destination point. } 230 | BEGIN 231 | IF thePort3D^.ident THEN dst:=src 232 | ELSE WITH thePort3D^ DO 233 | BEGIN 234 | dst.x:=src.x * xForm[0,0] + src.y * xForm[1,0] 235 | + src.z * xForm[2,0] + xForm[3,0]; 236 | dst.y:=src.x * xForm[0,1] + src.y * xForm[1,1] 237 | + src.z * xForm[2,1] + xForm[3,1]; 238 | dst.z:=src.x * xForm[0,2] + src.y * xForm[1,2] 239 | + src.z * xForm[2,2] + xForm[3,2]; 240 | END; 241 | END; 242 | 243 | 244 | FUNCTION Clip3D(* src1,src2: Point3D; VAR dst1,dst2: POINT *); 245 | { do full 3D clipping to viewing pyramid and return 2D } 246 | { screen coords in dst. Function value true if visible. } 247 | LABEL 0; 248 | TYPE Edge=(left,top,right,bottom); 249 | OutCode=SET OF Edge; 250 | VAR c,c1,c2: OutCode; 251 | pt3D: Point3D; 252 | t: REAL; 253 | pt1,pt2: POINT; 254 | 255 | PROCEDURE Code(pt3D: Point3D; VAR c: OutCode); 256 | BEGIN 257 | c:=[]; 258 | IF pt3D.x < -pt3D.z THEN c:=[left] ELSE IF pt3D.x > pt3D.z THEN c:=[right]; 259 | IF pt3D.y < -pt3D.z THEN c:=c+[bottom] ELSE IF pt3D.y > pt3D.z THEN c:=c+[top]; 260 | END; 261 | 262 | BEGIN 263 | Clip3D:=FALSE; 264 | WITH thePort3D^ DO 265 | BEGIN { convert both points into clipping coord system } 266 | src1.x:=(src1.x - eye.x) * xCotan; 267 | src1.y:=(src1.y - eye.y) * yCotan; 268 | src1.z:=eye.z - src1.z; 269 | 270 | src2.x:=(src2.x - eye.x) * xCotan; 271 | src2.y:=(src2.y - eye.y) * yCotan; 272 | src2.z:=eye.z - src2.z; 273 | END; 274 | 275 | 276 | Code(src1,c1); Code(src2,c2); 277 | WHILE c1+c2 <> [] DO 278 | BEGIN 279 | IF c1*c2 <> [] THEN GOTO 0; { both out on same side } 280 | c:=c1; IF c=[] THEN c:=c2; 281 | 282 | IF left IN c THEN { calc intersect with left edge } 283 | BEGIN 284 | t:=(src1.z+src1.x) / ((src1.x-src2.x) - (src2.z-src1.z)); 285 | pt3D.z:=t*(src2.z-src1.z) + src1.z; 286 | pt3D.x:=-pt3D.z; 287 | pt3D.y:=t*(src2.y-src1.y) + src1.y; 288 | END 289 | 290 | ELSE IF right IN c THEN { calc intersect with right edge } 291 | BEGIN 292 | t:=(src1.z-src1.x) / ((src2.x-src1.x) - (src2.z-src1.z)); 293 | pt3D.z:=t*(src2.z-src1.z) + src1.z; 294 | pt3D.x:=pt3D.z; 295 | pt3D.y:=t*(src2.y-src1.y) + src1.y; 296 | END 297 | 298 | ELSE IF bottom IN c THEN { calc intersect with bottom edge } 299 | BEGIN 300 | t:=(src1.z+src1.y) / ((src1.y-src2.y) - (src2.z-src1.z)); 301 | pt3D.z:=t*(src2.z-src1.z) + src1.z; 302 | pt3D.x:=t*(src2.x-src1.x) + src1.x; 303 | pt3D.y:=-pt3D.z; 304 | END 305 | 306 | ELSE IF top IN c THEN { calc intersect with top edge } 307 | BEGIN 308 | t:=(src1.z-src1.y) / ((src2.y-src1.y) - (src2.z-src1.z)); 309 | pt3D.z:=t*(src2.z-src1.z) + src1.z; 310 | pt3D.x:=t*(src2.x-src1.x) + src1.x; 311 | pt3D.y:=pt3D.z; 312 | END; 313 | 314 | IF c=c1 THEN BEGIN src1:=pt3D; Code(src1,c1); END 315 | ELSE BEGIN src2:=pt3D; Code(src2,c2); END; 316 | 317 | END; 318 | 319 | { if we reach here, the line from src1 to src2 is visible } 320 | Clip3D:=TRUE; 321 | WITH thePort3D^ DO 322 | WITH GPort^ DO 323 | BEGIN { convert clip coords to screen coords } 324 | dst1.H:=ROUND(hCenter + hSize * src1.x / src1.z); 325 | dst1.V:=ROUND(vCenter + vSize * src1.y / src1.z); 326 | dst2.H:=ROUND(hCenter + hSize * src2.x / src2.z); 327 | dst2.V:=ROUND(vCenter + vSize * src2.y / src2.z); 328 | END; 329 | 330 | 0: END; 331 | 332 | 333 | PROCEDURE Identity; 334 | { reset the transform matrix to identity } 335 | VAR ROW,COL: INTEGER; 336 | BEGIN; 337 | WITH thePort3D^ DO 338 | BEGIN 339 | FOR ROW:=0 TO 3 DO 340 | FOR COL:=0 TO 3 DO 341 | IF ROW=COL THEN xForm[ROW,COL]:=1.0 342 | ELSE xForm[ROW,COL]:=0.0; 343 | ident:=TRUE; { SET FLAG SO xForm CAN BE SKIPPED } 344 | END; 345 | END; 346 | 347 | 348 | PROCEDURE Scale(* xFactor,yFactor,zFactor: REAL *); 349 | { change xForm matrix to provide scaling } 350 | VAR ROW: INTEGER; 351 | BEGIN 352 | WITH thePort3D^ DO 353 | BEGIN 354 | ident:=FALSE; 355 | FOR ROW:=0 TO 3 DO 356 | BEGIN 357 | xForm[ROW,0]:=xForm[ROW,0]*xFactor; 358 | xForm[ROW,1]:=xForm[ROW,1]*yFactor; 359 | xForm[ROW,2]:=xForm[ROW,2]*zFactor; 360 | END; 361 | END; 362 | END; 363 | 364 | 365 | PROCEDURE Translate(* dx,dy,dz: REAL *); 366 | { change xForm matrix to translate } 367 | BEGIN 368 | WITH thePort3D^ DO 369 | BEGIN 370 | ident:=FALSE; 371 | xForm[3,0]:=xForm[3,0]+dx; 372 | xForm[3,1]:=xForm[3,1]+dy; 373 | xForm[3,2]:=xForm[3,2]+dz; 374 | END; 375 | END; 376 | 377 | 378 | PROCEDURE Pitch(* xAngle: REAL *); 379 | { change xForm matrix to rotate xAngle degrees around x-Axis } 380 | VAR si,co,TEMP: REAL; 381 | BEGIN 382 | xAngle:=xAngle/radConst; { convert degrees to rads } 383 | si:=SIN(xAngle); co:=COS(xAngle); 384 | WITH thePort3D^ DO 385 | BEGIN 386 | ident:=FALSE; 387 | TEMP:=xForm[0,1]*co+xForm[0,2]*si; 388 | xForm[0,2]:=xForm[0,2]*co-xForm[0,1]*si; xForm[0,1]:=TEMP; 389 | TEMP:=xForm[1,1]*co+xForm[1,2]*si; 390 | xForm[1,2]:=xForm[1,2]*co-xForm[1,1]*si; xForm[1,1]:=TEMP; 391 | TEMP:=xForm[2,1]*co+xForm[2,2]*si; 392 | xForm[2,2]:=xForm[2,2]*co-xForm[2,1]*si; xForm[2,1]:=TEMP; 393 | TEMP:=xForm[3,1]*co+xForm[3,2]*si; 394 | xForm[3,2]:=xForm[3,2]*co-xForm[3,1]*si; xForm[3,1]:=TEMP; 395 | END; 396 | END; 397 | 398 | 399 | PROCEDURE Yaw(* yAngle: REAL *); 400 | { change xForm matrix to rotate yAngle degrees around y-Axis } 401 | VAR si,co,TEMP: REAL; 402 | BEGIN 403 | yAngle:=yAngle/radConst; { convert degrees to rads } 404 | si:=SIN(yAngle); co:=COS(yAngle); 405 | WITH thePort3D^ DO 406 | BEGIN 407 | ident:=FALSE; 408 | TEMP:=xForm[0,0]*co-xForm[0,2]*si; 409 | xForm[0,2]:=xForm[0,0]*si+xForm[0,2]*co; xForm[0,0]:=TEMP; 410 | TEMP:=xForm[1,0]*co-xForm[1,2]*si; 411 | xForm[1,2]:=xForm[1,0]*si+xForm[1,2]*co; xForm[1,0]:=TEMP; 412 | TEMP:=xForm[2,0]*co-xForm[2,2]*si; 413 | xForm[2,2]:=xForm[2,0]*si+xForm[2,2]*co; xForm[2,0]:=TEMP; 414 | TEMP:=xForm[3,0]*co-xForm[3,2]*si; 415 | xForm[3,2]:=xForm[3,0]*si+xForm[3,2]*co; xForm[3,0]:=TEMP; 416 | END; 417 | END; 418 | 419 | 420 | PROCEDURE Roll(* zAngle: REAL *); 421 | { change xForm matrix to rotate zAngle degrees around z-Axis } 422 | VAR si,co,TEMP: REAL; 423 | BEGIN 424 | zAngle:=zAngle/radConst; { convert degrees to rads } 425 | si:=SIN(zAngle); co:=COS(zAngle); 426 | WITH thePort3D^ DO 427 | BEGIN 428 | ident:=FALSE; 429 | TEMP:=xForm[0,0]*co+xForm[0,1]*si; 430 | xForm[0,1]:=xForm[0,1]*co-xForm[0,0]*si; xForm[0,0]:=TEMP; 431 | TEMP:=xForm[1,0]*co+xForm[1,1]*si; 432 | xForm[1,1]:=xForm[1,1]*co-xForm[1,0]*si; xForm[1,0]:=TEMP; 433 | TEMP:=xForm[2,0]*co+xForm[2,1]*si; 434 | xForm[2,1]:=xForm[2,1]*co-xForm[2,0]*si; xForm[2,0]:=TEMP; 435 | TEMP:=xForm[3,0]*co+xForm[3,1]*si; 436 | xForm[3,1]:=xForm[3,1]*co-xForm[3,0]*si; xForm[3,0]:=TEMP; 437 | END; 438 | END; 439 | 440 | 441 | PROCEDURE Skew(* zAngle: REAL *); 442 | { change xForm matrix to skew zAngle degrees around z-Axis } 443 | { x := (x + y*TAN(zAngle)) zAngle limited to +-90 degrees } 444 | VAR co,TA: REAL; 445 | COL: INTEGER; 446 | BEGIN 447 | zAngle:=zAngle/radConst; { convert degrees to rads } 448 | co:= COS(zAngle); 449 | IF ABS(co) > 1.0E-5 THEN 450 | BEGIN 451 | TA:= SIN(zAngle)/co; 452 | WITH thePort3D^ DO 453 | BEGIN 454 | ident:=FALSE; 455 | FOR COL:=0 TO 2 DO 456 | xForm[1,COL]:=xForm[1,COL]+xForm[0,COL]*TA; 457 | END; 458 | END; 459 | END; 460 | 461 | 462 | PROCEDURE SetPt3D(* VAR pt3D: Point3D; x,y,z: REAL *); 463 | BEGIN 464 | pt3D.x:=x; 465 | pt3D.y:=y; 466 | pt3D.z:=z; 467 | END; 468 | 469 | 470 | PROCEDURE SetPt2D(* VAR pt2D: Point2D; x,y: REAL *); 471 | BEGIN 472 | pt2D.x:=x; 473 | pt2D.y:=y; 474 | END; 475 | 476 | 477 | END. { of Unit } 478 | -------------------------------------------------------------------------------- /GrafAsm.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;------------------------------------------------------------ 3 | ; 4 | ; --> GRAFASM.TEXT 5 | ; 6 | ; Miscellaneous unclassified routines. 7 | ; 8 | 9 | 10 | .PROC InitGraf,1 11 | ;-------------------------------------------------- 12 | ; 13 | ; PROCEDURE InitGraf(globalPtr: Ptr); 14 | ; 15 | ; 16 | PARAMSIZE .EQU 4 17 | GLOBALPTR .EQU PARAMSIZE+8-4 ;LONG 18 | 19 | 20 | LINK A6,#0 ;NO LOCALS 21 | MOVE.L A4,-(SP) ;SAVE REG 22 | MOVE.L GLOBALPTR(A6),A4 ;GET POINTER TO QUICKDRAW GLOBALS 23 | MOVE.L A4,GRAFGLOBALS(A5) ;SAVE IN MAGIC LOCATION 24 | ; 25 | ; new addition 22 Apr 85 26 | ; 27 | CLR.B $8F3 ; set lo-mem flag, QDExist 28 | 29 | LEA lastGrafGlob(A4),A0 ;SET UP START POINTER 30 | LEA thePort+4(A4),A1 ;SET UP LIMIT POINTER 31 | CLRLP CLR.W (A0)+ ;CLEAR A WORD 32 | CMPA.L A1,A0 ;CHECK LIMIT POINTER 33 | BNE CLRLP ;CLEAR ALL GLOBALS 34 | 35 | ;QDSpareD..QDSpare3 = all zeros 36 | ;playIndex := 0 37 | ;fontPtr = Nil 38 | ;FixTxWid := 0.0 39 | ;patAlign := (0,0) 40 | ;polyMax := 0 41 | ;thePoly := Nil 42 | ;QDSpare0 := 0 43 | ;playPic := Nil 44 | ;rgnMax := 0 45 | ;rgnIndex := 0 46 | ;rgnBuf := Nil 47 | LEA wideData(A4),A4 48 | MOVE.L A4,D0 ;REMEMBER ADDR OF WIDEDATA 49 | MOVE #10,(A4)+ ;wideData.rgnSize := 10 50 | MOVE.L #$80018001,(A4)+ ;wideData.rgnBBox := 51 | MOVE.L #$7FFF7FFF,(A4)+ ;(-32767,-32767,32767,32767) 52 | MOVE.L A4,D1 ;REMEMBER ADDR OF WIDEMASTER 53 | MOVE.L D0,(A4)+ ;wideMaster := @wideData 54 | MOVE.L D1,(A4)+ ;wideOpen := @wideMaster 55 | MOVEQ #1,D0 56 | MOVE.L D0,(A4)+ ;randSeed := 1 57 | MOVE.L A4,-(SP) ;point to screenBits 58 | _GetScrnBits ;fill in screenBits 59 | ADD #14,A4 ;bump past screenBits 60 | MOVEQ #26,D0 ;INIT LOOP COUNT 61 | LEA CURDATA,A0 ;POINT TO CURSOR DATA 62 | CRSRLP MOVE.L (A0)+,(A4)+ ;COPY A LONG INTO GLOBALS 63 | DBRA D0,CRSRLP ;LOOP FOR 27 LONGS 64 | ;thePort := NIL 65 | MOVE.L (SP)+,A4 ;RESTORE REG 66 | UNLINK PARAMSIZE,'INITGRAF' 67 | 68 | 69 | CURDATA .WORD $0000,$4000,$6000,$7000 ;ARROW.DATA 70 | .WORD $7800,$7C00,$7E00,$7F00 71 | .WORD $7F80,$7C00,$6C00,$4600 72 | .WORD $0600,$0300,$0300,$0000 73 | 74 | .WORD $C000,$E000,$F000,$F800 ;ARROW.MASK 75 | .WORD $FC00,$FE00,$FF00,$FF80 76 | .WORD $FFC0,$FFE0,$FE00,$EF00 77 | .WORD $CF00,$8780,$0780,$0380 78 | 79 | .WORD $0001,$0001 ;ARROW.HOTSPOT := (1,1) 80 | 81 | .LONG $77DD77DD,$77DD77DD ;dkGray 82 | .LONG $88228822,$88228822 ;ltGray 83 | .LONG $AA55AA55,$AA55AA55 ;gray 84 | .LONG $FFFFFFFF,$FFFFFFFF ;black 85 | .LONG $00000000,$00000000 ;white 86 | 87 | 88 | 89 | .PROC OpenPort,1 90 | .REF NewRgn 91 | ;------------------------------------------------------------- 92 | ; 93 | ; PROCEDURE OpenPort(port: GrafPtr); 94 | ; { allocate clipRgn and visRgn, then call InitPort. 95 | ; 96 | CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT 97 | JSR NEWRGN ;ALLOCATE A NEW REGION 98 | CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT 99 | JSR NEWRGN ;ALLOCATE A SECOND NEW REGION 100 | MOVE.L 12(SP),A0 ;POINT TO PORT 101 | MOVE.L (SP)+,CLIPRGN(A0) ;INSTALL NEW REGION INTO CLIPRGN 102 | MOVE.L (SP)+,VISRGN(A0) ;AND OTHER INTO VISRGN 103 | ;FALL THRU TO InitPort 104 | 105 | 106 | .PROC InitPort,1 107 | .REF RectRgn,CopyRgn 108 | ;------------------------------------------------------------- 109 | ; 110 | ; PROCEDURE InitPort(port: GrafPtr); 111 | ; 112 | ; { initialize all fields of an existing GrafPort } 113 | ; 114 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 115 | MOVE.L 4(SP),A1 ;GET PORT PARAM 116 | MOVE.L A1,THEPORT(A0) ;SetPort(port) 117 | CLR.W (A1)+ ;DEVICE := 0 118 | LEA SCREENBITS(A0),A0 ;POINT TO SCREENBITS 119 | MOVE.L (A0)+,(A1)+ ;portBits := screenBits 120 | MOVE.W (A0)+,(A1)+ ;COPY ROWBYTES 121 | MOVE.L (A0),(A1)+ ;COPY TOPLEFT 122 | MOVE.L 4(A0),(A1)+ ;COPY BOTRIGHT 123 | MOVE.L (A0),(A1)+ ;portRect := screenBits.bounds 124 | MOVE.L 4(A0),(A1)+ ;all 8 bytes 125 | MOVE.L (A1)+,-(SP) ;visRgn := screenBits.bounds 126 | MOVE.L A0,-(SP) 127 | JSR RECTRGN 128 | MOVE.L 4(SP),A1 ;GET PORT PARAM 129 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 130 | MOVE.L WIDEOPEN(A0),-(SP) ;PUSH WIDE OPEN RGN 131 | MOVE.L CLIPRGN(A1),-(SP) ;PUSH CLIPRGN 132 | JSR COPYRGN ;SET TO WIDE OPEN 133 | MOVE.L 4(SP),A1 ;GET PORT PARAM 134 | LEA BKPAT(A1),A1 135 | CLR.L (A1)+ ;bkPat := white 136 | CLR.L (A1)+ 137 | MOVEQ #-1,D0 138 | MOVE.L D0,(A1)+ ;fillPat := Black 139 | MOVE.L D0,(A1)+ 140 | CLR.L (A1)+ ;pnLoc := (0,0) 141 | MOVE.L #$00010001,(A1)+ ;pnSize := (1,1) 142 | MOVE #8,(A1)+ ;pnMode := patCopy 143 | MOVE.L D0,(A1)+ ;pnPat := black 144 | MOVE.L D0,(A1)+ 145 | CLR.W (A1)+ ;pnVis := 0 146 | CLR.L (A1)+ ;txFont, txFace := 0 147 | MOVE #1,(A1)+ ;txMode := srcOr 148 | CLR (A1)+ ;txSize := 0 149 | CLR.L (A1)+ ;spExtra := 0.0 150 | MOVE.L #blackColor,(A1)+ ;fgColor := blackColor 151 | MOVE.L #whiteColor,(A1)+ ;bkColor := whiteColor 152 | CLR.L (A1)+ ;colrBit,patStretch := 0 153 | CLR.L (A1)+ ;picSave := Nil 154 | CLR.L (A1)+ ;rgnSave := Nil 155 | CLR.L (A1)+ ;polySave := Nil 156 | CLR.L (A1)+ ;grafProcs := Nil 157 | MOVE.L (SP)+,(SP) ;STRIP PARAM 158 | RTS ;AND RETURN 159 | 160 | 161 | 162 | .PROC ClosePort,1 163 | ;------------------------------------------------------------- 164 | ; 165 | ; PROCEDURE ClosePort(port: GrafPtr); 166 | ; 167 | ; { just disposes of clipRgn and visRgn } 168 | ; 169 | MOVE.L 4(SP),A0 ;GET PORT 170 | MOVE.L CLIPRGN(A0),A0 ;GET CLIPRGN HANDLE 171 | _DisposHandle ;DISCARD IT 172 | MOVE.L 4(SP),A0 ;GET PORT 173 | MOVE.L VISRGN(A0),A0 ;GET VISRGN HANDLE 174 | _DisposHandle ;DISCARD IT 175 | MOVE.L (SP)+,(SP) ;STRIP PARAM 176 | RTS ;AND RETURN 177 | 178 | 179 | .PROC SetStdProcs,1 180 | .REF StdText,StdLine,StdRect,StdRRect,StdOval,StdArc,StdPoly 181 | .REF StdRgn,StdBits,StdComment,StdTxMeas,StdGetPic,StdPutPic 182 | ;------------------------------------------------------------- 183 | ; 184 | ; PROCEDURE SetStdProcs(VAR procs: QDProcs); 185 | ; 186 | MOVE.L 4(SP),A1 ;GET ADDRESS OF PROC RECORD 187 | LEA StdText,A0 188 | MOVE.L A0,(A1)+ 189 | LEA StdLine,A0 190 | MOVE.L A0,(A1)+ 191 | LEA StdRect,A0 192 | MOVE.L A0,(A1)+ 193 | LEA StdRRect,A0 194 | MOVE.L A0,(A1)+ 195 | LEA StdOval,A0 196 | MOVE.L A0,(A1)+ 197 | LEA StdArc,A0 198 | MOVE.L A0,(A1)+ 199 | LEA StdPoly,A0 200 | MOVE.L A0,(A1)+ 201 | LEA StdRgn,A0 202 | MOVE.L A0,(A1)+ 203 | LEA StdBits,A0 204 | MOVE.L A0,(A1)+ 205 | LEA StdComment,A0 206 | MOVE.L A0,(A1)+ 207 | LEA StdTxMeas,A0 208 | MOVE.L A0,(A1)+ 209 | LEA StdGetPic,A0 210 | MOVE.L A0,(A1)+ 211 | LEA StdPutPic,A0 212 | MOVE.L A0,(A1)+ 213 | MOVE.L (SP)+,(SP) ;STRIP PARAM 214 | RTS ;AND RETURN 215 | 216 | 217 | 218 | .PROC LocalToGlobal,1 219 | .DEF GlobalToLocal,AddPt,SubPt,SetPort,GetPort 220 | ;------------------------------------------------------------- 221 | ; 222 | ; PROCEDURE LocalToGlobal(VAR pt: Point); 223 | ; 224 | ; restores all registers. 225 | ; 226 | MOVEM.L D0-D2/A0/A1,-(SP) ;SAVE REGS 227 | MOVE.L #1,D2 ;INDICATE SUB 228 | BRA.S SHARE 229 | 230 | 231 | 232 | ;------------------------------------------------------------- 233 | ; 234 | ; PROCEDURE GlobalToLocal(VAR pt: Point); 235 | ; 236 | ; restores all registers. 237 | ; 238 | GlobalToLocal 239 | MOVEM.L D0-D2/A0/A1,-(SP) ;SAVE REGS 240 | MOVE.L #0,D2 ;INDICATE ADD 241 | SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 242 | MOVE.L THEPORT(A0),A0 ;POINT TO CURRENT GRAFPORT 243 | MOVE.L 24(SP),A1 ;POINT TO VAR PT 244 | MOVE PORTBITS+BOUNDS+TOP(A0),D0 ;GET DV 245 | MOVE PORTBITS+BOUNDS+LEFT(A0),D1 ;GET DH 246 | BSR.S ADDSUB ;CONVERT TO LOCAL 247 | MOVEM.L (SP)+,D0-D2/A0/A1 ;RESTORE REGS 248 | BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN 249 | ; 250 | ; 251 | ; 252 | ADDSUB TST D2 253 | BEQ.S JUSTADD 254 | NEG D0 255 | NEG D1 256 | JUSTADD ADD D0,(A1)+ 257 | ADD D1,(A1)+ 258 | RTS 259 | 260 | 261 | 262 | ;------------------------------------------------------------- 263 | ; 264 | ; PROCEDURE AddPt(src: Point; VAR dst: Point); 265 | ; { add two points together, restores all regs } 266 | ; 267 | AddPt MOVEM.L D0-D2/A1,-(SP) ;SAVE REGS 268 | MOVE.L #0,D2 ;INDICATE ADD 269 | BRA.S SHARE2 270 | 271 | 272 | 273 | ;------------------------------------------------------------- 274 | ; 275 | ; PROCEDURE SubPt(src: Point; VAR dst: Point); 276 | ; { subtract src Point from dst point, restores all regs } 277 | ; 278 | SubPt MOVEM.L D0-D2/A1,-(SP) ;SAVE REGS 279 | MOVE.L #1,D2 ;INDICATE SUB 280 | SHARE2 MOVE.L 20(SP),A1 ;POINT TO DST 281 | MOVE 24+V(SP),D0 ;GET SRC.V 282 | MOVE 24+H(SP),D1 ;GET SRC.H 283 | BSR.S ADDSUB 284 | MOVEM.L (SP)+,D0-D2/A1 ;RESTORE REGS 285 | MOVE.L (SP)+,(SP) 286 | SHARE3 MOVE.L (SP)+,(SP) 287 | RTS ;AND RETURN 288 | 289 | 290 | 291 | ;---------------------------------------------------------- 292 | ; 293 | ; PROCEDURE SetPort(gp: GrafPtr); 294 | ; { switch the current port to a different GrafPort } 295 | ; 296 | SetPort MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 297 | MOVE.L 4(SP),THEPORT(A0) ;INSTALL INTO THEPORT 298 | BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN 299 | 300 | 301 | 302 | ;---------------------------------------------------------- 303 | ; 304 | ; PROCEDURE GetPort(VAR gp: GrafPtr); 305 | ; { inquire the current GrafPort } 306 | ; 307 | GetPort MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 308 | MOVE.L 4(SP),A1 ;POINT TO VAR GP 309 | MOVE.L THEPORT(A0),(A1) ;COPY FROM THEPORT 310 | BRA.S SHARE3 ;STRIP 4 BYTES AND RETURN 311 | 312 | 313 | 314 | .PROC GrafDevice,1 315 | .REF PortWord 316 | ;---------------------------------------------------------- 317 | ; 318 | ; PROCEDURE GrafDevice(device: INTEGER); 319 | ; 320 | MOVEQ #DEVICE,D0 ;PUT PORT OFFSET IN D0 321 | JMP PORTWORD ;INSTALL PARAM INTO THEPORT 322 | 323 | 324 | 325 | .PROC SetPortBits,1 326 | .DEF BackPat 327 | ;---------------------------------------------------------- 328 | ; 329 | ; PROCEDURE SetPortBits(bm: BitMap); 330 | ; { re-direct output to a different BitMap } 331 | ; 332 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 333 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 334 | LEA PORTBITS(A0),A0 ;POINT TO PORTBITS 335 | MOVE.L 4(SP),A1 ;POINT TO BITMAP 336 | MOVE.L (A1)+,(A0)+ ;COPY BASEADDR 337 | MOVE.W (A1)+,(A0)+ ;COPY ROWBYTES 338 | SHARE MOVE.L (A1)+,(A0)+ ;COPY BOUNDS.TOPLEFT 339 | MOVE.L (A1)+,(A0)+ ;COPY BOUNDS.BOTRIGHT 340 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 341 | RTS ;AND RETURN 342 | 343 | 344 | 345 | ;---------------------------------------------------------- 346 | ; 347 | ; PROCEDURE BackPat(pat: Pattern); 348 | ; { set the background pattern } 349 | ; 350 | BackPat MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 351 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 352 | LEA BKPAT(A0),A0 ;POINT TO BKPAT 353 | MOVE.L 4(SP),A1 ;GET ADDR OF PATTERN 354 | BRA.S SHARE 355 | 356 | 357 | 358 | .PROC PortSize,2 359 | ;---------------------------------------------------------- 360 | ; 361 | ; PROCEDURE PortSize(width,height: INTEGER); 362 | ; 363 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 364 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 365 | MOVE PORTRECT+LEFT(A0),D0 ;GET PORTRECT.LEFT 366 | ADD 6(SP),D0 ;ADD WIDTH 367 | MOVE D0,PORTRECT+RIGHT(A0) ;UPDATE PORTRECT.RIGHT 368 | MOVE PORTRECT+TOP(A0),D0 ;GET PORTRECT.TOP 369 | ADD 4(SP),D0 ;ADD HEIGHT 370 | MOVE D0,PORTRECT+BOTTOM(A0) ;UPDATE PORTRECT.BOTTOM 371 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 372 | RTS ;AND RETURN 373 | 374 | 375 | 376 | .PROC MovePortTo,2 377 | .DEF SetOrigin,ClipRect 378 | .REF OffsetRgn,RectRgn 379 | ;---------------------------------------------------------- 380 | ; 381 | ; PROCEDURE MovePortTo(leftGlobal,topGlobal: INTEGER); 382 | ; { move portRect to a different part of the bitmap } 383 | ; 384 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 385 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 386 | MOVE PORTRECT+LEFT(A0),D0 ;GET PORTRECT.LEFT 387 | SUB PORTBITS+BOUNDS+LEFT(A0),D0 ;CONVERT TO GLOBAL 388 | SUB 6(SP),D0 ;SUB LEFTGLOBAL FOR DH 389 | MOVE PORTRECT+TOP(A0),D1 ;GET PORTRECT.TOP 390 | SUB PORTBITS+BOUNDS+TOP(A0),D1 ;CONVERT TO GLOBAL 391 | SUB 4(SP),D1 ;SUB TOPGLOBAL FOR DV 392 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 393 | OFSPORT LEA PORTBITS+BOUNDS(A0),A0 ;OFFSET PORTBITS.BOUNDS DH,DV 394 | OFSRECT ADD D1,(A0)+ ;OFFSET TOP 395 | ADD D0,(A0)+ ;OFFSET LEFT 396 | ADD D1,(A0)+ ;OFFSET BOTTOM 397 | ADD D0,(A0)+ ;OFFSET RIGHT 398 | RTS ;AND RETURN 399 | 400 | 401 | 402 | ;---------------------------------------------------------- 403 | ; 404 | ; PROCEDURE SetOrigin(h,v: INTEGER); 405 | ; { re-define the local coords by adjusting portBits.bounds, } 406 | ; { portRect, and visRgn } 407 | ; 408 | SetOrigin 409 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 410 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 411 | MOVE.L 4(SP),D0 ;GET V AND H BOTH 412 | CMP.L PORTRECT+TOPLEFT(A0),D0 ;SAME AS ALREADY IN THEPORT ? 413 | BEQ.S DONE ;YES, QUIT 414 | MOVE 6(SP),D0 ;GET H 415 | SUB PORTRECT+LEFT(A0),D0 ;DH:=H-PORTRECT.LEFT 416 | MOVE 4(SP),D1 ;GET V 417 | SUB PORTRECT+TOP(A0),D1 ;DV:=V-PORTRECT.TOP 418 | MOVE.L VISRGN(A0),-(SP) ;PUSH PARMS FOR LATER 419 | MOVE D0,-(SP) 420 | MOVE D1,-(SP) 421 | BSR.S OFSPORT ;OFFSET PORTBITS.BOUNDS 422 | LEA PORTRECT-PORTBITS-BOUNDS-8(A0),A0 ;POINT A0 AT PORTRECT 423 | BSR.S OFSRECT ;OFFSET PORTRECT 424 | JSR OFFSETRGN 425 | DONE MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 426 | RTS ;AND RETURN 427 | 428 | 429 | 430 | ;---------------------------------------------------------- 431 | ; 432 | ; PROCEDURE ClipRect(r: Rect); 433 | ; { Make the current grafport's clipRgn match a given rectangle } 434 | ; 435 | ClipRect 436 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 437 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 438 | MOVE.L CLIPRGN(A0),-(SP) ;PUSH CLIPRGN 439 | MOVE.L 8(SP),-(SP) ;PUCH ADDR OF RECT 440 | JSR RECTRGN 441 | BRA.S DONE 442 | 443 | 444 | 445 | .PROC SetClip,1 446 | .DEF GetClip 447 | .REF CopyRgn 448 | ;---------------------------------------------------------- 449 | ; 450 | ; PROCEDURE SetClip(rgn: RgnHandle); 451 | ; 452 | ; copy rgn into theport^.clipRgn 453 | ; 454 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 455 | MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS 456 | MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT 457 | MOVE.L CLIPRGN(A1),-(SP) ;PUSH THEPORT^.CLIPRGN 458 | BRA.S SHARE 459 | 460 | 461 | 462 | ;---------------------------------------------------------- 463 | ; 464 | ; PROCEDURE GetClip(rgn: RgnHandle); 465 | ; 466 | ; copy from theport^.clipRgn into rgn. 467 | ; 468 | GetClip 469 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 470 | MOVE.L (SP)+,D0 ;POP RGN HANDLE 471 | MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS 472 | MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT 473 | MOVE.L CLIPRGN(A1),-(SP) ;PUSH THEPORT^.CLIPRGN 474 | MOVE.L D0,-(SP) ;PUSH RGN 475 | SHARE MOVE.L A0,-(SP) ;RESTORE RETURN ADDR 476 | JMP COPYRGN ;AND GO TO COPYRGN 477 | 478 | 479 | 480 | .PROC SetPt,3 481 | ;------------------------------------------------------------- 482 | ; 483 | ; PROCEDURE SetPt(VAR pt: Point; h,v: INTEGER); 484 | ; 485 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 486 | MOVE.L (SP)+,D0 ;POP H,V 487 | MOVE.L (SP)+,A1 ;POP VAR ADDR OF PT 488 | MOVE.L D0,(A1) ;STORE H,V INTO PT 489 | JMP (A0) ;RETURN 490 | 491 | 492 | .FUNC EqualPt,2 493 | ;---------------------------------------------------------- 494 | ; 495 | ; FUNCTION EqualPt(pt1,pt2: Point): BOOLEAN; 496 | ; 497 | ; CLOBBERS D0,A0. 498 | ; 499 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 500 | MOVE.L (SP)+,D0 ;pop point1 501 | CMP.L (SP)+,D0 ;is point2 = point1 ? 502 | SEQ (SP) ;IF YES, SET TO TRUE 503 | NEG.B (SP) ;CONVERT -1 TO 1 504 | JMP (A0) ;RETURN 505 | 506 | 507 | .END 508 | -------------------------------------------------------------------------------- /GrafTypes.a: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------- 2 | ; 3 | ; --> GRAFTYPES.TEXT 4 | ; 5 | ; QUICKDRAW TYPE DECLARATIONS, USED BY ALL GRAPHICS ROUTINES 6 | ; 7 | NIL .EQU 0 ;IMPLEMENTATION VALUE OF NIL 8 | 9 | 10 | ;----------------------------------------------- 11 | ; 12 | ; QuickDraw VERBS: 13 | ; 14 | FRAME .EQU 0 15 | PAINT .EQU 1 16 | ERASE .EQU 2 17 | INVERT .EQU 3 18 | FILL .EQU 4 19 | 20 | 21 | ;----------------------------------------------- 22 | ; 23 | ; QuickDraw transfer MODES: 24 | ; 25 | srcCopy .EQU 0 26 | srcOr .EQU 1 27 | srcXor .EQU 2 28 | srcBic .EQU 3 29 | notSrcCopy .EQU 4 30 | notSrcOr .EQU 5 31 | notSrcXor .EQU 6 32 | notSrcBic .EQU 7 33 | patCopy .EQU 8 34 | patOr .EQU 9 35 | patXor .EQU 10 36 | patBic .EQU 11 37 | notPatCopy .EQU 12 38 | notPatOr .EQU 13 39 | notPatXor .EQU 14 40 | notPatBic .EQU 15 41 | 42 | 43 | ;----------------------------------------------- 44 | ; 45 | ; QuickDraw Color Separation: 46 | ; 47 | normalBit .EQU 0 ;normal screen mapping 48 | inverseBit .EQU 1 ;inverse screen mapping 49 | redBit .EQU 4 ;RGB additive mapping 50 | greenBit .EQU 3 ;for photos from screen 51 | blueBit .EQU 2 52 | cyanBit .EQU 8 ;CMYBk subtractive mapping 53 | magentaBit .EQU 7 ;for ink jet printer 54 | yellowBit .EQU 6 55 | blackBit .EQU 5 56 | 57 | blackColor .EQU 33 58 | whiteColor .EQU 30 59 | redColor .EQU 205 60 | greenColor .EQU 341 61 | blueColor .EQU 409 62 | cyanColor .EQU 273 63 | magentaColor .EQU 137 64 | yellowColor .EQU 69 65 | 66 | 67 | 68 | ;----------------------------------------------- 69 | ; 70 | ; OFFSETS WITHIN A POINT: 71 | ; 72 | V .EQU 0 ;WORD 73 | H .EQU 2 ;WORD 74 | 75 | 76 | ;----------------------------------------------- 77 | ; 78 | ; OFFSETS WITHIN A RECT: 79 | ; 80 | TOPLEFT .EQU 0 ;POINT 81 | BOTRIGHT .EQU 4 ;POINT 82 | 83 | TOP .EQU 0 ;INTEGER 84 | LEFT .EQU 2 ;INTEGER 85 | BOTTOM .EQU 4 ;INTEGER 86 | RIGHT .EQU 6 ;INTEGER 87 | 88 | 89 | ;----------------------------------------------- 90 | ; 91 | ; OFFSETS WITHIN A BITMAP: 92 | ; 93 | BASEADDR .EQU 0 ;LONG 94 | ROWBYTES .EQU 4 ;WORD 95 | BOUNDS .EQU 6 ;RECT 96 | 97 | 98 | ;----------------------------------------------- 99 | ; 100 | ; OFFSETS WITHIN A CURSOR: 101 | ; 102 | DATA .EQU 0 ;16 WORDS 103 | MASK .EQU 32 ;16 WORDS 104 | HOTSPOT .EQU 64 ;POINT 105 | 106 | 107 | 108 | ;----------------------------------------------- 109 | ; 110 | ; OFFSETS WITHIN A POLYGON: 111 | ; 112 | POLYSIZE .EQU 0 ;WORD, TOTAL BYTES 113 | POLYBBOX .EQU 2 ;RECT 114 | POLYPOINTS .EQU 10 ;ARRAY[0..0] OF Point 115 | 116 | 117 | ;----------------------------------------------- 118 | ; 119 | ; OFFSETS WITHIN A REGION: 120 | ; 121 | RGNSIZE .EQU 0 ;WORD, TOTAL BYTES 122 | RGNBBOX .EQU 2 ;RECT 123 | RGNDATA .EQU 10 ;START OF RGN DATA 124 | 125 | 126 | ;----------------------------------------------- 127 | ; 128 | ; OFFSETS WITHIN A PICTURE: 129 | ; 130 | PICSIZE .EQU 0 ;WORD, TOTAL BYTES 131 | PICFRAME .EQU 2 ;RECT 132 | PICDATA .EQU 10 ;START OF BYTE CODES 133 | 134 | 135 | ;----------------------------------------------- 136 | ; 137 | ; OFFSETS WITHIN QDProcs RECORD: 138 | ; 139 | textProc .EQU 0 ;PROCPTR 140 | lineProc .EQU textProc+4 ;PROCPTR 141 | rectProc .EQU lineProc+4 ;PROCPTR 142 | rRectProc .EQU rectProc+4 ;PROCPTR 143 | ovalProc .EQU rRectProc+4 ;PROCPTR 144 | arcProc .EQU ovalProc+4 ;PROCPTR 145 | polyProc .EQU arcProc+4 ;PROCPTR 146 | rgnProc .EQU polyProc+4 ;PROCPTR 147 | bitsProc .EQU rgnProc+4 ;PROCPTR 148 | commentProc .EQU bitsProc+4 ;PROCPTR 149 | txMeasProc .EQU commentProc+4 ;PROCPTR 150 | getPicProc .EQU txMeasProc+4 ;PROCPTR 151 | putPicProc .EQU getPicProc+4 ;PROCPTR 152 | 153 | 154 | 155 | ;----------------------------------------------- 156 | ; 157 | ; OFFSETS WITHIN A GRAFPORT: 158 | ; 159 | device .EQU 0 ;WORD 160 | portBits .EQU device+2 ;BITMAP 161 | portRect .EQU portBits+14 ;RECT 162 | visRgn .EQU portRect+8 ;RGNPTR 163 | clipRgn .EQU visRgn+4 ;RGNPTR 164 | bkPat .EQU clipRgn+4 ;PATTERN 165 | fillPat .EQU bkPat+8 ;PATTERN 166 | pnLoc .EQU fillPat+8 ;POINT 167 | pnSize .EQU pnLoc+4 ;POINT 168 | pnMode .EQU pnSize+4 ;WORD 169 | pnPat .EQU pnMode+2 ;PATTERN 170 | pnVis .EQU pnPat+8 ;WORD 171 | txFont .EQU pnVis+2 ;WORD 172 | txFace .EQU txFont+2 ;WORD 173 | txMode .EQU txFace+2 ;WORD 174 | txSize .EQU txMode+2 ;WORD 175 | spExtra .EQU txSize+2 ;Fixed Point 176 | fgColor .EQU spExtra+4 ;LONG 177 | bkColor .EQU fgColor+4 ;LONG 178 | colrBit .EQU bkColor+4 ;WORD 179 | patStretch .EQU colrBit+2 ;WORD 180 | picSave .EQU patStretch+2 ;handle 181 | rgnSave .EQU picSave+4 ;handle 182 | polySave .EQU rgnSave+4 ;handle 183 | grafProcs .EQU polySave+4 ;Pointer 184 | PORTREC .EQU grafProcs+4 ;SIZE OF A GRAFPORT 185 | PORTBOUNDS .EQU PORTBITS+BOUNDS 186 | 187 | 188 | ;----------------------------------------------------- 189 | ; 190 | ; OFFSETS IN A REGION STATE RECORD: 191 | ; 192 | RGNPTR .EQU 0 ;LONG 193 | DATAPTR .EQU RGNPTR+4 ;LONG 194 | SCANBUF .EQU DATAPTR+4 ;LONG 195 | SCANSIZE .EQU SCANBUF+4 ;WORD 196 | THISV .EQU SCANSIZE+2 ;WORD 197 | NEXTV .EQU THISV+2 ;WORD 198 | MINH .EQU NEXTV+2 ;WORD 199 | MAXH .EQU MINH+2 ;WORD 200 | LEFTH .EQU MAXH+2 ;WORD 201 | RGNREC .EQU LEFTH+2 ;SIZE OF A REGION RECORD 202 | 203 | 204 | ;----------------------------------------------------- 205 | ; 206 | ; Offsets in a PicSave record: 207 | ; 208 | thePic .EQU 0 ;PICHANDLE 209 | picMax .EQU thePic+4 ;LongInt 210 | picIndex .EQU picMax+4 ;LongInt 211 | picClipRgn .EQU picIndex+4 ;RgnHandle 212 | picBkPat .EQU picClipRgn+4 ;Pattern 213 | picTxFont .EQU picBkPat+8 ;WORD 214 | picTxFace .EQU picTxFont+2 ;Style 215 | picTxMode .EQU picTxFace+2 ;WORD 216 | picTxSize .EQU picTxMode+2 ;WORD 217 | picSpExtra .EQU picTxSize+2 ;Fixed Point 218 | picTxNumer .EQU picSpExtra+4 ;Point 219 | picTxDenom .EQU picTxNumer+4 ;Point 220 | picTxLoc .EQU picTxDenom+4 ;Point 221 | picPnLoc .EQU picTxLoc+4 ;Point 222 | picPnSize .EQU picPnLoc+4 ;Point 223 | picPnMode .EQU picPnSize+4 ;WORD 224 | picPnPat .EQU picPnMode+2 ;Pattern 225 | picFillPat .EQU picPnPat+8 ;Pattern 226 | picTheRect .EQU picFillPat+8 ;Rect 227 | picOvSize .EQU picTheRect+8 ;Point 228 | picOrigin .EQU picOvSize+4 ;Point 229 | picFgColor .EQU picOrigin+4 ;Long 230 | picBkColor .EQU picFgColor+4 ;Long 231 | 232 | picSaveRec .EQU picBkColor+4 ;total size in bytes 233 | 234 | 235 | ;----------------------------------------------------- 236 | ; 237 | ; QuickDraw GLOBAL VARIABLES: 238 | ; 239 | ; 52(A5) CONTAINS A POINTER TO THEPORT. 240 | ; ALL OTHER GLOBAL VARIABLES ARE EXPRESSED RELATIVE TO THEPORT. 241 | ; 242 | GRAFGLOBALS .EQU 0 ;A5 OFFSET TO GLOBALPTR 243 | 244 | 245 | ;----------------------------------------------------------- 246 | ; 247 | ; QuickDraw PUBLIC GLOBAL VARIABLES: 248 | ; 249 | thePort .EQU 0 ;GrafPtr 250 | white .EQU thePort-8 ;Pattern 251 | black .EQU white-8 ;Pattern 252 | gray .EQU black-8 ;Pattern 253 | ltGray .EQU gray-8 ;Pattern 254 | dkGray .EQU ltGray-8 ;Pattern 255 | arrow .EQU dkGray-68 ;Cursor 256 | screenBits .EQU arrow-14 ;BitMap 257 | randSeed .EQU screenBits-4 ;LONGINT 258 | 259 | 260 | ;------------------------------------------------------------ 261 | ; 262 | ; QuickDraw private global variables: 263 | ; 264 | wideOpen .EQU randSeed-4 ;RgnHandle 265 | wideMaster .EQU wideOpen-4 ;RgnPtr 266 | wideData .EQU wideMaster-10 ;Fake Region 267 | rgnBuf .EQU wideData-4 ;PointsHandle 268 | rgnIndex .EQU rgnBuf-2 ;INTEGER 269 | rgnMax .EQU rgnIndex-2 ;INTEGER 270 | playPic .EQU rgnMax-4 ;Long 271 | QDSpare0 .EQU playPic-2 ;unused word 272 | thePoly .EQU QDSpare0-4 ;POLYHANDLE 273 | polyMax .EQU thePoly-2 ;INTEGER 274 | patAlign .EQU polyMax-4 ;Point 275 | fixTxWid .EQU patAlign-4 ;Fixed Point 276 | fontPtr .EQU fixTxWid-4 ;long, ^FMOutput record 277 | playIndex .EQU fontPtr-4 ;long 278 | QDSpare3 .EQU playIndex-2 ;unused word 279 | QDSpare4 .EQU QDSpare3-2 ;unused word 280 | QDSpare5 .EQU QDSpare4-2 ;unused word 281 | QDSpare6 .EQU QDSpare5-2 ;unused word 282 | QDSpare7 .EQU QDSpare6-2 ;unused word 283 | QDSpare8 .EQU QDSpare7-2 ;unused word 284 | QDSpare9 .EQU QDSpare8-2 ;unused word 285 | QDSpareA .EQU QDSpare9-2 ;unused word 286 | QDSpareB .EQU QDSpareA-2 ;unused word 287 | QDSpareC .EQU QDSpareB-2 ;unused word 288 | QDSpareD .EQU QDSpareC-2 ;unused word 289 | lastGrafGlob .EQU QDSpareD 290 | grafSize .EQU 4-lastGrafGlob ;total size in bytes 291 | 292 | 293 | 294 | .MACRO UNLINK 295 | ;-------------------------------------------------------------- 296 | ; 297 | ; UNLINK A6, STRIP PARAMETERS, AND RETURN. 298 | ; 299 | ; FIRST PARAM IS NUMBER OF BYTES OF STACK BIAS. 300 | ; 301 | UNLK A6 ;RELEASE LOCAL VARIABLES 302 | 303 | .IF %1=0 ;NO PARAMETERS ? 304 | RTS ;THEN JUST RTS 305 | 306 | .ELSE 307 | .IF %1=4 ;4 BYTES OF PARAMS ? 308 | MOVE.L (SP)+,(SP) ;YES, STRIP AND ADJUST RET ADDR 309 | RTS 310 | 311 | .ELSE ;NOT 0 OR 4 BYTES OF PARAMS 312 | MOVE.L (SP)+,A0 ;POP RETURN ADDR INTO A0 313 | ADD #%1,SP ;STRIP PARAMETERS 314 | JMP (A0) ;JUMP THRU A0 TO RETURN 315 | .ENDC 316 | .ENDC 317 | 318 | .ENDM 319 | 320 | 321 | 322 | ;---------------------------------------------- 323 | ; 324 | ; Trap Macros used by QuickDraw: 325 | ; 326 | 327 | .MACRO _LongMul 328 | .WORD $A867 329 | .ENDM 330 | 331 | .MACRO _FixMul 332 | .WORD $A868 333 | .ENDM 334 | 335 | .MACRO _FixRatio 336 | .WORD $A869 337 | .ENDM 338 | 339 | .MACRO _NewHandle 340 | .WORD $A122 341 | .ENDM 342 | 343 | .MACRO _DisposHandle 344 | .WORD $A023 345 | .ENDM 346 | 347 | .MACRO _SetHandleSize 348 | .WORD $A024 349 | .ENDM 350 | 351 | .MACRO _GetHandleSize 352 | .WORD $A025 353 | .ENDM 354 | 355 | .MACRO _HLock 356 | .WORD $A029 357 | .ENDM 358 | 359 | .MACRO _HUnlock 360 | .WORD $A02A 361 | .ENDM 362 | 363 | .MACRO _GetScrnBits 364 | .WORD $A833 ;new trap number 365 | .ENDM 366 | 367 | .MACRO _StackAvail 368 | MOVE.L SP,D0 ;copy stack pointer 369 | SUB.L $114,D0 ;subtract HeapEnd for stack avail 370 | .ENDM 371 | 372 | .MACRO _SwapFont 373 | MOVE.L $8E0,A0 ;get pointer to FMSwapFont 374 | JSR (A0) ;call font manager 375 | .ENDM 376 | -------------------------------------------------------------------------------- /GrafUtil.p: -------------------------------------------------------------------------------- 1 | UNIT GrafUtil; 2 | 3 | INTERFACE 4 | 5 | USES {$U obj:QuickDraw } QuickDraw; 6 | 7 | TYPE Fixed = LongInt; 8 | Int64Bit = RECORD 9 | hiLong: LongInt; 10 | loLong: LongInt; 11 | END; 12 | 13 | FUNCTION BitAnd (long1,long2: LongInt): LongInt; 14 | FUNCTION BitOr (long1,long2: LongInt): LongInt; 15 | FUNCTION BitXor (long1,long2: LongInt): LongInt; 16 | FUNCTION BitNot (long: LongInt): LongInt; 17 | FUNCTION BitShift (long: LongInt; count: INTEGER): LongInt; 18 | FUNCTION BitTst (bytePtr: QDPtr; bitNum: LongInt): BOOLEAN; 19 | PROCEDURE BitSet (bytePtr: QDPtr; bitNum: LongInt); 20 | PROCEDURE BitClr (bytePtr: QDPtr; bitNum: LongInt); 21 | PROCEDURE LongMul (a,b: LongInt; VAR dst: Int64Bit); 22 | FUNCTION FixMul (a,b: Fixed): Fixed; 23 | FUNCTION FixRatio (numer,denom: INTEGER): Fixed; 24 | FUNCTION HiWord (x: Fixed): INTEGER; 25 | FUNCTION LoWord (x: Fixed): INTEGER; 26 | FUNCTION FixRound (x: Fixed): INTEGER; 27 | 28 | 29 | IMPLEMENTATION 30 | 31 | FUNCTION BitAnd; EXTERNAL; 32 | FUNCTION BitOr; EXTERNAL; 33 | FUNCTION BitXor; EXTERNAL; 34 | FUNCTION BitNot; EXTERNAL; 35 | FUNCTION BitShift; EXTERNAL; 36 | FUNCTION BitTst; EXTERNAL; 37 | PROCEDURE BitSet; EXTERNAL; 38 | PROCEDURE BitClr; EXTERNAL; 39 | PROCEDURE LongMul; EXTERNAL; 40 | FUNCTION FixMul; EXTERNAL; 41 | FUNCTION FixRatio; EXTERNAL; 42 | FUNCTION HiWord; EXTERNAL; 43 | FUNCTION LoWord; EXTERNAL; 44 | FUNCTION FixRound; EXTERNAL; 45 | 46 | 47 | END. { of unit } 48 | -------------------------------------------------------------------------------- /LCursor.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | 3 | ;------------------------------------------------------------------ 4 | ; 5 | ; --> LCURSOR.TEXT 6 | ; 7 | ; Links to MacIntosh Cursor routines. 8 | ; 9 | ; System Graphic Jump Vectors: 10 | ; 11 | ; Long pointers to system routine entry points. 12 | ; 13 | GRAFBEGIN .EQU $800 ;GRAF GLOBAL AREA 14 | JHIDECURSOR .EQU GRAFBEGIN 15 | JSHOWCURSOR .EQU JHIDECURSOR+4 16 | JSHIELDCURSOR .EQU JSHOWCURSOR+4 17 | JSCRNADDR .EQU JSHIELDCURSOR+4 ;not used (see _GetScrnBits) 18 | JSCRNSIZE .EQU JSCRNADDR+4 ;not used (see _GetScrnBits) 19 | JINITCRSR .EQU JSCRNSIZE+4 20 | JSETCRSR .EQU JINITCRSR+4 21 | JCRSROBSCURE .EQU JSETCRSR+4 22 | 23 | 24 | 25 | 26 | .PROC InitCursor,0 27 | .REF SetCursor 28 | ;---------------------------------------------------------- 29 | ; 30 | ; PROCEDURE InitCursor; 31 | ; 32 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 33 | PEA ARROW(A0) ;PUSH ADDR OF ARROW 34 | JSR SETCURSOR ;INSTALL ARROW CURSOR 35 | MOVE.L JInitCrsr,A0 ;get lo mem pointer 36 | JMP (A0) ;and call it 37 | 38 | 39 | 40 | .PROC SetCursor,1 41 | ;--------------------------------------------------- 42 | ; 43 | ; PROCEDURE SetCursor(crsr: Cursor); 44 | ; 45 | MOVE.L 4(SP),A0 ;Point to Cursor 46 | MOVE.L HOTSPOT+V(A0),-(SP) ;PUSH HOTX & HOTY 47 | MOVE #16,-(SP) ;HEIGHT:=16 48 | PEA DATA(A0) ;PUSH ADDR OF DATA 49 | PEA MASK(A0) ;PUSH ADDR OF MASK 50 | MOVE.L JSetCrsr,A0 ;get lo mem vector 51 | JSR (A0) ;call vector 52 | MOVE.L (SP)+,(SP) ;strip param 53 | RTS ;and return 54 | 55 | 56 | 57 | .PROC HideCursor,0 58 | ;--------------------------------------------------------- 59 | ; 60 | ; PROCEDURE HideCursor; 61 | ; 62 | ; ALL REGS PRESERVED. 63 | ; 64 | MOVE.L JHideCursor,-(SP) ;get lo mem vector 65 | RTS ;and call it 66 | 67 | 68 | 69 | .PROC ShowCursor,0 70 | ;--------------------------------------------------------- 71 | ; 72 | ; PROCEDURE ShowCursor; 73 | ; 74 | ; ALL REGS PRESERVED. 75 | ; 76 | MOVE.L JShowCursor,-(SP) ;get lo mem vector 77 | RTS ;and call it 78 | 79 | 80 | 81 | .PROC ShieldCursor,2 82 | ;--------------------------------------------------------- 83 | ; 84 | ; PROCEDURE ShieldCursor(shieldRect: Rect; offset: Point); 85 | ; 86 | ; ALL REGS PRESERVED. 87 | ; 88 | MOVEM.L D0-D3/A0-A1,-(SP) ;SAVE REGS 89 | MOVE.L 32(SP),A0 ;POINT TO SHIELDRECT 90 | MOVEM.W (A0)+,D0/D1/D2/D3 ;GET TOP ... RIGHT 91 | LEA 28(SP),A1 92 | SUB (A1),D0 ;TOP - OFFSET.V 93 | SUB (A1)+,D2 ;BOTTOM - OFFSET.V 94 | SUB (A1),D1 ;LEFT - OFFSET.H 95 | SUB (A1),D3 ;RIGHT - OFFSET.H 96 | MOVE D1,-(SP) ;PUSH GLOBAL LEFT 97 | MOVE D0,-(SP) ;PUSH GLOBAL TOP 98 | MOVE D3,-(SP) ;PUSH GLOBAL RIGHT 99 | MOVE D2,-(SP) ;PUSH GLOBAL BOTTOM 100 | MOVE.L JShieldCursor,A0 ;get lo mem vector 101 | JSR (A0) ;and call it 102 | MOVEM.L (SP)+,D0-D3/A0-A1 ;RESTORE REGS 103 | MOVE.L (SP)+,(SP) 104 | MOVE.L (SP)+,(SP) ;STRIP 8 BYTES 105 | RTS ;AND RETURN 106 | 107 | 108 | 109 | .PROC ObscureCursor,0 110 | ;--------------------------------------------------------- 111 | ; 112 | ; PROCEDURE ObscureCursor; 113 | ; 114 | ; Hide the cursor image until the next time the mouse moves. 115 | ; 116 | MOVE.L JCrsrObscure,A0 ;get lo mem vector 117 | JMP (A0) ;and call it 118 | 119 | 120 | 121 | 122 | .END 123 | -------------------------------------------------------------------------------- /Lines.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;----------------------------------------------------------------- 3 | ; 4 | ; 5 | ; * *** * * ***** *** 6 | ; * * * * * * * 7 | ; * * ** * * * 8 | ; * * * * * *** *** 9 | ; * * * ** * * 10 | ; * * * * * * * 11 | ; ***** *** * * ***** *** 12 | ; 13 | ; 14 | ; 15 | ; Line Drawing Rountines 16 | ; 17 | 18 | 19 | .PROC StdLine,1 20 | .REF CheckPic,PutPicVerb,PutPicByte,PutPicLong,DoLine 21 | ;--------------------------------------------------------------- 22 | ; 23 | ; PROCEDURE StdLine(newPt: Point); 24 | ; 25 | PARAMSIZE .EQU 4 26 | NEWPT .EQU PARAMSIZE+8-4 27 | 28 | LINK A6,#0 ;NO LOCAL VARS 29 | MOVEM.L D5-D7/A3-A4,-(SP) ;SAVE REGS 30 | JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE 31 | BLE.S NOTPIC ;BRANCH IF NOT PICSAVE 32 | 33 | MOVE.B #FRAME,-(SP) ;PUSH VERB 34 | JSR PutPicVerb ;CHECK pnSize, pnMode, pnPat 35 | 36 | ;-------------------------------------------------------- 37 | ; 38 | ; PUT ONE OF FOUR LINE OPCODES BASED ON NEWPT AND DH,DV. 39 | ; 40 | ; line 20, pnLoc(pt), newPt(pt) 41 | ; line from 21, newPt(pt) 42 | ; short line 22, pnLoc(pt), dh,dv(-128..127) 43 | ; short line from 23, dh,dv(-128..127) 44 | ; 45 | 46 | MOVEQ #$20,D7 ;INIT OPCODE TO $20 47 | MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE 48 | MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE 49 | MOVE.L PNLOC(A3),D0 ;GET CURRENT PNLOC 50 | CMP.L PICPNLOC(A4),D0 ;IS LINE FROM LAST ENDPOINT ? 51 | BNE.S NOTFROM ;NO, CONTINUE 52 | ADDQ #1,D7 ;YES, SET BIT ZERO 53 | NOTFROM MOVE NEWPT+H(A6),D6 ;GET NEWPT.H 54 | SUB D0,D6 ;CALC DH = NEWPT.H - PNLOC.H 55 | MOVE D6,D0 ;COPY DH 56 | EXT.W D0 57 | CMP.W D6,D0 ;IS DH -128..127 ? 58 | BNE.S PUTOP ;NO, CONTINUE 59 | 60 | MOVE NEWPT+V(A6),D5 ;GET NEWPT.V 61 | SUB PNLOC+V(A3),D5 ;CALC DV = NEWPT.V - PNLOC.V 62 | MOVE D5,D0 ;COPY DV 63 | EXT.W D0 64 | CMP.W D5,D0 ;IS DV -128..127 ? 65 | BNE.S PUTOP ;NO, CONTINUE 66 | ADDQ #2,D7 ;YES, SET BIT ONE IN OPCODE 67 | 68 | PUTOP MOVE.B D7,-(SP) 69 | JSR PutPicByte ;PUT ONE OF 4 LINE OPCODES 70 | ROR #1,D7 ;DO WE NEED STARTPT ? (BIT 0) 71 | BCS.S STARTOK ;NO, CONTINUE 72 | MOVE.L PNLOC(A3),-(SP) 73 | JSR PutPicLong ;YES, PUT STARTPT = PNLOC 74 | 75 | STARTOK ROR #1,D7 ;IS LINE SHORT ? (BIT 1) 76 | BCS.S DHDV ;YES, PUT DH,DV 77 | MOVE.L NEWPT(A6),-(SP) ;NO, PUT LONG NEWPT 78 | JSR PutPicLong ;PUT NEWPT TO THEPIC 79 | BRA.S UPDATE 80 | 81 | DHDV MOVE.B D6,-(SP) ;PUSH DH (-128..127) 82 | JSR PutPicByte ;PUT TO THEPIC 83 | MOVE.B D5,-(SP) ;PUSH DV (-128..127) 84 | JSR PutPicByte ;PUT TO THEPIC 85 | 86 | UPDATE MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE 87 | MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE 88 | MOVE.L NEWPT(A6),PICPNLOC(A4) ;UPDATE PICTURE SAVING STATE 89 | 90 | NOTPIC MOVE.L NEWPT(A6),-(SP) ;PUSH NEWPT 91 | JSR DoLine ;DoLine(newPt); 92 | MOVEM.L (SP)+,D5-D7/A3-A4 ;RESTORE REGS 93 | UNLINK PARAMSIZE,'STDLINE ' 94 | 95 | 96 | 97 | .PROC LineTo,2 98 | .REF StdLine 99 | ;---------------------------------------------------------- 100 | ; 101 | ; PROCEDURE LineTo(h,v: INTEGER); 102 | ; 103 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 104 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 105 | MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ? 106 | LEA STDLINE,A0 107 | BEQ.S USESTD ;YES, USE STD PROC 108 | MOVE.L D0,A0 109 | MOVE.L LINEPROC(A0),A0 ;NO, GET PROC PTR 110 | USESTD JMP (A0) ;GO TO IT 111 | 112 | 113 | .PROC Line,2 114 | .REF LineTo 115 | ;---------------------------------------------------------- 116 | ; 117 | ; PROCEDURE Line(dh,dv: INTEGER); 118 | ; 119 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 120 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 121 | MOVE PNLOC+H(A0),D0 ;GET CURRENT PENLOC.H 122 | ADD D0,6(SP) ;ADD TO DH 123 | MOVE PNLOC+V(A0),D0 ;GET CURRENT PENLOC.V 124 | ADD D0,4(SP) ;ADD TO DV 125 | JMP LineTo ;LineTo(pnLoc.h+dh,pnLoc.v+dv); 126 | 127 | 128 | 129 | .PROC MoveTo,2 130 | ;---------------------------------------------------------- 131 | ; 132 | ; PROCEDURE MoveTo(h,v: INTEGER); 133 | ; 134 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 135 | MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS 136 | MOVE.L THEPORT(A1),A1 ;POINT TO CURRENT GRAFPORT 137 | MOVE.L (SP)+,PNLOC(A1) ;COPY POINT INTO PNLOC 138 | JMP (A0) ;RETURN 139 | 140 | 141 | 142 | .PROC MQVE,2 143 | .DEF Moov 144 | ;---------------------------------------------------------- 145 | ; 146 | ; PROCEDURE Move(dh,dv: INTEGER); 147 | ; 148 | MOOV MOVE.L (SP)+,A0 ;POP RETURN ADDR 149 | MOVE (SP)+,D0 ;POP DV 150 | MOVE (SP)+,D1 ;POP DH 151 | MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QUICKDRAW GLOBALS 152 | MOVE.L THEPORT(A1),A1 ;GET CURRENT GRAFPORT 153 | ADD D0,PNLOC+V(A1) ;ADD DV TO PNLOC.V 154 | ADD D1,PNLOC+H(A1) ;ADD DH TO PNLOC.H 155 | JMP (A0) ;RETURN 156 | 157 | 158 | 159 | .PROC DoLine,1 160 | .REF DrawLine,PutLine,SetSize 161 | ;---------------------------------------------------------- 162 | ; 163 | ; PROCEDURE DoLine(newPt: Point); 164 | ; 165 | ; { called by StdLine and StdPoly frame } 166 | ; 167 | MOVEM.L D6-D7/A3-A4,-(SP) ;SAVE REGS 168 | MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS 169 | MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT 170 | MOVE.L 20(SP),D7 ;GET NEWPT 171 | MOVE.L PNLOC(A3),D6 ;OLDPT := THEPORT^.PNLOC 172 | ; 173 | ; CHECK IF WE ARE SAVING FOR A POLYGON 174 | ; 175 | TST.L POLYSAVE(A3) ;ARE WE SAVING FOR A POLYGON ? 176 | BEQ.S NOTPOLY ;NO, CONTINUE 177 | MOVE.L THEPOLY(A4),A1 ;YES, GET POLYHANDLE 178 | MOVE.L (A1),A0 ;DE-REFERENCE IT 179 | MOVE (A0),D0 ;GET CURRENT POLYSIZE 180 | CMP #10,D0 ;IS THIS THE FIRST POINT ? 181 | BNE.S FIRSTOK ;NO, CONTINUE 182 | MOVE.L D6,0(A0,D0) ;YES, INSTALL FIRST := OLDPT 183 | ADD #4,D0 ;BUMP INDEX 184 | FIRSTOK MOVE.L D7,0(A0,D0) ;INSTALL NEWPT AT END 185 | ADD #4,D0 ;BUMP INDEX 186 | MOVE D0,(A0) ;UPDATE INDEX 187 | CMP POLYMAX(A4),D0 ;TIME TO MAKE BIGGER ? 188 | BLT.S SIZEOK ;NO, CONTINUE 189 | ADD #256,POLYMAX(A4) ;YES, GROW IN CHUNKS 190 | MOVE.L A1,-(SP) ;PUSH POLYHANDLE 191 | MOVE POLYMAX(A4),-(SP) ;PUSH NEW SIZE 192 | JSR SETSIZE ;MAKE THEPOLY BIGGER 193 | SIZEOK BRA.S NOTRGN ;DONT SAVE FOR RGN TOO 194 | ; 195 | ; IF NOT POLY, THEN CHECK FOR RGNSAVE. 196 | ; IF RGNSAVE THEN PutLine(oldPt,newPt,rgnBuf,rgnIndex,rgnMax); 197 | ; 198 | NOTPOLY TST.L RGNSAVE(A3) ;ARE WE SAVING FOR A REGION ? 199 | BEQ.S NOTRGN 200 | MOVE.L D6,-(SP) ;PUSH OLDPT 201 | MOVE.L D7,-(SP) ;PUSH NEWPT 202 | MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF 203 | PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX 204 | PEA RGNMAX(A4) ;PUSH VAR RGNMAX 205 | JSR PUTLINE ;ADD INVERSION PTS TO RGNBUF 206 | 207 | NOTRGN MOVE.L D6,-(SP) ;PUSH OLDPT 208 | MOVE.L D7,-(SP) ;PUSH NEWPT 209 | JSR DRAWLINE ;DRAW THE LINE 210 | MOVE.L D7,PNLOC(A3) ;UPDATE THEPORT^.PNLOC 211 | MOVEM.L (SP)+,D6-D7/A3-A4 ;RESTORE REGS 212 | MOVE.L (SP)+,(SP) ;STRIP PARAM 213 | RTS ;AND RETURN 214 | 215 | 216 | 217 | .PROC HidePen,0 218 | .DEF ShowPen 219 | ;---------------------------------------------------------- 220 | ; 221 | ; PROCEDURE HidePen; 222 | ; 223 | MOVEQ #-1,D0 224 | BRA.S SHARE 225 | 226 | 227 | 228 | ;---------------------------------------------------------- 229 | ; 230 | ; PROCEDURE ShowPen; 231 | ; 232 | ShowPen MOVEQ #1,D0 233 | SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 234 | MOVE.L THEPORT(A0),A0 ;GET CURRENT PORT 235 | ADD D0,PNVIS(A0) ;INCREMENT/DECREMENT PNVIS 236 | RTS ;AND RETURN 237 | 238 | 239 | 240 | .PROC GetPenState,1 241 | .DEF SetPenState 242 | ;---------------------------------------------------------- 243 | ; 244 | ; PROCEDURE GetPenState(VAR pnState: PenState); 245 | ; PROCEDURE SetPenState(pnState: PenState); 246 | ; 247 | MOVEQ #1,D0 ;SET A FLAG 248 | BRA.S SHARE ;AND SHARE CODE 249 | 250 | SetPenState 251 | CLR D0 ;CLEAR FLAG AND SHARE 252 | 253 | SHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 254 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 255 | LEA PNLOC(A0),A0 ;POINT TO PNLOC 256 | MOVE.L 4(SP),A1 ;POINT TO VAR PNSTATE 257 | TST D0 ;is this SET penstate ? 258 | BNE.S NOTSET ;NO, CONTINUE 259 | EXG A0,A1 ;YES, SWAP SRC AND DST 260 | 261 | NOTSET MOVE.L (A0)+,(A1)+ ;COPY PNLOC FROM THEPORT 262 | MOVE.L (A0)+,(A1)+ ;COPY PNSIZE FROM THEPORT 263 | MOVE.W (A0)+,(A1)+ ;COPY PNMODE FROM THEPORT 264 | MOVE.L (A0)+,(A1)+ ;COPY PNPAT FROM THEPORT 265 | MOVE.L (A0)+,(A1)+ ;ALL 8 BYTES 266 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 267 | RTS ;AND RETURN 268 | 269 | 270 | 271 | .PROC GetPen,1 272 | ;---------------------------------------------------------- 273 | ; 274 | ; PROCEDURE GetPen(VAR pt: Point); 275 | ; { inquire the current pen location } 276 | ; 277 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 278 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 279 | MOVE.L 4(SP),A1 ;POINT TO VAR PT 280 | MOVE.L PNLOC(A0),(A1) ;GET PNLOC FROM THEPORT 281 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 282 | RTS ;AND RETURN 283 | 284 | 285 | 286 | .PROC PenSize,2 287 | ;---------------------------------------------------------- 288 | ; 289 | ; PROCEDURE PenSize(width,height: INTEGER); 290 | ; { set the pen width and height } 291 | ; 292 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 293 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 294 | MOVE.L 4(SP),PNSIZE(A0) ;SET PEN WIDTH AND HEIGHT 295 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 296 | RTS ;AND RETURN 297 | 298 | 299 | 300 | .PROC PenMode,1 301 | .REF PortWord 302 | ;---------------------------------------------------------- 303 | ; 304 | ; PROCEDURE PenMode(mode: INTEGER); 305 | ; { set the transfer mode for line drawing } 306 | ; 307 | MOVEQ #PNMODE,D0 ;PUT PORT OFFSET IN D0 308 | JMP PORTWORD ;INSTALL PARAM INTO THEPORT 309 | 310 | 311 | 312 | .PROC PenPat,1 313 | ;---------------------------------------------------------- 314 | ; 315 | ; PROCEDURE PenPat(pat: Pattern); 316 | ; { set the pattern for line drawing } 317 | ; 318 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 319 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 320 | LEA PNPAT(A0),A0 ;POINT TO PNPAT 321 | MOVE.L 4(SP),A1 ;POINT TO INPUT PATTERN 322 | MOVE.L (A1)+,(A0)+ ;COPY PATTERN INTO THEPORT 323 | MOVE.L (A1)+,(A0)+ ;ALL 8 BYTES 324 | MOVE.L (SP)+,(SP) ;STRIP 4 BYTES 325 | RTS ;AND RETURN 326 | 327 | 328 | 329 | .PROC PenNormal,0 330 | ;---------------------------------------------------------- 331 | ; 332 | ; PROCEDURE PenNormal; 333 | ; { restore all line drawing parameters to normal } 334 | ; 335 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 336 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 337 | MOVE.L #$00010001,PNSIZE(A0) ;PEN SIZE:=1,1 338 | MOVE #8,PNMODE(A0) ;PENMODE:=PATTERN COPY 339 | MOVEQ #-1,D0 340 | MOVE.L D0,PNPAT(A0) ;PNPAT:=BLACK 341 | MOVE.L D0,PNPAT+4(A0) 342 | RTS 343 | 344 | 345 | 346 | 347 | .END 348 | -------------------------------------------------------------------------------- /Ovals.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;----------------------------------------------------------- 3 | ; 4 | ; 5 | ; *** * * * * *** 6 | ; * * * * * * * * * 7 | ; * * * * * * * * 8 | ; * * * * * * * *** 9 | ; * * * * ***** * * 10 | ; * * * * * * * * * 11 | ; *** * * * ***** *** 12 | ; 13 | ; 14 | ; 15 | .PROC StdOval,2 16 | .REF CheckPic,PutPicVerb,PutPicRect 17 | .REF PutOval,PushVerb,DrawArc 18 | ;--------------------------------------------------------------- 19 | ; 20 | ; PROCEDURE StdOval(verb: GrafVerb; r: Rect); 21 | ; 22 | ; A6 OFFSETS OF PARAMS AFTER LINK: 23 | ; 24 | PARAMSIZE .EQU 6 25 | VERB .EQU PARAMSIZE+8-2 ;GRAFVERB 26 | RECT .EQU VERB-4 ;LONG, ADDR OF RECT 27 | 28 | OVWD .EQU -2 ;WORD 29 | OVHT .EQU OVWD-2 ;WORD 30 | VARSIZE .EQU OVHT ;TOTAL BYTES OF LOCALS 31 | 32 | 33 | LINK A6,#VARSIZE ;ALLOCATE STACK FRAME 34 | MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS 35 | MOVE.B VERB(A6),D7 ;GET VERB 36 | JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE 37 | BLE.S NOTPIC ;BRANCH IF NOT PICSAVE 38 | 39 | MOVE.B D7,-(SP) 40 | JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC 41 | MOVEQ #$50,D0 ;PUT OVALNOUN IN HI NIBBLE 42 | ADD D7,D0 ;PUT VERB IN LO NIBBLE 43 | MOVE.B D0,-(SP) ;PUSH OPCODE 44 | MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT 45 | JSR PutPicRect ;PUT OPCODE AND RECTANGLE 46 | 47 | NOTPIC MOVE.L RECT(A6),A0 ;POINT TO RECT 48 | MOVE RIGHT(A0),D0 49 | SUB LEFT(A0),D0 50 | MOVE D0,OVWD(A6) ;OVWD := R.RIGHT - R.LEFT 51 | MOVE BOTTOM(A0),D0 52 | SUB TOP(A0),D0 53 | MOVE D0,OVHT(A6) ;OVHT := R.BOTTOM - R.TOP 54 | 55 | MOVE.L A0,-(SP) ;PUSH ADDR OF RECT 56 | TST.B D7 ;IS VERB FRAME ? 57 | BNE.S NOTFR ;NO, CONTINUE 58 | TST.L RGNSAVE(A3) ;YES, IS RGNSAVE TRUE ? 59 | BEQ.S NOTRGN ;NO, CONTINUE 60 | 61 | MOVE.L A0,-(SP) ;YES, PUSH ADDR OF RECT 62 | MOVE.L OVHT(A6),-(SP) ;PUSH OVWD, OVHT 63 | MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF 64 | PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX 65 | PEA RGNMAX(A4) ;PUSH VAR RGNMAX 66 | JSR PutOval ;ADD AN OVAL TO THERGN 67 | 68 | NOTRGN MOVE.B #1,-(SP) ;PUSH HOLLOW = TRUE 69 | BRA.S DOIT 70 | NOTFR CLR.B -(SP) ;PUSH HOLLOW = FALSE 71 | DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT 72 | JSR PushVerb ;PUSH MODE AND PATTERN 73 | CLR -(SP) ;PUSH STARTANGLE = 0 74 | MOVE #360,-(SP) ;PUSH ARCANGLE = 360 75 | 76 | ; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng); 77 | 78 | JSR DrawArc 79 | MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS 80 | UNLINK PARAMSIZE,'STDOVAL ' 81 | 82 | 83 | 84 | .PROC FrameOval,1 85 | .DEF CallOval,PaintOval,EraseOval,InvertOval,FillOval 86 | .REF StdOval 87 | ;----------------------------------------------------- 88 | ; 89 | ; PROCEDURE FrameOval(* r: Rect *); 90 | ; 91 | MOVEQ #FRAME,D0 ;VERB = FRAME 92 | BRA.S CallOval ;SHARE COMMON CODE 93 | 94 | 95 | ;----------------------------------------------------- 96 | ; 97 | ; PROCEDURE PaintOval(* r: Rect *); 98 | ; 99 | PaintOval 100 | MOVEQ #PAINT,D0 ;VERB = PAINT 101 | BRA.S CallOval ;SHARE COMMON CODE 102 | 103 | 104 | ;-------------------------------------------------------- 105 | ; 106 | ; PROCEDURE EraseOval(* r: Rect *); 107 | ; 108 | EraseOval 109 | MOVEQ #ERASE,D0 ;VERB = ERASE 110 | BRA.S CallOval ;SHARE COMMON CODE 111 | 112 | 113 | ;-------------------------------------------------------- 114 | ; 115 | ; PROCEDURE InvertOval(* r: Rect *); 116 | ; 117 | InvertOval 118 | MOVEQ #INVERT,D0 ;VERB = INVERT 119 | BRA.S CallOval ;SHARE COMMON CODE 120 | 121 | 122 | ;-------------------------------------------------------- 123 | ; 124 | ; PROCEDURE FillOval(* r: Rect; pat: Pattern *); 125 | ; 126 | FillOval 127 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 128 | MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN 129 | MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK 130 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 131 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 132 | LEA FILLPAT(A0),A0 ;POINT TO FILLPAT 133 | MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT 134 | MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES 135 | MOVEQ #FILL,D0 ;VERB = FILL 136 | BRA.S CallOval ;SHARE COMMON CODE 137 | 138 | 139 | 140 | ;--------------------------------------------------------------- 141 | ; 142 | ; PROCEDURE CallOval(r: Rect); 143 | ; 144 | ; code shared by FrameOval, PaintOval, EraseOval, InvertOval, and FillOval. 145 | ; enter with verb in D0. 146 | ; 147 | CallOval 148 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 149 | MOVE.L (SP)+,A1 ;POP ADDR OF RECT 150 | MOVE.B D0,-(SP) ;PUSH VERB 151 | MOVE.L A1,-(SP) ;PUSH ADDR OF RECT 152 | MOVE.L A0,-(SP) ;RESTORE RETURN ADDR 153 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 154 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 155 | MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ? 156 | LEA STDOVAL,A0 157 | BEQ.S USESTD ;YES, USE STD PROC 158 | MOVE.L D0,A0 159 | MOVE.L OVALPROC(A0),A0 ;NO, GET PROC PTR 160 | USESTD JMP (A0) ;GO TO IT 161 | 162 | 163 | .END 164 | -------------------------------------------------------------------------------- /PackRgn.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | 3 | 4 | .PROC PACKRGN,3 5 | .REF SETSIZE 6 | ;----------------------------------------------------------------- 7 | ; 8 | ; PROCEDURE PackRgn(srcHandle: Handle; nPoints: INTEGER; dstRgn: RgnHandle); 9 | ; 10 | ; Converts a sorted array of inversion points into a region. 11 | ; Calls storage allocator to make more room and trim result to minimum size. 12 | ; 13 | ; OUTPUT IS IN THE FOLLOWING FORM: 14 | ; 15 | ; RGNSIZE 16 | ; RGNBBOX 17 | ; V H .. H 32767 18 | ; V H .. H 32767 19 | ; V=32767 20 | ; 21 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 22 | ; 23 | PARAMSIZE .EQU 10 ;TOTAL BYTES OF PARAMS 24 | SRCHANDLE .EQU PARAMSIZE+8-4 ;LONG 25 | NPOINTS .EQU SRCHANDLE-2 ;INTEGER 26 | DSTRGN .EQU NPOINTS-4 ;LONG, HANDLE 27 | 28 | 29 | ;------------------------------------------------------- 30 | ; 31 | ; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK: 32 | ; 33 | BBOX .EQU -8 ;RECTANGLE 34 | VARSIZE .EQU BBOX ;SIZE OF LOCAL VARIABLES 35 | 36 | 37 | LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES 38 | MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS 39 | MOVE.L SRCHANDLE(A6),A4 ;GET SRC HANDLE 40 | MOVE.L DSTRGN(A6),A3 ;GET DST RGNHANDLE 41 | MOVE NPOINTS(A6),D6 ;GET NUMBER OF POINTS 42 | MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN 43 | MOVE RGNSIZE(A1),D5 ;GET CURRENT RGNSIZE 44 | MOVE.L (A4),A0 ;DE-REFERENCE SRCHANDLE 45 | 46 | 47 | ;------------------------------------------------------------------------ 48 | ; 49 | ; CHECK NPOINTS TO SPECIAL CASE EMPTY AND RECTANGULAR REGIONS. 50 | ; 51 | MOVEQ #10,D7 ;INIT RGNSIZE TO EMPTY RGN SIZE 52 | CLR.L BBOX+TOPLEFT(A6) ;INIT BOUNDING BOX TO EMPTY 53 | CLR.L BBOX+BOTRIGHT(A6) 54 | CMP #4,D6 ;HOW MANY POINTS IN SOURCE ? 55 | BGT.S NOTRECT ;MORE THAN 4, NOT RECTANGULAR 56 | BLT.S DONE ;LESS THAN 4, EMPTY REGION 57 | MOVE.L 0(A0),BBOX+TOPLEFT(A6) ;GET TOPLEFT OF BOUNDING BOX 58 | MOVE.L 12(A0),BBOX+BOTRIGHT(A6) ;GET BOTRIGHT OF BOUNDING BOX 59 | BRA.S DONE ;INSTALL RGNSIZE AND BBOX AND QUIT 60 | 61 | 62 | ;------------------------------------------------------------------------ 63 | ; 64 | ; MORE THAN FOUR POINTS, NON-RECTANGULAR. SCAN FOR BBOX LEFT AND RIGHT. 65 | ; 66 | NOTRECT MOVE V(A0),BBOX+TOP(A6) ;BBOX TOP:=FIRST POINT.V 67 | MOVE H(A0),D1 ;INIT MINH TO FIRST HORIZ 68 | MOVE D1,D2 ;INIT MAXH TO FIRST HORIZ ALSO 69 | MOVE D6,D3 ;GET NUMPER OF POINTS IN SRC 70 | SCAN SUB #1,D3 ;ANY POINTS LEFT ? 71 | BLT.S ENDSCAN ;NO, QUIT SCANNING 72 | MOVE.L (A0)+,D0 ;YES, GET NEXT POINT 73 | CMP.W D1,D0 ;IS PT.H < MINH ? 74 | BGE.S LEFTOK ;NO, CONTINUE 75 | MOVE D0,D1 ;YES, MINH:=PT.H 76 | BRA SCAN ;LOOP FOR MORE 77 | 78 | LEFTOK CMP.W D2,D0 ;IS PT.H > MAXH ? 79 | BLE SCAN ;NO, GO FOR NEXT 80 | MOVE D0,D2 ;YES, MAXH:=PT.H 81 | BRA SCAN ;GO FOR NEXT 82 | 83 | ENDSCAN MOVE D1,BBOX+LEFT(A6) ;BBOX LEFT:=MINH 84 | MOVE D2,BBOX+RIGHT(A6) ;BBOX RIGHT:=MAXH 85 | MOVE -4+V(A0),BBOX+BOTTOM(A6) ;BBOX BOTTOM:=LAST POINT.V 86 | 87 | 88 | ;---------------------------------------------------------------- 89 | ; 90 | ; EXPAND DSTRGN TO HOLD WORST CASE = 12 + 4*NPOINTS bytes. 91 | ; 92 | MOVEQ #3,D5 93 | ADD D6,D5 ;GET NPOINTS + 3 94 | LSL #2,D5 ;TIMES 4 95 | MOVE.L A3,-(SP) ;PUSH DSTRGN 96 | MOVE D5,-(SP) ;PUSH NEW BYTECOUNT 97 | JSR SetSize ;MAKE IT THAT BIG 98 | 99 | 100 | ;---------------------------------------------------- 101 | ; 102 | ; NEWLY DE-REFERENCE SRC AND DST HANDLES 103 | ; 104 | MOVE.L (A4),A0 ;DE-REFERENCE SRC HANDLE 105 | MOVE.L (A3),A1 ;DE-REFERENCE DSTRGN HANDLE 106 | ADD D7,A1 ;SKIP OVER RGNSIZE & BBOX 107 | 108 | SUB #1,D6 ;DBRA COUNT = NPOINTS - 1 109 | MOVE (A0)+,D0 ;GET FIRST VERT COORD 110 | MOVE #32767,D1 111 | BRA.S START ;GO TO LOOP START 112 | 113 | NEXTPT CMP (A0)+,D0 ;SAME VERT COORD ? 114 | BEQ.S VSAME ;YES, CONTINUE 115 | MOVE D1,(A1)+ ;PUT END OF ROW MARKER 116 | MOVE -2(A0),D0 ;GET NEW VERT COORD 117 | START MOVE D0,(A1)+ ;PUT VERT COORD 118 | VSAME MOVE (A0)+,(A1)+ ;PUT HORIZ COORD 119 | DBRA D6,NEXTPT ;LOOP FOR ALL POINTS 120 | 121 | MOVE D1,(A1)+ ;PUT END OF ROW MARKER 122 | MOVE D1,(A1)+ ;PUT FINAL VERT = 32767 123 | MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE 124 | SUB.L A0,A1 ;SUBTRACT FROM DSTPTR 125 | MOVE.W A1,D7 ;TO COMPUTE RGNSIZE 126 | 127 | 128 | ;-------------------------------------------------------- 129 | ; 130 | ; INSTALL RGNSIZE AND RGNBBOX. 131 | ; 132 | DONE MOVE.L (A3),A0 ;DE-REFERENCE DSTRGN HANDLE 133 | MOVE D7,(A0)+ ;INSTALL RGNSIZE 134 | MOVE.L BBOX+TOPLEFT(A6),(A0)+ ;INSTALL BOUNDING BOX TOPLEFT 135 | MOVE.L BBOX+BOTRIGHT(A6),(A0)+ ;AND BOTRIGHT 136 | 137 | 138 | ;-------------------------------------------------------- 139 | ; 140 | ; TRIM DSTRGN TO EXACT SIZE IF IT ISN'T ALREADY. 141 | ; 142 | CMP D7,D5 ;IS IT ALREADY THE RIGHT SIZE ? 143 | BEQ.S SIZEOK ;YES, SKIP 144 | MOVE.L A3,-(SP) ;PUSH DSTRGN HANDLE 145 | MOVE D7,-(SP) ;PUSH NEW SIZE 146 | JSR SETSIZE 147 | 148 | 149 | ;------------------------------------------------------ 150 | ; 151 | ; CLEAN UP THE STACK AND GO HOME. 152 | ; 153 | SIZEOK MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGISTERS 154 | UNLINK PARAMSIZE,'PACKRGN ' 155 | 156 | 157 | 158 | 159 | .END 160 | -------------------------------------------------------------------------------- /PicFormat.txt: -------------------------------------------------------------------------------- 1 | QUICKDRAW INTERNAL PICTURE FORMAT: 2 | 3 | 4 | OPCODE NAME ADDITIONAL PARAMS TOTAL BYTES 5 | 6 | 00 nop none 1 7 | 01 clipRgn region 1 + region 8 | 02 bkPat pattern 9 9 | 03 txFont font(word) 3 10 | 04 txFace face(byte) 2 11 | 05 txMode mode(word) 3 12 | 06 spExtra extra(fixed Point) 5 13 | 07 pnSize pnSize(point) 5 14 | 08 pnMode mode(word) 3 15 | 09 pnPat pattern 9 16 | 0A thePat pattern 9 17 | 0B ovSize point 5 18 | 0C origin dh(word),dv(word) 5 19 | 0D txSize size(word) 3 20 | 0E fgColor color(long) 4 21 | 0F bkColor color(long) 4 22 | 23 | 10 txRatio numer(pt), denom(pt) 9 24 | 11 picVersion version(byte) 2 25 | 26 | 20 line pnLoc(pt), newPt(pt) 9 27 | 21 line from newPt(pt) 5 28 | 22 short line pnLoc(pt), dh, dv(-128..127) 7 29 | 23 short line from dh, dv(-128..127) 3 30 | 31 | 28 long text: txLoc(pt), count(0..255), text 6 + text 32 | 29 DH text: dh(0..255), count(0..255), text 3 + text 33 | 2A DV text: dv(0..255), count(0..255), text 3 + text 34 | 2B DHDV text: dh,dv(0,..255), count(0..255), text 4 + text 35 | 36 | 30 frameRect rect 9 37 | 31 paintRect rect 9 38 | 32 eraseRect rect 9 39 | 33 invertRect rect 9 40 | 34 fillRect rect 9 41 | 42 | 38 frameSameRect 1 43 | 39 paintSameRect 1 44 | 3A eraseSameRect 1 45 | 3B invertSameRect 1 46 | 3C fillSameRect 1 47 | 48 | 40 frameRRect rect 9 49 | 41 paintRRect rect 9 50 | 42 eraseRRect rect 9 51 | 43 invertRRect rect 9 52 | 44 fillRRect rect 9 53 | 54 | 48 frameSameRRect 1 55 | 49 paintSameRRect 1 56 | 4A eraseSameRRect 1 57 | 4B invertSameRRect 1 58 | 4C fillSameRRect 1 59 | 60 | 50 frameOval rect 9 61 | 51 paintOval rect 9 62 | 52 eraseOval rect 9 63 | 53 invertOval rect 9 64 | 54 fillOval rect 9 65 | 66 | 58 frameSameOval 1 67 | 59 paintSameOval 1 68 | 5A eraseSameOval 1 69 | 5B invertSameOval 1 70 | 5C fillSameOval 1 71 | 72 | 60 frameArc rect 9 73 | 61 paintArc rect 9 74 | 62 eraseArc rect 9 75 | 63 invertArc rect 9 76 | 64 fillArc rect 9 77 | 78 | 68 frameSameArc 1 79 | 69 paintSameArc 1 80 | 6A eraseSameArc 1 81 | 6B invertSameArc 1 82 | 6C fillSameArc 1 83 | 84 | 70 framePoly poly 1 + poly 85 | 71 paintPoly poly 1 + poly 86 | 72 erasePoly poly 1 + poly 87 | 73 invertPoly poly 1 + poly 88 | 74 fillPoly poly 1 + poly 89 | 90 | 78 frameSamePoly (not implemented yet) 91 | 79 paintSamePoly (not implemented yet) 92 | 7A eraseSamePoly (not implemented yet) 93 | 7B invertSamePoly (not implemented yet) 94 | 7C fillSamePoly (not implemented yet) 95 | 96 | 80 frameRgn rgn 1 + region 97 | 81 paintRgn rgn 1 + region 98 | 82 eraseRgn rgn 1 + region 99 | 83 invertRgn rgn 1 + region 100 | 84 fillRgn rgn 1 + region 101 | 102 | 88 frameSameRgn (not implemented yet) 103 | 89 paintSameRgn (not implemented yet) 104 | 8A eraseSameRgn (not implemented yet) 105 | 8B invertSameRgn (not implemented yet) 106 | 8C fillSameRgn (not implemented yet) 107 | 108 | 90 BitsRect rowBytes, bounds, srcRect, dstRect, mode, 109 | byteCount, unpacked bitData 110 | 91 BitsRgn rowBytes, bounds, srcRect, dstRect, mode, 111 | maskRgn, byteCount, unpacked bitData 112 | 98 PackBitsRect rowBytes, bounds, srcRect, dstRect, mode 113 | byteCount, packed bitData 114 | 99 PackBitsRgn rowBytes, bounds, srcRect, dstRect, mode 115 | maskRgn, byteCount, packed bitData 116 | 117 | A0 shortComment kind(word) 3 118 | A1 longComment kind(word) size(word) data 5 + data 119 | 120 | FF endOfPicture 121 | -------------------------------------------------------------------------------- /Polygons.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;-------------------------------------------------------------- 3 | ; 4 | ; 5 | ; **** *** * * * *** *** * * *** 6 | ; * * * * * * * * * * * * * * * 7 | ; * * * * * * * * * ** * * 8 | ; **** * * * * * ** * * * * * *** 9 | ; * * * * * * * * * * ** * 10 | ; * * * * * * * * * * * * * 11 | ; * *** ***** * *** *** * * *** 12 | ; 13 | ; 14 | 15 | .PROC StdPoly,2 16 | .REF CheckPic,PutPicVerb,DPutPicByte,PutPicRgn 17 | .REF PushVerb,FrPoly,RSect,DrawPoly 18 | ;--------------------------------------------------------------- 19 | ; 20 | ; PROCEDURE StdPoly(verb: GrafVerb; poly: PolyHandle); 21 | ; 22 | ; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK: 23 | ; 24 | PARAMSIZE .EQU 6 25 | VERB .EQU PARAMSIZE+8-2 ;GRAFVERB 26 | POLY .EQU VERB-4 ;LONG, PolyHandle 27 | 28 | MINRECT .EQU -8 ;RECT 29 | VARSIZE .EQU MINRECT ;TOTAL BYTES OF LOCALS 30 | 31 | 32 | LINK A6,#VARSIZE ;ALLOCATE STACK FRAME 33 | MOVEM.L D5-D7/A2-A4,-(SP) ;SAVE REGS 34 | MOVE.B VERB(A6),D7 ;GET VERB 35 | JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE 36 | BLE.S NOTPIC ;BRANCH IF NOT PICSAVE 37 | 38 | MOVE.B D7,-(SP) 39 | JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC 40 | MOVEQ #$70,D0 ;PUT POLYNOUN IN HI NIBBLE 41 | ADD D7,D0 ;PUT VERB IN LO NIBBLE 42 | JSR DPutPicByte ;PUT OPCODE TO THEPIC 43 | MOVE.L POLY(A6),-(SP) ;PUSH POLYHANDLE 44 | JSR PutPicRgn ;TREAT SAME AS A REGION 45 | 46 | NOTPIC MOVE.L POLY(A6),A2 ;GET POLYHANDLE 47 | TST.B D7 ;IS VERB FRAME ? 48 | BNE.S NOTFR ;NO, CONTINUE 49 | MOVE.L A2,-(SP) ;PUSH POLYHANDLE 50 | JSR FrPoly ;FrPoly(poly); 51 | BRA.S GOHOME ;AND QUIT 52 | 53 | NOTFR MOVE.L (A2),A0 ;DE-REFERANCE POLYHANDLE 54 | PEA POLYBBOX(A0) ;PUSH POLYBBOX 55 | MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE 56 | MOVE.L (A0),A0 ;DE-REFERENCE HANDLE 57 | PEA RGNBBOX(A0) ;PUSH VISRGN BBOX 58 | MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE 59 | MOVE.L (A0),A0 ;DE-REFERENCE HANDLE 60 | PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX 61 | MOVE #3,-(SP) ;PUSH NRECTS = 3 62 | PEA MINRECT(A6) ;PUT RESULT IN MINRECT 63 | JSR RSECT ;CALC INTERSECTION 64 | BEQ.S GOHOME ;QUIT IF NO INTERSECT 65 | 66 | MOVE.L A2,-(SP) ;PUSH POLYHANDLE 67 | JSR PushVerb ;PUSH MODE AND PATTERN 68 | JSR DrawPoly ;DrawPoly(poly,mode,pat); 69 | 70 | GOHOME MOVEM.L (SP)+,D5-D7/A2-A4 ;RESTORE REGS 71 | UNLINK PARAMSIZE,'STDPOLY ' 72 | 73 | 74 | 75 | .PROC FramePoly,1 76 | .DEF CallPoly,PaintPoly,ErasePoly,InvertPoly,FillPoly 77 | .REF StdPoly 78 | ;----------------------------------------------------- 79 | ; 80 | ; PROCEDURE FramePoly(* poly: PolyHandle *); 81 | ; 82 | MOVEQ #FRAME,D0 ;VERB = FRAME 83 | BRA.S CallPoly ;SHARE COMMON CODE 84 | 85 | 86 | 87 | ;----------------------------------------------------- 88 | ; 89 | ; PROCEDURE PaintPoly(* poly: PolyHandle *); 90 | ; 91 | PaintPoly 92 | MOVEQ #PAINT,D0 ;VERB = PAINT 93 | BRA.S CallPoly ;SHARE COMMON CODE 94 | 95 | 96 | 97 | ;-------------------------------------------------------- 98 | ; 99 | ; PROCEDURE ErasePoly(* poly: PolyHandle *); 100 | ; 101 | ErasePoly 102 | MOVEQ #ERASE,D0 ;VERB = ERASE 103 | BRA.S CallPoly ;SHARE COMMON CODE 104 | 105 | 106 | 107 | ;-------------------------------------------------------- 108 | ; 109 | ; PROCEDURE InvertPoly(* poly: PolyHandle *); 110 | ; 111 | InvertPoly 112 | MOVEQ #INVERT,D0 ;VERB = INVERT 113 | BRA.S CallPoly ;SHARE COMMON CODE 114 | 115 | 116 | 117 | ;-------------------------------------------------------- 118 | ; 119 | ; PROCEDURE FillPoly(* poly: PolyHandle; pat: Pattern *); 120 | ; 121 | FillPoly 122 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 123 | MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN 124 | MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK 125 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 126 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 127 | LEA FILLPAT(A0),A0 ;POINT TO FILLPAT 128 | MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT 129 | MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES 130 | MOVEQ #FILL,D0 ;VERB = FILL 131 | BRA.S CallPoly ;SHARE COMMON CODE 132 | 133 | 134 | 135 | ;--------------------------------------------------------------- 136 | ; 137 | ; PROCEDURE CallPoly(poly: PolyHandle); 138 | ; 139 | ; code shared by FramePoly, PaintPoly, ErasePoly, InvertPoly, and FillPoly. 140 | ; enter with verb in D0. 141 | ; 142 | CallPoly 143 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 144 | MOVE.L (SP)+,A1 ;POP POLY 145 | MOVE.B D0,-(SP) ;PUSH VERB 146 | MOVE.L A1,-(SP) ;PUSH POLY 147 | MOVE.L A0,-(SP) ;RESTORE RETURN ADDR 148 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 149 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 150 | MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ? 151 | LEA STDPOLY,A0 152 | BEQ.S USESTD ;YES, USE STD PROC 153 | MOVE.L D0,A0 154 | MOVE.L POLYPROC(A0),A0 ;NO, GET PROC PTR 155 | USESTD JMP (A0) ;GO TO IT 156 | 157 | 158 | 159 | .FUNC OpenPoly,0 160 | .REF HidePen,NewHandle 161 | ;--------------------------------------------------------------- 162 | ; 163 | ; FUNCTION OpenPoly: PolyHandle; 164 | ; 165 | STARTSIZE .EQU 138 ;ENOUGH FOR 32 POINTS 166 | 167 | JSR HidePen ;TURN OFF DRAWING 168 | CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT 169 | MOVE #STARTSIZE,-(SP) ;PUSH BYTE COUNT = STARTSIZE 170 | JSR NEWHANDLE ;ALLOCATE NEWHANDLE 171 | MOVE.L (SP)+,A1 ;POP RESULTING HANDLE 172 | MOVE.L A1,4(SP) ;PUT HANDLE IN FCN RESULT 173 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 174 | MOVE.L A1,THEPOLY(A0) ;REMEMBER HANDLE IN THEPOLY 175 | MOVE #STARTSIZE,POLYMAX(A0) ;POLYMAX := STARTSIZE; 176 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 177 | MOVEQ #1,D0 178 | MOVE.L D0,POLYSAVE(A0) ;POLYSAVE := TRUE 179 | MOVE.L (A1),A1 ;DE-REFERENCE HANDLE 180 | MOVE #10,(A1)+ ;INSTALL POLYSIZE = 10 181 | CLR.L (A1)+ ;ZERO OUT POLYBBOX 182 | CLR.L (A1)+ 183 | RTS ;RETURN 184 | 185 | 186 | 187 | .PROC ClosePoly,0 188 | .REF SetSize,ShowPen 189 | ;--------------------------------------------------------------- 190 | ; 191 | ; PROCEDURE ClosePoly; 192 | ; 193 | ; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK: 194 | ; 195 | MOVEM.L D3-D7/A4,-(SP) ;SAVE REGS 196 | MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS 197 | MOVE.L THEPORT(A4),A0 ;GET CURRENT GRAFPORT 198 | CLR.L POLYSAVE(A0) ;POLYSAVE := FALSE 199 | MOVE.L THEPOLY(A4),A4 ;GET THEPOLY HANDLE 200 | MOVE.L (A4),A0 ;DE-REFERENCE THEPOLY 201 | MOVE (A0)+,D7 ;GET POLYSIZE 202 | CLR.L (A0)+ ;ZERO OUT POLYBBOX 203 | CLR.L (A0)+ 204 | MOVE D7,D6 205 | SUB #10,D6 206 | LSR #2,D6 ;NPOINTS = (SIZE-10) DIV 4 207 | BEQ.S EMPTY ;QUIT IF NO POINTS 208 | 209 | 210 | ;----------------------------------------------------- 211 | ; 212 | ; SCAN FOR BOUNDING BOX OF POLYGON 213 | ; 214 | MOVE (A0)+,D1 ;TOP := FIRST POINT VERT 215 | MOVE D1,D2 ;BOTTOM := FIRST POINT VERT 216 | MOVE (A0)+,D3 ;LEFT := FIRST POINT HORIZ 217 | MOVE D3,D4 ;RIGHT := FIRST POINT HORIZ 218 | SUB #1,D6 ;DECREMENT POINT COUNT 219 | BRA.S RIGHTOK ;GO TO LOOP START 220 | NEXTPT MOVE (A0)+,D0 ;GET VERT COORD 221 | CMP D1,D0 ;IS VERT < BBOX TOP ? 222 | BGE.S TOPOK ;NO, CONTINUE 223 | MOVE D0,D1 ;YES, UPDATE BBOX TOP 224 | TOPOK CMP D2,D0 ;IS VERT > BBOX BOTTOM ? 225 | BLE.S BOTOK ;NO, CONTINUE 226 | MOVE D0,D2 ;YES, UPDATE BBOX BOTTOM 227 | BOTOK MOVE (A0)+,D0 ;GET HORIZ COORD 228 | CMP D3,D0 ;IS HORIZ < BBOX LEFT ? 229 | BGE.S LEFTOK ;NO, CONTINUE 230 | MOVE D0,D3 ;YES, UPDATE BBOX LEFT 231 | LEFTOK CMP D4,D0 ;IS HORIZ > BBOX RIGHT ? 232 | BLE.S RIGHTOK ;NO, CONTINUE 233 | MOVE D0,D4 ;YES, UPDATE BBOX RIGHT 234 | RIGHTOK DBRA D6,NEXTPT ;LOOP ALL POINTS 235 | MOVE.L (A4),A0 ;DE-REFERENCE THEPOLY 236 | LEA POLYBBOX(A0),A0 ;POINT TO POLYBBOX 237 | MOVE D1,(A0)+ ;INSTALL BBOX TOP 238 | MOVE D3,(A0)+ ;INSTALL BBOX LEFT 239 | MOVE D2,(A0)+ ;INSTALL BBOX BOTTOM 240 | MOVE D4,(A0)+ ;INSTALL BBOX RIGHT 241 | 242 | 243 | ;-------------------------------------------------------- 244 | ; 245 | ; TRIM THEPOLY TO FINAL SIZE, SHOW PEN AND QUIT 246 | ; 247 | EMPTY MOVE.L A4,-(SP) ;PUSH THEPOLY HANDLE 248 | MOVE D7,-(SP) ;PUSH BYTECOUNT = POLYSIZE 249 | JSR SETSIZE ;TRIM TO MINIMUM SIZE 250 | JSR SHOWPEN ;RESTORE PNVIS 251 | MOVEM.L (SP)+,D3-D7/A4 ;RESTORE REGS 252 | RTS ;AND RETURN 253 | 254 | 255 | 256 | .PROC KillPoly,1 257 | ;--------------------------------------------------- 258 | ; 259 | ; PROCEDURE KillPoly(poly: PolyHandle); 260 | ; 261 | MOVE.L (SP)+,A1 ;pop return addr 262 | MOVE.L (SP)+,A0 ;pop handle 263 | _DisposHandle ;discard it 264 | JMP (A1) ;and return 265 | 266 | 267 | 268 | 269 | .PROC OffsetPoly,3 270 | ;--------------------------------------------------- 271 | ; 272 | ; PROCEDURE OffsetPoly(poly: PolyHandle; dh,dv: INTEGER); 273 | ; 274 | MOVE.L (SP)+,A0 ;POP RETURN ADDRESS 275 | MOVE (SP)+,D0 ;POP DV 276 | MOVE (SP)+,D1 ;POP DH 277 | MOVE.L (SP)+,A1 ;POP POLYHANDLE 278 | MOVE.L (A1),A1 ;DE-REFERENCE POLYHANDLE 279 | MOVE (A1)+,D2 ;GET POLYSIZE 280 | SUB #2,D2 ;CALC TOTAL # POINTS, INCL BBOX 281 | LSR #2,D2 ; # POINTS = (SIZE-2) DIV 4 282 | SUB #1,D2 ;INIT DBRA COUNT 283 | NEXTPT ADD D0,(A1)+ ;OFFSET VERT COORD 284 | ADD D1,(A1)+ ;OFFSET HORIZ COORD 285 | DBRA D2,NEXTPT ;LOOP FOR ALL POINTS 286 | JMP (A0) ;AND RETURN 287 | 288 | 289 | 290 | .PROC MapPoly,3 291 | .REF MapPt,MapRect 292 | ;------------------------------------------------------------- 293 | ; 294 | ; PROCEDURE MapPoly(poly: PolyHandle; fromRect,toRect: Rect); 295 | ; 296 | ; A6 OFFSETS OF PARAMETERS AND LOCALS AFTER LINK: 297 | ; 298 | PARAMSIZE .EQU 12 299 | POLY .EQU PARAMSIZE+8-4 ;LONG, RGNHANDLE 300 | FROMRECT .EQU POLY-4 ;LONG, ADDR OF RECT 301 | TORECT .EQU FROMRECT-4 ;LONG, ADDR OF RECT 302 | 303 | LINK A6,#0 ;ALLOCATE STACK FRAME 304 | MOVEM.L D7/A2-A4,-(SP) ;SAVE REGS 305 | ; 306 | ; QUIT FAST IF FROMRECT = TORECT 307 | ; 308 | MOVE.L FROMRECT(A6),A2 ;POINT TO FROMRECT 309 | MOVE.L TORECT(A6),A3 ;POINT TO TORECT 310 | MOVE.L (A2),D0 311 | CMP.L (A3),D0 ;IS TOPLEFT SAME ? 312 | BNE.S NOTSAME ;NO, CONTINUE 313 | MOVE.L 4(A2),D0 314 | CMP.L 4(A3),D0 ;YES, IS BOTRIGHT SAME TOO ? 315 | BEQ.S DONE ;IF SO, JUST QUIT 316 | 317 | NOTSAME MOVE.L POLY(A6),A4 ;GET POLYHANDLE 318 | MOVE.L (A4),A4 ;DE-REFERENCE POLYHANDLE 319 | PEA POLYBBOX(A4) ;PUSH ADDR OF BBOX 320 | MOVE.L A2,-(SP) ;PUSH FROMRECT 321 | MOVE.L A3,-(SP) ;PUSH TORECT 322 | JSR MAPRECT ;MAP POLYBBOX 323 | 324 | MOVEQ #10,D0 325 | MOVE POLYSIZE(A4),D7 ;GET POLYSIZE 326 | SUB D0,D7 327 | LSR #2,D7 ;NPOINTS = (POLYSIZE-10) DIV 4 328 | ADD D0,A4 ;POINT TO FIRST POINT 329 | BRA.S START ;GO TO LOOP START 330 | NEXTPT MOVE.L A4,-(SP) ;PUSH ADDR OF POINT 331 | MOVE.L A2,-(SP) ;PUSH FROMRECT 332 | MOVE.L A3,-(SP) ;PUSH TORECT 333 | JSR MAPPT ;MAP THIS POINT 334 | ADD #4,A4 ;BUMP TO NEXT POINT 335 | START DBRA D7,NEXTPT ;LOOP ALL POINTS IN POLY 336 | 337 | DONE MOVEM.L (SP)+,D7/A2-A4 ;RESTORE REGS 338 | UNLINK PARAMSIZE,'MAPPOLY ' 339 | 340 | 341 | 342 | .PROC FrPoly,1 343 | .REF MoveTo,DoLine 344 | ;-------------------------------------------------------- 345 | ; 346 | ; PROCEDURE FrPoly(poly: PolyHandle); 347 | ; 348 | ; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK: 349 | ; 350 | PARAMSIZE .EQU 4 351 | POLY .EQU PARAMSIZE+8-4 ;LONG, POLYHANDLE 352 | 353 | LINK A6,#0 ;ALLOCATE STACK FRAME 354 | MOVEM.L D6-D7/A4,-(SP) ;SAVE REGS 355 | MOVE.L POLY(A6),A4 ;GET POLYHANDLE 356 | MOVE.L (A4),A0 ;DE-REFERENCE IT 357 | MOVE (A0),D7 ;GET POLYSIZE 358 | SUB #10,D7 359 | LSR #2,D7 ;NPOINTS = (SIZE-10) DIV 4 360 | BEQ.S DONE ;QUIT IF EMPTY POLYGON 361 | MOVE.L 10(A0),-(SP) ;PUSH FIRST POINT 362 | JSR MOVETO ;MOVETO(FIRST POINT) 363 | MOVE.L #14,D6 ;INIT BYTE OFFSET 364 | SUB #1,D7 ;DECREMENT COUNT 365 | BRA.S START ;GOT TO LOOP START 366 | NEXTPT MOVE.L (A4),A0 ;DE-REFERENCE POLYHANDLE 367 | MOVE.L 0(A0,D6),-(SP) ;PUSH NEXT POINT 368 | ADD #4,D6 ;BUMP BYTE OFFSET 369 | JSR DOLINE ;DOLINE(PT) 370 | START DBRA D7,NEXTPT ;LOOP FOR ALL POINTS 371 | DONE MOVEM.L (SP)+,D6-D7/A4 ;RESTORE REGS 372 | UNLINK PARAMSIZE,'FRPOLY ' 373 | 374 | 375 | 376 | .PROC DrawPoly,3 377 | .REF OpenRgn,FrPoly,DoLine,NewRgn,CloseRgn,DrawRgn 378 | ;-------------------------------------------------------- 379 | ; 380 | ; PROCEDURE DrawPoly(poly: PolyHandle; mode: INTEGER; VAR pat: Pattern); 381 | ; 382 | ; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK: 383 | ; 384 | PARAMSIZE .EQU 10 385 | POLY .EQU PARAMSIZE+8-4 ;LONG, POLYHANDLE 386 | MODE .EQU POLY-2 ;WORD 387 | PAT .EQU MODE-4 ;LONG, ADDR OF PATTERN 388 | 389 | LINK A6,#0 ;NO LOCAL VARS 390 | MOVE.L A4,-(SP) ;SAVE REG 391 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS 392 | MOVE.L THEPORT(A0),A0 ;GET CURRENT PORT 393 | TST PNVIS(A0) ;IS PNVIS NEG ? 394 | BMI.S DONE ;YES, QUIT 395 | JSR OPENRGN ;OpenRgn 396 | MOVE.L POLY(A6),-(SP) 397 | JSR FRPOLY ;FrPoly(poly); 398 | MOVE.L POLY(A6),A0 399 | MOVE.L (A0),A0 400 | MOVE.L 10(A0),-(SP) ;PUSH FIRST POINT 401 | JSR DOLINE ;MAKE SURE IT CLOSES 402 | CLR.L -(SP) ;ROOM FOR FCN RESULT 403 | JSR NEWRGN ;ALLOCATE TEMPRGN 404 | MOVE.L (SP),A4 ;PUT TEMPRGN IN A4 405 | JSR CLOSERGN ;CLOSERGN(TEMPRGN) 406 | MOVE.L A4,-(SP) 407 | MOVE MODE(A6),-(SP) 408 | MOVE.L PAT(A6),-(SP) 409 | JSR DRAWRGN ;DrawRgn(tempRgn,mode,pat); 410 | MOVE.L A4,A0 ;get tempRgn 411 | _DisposHandle ;DISCARD IT 412 | DONE MOVEM.L (SP)+,A4 ;RESTORE REG 413 | UNLINK PARAMSIZE,'DRAWPOLY' 414 | 415 | 416 | 417 | .END 418 | -------------------------------------------------------------------------------- /PutLine.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;----------------------------------------------------------- 3 | ; 4 | ; --> PUTLINE.TEXT 5 | ; 6 | ; Decompose a line segment into a list of inversion points. 7 | ; 8 | ; 9 | 10 | 11 | .PROC PUTLINE,5 12 | .REF SETSIZE 13 | ;------------------------------------------------------------------ 14 | ; 15 | ; PROCEDURE PutLine(pt1,pt2: Point; dst: Handle; VAR index,bufMax: INTEGER); 16 | ; 17 | ; INVERSION POINTS FOR A LINE SEGMENT 18 | ; 19 | ; SP OFFSETS OF PARAMETERS: 20 | ; 21 | PARAMSIZE .EQU 20 ;TOTAL SIZE OF PARAMETERS 22 | PT1 .EQU PARAMSIZE+4-4 ;LONG, POINT (VALUE) 23 | PT2 .EQU PT1-4 ;LONG, POINT (VALUE) 24 | BUF .EQU PT2-4 ;LONG, HANDLE 25 | INDEX .EQU BUF-4 ;LONG, (VAR) 26 | BUFMAX .EQU INDEX-4 ;LONG, (VAR) 27 | 28 | 29 | 30 | MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS, 8*4 ==> 32 31 | 32 | 33 | ;----------------------------------------------------- 34 | ; 35 | ; IF LINE IS VERTICAL, IGNORE IT. 36 | ; 37 | MOVE PT1+H+32(SP),D2 ;GET 1ST POINT'S HORIZ 38 | MOVE PT2+H+32(SP),D4 ;GET 2ND POINT'S HORIZ 39 | CMP D2,D4 ;IS THIS A VERTICAL LINE ? 40 | BEQ GOHOME ;YES, IGNORE IT 41 | 42 | 43 | ;------------------------------------------------------ 44 | ; 45 | ; CALC BYTESNEEDED = 8 * ( Min(ABS(dh),ABS(dv)) + 1) 46 | ; 47 | MOVE D2,D0 ;GET H1 48 | SUB D4,D0 ;SUBTRACT H2 49 | BPL.S DHPOS ;BR IF DH POS 50 | NEG D0 ;ELSE TAKE ABSOLUTE VALUE 51 | DHPOS MOVE PT1+V+32(SP),D1 ;GET V1 52 | SUB PT2+V+32(SP),D1 ;SUBTRACT V2 53 | BPL.S DVPOS ;BR IF DV POS 54 | NEG D1 ;ELSE TAKE ABSOLUTE VALUE 55 | DVPOS CMP D1,D0 ;IS DH <= DV ? 56 | BLE.S DHLESS ;YES, CONTINUE 57 | MOVE D1,D0 ;NO, PUT MIN(DH,DV) INTO D0 58 | DHLESS ADD #1,D0 ;CALC MIN(DH,DV)+1 59 | LSL #3,D0 ;TIMES EIGHT FOR BYTESNEEDED 60 | 61 | 62 | MOVE.L BUF+32(SP),A3 ;GET DSTHANDLE 63 | MOVE.L INDEX+32(SP),A4 ;POINT TO CURRENT INDEX 64 | 65 | ;----------------------------------------------------- 66 | ; 67 | ; GROW POINT BUFFER AS NECESSARY TO HOLD BYTESNEEDED 68 | ; 69 | ADD (A4),D0 ;NEWSIZE := INDEX + BYTESNEEDED 70 | MOVE.L BUFMAX+32(SP),A0 ;POINT TO BUFMAX 71 | CMP (A0),D0 ;DO WE HAVE TO GROW DSTBUF ? 72 | BLE.S NOGROW ;NO, CONTINUE 73 | ADD #512,D0 ;GROW IN CHUNKS 74 | MOVE D0,(A0) ;UPDATE NEW BUFMAX 75 | MOVE.L A3,-(SP) ;PUSH DSTBUF HANDLE 76 | MOVE D0,-(SP) ;PUSH NEW BUFMAX 77 | JSR SETSIZE ;MAKE THE BUFFER BIGGER 78 | MOVE PT1+H+32(SP),D2 ;RESTORE CLOBBERED REG 79 | 80 | NOGROW 81 | 82 | 83 | MOVE.L (A3),A3 ;DE-REFERENCE DSTHANDLE 84 | ADD (A4),A3 ;ADD INDEX TO BUFPTR 85 | 86 | ;----------------------------------------------------- 87 | ; 88 | ; IF LINE IS HORIZONTAL, PUT ITS TWO ENDPOINTS 89 | ; 90 | MOVE PT1+V+32(SP),D1 ;GET 1ST POINT'S VERT 91 | MOVE PT2+V+32(SP),D3 ;GET 2ND POINT'S VERT 92 | CMP D1,D3 ;IS THIS A HORIZONTAL LINE ? 93 | BNE.S SLANTED ;NO, BRANCH 94 | MOVE D1,(A3)+ ;PUT V1 VERT COORD 95 | MOVE D2,(A3)+ ;PUT H1 HORIZ COORD 96 | MOVE D3,(A3)+ ;PUT V2 VERT COORD 97 | MOVE D4,(A3)+ ;PUT H2 HORIZ COORD 98 | BRA.S DONE ;UPDATE INDEX AND QUIT 99 | 100 | 101 | ;------------------------------------------------------ 102 | ; 103 | ; LINE IS SLANTED. DIVIDE IT INTO HORIZONTAL SLABS 104 | ; AND PUT THE TWO ENDPOINTS OF EACH SLAB. 105 | ; 106 | ; START BY SORTING POINTS VERTICALLY. 107 | ; 108 | SLANTED BGT.S NOSWAP ;SKIP IF ALREADY IN ORDER 109 | EXG D1,D3 ;SORT POINTS BY VERTICAL 110 | EXG D2,D4 ;SWAP HORIZ TO MATCH 111 | NOSWAP MOVE D1,D6 ;INIT V TO TOPV 112 | 113 | 114 | ;------------------------------------------------------------ 115 | ; 116 | ; CALCULATE FIXED POINT SLOPE = FixRatio(dh,dv); 117 | ; 118 | CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT 119 | MOVE D4,-(SP) ;PUSH BOTTOM HORIZ 120 | SUB D2,(SP) ;CALC DH 121 | MOVE D3,-(SP) ;PUSH BOTTOM VERT 122 | SUB D1,(SP) ;CALC DV 123 | _FixRatio ;CALC FIXED POINT SLOPE 124 | MOVE.L (SP)+,D7 ;POP RESULT 125 | 126 | 127 | ;--------------------------------------------------------- 128 | ; 129 | ; SET UP STARTING HORIZ FIXED POINT. 130 | ; 131 | MOVE.W D2,D1 132 | SWAP D1 ;HORIZ.INT := TOP HORIZ 133 | MOVE.W #$8000,D1 ;HORIZ.FRACT := 1/2 134 | ; 135 | ; ADJUST HORIZ DEPENDING ON SIGN AND MAGNITUDE OF SLOPE 136 | ; 137 | MOVE.L D7,D0 ;COPY SLOPE 138 | ASR.L #1,D0 ;CALC SLOPE/2 139 | ADD.L D0,D1 ;HORIZ := HORIZ + SLOPE/2 140 | 141 | MOVE.L #$00010000,D0 142 | 143 | TST.L D7 ;IS SLOPE NEG ? 144 | BMI.S NEGSLOPE ;YES, CONTINUE 145 | 146 | CMP.L D0,D7 ;IS SLOPE < ONE ? 147 | BGE.S SLOPEOK ;NO, CONTINUE 148 | ADD.L D7,D1 ;ADD SLOPE TO LEFTEDGE 149 | BRA.S SLOPEOK ;CONTINUE 150 | 151 | NEGSLOPE CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ? 152 | BGE.S SLOPEOK ;YES, CONTINUE 153 | ADD.L D0,D1 ;YES, HORIZ := HORIZ + 1 154 | 155 | SLOPEOK 156 | 157 | 158 | 159 | ;------------------------------------------------------ 160 | ; 161 | ; FOR VERT:=TOPV TO BOTV-1 ADD SLOPE TO HORIZ AND PUT SLABS 162 | ; 163 | MOVE D2,D5 ;H:=TOPH 164 | LOOP SWAP D1 ;GET HORIZ.INT INTO D1 LOWER 165 | CMP D1,D5 ;HAS HORIZ.INT CHANGED ? 166 | BEQ.S NOCHNG ;NO, CONTINUE 167 | MOVE D6,(A3)+ ;YES, PUT VERT COORD 168 | MOVE D5,(A3)+ ;PUT OLD HORIZ COORD 169 | MOVE.W D1,D5 ;OLDH := HORIZ.INT 170 | MOVE D6,(A3)+ ;PUT VERT COORD 171 | MOVE D5,(A3)+ ;PUT NEW HORIZ COORD 172 | NOCHNG SWAP D1 ;PUTBACK HORIZ.INT INTO D1 UPPER 173 | ADD #1,D6 ;VERT:=VERT+1 174 | ADD.L D7,D1 ;ADD SLOPE TO HORIZ 175 | CMP D6,D3 ;IS VERT AT BOTTOM VERT YET ? 176 | BNE LOOP ;NO, GO FOR MORE 177 | 178 | 179 | ;------------------------------------------------- 180 | ; 181 | ; FINISH UP LAST SLAB 182 | ; 183 | CMP D4,D5 ;IS OLDH = BOTTOM H ? 184 | BEQ.S DONE ;YES, CONTINUE 185 | MOVE D6,(A3)+ ;NO, PUT VERT COORD 186 | MOVE D5,(A3)+ ;PUT HORIZ COORD 187 | MOVE D6,(A3)+ ;PUT VERT COORD 188 | MOVE D4,(A3)+ ;PUT BOTTOM H COORD 189 | 190 | 191 | ;--------------------------------------------------- 192 | ; 193 | ; UPDATE INDEX TO REFLECT POINTS ADDED. 194 | ; 195 | DONE MOVE.L BUF+32(SP),A0 ;GET DSTHANDLE 196 | SUB.L (A0),A3 ;INDEX := BUFPTR-BUFSTART 197 | MOVE A3,(A4) ;UPDATE INDEX 198 | 199 | GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS 200 | MOVE.L (SP)+,A0 201 | ADD.W #PARAMSIZE,A7 202 | JMP (A0) 203 | 204 | 205 | .END 206 | -------------------------------------------------------------------------------- /PutOval.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;----------------------------------------------------------- 3 | ; 4 | ; --> PUTOVAL.TEXT 5 | ; 6 | ; Routine to add the inversion points for an oval to a region. 7 | ; 8 | 9 | 10 | ;------------------------------------------------------ 11 | ; 12 | ; OFFSETS IN AN OVAL STATE RECORD: 13 | ; 14 | OVALTOP .EQU 0 ;INTEGER 15 | OVALBOT .EQU OVALTOP+2 ;INTEGER 16 | OVALY .EQU OVALBOT+2 ;INTEGER 17 | RSQYSQ .EQU OVALY+2 ;LONGINT 18 | SQUARE .EQU RSQYSQ+4 ;64 BIT LONGFIX 19 | ODDNUM .EQU SQUARE+8 ;64 BIT LONGFIX 20 | ODDBUMP .EQU ODDNUM+8 ;64 BIT LONGFIX 21 | LEFTEDGE .EQU ODDBUMP+8 ;32 BIT FIXED POINT 22 | RIGHTEDGE .EQU LEFTEDGE+4 ;32 BIT FIXED POINT 23 | ONEHALF .EQU RIGHTEDGE+4 ;32 BIT FIXED POINT 24 | OVALSIZE .EQU ONEHALF+4 ;SIZE OF AN OVALREC 25 | 26 | 27 | 28 | .PROC PUTOVAL,6 29 | .REF INITOVAL,BUMPOVAL,SETSIZE 30 | ;---------------------------------------------------------------- 31 | ; 32 | ; PROCEDURE PutOval(dstRect: Rect; ovalWidth,ovalHeight: INTEGER; 33 | ; bufHandle: Handle; VAR index,size: INTEGER); 34 | ; 35 | ; Create region inversion points for an oval or roundRect. 36 | ; 37 | 38 | 39 | ;------------------------------------------------ 40 | ; 41 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 42 | ; 43 | PARAMSIZE .EQU 20 ;TOTAL SIZE OF PARAMETERS 44 | DSTRECT .EQU PARAMSIZE+8-4 ;ADDR OF RECT 45 | OVALWIDTH .EQU DSTRECT-2 ;INTEGER 46 | OVALHEIGHT .EQU OVALWIDTH-2 ;INTEGER 47 | BUFHANDLE .EQU OVALHEIGHT-4 ;LONG, HANDLE 48 | INDEX .EQU BUFHANDLE-4 ;LONG, VAR 49 | SIZE .EQU INDEX-4 ;LONG, VAR 50 | 51 | 52 | ;------------------------------------------------ 53 | ; 54 | ; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK: 55 | ; 56 | OVAL .EQU -OVALSIZE ;OVAL RECORD 57 | SKIPTOP .EQU OVAL-2 ;WORD 58 | SKIPBOT .EQU SKIPTOP-2 ;WORD 59 | OLDLEFT .EQU SKIPBOT-2 ;WORD 60 | OLDRIGHT .EQU OLDLEFT-2 ;WORD 61 | VARSIZE .EQU OLDRIGHT ;SIZE OF LOCAL VARIABLES 62 | 63 | 64 | ENTRY LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS 65 | MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS 66 | 67 | 68 | ;--------------------------------------------------------------- 69 | ; 70 | ; INIT AN OVAL RECORD 71 | ; 72 | MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT 73 | LEA OVAL(A6),A1 ;POINT TO OVAL RECORD 74 | MOVE OVALWIDTH(A6),D2 ;GET OVALWIDTH 75 | MOVE OVALHEIGHT(A6),D1 ;GET OVALHEIGHT 76 | JSR INITOVAL ;INIT OVAL RECORD 77 | MOVE.W OVAL+LEFTEDGE(A6),OLDLEFT(A6) 78 | MOVE.W OVAL+RIGHTEDGE(A6),OLDRIGHT(A6) 79 | 80 | MOVE OVALHEIGHT(A6),D0 ;GET OVALHEIGHT 81 | ASR #1,D0 ;CALC OVAL HEIGHT DIV 2 82 | ADD OVAL+OVALTOP(A6),D0 ;ADD OVAL TOP 83 | MOVE D0,SKIPTOP(A6) ;SAVE SKIPTOP 84 | 85 | MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT 86 | ADD BOTTOM(A0),D0 ;ADD BOTTOM 87 | SUB TOP(A0),D0 ;SUBTRACT TOP 88 | SUB OVALHEIGHT(A6),D0 ;SUBTRACT OVALHEIGHT 89 | MOVE D0,SKIPBOT(A6) ;SAVE SKIPBOT 90 | 91 | 92 | ;----------------------------------------------------------------- 93 | ; 94 | ; GET BUF HANDLE, DE-REFERENCE IT, AND ADD INDEX 95 | ; 96 | MOVE.L BUFHANDLE(A6),A3 ;GET HANDLE 97 | MOVE.L (A3),A3 ;DE-REFERENCE IT 98 | MOVE.L A3,A2 ;REMEMBER BUFSTART FOR LATER 99 | MOVE.L INDEX(A6),A0 ;GET ADDR OF INDEX 100 | ADD (A0),A3 ;ADD INDEX TO BUFPTR 101 | 102 | 103 | ;---------------------------------------------------------- 104 | ; 105 | ; BUFLIMIT := BUFSTART + BUFSIZE 106 | ; 107 | MOVE.L A2,A1 ;GET BUFSTART 108 | MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE 109 | ADD (A0),A1 ;LEAVE BUFLIMIT IN A1 110 | 111 | 112 | ;------------------------------------------------ 113 | ; 114 | ; PUT THE TOP EDGE 115 | ; 116 | MOVE OVAL+OVALTOP(A6),D6 ;START VERT:= OVAL TOP 117 | MOVE OLDLEFT(A6),D5 118 | JSR PUTPT ;PUTPOINT (OLDLEFT,VERT) 119 | MOVE OLDRIGHT(A6),D5 120 | JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT) 121 | 122 | 123 | ;----------------------------------------------------- 124 | ; 125 | ; FOR EACH VERTICAL, BUMP LEFTEDGE AND RIGHTEDGE. 126 | ; IF THEY DIFFER FROM OLDLEFT AND OLDRIGHT, PUT INVERSION 127 | ; POINTS FOR THE DIFFERENCES 128 | ; 129 | NXTVERT CMP SKIPTOP(A6),D6 ;IS VERT < SKIPTOP ? 130 | BLT.S YESBUMP ;YES, BUMP OVAL RECORD 131 | CMP SKIPBOT(A6),D6 ;IS VERT >= SKIPBOT ? 132 | BLT.S RIGHTOK ;NO, SKIP BUMPING 133 | 134 | YESBUMP MOVEM.L D6/A1-A3,-(SP) ;PRESERVE REGS 135 | LEA OVAL(A6),A3 ;POINT TO OVAL RECORD 136 | MOVE D6,D0 ;GET CURRENT VERT 137 | JSR BUMPOVAL ;BUMP IT TO NEXT SCANLINE 138 | MOVEM.L (SP)+,D6/A1-A3 ;RESTORE REGS 139 | 140 | 141 | ; CHECK LEFT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED 142 | 143 | MOVE.W OVAL+LEFTEDGE(A6),D5 ;GET LEFTEDGE.INT 144 | CMP OLDLEFT(A6),D5 ;SAME AS OLDLEFT ? 145 | BEQ.S LEFTOK ;YES, CONTINUE 146 | JSR PUTPT ;PUTPOINT (NEWLEFT,VERT) 147 | MOVE OLDLEFT(A6),D5 148 | JSR PUTPT ;PUTPOINT(OLDLEFT,VERT) 149 | MOVE OVAL+LEFTEDGE(A6),OLDLEFT(A6) ;UPDATE OLDLEFT 150 | 151 | ; CHECK RIGHT EDGE AND PUT TWO INVERSION POINTS IF IT HAS CHANGED 152 | 153 | LEFTOK MOVE.W OVAL+RIGHTEDGE(A6),D5 ;GET RIGHTEDGE.INT 154 | CMP OLDRIGHT(A6),D5 ;SAME AS OLDRIGHT ? 155 | BEQ.S RIGHTOK ;YES, CONTINUE 156 | JSR PUTPT ;PUTPOINT (NEWRIGHT,VERT) 157 | MOVE OLDRIGHT(A6),D5 158 | JSR PUTPT ;PUTPOINT(OLDRIGHT,VERT) 159 | MOVE OVAL+RIGHTEDGE(A6),OLDRIGHT(A6) ;UPDATE OLDRIGHT 160 | 161 | RIGHTOK ADD #1,D6 ;BUMP CURRENT VERT 162 | CMP OVAL+OVALBOT(A6),D6 ;DONE WITH THE OVAL ? 163 | BLT NXTVERT ;LOOP FOR ALL VERTICALS 164 | 165 | 166 | ;------------------------------------------------ 167 | ; 168 | ; PUT THE BOTTOM EDGE 169 | ; 170 | MOVE OLDLEFT(A6),D5 171 | JSR PUTPT ;PUTPOINT (OLDLEFT,VERT) 172 | MOVE OLDRIGHT(A6),D5 173 | JSR PUTPT ;PUTPOINT (OLDRIGHT,VERT) 174 | 175 | 176 | ;---------------------------------------------------- 177 | ; 178 | ; UPDATE INDEX TO REFLECT POINTS ADDED, CLEAN UP STACK AND GO HOME. 179 | ; 180 | SUB.L A2,A3 ;CALC BUFPTR-BUFSTART 181 | MOVE.L INDEX(A6),A0 ;GET VAR ADDR OF INDEX 182 | MOVE A3,(A0) ;UPDATE INDEX 183 | MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS 184 | UNLINK PARAMSIZE,'PUTOVAL ' 185 | 186 | 187 | 188 | ;----------------------------------------------------------------------- 189 | ; 190 | ; Local routine to Append a point to the end of the saved points buffer, 191 | ; extending buffer if necessary. If pt is a duplicate of the last pt, 192 | ; cancel both instead. 193 | ; 194 | ; INPUTS: D5: HORIZ COORD 195 | ; D6: VERT COORD 196 | ; A1: BUFLIMIT GETS EXPANDED AND RELOCATED 197 | ; A2: BUFSTART GETS RELOCATED 198 | ; A3: BUFPTR GETS BUMPED AND RELOCATED 199 | ; 200 | ; ALTERS: A1,A2,A3, VAR SIZE 201 | ; 202 | PUTPT CMP.L A1,A3 ;IS BUFPTR < BUFLIMIT ? 203 | BLT.S SIZEOK ;YES, CONTINUE 204 | 205 | 206 | ;--------------------------------------------------------------------- 207 | ; 208 | ; BUFFER IS FULL, CALL STORAGE ALLOCATOR TO MAKE ROOM FOR 256 MORE POINTS. 209 | ; UPDATE BUFPTR, BUFSTART, BUFLIMIT, AND BUFSIZE AFTER RELOCATION. 210 | ; 211 | SUB.L A2,A3 ;MAKE BUFPTR RELATIVE 212 | SUB.L A2,A1 ;MAKE BUFLIMIT RELATIVE 213 | ADD #1024,A1 ;MAKE BUFLIMIT BIGGER 214 | 215 | MOVEM.L D0-D7/A0-A3,-(SP) ;SAVE REGS 216 | MOVE.L SIZE(A6),A0 ;GET ADDR OF SIZE 217 | MOVE A1,(A0) ;UPDATE BUFFER SIZE 218 | MOVE.L BUFHANDLE(A6),-(SP) ;PUSH HANDLE PARAM 219 | MOVE A1,-(SP) ;PUSH NEW SIZE 220 | JSR SETSIZE ;MAKE THE BUFFER BIGGER 221 | MOVEM.L (SP)+,D0-D7/A0-A3 ;RESTORE REGS 222 | 223 | MOVE.L BUFHANDLE(A6),A2 ;GET BUF HANDLE 224 | MOVE.L (A2),A2 ;GET NEW BUFSTART 225 | ADD.L A2,A3 ;MAKE BUFPTR UN-RELATIVE 226 | ADD.L A2,A1 ;MAKE BUFLIMIT UN-RELATIVE 227 | 228 | 229 | ;------------------------------------------------------------------- 230 | ; 231 | ; ADD NEW POINT TO THE SAVE BUFFER UNLESS IT MATCHED THE PREVIOUS PT. 232 | ; DELETE DUPLICATE POINTS SINCE THEY WILL CANCEL EACH OTHER ANYWAY. 233 | ; 234 | SIZEOK CMP.L A2,A3 ;IS BUFPTR=STARTPTR ? 235 | BEQ.S APPEND ;BR IF FIRST POINT 236 | CMP -4+H(A3),D5 ;IS PREVIOUS HORIZ SAME ? 237 | BNE.S APPEND ;NO, APPEND NEW POINT 238 | CMP -4+V(A3),D6 ;YES, IS PREVIOUS VERT SAME TOO ? 239 | BNE.S APPEND ;NO, APPEND NEW POINT 240 | SUB #4,A3 ;YES, DELETE OLD INSTEAD 241 | RTS 242 | 243 | APPEND MOVE D6,(A3)+ ;PUT VERT COORD 244 | MOVE D5,(A3)+ ;PUT HORIZ COORD 245 | RTS 246 | 247 | 248 | 249 | .END 250 | -------------------------------------------------------------------------------- /PutRgn.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | 3 | 4 | .PROC PUTRGN,4 5 | .REF SETSIZE 6 | ;---------------------------------------------------------------- 7 | ; 8 | ; PROCEDURE PutRgn(Rgn: RgnHandle; bufHandle: Handle; VAR index,size: INTEGER); 9 | ; 10 | ; Expands a region out to an array of inversion points. 11 | ; 12 | 13 | 14 | ;------------------------------------------------ 15 | ; 16 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 17 | ; 18 | PARAMSIZE .EQU 16 ;TOTAL SIZE OF PARAMETERS 19 | RGNHANDLE .EQU PARAMSIZE+8-4 ;LONG,RGNHANDLE 20 | BUFHANDLE .EQU RGNHANDLE-4 ;LONG, HANDLE 21 | INDEX .EQU BUFHANDLE-4 ;LONG, VAR 22 | SIZE .EQU INDEX-4 ;LONG, VAR 23 | 24 | 25 | LINK A6,#0 ;NO LOCAL VARS 26 | MOVEM.L D7/A2-A4,-(SP) ;SAVE REGS 27 | 28 | ;------------------------------------------------------- 29 | ; 30 | ; EXPAND BUF TO FIT WORST CASE BYTESNEEDED = RGNSIZE * 2 31 | ; 32 | MOVE.L BUFHANDLE(A6),A4 ;GET BUFHANDLE 33 | MOVE.L RGNHANDLE(A6),A3 ;GET RGNHANDLE 34 | MOVE.L INDEX(A6),A2 ;POINT TO CURRENT INDEX 35 | MOVE.L (A3),A0 ;DE-REFERENCE RGN 36 | MOVE (A0),D7 ;GET RGNSIZE 37 | ADD D7,D7 ;TIMES 2 38 | ADD (A2),D7 ;ADD CURRENT INDEX 39 | MOVE.L SIZE(A6),A1 ;POINT TO SIZE 40 | CMP (A1),D7 ;IS REQUIRED > CURRENT SIZE ? 41 | BLE.S NOGROW ;NO, CONTINUE 42 | 43 | ADD #256,D7 ;GROW IN CHUNKS 44 | MOVE D7,(A1) ;UPDATE CURRENT SIZE 45 | MOVE.L A4,-(SP) ;PUSH BUFHANDLE 46 | MOVE D7,-(SP) ;PUSH NEW SIZE 47 | JSR SETSIZE ;MAKE ROOM IN BUF 48 | MOVE.L (A3),A0 ;RE-DEREFERENCE RGNHANDLE 49 | MOVE.L INDEX(A6),A2 ;GET ADDR OF INDEX AGAIN 50 | 51 | NOGROW MOVE.L (A4),A1 ;DE-REFERENCE BUFHANDLE 52 | ADD (A2),A1 ;ADD INDEX TO BUFPTR 53 | CMP #10,RGNSIZE(A0) ;IS REGION RECTANGULAR ? 54 | BNE.S NOTRECT ;NO, CONTINUE 55 | ADD #2,A0 ;YES, POINT TO BBOX TOPLEFT 56 | MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT 57 | MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT 58 | BRA.S DONE ;UPDATE INDEX AND QUIT 59 | 60 | NOTRECT LEA RGNDATA(A0),A0 ;POINT TO TOP VERT IN RGN 61 | NXTVERT MOVE.L (A0)+,D7 ;GET VERT AND HORIZ COORDS 62 | NXTHOR MOVE.L D7,(A1)+ ;PUT LEFT POINT TO DST 63 | MOVE (A0)+,D7 ;GET HORIZ COORD 64 | MOVE.L D7,(A1)+ ;PUT RIGHT POINT TO DST 65 | MOVE (A0)+,D7 ;GET NEXT HORIZ COORD 66 | CMP #32767,D7 ;END OF SCAN FLAG ? 67 | BNE NXTHOR ;NO, GO FOR MORE 68 | CMP #32767,(A0) ;END OF REGION ? 69 | BNE NXTVERT ;NO, LOOP FOR MORE 70 | 71 | DONE SUB.L (A4),A1 ;CALC DSTPTR - DSTSTART 72 | MOVE A1,(A2) ;UPDATE VAR INDEX 73 | GOHOME MOVEM.L (SP)+,D7/A2-A4 ;RESTORE REGISTERS 74 | UNLINK PARAMSIZE,'PUTRGN ' 75 | 76 | 77 | 78 | 79 | .END 80 | -------------------------------------------------------------------------------- /QuickDraw.p: -------------------------------------------------------------------------------- 1 | UNIT QuickDraw; 2 | 3 | { Copyright 1983 Apple Computer Inc. } 4 | { Written by Bill Atkinson } 5 | 6 | INTERFACE 7 | 8 | CONST srcCopy = 0; { the 16 transfer modes } 9 | srcOr = 1; 10 | srcXor = 2; 11 | srcBic = 3; 12 | notSrcCopy = 4; 13 | notSrcOr = 5; 14 | notSrcXor = 6; 15 | notSrcBic = 7; 16 | patCopy = 8; 17 | patOr = 9; 18 | patXor = 10; 19 | patBic = 11; 20 | notPatCopy = 12; 21 | notPatOr = 13; 22 | notPatXor = 14; 23 | notPatBic = 15; 24 | 25 | { QuickDraw color separation constants } 26 | 27 | normalBit = 0; { normal screen mapping } 28 | inverseBit = 1; { inverse screen mapping } 29 | redBit = 4; { RGB additive mapping } 30 | greenBit = 3; 31 | blueBit = 2; 32 | cyanBit = 8; { CMYBk subtractive mapping } 33 | magentaBit = 7; 34 | yellowBit = 6; 35 | blackBit = 5; 36 | 37 | blackColor = 33; { colors expressed in these mappings } 38 | whiteColor = 30; 39 | redColor = 205; 40 | greenColor = 341; 41 | blueColor = 409; 42 | cyanColor = 273; 43 | magentaColor = 137; 44 | yellowColor = 69; 45 | 46 | picLParen = 0; { standard picture comments } 47 | picRParen = 1; 48 | 49 | 50 | TYPE QDByte = -128..127; 51 | QDPtr = ^QDByte; { blind pointer } 52 | QDHandle = ^QDPtr; { blind handle } 53 | Str255 = String[255]; 54 | Pattern = PACKED ARRAY[0..7] OF 0..255; 55 | Bits16 = ARRAY[0..15] OF INTEGER; 56 | VHSelect = (v,h); 57 | GrafVerb = (frame,paint,erase,invert,fill); 58 | StyleItem = (bold,italic,underline,outline,shadow,condense,extend); 59 | Style = SET OF StyleItem; 60 | 61 | FontInfo = RECORD 62 | ascent: INTEGER; 63 | descent: INTEGER; 64 | widMax: INTEGER; 65 | leading: INTEGER; 66 | END; 67 | 68 | Point = RECORD CASE INTEGER OF 69 | 70 | 0: (v: INTEGER; 71 | h: INTEGER); 72 | 73 | 1: (vh: ARRAY[VHSelect] OF INTEGER); 74 | 75 | END; 76 | 77 | 78 | Rect = RECORD CASE INTEGER OF 79 | 80 | 0: (top: INTEGER; 81 | left: INTEGER; 82 | bottom: INTEGER; 83 | right: INTEGER); 84 | 85 | 1: (topLeft: Point; 86 | botRight: Point); 87 | END; 88 | 89 | 90 | BitMap = RECORD 91 | baseAddr: QDPtr; 92 | rowBytes: INTEGER; 93 | bounds: Rect; 94 | END; 95 | 96 | 97 | Cursor = RECORD 98 | data: Bits16; 99 | mask: Bits16; 100 | hotSpot: Point; 101 | END; 102 | 103 | 104 | PenState = RECORD 105 | pnLoc: Point; 106 | pnSize: Point; 107 | pnMode: INTEGER; 108 | pnPat: Pattern; 109 | END; 110 | 111 | 112 | PolyHandle = ^PolyPtr; 113 | PolyPtr = ^Polygon; 114 | Polygon = RECORD 115 | polySize: INTEGER; 116 | polyBBox: Rect; 117 | polyPoints: ARRAY[0..0] OF Point; 118 | END; 119 | 120 | 121 | RgnHandle = ^RgnPtr; 122 | RgnPtr = ^Region; 123 | Region = RECORD 124 | rgnSize: INTEGER; { rgnSize = 10 for rectangular } 125 | rgnBBox: Rect; 126 | { plus more data if not rectangular } 127 | END; 128 | 129 | 130 | PicHandle = ^PicPtr; 131 | PicPtr = ^Picture; 132 | Picture = RECORD 133 | picSize: INTEGER; 134 | picFrame: Rect; 135 | { plus byte codes for picture content } 136 | END; 137 | 138 | 139 | QDProcsPtr = ^QDProcs; 140 | QDProcs = RECORD 141 | textProc: QDPtr; 142 | lineProc: QDPtr; 143 | rectProc: QDPtr; 144 | rRectProc: QDPtr; 145 | ovalProc: QDPtr; 146 | arcProc: QDPtr; 147 | polyProc: QDPtr; 148 | rgnProc: QDPtr; 149 | bitsProc: QDPtr; 150 | commentProc: QDPtr; 151 | txMeasProc: QDPtr; 152 | getPicProc: QDPtr; 153 | putPicProc: QDPtr; 154 | END; 155 | 156 | 157 | GrafPtr = ^GrafPort; 158 | GrafPort = RECORD 159 | device: INTEGER; 160 | portBits: BitMap; 161 | portRect: Rect; 162 | visRgn: RgnHandle; 163 | clipRgn: RgnHandle; 164 | bkPat: Pattern; 165 | fillPat: Pattern; 166 | pnLoc: Point; 167 | pnSize: Point; 168 | pnMode: INTEGER; 169 | pnPat: Pattern; 170 | pnVis: INTEGER; 171 | txFont: INTEGER; 172 | txFace: Style; 173 | txMode: INTEGER; 174 | txSize: INTEGER; 175 | spExtra: LongInt; 176 | fgColor: LongInt; 177 | bkColor: LongInt; 178 | colrBit: INTEGER; 179 | patStretch: INTEGER; 180 | picSave: QDHandle; 181 | rgnSave: QDHandle; 182 | polySave: QDHandle; 183 | grafProcs: QDProcsPtr; 184 | END; 185 | 186 | 187 | 188 | VAR thePort: GrafPtr; 189 | white: Pattern; 190 | black: Pattern; 191 | gray: Pattern; 192 | ltGray: Pattern; 193 | dkGray: Pattern; 194 | arrow: Cursor; 195 | screenBits: BitMap; 196 | randSeed: LongInt; 197 | 198 | 199 | { GrafPort Routines } 200 | 201 | PROCEDURE InitGraf (globalPtr: QDPtr); 202 | PROCEDURE OpenPort (port: GrafPtr); 203 | PROCEDURE InitPort (port: GrafPtr); 204 | PROCEDURE ClosePort (port: GrafPtr); 205 | PROCEDURE SetPort (port: GrafPtr); 206 | PROCEDURE GetPort (VAR port: GrafPtr); 207 | PROCEDURE GrafDevice (device: INTEGER); 208 | PROCEDURE SetPortBits(bm: BitMap); 209 | PROCEDURE PortSize (width,height: INTEGER); 210 | PROCEDURE MovePortTo (leftGlobal,topGlobal: INTEGER); 211 | PROCEDURE SetOrigin (h,v: INTEGER); 212 | PROCEDURE SetClip (rgn: RgnHandle); 213 | PROCEDURE GetClip (rgn: RgnHandle); 214 | PROCEDURE ClipRect (r: Rect); 215 | PROCEDURE BackPat (pat: Pattern); 216 | 217 | 218 | { Cursor Routines } 219 | 220 | PROCEDURE InitCursor; 221 | PROCEDURE SetCursor(crsr: Cursor); 222 | PROCEDURE HideCursor; 223 | PROCEDURE ShowCursor; 224 | PROCEDURE ObscureCursor; 225 | 226 | 227 | { Line Routines } 228 | 229 | PROCEDURE HidePen; 230 | PROCEDURE ShowPen; 231 | PROCEDURE GetPen (VAR pt: Point); 232 | PROCEDURE GetPenState(VAR pnState: PenState); 233 | PROCEDURE SetPenState(pnState: PenState); 234 | PROCEDURE PenSize (width,height: INTEGER); 235 | PROCEDURE PenMode (mode: INTEGER); 236 | PROCEDURE PenPat (pat: Pattern); 237 | PROCEDURE PenNormal; 238 | PROCEDURE MoveTo (h,v: INTEGER); 239 | PROCEDURE Move (dh,dv: INTEGER); 240 | PROCEDURE LineTo (h,v: INTEGER); 241 | PROCEDURE Line (dh,dv: INTEGER); 242 | 243 | 244 | { Text Routines } 245 | 246 | PROCEDURE TextFont (font: INTEGER); 247 | PROCEDURE TextFace (face: Style); 248 | PROCEDURE TextMode (mode: INTEGER); 249 | PROCEDURE TextSize (size: INTEGER); 250 | PROCEDURE SpaceExtra (extra: LongInt); 251 | PROCEDURE DrawChar (ch: char); 252 | PROCEDURE DrawString (s: Str255); 253 | PROCEDURE DrawText (textBuf: QDPtr; firstByte,byteCount: INTEGER); 254 | FUNCTION CharWidth (ch: CHAR): INTEGER; 255 | FUNCTION StringWidth (s: Str255): INTEGER; 256 | FUNCTION TextWidth (textBuf: QDPtr; firstByte,byteCount: INTEGER): INTEGER; 257 | PROCEDURE GetFontInfo (VAR info: FontInfo); 258 | 259 | 260 | { Point Calculations } 261 | 262 | PROCEDURE AddPt (src: Point; VAR dst: Point); 263 | PROCEDURE SubPt (src: Point; VAR dst: Point); 264 | PROCEDURE SetPt (VAR pt: Point; h,v: INTEGER); 265 | FUNCTION EqualPt (pt1,pt2: Point): BOOLEAN; 266 | PROCEDURE ScalePt (VAR pt: Point; fromRect,toRect: Rect); 267 | PROCEDURE MapPt (VAR pt: Point; fromRect,toRect: Rect); 268 | PROCEDURE LocalToGlobal (VAR pt: Point); 269 | PROCEDURE GlobalToLocal (VAR pt: Point); 270 | 271 | 272 | { Rectangle Calculations } 273 | 274 | PROCEDURE SetRect (VAR r: Rect; left,top,right,bottom: INTEGER); 275 | FUNCTION EqualRect (rect1,rect2: Rect): BOOLEAN; 276 | FUNCTION EmptyRect (r: Rect): BOOLEAN; 277 | PROCEDURE OffsetRect (VAR r: Rect; dh,dv: INTEGER); 278 | PROCEDURE MapRect (VAR r: Rect; fromRect,toRect: Rect); 279 | PROCEDURE InsetRect (VAR r: Rect; dh,dv: INTEGER); 280 | FUNCTION SectRect (src1,src2: Rect; VAR dstRect: Rect): BOOLEAN; 281 | PROCEDURE UnionRect (src1,src2: Rect; VAR dstRect: Rect); 282 | FUNCTION PtInRect (pt: Point; r: Rect): BOOLEAN; 283 | PROCEDURE Pt2Rect (pt1,pt2: Point; VAR dstRect: Rect); 284 | 285 | 286 | { Graphical Operations on Rectangles } 287 | 288 | PROCEDURE FrameRect (r: Rect); 289 | PROCEDURE PaintRect (r: Rect); 290 | PROCEDURE EraseRect (r: Rect); 291 | PROCEDURE InvertRect (r: Rect); 292 | PROCEDURE FillRect (r: Rect; pat: Pattern); 293 | 294 | 295 | { RoundRect Routines } 296 | 297 | PROCEDURE FrameRoundRect (r: Rect; ovWd,ovHt: INTEGER); 298 | PROCEDURE PaintRoundRect (r: Rect; ovWd,ovHt: INTEGER); 299 | PROCEDURE EraseRoundRect (r: Rect; ovWd,ovHt: INTEGER); 300 | PROCEDURE InvertRoundRect (r: Rect; ovWd,ovHt: INTEGER); 301 | PROCEDURE FillRoundRect (r: Rect; ovWd,ovHt: INTEGER; pat: Pattern); 302 | 303 | 304 | { Oval Routines } 305 | 306 | PROCEDURE FrameOval (r: Rect); 307 | PROCEDURE PaintOval (r: Rect); 308 | PROCEDURE EraseOval (r: Rect); 309 | PROCEDURE InvertOval (r: Rect); 310 | PROCEDURE FillOval (r: Rect; pat: Pattern); 311 | 312 | 313 | { Arc Routines } 314 | 315 | PROCEDURE FrameArc (r: Rect; startAngle,arcAngle: INTEGER); 316 | PROCEDURE PaintArc (r: Rect; startAngle,arcAngle: INTEGER); 317 | PROCEDURE EraseArc (r: Rect; startAngle,arcAngle: INTEGER); 318 | PROCEDURE InvertArc (r: Rect; startAngle,arcAngle: INTEGER); 319 | PROCEDURE FillArc (r: Rect; startAngle,arcAngle: INTEGER; pat: Pattern); 320 | PROCEDURE PtToAngle (r: Rect; pt: Point; VAR angle: INTEGER); 321 | 322 | 323 | { Polygon Routines } 324 | 325 | FUNCTION OpenPoly: PolyHandle; 326 | PROCEDURE ClosePoly; 327 | PROCEDURE KillPoly (poly: PolyHandle); 328 | PROCEDURE OffsetPoly (poly: PolyHandle; dh,dv: INTEGER); 329 | PROCEDURE MapPoly (poly: PolyHandle; fromRect,toRect: Rect); 330 | PROCEDURE FramePoly (poly: PolyHandle); 331 | PROCEDURE PaintPoly (poly: PolyHandle); 332 | PROCEDURE ErasePoly (poly: PolyHandle); 333 | PROCEDURE InvertPoly (poly: PolyHandle); 334 | PROCEDURE FillPoly (poly: PolyHandle; pat: Pattern); 335 | 336 | 337 | { Region Calculations } 338 | 339 | FUNCTION NewRgn: RgnHandle; 340 | PROCEDURE DisposeRgn(rgn: RgnHandle); 341 | PROCEDURE CopyRgn (srcRgn,dstRgn: RgnHandle); 342 | PROCEDURE SetEmptyRgn(rgn: RgnHandle); 343 | PROCEDURE SetRectRgn(rgn: RgnHandle; left,top,right,bottom: INTEGER); 344 | PROCEDURE RectRgn (rgn: RgnHandle; r: Rect); 345 | PROCEDURE OpenRgn; 346 | PROCEDURE CloseRgn (dstRgn: RgnHandle); 347 | PROCEDURE OffsetRgn (rgn: RgnHandle; dh,dv: INTEGER); 348 | PROCEDURE MapRgn (rgn: RgnHandle; fromRect,toRect: Rect); 349 | PROCEDURE InsetRgn (rgn: RgnHandle; dh,dv: INTEGER); 350 | PROCEDURE SectRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle); 351 | PROCEDURE UnionRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle); 352 | PROCEDURE DiffRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle); 353 | PROCEDURE XorRgn (srcRgnA,srcRgnB,dstRgn: RgnHandle); 354 | FUNCTION EqualRgn (rgnA,rgnB: RgnHandle): BOOLEAN; 355 | FUNCTION EmptyRgn (rgn: RgnHandle): BOOLEAN; 356 | FUNCTION PtInRgn (pt: Point; rgn: RgnHandle): BOOLEAN; 357 | FUNCTION RectInRgn (r: Rect; rgn: RgnHandle): BOOLEAN; 358 | 359 | 360 | { Graphical Operations on Regions } 361 | 362 | PROCEDURE FrameRgn (rgn: RgnHandle); 363 | PROCEDURE PaintRgn (rgn: RgnHandle); 364 | PROCEDURE EraseRgn (rgn: RgnHandle); 365 | PROCEDURE InvertRgn (rgn: RgnHandle); 366 | PROCEDURE FillRgn (rgn: RgnHandle; pat: Pattern); 367 | 368 | 369 | { Graphical Operations on BitMaps } 370 | 371 | PROCEDURE ScrollRect(dstRect: Rect; dh,dv: INTEGER; updateRgn: rgnHandle); 372 | PROCEDURE CopyBits (srcBits,dstBits: BitMap; 373 | srcRect,dstRect: Rect; 374 | mode: INTEGER; 375 | maskRgn: RgnHandle); 376 | 377 | { Picture Routines } 378 | 379 | FUNCTION OpenPicture(picFrame: Rect): PicHandle; 380 | PROCEDURE ClosePicture; 381 | PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect); 382 | PROCEDURE PicComment(kind,dataSize: INTEGER; dataHandle: QDHandle); 383 | PROCEDURE KillPicture(myPicture: PicHandle); 384 | 385 | 386 | { The Bottleneck Interface: } 387 | 388 | PROCEDURE SetStdProcs(VAR procs: QDProcs); 389 | PROCEDURE StdText (count: INTEGER; textAddr: QDPtr; numer,denom: Point); 390 | PROCEDURE StdLine (newPt: Point); 391 | PROCEDURE StdRect (verb: GrafVerb; r: Rect); 392 | PROCEDURE StdRRect (verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER); 393 | PROCEDURE StdOval (verb: GrafVerb; r: Rect); 394 | PROCEDURE StdArc (verb: GrafVerb; r: Rect; startAngle,arcAngle: INTEGER); 395 | PROCEDURE StdPoly (verb: GrafVerb; poly: PolyHandle); 396 | PROCEDURE StdRgn (verb: GrafVerb; rgn: RgnHandle); 397 | PROCEDURE StdBits (VAR srcBits: BitMap; VAR srcRect,dstRect: Rect; 398 | mode: INTEGER; maskRgn: RgnHandle); 399 | PROCEDURE StdComment (kind,dataSize: INTEGER; dataHandle: QDHandle); 400 | FUNCTION StdTxMeas (count: INTEGER; textAddr: QDPtr; 401 | VAR numer,denom: Point; VAR info: FontInfo): INTEGER; 402 | PROCEDURE StdGetPic (dataPtr: QDPtr; byteCount: INTEGER); 403 | PROCEDURE StdPutPic (dataPtr: QDPtr; byteCount: INTEGER); 404 | 405 | 406 | { Misc Utility Routines } 407 | 408 | FUNCTION GetPixel (h,v: INTEGER): BOOLEAN; 409 | FUNCTION Random: INTEGER; 410 | PROCEDURE StuffHex (thingptr: QDPtr; s:Str255); 411 | PROCEDURE ForeColor (color: LongInt); 412 | PROCEDURE BackColor (color: LongInt); 413 | PROCEDURE ColorBit (whichBit: INTEGER); 414 | 415 | 416 | IMPLEMENTATION 417 | 418 | {$I QuickDraw2.text } 419 | -------------------------------------------------------------------------------- /QuickDraw2.p: -------------------------------------------------------------------------------- 1 | { QuickDraw2.text: Implementation part of QuickDraw } 2 | 3 | {$S Graf } 4 | 5 | TYPE FMOutPtr = ^FMOutRec; 6 | FMOutrec = PACKED RECORD 7 | errNum: INTEGER; { used only for GrafError } 8 | fontHandle: QDHandle; { handle to font } 9 | bold: 0..255; { how much to smear horiz } 10 | italic: 0..255; { how much to shear } 11 | ulOffset: 0..255; { pixels below baseline } 12 | ulShadow: 0..255; { how big is the halo } 13 | ulThick: 0..255; { how thick is the underline } 14 | shadow: 0..255; { 0,1,2,or 3 only } 15 | extra: -128..127; { extra white dots each char } 16 | ascent: 0..255; { ascent measure for font } 17 | descent: 0..255; { descent measure for font } 18 | widMax: 0..255; { width of widest char } 19 | leading: -128..127; { leading between lines } 20 | unused: 0..255; 21 | numer: Point; { use this modified scale to } 22 | denom: Point; { draw or measure text with } 23 | END; 24 | 25 | 26 | 27 | VAR wideOpen: RgnHandle; { a dummy rectangular region, read-only } 28 | wideMaster: RgnPtr; 29 | wideData: Region; 30 | rgnBuf: QDHandle; { point saving buffer for OpenRgn } 31 | rgnIndex: INTEGER; { current bytes used in rgnBuf } 32 | rgnMax: INTEGER; { max bytes allocated so far to rgnBuf } 33 | playPic: PicHandle; { used by StdGetPic } 34 | QDSpare0: INTEGER; { unused word } 35 | thePoly: PolyHandle; { the current polygon being defined } 36 | polyMax: INTEGER; { max bytes allocated so far to thePoly } 37 | patAlign: Point; { to align pattern during DrawPicture } 38 | fixTxWid: Fixed; { Fixed Point width from StdTxMeas. } 39 | fontPtr: FMOutPtr; { the last font used, used by DrawText } 40 | playIndex: LongInt; { used by StdGetPic during DrawPicture } 41 | QDSpare3: INTEGER; { unused word } 42 | QDSpare4: INTEGER; { unused word } 43 | QDSpare5: INTEGER; { unused word } 44 | QDSpare6: INTEGER; { unused word } 45 | QDSpare7: INTEGER; { unused word } 46 | QDSpare8: INTEGER; { unused word } 47 | QDSpare9: INTEGER; { unused word } 48 | QDSpareA: INTEGER; { unused word } 49 | QDSpareB: INTEGER; { unused word } 50 | QDSpareC: INTEGER; { unused word } 51 | QDSpareD: INTEGER; { unused word } 52 | 53 | 54 | 55 | 56 | { grafPort routines } 57 | 58 | PROCEDURE InitGraf; EXTERNAL; 59 | PROCEDURE OpenPort; EXTERNAL; 60 | PROCEDURE InitPort; EXTERNAL; 61 | PROCEDURE ClosePort; EXTERNAL; 62 | PROCEDURE GrafDevice; EXTERNAL; 63 | PROCEDURE SetPort; EXTERNAL; 64 | PROCEDURE GetPort; EXTERNAL; 65 | PROCEDURE SetPortBits; EXTERNAL; 66 | PROCEDURE PortSize; EXTERNAL; 67 | PROCEDURE MovePortTo; EXTERNAL; 68 | PROCEDURE SetOrigin; EXTERNAL; 69 | PROCEDURE SetClip; EXTERNAL; 70 | PROCEDURE GetClip; EXTERNAL; 71 | PROCEDURE ClipRect; EXTERNAL; 72 | PROCEDURE BackPat; EXTERNAL; 73 | 74 | 75 | { cursor routines } 76 | 77 | PROCEDURE InitCursor; EXTERNAL; 78 | PROCEDURE SetCursor; EXTERNAL; 79 | PROCEDURE HideCursor; EXTERNAL; 80 | PROCEDURE ShowCursor; EXTERNAL; 81 | PROCEDURE ObscureCursor; EXTERNAL; 82 | 83 | 84 | { text routines } 85 | 86 | PROCEDURE TextFont; EXTERNAL; 87 | PROCEDURE TextFace; EXTERNAL; 88 | PROCEDURE TextMode; EXTERNAL; 89 | PROCEDURE TextSize; EXTERNAL; 90 | PROCEDURE SpaceExtra; EXTERNAL; 91 | PROCEDURE DrawChar; EXTERNAL; 92 | PROCEDURE DrawString; EXTERNAL; 93 | PROCEDURE DrawText; EXTERNAL; 94 | FUNCTION CharWidth; EXTERNAL; 95 | FUNCTION StringWidth; EXTERNAL; 96 | FUNCTION TextWidth; EXTERNAL; 97 | PROCEDURE GetFontInfo; EXTERNAL; 98 | 99 | 100 | { line routines } 101 | 102 | PROCEDURE HidePen; EXTERNAL; 103 | PROCEDURE ShowPen; EXTERNAL; 104 | PROCEDURE GetPen; EXTERNAL; 105 | PROCEDURE GetPenState; EXTERNAL; 106 | PROCEDURE SetPenState; EXTERNAL; 107 | PROCEDURE PenSize; EXTERNAL; 108 | PROCEDURE PenMode; EXTERNAL; 109 | PROCEDURE PenPat; EXTERNAL; 110 | PROCEDURE PenNormal; EXTERNAL; 111 | PROCEDURE MoveTo; EXTERNAL; 112 | PROCEDURE Move; EXTERNAL; 113 | PROCEDURE LineTo; EXTERNAL; 114 | PROCEDURE Line; EXTERNAL; 115 | 116 | 117 | { rectangle calculations } 118 | 119 | PROCEDURE SetRect; EXTERNAL; 120 | FUNCTION EqualRect; EXTERNAL; 121 | FUNCTION EmptyRect; EXTERNAL; 122 | PROCEDURE OffsetRect; EXTERNAL; 123 | PROCEDURE MapRect; EXTERNAL; 124 | PROCEDURE InsetRect; EXTERNAL; 125 | FUNCTION SectRect; EXTERNAL; 126 | PROCEDURE UnionRect; EXTERNAL; 127 | FUNCTION PtInRect; EXTERNAL; 128 | PROCEDURE Pt2Rect; EXTERNAL; 129 | 130 | 131 | { graphical operations on rectangles } 132 | 133 | PROCEDURE FrameRect; EXTERNAL; 134 | PROCEDURE PaintRect; EXTERNAL; 135 | PROCEDURE EraseRect; EXTERNAL; 136 | PROCEDURE InvertRect; EXTERNAL; 137 | PROCEDURE FillRect; EXTERNAL; 138 | 139 | 140 | { graphical operations on RoundRects } 141 | 142 | PROCEDURE FrameRoundRect; EXTERNAL; 143 | PROCEDURE PaintRoundRect; EXTERNAL; 144 | PROCEDURE EraseRoundRect; EXTERNAL; 145 | PROCEDURE InvertRoundRect; EXTERNAL; 146 | PROCEDURE FillRoundRect; EXTERNAL; 147 | 148 | 149 | { graphical operations on Ovals } 150 | 151 | PROCEDURE FrameOval; EXTERNAL; 152 | PROCEDURE PaintOval; EXTERNAL; 153 | PROCEDURE EraseOval; EXTERNAL; 154 | PROCEDURE InvertOval; EXTERNAL; 155 | PROCEDURE FillOval; EXTERNAL; 156 | 157 | 158 | { Arc routines } 159 | 160 | PROCEDURE FrameArc; EXTERNAL; 161 | PROCEDURE PaintArc; EXTERNAL; 162 | PROCEDURE EraseArc; EXTERNAL; 163 | PROCEDURE InvertArc; EXTERNAL; 164 | PROCEDURE FillArc; EXTERNAL; 165 | PROCEDURE PtToAngle; EXTERNAL; 166 | 167 | 168 | { polygon routines } 169 | 170 | FUNCTION OpenPoly; EXTERNAL; 171 | PROCEDURE ClosePoly; EXTERNAL; 172 | PROCEDURE KillPoly; EXTERNAL; 173 | PROCEDURE OffsetPoly; EXTERNAL; 174 | PROCEDURE MapPoly; EXTERNAL; 175 | 176 | PROCEDURE FramePoly; EXTERNAL; 177 | PROCEDURE PaintPoly; EXTERNAL; 178 | PROCEDURE ErasePoly; EXTERNAL; 179 | PROCEDURE InvertPoly; EXTERNAL; 180 | PROCEDURE FillPoly; EXTERNAL; 181 | 182 | 183 | { region calculations } 184 | 185 | FUNCTION NewRgn; EXTERNAL; 186 | PROCEDURE DisposeRgn; EXTERNAL; 187 | PROCEDURE OpenRgn; EXTERNAL; 188 | PROCEDURE CloseRgn; EXTERNAL; 189 | PROCEDURE OffsetRgn; EXTERNAL; 190 | PROCEDURE MapRgn; EXTERNAL; 191 | PROCEDURE InsetRgn; EXTERNAL; 192 | PROCEDURE SectRgn; EXTERNAL; 193 | PROCEDURE CopyRgn; EXTERNAL; 194 | PROCEDURE SetEmptyRgn; EXTERNAL; 195 | PROCEDURE SetRectRgn; EXTERNAL; 196 | PROCEDURE RectRgn; EXTERNAL; 197 | PROCEDURE UnionRgn; EXTERNAL; 198 | PROCEDURE DiffRgn; EXTERNAL; 199 | PROCEDURE XorRgn; EXTERNAL; 200 | FUNCTION EqualRgn; EXTERNAL; 201 | FUNCTION EmptyRgn; EXTERNAL; 202 | FUNCTION PtInRgn; EXTERNAL; 203 | FUNCTION RectInRgn; EXTERNAL; 204 | 205 | 206 | { graphical operations on Regions } 207 | 208 | PROCEDURE FrameRgn; EXTERNAL; 209 | PROCEDURE PaintRgn; EXTERNAL; 210 | PROCEDURE EraseRgn; EXTERNAL; 211 | PROCEDURE InvertRgn; EXTERNAL; 212 | PROCEDURE FillRgn; EXTERNAL; 213 | 214 | 215 | { BitMap routines } 216 | 217 | PROCEDURE CopyBits; EXTERNAL; 218 | PROCEDURE ScrollRect; EXTERNAL; 219 | 220 | 221 | { Picture routines } 222 | 223 | FUNCTION OpenPicture; EXTERNAL; 224 | PROCEDURE ClosePicture; EXTERNAL; 225 | PROCEDURE KillPicture; EXTERNAL; 226 | PROCEDURE DrawPicture; EXTERNAL; 227 | PROCEDURE PicComment; EXTERNAL; 228 | 229 | 230 | { BottleNeck routines } 231 | 232 | PROCEDURE StdText; EXTERNAL; 233 | PROCEDURE StdLine; EXTERNAL; 234 | PROCEDURE StdRect; EXTERNAL; 235 | PROCEDURE StdRRect; EXTERNAL; 236 | PROCEDURE StdOval; EXTERNAL; 237 | PROCEDURE StdArc; EXTERNAL; 238 | PROCEDURE StdPoly; EXTERNAL; 239 | PROCEDURE StdRgn; EXTERNAL; 240 | PROCEDURE StdBits; EXTERNAL; 241 | PROCEDURE StdComment; EXTERNAL; 242 | FUNCTION StdTxMeas; EXTERNAL; 243 | PROCEDURE StdGetPic; EXTERNAL; 244 | PROCEDURE StdPutPic; EXTERNAL; 245 | 246 | 247 | { misc utility routines } 248 | 249 | FUNCTION GetPixel; EXTERNAL; 250 | FUNCTION Random; EXTERNAL; 251 | PROCEDURE AddPt; EXTERNAL; 252 | PROCEDURE SubPt; EXTERNAL; 253 | PROCEDURE SetPt; EXTERNAL; 254 | FUNCTION EqualPt; EXTERNAL; 255 | PROCEDURE StuffHex; EXTERNAL; 256 | PROCEDURE LocalToGlobal; EXTERNAL; 257 | PROCEDURE GlobalToLocal; EXTERNAL; 258 | PROCEDURE ScalePt; EXTERNAL; 259 | PROCEDURE MapPt; EXTERNAL; 260 | PROCEDURE ForeColor; EXTERNAL; 261 | PROCEDURE BackColor; EXTERNAL; 262 | PROCEDURE ColorBit; EXTERNAL; 263 | PROCEDURE SetStdProcs; EXTERNAL; 264 | 265 | 266 | 267 | END. { of UNIT } 268 | -------------------------------------------------------------------------------- /QuickGlue.a: -------------------------------------------------------------------------------- 1 | ; File: QuickGlue.TEXT 2 | ;------------------------------------------------------------------ 3 | ; 4 | ; QuickDraw/Mac OS Interface 5 | ; 6 | ; written by Andy Hertzfeld 16-Sept-82 7 | ; 8 | ; (c) 1982 by Apple Computer, Inc. All rights reserved. 9 | ; 10 | ; QuickGlue is the QuickDraw/Mac OS interface. It is linked with QuickDraw and 11 | ; defines all of the externals required by QuickDraw except those of the 12 | ; font manager. All of these are very short and simple (memory manager traps or 13 | ; jumps through the graphics jump table). 14 | ; 15 | ; Modification History 16 | ; 17 | ; 16-Nov-82 AJH Made font manager interface go through graphics jump table 18 | ; 09-Feb-83 AJH Added LockHandle, UnLockHandle 19 | ; 17-Aug-83 SC Made all cursor jumps preserve A0 20 | ; 22-Apr-85 LAK Removed RInitGraf (coordinated with Bill clearing 21 | ; QDExist flag in InitGraf). 22 | ;------------------------------------------------------------------ 23 | 24 | .INCLUDE tlasm-SysTlQk.Sym 25 | 26 | ; 27 | ; Here is a subset of Unit Storage (the ones needed by 28 | ; QuickDraw), implemented by trapping to the Mac OS. 29 | ; 30 | 31 | 32 | ; 33 | ; FUNCTION NewHandle(byteCount: INTEGER): Ptr; 34 | ; 35 | .FUNC NewHandle,1 36 | ; 37 | MOVEQ #0,D0 ;clear out high part 38 | MOVE.L (SP)+,A1 ;get return address 39 | MOVE.W (SP)+,D0 ;get the byte count 40 | _NEWHANDLE ;ask OS to do request 41 | BNE.S MemFull ;if memory full, deep shit! 42 | MOVE.L A0,(SP) ;return result handle on stack 43 | JMP (A1) ;return to caller 44 | 45 | ; handle the memory full error by deep-shitting 46 | 47 | MemFull 48 | MOVEQ #DSMemFullErr,D0 49 | _SysError 50 | .WORD $A9FF ;invoke debugger just in case it comes back 51 | 52 | ; 53 | ; PROCEDURE SetSize(h: Handle; newSize: INTEGER); 54 | ; 55 | .DEF SetSize 56 | ; 57 | SetSize 58 | MOVEQ #0,D0 ;clear out high part 59 | MOVE.L (SP)+,A1 ;get return address 60 | MOVE.W (SP)+,D0 ;get the new size 61 | MOVE.L (SP)+,A0 ;get the handle 62 | _SETHANDLESIZE ;let OS do it 63 | BNE.S MemFull ;if out of memory, deepShit 64 | JMP (A1) ;return to caller 65 | 66 | ; 67 | ; PROCEDURE DisposeHandle(h: Handle); 68 | ; 69 | .PROC DisposeHandle,2 70 | ; 71 | MOVE.L (SP)+,A1 ;get return address 72 | MOVE.L (SP)+,A0 ;get parameter 73 | _DISPOSHANDLE ;let OS do work 74 | JMP (A1) ;return to caller 75 | ; 76 | ; PROCEDURE LockHandle(h: Handle); 77 | ; 78 | .PROC LockHandle 79 | 80 | MOVE.L 4(SP),A0 81 | BSET #7,(A0) 82 | MOVE.L (SP)+,(SP) 83 | RTS 84 | ; 85 | ; PROCEDURE UnLockHandle(h: handle); 86 | ; 87 | .PROC UnlockHandle 88 | 89 | MOVE.L 4(SP),A0 90 | BCLR #7,(A0) 91 | MOVE.L (SP)+,(SP) 92 | RTS 93 | 94 | ; 95 | ; Following is the QuickDraw cursor interface, implemented by accessing 96 | ; system routines through the graphics jump table 97 | ; 98 | .PROC CursorDisplay,0 99 | ; 100 | MOVE.L JShowCursor,-(SP) 101 | RTS 102 | ; 103 | .PROC CursorHide,0 104 | ; 105 | MOVE.L JHideCursor,-(SP) 106 | RTS 107 | ; 108 | .PROC CursorImage,0 109 | ; 110 | MOVE.L JSetCrsr,-(SP) 111 | RTS 112 | ; 113 | .PROC CursorInit,0 114 | ; 115 | MOVE.L JInitCrsr,-(SP) 116 | RTS 117 | ; 118 | .PROC CursorObscure,0 119 | ; 120 | MOVE.L JCrsrObscure,-(SP) 121 | RTS 122 | ; 123 | .PROC CursorShield,0 124 | ; 125 | MOVE.L JShieldCursor,-(SP) 126 | RTS 127 | ; 128 | .PROC ScreenAdress,0 129 | ; 130 | MOVE.L JScrnAddr,-(SP) 131 | RTS 132 | ; 133 | .PROC ScreenSize,0 134 | ; 135 | MOVE.L JScrnSize,-(SP) 136 | RTS 137 | ; 138 | .PROC FMSwapFont,0 139 | 140 | MOVE.L JSwapFont,-(SP) 141 | RTS 142 | 143 | 144 | 145 | .END 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QuickDraw 2 | ========= 3 | 4 | Bill Atkinson's original QuickDraw implementation, from The [Computer History Museum](http://www.computerhistory.org/highlights/macpaint/) -------------------------------------------------------------------------------- /RRects.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | 3 | ;----------------------------------------------------------- 4 | ; 5 | ; 6 | ; **** **** ***** *** ***** *** 7 | ; * * * * * * * * * * 8 | ; * * * * * * * * 9 | ; **** **** *** * * *** 10 | ; * * * * * * * * 11 | ; * * * * * * * * * * 12 | ; * * * * ***** *** * *** 13 | ; 14 | ; 15 | ; procedures for operating on RoundRects. 16 | ; 17 | ; 18 | 19 | .PROC StdRRect,4 20 | .REF CheckPic,DPutPicByte,PutPicVerb,PutPicLong,PutPicRect 21 | .REF PutOval,PushVerb,DrawArc 22 | ;--------------------------------------------------------------- 23 | ; 24 | ; PROCEDURE StdRRect(verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER); 25 | ; 26 | ; A6 OFFSETS OF PARAMS AFTER LINK: 27 | ; 28 | PARAMSIZE .EQU 10 29 | VERB .EQU PARAMSIZE+8-2 ;GRAFVERB 30 | RECT .EQU VERB-4 ;LONG, ADDR OF RECT 31 | OVWD .EQU RECT-2 ;WORD 32 | OVHT .EQU OVWD-2 ;WORD 33 | 34 | LINK A6,#0 ;NO LOCALS 35 | MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS 36 | MOVE.B VERB(A6),D7 ;GET VERB 37 | JSR CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE 38 | BLE.S NOTPIC ;BRANCH IF NOT PICSAVE 39 | 40 | MOVE.B D7,-(SP) ;PUSH VERB 41 | JSR PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC 42 | ; 43 | ; CHECK FOR NEW OVAL SIZE 44 | ; 45 | MOVE.L PICSAVE(A3),A0 ;GET PICSAVE HANDLE 46 | MOVE.L (A0),A0 ;DE-REFERENCE PICSAVE 47 | MOVE.L OVHT(A6),D0 ;GET OVWD AND OVHT 48 | CMP.L PICOVSIZE(A0),D0 ;SAME AS CURRENT OVAL SIZE ? 49 | BEQ.S OVALOK ;YES, CONTINUE 50 | MOVE.L D0,PICOVSIZE(A0) ;NO, UPDATE STATE VARIABLE 51 | MOVE.L D0,-(SP) ;PUSH OVSIZE FOR PutPicLong CALL 52 | MOVEQ #$0B,D0 53 | JSR DPutPicByte ;PUT OVSIZE OPCODE 54 | JSR PutPicLong ;PUT NEW OVAL SIZE DATA 55 | 56 | OVALOK MOVEQ #$40,D0 ;PUT RRECT NOUN IN HI NIBBLE 57 | ADD D7,D0 ;PUT VERB IN LO NIBBLE 58 | MOVE.B D0,-(SP) ;PUSH OPCODE 59 | MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT 60 | JSR PutPicRect ;PUT OPCODE AND RECTANGLE 61 | 62 | NOTPIC MOVE.L RECT(A6),-(SP) ;PUSH ADDR OF RECT 63 | CLR.B -(SP) ;PUSH HOLLOW = FALSE 64 | TST.B D7 ;IS VERB FRAME ? 65 | BNE.S DOIT ;NO, CONTINUE 66 | TST.L RGNSAVE(A3) ;YES, IS RGNSAVE TRUE ? 67 | BEQ.S NOTRGN ;NO, CONTINUE 68 | 69 | MOVE.L RECT(A6),-(SP) ;YES, PUSH ADDR OF RECT 70 | MOVE.L OVHT(A6),-(SP) ;PUSH OVWD, OVHT 71 | MOVE.L RGNBUF(A4),-(SP) ;PUSH RGNBUF 72 | PEA RGNINDEX(A4) ;PUSH VAR RGNINDEX 73 | PEA RGNMAX(A4) ;PUSH VAR RGNMAX 74 | JSR PutOval ;ADD AN OVAL TO THERGN 75 | 76 | NOTRGN MOVE.B #1,(SP) ;REPLACE, PUSH HOLLOW = TRUE 77 | DOIT MOVE.L OVHT(A6),-(SP) ;PUSH OVWD,OVHT 78 | JSR PushVerb ;PUSH MODE AND PATTERN 79 | CLR -(SP) ;PUSH STARTANGLE = 0 80 | MOVE #360,-(SP) ;PUSH ARCANGLE = 360 81 | 82 | ; DrawArc(r,hollow,ovWd,ovHt,mode,pat,startAng,arcAng); 83 | 84 | JSR DrawArc 85 | 86 | MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS 87 | UNLINK PARAMSIZE,'STDRRECT' 88 | 89 | 90 | 91 | .PROC FrameRoundRect,3 92 | .DEF CallRRect,PaintRoundRect,EraseRoundRect 93 | .DEF InvertRoundRect,FillRoundRect 94 | .REF StdRRect 95 | ;-------------------------------------------------------- 96 | ; 97 | ; PROCEDURE FrameRoundRect(* r: Rect; ovWd,ovHt: INTEGER *); 98 | ; 99 | MOVEQ #FRAME,D0 ;VERB = FRAME 100 | BRA.S CallRRect ;SHARE COMMON CODE 101 | 102 | 103 | ;-------------------------------------------------------- 104 | ; 105 | ; PROCEDURE PaintRoundRect(* r: Rect; ovWd,ovHt: INTEGER *); 106 | ; 107 | PaintRoundRect 108 | MOVEQ #PAINT,D0 ;VERB = PAINT 109 | BRA.S CallRRect ;SHARE COMMON CODE 110 | 111 | 112 | ;-------------------------------------------------------- 113 | ; 114 | ; PROCEDURE EraseRoundRect(* r: Rect; ovWd,ovHt: INTEGER *); 115 | ; 116 | EraseRoundRect 117 | MOVEQ #ERASE,D0 ;VERB = ERASE 118 | BRA.S CallRRect ;SHARE COMMON CODE 119 | 120 | 121 | ;-------------------------------------------------------- 122 | ; 123 | ; PROCEDURE InvertRoundRect(* r: Rect; ovWd,ovHt: INTEGER *); 124 | ; 125 | InvertRoundRect 126 | MOVEQ #INVERT,D0 ;VERB = INVERT 127 | BRA.S CallRRect ;SHARE COMMON CODE 128 | 129 | 130 | ;-------------------------------------------------------- 131 | ; 132 | ; PROCEDURE FillRoundRect(r: Rect; ovWd,ovHt: INTEGER; pat: Pattern); 133 | ; 134 | FillRoundRect 135 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 136 | MOVE.L (SP)+,A1 ;POP ADDR OF PATTERN 137 | MOVE.L A0,-(SP) ;PUT RETURN ADDR BACK 138 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 139 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 140 | LEA FILLPAT(A0),A0 ;POINT TO FILLPAT 141 | MOVE.L (A1)+,(A0)+ ;COPY PAT INTO FILLPAT 142 | MOVE.L (A1)+,(A0)+ ;ALL EIGHT BYTES 143 | MOVEQ #FILL,D0 ;VERB = FILL 144 | BRA.S CallRRect ;SHARE COMMON CODE 145 | 146 | 147 | 148 | ;--------------------------------------------------------------- 149 | ; 150 | ; PROCEDURE CallRRect(r: Rect; ovWd,ovHt: INTEGER); 151 | ; 152 | ; code shared by FrameRoundRect, PaintRoundRect, EraseRoundRect, 153 | ; InvertRoundRect, and FillRoundRect. 154 | ; enter with verb in D0. 155 | ; 156 | CallRRect 157 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 158 | MOVE.L (SP)+,D1 ;POP ovWd and ovHt 159 | MOVE.L (SP)+,A1 ;POP ADDR OF RECT 160 | MOVE.B D0,-(SP) ;PUSH VERB 161 | MOVE.L A1,-(SP) ;PUSH ADDR OF RECT 162 | MOVE.L D1,-(SP) ;PUSH ovWd and ovHt 163 | MOVE.L A0,-(SP) ;RESTORE RETURN ADDR 164 | MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO LISAGRAF GLOBALS 165 | MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT 166 | MOVE.L GRAFPROCS(A0),D0 ;IS GRAFPROCS NIL ? 167 | LEA STDRRECT,A0 168 | BEQ.S USESTD ;YES, USE STD PROC 169 | MOVE.L D0,A0 170 | MOVE.L RRECTPROC(A0),A0 ;NO, GET PROC PTR 171 | USESTD JMP (A0) ;GO TO IT 172 | 173 | 174 | 175 | 176 | 177 | .END 178 | -------------------------------------------------------------------------------- /RgnOp.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | 3 | .FUNC RgnOp,7 4 | .REF SectScan,DiffScan,UnionScan,XorScan,InsetScan,SetSize 5 | ;------------------------------------------------------------------- 6 | ; 7 | ; FUNCTION RgnOp(rgnA,rgnB: RgnHandle; 8 | ; bufHandle: Handle; 9 | ; maxBytes: INTEGER; 10 | ; op,dh: INTEGER; 11 | ; okGrow: BOOLEAN): INTEGER; 12 | ; 13 | ; Computes the intersection, difference, union, or XOR of two regions, 14 | ; or the horizontal inset of one region, and stores the result as an 15 | ; unpacked array of sorted inversion points in bufHandle. Returns the 16 | ; number of points as the function value. BufHandle will be grown only 17 | ; if more space is needed needed and okGrow is true. 18 | ; 19 | ; OP = 0: SECT 20 | ; 2: DIFF A-B 21 | ; 4: UNION 22 | ; 6: XOR 23 | ; 8: HORIZ INSET 24 | ; 25 | ; 26 | ; A6 OFFSETS OF PARAMETERS AND LOCALS AFTER LINK: 27 | ; 28 | PARAMSIZE .EQU 20 ;TOTAL # BYTES 29 | RESULT .EQU PARAMSIZE+8 ;INTEGER, FUNCTION RESULT 30 | RGNA .EQU RESULT-4 ;LONG, RGNHANDLE 31 | RGNB .EQU RGNA-4 ;LONG, RGNHANDLE 32 | BUFHANDLE .EQU RGNB-4 ;LONG, HANDLE TO POINT BUFFER 33 | MAXBYTES .EQU BUFHANDLE-2 ;WORD 34 | OP .EQU MAXBYTES-2 ;WORD 35 | DH .EQU OP-2 ;WORD 36 | OKGROW .EQU DH-2 ;BOOLEAN 37 | 38 | SCAN1 .EQU -4 ;long 39 | SCAN2 .EQU SCAN1-4 ;long 40 | SCAN3 .EQU SCAN2-4 ;long 41 | SCAN4 .EQU SCAN3-4 ;long 42 | SCAN5 .EQU SCAN4-4 ;long 43 | NEXTA .EQU SCAN5-2 ;WORD 44 | NEXTB .EQU NEXTA-2 ;WORD 45 | VERT .EQU NEXTB-2 ;WORD 46 | BUFPTR .EQU VERT-4 ;LONG, ^POINT 47 | BUFLIMIT .EQU BUFPTR-4 ;LONG 48 | FAKEB .EQU BUFLIMIT-18 ;18 BYTE FAKE RGN DATA 49 | MASTERB .EQU FAKEB-4 ;LONG 50 | FAKEA .EQU MASTERB-18 ;18 BYTE FAKE RGN DATA 51 | MASTERA .EQU FAKEA-4 ;LONG 52 | CASEJMP .EQU MASTERA-4 ;LONG 53 | SAVESTK .EQU CASEJMP-4 ;LONG 54 | VARSIZE .EQU SAVESTK ;TOTAL BYTES OF LOCALS 55 | 56 | 57 | 58 | LINK A6,#VARSIZE ;ALLOCATE STACK FRAME 59 | MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS 60 | MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK PTR 61 | 62 | 63 | ;------------------------------------------------------------ 64 | ; 65 | ; DE-REFERENCE RGNA AND RGNB AND OFFSET TO FIRST RGNDATA. 66 | ; IF EITHER IS RECTANGULAR, REPLACE IT WITH AN EXPANDED ONE. 67 | ; 68 | LEA MASTERA(A6),A2 ;POINT TO FAKE AREA 69 | LEA RGNA(A6),A0 ;POINT TO RGNA HANDLE 70 | BSR EXPAND ;DE-REFERENCE AND EXPAND 71 | MOVE.L A0,A3 ;SAVE RGNA DATA PTR IN A3 72 | LEA RGNB(A6),A0 ;POINT TO RGNB HANDLE 73 | BSR EXPAND ;DE-REFERENCE AND EXPAND 74 | MOVE.L A0,A4 ;SAVE RGNB DATA PTR IN A4 75 | 76 | 77 | ;----------------------------------------------------------- 78 | ; 79 | ; SET UP A CASE JUMP BASED ON OP 80 | ; 81 | LEA SECTSCAN,A0 82 | MOVE OP(A6),D0 83 | BEQ.S CASEOK ;BR IF OP = SECT 84 | LEA DIFFSCAN,A0 85 | SUB #2,D0 86 | BEQ.S CASEOK ;BR IF OP = DIFF 87 | LEA UNIONSCAN,A0 88 | SUB #2,D0 89 | BEQ.S CASEOK ;BR IF OP = UNION 90 | LEA XORSCAN,A0 91 | SUB #2,D0 92 | BEQ.S CASEOK ;BR IF OP = XOR 93 | LEA INSETSCAN,A0 ;ELSE OP = INSET 94 | CASEOK MOVE.L A0,CASEJMP(A6) ;SAVE FOR LATER 95 | 96 | 97 | 98 | ;----------------------------------------------------------------- 99 | ; 100 | ; Calc bufSize based on StackAvail and allocate 5 scan buffers 101 | ; 102 | _StackAvail ;get stack avail in D0.L 103 | SUB.L #1024,D0 ;subtract slop factor 104 | CMP.L #200,D0 ;is result < 200 bytes ? 105 | BGE.S STKOK1 ;no, continue 106 | MOVE #40,D0 ;yes, make bufSize = 40 bytes 107 | BRA.S ALLOC ;and continue 108 | STKOK1 DIVS #5,D0 ;no, divide for 5 buffers 109 | BVC.S STKOK2 ;overflow ? 110 | MOVE #30000,D0 ;yes, use 30K bytes 111 | STKOK2 BCLR #0,D0 ;make bufSize even 112 | ALLOC SUB D0,SP ;allocate one buffer 113 | MOVE.L SP,SCAN1(A6) ;remember buffer pointer 114 | SUB D0,SP ;allocate one buffer 115 | MOVE.L SP,SCAN2(A6) ;remember buffer pointer 116 | SUB D0,SP ;allocate one buffer 117 | MOVE.L SP,SCAN3(A6) ;remember buffer pointer 118 | SUB D0,SP ;allocate one buffer 119 | MOVE.L SP,SCAN4(A6) ;remember buffer pointer 120 | SUB D0,SP ;allocate one buffer 121 | MOVE.L SP,SCAN5(A6) ;remember buffer pointer 122 | 123 | 124 | 125 | ;----------------------------------------------------------- 126 | ; 127 | ; INIT ASSORTED POINTERS 128 | ; 129 | MOVE.L BUFHANDLE(A6),A0 ;GET BUFHANDLE 130 | MOVE.L (A0),A0 ;DE-REFERENCE IT 131 | MOVE.L A0,BUFPTR(A6) ;BUFPTR := BUFSTART 132 | AND #$FFF8,MAXBYTES(A6) ;TRUNCATE TO A MULT OF 8 BYTES 133 | ADD MAXBYTES(A6),A0 134 | MOVE.L A0,BUFLIMIT(A6) ;BUFLIMIT:=BUFSTART+MAXBYTES 135 | MOVE.L SCAN1(A6),A0 136 | MOVE.L A0,D4 ;SCANA := @SCAN1 137 | MOVE #32767,D0 138 | MOVE D0,(A0) ;INIT SCANA TO EMPTY 139 | MOVE.L SCAN2(A6),A0 140 | MOVE.L A0,D5 ;SCANB := @SCAN2 141 | MOVE D0,(A0) ;INIT SCANB TO EMPTY 142 | MOVE.L SCAN3(A6),A0 143 | MOVE.L A0,D6 ;SCANC := @SCAN3 144 | MOVE D0,(A0) ;INIT SCANC TO EMPTY 145 | MOVE.L SCAN4(A6),A0 146 | MOVE.L A0,D7 ;TEMPSCAN := @SCAN4 147 | MOVE (A3)+,NEXTA(A6) ;NEXTA := FIRST VERT IN A 148 | MOVE (A4)+,NEXTB(A6) ;NEXTB := FIRST VERT IN B 149 | CMP #8,OP(A6) ;IS OP = INSET ? 150 | BNE.S NXTVERT ;NO, CONTINUE 151 | MOVE D0,NEXTB(A6) ;YES, NEXTB := 32767 152 | NXTVERT MOVE NEXTA(A6),D0 ;GET NEXT VERT IN A 153 | CMP NEXTB(A6),D0 ;WHICH COMES FIRST ? 154 | BEQ.S BOTH ;SAME, UPDATE BOTH RGNS 155 | BGT.S UPDATEB ;B, UPDATE RGNB ONLY 156 | BSR.S UPDATEA ;A, UPDATE RGNA ONLY 157 | BRA.S CALC ;CALC NEW C-SCAN 158 | 159 | 160 | UPDATEA MOVE NEXTA(A6),VERT(A6) ;VERT := NEXTA 161 | MOVE.L A3,A0 ;SRCA := PTRA 162 | MOVE.L D4,A1 ;SRCB := SCANA 163 | MOVE.L D7,A2 ;DSTC := TEMPSCAN 164 | JSR XORSCAN ;XORSCAN(PTRA,SCANA,TEMPSCAN) 165 | MOVE.L A0,A3 ;BUMP PTRA TO END OF SCAN 166 | MOVE (A3)+,NEXTA(A6) ;NEXTA := NEXT VERT 167 | EXG D4,D7 ;SWAP SCANA AND TEMPSCAN 168 | RTS ;RETURN TO LOCAL CALLER 169 | 170 | 171 | BOTH CMP #32767,D0 ;ARE BOTH VERTICALS 32767 ? 172 | BEQ DONE ;YES, WE'RE ALL FINISHED 173 | BSR.S UPDATEA ;UPDATE RGNA 174 | UPDATEB MOVE NEXTB(A6),VERT(A6) ;VERT := NEXTB 175 | MOVE.L A4,A0 ;SRCA := PTRB 176 | MOVE.L D5,A1 ;SRCB := SCANB 177 | MOVE.L D7,A2 ;DSTC := TEMPSCAN 178 | JSR XORSCAN ;XORSCAN(PTRB,SCANB,TEMPSCAN) 179 | MOVE.L A0,A4 ;BUMP PTRB TO END OF SCAN 180 | MOVE (A4)+,NEXTB(A6) ;NEXTB := NEXT VERT 181 | EXG D7,D5 ;SWAP SCANB AND TEMPSCAN 182 | 183 | ;--------------------------------------------------------- 184 | ; 185 | ; CALCULATE SECT, DIFF, UNION, XOR, OR INSET INTO SCANC 186 | ; 187 | CALC MOVE.L D4,A0 ;POINT TO SCANA 188 | MOVE.L D5,A1 ;POINT TO SCANB 189 | MOVE.L D7,A2 ;POINT TO TEMPSCAN 190 | MOVE DH(A6),D2 ;GET DH IN CASE INSET 191 | PEA CHANGES ;PUSH RETURN ADDR 192 | MOVE.L CASEJMP(A6),-(SP) ;PUSH CASE JUMP 193 | RTS ;DO CASE JSR 194 | 195 | 196 | ;------------------------------------------------------------- 197 | ; 198 | ; FIND ANY CHANGES NOT IN PREVIOUS SCANC, THEN UPDATE SCANC 199 | ; 200 | CHANGES MOVE.L D7,A0 ;GET TEMPSCAN 201 | MOVE.L D6,A1 ;GET SCANC 202 | MOVE.L SCAN5(A6),A2 ;GET OUTPUT SCAN 203 | JSR XORSCAN ;XorScan(tempScan,scanC,@SCAN5); 204 | EXG D7,D6 ;SWAP TEMPSCAN AND SCANC 205 | 206 | MOVE.L SCAN5(A6),A0 ;POINT TO OUTPUT SCAN 207 | MOVE.L BUFPTR(A6),A1 ;POINT TO DST POINT BUFFER 208 | MOVE.L BUFLIMIT(A6),A2 ;GET BUFLIMIT 209 | MOVE.L VERT(A6),D0 ;GET VERT COORD IN HI WORD 210 | BRA.S OUTTEST ;GO TO LOOP START 211 | OUTLOOP MOVE.W (A0)+,D0 ;GET LEFT HORIZ COORD 212 | MOVE.L D0,(A1)+ ;PUT LEFT POINT 213 | MOVE.W (A0)+,D0 ;GET RIGHT HORIZ COORD 214 | MOVE.L D0,(A1)+ ;PUT RIGHT POINT 215 | OUTTEST CMP.L A2,A1 ;IS BUFPTR >= BUFLIMIT ? 216 | BLO.S SIZEOK ;NO, CONTINUE 217 | 218 | 219 | ;----------------------------------------------------------- 220 | ; 221 | ; THE POINT BUFFER IS FULL, GROW IT IF OKGROW IS TRUE 222 | ; 223 | TST.B OKGROW(A6) ;ARE WE ALLOWED TO GROW ? 224 | BEQ ABORT ;NO, ABORT RGNOP 225 | MOVE.L A0,D1 ;YES, SAVE OUTPUT SCAN PTR 226 | MOVE.L RGNA(A6),A0 ;GET RGNA MASTER 227 | SUB.L (A0),A3 ;MAKE RGNA PTR RELATIVE 228 | MOVE.L RGNB(A6),A0 ;GET RGNB MASTER 229 | SUB.L (A0),A4 ;MAKE RGNB PTR RELATIVE 230 | MOVE.L BUFHANDLE(A6),A0 ;GET BUFHANDLE 231 | SUB.L (A0),A1 ;MAKE BUFPTR RELATIVE 232 | SUB.L (A0),A2 ;MAKE BUFLIMIT RELATIVE, = SIZE 233 | ADD #256,A2 ;BUMP BUFLIMIT 256 BYTES 234 | MOVEM.L D0-D2/A0-A2,-(SP) ;SAVE REGS 235 | MOVE.L A0,-(SP) ;PUSH BUFHANDLE 236 | MOVE.W A2,-(SP) ;PUSH NEW BYTECOUNT 237 | JSR SETSIZE ;GROW POINT BUFFER 238 | MOVEM.L (SP)+,D0-D2/A0-A2 ;RESTORE REGS 239 | MOVE.L RGNA(A6),A0 ;GET RGNA MASTER 240 | ADD.L (A0),A3 ;MAKE RGNA UN-RELATIVE 241 | MOVE.L RGNB(A6),A0 ;GET RGNB MASTER 242 | ADD.L (A0),A4 ;MAKE RGNB UN-RELATIVE 243 | MOVE.L BUFHANDLE(A6),A0 ;GET BUFHANDLE 244 | ADD.L (A0),A1 ;MAKE BUFPTR UN-RELATIVE 245 | ADD.L (A0),A2 ;MAKE BUFLIMIT UN-RELATIVE 246 | MOVE.L A2,BUFLIMIT(A6) ;UPDATE BUFLIMIT 247 | MOVE.L D1,A0 ;RESTORE OUTPUT SCAN PTR 248 | 249 | 250 | SIZEOK CMP #32767,(A0) ;END OF SCAN MARKER ? 251 | BNE OUTLOOP ;NO, GO FOR MORE 252 | MOVE.L A1,BUFPTR(A6) ;UPDATE BUFPTR 253 | BRA NXTVERT ;LOOP FOR NEXT VERT 254 | 255 | 256 | ;------------------------------------------------------------------------ 257 | ; 258 | ; LOCAL ROUTINE TO EXPAND A RECTANGULAR REGION TO ITS INVERSION POINTS. 259 | ; ENTER WITH ADDR OF RGNHANDLE IN A0, ADDR OF FAKE MASTER IN A2. 260 | ; RETURNS IN A0 DE-REFERENCED POINTER BUMPED TO FIRST RGNDATA, 261 | ; AND A2 BUMPED TO NEXT AVAILABLE FAKE MASTER. 262 | ; 263 | EXPAND MOVE.L (A0),A1 ;GET RGNHANDLE 264 | MOVE.L (A1),A1 ;DE-REFERENCE HANDLE 265 | CMP #10,RGNSIZE(A1) ;IS REGION RECTANGULAR ? 266 | BNE.S NOTRECT ;NO, DON'T EXPAND IT 267 | MOVE.L A2,(A0) ;POINT HANDLE TO FAKE MASTER 268 | LEA -6(A2),A0 ;POINT 10 BYTES BEFORE DATA 269 | MOVE.L A0,(A2)+ ;FILL IN FAKE MASTER 270 | MOVE.L RGNBBOX+TOPLEFT(A1),(A2)+ ;PUT TOP V AND LEFT H 271 | MOVE RGNBBOX+RIGHT(A1),(A2)+ ;PUT RIGHT HORIZ 272 | MOVE #32767,D0 273 | MOVE D0,(A2)+ ;PUT HORIZ TERMINATOR 274 | MOVE RGNBBOX+BOTTOM(A1),(A2)+ ;PUT BOTTOM VERT 275 | MOVE RGNBBOX+LEFT(A1),(A2)+ ;PUT LEFT HORIZ 276 | MOVE RGNBBOX+RIGHT(A1),(A2)+ ;PUT RIGHT HORIZ 277 | MOVE D0,(A2)+ ;PUT HORIZ TERMINATOR 278 | MOVE D0,(A2)+ ;PUT VERT TERMINATOR 279 | MOVE.L A0,A1 ;PUT FAKE RGNPTR IN A1 280 | NOTRECT LEA RGNDATA(A1),A0 ;OFFSET TO FIRST REGION DATA 281 | RTS ;AND RETURN 282 | 283 | 284 | ABORT MOVE.L A1,BUFPTR(A6) ;UPDATE BUFPTR 285 | DONE MOVE.L BUFPTR(A6),D0 ;GET BUFPTR 286 | MOVE.L BUFHANDLE(A6),A0 ;GET BUFHANDLE 287 | SUB.L (A0),D0 ;BYTES USED = BUFPTR - BUFSTART 288 | LSR #2,D0 ;DIV BY 4 FOR NPOINTS 289 | MOVE D0,RESULT(A6) ;RETURN NPOINTS 290 | MOVE.L SAVESTK(A6),SP ;STRIP SCAN BUFFERS 291 | MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS 292 | UNLINK PARAMSIZE,'RGNOP ' 293 | 294 | 295 | 296 | .PROC SectScan,3 297 | .DEF DiffScan,UnionScan 298 | ;--------------------------------------------------------- 299 | ; 300 | ; PROCEDURE SectScan(srcA,srcB,dstC: ScanPtr); 301 | ; 302 | ; Calculate the intersection, difference, or union of two inversion scans. 303 | ; 304 | ; Each input scan is a sorted array of integers terminated by 32767. 305 | ; The output scan contains the inversion coordinates for the result. 306 | ; 307 | ; INPUTS: A0 SRCA 308 | ; A1 SRCB 309 | ; A2 DSTC 310 | ; 311 | ; CLOBBERS D0-D3, A0-A2 312 | ; 313 | SECT CLR D2 ;RESET ASTATE OFF 314 | CLR D3 ;RESET BSTATE OFF 315 | BRA.S SHARE ;SHARE CODE 316 | DIFFSCAN CLR D2 ;RESET ASTATE OFF 317 | BRA.S UNION2 ;SHARE CODE 318 | UNIONSCAN MOVEQ #-1,D2 ;SET ASTATE ON 319 | UNION2 MOVEQ #-1,D3 ;SET BSTATE ON 320 | 321 | SHARE MOVE (A0)+,D0 ;GET NEXTA 322 | MOVE (A1)+,D1 ;GET NEXTB 323 | NEXT CMP D1,D0 ;IS NEXTA < NEXT B ? 324 | BLT.S ALESS ;YES, BRANCH 325 | BGT.S BLESS ;BR IF NEXTB IS LESS 326 | EQUAL CMP #32767,D0 ;ARE WE AT THE END ? 327 | BEQ.S DONE ;YES, QUIT 328 | CMP D3,D2 ;ARE ASTATE AND BSTATE SAME ? 329 | BNE.S SKIP0 ;NO, SKIP 330 | MOVE D0,(A2)+ ;YES, PUT CHANGE 331 | SKIP0 MOVE (A0)+,D0 ;GET NEW NEXTA 332 | NOT D2 ;TOGGLE ASTATE 333 | MOVE (A1)+,D1 ;GET NEW NEXTB 334 | NOT D3 ;TOGGLE BSTATE 335 | BRA NEXT ;LOOP FOR MORE 336 | ALESS TST D3 ;TEST BSTATE 337 | BEQ.S SKIP1 ;SKIP IF NOT TRUE 338 | MOVE D0,(A2)+ ;PUT NEXTA 339 | SKIP1 MOVE (A0)+,D0 ;GET NEW NEXTA 340 | NOT D2 ;AND TOGGLE ASTATE 341 | BRA NEXT ;LOOP FOR MORE 342 | BLESS TST D2 ;TEST ASTATE 343 | BEQ.S SKIP2 ;SKIP IF NOT TRUE 344 | MOVE D1,(A2)+ ;PUT NEXTB 345 | SKIP2 MOVE (A1)+,D1 ;GET NEW NEXTB 346 | NOT D3 ;AND TOGGLE BSTATE 347 | BRA NEXT ;LOOP FOR MORE 348 | DONE MOVE #32767,(A2)+ ;PUT END MARKER INTO DST 349 | RTS 350 | 351 | 352 | .PROC InsetScan,3 353 | .DEF XorScan 354 | ;--------------------------------------------------------- 355 | ; 356 | ; PROCEDURE InsetScan(src,dst: ScanPtr; dh: INTEGER); 357 | ; 358 | ; Horizontally inset an inversion scan by dh; 359 | ; 360 | ; The input scan is a sorted array of integers terminated by 32767. 361 | ; The output scan contains the inversion coordinates for the inset. 362 | ; 363 | ; INPUTS: A0 SRC 364 | ; A2 DST 365 | ; D2 DH 366 | ; 367 | ; CLOBBERS D0-D1/A0-A2 368 | ; 369 | TST D2 ;IS DH NEG ? 370 | BLT.S OUTSET ;YES, OUTSET 371 | 372 | ;--------------------------------------------------------------- 373 | ; 374 | ; GET EACH PAIR OF COORDS, INSET THEM, AND CANCEL IF THEY CROSS. 375 | ; 376 | INSET CMP #32767,(A0) ;CHECK FOR TERMINATOR 377 | BEQ.S DONE ;QUIT WHEN FOUND 378 | MOVE (A0)+,D0 ;GET LEFT COORD 379 | MOVE (A0)+,D1 ;GET RIGHT COORD 380 | ADD.W D2,D0 ;ADD DH TO LEFT 381 | SUB.W D2,D1 ;SUB DH FROM RIGHT 382 | CMP D1,D0 ;IS LEFT >= RIGHT ? 383 | BGE.S INSET ;YES, SKIP BOTH 384 | MOVE D0,(A2)+ ;PUT LEFT COORD TO DST 385 | MOVE D1,(A2)+ ;PUT RIGHT COORD TO DST 386 | BRA.S INSET ;LOOP ENTIRE SCAN 387 | 388 | 389 | ;------------------------------------------------------------------ 390 | ; 391 | ; GET EACH PAIR OF COORDS, OUTSET THEM, AND CANCEL IF THEY CROSS. 392 | ; 393 | OUTSET MOVE #-32767,A1 ;OLDRIGHT := -32767 394 | BRA.S START ;GO TO LOOP START 395 | OUTLOOP MOVE (A0)+,D0 ;GET LEFT COORD 396 | MOVE (A0)+,D1 ;GET RIGHT COORD 397 | ADD D2,D0 ;ADD DH TO LEFT 398 | SUB D2,D1 ;SUB DH FROM RIGHT 399 | CMP A1,D0 ;IS LEFT <= OLDRIGHT ? 400 | BGT.S OUTOK ;NO, CONTINUE 401 | SUB #2,A2 ;YES, OVER-WRITE PREVIOUS RIGHT 402 | BRA.S OUTOK2 ;AND CONTINUE 403 | OUTOK MOVE D0,(A2)+ ;PUT LEFT COORD 404 | OUTOK2 MOVE D1,(A2)+ ;PUT RIGHT COORD 405 | MOVE D1,A1 ;OLDRIGHT := RIGHT 406 | START CMP #32767,(A0) ;CHECK FOR TERMINATOR 407 | BNE OUTLOOP ;AND LOOP ENTIRE SCAN 408 | 409 | DONE MOVE #32767,(A2)+ ;PUT TERMINATOR 410 | RTS 411 | 412 | 413 | ;-------------------------------------------------------------- 414 | ; 415 | ; LOCAL PROCEDURE XorScan(srcA,srcB,dstC: ScanPtr); 416 | ; 417 | ; Form the exclusive-or of two inversion scans. 418 | ; 419 | ; Each input scan is a sorted array of integers terminated by 32767. 420 | ; The output scan conatins all input coordinates from each, but 421 | ; with duplicate pairs cancelled. It also is terminated by 32767. 422 | ; 423 | ; INPUTS: A0 SRCA 424 | ; A1 SRCB 425 | ; A2 DSTC 426 | ; 427 | ; CLOBBERS D0-D1, A0-A2 428 | ; 429 | EQUAL CMP #32767,D0 ;ALL DONE ? 430 | BEQ.S DONE ;YES, QUIT 431 | XorScan MOVE (A0)+,D0 ;GET NEXT A 432 | MOVE (A1)+,D1 ;GET NEXT B 433 | NEXT CMP D1,D0 ;WHICH IS LESS, A OR B ? 434 | BEQ.S EQUAL ;THE SAME, SO CANCEL 435 | BLT.S ALESS ;A IS LESS 436 | BLESS MOVE D1,(A2)+ ;PUT B TO DST 437 | MOVE (A1)+,D1 ;GET NEXT B 438 | BRA.S NEXT ;LOOP FOR MORE 439 | ALESS MOVE D0,(A2)+ ;PUT A TO DST 440 | MOVE (A0)+,D0 ;GET NEXT A 441 | BRA.S NEXT ;LOOP FOR MORE 442 | 443 | 444 | .END 445 | -------------------------------------------------------------------------------- /SeekRgn.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;------------------------------------------------------------------ 3 | ; 4 | ; --> SEEKRGN.TEXT 5 | ; 6 | ; Routines to play back a region into a scanline buffer. 7 | ; 8 | ; 9 | 10 | 11 | .PROC INITRGN,0 12 | ;------------------------------------------------------ 13 | ; 14 | ; INPUTS: A0: RGNPTR 15 | ; A1: STATE RECORD 16 | ; D0: MINH 17 | ; D1: MAXH 18 | ; D2: BUFLEFT 19 | ; 20 | ; OUTPUTS: ALL FIELDS OF STATE RECORD, 21 | ; SCANBUF ALLOCATED ON STACK 22 | ; 23 | ; CLOBBERS: D0,D1,A0 24 | ; 25 | MOVE D0,MINH(A1) ;INSTALL MINH 26 | MOVE D1,MAXH(A1) ;INSTALL MAXH 27 | MOVE D2,LEFTH(A1) ;INSTALL LEFTH 28 | MOVE.L A0,RGNPTR(A1) ;INSTALL RGNPTR 29 | MOVE #-32767,THISV(A1) ;THISV := -32767 30 | MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := RGN BBOX TOP 31 | LEA RGNDATA(A0),A0 ;POINT TO FIRST DATA 32 | MOVE.L A0,DATAPTR(A1) ;INIT DATAPTR 33 | MOVE.L (SP)+,A0 ;POP RETURN ADDR 34 | SUB D2,D1 ;CALC BUFFER WIDTH IN DOTS 35 | LSR #5,D1 ;DIV BY 32 FOR #LONGS-1 36 | MOVE D1,SCANSIZE(A1) ;SAVE SCANSIZE FOR LATER 37 | 38 | CLRLOOP CLR.L -(SP) ;ALLOCATE AND CLEAR BUFFER 39 | DBRA D1,CLRLOOP 40 | MOVE.L SP,SCANBUF(A1) ;REMEMBER BUFFER START 41 | JMP (A0) ;RETURN 42 | 43 | 44 | 45 | .PROC SEEKRGN,0 46 | .REF MaskTab 47 | ;------------------------------------------------------------------ 48 | ; 49 | ; SeekRgn(rgnState,vert); 50 | ; 51 | ; ROUTINE TO PLAY BACK A REGION FORWARD OR BACKWARD UNTIL ITS SCAN 52 | ; BUFFER CONTAINS THE BITMAP FOR THE GIVEN VERTICAL COORDINATE. 53 | ; 54 | ; INPUTS: A1 POINTS TO A REGION STATE RECORD 55 | ; DO CONTAINS THE DESIRED VERTICAL COORD 56 | ; 57 | ; OUTPUTS: UPDATES THISV, NEXTV, DATAPTR, AND SCANBUF^ OF STATE RECORD 58 | ; D1-->1 IF CHANGE, 0 IF NO CHANGE. (Z-FLAG SET IF NO CHANGE) 59 | ; 60 | ; CLOBBERS: A0,D1. 61 | ; 62 | 63 | ;---------------------------------------------------- 64 | ; 65 | ; RETURN QUICKLY IF SCANBUF IS ALREADY CURRENT. 66 | ; 67 | CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ? 68 | BGE.S DOWN ;YES, BUMP DOWNWARD 69 | CMP THISV(A1),D0 ;IS DESIRED VERT < CURRENT VERT ? 70 | BLT.S UP ;YES, BUMP UPWARD 71 | CLR D1 ;ELSE REPORT NO CHANGES 72 | RTS ;AND RETURN 73 | 74 | 75 | ;----------------------------------------------------- 76 | ; 77 | ; TO MOVE UPWARDS, JUST RESET TO START AND MOVE DOWN. 78 | ; 79 | UP MOVE.L SCANBUF(A1),A0 ;POINT TO SCANBUF 80 | MOVE SCANSIZE(A1),D1 ;GET BUFFER SIZE 81 | CLRLP CLR.L (A0)+ ;CLEAR A LONG 82 | DBRA D1,CLRLP ;LOOP ENTIRE SCANBUF 83 | MOVE.L RGNPTR(A1),A0 ;GET RGNPTR 84 | MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := TOP VERT 85 | MOVE #-32767,THISV(A1) ;RESET THISV TO -32767 86 | LEA RGNDATA(A0),A0 ;POINT TO START OF REGION DATA 87 | MOVE.L A0,DATAPTR(A1) ;RESET DATAPTR 88 | CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ? 89 | BLT DONE ;NO, QUIT 90 | 91 | 92 | ;------------------------------------------------------ 93 | ; 94 | ; WHILE DESIRED VERT >= NEXTV DO BUMP DOWN. 95 | ; 96 | DOWN MOVEM.L D0-D6/A2-A3,-(SP) ;SAVE REGS 97 | MOVE D0,D2 ;SAVE VERT 98 | MOVE.L DATAPTR(A1),A2 ;POINT TO VERT COORD 99 | DOWN1 MOVE (A2)+,THISV(A1) ;UPDATE CURRENT VERT 100 | 101 | 102 | ;------------------------------------------------- 103 | ; 104 | ; GET LEFT AND RIGHT HORIZ COORDS 105 | ; AND TRIM AGAINST MINH AND MAXH 106 | ; 107 | NEXTHOR MOVE (A2)+,D3 ;GET LEFT COORD 108 | CMP #32767,D3 ;IS IT A TERMINATOR ? 109 | BEQ.S DONE1 ;YES, QUIT 110 | MOVE (A2)+,D4 ;GET RIGHT COORD 111 | CMP MINH(A1),D4 ;IS RIGHT <= MINH ? 112 | BLE NEXTHOR ;YES, IGNORE ON LEFT 113 | CMP MAXH(A1),D3 ;IS LEFT >= MAXH ? 114 | BGE NEXTHOR ;YES, IGNORE ON RIGHT 115 | CMP MINH(A1),D3 ;IS LEFT < MINH ? 116 | BGE.S LOK ;NO, CONTINUE 117 | MOVE MINH(A1),D3 ;YES, TRIM LEFT 118 | LOK CMP MAXH(A1),D4 ;IS RIGHT > MAXH ? 119 | BLE.S ROK ;NO, CONTINUE 120 | MOVE MAXH(A1),D4 ;YES, TRIM RIGHT 121 | 122 | ROK SUB LEFTH(A1),D3 ;MAKE COORDS REL TO BUFFER 123 | SUB LEFTH(A1),D4 124 | 125 | 126 | ;------------------------------------------ 127 | ; 128 | ; GET LEFTMASK AND RIGHTMASK 129 | ; 130 | LEA MASKTAB,A0 ;POINT TO MASK TABLE 131 | MOVEQ #$F,D0 ;GET MASK FOR LO 4 BITS 132 | 133 | MOVE D3,D5 ;COPY LEFT COORD 134 | AND D0,D5 ;CALC LEFT MOD 16 135 | ADD D5,D5 ;DOUBLE FOR INDEX 136 | MOVE 0(A0,D5),D5 ;GET MASK FROM TABLE 137 | NOT D5 ;INVERT FOR LEFTMASK 138 | 139 | MOVE D4,D6 ;COPY RIGHT COORD 140 | AND D0,D6 ;CALC RIGHT MOD 16 141 | ADD D6,D6 ;DOUBLE FOR INDEX 142 | MOVE 0(A0,D6),D6 ;GET RIGHTMASK IN D6 143 | 144 | 145 | ;------------------------------------------ 146 | ; 147 | ; CALC LEFTWORD, BUFPTR, WORDCOUNT 148 | ; 149 | LSR #4,D3 ;CONVERT DOTS TO WORDS 150 | MOVE.L SCANBUF(A1),A3 ;COPY BUFSTART 151 | ADD D3,A3 152 | ADD D3,A3 ;INIT BUFPTR TO LEFTWORD 153 | LSR #4,D4 ;CALC RIGHT DIV 16 154 | SUB D3,D4 ;WORDCOUNT:=RIGHTWORD-LEFTWORD 155 | BGT.S NOTIN1 ;BR IF NOT ALL IN ONE 156 | 157 | 158 | ;------------------------------------------ 159 | ; 160 | ; LEFT AND RIGHT ARE ALL IN ONE WORD 161 | ; 162 | AND D5,D6 ;COMBINE LEFT AND RIGHT MASKS 163 | EOR D6,(A3) ;XOR COMBINATION INTO BUFFER 164 | BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN 165 | 166 | 167 | ;------------------------------------------ 168 | ; 169 | ; NOT ALL IN ONE WORD. DO LEFT, MIDDLE IF ANY, THEN RIGHT 170 | ; 171 | NOTIN1 EOR D5,(A3)+ ;XOR LEFTMASK INTO BUFFER 172 | BRA.S TEST ;SEE IF ANY FULL WORDS 173 | INVLONG NOT.L (A3)+ ;INVERT 2 WHOLE WORDS 174 | TEST SUBQ #2,D4 ;ANY FULL WORDS LEFT ? 175 | BGT INVLONG ;YES, AT LEAST 2 176 | BLT.S ENDWORD ;NO, FINISH UP LAST WITH MASK 177 | NOT (A3)+ ;YES, DO LAST FULL WORD 178 | ENDWORD EOR D6,(A3) ;XOR RIGHTMASK INTO BUFFER 179 | BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN 180 | 181 | 182 | DONE1 MOVE.L A2,DATAPTR(A1) ;UPDATE DATAPTR 183 | MOVE (A2),NEXTV(A1) ;UPDATE NEXT VERT 184 | CMP NEXTV(A1),D2 ;IS DESIRED VERT >= NEXTV ? 185 | BGE DOWN1 ;YES, BUMP DOWN SOME MORE 186 | MOVEM.L (SP)+,D0-D6/A2-A3 ;RESTORE REGS 187 | DONE MOVEQ #1,D1 ;REPORT SCANLINE CHANGED 188 | RTS ;AND RETURN 189 | 190 | 191 | 192 | .END 193 | -------------------------------------------------------------------------------- /SortPoints.a: -------------------------------------------------------------------------------- 1 | .INCLUDE GRAFTYPES.TEXT 2 | ;------------------------------------------------------------------ 3 | ; 4 | ; --> SORTPOINTS.TEXT 5 | ; 6 | ; Routines to sort inversion points and cull duplicates. 7 | ; 8 | 9 | 10 | .PROC SortPoints 11 | ;------------------------------------------------------------- 12 | ; 13 | ; PROCEDURE SortPoints(ptBuf: PointsPtr; ptCount: INTEGER); 14 | ; 15 | ; PERFORMS A NON-RECURSIVE QUICKSORT ON AN ARRAY OF POINTS 16 | ; TO PUT THEM IN INCREASING VERT.HORIZ ORDER. 17 | ; 18 | ; RE-WROTE 5 SEPT 83 TO CUT DOWN WORST CASE STACK USAGE 19 | ; 20 | ; See Algorithms + Data Structures = Programs, p.80 21 | ; 22 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 23 | ; 24 | PARAMSIZE .EQU 6 25 | PTBUF .EQU PARAMSIZE+8-4 ;LONG 26 | PTCOUNT .EQU PTBUF-2 ;WORD 27 | 28 | 29 | 30 | LINK A6,#0 ;NO LOCAL VARIABLES 31 | MOVEM.L D3-D4/A2-A4,-(SP) ;SAVE REGS 32 | MOVE.L PTBUF(A6),A3 ;LEFTPTR:=START OF PT ARRAY 33 | MOVE A3,D3 34 | AND #3,D3 ;SET UP LOBITS FOR SORT 35 | CLR.L D0 36 | MOVE PTCOUNT(A6),D0 ;GET PTCOUNT 37 | BLE.S GOHOME ;DO NOTHING IF NO POINTS 38 | LSL.L #2,D0 ;QUAD PTCOUNT FOR BYTES 39 | MOVE.L A3,A4 40 | ADD.L D0,A4 ;ADD TO DSTSTART 41 | SUB #4,A4 ;RIGHTPTR:=DSTEND-4 42 | 43 | MOVE.L SP,D4 ;REMEMBER STACK MARKER 44 | MOVEM.L A3/A4,-(SP) ;PUSH LEFTPTR AND RIGHTPTR 45 | 46 | 47 | POPNXT MOVEM.L (SP)+,A3/A4 ;POP LEFTPTR AND RIGHTPTR 48 | 49 | 50 | SPLIT MOVE.L A3,A1 ;IPTR := LEFTPTR 51 | MOVE.L A4,A2 ;JPTR := RIGHTPTR 52 | ; 53 | ; CALC MIDPTR AND MIDPT 54 | ; 55 | MOVE.L A3,D0 ;ADD LEFTPTR 56 | ADD.L A4,D0 ;AND RIGHTPTR 57 | ROXR.L #1,D0 ;THEN DIVIDE BY 2 FOR MIDPTR 58 | AND #$FFFC,D0 ;TRUNC TO MULTIPLE OF 4 BYTES 59 | OR D3,D0 ;OR IN LOBITS FOR POINT BOUNDARY 60 | MOVE.L D0,A0 ;GET MIDPTR INTO A-REG 61 | MOVE H(A0),D1 ;GET MIDPT.H 62 | MOVE V(A0),D2 ;AND MIDPT.V 63 | 64 | SCAN 65 | ; 66 | ; WHILE IPTR^ < MIDPT DO BUMP IPTR TO RIGHT 67 | ; 68 | BRA.S TWO ;GO TO LOOP START 69 | ONE ADD #4,A1 ;BUMP IPTR TO RIGHT 70 | TWO CMP V(A1),D2 ;IS MIDPT.V > IPTR^.V ? 71 | BGT ONE ;YES, BUMP SOME MORE 72 | BLT.S THREE ;BR IF DONE WITH IPTR. 73 | CMP H(A1),D1 ;IF SAME VERT, LOOK AT HORIZ 74 | BGT ONE ;KEEP BUMPING IF MIDPT.H > IPTR^.H 75 | THREE 76 | 77 | 78 | ; 79 | ; WHILE JPTR^ > MIDPT DO BUMP JPTR TO LEFT 80 | ; 81 | BRA.S FIVE ;GO TO LOOP START 82 | FOUR SUB #4,A2 ;BUMP JPTR TO LEFT 83 | FIVE CMP V(A2),D2 ;IS MIDPT.V < JPTR^.V ? 84 | BLT FOUR ;YES, BUMP SOME MORE 85 | BGT.S SIX ;BR IF DONE BUMPING JPTR 86 | CMP H(A2),D1 ;IF SAME VERT, LOOK AT HORIZ 87 | BLT FOUR ;KEEP BUMPING IF MIDPT.H < JPTR^.H 88 | SIX 89 | 90 | ; 91 | ; if IPtr <= JPtr then swap IPtr^ and JPtr^, and bump both pointers 92 | ; 93 | CMP.L A2,A1 ;IS IPTR > JPTR ? 94 | BGT.S NOSWAP ;YES, ALL DONE 95 | MOVE.L (A1),D0 96 | MOVE.L (A2),(A1) 97 | MOVE.L D0,(A2) ;SWAP POINTS 98 | ADD #4,A1 ;BUMP IPTR TO RIGHT 99 | SUB #4,A2 ;BUMP JPTR TO LEFT 100 | 101 | ; 102 | ; repeat until this partitioning is complete, IPtr > JPtr 103 | ; 104 | NOSWAP CMPA.L A2,A1 ;IS IPTR > JPTR ? 105 | BLS SCAN ;NO, LOOP AGAIN 106 | 107 | ; 108 | ; IF i < right then stack request to sort right partition 109 | ; 110 | CMPA.L A4,A1 ;IS IPTR < RIGHTPTR ? 111 | BHS.S RIGHTOK ;YES, CONTINUE 112 | MOVEM.L A1/A4,-(SP) ;NO, PUSH IPTR,RIGHTPTR 113 | 114 | RIGHTOK MOVE.L A2,A4 ;RIGHTPTR := JPTR 115 | 116 | CMPA.L A4,A3 ;IS LEFTPTR >= RIGHTPTR ? 117 | BLO SPLIT ;NO, PARTITION AGAIN 118 | 119 | CMPA.L D4,SP ;IS STACK EMPTY YET ? 120 | BNE POPNXT ;NO, LOOP FOR MORE 121 | 122 | GOHOME MOVEM.L (SP)+,D3-D4/A2-A4 ;RESTORE REGS 123 | UNLINK PARAMSIZE,'SORTPOIN' 124 | 125 | 126 | 127 | 128 | 129 | .PROC CullPoints,2 130 | ;------------------------------------------------------------- 131 | ; 132 | ; PROCEDURE CullPoints(ptBuf: PointsPtr; VAR ptCount: INTEGER); 133 | ; 134 | ; CANCEL ANY DUPLICATE PAIRS OF POINTS IN AN ARRAY OF POINTS. 135 | ; 136 | ; 137 | ; A6 OFFSETS OF PARAMETERS AFTER LINK: 138 | ; 139 | PARAMSIZE .EQU 8 140 | PTBUF .EQU PARAMSIZE+8-4 ;LONG 141 | PTCOUNT .EQU PTBUF-4 ;LONG, VAR 142 | 143 | LINK A6,#0 ;NO LOCAL VARIABLES 144 | MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS 145 | MOVE.L PTCOUNT(A6),A0 ;GET VAR ADDR OF PTCOUNT 146 | MOVE (A0),D0 ;GET PTCOUNT 147 | BLE GOHOME ;DO NOTHING IF NO POINTS 148 | MOVE.L PTBUF(A6),A1 ;SRCPTR:=START PTR 149 | MOVE.L A1,A3 ;COPY START 150 | EXT.L D0 ;CLEAR HI WORD 151 | LSL.L #2,D0 ;QUAD PTCOUNT FOR BYTES 152 | ADD.L D0,A3 ;ADD TO START 153 | SUB #4,A3 ;LAST POINT IS AT END-4 154 | MOVE.L A1,D5 ;SAVE START FOR LATER 155 | MOVE.L A1,A2 ;DSTPTR:=START 156 | BRA.S WHILE1 ;GO TO LOOP START 157 | 158 | DELETE ADD #4,A1 ;SKIP OVER BOTH SRC POINTS 159 | BRA.S WHILE1 ;GO TO LOOP START 160 | MORE1 MOVE.L (A1)+,D0 ;GET CURRENT SRC POINT 161 | CMP.L (A1),D0 ;IS IT SAME AS NEXT ? 162 | BEQ DELETE ;YES, DELETE BOTH 163 | MOVE.L D0,(A2)+ ;NO, COPY TO DST 164 | WHILE1 CMP.L A3,A1 ;IS SRCPTR < LASTPTR ? 165 | BLT.S MORE1 ;YES, GO FOR MORE 166 | BGT.S DONE 167 | MOVE.L (A1)+,(A2)+ ;FINISH UP LAST POINT 168 | DONE MOVE.L A2,D0 ;GET DST PTR 169 | SUB.L D5,D0 ;SUBTRACT START PTR 170 | LSR #2,D0 ;DIV BY 4 FOR PTCOUNT 171 | MOVE.L PTCOUNT(A6),A0 ;GET VAR ADDR 172 | MOVE D0,(A0) ;UPDATE PTCOUNT TO REFLECT DELETIONS 173 | GOHOME MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGS 174 | UNLINK PARAMSIZE,'CULLPOIN' 175 | 176 | 177 | 178 | 179 | 180 | .END 181 | --------------------------------------------------------------------------------