;
; rules.s
;
; Draws horizontal and vertical rules for Sculptrix borders
;
;  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

;----- The main idea --------------------------------------------------------
;
; In the new version of Sculptrix, we define border types in terms of
; a collection of rules, which may be horizontal and vertical.  The positions
; of these rules relative to the icon, and their colours, are determined
; by a `border definition', which is parsed elsewhere.  This calls the
; rule drawing routines through a standardised interface.
;
; On entry to a rule routine, the colour has already been set up, through
; a call to Wimp_SetColour, or similar.  Coordinates for the rule to plot
; are passed in R3-R6, although all the registers may not have sensible
; values.  Values of dx, dy, and `start' are passed in R7, R8, and R9
; respectively.

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

		AREA	|Module$$Code|,CODE,READONLY

; --- rule_left ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == bottom y position
;		R5 == unused
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a vertical rule in the current colour.

		EXPORT	rule_left
rule_left	ROUT

		STMFD	R13!,{R14}		;Save some registers

		MOV	R0,#move+abs		;Move cursor absolute
		SUB	R1,R3,#4		;Get the x position sorted
		SUB	R2,R4,#4		;And the y position
		SWI	XOS_Plot		;Move the graphics cursor

		MOV	R0,#rectfill+abs+fore	;Now do the rectangle fill
		SUB	R1,R3,R7		;Find the x limit
		SUB	R2,R6,R8		;And the y limit
		ADD	R2,R2,#4		;Provide some overlap
		SWI	XOS_Plot		;Do that, please

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_right ---
;
; On entry:	R3 == unused
;		R4 == bottom y position
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a vertical rule in the current colour.

		EXPORT	rule_right
rule_right	ROUT

		STMFD	R13!,{R14}		;Save some registers

		MOV	R0,#move+abs		;Move cursor absolute
		MOV	R1,R5			;Get the x position sorted
		SUB	R2,R4,#4		;And the y position
		SWI	XOS_Plot		;Move the graphics cursor

		MOV	R0,#rectfill+abs+fore	;Now do the rectangle fill
		SUB	R1,R5,R7		;Find the x limit
		ADD	R1,R1,#4		;Move over, for niceness
		SUB	R2,R6,R8		;And the y limit
		ADD	R2,R2,#4		;Provide some overlap
		SWI	XOS_Plot		;Do that, please

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_top ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == unused
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a horizontal rule in the current colour.

		EXPORT	rule_top
rule_top	ROUT

		STMFD	R13!,{R14}		;Save return address

		; --- Set up for the loop ---

		ADD	R4,R6,#4		;A limit for the loop
		SUB	R5,R5,R7		;Step back a pixel
		ADD	R5,R5,R9		;And move on one too

		; --- Now do the plotting ---

00		MOV	R0,#move+abs		;Move cursor absolute
		SUB	R1,R3,#4		;Get the x position
		MOV	R2,R6			;And the y position
		SWI	XOS_Plot		;Go and do that then
		MOV	R0,#line+abs+fore	;Draw line absolute
		MOV	R1,R5			;Get the x limit value
		MOV	R2,R6			;And the old y position
		SWI	XOS_Plot		;Go and do that, please

		ADD	R5,R5,R8		;Extend the mitring
		ADD	R6,R6,R8		;Move up by a pixel
		CMP	R6,R4			;Have we reached the end?
		BLT	%b00			;No -- look back then

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_bottom ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == unused
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a horizontal rule in the current colour.

		EXPORT	rule_bottom
rule_bottom	ROUT

		STMFD	R13!,{R14}		;Save return address

		; --- Set up for the loop ---

		SUB	R6,R4,R8		;Drop down a pixel to start
		SUB	R4,R4,#4		;A limit for the loop
		SUB	R3,R3,R9		;And move on one too
		SUBS	R14,R7,R8		;Which pixel size is bigger?
		ADDPL	R3,R3,R14		;Bodge for flattened modes
		SUB	R5,R5,R7		;Sort out right hand side

		; --- Now do the plotting ---

00		MOV	R0,#move+abs		;Move cursor absolute
		MOV	R1,R3			;Get the x position
		MOV	R2,R6			;And the y position
		SWI	XOS_Plot		;Go and do that then
		MOV	R0,#line+abs+fore	;Draw line absolute
		ADD	R1,R5,#4		;Get the x limit value
		MOV	R2,R6			;And the old y position
		SWI	XOS_Plot		;Go and do that, please

		SUB	R3,R3,R8		;Extend the mitring
		SUB	R6,R6,R8		;Move up by a pixel
		CMP	R6,R4			;Have we reached the end?
		BGE	%b00			;No -- look back then

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_pTop ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == unused
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a horizontal rule in the current colour, without
;		mitring.

		EXPORT	rule_pTop
rule_pTop	ROUT

		STMFD	R13!,{R14}		;Save return address

		MOV	R0,#move+abs		;Move cursor absolute
		SUB	R1,R3,#4		;Sort out left hand side
		MOV	R2,R6			;And the y position
		SWI	XOS_Plot		;Move the cursor

		MOV	R0,#rectfill+abs+fore	;Plot the rectangle
		SUB	R1,R5,R7		;Sort out the overhang
		ADD	R1,R1,#4		;And add some overlap
		SUB	R2,R6,R8		;Set the y position
		ADD	R2,R2,#4		;Move up a little
		SWI	XOS_Plot		;And plot the rectangle

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_pBottom ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == unused
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Plots a horizontal rule in the current colour, without
;		mitring.

		EXPORT	rule_pBottom
rule_pBottom	ROUT

		STMFD	R13!,{R14}		;Save return address

		MOV	R0,#move+abs		;Move cursor absolute
		SUB	R1,R3,#4		;Sort out left hand side
		SUB	R2,R4,#4		;And the y position
		SWI	XOS_Plot		;Move the cursor

		MOV	R0,#rectfill+abs+fore	;Plot the rectangle
		SUB	R1,R5,R7		;Sort out the overhang
		ADD	R1,R1,#4		;And add some overlap
		SUB	R2,R4,R8		;Set the y position
		SWI	XOS_Plot		;And plot the rectangle

		LDMFD	R13!,{PC}^		;And return to caller

		LTORG

; --- rule_border ---
;
; On entry:	R3 == left hand side of the icon
;		R4 == bottom edge of icon
;		R5 == right hand side of the icon
;		R6 == top y position
;		R7 == pixel width
;		R8 == pixel height
;		R9 == start position for mitring
;
; On exit:	R0-R6 corrupted
;
; Use:		Fills the icon in, and plots a border around it, using the
;		current foreground and background colours.

		EXPORT	rule_border
rule_border	ROUT

		STMFD	R13!,{R14}		;Save return address

		; --- Fill in the background ---
		;
		; We plot /within/ the border, to ensure that there's no
		; flicker.

		MOV	R0,#move+abs		;Move cursor absolute
		ADD	R1,R3,R7		;Move slightly inwards
		ADD	R2,R4,R8		;Move slightly upwards
		SWI	XOS_Plot		;Do the plotting

		MOV	R0,#rectfill+abs+back	;Plot rectangle in background
		SUB	R1,R5,R7,LSL #1		;Move inwards from right
		SUB	R2,R6,R8,LSL #1		;And downwards from top
		SWI	XOS_Plot		;Do the rectangle now

		; --- Plot the border around the edge ---

		MOV	R0,#move+abs		;Move cursor absolute
		MOV	R1,R3			;Start on the left
		MOV	R2,R4			;And at the bottom
		SWI	XOS_Plot		;Move the cursor

		MOV	R0,#line+abs+fore	;Draw line absolute
		MOV	R1,R3			;Stay on the left
		SUB	R2,R6,R8		;Move to the top
		SWI	XOS_Plot		;Draw the line

		MOV	R0,#line+abs+fore	;Draw line absolute
		SUB	R1,R5,R7		;Move to the right
		SUB	R2,R6,R8		;Stay at the top
		SWI	XOS_Plot		;Draw the line

		MOV	R0,#line+abs+fore	;Draw line absolute
		SUB	R1,R5,R7		;Stay on the right
		MOV	R2,R4			;Move to the bottom
		SWI	XOS_Plot		;Draw the line

		MOV	R0,#line+abs+fore	;Draw line absolute
		MOV	R1,R3			;Move to the left
		MOV	R2,R4			;Stay at the bottom
		SWI	XOS_Plot		;Draw the line

		LDMFD	R13!,{PC}^		;Return when done

		LTORG

;----- Plot codes -----------------------------------------------------------

rel		EQU	0
abs		EQU	4

move		EQU	0
line		EQU	0
rectfill	EQU	96

fore		EQU	1
back		EQU	3

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

		END
