	LOAD	'Macros.dump'
	INCLUDE 'Pict.equ'
	INCLUDE	'Driver.equ'

	IMPORT	D_MemoryError
	IMPORT	D_BeachBall
	
	IMPORT	Q_BgColor
	IMPORT	Q_ChExtra
	IMPORT	Q_DhDvText
	IMPORT	Q_DhText
	IMPORT	Q_DvText
	IMPORT	Q_FgColor
	IMPORT	D_GrowHandle
	IMPORT	Q_LongText
	IMPORT	D_NeedHandle
	IMPORT	Q_PixRect
	IMPORT	Q_PixRgn
	IMPORT	Q_Region
	IMPORT	Q_SpExtra
	IMPORT	Q_Text
	IMPORT	Q_TxFace
	IMPORT	Q_TxFont
	IMPORT	Q_TxMode
	IMPORT	Q_TxSize
	IMPORT	Q_addbytes
	IMPORT	Q_center
	IMPORT	Q_gotPScomm
	IMPORT	Q_op
	IMPORT	Q_pictSCB
	IMPORT	Q_picterr
	IMPORT	Q_theBGcolor
	IMPORT	Q_theChExtra
	IMPORT	Q_theFGcolor
	IMPORT	Q_theMask
	IMPORT	Q_thePnLoc
	IMPORT	Q_thePnSize
	IMPORT	Q_theSpExtra
	IMPORT	Q_theTxFont
	IMPORT	Q_theTxLoc
	IMPORT	Q_theTxMode

	ENTRY	Q_Angles
	ENTRY	Q_Arc
	ENTRY	Q_Arcs
	ENTRY	Q_ChangePictSize
	ENTRY	Q_Comments
	ENTRY	Q_Copy2
	ENTRY	Q_Copy4
	ENTRY	Q_CopyPt
	ENTRY	Q_DhDv
	ENTRY	Q_FakeDhDv
	ENTRY	Q_JustRect
	ENTRY	Q_linetext
	ENTRY	Q_manglePt
	ENTRY	Q_Mask
	ENTRY	Q_Nop
	ENTRY	Q_NudgePt
	ENTRY	Q_OvalSize
	ENTRY	Pict_pattern
	ENTRY	Q_PenSize
	ENTRY	Q_Pixels
	ENTRY	Q_Point
	ENTRY	Q_Poly
	ENTRY	Q_Polys
	ENTRY	Q_Rect
	ENTRY	Q_Rects
	ENTRY	Q_Regions
	ENTRY	Q_ShiftPen
	ENTRY	Q_Undef
	ENTRY	Q_Lfrom
	ENTRY	Q_Line
	ENTRY	Q_Slfrom
	ENTRY	Q_Sline
****************************************************************
*															  ;
*				   Picture mangling routines				  ;
*______________________________________________________________*
*															  ;
*		Some things should be brought to the attention of	 ;
*	whoever tries to D_Read this piece of spaghetti code.	   ;
*															  ;
*		First of all, all pictures are flipped and rotated	;
*	;as if* the picture were defined in 320-mode.  The actual ;
*	SCB for the D_New picture is no different from that of the  ;
*	old picture, but rectangles which look approximately	  ;
*	Q_square will still look approximately Q_square when rotated. ;
*	Such a rectangle will in fact be twice as wide as tall if ;
*	it's defined in 640 mode, so before rotation, horizontal  ;
*	values are doubled and vertical values are halved.  This  ;
*	can introduce a bit of round-off error, but it's		  ;
*	unavoidable.											  ;
*															  ;
*		A result of this mode-faking is that occasionally,	;
*	a 'ShortLine' opcode will have to be translated into a	;
*	'Q_Line' opcode, or a 'SLineFrom' into 'LineFrom'.  For	 ;
*	this reason (and to place mangled Q_Text), the location of  ;
*	the pen is maintained throughout the source picture.	  ;
*															  ;
*		Secondly, naively rotated and flipped lines will not  ;
*	appear to be mangled correctly, due to the somewhat	   ;
*	inconsistent way QuickDraw handles pensizes.  Thus, the   ;
*	pen size is also maintained, and used in Q_NudgePt.		 ;
*															  ;
*		Third, there is some number-hacking in Q_Point rotation ;
*	to prevent rotated pictures from creeping up and to the   ;
*	left.  There's a comment in Q_CopyPt describing the hack.   ;
*															  ;
*		Other notes concerning the mangling of pixel maps,	;
*	Q_Text, and Q_Regions can be found in their respective files. ;
*															  ;
*									   -- jge, 2/4/88		 ;
*															  ;
****************************************************************


****************************************************************
*
*   Q_ManglePict(oldpict:l,what:w) -> newpict:l -- the guts of the
*		picture routines.  Interprets the opcodes, distributing
*		the work to other routines.
*
****************************************************************
Q_ManglePict	PROC		EXPORT
			;Using Q_PictData
		EXPORT	Q_linetext
		EXPORT	Q_Rects
		EXPORT	Q_Arcs
		EXPORT	Q_Polys
		EXPORT	Q_Regions
		EXPORT	Q_Pixels
		EXPORT	Q_Comments
		EXPORT	Q_Nop
		EXPORT	Q_Copy2
		EXPORT	Q_Copy4
		EXPORT	Q_Copy6
		EXPORT	Q_Point
		EXPORT	Q_OvalSize
		EXPORT	Q_PenSize
		EXPORT	Q_Line
		EXPORT	Q_Lfrom
		EXPORT	Q_Sline
		EXPORT	Q_Slfrom
		EXPORT	Q_Rect
		EXPORT	Q_JustRect
		EXPORT	Q_FixRect
		EXPORT	Q_Arc
		EXPORT	Q_Poly
		EXPORT	Q_DhDv
		EXPORT	Q_ShiftPen
		EXPORT	Q_FakeDhDv
		EXPORT	Q_CopyPt
		EXPORT	Q_manglePt
		EXPORT	Q_NudgePt
		EXPORT	Q_Angles
		EXPORT	Pict_pattern
		EXPORT	Q_Mask
		EXPORT	Q_Undef
		EXPORT	Q_ChangePictSize
		export	oldpict
		export	what
		export	newpict
		export	Q_newsize
		export	oldptr
		export	newptr
		export	count
		export	thepoint
		export	temp

		input	~~oldpict:l,~~what:w
		output  ~~newpict:l

		local	oldsize:l,~~newsize:l
		local	~~oldptr:l,~~newptr:l
		local	oldend:l
		local	~~count:w,~~thepoint:l,~~temp:l


		begin	+b
		stz	  Q_picterr
*--------------------------------------------------------------*
*	Lock down the old pict, allocate the D_New one, copy the	;
*	header, and compute some useful information.			  ;
*--------------------------------------------------------------*
		movelong #0,Q_theTxFont
		movelong #0,Q_theSpExtra
		movelong #0,Q_theChExtra
		moveword #1,Q_thePnSize
		moveword #1,Q_thePnSize+2
		moveword #0,Q_theFGcolor
		moveword #15,Q_theBGcolor
		moveword #0,Q_theTxMode
		movelong #$ffffffff,Q_theMask
		movelong #$ffffffff,Q_theMask+4
		movelong #0,Q_thePnLoc
		movelong #0,Q_theTxLoc
		stz	  Q_gotPScomm

		pushlong <oldpict
		_Hlock

		movelong [<oldpict],<oldptr

		addword  [<oldptr]:#6,[<oldptr]:#2,Q_center		 ; get the Q_center
		addword  [<oldptr]:#8,[<oldptr]:#4,Q_center+2	   ;  of the pict.

		spacelong				; get the size
		pushlong <oldpict
		_GetHandleSize
		pulllong oldsize

		addlong  <oldptr,oldsize,oldend  ; compute end of pict

		movelong oldsize,<Q_newsize

		spacelong				; allocate the D_New pict handle
		pushlong <Q_newsize
		pushword #$8000		  ; X_Locked, while I use the pointer...
		jsl	  D_NeedHandle
		sta	  Q_picterr		 ; store the error code
		pulllong <newpict
		jcs	  accept		   ; (uh oh.)

		movelong [<newpict],<newptr	   ; ...which I get here!

		lda	  [<oldptr]		; D_Save the SCB
		and	  #$80
		sta	  Q_pictSCB

		beq	  centerok		; adjust for 640 mode?
		cmpw	 <what,#Q_rotr	  ; only if rotating!
		blt	  centerok

		lsr	  Q_center+2

centerok	jsl	  Q_Copy2		   ; copy SCB
		jsl	  Q_JustRect		; copy frame
		jsl	  Q_Nop			 ; copy version
*--------------------------------------------------------------*
*				D_Read and interpret the opcodes				;
*--------------------------------------------------------------*
loop	
		jsl		D_BeachBall
		cmpl	 <oldptr,oldend
		jeq	  accept
		jgt	  myabort

		moveword [<oldptr],Q_op	 ; get the opcode

		cmpw	 Q_op,#$15		 ; classify it.
		bgt	  it_draws		; is it a drawing opcode?

		jtl	  H_table1,Q_op	 ; if not, use the table and loop back.
		jcs	  abort
		brl	  loop

it_draws	cmpw	 Q_op,#$A1		 ; is it too big?
		jgt	  myabort

		lda	  Q_op			  ; get the high nybble...
		lsr	  a
		lsr	  a
		lsr	  a
		lsr	  a
		dec	  a			   ; ...and skip over $0X and $1X.
		dec	  a
		jtl	  H_table2
		jcs	  abort
		brl	  loop

myabort	moveword #$a501,Q_picterr  ; (JE error 1)

abort	pushlong <newpict
		_DisposeHandle

accept	lda		Q_Picterr
		return   a
*--------------------------------------------------------------*
*					The long routine table					;
*--------------------------------------------------------------*
H_table1	DC.L	Q_Nop	; 00 = Q_Nop
	DC.L	Q_Region	; 01 = clip Q_Region
	DC.L	Pict_pattern	; 02 = background D_Pattern
	DC.L	Q_TxFont	; 03 = Q_Text font
	DC.L	Q_TxFace	; 04 = Q_Text face
	DC.L	Q_TxMode	; 05 = Q_Text mode
	DC.L	Q_SpExtra	; 06 = space extra
	DC.L	Q_PenSize	; 07 = pen size
	DC.L	Q_Copy4	; 08 = pen mode
	DC.L	Pict_pattern	; 09 = pen D_Pattern
	DC.L	Pict_pattern	; 0A = fill D_Pattern
	DC.L	Q_OvalSize	; 0B = oval size
	DC.L	Q_Point	; 0C = origin
	DC.L	Q_TxSize	; 0D = Q_Text size
	DC.L	Q_FgColor	; 0E = foreground color
	DC.L	Q_BgColor	; 0F = background color
	DC.L	Q_Undef	; 10 = <undefined>
	DC.L	Q_Undef	; 11 = <version>
	DC.L	Q_ChExtra	; 12 = char extra
	DC.L	Q_Mask	; 13 = pen Q_Mask
	DC.L	Q_Copy4	; 14 = Q_Arc rot??
	DC.L	Q_Copy4	; 15 = font flags
*--------------------------------------------------------------*
*				   The short routine table					;
*--------------------------------------------------------------*
h_table2	DC.L	Q_linetext	; 2x = lines or Q_Text
	DC.L	Q_Rects	; 3x = rectangle
	DC.L	Q_Rects	; 4x = round Q_Rect
	DC.L	Q_Rects	; 5x = oval
	DC.L	Q_Arcs	; 6x = Q_Arc
	DC.L	Q_Polys	; 7x = polygon
	DC.L	Q_Regions	; 8x = Q_Region
	DC.L	Q_Pixels	; 9x = Q_Pixels
	DC.L	Q_Comments	; Ax = Q_Comments

****************************************************************
*															  ;
*				 DRAWING OPCODE-GROUP ROUTINES				;
*															  ;
****************************************************************
*--------------------------------------------------------------*
*	   Copy lines or Q_Text, depending on low nybble of Q_op	  ;
*--------------------------------------------------------------*
Q_linetext		;		

		lda	  Q_op			  ; get the low nybble
		and	  #$f

		jtl	  lt_table
		rtl

lt_table	DC.L	Q_Line	; 20 = Q_Line
	DC.L	Q_Lfrom	; 21 = Q_Line from
	DC.L	Q_Sline	; 22 = short Q_Line
	DC.L	Q_Slfrom	; 23 = short Q_Line from
	DC.L	Q_Undef	; 24 = <undefined>
	DC.L	Q_Undef	; 25 = <undefined>
	DC.L	Q_Undef	; 26 = <undefined>
	DC.L	Q_Undef	; 27 = <undefined>
	DC.L	Q_Text	; 28 = Q_Text
	DC.L	Q_DhText	; 29 = dh Q_Text
	DC.L	Q_DvText	; 2A = dv Q_Text
	DC.L	Q_DhDvText	; 2B = offset Q_Text
	DC.L	Q_LongText	; 2C = long Q_Text
	DC.L	Q_Undef	; 2D = <undefined>
	DC.L	Q_Undef	; 2E = <undefined>
	DC.L	Q_Undef	; 2F = <undefined>

*--------------------------------------------------------------*
*		   Copy Q_Rect opcode and parameters (if any)		   ;
*--------------------------------------------------------------*
Q_Rects		;		

		lda	  Q_op			  ; get the low three bits
		and	  #7
		cmp	  #5			  ; is this legal?
		jgt	  Q_Undef

		lda	  Q_op
		and	  #8			  ; same Q_Rect?
		jeq	  Q_Rect			; if not, copy the D_New one
		jmp	  Q_Nop			 ; otherwise, just the opcode will do

*--------------------------------------------------------------*
*			Copy Q_Arc opcode and parameters (if any)		   ;
*--------------------------------------------------------------*
Q_Arcs		;		

		lda	  Q_op			  ; get the low nybble
		and	  #$7
		cmp	  #$5			 ; is this legal?
		jgt	  Q_Undef

		lda	  Q_op
		and	  #$8			 ; same?
		jeq	  Q_Arc			 ; if not, copy the D_New one

		jsl	  Q_Nop			 ; if so, just copy the opcode
		jmp	  Q_Angles		  ;  and the Q_Angles

*--------------------------------------------------------------*
*			Copy Q_Poly opcode and parameters (if any)		  ;
*--------------------------------------------------------------*
Q_Polys		;		

		lda	  Q_op			  ; get the low nybble
		and	  #$7
		cmp	  #$5			 ; is this legal?
		jgt	  Q_Undef

		lda	  Q_op
		and	  #$8			 ; same?
		jeq	  Q_Poly			; if not, copy it
		jmp	  Q_Nop			 ; else, just copy the opcode

*--------------------------------------------------------------*
*		   Copy Q_Region opcode and parameters (if any)		 ;
*--------------------------------------------------------------*
Q_Regions		;		

		lda	  Q_op			  ; get the low nybble
		and	  #$7
		cmp	  #$5			 ; is this legal?
		jgt	  Q_Undef

		lda	  Q_op
		and	  #$8			 ; same?
		jeq	  Q_Region		  ; if not, copy the D_New one
		jmp	  Q_Nop			 ; else just copy the opcode

*--------------------------------------------------------------*
*			  Copy pixelmap opcode and parameters			 ;
*--------------------------------------------------------------*
Q_Pixels		;		

		cmpw	 Q_op,#$91
		jgt	  Q_Undef
		jeq	  Q_PixRgn
		jmp	  Q_PixRect

*--------------------------------------------------------------*
*				 Copy comment opcode and data				 ;
*	 Now mangles the first PSHandle comment appropriately	 ;
*--------------------------------------------------------------*
Q_Comments		;		

		cmpw	 Q_op,#$A1
		jne	  Q_Undef

		jsl	  Q_Copy2		   ; copy the opcode

		moveword [<oldptr],<temp   ; get the type
		jsl	  Q_Copy2		   ; copy it

		moveword [<oldptr],<count  ; get the data size
		jsl	  Q_Copy2		   ; copy it

		pushlong <oldptr		  ; copy the data
		pushlong <newptr
		pushword #0			  ; high word
		pushword <count		   ; low word
		_BlockMove

		cmpw	 <temp,#192	   ; PSHandle?
		bne	  notps
		lda	  Q_gotPScomm	   ; First one?
		bne	  notps

		jtl	  manglePS,<what

notPS	addwl	<count,<oldptr
		addwl	<count,<newptr

		clc
		rtl

ManglePS	DC.L	FlipHPS
	DC.L	FlipVPS
	DC.L	RotRPS
	DC.L	RotLPS
*--------------------------------------------------------------*
FlipHPS	rtl

*--------------------------------------------------------------*
FlipVPS	rtl

*--------------------------------------------------------------*
RotRPS	rtl

*--------------------------------------------------------------*
RotLPS	rtl

****************************************************************
*															  ;
*			  SIMPLE OPCODE INTERPRETING ROUTINES			 ;
*															  ;
****************************************************************
*--------------------------------------------------------------*
*					  Copy the Q_Nop opcode					 ;
*--------------------------------------------------------------*
Q_Nop		;		
Q_Copy2		;		

		moveword [<oldptr],[<newptr]	  ; store the opcode

		addwl	#2,<oldptr	   ; move the pointers
		addwl	#2,<newptr

		clc
		rtl

*--------------------------------------------------------------*
*		  Copy an opcode and its two byte parameter		   ;
*--------------------------------------------------------------*
Q_Copy4		;		

		movelong [<oldptr],[<newptr]	  ; store the opcode

		addwl	#4,<oldptr	   ; move the pointers
		addwl	#4,<newptr

		clc
		rtl

*--------------------------------------------------------------*
*		  Copy an opcode and its four byte parameter		  ;
*--------------------------------------------------------------*
Q_Copy6		;		

		movelong [<oldptr],[<newptr]	  ; store the opcode
		ldy	  #4
		moveword [<oldptr]:y,[<newptr]:y

		addwl	#6,<oldptr	   ; move the pointers
		addwl	#6,<newptr

		clc
		rtl

*--------------------------------------------------------------*
*		 Copy a Q_Point opcode and mangle its parameters		;
*--------------------------------------------------------------*
Q_Point		;		

		jsl	  Q_Nop			 ; copy the opcode
		jmp	  Q_CopyPt		  ; mangle and copy the Q_Point

*--------------------------------------------------------------*
*		  Copy an Q_OvalSize opcode and mangle its data		 ;
*--------------------------------------------------------------*
Q_OvalSize		;		

		jsl	  Q_Nop

		movelong [<oldptr],<thepoint	  ; get the value

		cmpw	 <what,#Q_rotr
		jlt	  keepit

		ldx	  <thepoint			   ; if I'm rotating,
		lda	  <thepoint+2			 ;  swap the components
		stx	  <thepoint+2
		sta	  <thepoint

		lda	  Q_pictSCB		 ; 640 mode?
		beq	  keepit
		asl	  <thepoint+2	  ; if so, double the D_New xcoord
		lsr	  <thepoint		; and halve the D_New ycoord

keepit	movelong <thepoint,[<newptr]	  ; store it!

		addwl	#4,<oldptr			  ; adjust the pointers
		addwl	#4,<newptr

		rtl

*--------------------------------------------------------------*
*	Copy a Q_PenSize opcode, mangle the data, and remember it   ;
*--------------------------------------------------------------*
Q_PenSize		;		

		jsl	  Q_OvalSize
		movelong <thepoint,Q_thePnSize	 ; it's left here by Q_OvalSize

		rtl

*--------------------------------------------------------------*
*			Copy a Q_Line opcode and mangle its data			;
*--------------------------------------------------------------*
Q_Line		;		

		jsl	  Q_Point				  ; opcode, pnloc
		jsl	  Q_NudgePt				; adjust for the Q_PenSize
		jsl	  Q_CopyPt
		movelong [<oldptr],Q_thePnLoc	  ; remember the pen location
		jmp	  Q_NudgePt

*--------------------------------------------------------------*
*		  Copy a Q_Line from opcode and mangle its data		 ;
*--------------------------------------------------------------*
Q_Lfrom		;		

		jsl	  Q_Nop					; opcode
		movelong [<oldptr],Q_thePnLoc	  ; remember the pen location
		jsl	  Q_CopyPt				 ; pnloc
		jmp	  Q_NudgePt				; adjust for the Q_PenSize

*--------------------------------------------------------------*
*		 Copy a short Q_Line opcode and mangle its data		 ;
*--------------------------------------------------------------*
Q_Sline		;		

		cmpw	 <what,#Q_rotr	  ; am I rotating?
		blt	  dosline
		lda	  Q_pictSCB		 ; in 640 mode?
		beq	  dosline

;			   moveword [<oldptr]:#6,a   ; I need to turn this into a Q_Line
;			   and	  #$ff			; opcode if I'm in 640 mode
;			   cmp	  #64
;			   blt	  dosline		 ; > P U N T <
;			   cmp	  #256-64
;			   bgt	  dosline
;
		movelong #2,Q_addbytes	 ; What luck.  Change the pict size
		jsl	  Q_ChangePictSize  ; to accomodate the different opcode

		moveword #$20,[<newptr]   ; (Q_Line)
		addwl	#2,<oldptr	   ; adjust the pointers
		addwl	#2,<newptr

		movelong [<oldptr],Q_thePnLoc	  ; remember the pen location
		jsl	  Q_CopyPt				 ; copy pen loc
		jsl	  Q_NudgePt				; adjust for Q_PenSize
		jsl	  Q_FakeDhDv			   ; account for dh, dv (see below)
		jmp	  Q_NudgePt				; adjust for Q_PenSize

dosline	jsl	  Q_Nop					; opcode
		movelong [<oldptr],Q_thePnLoc	  ; remember the pen location
		jsl	  Q_CopyPt				 ; pnloc
		jsl	  Q_NudgePt				; adjust for the Q_PenSize
		jmp	  Q_DhDv				   ; dh, dv

*--------------------------------------------------------------*
*	   Copy a short Q_Line from opcode and mangle its data	  ;
*--------------------------------------------------------------*
Q_Slfrom		;		

		cmpw	 <what,#Q_rotr	  ; am I rotating?
		blt	  doslfrom
		lda	  Q_pictSCB		 ; in 640 mode?
		beq	  doslfrom

;				moveword [<oldptr]:#2,a   ; I need to turn this into a Q_Line
;				and	  #$ff			; opcode if I'm in 640 mode!!
;				cmp	  #64
;				blt	  doslfrom		; > P U N T <
;				cmp	  #265-64
;				bgt	  doslfrom

		movelong #2,Q_addbytes	 ; What luck.  Change the pict size
		jsl	  Q_ChangePictSize  ; to accomodate the different opcode

		moveword #$21,[<newptr]   ; (LineFrom)
		addwl	#2,<oldptr	   ; adjust the pointers
		addwl	#2,<newptr

		jsl	  Q_FakeDhDv		; account for dh, dv (see below)
		jmp	  Q_NudgePt		 ; adjust for Q_PenSize

doslfrom	jsl	  Q_Nop			 ; opcode
		jmp	  Q_DhDv			; dh, dv

*--------------------------------------------------------------*
*		 Copy a Q_Rect opcode and mangle its parameters		 ;
*--------------------------------------------------------------*
Q_Rect		;		

		jsl	  Q_Nop			 ; copy the opcode

Q_JustRect		;		; ---- Copy ONLY the Q_Rect ----

		jsl	  Q_CopyPt		  ; copy the upper left Q_Point
		jsl	  Q_CopyPt		  ; copy the lower right Q_Point

		subwl	#8,<newptr	   ; back up a minute

Q_FixRect		;		; ---- Legalize Q_Rect at newptr ----

		ldy	  #4
		cmpw	 [<newptr],[<newptr]:y			; top and bottom ok?
		bmi	  tb_ok
		pushword [<newptr]					   ; if not, swap 'em.
		moveword [<newptr]:y,[<newptr]
		pullword [<newptr]:y

tb_ok	addwl	#2,<newptr

		cmpw	 [<newptr],[<newptr]:y			; left and right ok?
		bmi	  lr_ok
		pushword [<newptr]					   ; if not, swap 'em.
		moveword [<newptr]:y,[<newptr]
		pullword [<newptr]:y

lr_ok	addwl	#6,<newptr

		clc
		rtl

*--------------------------------------------------------------*
*			Copy an Q_Arc opcode and mangle its data			;
*--------------------------------------------------------------*
Q_Arc		;		

		jsl	  Q_Rect			; copy the opcode and mangle the Q_Rect
		jmp	  Q_Angles		  ; mangle the Q_Angles

*--------------------------------------------------------------*
*		   Copy a polygon opcode and mangle its data		  ;
*--------------------------------------------------------------*
Q_Poly		;		

		jsl	  Q_Nop			 ; copy the opcode

		moveword [<oldptr],<count		 ; get the size of the polygon
		jsl	  Q_Rect				   ; copy it and the bounds

		subword  <count,#10,<count		; subtract size and bounds
		lsr	  <count				  ;  and divide by 4
		lsr	  <count				  ;  to get number of points

ptloop	jsl	  Q_CopyPt		  ; mangle a Q_Point
		jsl	  Q_NudgePt		 ; adjust for the Q_PenSize
		dec	  <count		   ; one less left
		bne	  ptloop		  ; repeat until no more

		clc
		rtl

****************************************************************
*															  ;
*			   BOTTOM-LEVEL GRUNGE WORK ROUTINES			  ;
*															  ;
****************************************************************
*--------------------------------------------------------------*
*  Mangle and copy a distance parameter from oldptr to newptr  ;
*--------------------------------------------------------------*
*	   NOTE: At this Q_Point we know ;dh|<63 or Q_pictSCB=0	   ;
*--------------------------------------------------------------*
Q_DhDv		;		

		moveword [<oldptr],<thepoint

		jsl	  Q_ShiftPen		; adjust the pen location

		jtl	  mangleDist,<what

		moveword <thepoint,[<newptr]

		addwl	#2,<oldptr
		addwl	#2,<newptr

		clc
		rtl

mangleDist	DC.L	h_dist
	DC.L	v_dist
	DC.L	r_dist
	DC.L	l_dist

h_dist	lda	  <thepoint
		eor	  #$ff00		  ; flip the high byte (dx)
		clc
		adc	  #$100
		sta	  <thepoint
		rtl

v_dist	lda	  <thepoint
		xba					  ; reverse the bytes (switch dx and dy)
		eor	  #$ff00		  ; flip the low byte (dy)
		clc
		adc	  #$100
		xba					  ; reverse the bytes (switch dx and dy)
		sta	  <thepoint
		rtl

r_dist	lda	  <thepoint		; dx = dy; dy = -dx
		xba					  ; reverse the bytes (switch dx and dy)
		eor	  #$ff00		  ; flip the high byte (dy)
		clc
		adc	  #$100
		sta	  <thepoint
		bra	  fix_dist		; adjust for mode if necessary

l_dist	lda	  <thepoint		; dx = -dy ; dy = dx
		eor	  #$ff00		  ; flip the high byte (dy)
		clc
		adc	  #$100
		xba					  ; reverse the bytes (switch dx and dy)
		sta	  <thepoint

fix_dist	lda	  Q_pictSCB		 ; am I in 640 mode?
		jeq	  nofix

		short

		asl	  <thepoint+1	  ; double dh
		lda	  <thepoint		; halve dv
		asl	  a
		ror	  <thepoint

		long

nofix	rtl

*--------------------------------------------------------------*
*	Shift Q_thePnLoc by the value store in thePoint (dh, dv)	;
*--------------------------------------------------------------*
Q_ShiftPen		;		

		lda	  <thepoint		; ---- Adjust Q_thePnLoc ----
		and	  #$ff			; get just dv
		bit	  #$80			; get dv's sign
		beq	  gotdv
		ora	  #$ff00
gotdv	clc
		adc	  Q_thePnLoc
		sta	  Q_thePnLoc

		lda	  <thepoint+1
		and	  #$ff			; get just dh
		bit	  #$80			; get dh's sign
		beq	  gotdh
		ora	  #$ff00
gotdh	clc
		adc	  Q_thePnLoc+2
		sta	  Q_thePnLoc+2

		rtl

*--------------------------------------------------------------*
*	   Convert a dh, dv parameter into a Q_Point parameter	  ;
*--------------------------------------------------------------*
Q_FakeDhDv		;		

		moveword [<oldptr],<thepoint	  ; get the distance
		jsl	  Q_ShiftPen			   ; adjust the pen location
		movelong Q_thePnLoc,<thepoint	  ; that's the D_New Q_Point!
		jtl	  Q_manglePt,<what		  ; mangle it
		movelong <thepoint,[<newptr]	  ; store it

		addwl	#2,<oldptr	   ; adjust the pointers
		addwl	#4,<newptr

		rtl

*--------------------------------------------------------------*
*		 Mangle and copy a Q_Point from oldptr to newptr		;
*--------------------------------------------------------------*
Q_CopyPt		;		

		movelong [<oldptr],<thepoint

		jtl	  Q_manglePt,<what

		movelong <thepoint,[<newptr]

		addwl	#4,<oldptr
		addwl	#4,<newptr

		clc
		rtl

Q_manglePt		;		
	DC.L	h_point
	DC.L	v_point
	DC.L	r_point
	DC.L	l_point
*--------------------------------------------------------------*
h_point	lda	  Q_center+2		; H-flip the Q_Point around Q_center.x
		sec
		sbc	  <thepoint+2
		sta	  <thepoint+2
		rtl
*--------------------------------------------------------------*
v_point	lda	  Q_center		  ; V-flip the Q_Point around Q_center.y
		sec
		sbc	  <thepoint
		sta	  <thepoint
		rtl
*--------------------------------------------------------------*
;
;  NOTE: The reason behind adding the last bit of either Q_center or
;		Q_center+2 in the calculations below is to prevent the picture
;		from creeping up and/or to the left when (Q_center)+(Q_center+2)
;		is odd.  Trust me.  It works.
;											  -- jge, 1/20/88
;
r_point	lda	  Q_pictSCB		 ; adjust for 640 mode?
		beq	  dor_point

		lda	  <thepoint+2	  ; if so, halve the x-coord (sigh)
		asl	  a			   ; (preserve the sign)
		ror	  <thepoint+2

dor_point	lda	  Q_center+2		; R-rotate the Q_Point around Q_center
		and	  #1			  ; <adjust for creep>
		clc
		adc	  Q_center+2		; pt.x <= -(pt.y - Q_center.y) + Q_center.x
		adc	  Q_center
		sta	  <temp			; (divide by 2, preserving
		asl	  <temp			 ;  the sign)
		ror	  a			   ;
		sec
		sbc	  <thepoint
		tax					  ; D_Save it here...

		lda	  Q_center		  ; pt.y <= pt.x - Q_center.x + Q_center.y
		and	  #1			  ; <adjust for creep>
		clc
		adc	  Q_center
		sec
		sbc	  Q_center+2
		sta	  <temp			; (divide by 2, preserving
		asl	  <temp			 ;  the sign)
		ror	  a			   ;
		clc
		adc	  <thepoint+2
		sta	  <thepoint

		stx	  <thepoint+2	  ; ...and store it here.

		lda	  Q_pictSCB		 ; adjust for 640 mode?
		beq	  didr_point
		asl	  <thepoint+2	  ; if so, double the D_New x-coord

didr_point	rtl
*--------------------------------------------------------------*
l_point	lda	  Q_pictSCB		 ; adjust for 640-mode?
		beq	  dol_point

		lda	  <thepoint+2	  ; if so, halve the x-coord (sigh)
		asl	  a			   ; (preserve the sign)
		ror	  <thepoint+2

dol_point	lda	  Q_center		  ; L-rotate the Q_Point around Q_center
		and	  #1			  ; <adjust for creep>
		clc
		adc	  Q_center		  ; pt.y <= -(pt.x - Q_center.x) + Q_center.y
		adc	  Q_center+2
		sta	  <temp			; (divide by 2, preserving
		asl	  <temp			 ;  the sign)
		ror	  a			   ;
		sec
		sbc	  <thepoint+2
		tay					  ; D_Save it here...

		lda	  Q_center+2		; pt.x <= pt.y - Q_center.y + Q_center.x
		and	  #1			  ; <adjust for creep>
		clc
		adc	  Q_center+2
		sec
		sbc	  Q_center
		sta	  <temp			; (divide by 2, preserving
		asl	  <temp			 ;  the sign)
		ror	  a			   ;
		clc
		adc	  <thepoint
		sta	  <thepoint+2

		sty	  <thepoint		; ...and store it here.

		lda	  Q_pictSCB		 ; adjust for 640-mode?
		beq	  didl_point
		asl	  <thepoint+2	  ; if so, double the D_New x-coord

didl_point	rtl

*--------------------------------------------------------------*
*   Adjust the last mangled Q_Point with respect to the Q_PenSize  ;
*--------------------------------------------------------------*
Q_NudgePt		;		

		subwl	#4,<newptr	   ; back up a minute

		lda	  <what			; which coordinate do I need to nudge?
		and	  #1
		beq	  HorR

		subword  [<newptr],Q_thePnSize,[<newptr]	; if V or L, nudge y up
		bra	  nudged

HorR	ldy #2				   ; if H or R, nudge x left
		subword  [<newptr]:y,Q_thePnSize+2,[<newptr]:y

nudged	addwl	#4,<newptr	   ; ok, I'm done now
		rtl

*--------------------------------------------------------------*
*		 Mangle and copy Q_Angles from oldptr to newptr		 ;
*--------------------------------------------------------------*
Q_Angles		;		

		movelong [<oldptr],<thepoint

		jtl	  mangleAngle,<what

		movelong <thepoint,[<newptr]

		addwl	#4,<oldptr
		addwl	#4,<newptr
		clc
		rtl

mangleAngle	DC.L	h_angle
	DC.L	v_angle
	DC.L	r_angle
	DC.L	l_angle

h_angle	lda	  #360			; start = (360-start-Q_Arc) mod 360
		sec
		sbc	  <thepoint
		sbc	  <thepoint+2
		bge	  h_ok			; is it still positive?
		clc
		adc	  #360			; if not, adjust it.
h_ok	sta	  <thepoint
		rtl

v_angle	lda	  #180			; start = (180-start-Q_Arc) mod 360
		sec
		sbc	  <thepoint
		sbc	  <thepoint+2
		bge	  v_ok			; still positive?
		clc
		adc	  #360			; if not, adjust.
v_ok	sta	  <thepoint
		rtl

r_angle	lda	  <thepoint		; start = (start + 90) mod 360
		clc
		adc	  #90
		cmp	  #360			; less than 360?
		blt	  r_ok
		sec					  ; if not, adjust.
		sbc	  #360
r_ok	sta	  <thepoint
		rtl

l_angle	lda	  <thepoint		; start = (start - 90) mod 360
		sec
		sbc	  #90
		bge	  l_ok			; still positive?
		clc					  ; if not, adjust.
		adc	  #360
l_ok	sta	  <thepoint
		rtl

*--------------------------------------------------------------*
*		  Copy a D_Pattern opcode and mangle its data		   ;
*--------------------------------------------------------------*
*	NOTE: This doesn't flip or rotate patterns, since that	;
*		  would be seriously screwed up in 640 mode.		  ;
*--------------------------------------------------------------*
Pict_pattern		;		

		jsl	  Q_Nop			 ; move the opcode

		pushlong <oldptr		  ; move the D_Pattern
		pushlong <newptr
		pushlong #32
		_BlockMove

		addwl	#32,<oldptr
		addwl	#32,<newptr

		rtl

*--------------------------------------------------------------*
*			Copy a Q_Mask opcode and mangle its data			;
*--------------------------------------------------------------*
*	 NOTE: DOESN'T REALLY MANGLE, AND PROBABLY NEVER WILL!	;
*--------------------------------------------------------------*
Q_Mask		;		

		jsl	  Q_Nop			 ; move the opcode

		movelong [<oldptr],[<newptr]	  ; move the Q_Mask
		ldy	  #4
		movelong [<oldptr]:y,[<newptr]:y

		addwl	#8,<oldptr
		addwl	#8,<newptr

		rtl					  ; No surgery (for now) <or for ever?>

****************************************************************
*															  ;
*						  MISCELLANY						  ;
*															  ;
****************************************************************
*--------------------------------------------------------------*
*			Abort!  An undefined opcode was found!			;
*--------------------------------------------------------------*
Q_Undef		;		

		moveword #$A501,Q_picterr
		sec
		rtl

*--------------------------------------------------------------*
*		 Add Q_addbytes to newpict and D_Update the pointer	   ;
*--------------------------------------------------------------*
Q_ChangePictSize		;		

		sublong  <newptr,[<newpict],<temp	   ; get offset into pict

		pushlong <newpict
		_HUnLock

		addlong	Q_addbytes,<Q_newsize,<Q_newsize

		pushlong <Q_newsize
		pushlong <newpict
		jsl	  D_GrowHandle
		sta	  Q_picterr
		bcs	  nochange

		pushlong <newpict
		_HLock

		addlong  [<newpict],<temp,<newptr

		lda	  #0
		clc
nochange	rtl

oldpict	equ ~~oldpict	
what	equ	~~what
newpict	equ	~~newpict
Q_newsize	equ	~~newsize
oldptr	equ	~~oldptr
newptr	equ	~~newptr
count	equ	~~count
thepoint	equ	~~thepoint
temp	equ	~~temp

		ENDP
		END

