;
; sculptrix.s
;
; Sculptrix module header and initialisation
;
;  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.bbox
		GET	sh.config
		GET	sh.plot
		GET	sh.redraw
		GET	sh.slab
		GET	sh.vString
		GET	sh.wSpace

		GET	sh.messages

		IMPORT	version

;----- Module header --------------------------------------------------------

		AREA	|!Module$$Code|,CODE,READONLY

		DCD	0
		DCD	sculpt__init
		DCD	sculpt__final
		DCD	sculpt__service
		DCD	sculpt__name
		DCD	version
		DCD	sculpt__cmds
		DCD	&4A2C0
		DCD	sculpt__swis
		DCD	sculpt__swiTbl
		DCD	0

sculpt__name	DCB	"Sculptrix",0

;----- SWI name table -------------------------------------------------------

sculpt__swiTbl	DCB	"Sculptrix",0
		DCB	"RedrawWindow",0
		DCB	"DoSlab",0
		DCB	"SlabIcon",0
		DCB	"UnslabIcon",0
		DCB	"BoundingBox",0
		DCB	"PlotIcon",0
		DCB	"PlotGroupBox",0
		DCB	"SetSpriteArea",0
		DCB	"UpdateIcon",0
		DCB	"SlabColour",0
		DCB	"SetConfig",0
		DCB	"ReadConfig",0
		DCB	0

;----- *Command table -------------------------------------------------------

sculpt__cmds	DCB	"Sculptrix_LoadConfig",0
		DCD	config_load
		DCB	1,0,1,0
		DCD	synt_config
		DCD	help_config

		DCD	0

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

; --- sculpt__init ---
;
; On entry:	--
;
; On exit:	R0-R6 corrupted
;
; Use:		Initialises the Sculptrix module.

sculpt__init	ROUT

		STMFD	R13!,{R14}		;Save some registers

		; --- Allocate workspace ---

		MOV	R0,#6			;Allocate some space please
		LDR	R3,=sculpt_wSize	;Get the workspace size
		SWI	XOS_Module		;Try to allocate the space
		LDMVSFD	R13!,{PC}		;Abort if it failed
		STR	R2,[R12,#0]		;Store the workspace address
		MOV	R12,R2			;Put pointer in R12

		; --- Initialise the workspace ---

		BL	sculpt__vduVars		;Read the VDU variables
		MOV	R14,#1			;Use Wimp area by default
		STR	R14,sculpt_sprArea	;Store this as the area
		MOV	R14,#0			;Clear some initial flags
		STR	R14,sculpt_flags	;Store these away

		; --- Initialise colour tables ---

		ADR	R0,sculpt__colDefs	;Point to the config block
		BL	config_set		;Set the configuration

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

sculpt__colDefs	DCD	0
		DCB	4,0,4,0
		DCB	2,0,2,0
		DCB	12,14

		LTORG

; --- sculpt__final ---
;
; On entry:	--
;
; On exit:	R0-R6 corrupted
;
; Use:		Clears up after Sculptrix.  We try to free the workspace,
;		but return even if this failed, since it isn't worth screwing
;		up the whole computer for the sake of <1K of memory.

sculpt__final	ROUT

		STMFD	R13!,{R14}		;Save return address

		; --- Just workspace to free ---

		MOV	R0,#7			;Free RMA block
		LDR	R2,[R12,#0]		;Load the address
		SWI	XOS_Module		;Try to do this
		MOV	R14,#0			;Zero workspace address
		STR	R14,[R12,#0]		;Do this anyway

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

		LTORG

; --- sculpt__service ---
;
; On entry:	R1 == service number
;
; On exit:	--
;
; Use:		Handles service calls to the Sculptrix module.

sculpt__service	ROUT

		CMP	R1,#&46			;Is it a mode change call?
		MOVNES	PC,R14			;No -- ignore it then

		LDR	R12,[R12,#0]		;Load the workspace address
		B	sculpt__vduVars		;Set up the VDU variables

		LTORG

; --- sculpt__vduVars ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Reads the VDU variables into Sculptrix's cache buffer.

sculpt__vduVars	ROUT

		STMFD	R13!,{R0-R2,R14}	;Save some registers

		; --- Read the pixel sizes ---

		ADR	R0,sculpt__vduList	;Point to request list
		ADR	R1,sculpt_vduVars	;Point to output buffer
		SWI	XOS_ReadVduVariables	;Read the variable values

		LDMIA	R1,{R0,R1}		;Load the values out

		; --- Now work out the mitring start ---

		ORR	R2,R0,R1,LSL #2		;Build a table index
		ADR	R14,sculpt__mitres	;Point to the table
		LDRB	R2,[R14,R2]		;Load the value I want

		; --- Convert to pixels ---

		MOV	R14,#1			;We need this...
		MOV	R0,R14,LSL R0		;Convert log to pixels
		MOV	R1,R14,LSL R1		;For both of them, please
		ADR	R14,sculpt_vduVars	;Point to output buffer
		STMIA	R14,{R0-R2}		;Store the values away
		LDMFD	R13!,{R0-R2,PC}^	;Return when finished

		; --- Which VDU variables to get ---

sculpt__vduList	DCD	4,5,-1			;Just x- and y-EIG factors

		; --- Table of mitring values ---

sculpt__mitres	DCB	1,2,0,0
		DCB	2,2,0,0
		DCB	2,2,4,0

		LTORG

; --- sculpt__swis ---
;
; On entry:	R0-R9 == arguments
;		R11 == SWI number
;
; On exit:	R0-R9 == return values
;
; Use:		Processes SWI calls to Sculptrix.

sculpt__swis	ROUT

		LDR	R12,[R12,#0]		;Load my workspace pointer
		CMP	R11,#(%10-%00)/4	;Is the SWI in range?
		ADDCC	PC,PC,R11,LSL #2	;Yes -- dispatch to handler
		B	%10sculpt__swis		;Otherwise report error

00		B	redraw_window		;Sculptrix_RedrawWindow
		B	slab_doSlab		;Sculptrix_DoSlab
		B	slab_slab		;Sculptrix_SlabIcon
		B	slab_unslab		;Sculptrix_UnslabIcon
		B	bbox_calc		;Sculptrix_BoundingBox
		B	redraw_icon		;Sculptrix_PlotIcon
		B	redraw_group		;Sculptrix_PlotGroupBox
		B	sculpt__setArea		;Sculptrix_SetSpriteArea
		B	redraw_update		;Sculptrix_UpdateIcon
		B	slab_colour		;Sculptrix_SlabColour
		B	config_set		;Sculptrix_SetConfig
		B	config_read		;Sculptrix_ReadConfig

10		ADRL	R0,msg_errBadSwi	;Point to the error message
		ORRS	PC,R14,#V_flag		;And return the error

		LTORG

; --- sculpt__setArea ---
;
; On entry:	R0 == sprite area to select
;
; On exit:	--
;
; Use:		Sets the sprite area to use.

sculpt__setArea	ROUT

		STR	R0,sculpt_sprArea	;Store the area address
		MOVS	PC,R14			;And return to caller

		LTORG

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

		END
