;
; dynPtr.s
;
; Dynamic pointer changing (TMA)
;
;  1994-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sapphire library.
;
; Sapphire is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sapphire is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sapphire.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

;----- External dependencies ------------------------------------------------

		GET	sapphire:ptr
		GET	sapphire:resspr

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- dynPtr_change ---
;
; On entry:	R0 == pointer to string to use
;		R1 == pointer to pointer name
;		R2 == x hot spot
;		R3 == y hot spot
;
; On exit:	--
;
; Use:		Attaches a string to the default pointer shape.

		EXPORT	dynPtr_change
dynPtr_change	ROUT

		STMFD	R13!,{R0-R10,R14}	;Stack some registers

		MOV	R9,R0			;Remember this pointer

		; --- Output VDU operations to our sprite ---

		BL	resspr_area		;Get the address
		MOV	R8,R0			;Remember this
		MOV	R1,R0			;Put that in R1
		MOV	R0,#60+256		;Output to a sprite
		ADR	R2,dynPtr__blank	;To this sprite please
		MOV	R3,#0			;No save area
		SWI	OS_SpriteOp		;Okay dokay
		STMFD	R13!,{R0-R3}		;For the reversal operation

		; --- Clear the background ---

		SWI	OS_WriteI+16		;CLG (Me... cheat?)

		; --- Copy the default pointer into our sprite ---

		BL	resspr_area		;Get callers sprite area
		MOV	R1,R0			;Put it in R1
		MOV	R0,#256			;Use area pointer
		ADD	R0,R0,#40		;Get info
		LDR	R2,[R13,#20]		;Load the name ptr
		SWI	XOS_SpriteOp		;Try it then
		MOVVS	R0,#40			;If no go -- try WIMP area
		SWIVS	Wimp_SpriteOp		;Get the info

		MOV	R0,R6			;The screen mode
		MOV	R1,#4			;XEig factor
		SWI	OS_ReadModeVariable	;Read it now
		MOV	R5,R2			;Remember this
		MOV	R1,#5			;YEig factor
		SWI	OS_ReadModeVariable	;Read it now

		MOV	R14,#1			;Get a nice unit value
		MOV	R0,R14,LSL R5		;Turn it into a useful value
		MOV	R1,R14,LSL R2		;This one too
		SUB	R13,R13,#16		;Get a block
		MOV	R14,R13			;Remember this value
		STMIA	R14!,{R0,R1}		;Put this in the block
		MOV	R0,#2			;XEig of our sprite
		MOV	R1,#2			;YEig of our sprite
		STMIA	R14!,{R0,R1}		;Put this in the block too

		MOV	R4,R4,LSL R2		;Height in OS pixels
		RSB	R4,R4,#64		;Plot it here please
		MOV	R3,#0			;And here too
		MOV	R5,#&08			;Plot action
		MOV	R6,R13			;Point to the block
		MOV	R7,#0			;No translation table
		LDR	R2,[R13,#36]		;Load the name ptr
		BL	resspr_area		;Get callers sprite area
		MOV	R1,R0			;Put it in R1
		MOV	R0,#256			;Use area pointer
		ADD	R0,R0,#52		;Plot scaled
		SWI	XOS_SpriteOp		;Try it then
		MOVVS	R0,#52			;If no go -- try WIMP area
		SWIVS	Wimp_SpriteOp		;Plot it
		ADD	R13,R13,#12		;Mark remembered it!!!

		; --- Now work out the width of the text ---

		MOV	R7,#2			;Width so far
		MOV	R14,#0			;A NULL word
		STRB	R14,[R13,#1]		;A NULL terminated string!
		MOV	R14,R9			;Point to the string
		MOV	R1,R8			;The sprite area
		MOV	R0,#40+256		;Sprite info
		MOV	R2,R13			;Point to our name buffer
10dynPtr_change	LDRB	R3,[R14],#1		;Load out a character
		CMP	R3,#32			;Is it a control character
		BLT	%20dynPtr_change	;Yes -- skip out of loop
		STRB	R3,[R2]			;Store in my block
		SWI	OS_SpriteOp		;Get the width
		ADD	R7,R7,R3,LSL #1		;Add on the width
		ADD	R7,R7,#2		;Don't forget the gap
  		B	%10dynPtr_change	;Keep on looping

		; --- Do a background rectangle ---

20dynPtr_change	SWI	OS_WriteI+18		;Change colour
		SWI	OS_WriteI+0		;Still doing it
		SWI	OS_WriteI+1		;Ahhh... this is the colour
		MOV	R0,#4			;Do a move absolute
		MOV	R1,#0			;Start at the left
		MOV	R2,#0			;Bottom left
		SWI	OS_Plot			;Move to the point
		MOV	R0,#101			;Rectangle fill
		MOV	R1,R7			;The width
		MOV	R2,#26			;Draw it this high
		SWI	OS_Plot			;Fill in the rectangle

		; --- Now plot the string ---

		MOV	R0,#1			;Don't scale horizontally
		MOV	R1,#2			;Double height
		MOV	R2,#1			;Don't divide
		MOV	R3,#1			;No, not at all
		STMFD	R13!,{R0-R3}		;Save the scale factors
		MOV	R1,R8			;Point to the sprite area
		ADD	R2,R13,#16		;Point to sprite names
		MOV	R10,#2			;Current x position

30dynPtr_change	LDRB	R14,[R9],#1		;Get byte from string
		CMP	R14,#32			;Is it the end?
		BLO	%40dynPtr_change	;Yes -- skip to the end then

		STRB	R14,[R2]		;Save the sprite name
		MOV	R0,#52+256		;Plot sprite scaled, please
		MOV	R3,R10			;Get x position
		MOV	R4,#4			;And a little bit up
		MOV	R5,#0			;No GCOL action
		MOV	R6,R13			;Point to scale factors
		MOV	R7,#0			;No translate table please
		SWI	OS_SpriteOp		;Plot the sprite nicely

		MOV	R0,#40+256		;Get sprite information
		SWI	OS_SpriteOp		;Read the sprite information
		ADD	R10,R10,R3,LSL #1	;Add on the sprite's width
		ADD	R10,R10,#2		;And a little bit of space
		B	%30dynPtr_change	;And go round for more

		; --- Reset screen context, set shape and return ---

40dynPtr_change	ADD	R13,R13,#20		;Reset the stack pointer
		LDMFD	R13!,{R0-R3}		;Load back the context
		SWI	OS_SpriteOp		;Back to the screen please

		ADR	R0,dynPtr__blank	;Point to the sprite name
		ADD	R14,R13,#8		;Point to the hot spot values
		LDMIA	R14,{R1,R2}		;Lad them out
		BL	ptr_setShape		;And set the pointer
		LDMFD	R13!,{R0-R10,PC}^	;Ta-da!  Return to caller

dynPtr__blank	DCB	"ptr_blank",0,0,0

		LTORG

;----- That's all, folks ----------------------------------------------------

		END
