OSDN Git Service

- Added desaturation translation support to ACC. This is the same as the % syntax...
[zandronum/zandronum-acc.git] / misc.c
1 \r
2 //**************************************************************************\r
3 //**\r
4 //** misc.c\r
5 //**\r
6 //**************************************************************************\r
7 \r
8 // HEADER FILES ------------------------------------------------------------\r
9 \r
10 #ifdef __NeXT__\r
11 #include <libc.h>\r
12 #else\r
13 #include <fcntl.h>\r
14 #include <stdlib.h>\r
15 #ifndef unix\r
16 #include <io.h>\r
17 #endif\r
18 #endif\r
19 #ifdef __GNUC__\r
20 #include <sys/stat.h>\r
21 #include <unistd.h>\r
22 #endif\r
23 #ifdef _WIN32\r
24 #include <sys/stat.h>\r
25 #include <sys/types.h>\r
26 #endif\r
27 #include <stdio.h>\r
28 #include <stddef.h>\r
29 #include <stdarg.h>\r
30 #include <string.h>\r
31 #include <ctype.h>\r
32 #include "common.h"\r
33 #include "misc.h"\r
34 #include "error.h"\r
35 \r
36 // MACROS ------------------------------------------------------------------\r
37 \r
38 #ifndef O_BINARY\r
39 #define O_BINARY 0\r
40 #endif\r
41 \r
42 // TYPES -------------------------------------------------------------------\r
43 \r
44 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------\r
45 \r
46 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------\r
47 \r
48 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------\r
49 \r
50 // EXTERNAL DATA DECLARATIONS ----------------------------------------------\r
51 \r
52 extern boolean acs_BigEndianHost;\r
53 extern boolean acs_VerboseMode;\r
54 extern boolean acs_DebugMode;\r
55 extern FILE *acs_DebugFile;\r
56 \r
57 // PUBLIC DATA DEFINITIONS -------------------------------------------------\r
58 \r
59 // PRIVATE DATA DEFINITIONS ------------------------------------------------\r
60 \r
61 // CODE --------------------------------------------------------------------\r
62 \r
63 //==========================================================================\r
64 //\r
65 // MS_Alloc\r
66 //\r
67 //==========================================================================\r
68 \r
69 void *MS_Alloc(size_t size, error_t error)\r
70 {\r
71         void *mem;\r
72 \r
73         if((mem = malloc(size)) == NULL)\r
74         {\r
75                 ERR_Exit(error, NO);\r
76         }\r
77         return mem;\r
78 }\r
79 \r
80 //==========================================================================\r
81 //\r
82 // MS_Realloc\r
83 //\r
84 //==========================================================================\r
85 \r
86 void *MS_Realloc(void *base, size_t size, error_t error)\r
87 {\r
88         void *mem;\r
89 \r
90         if((mem = realloc(base, size)) == NULL)\r
91         {\r
92                 ERR_Exit(error, NO);\r
93         }\r
94         return mem;\r
95 }\r
96 \r
97 //==========================================================================\r
98 //\r
99 // MS_LittleUWORD\r
100 //\r
101 // Converts a host U_WORD (2 bytes) to little endian byte order.\r
102 //\r
103 //==========================================================================\r
104 \r
105 U_WORD MS_LittleUWORD(U_WORD val)\r
106 {\r
107         if(acs_BigEndianHost == NO)\r
108         {\r
109                 return val;\r
110         }\r
111         return ((val&255)<<8)+((val>>8)&255);\r
112 }\r
113 \r
114 //==========================================================================\r
115 //\r
116 // MS_LittleUINT\r
117 //\r
118 // Converts a host U_INT (4 bytes) to little endian byte order.\r
119 //\r
120 //==========================================================================\r
121 \r
122 U_INT MS_LittleUINT(U_INT val)\r
123 {\r
124         if(acs_BigEndianHost == NO)\r
125         {\r
126                 return val;\r
127         }\r
128         return ((val&255)<<24)+(((val>>8)&255)<<16)+(((val>>16)&255)<<8)\r
129                 +((val>>24)&255);\r
130 }\r
131 \r
132 //==========================================================================\r
133 //\r
134 // MS_LoadFile\r
135 //\r
136 //==========================================================================\r
137 \r
138 int MS_LoadFile(char *name, char **buffer)\r
139 {\r
140         int handle;\r
141         int size;\r
142         int count;\r
143         char *addr;\r
144         struct stat fileInfo;\r
145 \r
146         if(strlen(name) >= MAX_FILE_NAME_LENGTH)\r
147         {\r
148                 ERR_Exit(ERR_FILE_NAME_TOO_LONG, NO, name);\r
149         }\r
150         if((handle = open(name, O_RDONLY|O_BINARY, 0666)) == -1)\r
151         {\r
152                 ERR_Exit(ERR_CANT_OPEN_FILE, NO, name);\r
153         }\r
154         if(fstat(handle, &fileInfo) == -1)\r
155         {\r
156                 ERR_Exit(ERR_CANT_READ_FILE, NO, name);\r
157         }\r
158         size = fileInfo.st_size;\r
159         if((addr = malloc(size)) == NULL)\r
160         {\r
161                 ERR_Exit(ERR_NONE, NO, "Couldn't malloc %d bytes for "\r
162                         "file \"%s\".", size, name);\r
163         }\r
164         count = read(handle, addr, size);\r
165         close(handle);\r
166         if(count < size)\r
167         {\r
168                 ERR_Exit(ERR_CANT_READ_FILE, NO, name);\r
169         }\r
170         *buffer = addr;\r
171         return size;\r
172 }\r
173 \r
174 \r
175 //==========================================================================\r
176 //\r
177 // MS_FileExists\r
178 //\r
179 // Pascal 21/11/08\r
180 //\r
181 //==========================================================================\r
182 boolean MS_FileExists(char *name)\r
183 {\r
184         struct stat info;\r
185         int ret = stat(name, &info);\r
186         return (ret == 0);\r
187 }\r
188 \r
189 \r
190 //==========================================================================\r
191 //\r
192 // MS_SaveFile\r
193 //\r
194 //==========================================================================\r
195 \r
196 boolean MS_SaveFile(char *name, void *buffer, int length)\r
197 {\r
198         int handle;\r
199         int count;\r
200 \r
201         handle = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);\r
202         if(handle == -1)\r
203         {\r
204                 return FALSE;\r
205         }\r
206         count = write(handle, buffer, length);\r
207         close(handle);\r
208         if(count < length)\r
209         {\r
210                 return FALSE;\r
211         }\r
212         return TRUE;\r
213 }\r
214 \r
215 //==========================================================================\r
216 //\r
217 // MS_StrCmp\r
218 //\r
219 //==========================================================================\r
220 \r
221 int MS_StrCmp(char *s1, char *s2)\r
222 {\r
223         for(; tolower(*s1) == tolower(*s2); s1++, s2++)\r
224         {\r
225                 if(*s1 == '\0')\r
226                 {\r
227                         return 0;\r
228                 }\r
229         }\r
230         return tolower(*s1)-tolower(*s2);\r
231 }\r
232 \r
233 //==========================================================================\r
234 //\r
235 // MS_StrLwr\r
236 //\r
237 //==========================================================================\r
238 \r
239 char *MS_StrLwr(char *string)\r
240 {\r
241         char *c;\r
242 \r
243         c = string;\r
244         while(*c)\r
245         {\r
246                 *c = tolower(*c);\r
247                 c++;\r
248         }\r
249         return string;\r
250 }\r
251 \r
252 //==========================================================================\r
253 //\r
254 // MS_StrUpr\r
255 //\r
256 //==========================================================================\r
257 \r
258 char *MS_StrUpr(char *string)\r
259 {\r
260         char *c;\r
261 \r
262         c = string;\r
263         while(*c)\r
264         {\r
265                 *c = toupper(*c);\r
266                 c++;\r
267         }\r
268         return string;\r
269 }\r
270 \r
271 //==========================================================================\r
272 //\r
273 // MS_SuggestFileExt\r
274 //\r
275 //==========================================================================\r
276 \r
277 void MS_SuggestFileExt(char *base, char *extension)\r
278 {\r
279         char *search;\r
280 \r
281         search = base+strlen(base)-1;\r
282         while(!MS_IsDirectoryDelimiter(*search) && search != base)\r
283         {\r
284                 if(*search-- == '.')\r
285                 {\r
286                         return;\r
287                 }\r
288         }\r
289         strcat(base, extension);\r
290 }\r
291 \r
292 //==========================================================================\r
293 //\r
294 // MS_IsDirectoryDelimiter\r
295 //\r
296 //==========================================================================\r
297 \r
298 boolean MS_IsDirectoryDelimiter(char foo)\r
299 {\r
300 #if defined(_WIN32) || defined(__MSDOS__)\r
301         return foo == '/' || foo == '\\' || foo == ':';\r
302 #else\r
303         return foo == '/';\r
304 #endif\r
305 }\r
306 \r
307 \r
308 //==========================================================================\r
309 //\r
310 // MS_StripFileExt\r
311 //\r
312 //==========================================================================\r
313 \r
314 void MS_StripFileExt(char *name)\r
315 {\r
316         char *search;\r
317 \r
318         search = name+strlen(name)-1;\r
319         while(!MS_IsDirectoryDelimiter(*search) && search != name)\r
320         {\r
321                 if(*search == '.')\r
322                 {\r
323                         *search = '\0';\r
324                         return;\r
325                 }\r
326                 search--;\r
327         }\r
328 }\r
329 \r
330 //==========================================================================\r
331 //\r
332 // MS_StripFilename\r
333 //\r
334 // [RH] This now leaves the directory delimiter in place.\r
335 //\r
336 //==========================================================================\r
337 \r
338 boolean MS_StripFilename(char *name)\r
339 {\r
340         char *c;\r
341 \r
342         c = name+strlen(name);\r
343         do\r
344         {\r
345                 if(--c == name)\r
346                 { // No directory delimiter\r
347                         return NO;\r
348                 }\r
349         } while(!MS_IsDirectoryDelimiter(*c));\r
350         *(c+1) = 0;\r
351         return YES;\r
352 }\r
353 \r
354 //==========================================================================\r
355 //\r
356 // MS_Message\r
357 //\r
358 //==========================================================================\r
359 \r
360 void MS_Message(msg_t type, char *text, ...)\r
361 {\r
362         FILE *fp;\r
363         va_list argPtr;\r
364 \r
365         if(type == MSG_VERBOSE && acs_VerboseMode == NO)\r
366         {\r
367                 return;\r
368         }\r
369         fp = stdout;\r
370         if(type == MSG_DEBUG)\r
371         {\r
372                 if(acs_DebugMode == NO)\r
373                 {\r
374                         return;\r
375                 }\r
376                 if(acs_DebugFile != NULL)\r
377                 {\r
378                         fp = acs_DebugFile;\r
379                 }\r
380         }\r
381         if(text)\r
382         {\r
383                 va_start(argPtr, text);\r
384                 vfprintf(fp, text, argPtr);\r
385                 va_end(argPtr);\r
386         }\r
387 }\r
388 \r
389 //==========================================================================\r
390 //\r
391 // MS_IsPathAbsolute\r
392 //\r
393 // Pascal 30/11/08\r
394 //\r
395 //==========================================================================\r
396 \r
397 boolean MS_IsPathAbsolute(char *name)\r
398 {\r
399 #if defined(_WIN32) || defined(__MSDOS__)\r
400         // In Windows, the second character must be : if it is an\r
401         // absolute path (the first character indicates the drive)\r
402         // or the first character is either / or \ for absolute path\r
403         if((name[0] != '\0') && (name[1] == ':'))\r
404                 return TRUE;\r
405 #endif\r
406         // In Unix-land, the first character must be / for a root path\r
407         return MS_IsDirectoryDelimiter(name[0]);\r
408 }\r