;
; res.s
;
; Locating resources (MDW)
;
;  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:string
		GET	sapphire:sapphire

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

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- res_exists ---
;
; On entry:	R0 == pointer to pathname
;
; On exit:	CS if the file exists, CC otherwise
;
; Use:		Tries to find the named file.  The file is deemed to exist
;		if OS_File can return a valid object type for it (i.e. not
;		`non-existant object' or actually raising errors).

		EXPORT	res_exists
res_exists	ROUT

		STMFD	R13!,{R0-R5,R14}	;Stack some registers
		MOV	R1,R0			;Point to the filename
		MOV	R0,#17			;Find information about file
		SWI	XOS_File		;Try to find the file
		MOVVS	R0,#0			;If error, say didn't exist
		CMP	R0,#0			;Is it a nonexistant thing?
		LDMFD	R13!,{R0-R5,R14}	;Restore the registers
		ORRNES	PC,R14,#C_flag		;If it is there, set C
		BICEQS	PC,R14,#C_flag		;Otherwise clear it

		LTORG

; --- res__trySuffix ---
;
; On entry:	R0 == pointer to pathname to try
;		R1 == pointer to end of pathname
;
; On exit:	R0 == pointer to pathname start (same as entry)
;		R1 == pointer to pathname end (may be different)
;		If C is set on exit, the pathname is updated to show the
;		  suffix which was found successfully.
;
; Use:		Tries to find a named file with either a suffix
;		(Wimp_ReadSysInfo-style) or no suffix with the given
;		basename.

res__trySuffix	ROUT

		STMFD	R13!,{R0,R2-R4,R14}	;Stack some registers again

		; --- Try to read the suffix string ---

		MOV	R4,R1			;Keep end pointer
		MOV	R3,R0			;Keep start pointer too!
		MOV	R0,#-1			;Use the current mode
		MOV	R1,#5			;Read the y-EIG factor
		SWI	OS_ReadModeVariable	;Read that then, please
		CMP	R2,#2			;Is this a low-res mode?
		ADRCS	R1,res__lowRes		;Yes -- point to the suffix
		ADRCC	R1,res__hiRes		;No -- point to other suffix

		; --- Tack the suffix on the end of the string ---

		MOV	R0,R4			;Point to the main string
		BL	str_cpy			;Copy the suffix on

		; --- Find out whether the file exists ---

		MOV	R1,R0			;Point to null terminator
		MOV	R0,R3			;Point to the string base
		BL	res_exists		;Does it exist?
		LDMCSFD	R13!,{R0,R2-R4,PC}	;Yes -- return with C set
		MOV	R0,#0			;Chop off terminator again
		STRB	R0,[R4,#0]		;Store it on the end

		; --- See if the basic file exists ---

		MOV	R0,R3			;Point to the base name
		MOV	R1,R4			;Point to the terminator
		LDMFD	R13!,{R0,R2-R4,R14}	;Unstack all the registers
		B	res_exists		;And see if it exists

res__lowRes	DCB	"24",0
res__hiRes	DCB	"22",0

		LTORG

; --- res_country ---
;
; On entry:	R0 == pointer to a buffer to use
;
; On exit:	R0 == pointer to country name (may not be in the buffer)
;
; Use:		Reads the name of the current country.  If no name can be
;		found, it returns a pointer to the string `UK' which should
;		do as a suitable default

		EXPORT	res_country
res_country	ROUT

		STMFD	R13!,{R0-R5,R14}	;Save loads of registers

		; --- Read the country number ---

		MOV	R0,#240			;Read country number
		MOV	R1,#0			;Read, don't write
		MOV	R2,#255			;Read, don't write
		SWI	OS_Byte			;Find the country number

		; --- Now get someone to translate it for us ---

		MOV	R3,R1			;Get the country number
		MOV	R1,#&43			;Service_International
		MOV	R2,#2			;The magic reason code
		LDR	R4,[R13],#4		;Get the buffer pointer
		MOV	R5,#20			;A fair size for the name
		SWI	OS_ServiceCall		;Try to find the name

		CMP	R1,#0			;Was the service call claimed
		ADRNE	R0,res__uk		;No -- point to `UK'
		STREQB	R1,[R4,R5]		;Yes -- null terminate string
		MOVEQ	R0,R4			;... and point to the name
		LDMFD	R13!,{R1-R5,PC}^	;Return to the caller

res__uk		DCB	"UK",0

		LTORG

; --- res_find ---
;
; On entry:	R0 == pointer to resource filename
;		R1 == pointer to buffer to build filename in
;
; On exit:	R0 == pointer to start of full pathname (R1 on entry)
;		R1 == pointer to terminating null character
;		CS if the file could actually be found, CC otherwise
;
; Use:		Locates a resource file.  It searches, in order:
;
;		* resPrefix.Resources.leaf[suffix]
;		* resPrefix.Resources.country.leaf[suffix]
;		* resPrefix.leaf[suffix]
;
;		returning the last if none of them could be found.  Note
;		that `country' here is the currently configured country
;		setting, and `suffix' is the WIMP mode aspect ratio suffix
;		for the current mode (RISC OS 3 only).

		EXPORT	res_find
res_find	ROUT

		STMFD	R13!,{R7-R10,R12,R14}	;Save some registers

		; --- First build the resource prefix ---

		WSPACE	res_wspace		;Find the workspace
		MOV	R10,R1			;Keep buffer pointer
		MOV	R7,R0			;Keep leafname pointer
		MOV	R0,R1			;Point to the buffer
		ADR	R1,res_prefix		;Point to resource root
		BL	str_cpy			;Copy it over

		; --- Now build resPrefix.Resources.leaf ---

		MOV	R1,#'.'			;Put a dot in there
		STRB	R1,[R0],#1		;Insert after res prefix
		MOV	R9,R0			;Keep this pointer
		ADR	R1,res__resources	;Point to `Resources'
		BL	str_cpy			;Copy it over
		MOV	R8,R0			;Keep this pointer for later
		MOV	R1,R7			;Point to leafname pointer
		BL	str_cpy			;Copy it over
		MOV	R1,R0			;Keep terminator pointer
		MOV	R0,R10			;Point to buffer
		BL	res__trySuffix		;Try adding a suffix then
		BCS	%10res_find		;If it's there return

		; --- Try resPrefix.Resources.country.leaf ---

		SUB	R13,R13,#20		;Drop the stack a bit
		MOV	R0,R13			;Point to this new buffer
		BL	res_country		;Read the country name
		MOV	R1,R0			;Keep the pointer
		MOV	R0,R8			;We remembered this pointer
		BL	str_cpy			;Copy the country name over
		ADD	R13,R13,#20		;Reclaim the stack
		MOV	R1,#'.'			;Put a dot in there
		STRB	R1,[R0],#1		;Insert after country name
		MOV	R1,R7			;Point to leafname
		BL	str_cpy			;Copy it over
		MOV	R1,R0			;Keep the end pointer
		MOV	R0,R10			;Point to buffer
		BL	res__trySuffix		;Try adding a suffix then
		BCS	%10res_find		;If it's there return

		; --- Try resPrefix.Resources.UK.leaf ---

		MOV	R0,R8			;We remembered this pointer
		ADR	R1,res__uk		;Point to the UK string
		BL	str_cpy			;Copy the country name over
		MOV	R1,#'.'			;Put a dot in there
		STRB	R1,[R0],#1		;Insert after country name
		MOV	R1,R7			;Point to leafname
		BL	str_cpy			;Copy it over
		MOV	R1,R0			;Keep the end pointer
		MOV	R0,R10			;Point to buffer
		BL	res__trySuffix		;Try adding a suffix then
		BCS	%10res_find		;If it's there return

		; --- No joy so just build resPrefix.leafname and quit ---

		MOV	R0,R9			;We remembered this point
		MOV	R1,R7			;Point to the leafname
		BL	str_cpy			;Copy it over
		MOV	R1,R0			;Keep the end pointer
		MOV	R0,R10			;Point to buffer
		BL	res__trySuffix		;Try adding a suffix then
		BCS	%10res_find		;If it's there return

		; --- Couldn't find it at all -- return with C clear ---

		LDMFD	R13!,{R7-R10,R12,R14}	;Unstack loads of registers
		BICS	PC,R14,#C_flag		;Return with C clear

		; --- We found a resource name -- return with C set ---

10res_find	LDMFD	R13!,{R7-R10,R12,R14}	;Unstack loads of registers
		ORRS	PC,R14,#C_flag		;Return with C set

res__resources	DCB	"Resources.",0

		LTORG

; --- res_init ---
;
; On entry:	R0 == pointer to application name
;
; On exit:	--
;
; Use:		Initialises the resource prefix to <appname$Dir>

		EXPORT	res_init
res_init	ROUT

		STMFD	R13!,{R0-R2,R12,R14}	;Save some registers
		WSPACE	res_wspace		;Get my workspace pointer
		LDR	R14,res_wstart		;Get the first word
		CMP	R14,#0			;Are we initialised?
		LDMNEFD	R13!,{R0-R2,R12,PC}^	;Yes -- return
		MOV	R2,R0			;Point to application name
		ADR	R1,res_prefix		;Point to my buffer
		ADR	R0,res__skeleton	;Point to skeleton for this
		BL	str_subst		;Build the string up
		LDMFD	R13!,{R0-R2,R12,PC}^	;Return to caller

res__skeleton	DCB	"<%0$Dir>",0

		LTORG

res_wspace	DCD	0

;----- Workspace ------------------------------------------------------------

		^	0,R12
res_wstart	#	0

res_prefix	#	40			;Prefix string

res_wsize	EQU	{VAR}-res_wstart

		AREA	|Sapphire$$LibData|,CODE,READONLY

		DCD	res_wsize
		DCD	res_wspace
		DCD	0
		DCD	res_init

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


		END
