diff options
Diffstat (limited to 'src/Support.cpp')
-rw-r--r-- | src/Support.cpp | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/src/Support.cpp b/src/Support.cpp new file mode 100644 index 0000000..7c77fc5 --- /dev/null +++ b/src/Support.cpp @@ -0,0 +1,386 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "SDL/SDL.h" + +#include "Support.h" +#include "Files.h" + +int Random() +{ +#if RAND_MAX >= 65535 + return (rand() % 65535) - 32767; +#else +#error please fix this for your platform +#endif +} + +void Microseconds(UnsignedWide *microTickCount) +{ + /* NOTE: hi isn't used in BS, so it's not implemented here */ + /* TODO: does game need microsecond precision? */ + microTickCount->hi = 0; + microTickCount->lo = SDL_GetTicks() * 1000; +} + +void GetMouse(Point *p) +{ + int x; + int y; + + SDL_GetMouseState(&x, &y); + + p->h = x; + p->v = y; +} + +void GetMouseRel(Point *p) +{ + int x; + int y; + + SDL_GetRelativeMouseState(&x, &y); + + p->h = x; + p->v = y; +} +int Button(void) +{ + return (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)); +} + +void InitMouse() +{ +// STUB_FUNCTION; +} + +void MoveMouse(int xcoord, int ycoord, Point *mouseloc) +{ + /* TODO: mouse warp is annoying when we can just grab the mouse */ +#ifdef FULLSCREEN + SDL_WarpMouse(xcoord, ycoord); + SDL_PumpEvents(); +#endif + GetMouse(mouseloc); +} + +void DisposeMouse() +{ +// STUB_FUNCTION; +} + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifndef MAX_PATH +#define MAX_PATH 256 +#endif + +static int find_filename(char *filename) +{ + char *ptr; + char *cur; + char *next; + DIR *dir; + struct dirent *dirent; + + if (access(filename, R_OK) == 0) { + return 1; + } + + ptr = filename; + + while (*ptr) { + if (ptr == filename || *ptr == '/') { + if (*ptr == '/') { + cur = ptr+1; + } else { + cur = ptr; + } + + if (*cur == 0) { + /* hit the end */ + break; + } + + next = strchr(cur, '/'); + + if (ptr != filename) { + *ptr = 0; + } + + if (next) { + *next = 0; + } + + if (ptr == filename && *ptr == '/') { + dir = opendir("/"); + } else { + dir = opendir(filename); + } + + if (dir == NULL) { + if (ptr != filename) { + *ptr = '/'; + } + + if (next) { + *next = 0; + } + + return 0; + } + + while ((dirent = readdir(dir)) != NULL) { + if (strcasecmp(cur, dirent->d_name) == 0) { + strcpy(cur, dirent->d_name); + break; + } + } + + closedir(dir); + + if (ptr != filename) { + *ptr = '/'; + } + + if (next) { + *next = '/'; + ptr = next; + } else { + ptr++; + } + } else { + ptr++; + } + } + + if (access(filename, R_OK) == 0) { + return 1; + } + + return 0; +} + +static void fix_filename(const char *original, char *fixed) +{ + const char *start; + int i; + int len; + + start = original; + if (original[0] == ':') { + start = &original[1]; + } + + fixed[MAX_PATH-1] = 0; + + strncpy(fixed, start, MAX_PATH); + + /* check to see if strncpy overwrote the terminator */ + if (fixed[MAX_PATH-1] != 0) { + fixed[MAX_PATH-1] = 0; + + fprintf(stderr, "ERROR: file truncation error: %s -> %s\n", + original, fixed); + } + + len = strlen(fixed); + for (i = 0; i < len; i++) { + if (fixed[i] == ':') { + fixed[i] = '/'; + } + } + + /* + here we would try to see if the file is available (game dir), + else try another dir + + really, this function also needs a flag to indicate whether + it should only go to local (write) or both (read) + */ + + if (find_filename(fixed) == 0) { + fprintf(stderr, "find failed: %s\n", fixed); + } +} + +/* +Convenient Filename Hacks +*/ + +FILE *cfh_fopen(const char *filename, const char *mode) +{ + char filename1[MAX_PATH]; + + fix_filename(filename, filename1); + + return fopen(filename1, mode); +} + +int Files::OpenFile(Str255 Name) +{ + char filename1[MAX_PATH]; + + fix_filename((char *)Name, filename1); + + sFile = open(filename1, O_RDONLY | O_BINARY); + return sFile; +} + +void Files::EndLoad() +{ + if (sFile != -1) { + FSClose( sFile ); + } + + sFile = -1; +} + +#ifdef NOOGG +/* + Our own special magic version that fixes the filename. + */ +void alutLoadWAVFile_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq) +{ + char filename1[MAX_PATH]; + ALsizei format1, size1, bits1, freq1; + + fix_filename(filename, filename1); + + alutLoadWAV(filename1, wave, &format1, &size1, &bits1, &freq1); + + *format = format1; + *size = size1; + *freq = freq1; +} + +void alutUnloadWAV_CFH(ALenum format, void *wave, unsigned int size, + ALsizei freq) +{ + free(wave); +} +#else +#include <vorbis/vorbisfile.h> + +/* +Read the requested OGG file into memory, and extract the information required +by OpenAL +*/ +void LoadOGG_CFH(char *filename, ALenum *format, void **wave, + unsigned int *size, ALsizei *freq) +{ + char filename1[MAX_PATH]; + ALsizei format1, size1, freq1; + void *wave1; + OggVorbis_File vf; + vorbis_info *vi; + FILE *fp; + int current_section; + char *buf; + int asize; + int err; + int eof; + +#if BYTE_ORDER == BIG_ENDIAN + const int endian = 1; +#else + const int endian = 0; +#endif + + /* try to find the real file (and place it in filename1) */ + fix_filename(filename, filename1); + + /* open it for reading */ + fp = fopen(filename1, "rb"); + if (fp == NULL) { + fprintf(stderr, "ERROR: unable to open %s\n", filename1); + exit(EXIT_FAILURE); + } + + /* open it up */ + err = ov_open(fp, &vf, NULL, 0); + if (err < 0) { + fprintf(stderr, "ERROR: vorbis error %d opening %s\n", -err, filename1); + exit(EXIT_FAILURE); + } + + /* get the ogg information */ + vi = ov_info(&vf, -1); + if (vi == NULL) { + fprintf(stderr, "ERROR: vorbis error opening %s (ov_info failed)\n", filename1); + exit(EXIT_FAILURE); + } + + /* calculate the byte size */ + size1 = vi->channels * 2 * ov_pcm_total(&vf, -1); + + /* hack around some possible ogg vorbis weirdness */ + asize = ((size1 + 2047) / 2048 + 1) * 2048; + + /* allocate our buffer */ + wave1 = malloc(asize); + + if (wave1 == NULL) { + fprintf(stderr, "ERROR: could not allocate %d bytes while loading %s\n", size1, filename1); + exit(EXIT_FAILURE); + } + + /* read it in */ + eof = 0; + buf = (char *)wave1; + + while(!eof) { + long ret = ov_read(&vf, buf, 1024, endian, 2, 1, + ¤t_section); + + if (ret == 0) { + /* end of file */ + eof = 1; + } else if (ret < 0) { + /* some sort of error */ + + /* TODO: is this ok to ignore? */ + } else { + buf += ret; + } + } + + /* get the rest of the information */ + if (vi->channels == 1) { + format1 = AL_FORMAT_MONO16; + } else if (vi->channels == 2) { + format1 = AL_FORMAT_STEREO16; + } else { + fprintf(stderr, "ERROR: ogg %s has %d channels\n", filename1, vi->channels); + exit(EXIT_FAILURE); + } + + freq1 = vi->rate; + + /* we are done with the ogg, so free it */ + ov_clear(&vf); + + /* finall, give the values to the caller */ + *format = format1; + *size = size1; + *freq = freq1; + *wave = wave1; +} + +/* +Free the OGG buffer +*/ +void FreeOGG(ALenum format, void *wave, unsigned int size, + ALsizei freq) +{ + free(wave); +} +#endif |