1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 
6 #include <sys/stat.h>
7 #if PLATFORM_UNIX
8 #include <sys/types.h>
9 #include <errno.h>
10 #include <unistd.h>
11 #endif
12 
13 #include <fcntl.h>
14 
15 #include "rt_def.h"
16 
17 #if defined(USE_SDL)
18 #include "SDL.h"
19 #endif
20 
21 /*
22   Copied over from Wolf3D Linux: http://www.icculus.org/wolf3d/
23   Modified for ROTT.
24  */
25 
26 int _argc;
27 char **_argv;
28 
29 #if PLATFORM_UNIX
30 #ifndef DC
filelength(int handle)31 long filelength(int handle)
32 {
33 	struct stat buf;
34 
35 	if (fstat(handle, &buf) == -1) {
36 		perror("filelength");
37 		exit(EXIT_FAILURE);
38 	}
39 
40 	return buf.st_size;
41 }
42 #endif
43 
strlwr(char * s)44 char *strlwr(char *s)
45 {
46 	char *p = s;
47 
48 	while (*p) {
49 		*p = tolower(*p);
50 		p++;
51 	}
52 
53 	return s;
54 }
55 
strupr(char * s)56 char *strupr(char *s)
57 {
58 	char *p = s;
59 
60 	while (*p) {
61 		*p = toupper(*p);
62 		p++;
63 	}
64 
65 	return s;
66 }
67 
itoa(int value,char * string,int radix)68 char *itoa(int value, char *string, int radix)
69 {
70 	switch (radix) {
71 		case 10:
72 			sprintf(string, "%d", value);
73 			break;
74 		case 16:
75 			sprintf(string, "%x", value);
76 			break;
77 		default:
78 			STUB_FUNCTION;
79 			break;
80 	}
81 
82 	return string;
83 }
84 
ltoa(long value,char * string,int radix)85 char *ltoa(long value, char *string, int radix)
86 {
87 	switch (radix) {
88 		case 10:
89 			sprintf(string, "%ld", value);
90 			break;
91 		case 16:
92 			sprintf(string, "%lx", value);
93 			break;
94 		default:
95 			STUB_FUNCTION;
96 			break;
97 	}
98 
99 	return string;
100 }
101 
ultoa(unsigned long value,char * string,int radix)102 char *ultoa(unsigned long value, char *string, int radix)
103 {
104 	switch (radix) {
105 		case 10:
106 			sprintf(string, "%lu", value);
107 			break;
108 		case 16:
109 			sprintf(string, "%lux", value);
110 			break;
111 		default:
112 			STUB_FUNCTION;
113 			break;
114 	}
115 
116 	return string;
117 }
118 #endif
119 
getch(void)120 char getch(void)
121 {
122 	getchar();
123 	return 0;
124 }
125 
126 extern char ApogeePath[256];
127 
setup_homedir(void)128 int setup_homedir (void)
129 {
130 #if PLATFORM_UNIX && !defined(DC)
131 	int err;
132 
133 	/* try to create the root directory */
134 	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
135 	err = mkdir (ApogeePath, S_IRWXU);
136 
137 /* keep the shareware and registered game data separated */
138 #if (SHAREWARE == 1)
139 	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
140 #else
141 	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/darkwar/", getenv ("HOME"));
142 #endif
143 
144 	err = mkdir (ApogeePath, S_IRWXU);
145 	if (err == -1 && errno != EEXIST)
146 	{
147 		fprintf (stderr, "Couldn't create preferences directory: %s\n",
148 				strerror (errno));
149 		return -1;
150 	}
151 #else
152     sprintf(ApogeePath, ".%s", PATH_SEP_STR);
153 #endif
154 
155 	return 0;
156 }
157 
158 /* from Dan Olson */
put_dos2ansi(byte attrib)159 void put_dos2ansi(byte attrib)
160 {
161 	int lookup[] = {30,34,32,36,31,35,33,37};
162 	byte fore,back,blink=0,intens=0;
163 
164 	fore = attrib&15;	/* bits 0-3 */
165 	back = attrib&112; /* bits 4-6 */
166        	blink = attrib&128; /* bit 7 */
167 
168 	/* Fix background, blink is either on or off. */
169 	back = back>>4;
170 
171 	/* Fix foreground */
172 	if (fore > 7) {
173 		intens = 1;
174 		fore-=8;
175 	}
176 
177 	/* Convert fore/back */
178 	fore = lookup[fore];
179 	back = lookup[back]+10;
180 
181 	// 'Render"
182 	if (blink)
183 		printf ("\033[%d;5;%dm\033[%dm", intens, fore, back);
184 	else
185 		printf ("\033[%d;25;%dm\033[%dm", intens, fore, back);
186 }
187 
DisplayTextSplash(byte * text,int l)188 void DisplayTextSplash(byte *text, int l)
189 {
190 	int i;
191 	int bound = 80*l*2;
192 
193 	for (i=0;i<bound;i+=2)
194 	{
195 		put_dos2ansi(text[i+1]);
196 		putchar (text[i]);
197 	}
198 
199 	printf ("\033[m");
200 }
201 
202 #if (USE_EXECINFO == 1)
203 #include <execinfo.h>
204 
print_stack(int level)205 void print_stack (int level)
206 {
207 	void *array[64];
208 	char **syms;
209 	int size, i;
210 
211 	printf ("Stack dump:\n");
212 	printf ("{\n");
213 	size = backtrace (array, (sizeof (array))/(sizeof (array[0])));
214 	syms = backtrace_symbols (array, size);
215 	for (i=level+1; i<size;++i) {
216 		printf ("\t%s\n",syms[i]);
217 	}
218 	free (syms);
219 	/*
220 	for (i = 2; i <size; ++i) {
221 		printf ("\t%p\n", array[i]);
222 	}
223 	*/
224 	printf ("}\n");
225 }
226 #else
227 
print_stack(int level)228 void print_stack (int level)
229 {
230         printf("Stack dump not implemented.\n");
231 }
232 
233 #endif
234 
crash_print(int sig)235 void crash_print (int sig)
236 {
237 	printf ("OH NO OH NO ROTT CRASHED!\n");
238 	printf ("Here is where:\n");
239 	print_stack (1);
240 #if defined(USE_SDL)
241 	SDL_Quit ();
242 #endif
243 	exit (1);
244 }
245 
246 #if 0
247 /* ** */
248 
249 uint16_t SwapInt16L(uint16_t i)
250 {
251 #if BYTE_ORDER == BIG_ENDIAN
252 	return ((uint16_t)i >> 8) | ((uint16_t)i << 8);
253 #else
254 	return i;
255 #endif
256 }
257 
258 uint32_t SwapInt32L(uint32_t i)
259 {
260 #if BYTE_ORDER == BIG_ENDIAN
261 	return	((uint32_t)(i & 0xFF000000) >> 24) |
262 		((uint32_t)(i & 0x00FF0000) >>  8) |
263 		((uint32_t)(i & 0x0000FF00) <<  8) |
264 		((uint32_t)(i & 0x000000FF) << 24);
265 #else
266 	return i;
267 #endif
268 }
269 
270 /* ** */
271 
272 int OpenWrite(char *_fn)
273 {
274 	int fp;
275     char fn[MAX_PATH];
276     strncpy(fn, _fn, sizeof (fn));
277     fn[sizeof (fn) - 1] = '\0';
278     FixFilePath(fn);
279 
280 	fp = open(fn, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
281 	return fp;
282 }
283 
284 int OpenWriteAppend(char *_fn)
285 {
286 	int fp;
287     char fn[MAX_PATH];
288     strncpy(fn, _fn, sizeof (fn));
289     fn[sizeof (fn) - 1] = '\0';
290     FixFilePath(fn);
291 
292 	fp = open(fn, O_CREAT|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
293 	return fp;
294 }
295 
296 void CloseWrite(int fp)
297 {
298 	close(fp);
299 }
300 
301 int WriteSeek(int fp, int offset, int whence)
302 {
303 	return lseek(fp, offset, whence);
304 }
305 
306 int WritePos(int fp)
307 {
308 	return lseek(fp, 0, SEEK_CUR);
309 }
310 
311 int WriteInt8(int fp, int8_t d)
312 {
313 	return write(fp, &d, 1);
314 }
315 
316 int WriteInt16(int fp, int16_t d)
317 {
318 	int16_t b = SwapInt16L(d);
319 
320 	return write(fp, &b, 2) / 2;
321 }
322 
323 int WriteInt32(int fp, int32_t d)
324 {
325 	int32_t b = SwapInt32L(d);
326 
327 	return write(fp, &b, 4) / 4;
328 }
329 
330 int WriteBytes(int fp, byte *d, int len)
331 {
332 	return write(fp, d, len);
333 }
334 
335 
336 int OpenRead(char *_fn)
337 {
338 	int fp;
339     char fn[MAX_PATH];
340     strncpy(fn, _fn, sizeof (fn));
341     fn[sizeof (fn) - 1] = '\0';
342     FixFilePath(fn);
343 
344 	fp = open(fn, O_RDONLY | O_BINARY);
345 
346 	return fp;
347 }
348 
349 void CloseRead(int fp)
350 {
351 	close(fp);
352 }
353 
354 int ReadSeek(int fp, int offset, int whence)
355 {
356 	return lseek(fp, offset, whence);
357 }
358 
359 int ReadLength(int fp)
360 {
361 	return filelength(fp);
362 }
363 
364 int8_t ReadInt8(int fp)
365 {
366 	byte d[1];
367 
368 	read(fp, d, 1);
369 
370 	return d[0];
371 }
372 
373 int16_t ReadInt16(int fp)
374 {
375 	byte d[2];
376 
377 	read(fp, d, 2);
378 
379 	return (d[0]) | (d[1] << 8);
380 }
381 
382 int32_t ReadInt32(int fp)
383 {
384 	byte d[4];
385 
386 	read(fp, d, 4);
387 
388 	return (d[0]) | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
389 }
390 
391 int ReadBytes(int fp, byte *d, int len)
392 {
393 	return read(fp, d, len);
394 }
395 
396 #endif
397