chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Steel / c / res
1 /*
2  * res
3  *
4  * Access to resources
5  *
6  * © 1993-1998 Straylight
7  */
8
9 /*----- Licensing note ----------------------------------------------------*
10  *
11  * This file is part of Straylight's Steel library.
12  *
13  * Steel is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * Steel is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with Steel.  If not, write to the Free Software Foundation,
25  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 #include <string.h>
29 #include <stdio.h>
30 #include "os.h"
31 #include "swiv.h"
32 #include "swis.h"
33 #include "wimpt.h"
34 #include "res.h"
35 #include "buffer.h"
36
37 static char res__prefix[40];
38
39 /*
40  *
41  * void res_init(char *progname)
42  *
43  * Use
44  *  Sets up res to use a certain path for resources.  Mainly for
45  *  compatibility with older applications.
46  *
47  * Parameters
48  *  char *progname == the program name (sets up path as <progname$Dir>)
49  */
50
51 void res_init(char *progname)
52 {
53   sprintf(res__prefix,"<%s$Dir>",progname);
54 }
55
56 /*
57  * void res_setPrefix(char *prefix)
58  *
59  * Use
60  *  Sets up a full prefix for resources.  This means you can keep resources
61  *  in separate directories.
62  *
63  * Parameters
64  *  char *prefix == the prefix
65  */
66
67 void res_setPrefix(char *prefix)
68 {
69   strcpy(res__prefix,prefix);
70 }
71
72 /*
73  * BOOL res_fileExists(char *name)
74  *
75  * Use
76  *  Informs the caller if a given file exists
77  *
78  * Parameters
79  *  char *name == the name of the file
80  *
81  * Returns
82  *  TRUE if the file really does exist
83  */
84
85 BOOL res_fileExists(char *name)
86 {
87   os_filestr f;
88   f.action=17;
89   f.name=name;
90   if (os_file(&f))
91     return (FALSE);
92   return (!!f.action);
93 }
94
95 /*
96  * BOOL res__trySuffix(char *name)
97  *
98  * Use
99  *  Tries to find a file with a possible WIMP-style mode suffix (24,23,22
100  *  etc.)  If it did, it updates the name in the caller's buffer, and
101  *  returns TRUE.  Otherwise, the name is preserved, and it returns FALSE.
102  */
103
104 static BOOL res__trySuffix(char *name)
105 {
106   char *suff;
107   char *end;
108   if (wimpt_getVersion()>=300)
109   {
110     end=name+strlen(name);
111     wimpt_noerr(wimp_readsysinfo(2,(int *)&suff));
112     strcat(name,suff);
113     if (res_fileExists(name))
114       return (TRUE);
115     *end=0;
116   }
117   if (res_fileExists(name))
118     return (TRUE);
119   return (FALSE);
120 }
121
122 /*
123  * char *res__findCountryName(void)
124  *
125  * Use
126  *  Returns the name of the current country.  If the current country is
127  *  unknown, try the UK.
128  */
129
130 static char *res__findCountryName(void)
131 {
132   char *buffer=buffer_find();
133   int country=_swi(OS_Byte,_inr(0,2)+_return(1),240,0,255);
134   int len;
135   if (_swi(OS_ServiceCall,
136            _inr(1,4)+_out(5)+_return(1),
137            0x43,2,country,buffer,
138            &len)==1)
139     return ("UK");
140   else
141   {
142     buffer[len]=0;
143     return (buffer);
144   }
145 }
146
147 /*
148  * int res_findname(const char *resname,char *buf)
149  *
150  * Use
151  *  Returns a full pathname for the resource file as given in the buffer.
152  *  This is for compatibility reasons.  If I was writing this fresh, I
153  *  would return a pointer to an internal static object, but Acorn know
154  *  best...
155  *
156  *  Some new functionality has been added.  It will look for files first in
157  *  the directory set up using res_init or res_setPrefix, and then in the
158  *  'Resources' subdirectory.  If neither is present, then the name returned
159  *  is in the main application directory.
160  *
161  *  Also, under RISC OS 3, it will search for files with mode prefixes, so
162  *  you can use multiple sprite files for different resolutions.  Isn't this
163  *  fun!
164  *
165  * Parameters
166  *  const char *resname == the leafname of the resource file.
167  *  char *buf == where to put the result.
168  *
169  * Returns
170  *  TRUE for compatibility with the Acorn version.  What good it does, I
171  *  don't know.  This is in all a very odd routine indeed.
172  */
173
174 int res_findname(const char *resname,char *buf)
175 {
176   sprintf(buf,"%s.Resources.%s",res__prefix,resname);
177   if (res__trySuffix(buf))
178     return (TRUE);
179   sprintf(buf,
180           "%s.Resources.%s.%s",
181           res__prefix,
182           res__findCountryName(),
183           resname);
184   if (res__trySuffix(buf))
185     return (TRUE);
186   sprintf(buf,
187           "%s.Resources.UK.%s",
188           res__prefix,
189           resname);
190   if (res__trySuffix(buf))
191     return (TRUE);
192   sprintf(buf,"%s.%s",res__prefix,resname);
193   if (res__trySuffix(buf))
194     return (TRUE);
195   sprintf(buf,"%s.%s",res__prefix,resname);
196   return (TRUE);
197 }
198
199 /*
200  * char *res_name(const char *resname)
201  *
202  * Use
203  *  Translates the name given as for res_findname and returns a pointer to
204  *  the translated string
205  */
206
207 char *res_name(const char *resname)
208 {
209   char *buffer=buffer_find();
210   res_findname(resname,buffer);
211   return (buffer);
212 }
213
214 /*
215  * FILE *res_openfile(const char *resname,const char *mode)
216  *
217  * Use
218  *  Opens a resource file in a given ANSI mode.  It does this without the
219  *  odd adding on of numbers to the end that the Acorn one does (I hope!)
220  *
221  * Parameters
222  *  const char *resname == leafname of file to open
223  *  const char *mode == pointer to ANSI mode string
224  *
225  * Returns
226  *  A standard ANSI-type FILE pointer.
227  */
228
229 FILE *res_openfile(const char *resname,const char *mode)
230 {
231   return (fopen(res_name(resname),mode));
232 }