
	load 'macros.dump'
	include 'driver.equ'
	include 'pl.equ'

;-----------------------------------------------
;
;   Imported addresses
;
;-----------------------------------------------

	IMPORT	D_AddRectRgn
	IMPORT	D_Deref
	IMPORT	P_DrawHandles
	IMPORT	P_Fix2Int
	IMPORT	P_FixRect
	IMPORT	P_GetModifiers
	IMPORT	P_GetPageMode

;-----------------------------------------------
;
;   Forward addresses and entries
;
;-----------------------------------------------

	ENTRY	P_AddObjRgn
	ENTRY	P_DoHandles
	ENTRY	P_FixSpecRect
	ENTRY	P_PtInLine
	ENTRY	P_PtInOval
	ENTRY	P_ValidRect





;------------------------------------------------------------------------------
;
; P_ListOp (ObjList:l,Oper:w,Data:l,Data2:l)
;
; Automatically skips any object with the Deleted flag set.

P_ListOp	PROC		EXPORT
			;Using P_ObjData

		INPUT ObjList:l,Oper:w,Data:l,Data2:l
		LOCAL ObjPtr:l,ObjType:w,Selected:w,Q_Rect:r

		BEGIN

ObjLoop	cpzl ObjList
		beq Exit

		movelong [ObjList],ObjPtr
		moveword [ObjPtr]:#P_Deleted,a
		bne NextObj
		tool _HLock,in=(ObjList:l)

		moveword [ObjPtr]:#P_Type,ObjType
		moveword [ObjPtr]:#P_Selected,Selected
		moverect [ObjPtr]:#P_ObjRect,Q_Rect


		lda Oper
		asl a
		tax
		jsr (JumpTable,x)

		tool _HUnlock,in=(ObjList:l)

NextObj	movelong [ObjPtr],ObjList
		bra ObjLoop


Exit	RETURN

JumpTable
	DC.W	SelectRect
	DC.W	DeselectAll
	DC.W	SelectAll
	DC.W	FixTObj
	DC.W	OffsetObj
	DC.W	AddUpdate
	DC.W	ClrUndoData
	DC.W	SetUndoData
	DC.W	CpyUndoData



; -------- Operation 0

SelectRect

;TopLeft
		tool _PtInRect,in=(!Q_Rect:l,Data:l),out=(a:w)
		beq Exit0

;BottomRight
		tool _PtInRect,in=(!Q_Rect+4:l,Data:l),out=(a:w)
		beq Exit0

		lda Selected
		eor #1
		moveword a,[ObjPtr]:#P_Selected
		call P_DrawHandles,in=(ObjPtr:l)
Exit0	rts



; -------- Operation 1
;
; If Data is not 0, then don't D_Update the screen.

DeselectAll
		lda Selected
		beq Exit1
		moveword #0,[ObjPtr]:#P_Selected
		lda Data
		bne Exit1
		call P_DrawHandles,in=(ObjPtr:l)
Exit1	rts



; ------- Operation 2

SelectAll
		lda Selected
		bne Exit2
		inc a
		moveword a,[ObjPtr]:#P_Selected
		call P_DrawHandles,in=(ObjPtr:l)
Exit2	rts



; ------- Operation 3

FixTObj
		cmpw ObjType,#P_ALPHA
		bne Exit3
		moveword Data,[ObjPtr]:#P_PageNo
Exit3	rts


; ------- Operation 4
;			 Offsets all object Q_Rects by Data.

OffsetObj
		lda Selected
		beq Exit4

		addword Q_Rect,Data,[ObjPtr]:#P_ObjRect
		addword Q_Rect+4,Data,[ObjPtr]:#P_ObjRect+4
		addword Q_Rect+2,Data+2,[ObjPtr]:#P_ObjRect+2
		addword Q_Rect+6,Data+2,[ObjPtr]:#P_ObjRect+6

		cmpw ObjType,#P_PICTURE
		bne PictSet

		addword [ObjPtr]:#P_PictRect,Data,[ObjPtr]:#P_PictRect
		addword [ObjPtr]:#P_PictRect+4,Data,[ObjPtr]:#P_PictRect+4
		addword [ObjPtr]:#P_PictRect+2,Data+2,[ObjPtr]:#P_PictRect+2
		addword [ObjPtr]:#P_PictRect+6,Data+2,[ObjPtr]:#P_PictRect+6
PictSet

		call P_FixSpecRect,in=(ObjPtr:l)

Exit4	rts



; ------- Operation 5
; Adds the selected objects to the D_Update Q_Region passed in Data.

AddUpdate
		lda Selected
		beq Exit5
		call P_AddObjRgn,in=(ObjPtr:l,Data:l)
Exit5	rts



; ------ Operation 6
; Sets the UndoData for all selected objects.

ClrUndoData
		moveword #0,[ObjPtr]:#P_UndoData
Exit6	rts



; ------ Operation 7
; Sets the UndoData for all selected objects.

SetUndoData
		lda Selected
		beq Exit7
		moveword Data,[ObjPtr]:#P_UndoData
Exit7	rts



; ------ Operation 8
; Copies the UndoData into the Selected field.  Used for redo of obj deletion.

CpyUndoData
		moveword [ObjPtr]:#P_UndoData,[ObjPtr]:#P_Selected
Exit8	rts



		ENDP




;------------------------------------------------------------------------------
;
; P_FindObject (ObjList:l,Pt:l) : ObjHdl:l,Handle:w
;
; Pt must be in screen coordinates.
;
; Returns 0 for ObjHdl if no object is found.
; Handle ranges from 1 to 4 for normal objects, and includes
; 5 and 6 for Q_Text objects.
;
; [BOGUS] -- leaves ObjHdl X_Locked.


P_FindObject	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData

		INPUT  ObjList:l,Pt:l
		OUTPUT ObjHdl:l,Handle:w

		LOCAL  ObjPtr:l,Q_Rect:r,InnerRect:r,HRect:r,PageMode:w
		LOCAL  ObjType:w,Q_PenSize:w,RgnHdl:l,InLine:w

		BEGIN


		rcall P_GetPageMode,out=(PageMode:a)


; Check Handles of all objects first
		movelong ObjList,ObjHdl

Loop	cpzl ObjHdl
		beq CheckObjects

		rcall D_Deref,in=(ObjHdl:ax),out=(ObjPtr:ax)
		moveword [ObjPtr]:#P_Deleted,a
		bne TryNext
		moveword [ObjPtr]:#P_Selected,a
		beq TryNext

		call P_DoHandles,in=(ObjPtr:l,#1:w,Pt:l),out=(Handle:w)
		jne Exit

TryNext
		tool _HUnlock,in=(ObjHdl:l)
		movelong [ObjPtr],ObjHdl
		brl Loop



; Check all the objects

CheckObjects
		stz Handle
		movelong ObjList,ObjHdl

Loop2	cpzl ObjHdl
		jeq Exit

		rcall D_Deref,in=(ObjHdl:ax),out=(ObjPtr:ax)
		moveword [ObjPtr]:#P_Deleted,a
		jne TryNext2

		moveword [ObjPtr]:#P_Type,ObjType
		moveword [ObjPtr]:#P_PenSize,Q_PenSize
		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		moverect Q_Rect,InnerRect

		call P_FixRect,in=(!Q_Rect:l,ObjType:w,PageMode:w,#1:w)

; Inset by Q_PenSize
		pushlong !InnerRect
		lda Q_PenSize
		tax
		asl a
		inc a
		pha
		inx
		phx
		_InsetRect

		call P_FixRect,in=(!InnerRect:l,ObjType:w,PageMode:w,#1:w)


		lda ObjType
		asl a
		tax
		jmp (JumpTable,x)

CheckLine
		call P_PtInLine,in=(Pt:l,ObjPtr:l,!Q_Rect:l),out=(a:w)
		jne Exit
		brl TryNext2

CheckFRect
		tool _PtInRect,in=(!Pt:l,!Q_Rect:l),out=(a:w)
		jne Exit
		brl TryNext2

CheckRect
		moveword [ObjPtr]:#P_ObjFilled,a
		bne CheckFRect
		tool _PtInRect,in=(!Pt:l,!Q_Rect:l),out=(a:w)
		beq TryNext2

		tool _PtInRect,in=(!Pt:l,!InnerRect:l),out=(a:w)
		beq Exit
		bra TryNext2


CheckCircle
		call P_PtInOval,in=(Pt:l,!Q_Rect:l),out=(a:w)
		beq TryNext2
		moveword [ObjPtr]:#P_ObjFilled,a
		bne Exit

		call P_PtInOval,in=(Pt:l,!InnerRect:l),out=(a:w)
		beq Exit


TryNext2	tool _HUnlock,in=(ObjHdl:l)
		movelong [ObjPtr],ObjHdl
		brl Loop2


Exit	RETURN


JumpTable	DC.W	TryNext2
	DC.W	CheckFRect
	DC.W	CheckFRect
	DC.W	CheckFRect
	DC.W	CheckLine
	DC.W	CheckLine
	DC.W	CheckRect
	DC.W	CheckRect
	DC.W	CheckCircle
	DC.W	CheckFRect

		ENDP



;------------------------------------------------------------------------------
;
; P_LineAdjust (ObjPtr:l,RectPtr:l)
;

P_LineAdjust	PROC		EXPORT
			;Using P_ObjData

		INPUT ObjPtr:l,RectPtr:l
		LOCAL Q_PenSize:w

		BEGIN

		cmpw [ObjPtr]:#P_Type,#P_LINE
		beq IsLine
		cmp #P_STRLINE
		bne Exit
IsLine

		moveword [ObjPtr]:#P_PenSize,Q_PenSize

		cmpw [RectPtr]:#4,[RectPtr]
		bge Normal1
		addword Q_PenSize,[RectPtr],[RectPtr]
		bra Horiz

Normal1	addword Q_PenSize,[RectPtr]:#4,[RectPtr]:#4

Horiz
		asl Q_PenSize
		cmpw [RectPtr]:#6,[RectPtr]:#2
		bge Normal2
		addword Q_PenSize,[RectPtr]:#2,[RectPtr]:#2
		bra Exit

Normal2	addword Q_PenSize,[RectPtr]:#6,[RectPtr]:#6

Exit	RETURN
		ENDP




;------------------------------------------------------------------------------
;
; P_DoHandles (ObjPtr:l,DoFind:w,Where:l) : Handle:w
;
; DoFind --   1 - Find;  0 - Draw
; Where  --   Mouse pos. in local screen coordinates if Find
; Handle --   Result of Find
;
; General purpose routine for drawing and finding handles.

P_DoHandles	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData

		INPUT  ObjPtr:l,DoFind:w,Where:l
		OUTPUT Handle:w

		LOCAL Q_Rect:r,HRect:r,ObjType:w,Swapped:w
		LOCAL Type:w,Q_PenSize:w,DblPen:w,Temp:w,PageMode:w

Q_Line	equ  1
FlipLine	equ  2

		BEGIN

		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		call P_LineAdjust,in=(ObjPtr:l,!Q_Rect:l)

		moveword [ObjPtr]:#P_Type,ObjType
		moveword [ObjPtr]:#P_PenSize,Q_PenSize
		asl a
		sta DblPen

		rcall P_GetPageMode,out=(PageMode:a)
		call P_FixRect,in=(!Q_Rect:l,ObjType:w,PageMode:w,#1:w)
		call P_ValidRect,in=(!Q_Rect:l),out=(Swapped:w)


		lda DoFind
		beq Drawing

; finding - first test bounds, to make test fast for really bad pts

		stz Handle
		moverect Q_Rect,HRect
		tool _InsetRect,in=(!HRect:l,#-4:w,#-6:w)
		tool _PtInRect,in=(!Where:l,!HRect:l),out=(a:w)
		jeq done
Drawing


		stz Type
		cmpw ObjType,#P_LINE
		beq IsLine
		cmp #P_STRLINE
		bne Cont

IsLine
		inc Type
		lda Swapped
		beq Cont
		inc Type
Cont



TestHV
		lda Type
		jeq NotHV				 ; Not a horiz or vert Q_Line
		subword Q_Rect+6,Q_Rect+2,a   ; Q_Rect width = horiz. Q_PenSize?
		cmp DblPen
		bne NotVert


; Vertical Q_Line

		lsr a
		addword a,Q_Rect+2,a
		subword a,#3,HRect+2
		addword a,#6,HRect+6
		addword Q_Rect,#1,HRect+4
		subword a,#3,HRect
		lda #P_TLHdl
		jsr DoOneHand				   ; draw or test the handle
		jcs done						; carry set if hit: exit

		subword Q_Rect+4,#1,HRect
		addword a,#3,HRect+4
		lda #P_BRHdl
		jsr DoOneHand
		brl done

notvert	subword Q_Rect+4,Q_Rect,a		   ; Q_Rect height = vert. Q_PenSize?
		cmp DblPen
		bne nothv



; Horizontal Q_Line

		lsr a
		addword a,Q_Rect,a
		subword a,#1,HRect
		addword a,#3,HRect+4
		addword Q_Rect+2,#2,HRect+6
		subword a,#6,HRect+2
		lda #P_TLHdl
		jsr DoOneHand
		jcs done

		subword Q_Rect+6,#2,HRect+2
		addword a,#6,HRect+6
		lda #P_BRHdl
		jsr DoOneHand
		brl done


; Not horizontal or vertical

nothv
		addword Q_Rect,#1,HRect+4
		subword a,#3,HRect
		addword Q_Rect+2,#2,HRect+6
		subword a,#6,HRect+2
		cmpw Type,#FLipLine
		beq didul
		lda #P_TLHdl
		jsr DoOneHand
		jcs done

didul
		subword Q_Rect+4,#1,HRect
		addword a,#3,HRect+4
		cmpw Type,#Q_Line
		beq diddl
		lda #P_BLHdl
		jsr DoOneHand
		jcs done

diddl
		subword Q_Rect+6,#2,HRect+2
		addword a,#6,HRect+6
		cmpw Type,#FlipLine
		beq diddr
		lda #P_BRHdl
		jsr DoOneHand
		jcs done

diddr
		addword Q_Rect,#1,HRect+4
		subword a,#3,HRect
		cmpw Type,#Q_Line
		beq didur
		lda #P_TRHdl
		jsr DoOneHand
		jcs done
didur


		lda DoFind
		jeq done
		cmpw ObjType,#P_ALPHA
		jne done

		subword Q_Rect+6,Q_Rect+2,a
		lsr a
		subword a,#7,a
		addword a,Q_Rect+2,HRect+2
		addword a,#14,HRect+6

		moveword Q_Rect,HRect+4
		subword a,#5,HRect
		lda #5
		jsr DoOneHand
		jcs done

		moveword Q_Rect+4,HRect
		addword a,#6,HRect+4
		lda #6
		jsr DoOneHand



done
		cmpw Type,#2
		bne Exit

		cmpw Handle,#4
		bne Try2
		moveword #1,Handle
		bra Exit
Try2	cmp #3
		bne Exit
		moveword #2,Handle


Exit	RETURN


DoOneHand
		sta temp

		lda DoFind
		beq DrawIt

		tool _PtInRect,in=(!Where:l,!HRect:l),out=(a:w)
		beq notin
		sec
		moveword temp,Handle
notin	rts

DrawIt
		tool _InvertRect,in=(!HRect:l)
		rts

		ENDP











;-------------------------------------------------------------------------------
;
; P_DoThread (ObjHdl:l,NewObj:l,Dir:w)
;

P_DoThread	PROC		EXPORT
			;Using P_ObjData

		INPUT ObjHdl:l,NewObj:l,Dir:w

		LOCAL ObjPtr:l,NewPtr:l,PrevObj:l,PrevPtr:l
		LOCAL NextObj:l,NextPtr:l

		BEGIN

		movelong [ObjHdl],ObjPtr
		movelong [NewObj],NewPtr

		lda Dir
		bne After

		movelong [ObjPtr]:#P_PThread,PrevObj
		movelong ObjHdl,[NewPtr]:#P_NThread
		movelong PrevObj,[NewPtr]:#P_PThread
		movelong NewObj,[ObjPtr]:#P_PThread
		cpzl PrevObj
		beq Skip1
		movelong [PrevObj],PrevPtr
		movelong NewObj,[PrevPtr]:#P_NThread
Skip1
		bra Exit



After
		movelong [ObjPtr]:#P_NThread,NextObj
		movelong ObjHdl,[NewPtr]:#P_PThread
		movelong NextObj,[NewPtr]:#P_NThread
		movelong NewObj,[ObjPtr]:#P_NThread
		cpzl NextObj
		beq Skip2
		movelong [NextObj],NextPtr
		movelong NewObj,[NextPtr]:#P_PThread
Skip2


Exit	RETURN
		ENDP







;-----------------------------------------------------------------------------
;
; P_BoundsRect (ObjHdl:l,RectPtr:l) : Count:w
;

P_BoundsRect	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData

		INPUT  ObjHdl:l,RectPtr:l
		OUTPUT Count:w
		LOCAL  ObjPtr:l,Q_Rect:r

		BEGIN

		stz Count

WhileLoop	cpzl ObjHdl
		jeq EndLoop
		movelong [ObjHdl],ObjPtr
		moveword [ObjPtr]:#P_Deleted,a
		jne NextObject
		moveword [ObjPtr]:#P_Selected,a
		jeq NextObject

		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		call P_LineAdjust,in=(ObjPtr:l,!Q_Rect:l)
		call P_ValidRect,in=(!Q_Rect:l),out=(a:w)

		lda Count
		bne NotFirst
		moverect Q_Rect,[RectPtr]
NotFirst
		inc Count


		cmpw Q_Rect,[RectPtr]
		bpl x1
		sta [RectPtr]
x1
		cmpw Q_Rect+2,[RectPtr]:#2
		bpl x2
		sta [RectPtr],y
x2
		cmpw Q_Rect+4,[RectPtr]:#4
		bmi x3
		sta [RectPtr],y
x3
		cmpw Q_Rect+6,[RectPtr]:#6
		bmi x4
		sta [RectPtr],y
x4


NextObject	movelong [ObjPtr],ObjHdl
		brl WhileLoop
EndLoop

		RETURN
		ENDP



;------------------------------------------------------------------------------
;
; P_Constrain (Figure:w,AnchorPt:l,PointPtr:l,PrintHandle:l)
;

P_Constrain	PROC		EXPORT
			;Using P_ObjData

		INPUT Figure:w,AnchorPt:l,PointPtr:l,PHdl:l
		LOCAL ModFlags:w,Flags:w,NewPt:l
		LOCAL dx:w,dy:w,pdx:l,pdy:l
		LOCAL ratio:l,tmp:l,newdy:l

		BEGIN +B

		call P_GetModifiers,out=(ModFlags:w)

		lda Figure
		beq ToExit
		asl a
		tay
		lda ConstrainTable,y
		sta flags

		cmpw Figure,#P_STRLINE
		beq DoConstr

		lda ModFlags
		and #shiftKey
		bne DoConstr
ToExit	brl Exit


*
* This code constrains newpt with reference to anchorpt.  The type of
* constraint is specified in `flags,' a combination of the bits
* %01 (constrain horizontally/vertically) & %10 (constrain
* diagonally).  At least one bit must be set.
* Q_Pixels are assumed to be shaped as defined by the print record.
*

DoConstr	movelong [phdl],tmp

		tool _FixRatio,in=([tmp]:#4:w,[tmp]:#6:w),out=(ratio:l)

		movelong [pointptr],newpt

		subword anchorpt,newpt,dy
		abs a
		sta pdy+2
		stz pdy

		subword anchorpt+2,newpt+2,dx
		abs a
		sta pdx+2
		stz pdx

		tool _FixDiv,in=(pdy:l,ratio:l),out=(newdy:l)
		movelong newdy,tmp

		clc
		rol tmp
		rol tmp+2
		cmpl tmp,pdx				  ; if 2dy < dx, should be horizontal
		jlt horiz
		cmpl newdy,pdx				  ; if dy < dx, should be diag/horiz
		blt diag2

		movelong pdx,tmp
		clc
		rol tmp
		rol tmp+2
		cmpl newdy,tmp				; if dy < 2dx should be diag/vert
		blt diag1					 ; otherwise vertical.

vert	lda flags				   ; If can't be vertical, diagonal
		bit #1
		beq diag1

		moveword anchorpt+2,[pointptr]:#2
		brl exit

diag1	lda flags				   ; If can't be diagonal, vertical
		bit #2
		beq vert

		lda dx
		bpl d1pos
		rcall P_Fix2Int,in=(newdy:ax)
		addword a,anchorpt+2,[pointptr]:#2
		bra exit
d1pos	rcall P_Fix2Int,in=(newdy:ax)
		neg a
		addword a,anchorpt+2,[pointptr]:#2
		bra exit

diag2	lda flags				   ; If can't be diagonal, horizontal
		bit #2
		beq horiz

		tool _FixMul,in=(pdx:l,ratio:l),out=(pdx:l)
		lda dy
		bpl d2pos
		rcall P_Fix2Int,in=(pdx:ax)
		addword a,anchorpt,[pointptr]
		bra exit
d2pos	rcall P_Fix2Int,in=(pdx:ax)
		neg a
		addword a,anchorpt,[pointptr]
		bra exit

horiz	lda flags				   ; If can't be horizontal, diagonal
		bit #1
		beq diag2

		moveword anchorpt,[pointptr]


Exit	RETURN

ConstrainTable	DC.W	0,2,2,2,1,3,2,2,2,2,1
		ENDP




;-----------------------------------------------------------------------------
;
; P_AddObjRgn (ObjPtr:l; RgnHdl:l)
;
; Adds the area taken up by the object to the already created RgnHdl.


P_AddObjRgn	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData

		INPUT ObjPtr:l,RgnHdl:l
		LOCAL Q_Rect:r,HRect:r,PageMode:w

		BEGIN

		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		call P_LineAdjust,in=(ObjPtr:l,!Q_Rect:l)
		rcall P_GetPageMode,out=(PageMode:a)
		call P_FixRect,in=(!Q_Rect:l,#P_RECTANGLE:w,PageMode:w,#1:w)

		moveword [ObjPtr]:#P_Selected,a
		beq AddRect
		subword Q_Rect+2,#4,Q_Rect+2
		addword Q_Rect+6,#4,Q_Rect+6
		cmpw [ObjPtr]:#P_Type,#P_ALPHA
		bne NotAlpha
		subword Q_Rect,#6,Q_Rect
		addword Q_Rect+4,#6,Q_Rect+4
		bra AddRect
NotAlpha	dec Q_Rect
		dec Q_Rect
		inc Q_Rect+4
		inc Q_Rect+4

AddRect
		call D_AddRectRgn,in=(RgnHdl:l,!Q_Rect:l)

Exit	RETURN
		ENDP





;----------------------------------------------------------------------------
;
; P_SmallRect (RectPtr:l) : Small:w

P_SmallRect	PROC		EXPORT

		INPUT  RectPtr:l
		OUTPUT Small:w

		BEGIN

		stz Small

		subword [RectPtr]:#4,[RectPtr],a
		cmp #6
		bge Exit

		subword [RectPtr]:#6,[RectPtr]:#2,a
		cmp #12
		bge Exit
		inc Small

Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; P_MaskRect (RectPtr:l)
;

P_MaskRect	PROC		EXPORT

		INPUT RectPtr:l

		BEGIN

		ldy #2
		lda [RectPtr],y
		and #$FFFE
		sta [RectPtr],y

		ldy #6
		lda [RectPtr],y
		and #$FFFE
		sta [RectPtr],y

		RETURN
		ENDP





;---------------------------------------------------------------------------------
;
; P_FixSpecRect (ObjPtr:l)
;

P_FixSpecRect	PROC		EXPORT
			;Using P_ObjData

		INPUT ObjPtr:l
		LOCAL Q_Rect:r,TRect:r,Tmp:w

		BEGIN

		addlong ObjPtr,#P_ObjRect,s
		jsl P_MaskRect


		moveword [ObjPtr]:#P_Type,a
		cmp #P_ALPHA
		jne NotAlpha

		moverect [ObjPtr]:#P_ObjRect,Q_Rect
		addword Q_Rect+2,#22,Tmp
		scmpw Tmp,Q_Rect+6
		blt HOkay
		moveword Tmp,Q_Rect+6
		moveword a,[ObjPtr]:#P_ObjRect+6
HOkay

		addword Q_Rect,#4,Tmp
		scmpw Tmp,Q_Rect+4
		blt VOKay
		moveword Tmp,Q_Rect+4
		moveword a,[ObjPtr]:#P_ObjRect+4
VOkay

		addword Q_Rect,#1,TRect
		subword Q_Rect+4,#1,TRect+4
		addword Q_Rect+2,#4,TRect+2
		subword Q_Rect+6,#4,TRect+6

		moverect TRect,[ObjPtr]:#P_TRect
NotAlpha


		cmpw [ObjPtr]:#P_Type,#P_PICTURE
		bne Exit

		addlong ObjPtr,#P_PictRect,s
		jsl P_MaskRect

Exit	RETURN
		ENDP




;-----------------------------------------------------------------------------
;
; P_ValidRect (RectPtr:l) : Flipped:w
;

P_ValidRect	PROC		EXPORT
			;Using P_ObjData

		INPUT RectPtr:l
		OUTPUT Flipped:w

		BEGIN

		stz Flipped

		lda [RectPtr]
		tax
		cmpw a,[RectPtr]:#4
		bmi VOkay
		ldy #4
		moveword [RectPtr]:y,[RectPtr]
		txa
		moveword a,[RectPtr]:y
		inc Flipped
VOkay

		moveword [RectPtr]:#2,a
		tax
		cmpw a,[RectPtr]:#6
		bmi HOkay
		moveword [RectPtr]:#6,[RectPtr]:#2
		txa
		moveword a,[RectPtr]:#6
		lda Flipped
		eor #1
		sta Flipped
HOkay

Exit	RETURN
		ENDP




;------------------------------------------------------------------------------
;
; P_GetPictSize (PictHdl:l) : Pt:l
;
; Sets RectPtr to the bounding Q_Rect for the given picture.

P_GetPictSize	PROC		EXPORT

		INPUT  PictHdl:l
		OUTPUT Pt:l

		LOCAL Ptr:l

		BEGIN

		movelong [PictHdl],Ptr
		subword [Ptr]:#6,[Ptr]:#2,Pt
		subword [Ptr]:#8,[Ptr]:#4,Pt+2

;			 moveword [Ptr],a
;			 and #$80
;			 bne Not320
;			 asl Pt+2
Not320

		RETURN
		ENDP





;------------------------------------------------------------------------------
;
; P_PtInLine (Pt:l,ObjPtr:l,RectPtr:l) : Result:w
;
; Makes a rgn of the Q_Line and does a _PtInRgn

P_PtInLine	PROC		EXPORT
			;Using P_ObjData

		INPUT  Pt:l,ObjPtr:l,RectPtr:l
		OUTPUT Result:w

		LOCAL Start:l,End:l,width:w,height:w,lh:w,lv:w
		LOCAL RgnHdl:l,Flipped:w,Q_Rect:r


		BEGIN

; Make a quick check to the adjusted Q_Line coordinates to see if in
; bounding rectangle

		stz Result
		moverect [RectPtr],Q_Rect
		call P_LineAdjust,in=(ObjPtr:l,!Q_Rect:l)
		call P_ValidRect,in=(!Q_Rect:l),out=(a:w)
		tool _PtInRect,in=(!Pt:l,!Q_Rect:l),out=(Result:w)
		jeq Exit


		moveword [ObjPtr]:#P_PenSize,lv
		asl a
		sta lh

		call P_ValidRect,in=(RectPtr:l),out=(Flipped:w)
		movelong [RectPtr],End
		movelong [RectPtr]:#4,Start


; now ul is in end, dr in start

		subword start,end,height
		subword start+2,end+2,width

		tool _NewRgn,out=(RgnHdl:l)
		tool _OpenRgn

		lda Flipped
		bne Type2


; Q_Line is ul-dr

type1	tool _MoveTo,in=(end:l)
		tool _Line,in=(#0:w,lv:w)
		tool _Line,in=height:l
		tool _Line,in=(lh:w,#0:w)
		pea 0
		lda lv
		eor #-1
		inc a
		pha
		_Line
		lda width
		eor #-1
		inc a
		pha
		lda height
		eor #-1
		inc a
		pha
		_Line
		tool _LineTo,in=(end:l)
		bra done


; Q_Line is dl-ur

type2	tool _MoveTo,in=(end+2:w,start:w)
		tool _Line,in=(#0:w,lv:w)
		tool _Line,in=(lh:w,#0:w)
		pushw width
		lda height
		eor #-1
		inc a
		pha
		_Line
		pea 0
		lda lv
		eor #-1
		inc a
		pha
		_Line
		lda lh
		eor #-1
		inc a
		pha
		pea 0
		_Line
		tool _LineTo,in=(end+2:w,start:w)

done	tool _CloseRgn,in=(RgnHdl:l)
		tool _PtInRgn,in=(!Pt:l,RgnHdl:l),out=(Result:w)
		tool _DisposeRgn,in=(RgnHdl:l)

Exit
		RETURN
		ENDP





;------------------------------------------------------------------------------
;
;  P_PtInOval (Q_Point:l,RectPtr:l) : boolean;
;
;  Notes: To avoid floating Q_Point math or 64-bit numbers, the
;		equation used is x^2 a^2 / b^2 + y^2 <= a^2.  (The left
;		addend is actually computed as x*x/b*a/b*a)
;

P_PtInOval	PROC		EXPORT

		INPUT  Q_Point:l,rectptr:l
		OUTPUT init:w
		LOCAL  arad:w,brad:w,a2:l,midx:w,midy:w,temp:l

		BEGIN

		tool _PtInRect,in=(!Q_Point:l,RectPtr:l),out=(a:w)
		jeq notinoval

		subword [rectptr]:#4,[rectptr],arad	 ; get horiz. radius
		lsr arad
		addword arad,[rectptr],midy			 ; get horizontal Q_center

		subword [rectptr]:#6,[rectptr]:#2,brad  ; get vert. distance
		lsr brad
		addword brad,[rectptr]:#2,midx		  ; get vertical Q_center

		tool _Multiply,in=(arad:w,arad:w),out=(a2:l) ; compute a^2

		spacelong				; rmdr - used for result x*x/b*a/b*a
		spacelong				; quotient x*x/b*a/b
		spacelong				; rmdr - used for result x*x/b*a
		spacelong				; quotient x*x/b
		spacelong				; result x*x

		subword Q_Point+2,midx,a
		bpl xok				  ; Mutiply doesn't handle neg #s right	   

		eor #$ffff
		inc a

xok	pha
		pha
		_Multiply				; x*x

		pea 0
		pushword brad
		_LongDivide			  ; x*x/b
		pla					  ; significant word of quotient
		sta 1,s				  ; high word was 0 (assuming x <= b)	   
		pushword arad
		_Multiply				; x*x*a/b

		pea 0
		pushword brad
		_LongDivide			  ; x*x*a/(b*b)
		pla
		sta 1,s
		pushword arad
		_Multiply				; x*x*a*a/(b*b)
		pulllong temp

		spacelong				; for Multiply...
		lda Q_Point
		sec
		sbc midy

		bpl yok

		eor #$ffff
		inc a

yok	pha
		pha
		_Multiply

		addlong s,temp,temp

		cmpl a2,temp
		bge inoval

notinoval	stz init
		bra done

inoval	moveword #1,init

done	RETURN
		ENDP
		END

