;
; redraw.s
;
; Redrawing windows and icons
;
;  1995-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sculptrix.
;
; Sculptrix 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.
;
; Sculptrix 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 Sculptrix.  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

		GET	libs:stream

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

		GET	sh.plot
		GET	sh.vString
		GET	sh.wSpace

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

		AREA	|Module$$Code|,CODE,READONLY

; --- redraw_window ---
;
; On entry:	R1 == pointer to redraw block
;
; On exit:	May return an error
;
; Use:		Redraws all the icons in a window.

		EXPORT	redraw_window
redraw_window	ROUT

		STMFD	R13!,{R0-R11,R14}	;Save lots of registers
		BL	redraw__info		;Read in the information

		; --- Start on the icons ---

		SUB	R13,R13,#40		;Make space for an icon
		LDR	R8,[R1,#0]		;Load the window handle
		MOV	R11,#0			;Start from icon 0
		STMIA	R13,{R8,R11}		;Store them in the block

		; --- Main redrawing loop ---

00		MOV	R1,R13			;Point to my block
		SWI	XWimp_GetIconState	;Read the icon information
		BVS	%99redraw_window	;If failed, return
		LDR	R14,[R13,#24]		;Load the icon flags
		CMP	R14,#&00800000		;Is the icon deleted only?
		BEQ	%90redraw_window	;Yes -- there are no more

		ADD	R1,R13,#8		;Find the actual icon block
		LDMIA	R1,{R8-R10,R14}		;Load the coordinates
		CMP	R4,R10			;See if we need to plot it
		CMPLE	R5,R14
		CMPLE	R8,R6
		CMPLE	R9,R7
		BLLE	redraw__icon		;Yes -- plot it then
		BVS	%99redraw_window	;If failed, return

		ADD	R11,R11,#1		;Increment the icon number
		STR	R11,[R13,#4]		;Store in the block
		B	%b00			;And loop round some more

		; --- We're finished here now ---

90redraw_window	ADD	R13,R13,#40		;Restore stack pointer
		LDMFD	R13!,{R0-R11,PC}^	;Return to caller when done

99redraw_window	ADD	R13,R13,#40+4		;Don't restore R0
		LDMFD	R13!,{R1-R11,R14}	;And return with V set
		ORRS	PC,R14,#V_flag

		LTORG

; --- redraw_icon ---
;
; On entry:	R0 == pointer to icon block
;		R1 == pointer to redraw block
;
; On exit:	May return an error
;
; Use:		Redraws a single icon.

		EXPORT	redraw_icon
redraw_icon	ROUT

		STMFD	R13!,{R0-R10,R14}	;Stack some registers
		BL	redraw__info		;Get the redraw information
		MOV	R1,R0			;Point to the redraw block
		BL	redraw__icon		;Yes -- plot it then
		LDMVCFD	R13!,{R0-R10,PC}^	;If OK, return happy

		ADD	R13,R13,#4		;Don't restore R0
		LDMFD	R13!,{R1-R10,R14}	;And return when done
		ORRS	PC,R14,#V_flag

		LTORG

; --- redraw__icon ---
;
; On entry:	R1 == pointer to icon block
;		R2,R3 == window origin position
;
; On exit:	--
;
; Use:		Redraws an icon.

redraw__icon	ROUT

		STMFD	R13!,{R4,R14}		;Save some registers
		BL	vString_read		;Read icon validation string
		BLCS	plot_border		;If there's a border, plot
		LDMFD	R13!,{R4,R14}		;And return to caller
		BICVCS	PC,R14,#V_flag
		ORRVSS	PC,R14,#V_flag

		LTORG

; --- redraw_group ---
;
; On entry:	R0 == pointer to icon block
;		R1 == pointer to redraw block
;		R2 == `border type' (ignored in Sculptrix 2.00)
;		R3 == pointer to title string
;
; On exit:	--
;
; Use:		Plots a group box.

		EXPORT	redraw_group
redraw_group	ROUT

		STMFD	R13!,{R0-R11,R14}	;Save some registers
		MOV	R11,R3			;Look after this value
		BL	redraw__info		;Read redraw information
		MOV	R1,R0			;Point to the redraw block
		LDMIA	R1,{R8-R10,R14}		;Load the coordinates
		CMP	R4,R10			;See if we need to plot it
		CMPLE	R5,R14
		CMPLE	R8,R6
		CMPLE	R9,R7
		BGT	%90redraw_group		;No -- quit now

		MOVS	R6,R11			;Is there a title string?
		MOVEQ	R0,#vsBrd_ridge+vsFlag_fade+vsFlag_invert
		LDREQ	R14,sculpt_flags	;Load the flags word
		TSTEQ	R14,#scFlag_acorn	;Acorn style group box?
		BICEQ	R0,R0,#vsFlag_invert	;No -- don't invert it then
		CMP	R6,#0			;Find out again...
		BLNE	plot_group		;Plot it then
		BLEQ	plot_border		;Work out which is which
		BVS	%95redraw_group		;If it failed, return error

90redraw_group	LDMFD	R13!,{R0-R11,PC}^	;And return to caller

95redraw_group	ADD	R13,R13,#4
		LDMFD	R13!,{R1-R11,R14}	;And return with V set
		ORRS	PC,R14,#V_flag

		LTORG

; --- redraw_update ---
;
; On entry:	R0 == window handle
;		R1 == icon handle
;
; On exit:	--
;
; Use:		Updates an icon.

		EXPORT	redraw_update
redraw_update	ROUT

		STMFD	R13!,{R0-R8,R14}	;Save some registers
		SUB	R13,R13,#84		;For icon and redraw blocks
		STMIA	R13,{R0,R1}		;Store the icon block away
		MOV	R1,R13			;Point to the block
		SWI	XWimp_GetIconState	;Read the icon information
		BVS	%99redraw_update	;If failed, return error

		; --- Read the validation string out ---

		ADD	R1,R13,#8		;Point to the icon data
		BL	vString_read		;Read the button type
		BCC	%90redraw_update	;If nothing to do, skip
		MOV	R8,R0			;Remember this type code
		AND	R14,R0,#&0000FF00	;Extract the type code
		CMP	R14,#vsCode_tns		;Is it a text+sprite?
		BEQ	%50redraw_update	;Yes -- deal differently

		; --- Start the update job ---

10redraw_update	LDMIA	R1,{R2-R5}		;Load the coordinates out
		SUB	R2,R2,#16		;Extent to include everything
		SUB	R3,R3,#16
		ADD	R4,R4,#16
		ADD	R5,R5,#32

		ADD	R1,R13,#40		;Point to the update block
		LDR	R0,[R13,#0]		;Load the window handle
		STMIA	R1,{R0,R2-R5}		;Store all that lot
		SWI	XWimp_UpdateWindow	;Start the update job
		BVS	%99redraw_update	;If failed, return error

		CMP	R0,#0			;If nothing to do...
		BEQ	%90redraw_update	;Return now

		BL	redraw__info		;Get redraw information

		; --- Do the main upate loop ---

00		MOV	R0,R8			;Get the border type
		ADD	R1,R13,#8		;Point to the icon data
		BL	plot_border		;Plot the icon, please
		ADDVC	R1,R13,#40		;Point to the redraw block
		SWIVC	XWimp_GetRectangle	;Get the next rectangle
		BVS	%99redraw_update	;If failed, return error
		CMP	R0,#0			;Is there any more to do?
		BNE	%b00			;Yes -- go and do it then

		B	%90redraw_update	;Tidy up and return

		; --- Handle a text+sprite icon ---
		;
		; This is a bit complicated.  If the icon is anti-aliased
		; then a simple update won't redraw the text properly, so
		; we have to redraw the text in a flickery way.  We'll try to
		; avoid this.

50redraw_update	MOV	R0,#8			;Read the anti-aliased font
		SWI	XWimp_ReadSysInfo	;Go and do that, please
		MOVVS	R0,#0			;If unknown, assume no font
		ADD	R1,R13,#8		;Find the icon data
		CMP	R0,#0			;Is there a font?
		LDREQ	R14,[R13,#24]		;Load the icon flags
		TSTEQ	R14,#&40		;Check for anti-aliasing
		BEQ	%10redraw_update	;None -- behave as normal

		BL	plot_tnsBBox		;Find the text bounding box
		MOV	R4,R3			;Shift up through registers
		MOV	R3,R2
		MOV	R2,R1
		MOV	R1,R0
		LDR	R0,[R13,#0]		;Load the window handle
		SWI	XWimp_ForceRedraw	;And schedule a redraw
		BVS	%99redraw_update	;If failed, return error

		; --- Tidy up and return ---

90redraw_update	ADD	R13,R13,#84		;Restore the stack pointer
		LDMFD	R13!,{R0-R8,R14}	;Restore registers
		BICS	PC,R14,#V_flag		;And return with V clear

99redraw_update	ADD	R13,R13,#84+4		;Restore stack pointer
		LDMFD	R13!,{R1-R8,R14}	;Restore registers
		ORRS	PC,R14,#V_flag		;And return with V set

		LTORG

; --- redraw__info ---
;
; On entry:	R1 == pointer to redraw block
;
; On exit:	R2,R3 == window origin
;		R4-R7 == clipping rectangle (adjusted)
;
; Use:		Works out information about the redraw op.

redraw__info	ROUT

		CMP	R1,#0			;Is there a redraw block?
		BEQ	%50redraw__info		;No -- handle specially

		; --- Work out the window origin position ---

		LDR	R2,[R1,#4]		;Load the x0 position
		ADD	R4,R1,#16		;Find the other bits
		LDMIA	R4,{R3-R5}		;Load them out
		SUB	R2,R2,R4		;Find the x origin value
		SUB	R3,R3,R5		;And the y origin value

		; --- Now play with the clipping rectangle ---

		ADD	R4,R1,#28		;Find the clipping rectangle
		LDMIA	R4,{R4-R7}		;Load the rectangle out

		SUB	R4,R4,R2		;Convert to window coords
		SUB	R5,R5,R3
		SUB	R6,R6,R2
		SUB	R7,R7,R3

		; --- Extend to include our borders ---

20redraw__info	SUB	R4,R4,#16		;Extend to fit borders
		SUB	R5,R5,#32
		ADD	R6,R6,#16
		ADD	R7,R7,#16

		MOVS	PC,R14

		; --- Read graphics info to determine things ---

50redraw__info	STMFD	R13!,{R0,R1,R14}	;Save some registers

		; --- Read VDU variables which we need ---

		ADR	R0,redraw__vduVars	;Point to variables list
		ADR	R1,sculpt_misc		;Point to a handy buffer
		SWI	XOS_ReadVduVariables	;Read the variables
		LDMIA	R1,{R0-R7}		;Load all of them out

		; --- Now sort out the graphics window ---

		ADD	R6,R6,#1		;Make the border exclusive
		ADD	R7,R7,#1		;To match the Wimp's
		ADD	R5,R2,R5,LSL R0		;Convert, and add on origin
		ADD	R6,R3,R6,LSL R1
		ADD	R7,R2,R7,LSL R0
		ADD	R8,R3,R8,LSL R1

		; --- Sort out the origin positon ---

		MOV	R2,#0			;Easy -- use the screen posn
		MOV	R3,#0			;This will be all right
		LDMFD	R13!,{R0,R1,R14}	;Restore registers
		B	%20redraw__info		;Now transform the clip area

		; --- The VDU variables we need ---

redraw__vduVars	DCD	4,5			;X and Y EIG factors
		DCD	136,137			;Current origin position
		DCD	128,129,130,131		;Graphics window position
		DCD	-1			;End of the list

		LTORG

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

		END
