[Add] Support for non POSIX systems with open/read/write in packfile system
This commit is contained in:
parent
5841d23f54
commit
a296bd7aa0
@ -99,7 +99,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// See if the data file is valid.
|
||||
if(pack_check(data)) {
|
||||
ERR("Data file '%s' not found", data);
|
||||
ERR("Data file '%s' not found", DATA);
|
||||
WARN("You can specify what data file you want to use with '-d'");
|
||||
WARN("See -h or -- help for more infoamtion.");
|
||||
SDL_Quit();
|
||||
|
16
src/music.c
16
src/music.c
@ -8,8 +8,9 @@
|
||||
#include "pack.h"
|
||||
#include "music.h"
|
||||
|
||||
#define MUSIC_PLAYING (2<<0)
|
||||
#define MUSIC_KILL (9<<0)
|
||||
#define MUSIC_STOPPED (1<<1)
|
||||
#define MUSIC_PLAYING (1<<2)
|
||||
#define MUSIC_KILL (1<<9)
|
||||
#define music_is(f) (music_state & f)
|
||||
#define music_set(f) (music_state |= f)
|
||||
#define music_rm(f) (music_state ^= f)
|
||||
@ -71,6 +72,7 @@ int music_thread(void* unused) {
|
||||
// Main loop.
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
@ -113,6 +115,7 @@ int music_thread(void* unused) {
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
}
|
||||
music_set(MUSIC_STOPPED);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
}
|
||||
return 0;
|
||||
@ -135,6 +138,10 @@ static int stream_loadBuffer(ALuint buffer) {
|
||||
§ion); // Current bitstream.
|
||||
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE)
|
||||
WARN("OGG: Vorbis hole detected in music!");
|
||||
else if(result == OV_EBADLINK)
|
||||
WARN("OGG: Invalid stream section or corrupt link in music!");
|
||||
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
@ -148,7 +155,7 @@ static int stream_loadBuffer(ALuint buffer) {
|
||||
int music_init(void) {
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_find();
|
||||
music_vorbis.file.fd = 0; // Indication that it's not loaded..
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
@ -235,7 +242,7 @@ static int music_find(void) {
|
||||
static void music_free(void) {
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
|
||||
if(music_vorbis.file.fd != 0) {
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
}
|
||||
@ -257,6 +264,7 @@ void music_load(const char* name) {
|
||||
char tmp[64];
|
||||
|
||||
music_stop();
|
||||
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
|
||||
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
if(strcmp(music_selection[i], name)==0) {
|
||||
|
187
src/pack.c
187
src/pack.c
@ -43,6 +43,7 @@ const uint64_t magic = 0x25524573; // sER%
|
||||
|
||||
// Grab the filesize.
|
||||
static off_t getfilesize(const char* filename) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
struct stat file;
|
||||
|
||||
if(!stat(filename, &file))
|
||||
@ -50,46 +51,94 @@ static off_t getfilesize(const char* filename) {
|
||||
|
||||
ERR("Unable to get filesize of %s", filename);
|
||||
return 0;
|
||||
#else
|
||||
long size;
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if(fp == NULL) return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return true if filename is a Packfile.
|
||||
int pack_check(const char* filename) {
|
||||
int ret;
|
||||
char* buf;
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if(fd == -1) {
|
||||
ERR("Error opening %s: %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* buf = malloc(sizeof(magic));
|
||||
if(read(fd, buf, sizeof(magic)) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
close(fd);
|
||||
#else
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
ERR("Error opening '%s': %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
fclose(file);
|
||||
#endif
|
||||
|
||||
int ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Pack nfiles, infiles into outfile.
|
||||
#define WRITE(f,b,n) if(write(f,b,n)==-1) { \
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define WRITE(b,n) if(fwrite(b, 1, n, outf)==0) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
|
||||
#endif
|
||||
int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) {
|
||||
void* buf;
|
||||
#ifdef _POSIX_SOURCE
|
||||
struct stat file;
|
||||
int outfd, infd;
|
||||
#else
|
||||
FILE* outf, *inf;
|
||||
#endif
|
||||
uint32_t i;
|
||||
int namesize;
|
||||
int outfd, infd;
|
||||
uint32_t indexsize, pointer;
|
||||
int bytes;
|
||||
const uint8_t b = '\0';
|
||||
|
||||
for(namesize = 0, i = 0; i < nfiles; i++) {
|
||||
// Make sure file exists before writing.
|
||||
#ifdef _POSIX_SOURCE
|
||||
if(stat(infiles[i], &file)) {
|
||||
#else
|
||||
if(getfilesize(infiles[i]) == 0) {
|
||||
#endif
|
||||
ERR("File %s does not exist", infiles[i]);
|
||||
return -1;
|
||||
}
|
||||
@ -106,8 +155,13 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
DEBUG("Index size is %d", indexsize);
|
||||
|
||||
// Create the output file.
|
||||
#ifdef _POSIX_SOURCE
|
||||
outfd = creat(outfile, PERMS);
|
||||
if(outfd == -1) {
|
||||
#else
|
||||
outf = fopen(outfile, "wb");
|
||||
if(outf == NULL) {
|
||||
#endif
|
||||
ERR("Unable to open %s for writing", outfile);
|
||||
return -1;
|
||||
}
|
||||
@ -116,18 +170,18 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
buf = malloc(BLOCKSIZE);
|
||||
|
||||
// Magic number.
|
||||
WRITE(outfd, &magic, sizeof(magic));
|
||||
WRITE(&magic, sizeof(magic));
|
||||
DEBUG("Wrote magic number");
|
||||
// Number of files.
|
||||
WRITE(outfd, &nfiles, sizeof(nfiles));
|
||||
WRITE(&nfiles, sizeof(nfiles));
|
||||
DEBUG("Wrote number of files: %d", nfiles);
|
||||
// Create file dependent index part.
|
||||
pointer = indexsize;
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
WRITE(outfd, infiles[i], strlen(infiles[i]));
|
||||
WRITE(infiles[i], strlen(infiles[i]));
|
||||
DEBUG("File: '%s' at %d", infiles[i], pointer);
|
||||
WRITE(outfd, &b, 1);
|
||||
WRITE(outfd, &pointer, 4);
|
||||
WRITE(&b, 1);
|
||||
WRITE(&pointer, 4);
|
||||
pointer += 4 + getfilesize(infiles[i]) + 16; // Set pointer to be next file pos.
|
||||
}
|
||||
|
||||
@ -136,22 +190,35 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
md5_byte_t* md5val = malloc(16);
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
bytes = (uint32_t)getfilesize(infiles[i]);
|
||||
WRITE(outfd, &bytes, 4); // filesize.
|
||||
WRITE(&bytes, 4); // filesize.
|
||||
DEBUG("About to write '%s' of %d bytes", infiles[i], bytes);
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
md5_init(&md5);
|
||||
#ifdef _POSIX_SOURCE
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
while((bytes = read(infd, buf, BLOCKSIZE))) {
|
||||
WRITE(outfd, buf, bytes); // Data.
|
||||
#else
|
||||
nf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
#endif
|
||||
WRITE(buf, bytes); // Data.
|
||||
md5_append(&md5, buf, bytes);
|
||||
}
|
||||
md5_finish(&md5, md5val);
|
||||
WRITE(outfd, md5val, 16);
|
||||
WRITE(md5val, 16);
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(infd);
|
||||
#else
|
||||
fclose(inf);
|
||||
#endif
|
||||
DEBUG("Wrote file '%s'", infiles[i]);
|
||||
}
|
||||
free(md5val);
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(outfd);
|
||||
#else
|
||||
fclose(outf);
|
||||
#endif
|
||||
free(buf);
|
||||
|
||||
DEBUG("Packfile success\n\t%d files\n\t%d bytes", nfiles, (int)getfilesize(outfile));
|
||||
@ -160,9 +227,15 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#undef WRITE
|
||||
|
||||
// Opens the filename in packfile for reading.
|
||||
#define READ(f,b,n) if(read(f,b,n) != n) { \
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read. Expected more."); \
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
|
||||
ERR("Fewer bytes read then expected"); \
|
||||
free(buf); return -1; }
|
||||
#endif
|
||||
int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
int j;
|
||||
uint32_t nfiles, i;
|
||||
@ -170,46 +243,57 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
|
||||
file->start = file->end = 0;
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
file->fd = open(packfile, O_RDONLY);
|
||||
if(file->fd == -1) {
|
||||
#else
|
||||
file->fp = fopen(packfile, "rb");
|
||||
if(file->fp == NULL) {
|
||||
#endif
|
||||
ERR("Error opening %s: %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
READ(file->fd, buf, sizeof(magic)); // Make sure it's a packfile.
|
||||
READ(buf, sizeof(magic)); // Make sure it's a packfile.
|
||||
if(memcmp(buf, &magic, sizeof(magic))) {
|
||||
ERR("File %s is not a valid packfile", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
READ(file->fd, &nfiles, 4);
|
||||
READ(&nfiles, 4);
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
// Start to search files.
|
||||
j = 0;
|
||||
READ(file->fd, &buf[j], 1); // Get the name.
|
||||
READ(&buf[j], 1); // Get the name.
|
||||
while(buf[j++] != '\0')
|
||||
READ(file->fd, &buf[j], 1);
|
||||
READ(&buf[j], 1);
|
||||
|
||||
if(strcmp(filename, buf) == 0) {
|
||||
// We found the file.
|
||||
READ(file->fd, &file->start, 4);
|
||||
READ(&file->start, 4);
|
||||
DEBUG("'%s' found at %d", filename, file->start);
|
||||
break;
|
||||
}
|
||||
#ifdef _POSIX_SOURCE
|
||||
lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
|
||||
#else
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if(file->start) {
|
||||
// Go to the beginning of the file.
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) {
|
||||
#else
|
||||
fseek(file->fp, file->start, SEEK_SET);
|
||||
if(errno) {
|
||||
#endif
|
||||
ERR("Failure to seek to file start: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(read(file->fd, &file->end, 4) != 4) {
|
||||
ERR("Too few bytes read. Expected more.");
|
||||
return -1;
|
||||
}
|
||||
READ(&file->end, 4);
|
||||
DEBUG("\t%d bytes", file->end);
|
||||
file->pos = file->start;
|
||||
file->end += file->start;
|
||||
@ -228,7 +312,11 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
|
||||
int bytes;
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, buf, count)) == -1) {
|
||||
#else
|
||||
if((byts = freed(buf, 1, count, file->fp)) == -1) {
|
||||
#endif
|
||||
ERR("Error while reading file: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -270,8 +358,12 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
md5_byte_t* md5fd = malloc(16);
|
||||
md5_init(&md5);
|
||||
md5_append(&md5, buf, bytes);
|
||||
md5_finish(&md5, md5val);;
|
||||
md5_finish(&md5, md5val);
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, md5fd, 16)) == -1)
|
||||
#else
|
||||
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
|
||||
#endif
|
||||
WARN("Failure to read MD5, continuing anyway..");
|
||||
else if(memcmp(md5val, md5fd, 16))
|
||||
WARN("MD5 gives different value, possible memory corruption, continuing..");
|
||||
@ -295,46 +387,75 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
// Load the filenames int the packfile to filenames.
|
||||
// filenames should be freed after use
|
||||
// On error if filenames is (char**)-1.
|
||||
#define READ(f,b,n) if(read(f,b,n)!=n) { ERR("Too few bytes read. Expected more."); return NULL; }
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#endif
|
||||
char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
int fd, j;
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd;
|
||||
#else
|
||||
FILE* fp;
|
||||
#endif
|
||||
int j;
|
||||
uint32_t i;
|
||||
char** filenames;
|
||||
char* buf = malloc(sizeof(magic));
|
||||
|
||||
*nfiles = 0;
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
fd = open(packfile, O_RDONLY);
|
||||
if(fd == -1) {
|
||||
#else
|
||||
fp = fopen(packfile, "rb");
|
||||
if(fp == NULL) {
|
||||
#endif
|
||||
ERR("opening %s: %s", packfile, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
READ(fd, buf, sizeof(magic)); // Make sure it is a packfile.
|
||||
READ(buf, sizeof(magic)); // Make sure it is a packfile.
|
||||
if(memcmp(buf, &magic, sizeof(magic))) {
|
||||
ERR("File %s is not a valid packfile", packfile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
READ(fd, nfiles, 4);
|
||||
READ(nfiles, 4);
|
||||
filenames = malloc(((*nfiles)+1)*sizeof(char*));
|
||||
for(i = 0; i < *nfiles; i++) {
|
||||
// Start searching files.
|
||||
j = 0;
|
||||
filenames[i] = malloc(MAX_FILENAME * sizeof(char));
|
||||
READ(fd, &filenames[i][j], 1); // Get the name.
|
||||
READ(&filenames[i][j], 1); // Get the name.
|
||||
while(filenames[i][j++] != '\0')
|
||||
READ(fd, &filenames[i][j], 1);
|
||||
READ(fd, buf, 4); // skip the location.
|
||||
READ(&filenames[i][j], 1);
|
||||
READ(buf, 4); // skip the location.
|
||||
}
|
||||
free(buf);
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(fd);
|
||||
#else
|
||||
fclose(fp);
|
||||
#endif
|
||||
|
||||
return filenames;
|
||||
}
|
||||
#undef READ
|
||||
|
||||
// Close the packfile.
|
||||
int pack_close(Packfile* file) {
|
||||
int i = close(file->fd);
|
||||
int i;
|
||||
#ifdef _POSIX_SOURCE
|
||||
i = close(file->fd);
|
||||
#else
|
||||
i = fclose(file->fp);
|
||||
#endif
|
||||
return (i) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,16 @@
|
||||
#pragma once
|
||||
#include <fcntl.h>
|
||||
#ifndef _POSIX_SOURCE // No posix.
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd; // File descriptor.
|
||||
#else
|
||||
FILE* fp;
|
||||
#endif
|
||||
uint32_t pos; // position.
|
||||
uint32_t start, end; // file limits.
|
||||
} Packfile;
|
||||
|
Loading…
Reference in New Issue
Block a user