home *** CD-ROM | disk | FTP | other *** search
- //
- // BME (Blasphemous Multimedia Engine) datafile IO main module
- //
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <SDL/SDL.h>
-
- #include "bme_main.h"
- #include "bme_err.h"
- #include "bme_cfg.h"
-
- typedef struct
- {
- Uint32 offset;
- Sint32 length;
- char name[13];
- } HEADER;
-
- typedef struct
- {
- HEADER *currentheader;
- int filepos;
- int open;
- } HANDLE;
-
- static int io_usedatafile = 0;
- static HEADER *fileheaders;
- static unsigned files;
- static char ident[4];
- static char *idstring = "DAT!";
- static HANDLE handle[MAX_HANDLES];
- static FILE *fileptr[MAX_HANDLES] = {NULL};
- static FILE *datafilehandle = NULL;
- static unsigned char *datafileptr;
- static unsigned char *datafilestart;
-
- static unsigned freadle32(FILE *index);
- static void linkedseek(unsigned pos);
- static void linkedread(void *buffer, int length);
- static unsigned linkedreadle32(void);
-
- void io_setfilemode(int usedf)
- {
- io_usedatafile = usedf;
- }
-
- int io_openlinkeddatafile(unsigned char *ptr)
- {
- int index;
-
- if (datafilehandle) fclose(datafilehandle);
- datafilehandle = NULL;
-
- datafilestart = ptr;
- linkedseek(0);
-
- linkedread(ident, 4);
- if (memcmp(ident, idstring, 4))
- {
- bme_error = BME_WRONG_FORMAT;
- return BME_ERROR;
- }
-
- files = linkedreadle32();
- fileheaders = malloc(files * sizeof(HEADER));
- if (!fileheaders)
- {
- bme_error = BME_OUT_OF_MEMORY;
- return BME_ERROR;
- }
- for (index = 0; index < files; index++)
- {
- fileheaders[index].offset = linkedreadle32();
- fileheaders[index].length = linkedreadle32();
- linkedread(&fileheaders[index].name, 13);
- }
-
- for (index = 0; index < MAX_HANDLES; index++) handle[index].open = 0;
- io_usedatafile = 1;
- bme_error = BME_OK;
- return BME_OK;
- }
-
- int io_opendatafile(char *name)
- {
- int index;
-
- if (name)
- {
- datafilehandle = fopen(name, "rb");
- if (!datafilehandle)
- {
- bme_error = BME_OPEN_ERROR;
- return BME_ERROR;
- }
- }
-
- fread(ident, 4, 1, datafilehandle);
- if (memcmp(ident, idstring, 4))
- {
- bme_error = BME_WRONG_FORMAT;
- return BME_ERROR;
- }
-
- files = freadle32(datafilehandle);
- fileheaders = malloc(files * sizeof(HEADER));
- if (!fileheaders)
- {
- bme_error = BME_OUT_OF_MEMORY;
- return BME_ERROR;
- }
- for (index = 0; index < files; index++)
- {
- fileheaders[index].offset = freadle32(datafilehandle);
- fileheaders[index].length = freadle32(datafilehandle);
- fread(&fileheaders[index].name, 13, 1, datafilehandle);
- }
-
- for (index = 0; index < MAX_HANDLES; index++) handle[index].open = 0;
- io_usedatafile = 1;
- bme_error = BME_OK;
- return BME_OK;
- }
-
- // Returns nonnegative file handle if successful, -1 on error
-
- int io_open(char *name)
- {
- if (!name) return -1;
-
- if (!io_usedatafile)
- {
- int index;
- for (index = 0; index < MAX_HANDLES; index++)
- {
- if (!fileptr[index]) break;
- }
- if (index == MAX_HANDLES) return -1;
- else
- {
- FILE *file = fopen(name, "rb");
- if (!file)
- {
- return -1;
- }
- else
- {
- fileptr[index] = file;
- return index;
- }
- }
- }
- else
- {
- int index;
- int namelength;
- char namecopy[13];
-
- namelength = strlen(name);
- if (namelength > 12) namelength = 12;
- memcpy(namecopy, name, namelength + 1);
- for (index = 0; index < strlen(namecopy); index++)
- {
- namecopy[index] = toupper(namecopy[index]);
- }
-
- for (index = 0; index < MAX_HANDLES; index++)
- {
- if (!handle[index].open)
- {
- int count = files;
- handle[index].currentheader = fileheaders;
-
- while (count)
- {
- if (!strcmp(namecopy, handle[index].currentheader->name))
- {
- handle[index].open = 1;
- handle[index].filepos = 0;
- return index;
- }
- count--;
- handle[index].currentheader++;
- }
- return -1;
- }
- }
- return -1;
- }
- }
-
- // Returns file position after seek or -1 on error
-
- int io_lseek(int index, int offset, int whence)
- {
- if (!io_usedatafile)
- {
- fseek(fileptr[index], offset, whence);
- return ftell(fileptr[index]);
- }
- else
- {
- int newpos;
-
- if ((index < 0) || (index >= MAX_HANDLES)) return -1;
-
- if (!handle[index].open) return -1;
- switch(whence)
- {
- default:
- case SEEK_SET:
- newpos = offset;
- break;
-
- case SEEK_CUR:
- newpos = offset + handle[index].filepos;
- break;
-
- case SEEK_END:
- newpos = offset + handle[index].currentheader->length;
- break;
- }
- if (newpos < 0) newpos = 0;
- if (newpos > handle[index].currentheader->length) newpos = handle[index].currentheader->length;
- handle[index].filepos = newpos;
- return newpos;
- }
- }
-
- // Returns number of bytes actually read, -1 on error
-
- int io_read(int index, void *buffer, int length)
- {
- if (!io_usedatafile)
- {
- return fread(buffer, 1, length, fileptr[index]);
- }
- else
- {
- int readbytes;
-
- if ((index < 0) || (index >= MAX_HANDLES)) return -1;
-
- if (!handle[index].open) return -1;
- if (length + handle[index].filepos > handle[index].currentheader->length)
- length = handle[index].currentheader->length - handle[index].filepos;
-
- if (datafilehandle)
- {
- fseek(datafilehandle, handle[index].currentheader->offset + handle[index].filepos, SEEK_SET);
- readbytes = fread(buffer, 1, length, datafilehandle);
- }
- else
- {
- linkedseek(handle[index].currentheader->offset + handle[index].filepos);
- linkedread(buffer, length);
- readbytes = length;
- }
- handle[index].filepos += readbytes;
- return readbytes;
- }
- }
-
- // Returns nothing
-
- void io_close(int index)
- {
- if (!io_usedatafile)
- {
- fclose(fileptr[index]);
- fileptr[index] = NULL;
- }
- else
- {
- if ((index < 0) || (index >= MAX_HANDLES)) return;
-
- handle[index].open = 0;
- }
- }
-
- unsigned io_read8(int index)
- {
- unsigned char byte;
-
- io_read(index, &byte, 1);
- return byte;
- }
-
- unsigned io_readle16(int index)
- {
- unsigned char bytes[2];
-
- io_read(index, bytes, 2);
- return (bytes[1] << 8) | bytes[0];
- }
-
- unsigned io_readhe16(int index)
- {
- unsigned char bytes[2];
-
- io_read(index, bytes, 2);
- return (bytes[0] << 8) | bytes[1];
- }
-
- unsigned io_readle32(int index)
- {
- unsigned char bytes[4];
-
- io_read(index, bytes, 4);
- return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
- }
-
- unsigned io_readhe32(int index)
- {
- unsigned char bytes[4];
-
- io_read(index, bytes, 4);
- return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
- }
-
- static unsigned freadle32(FILE *file)
- {
- unsigned char bytes[4];
-
- fread(&bytes, 4, 1, file);
- return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
- }
-
- static void linkedseek(unsigned pos)
- {
- datafileptr = &datafilestart[pos];
- }
-
- static void linkedread(void *buffer, int length)
- {
- unsigned char *dest = (unsigned char *)buffer;
- while (length--)
- {
- *dest++ = *datafileptr++;
- }
- }
-
- static unsigned linkedreadle32(void)
- {
- unsigned char bytes[4];
-
- linkedread(&bytes, 4);
- return (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
- }
-
-