395 lines
5.9 KiB
C
Executable File
395 lines
5.9 KiB
C
Executable File
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include <sys/stat.h>
|
|
#if PLATFORM_UNIX
|
|
#include <sys/types.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include "rt_def.h"
|
|
|
|
#if defined(USE_SDL)
|
|
#include "SDL.h"
|
|
#endif
|
|
|
|
/*
|
|
Copied over from Wolf3D Linux: http://www.icculus.org/wolf3d/
|
|
Modified for ROTT.
|
|
*/
|
|
|
|
int _argc;
|
|
char **_argv;
|
|
|
|
#if PLATFORM_UNIX
|
|
long filelength(int handle)
|
|
{
|
|
struct stat buf;
|
|
|
|
if (fstat(handle, &buf) == -1) {
|
|
perror("filelength");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return buf.st_size;
|
|
}
|
|
|
|
char *strlwr(char *s)
|
|
{
|
|
char *p = s;
|
|
|
|
while (*p) {
|
|
*p = tolower(*p);
|
|
p++;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
char *strupr(char *s)
|
|
{
|
|
char *p = s;
|
|
|
|
while (*p) {
|
|
*p = toupper(*p);
|
|
p++;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
char *itoa(int value, char *string, int radix)
|
|
{
|
|
switch (radix) {
|
|
case 10:
|
|
sprintf(string, "%d", value);
|
|
break;
|
|
case 16:
|
|
sprintf(string, "%x", value);
|
|
break;
|
|
default:
|
|
STUB_FUNCTION;
|
|
break;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
char *ltoa(long value, char *string, int radix)
|
|
{
|
|
switch (radix) {
|
|
case 10:
|
|
sprintf(string, "%ld", value);
|
|
break;
|
|
case 16:
|
|
sprintf(string, "%lx", value);
|
|
break;
|
|
default:
|
|
STUB_FUNCTION;
|
|
break;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
char *ultoa(unsigned long value, char *string, int radix)
|
|
{
|
|
switch (radix) {
|
|
case 10:
|
|
sprintf(string, "%lu", value);
|
|
break;
|
|
case 16:
|
|
sprintf(string, "%lux", value);
|
|
break;
|
|
default:
|
|
STUB_FUNCTION;
|
|
break;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
#endif
|
|
|
|
char getch(void)
|
|
{
|
|
getchar();
|
|
return 0;
|
|
}
|
|
|
|
extern char ApogeePath[256];
|
|
|
|
int setup_homedir (void)
|
|
{
|
|
#if PLATFORM_UNIX && !defined(__MINGW32__)
|
|
int err;
|
|
|
|
/* try to create the root directory */
|
|
snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
|
|
err = mkdir (ApogeePath, S_IRWXU);
|
|
|
|
/* keep the shareware and registered game data separated */
|
|
#if (SHAREWARE == 1)
|
|
snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
|
|
#else
|
|
snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/darkwar/", getenv ("HOME"));
|
|
#endif
|
|
|
|
err = mkdir (ApogeePath, S_IRWXU);
|
|
if (err == -1 && errno != EEXIST)
|
|
{
|
|
fprintf (stderr, "Couldn't create preferences directory: %s\n",
|
|
strerror (errno));
|
|
return -1;
|
|
}
|
|
#else
|
|
sprintf(ApogeePath, ".%s", PATH_SEP_STR);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* from Dan Olson */
|
|
void put_dos2ansi(byte attrib)
|
|
{
|
|
int lookup[] = {30,34,32,36,31,35,33,37};
|
|
byte fore,back,blink=0,intens=0;
|
|
|
|
fore = attrib&15; /* bits 0-3 */
|
|
back = attrib&112; /* bits 4-6 */
|
|
blink = attrib&128; /* bit 7 */
|
|
|
|
/* Fix background, blink is either on or off. */
|
|
back = back>>4;
|
|
|
|
/* Fix foreground */
|
|
if (fore > 7) {
|
|
intens = 1;
|
|
fore-=8;
|
|
}
|
|
|
|
/* Convert fore/back */
|
|
fore = lookup[fore];
|
|
back = lookup[back]+10;
|
|
|
|
// 'Render"
|
|
if (blink)
|
|
printf ("\033[%d;5;%dm\033[%dm", intens, fore, back);
|
|
else
|
|
printf ("\033[%d;25;%dm\033[%dm", intens, fore, back);
|
|
}
|
|
|
|
void DisplayTextSplash(byte *text, int l)
|
|
{
|
|
int i;
|
|
int bound = 80*l*2;
|
|
|
|
for (i=0;i<bound;i+=2)
|
|
{
|
|
put_dos2ansi(text[i+1]);
|
|
putchar (text[i]);
|
|
}
|
|
|
|
printf ("\033[m");
|
|
}
|
|
|
|
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
|
|
#include <execinfo.h>
|
|
|
|
void print_stack (int level)
|
|
{
|
|
void *array[64];
|
|
char **syms;
|
|
int size, i;
|
|
|
|
printf ("Stack dump:\n");
|
|
printf ("{\n");
|
|
size = backtrace (array, (sizeof (array))/(sizeof (array[0])));
|
|
syms = backtrace_symbols (array, size);
|
|
for (i=level+1; i<size;++i) {
|
|
printf ("\t%s\n",syms[i]);
|
|
}
|
|
free (syms);
|
|
/*
|
|
for (i = 2; i <size; ++i) {
|
|
printf ("\t%p\n", array[i]);
|
|
}
|
|
*/
|
|
printf ("}\n");
|
|
}
|
|
#else
|
|
|
|
void print_stack (int level)
|
|
{
|
|
printf("Stack dump not implemented.\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
void crash_print (int sig)
|
|
{
|
|
printf ("OH NO OH NO ROTT CRASHED!\n");
|
|
printf ("Here is where:\n");
|
|
print_stack (1);
|
|
#if defined(USE_SDL)
|
|
SDL_Quit ();
|
|
#endif
|
|
exit (1);
|
|
}
|
|
|
|
#if 0
|
|
/* ** */
|
|
|
|
uint16_t SwapInt16L(uint16_t i)
|
|
{
|
|
#if BYTE_ORDER == BIG_ENDIAN
|
|
return ((uint16_t)i >> 8) | ((uint16_t)i << 8);
|
|
#else
|
|
return i;
|
|
#endif
|
|
}
|
|
|
|
uint32_t SwapInt32L(uint32_t i)
|
|
{
|
|
#if BYTE_ORDER == BIG_ENDIAN
|
|
return ((uint32_t)(i & 0xFF000000) >> 24) |
|
|
((uint32_t)(i & 0x00FF0000) >> 8) |
|
|
((uint32_t)(i & 0x0000FF00) << 8) |
|
|
((uint32_t)(i & 0x000000FF) << 24);
|
|
#else
|
|
return i;
|
|
#endif
|
|
}
|
|
|
|
/* ** */
|
|
|
|
int OpenWrite(char *_fn)
|
|
{
|
|
int fp;
|
|
char fn[MAX_PATH];
|
|
strncpy(fn, _fn, sizeof (fn));
|
|
fn[sizeof (fn) - 1] = '\0';
|
|
FixFilePath(fn);
|
|
|
|
fp = open(fn, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
|
return fp;
|
|
}
|
|
|
|
int OpenWriteAppend(char *_fn)
|
|
{
|
|
int fp;
|
|
char fn[MAX_PATH];
|
|
strncpy(fn, _fn, sizeof (fn));
|
|
fn[sizeof (fn) - 1] = '\0';
|
|
FixFilePath(fn);
|
|
|
|
fp = open(fn, O_CREAT|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
|
return fp;
|
|
}
|
|
|
|
void CloseWrite(int fp)
|
|
{
|
|
close(fp);
|
|
}
|
|
|
|
int WriteSeek(int fp, int offset, int whence)
|
|
{
|
|
return lseek(fp, offset, whence);
|
|
}
|
|
|
|
int WritePos(int fp)
|
|
{
|
|
return lseek(fp, 0, SEEK_CUR);
|
|
}
|
|
|
|
int WriteInt8(int fp, int8_t d)
|
|
{
|
|
return write(fp, &d, 1);
|
|
}
|
|
|
|
int WriteInt16(int fp, int16_t d)
|
|
{
|
|
int16_t b = SwapInt16L(d);
|
|
|
|
return write(fp, &b, 2) / 2;
|
|
}
|
|
|
|
int WriteInt32(int fp, int32_t d)
|
|
{
|
|
int32_t b = SwapInt32L(d);
|
|
|
|
return write(fp, &b, 4) / 4;
|
|
}
|
|
|
|
int WriteBytes(int fp, byte *d, int len)
|
|
{
|
|
return write(fp, d, len);
|
|
}
|
|
|
|
|
|
int OpenRead(char *_fn)
|
|
{
|
|
int fp;
|
|
char fn[MAX_PATH];
|
|
strncpy(fn, _fn, sizeof (fn));
|
|
fn[sizeof (fn) - 1] = '\0';
|
|
FixFilePath(fn);
|
|
|
|
fp = open(fn, O_RDONLY | O_BINARY);
|
|
|
|
return fp;
|
|
}
|
|
|
|
void CloseRead(int fp)
|
|
{
|
|
close(fp);
|
|
}
|
|
|
|
int ReadSeek(int fp, int offset, int whence)
|
|
{
|
|
return lseek(fp, offset, whence);
|
|
}
|
|
|
|
int ReadLength(int fp)
|
|
{
|
|
return filelength(fp);
|
|
}
|
|
|
|
int8_t ReadInt8(int fp)
|
|
{
|
|
byte d[1];
|
|
|
|
read(fp, d, 1);
|
|
|
|
return d[0];
|
|
}
|
|
|
|
int16_t ReadInt16(int fp)
|
|
{
|
|
byte d[2];
|
|
|
|
read(fp, d, 2);
|
|
|
|
return (d[0]) | (d[1] << 8);
|
|
}
|
|
|
|
int32_t ReadInt32(int fp)
|
|
{
|
|
byte d[4];
|
|
|
|
read(fp, d, 4);
|
|
|
|
return (d[0]) | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
|
|
}
|
|
|
|
int ReadBytes(int fp, byte *d, int len)
|
|
{
|
|
return read(fp, d, len);
|
|
}
|
|
|
|
#endif
|