diff --git a/src/ldata.c b/src/ldata.c index a20304c..4e242d3 100644 --- a/src/ldata.c +++ b/src/ldata.c @@ -34,9 +34,6 @@ static char* ldata_packName = NULL; /**< Name of the ldata module. */ static const char** ldata_fileList = NULL; /**< List of the files in the packfile. */ static uint32_t ldata_fileNList = 0; /**< Number of files in ldata_fileList. */ -/* Lock. */ -static SDL_mutex* ldata_lock = NULL; - static char** filterList(const char** list, int nlist, const char* path, uint32_t* nfiles); @@ -126,12 +123,6 @@ static int ldata_openPackfile(void) { * @return 0 on success. */ int ldata_open(void) { - /* Create the lock. */ - ldata_lock = SDL_CreateMutex(); - if(ldata_lock == NULL) { - WARN("Unable to create ldata lock."); - return -1; - } return 0; } @@ -139,8 +130,6 @@ int ldata_open(void) { * @brief Close and clean up the ldata file. */ void ldata_close(void) { - /* Lock the mutex. */ - SDL_mutexP(ldata_lock); /* Destroy the name. */ if(ldata_packName != NULL) { free(ldata_packName); @@ -159,13 +148,6 @@ void ldata_close(void) { pack_closeCache(ldata_cache); ldata_cache = NULL; } - - /* Unlock the mutex. */ - SDL_mutexV(ldata_lock); - - /* Destroy the mutex. */ - SDL_DestroyMutex(ldata_lock); - ldata_lock = NULL; } /** @@ -217,9 +199,6 @@ const char* ldata_name(void) { /** * @brief Read a file from the ldata. - * - * Thread Safe. - * * @param filename Name of the file to read. * @param[out] filesize Stores the size of the file. * @return The file data or NULL on error. @@ -229,9 +208,6 @@ void* ldata_read(const char* filename, uint32_t* filesize) { int nbuf; /* See if needs to load the packfile. */ if(ldata_cache == NULL) { - /* Lock the mutex. */ - SDL_mutexP(ldata_lock); - /* Try to read the file as locally. */ buf = lfile_readFile(&nbuf, filename); if(buf != NULL) { @@ -241,15 +217,33 @@ void* ldata_read(const char* filename, uint32_t* filesize) { /* Load the packfile. */ ldata_openPackfile(); - - /* Unlock the mutex. */ - SDL_mutexV(ldata_lock); } /* Get data from packfile. */ return pack_readfileCached(ldata_cache, filename, filesize); } +/** + * @brief Create an rwops from a file in the ldata. + * @param filename Name of the file create rwops of. + * @retuen rwops that accesses the file in the ldata. + */ +SDL_RWops* ldata_rwops(const char* filename) { + SDL_RWops* rw; + + if(ldata_cache == NULL) { + /* Try to open from file. */ + rw = SDL_RWFromFile(filename, "rb"); + if(rw != NULL) + return rw; + + /* Load the packfile. */ + ldata_openPackfile(); + } + + return pack_rwopsCached(ldata_cache, filename); +} + /** * @brief Filter a file list to match path. * @@ -296,9 +290,6 @@ static char** filterList(const char** list, int nlist, /** * @brief Get the list of files in the ldata. - * - * Thread safe. - * * @param path List files in path. * @param nfiles Number of files found. * @return List of files found. @@ -314,9 +305,6 @@ char** ldata_list(const char* path, uint32_t* nfiles) { /* See if we can load from local directory. */ if(ldata_cache == NULL) { - /* Lock the mutex. */ - SDL_mutexP(ldata_lock); - files = lfile_readDir(&n, path); /* Found locally. */ @@ -327,20 +315,11 @@ char** ldata_list(const char* path, uint32_t* nfiles) { /* Open packfile. */ ldata_openPackfile(); - - /* Unlock the mutex. */ - SDL_mutexV(ldata_lock); } - /* Lock the mutex. */ - SDL_mutexP(ldata_lock); - /* Load list. */ ldata_fileList = pack_listfilesCached(ldata_cache, &ldata_fileNList); - /* Unlock the mutex. */ - SDL_mutexV(ldata_lock); - return filterList(ldata_fileList, ldata_fileNList, path, nfiles); } diff --git a/src/ldata.h b/src/ldata.h index e1c2a9a..56ad270 100644 --- a/src/ldata.h +++ b/src/ldata.h @@ -1,6 +1,8 @@ #pragma once #include +#include "SDL.h" + /* ldata open/close. */ int ldata_open(void); void ldata_close(void); @@ -14,3 +16,6 @@ const char* ldata_name(void); void* ldata_read(const char* filename, uint32_t* filesize); char** ldata_list(const char* path, uint32_t* nfiles); +/* RWops. */ +SDL_RWops* ldata_rwops(const char* filename); + diff --git a/src/music.c b/src/music.c index 407707a..a6d0927 100644 --- a/src/music.c +++ b/src/music.c @@ -61,7 +61,6 @@ static int nmusic_selection = 0; /**< Size of available music selection. */ /* Current music. */ static char* music_name = NULL; /**< Current music name. */ -static void* music_data = NULL; /**< Current music data. */ static SDL_RWops* music_rw = NULL; /**< Current music RWops. */ static Mix_Music* music_music = NULL; /**< Current music. */ @@ -157,12 +156,10 @@ static void music_free(void) { Mix_HaltMusic(); Mix_FreeMusic(music_music); /*SDL_FreeRW(music_rw);*/ /*FreeMusic frees it itself. */ - free(music_data); free(music_name); music_name = NULL; music_music = NULL; music_rw = NULL; - music_data = NULL; } } @@ -234,7 +231,6 @@ int music_volume(const double vol) { * @param name Name of the file to load. */ void music_load(const char* name) { - unsigned int size; char filename[PATH_MAX]; if(music_disabled) return; @@ -244,8 +240,7 @@ void music_load(const char* name) { /* Load the data. */ snprintf(filename, PATH_MAX, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name); music_name = strdup(name); - music_data = ldata_read(filename, &size); - music_rw = SDL_RWFromMem(music_data, size); + music_rw = ldata_rwops(filename); music_music = Mix_LoadMUS_RW(music_rw); if(music_music == NULL) WARN("SDL_Mixer: %s", Mix_GetError()); diff --git a/src/pack.c b/src/pack.c index b1a2129..67a4ecc 100644 --- a/src/pack.c +++ b/src/pack.c @@ -98,6 +98,11 @@ const uint64_t magic = 0x25524573; /**< File magic number: sER% */ #define PACKFILE_FROMCACHE (1<<0) /**< Packfile comes from a packcache. */ static off_t getfilesize(const char* filename); +/* RWops stuff. */ +static int packrw_seek(SDL_RWops* rw, int offset, int whence); +static int packrw_read(SDL_RWops* rw, void* ptr, int size, int maxnum); +static int packrw_write(SDL_RWops* rw, const void* ptr, int size, int num); +static int packrw_close(SDL_RWops* rw); /** * @brief Open a packfile as a cache. @@ -199,7 +204,7 @@ Packfile_t* pack_openFromCache(Packcache_t* cache, const char* filename) { #if HAS_POSIX file->fd = dup(cache->fd); #else - file->fp = fopen(file->name, "rb"); + file->fp = fopen(cache->name, "rb"); #endif /* Copy information. */ @@ -554,8 +559,10 @@ ssize_t pack_read(Packfile_t* file, void* buf, size_t count) { * @return The position moved to. */ off_t pack_seek(Packfile_t* file, off_t offset, int whence) { - DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence); off_t ret; + + DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence); + switch(whence) { #if HAS_POSIX case SEEK_SET: @@ -569,8 +576,8 @@ off_t pack_seek(Packfile_t* file, off_t offset, int whence) { if(ret != ((off_t)file->pos + offset)) return -1; break; case SEEK_END: - if((file->end - offset) < file->start) return -1; - ret = lseek(file->fd, file->end - offset - 1, SEEK_SET); + if((file->end + offset) < file->start) return -1; + ret = lseek(file->fd, file->end + offset, SEEK_SET); if(ret != ((off_t)file->end - offset)) return -1; break; #else @@ -581,12 +588,12 @@ off_t pack_seek(Packfile_t* file, off_t offset, int whence) { break; case SEEK_CUR: if((file->start + offset) > file->end) return -1; - ret = flseek(file->fd, file->pos + offset, SEEK_SET); + ret = fseek(file->fd, file->pos + offset -1, SEEK_SET); if(ret != (file->pos + offset)) return -1; break; case SEEK_END: - if((file->end - offset) < file->start) return -1; - ret = flseek(file->fd, file->end - offset - 1, SEEK_SET); + if((file->end + offset) < file->start) return -1; + ret = fseek(file->fd, file->end + offset, SEEK_SET); if(ret != (file->end - offset)) return -1; break; #endif /* HAS_POSIX */ @@ -792,3 +799,108 @@ int pack_close(Packfile_t* file) { return (i) ? -1 : 0; } +static int packrw_seek(SDL_RWops* rw, int offset, int whence) { + Packfile_t* packfile; + packfile = rw->hidden.unknown.data1; + + return pack_seek(packfile, offset, whence); +} + +static int packrw_read(SDL_RWops* rw, void* ptr, int size, int maxnum) { + int i; + ssize_t ret; + char* buf; + Packfile_t* packfile; + packfile = rw->hidden.unknown.data1; + + buf = ptr; + + /* Read the data. */ + for(i = 0; i < maxnum; i++) { + ret = pack_read(packfile, &buf[i*size], size); + if(ret != size) + break; + } + + return i; +} + +static int packrw_write(SDL_RWops* rw, const void* ptr, int size, int num) { + (void) rw; + (void) ptr; + (void) size; + (void) num; + return -1; +} + +static int packrw_close(SDL_RWops* rw) { + Packfile_t* packfile; + packfile = rw->hidden.unknown.data1; + + return pack_close(packfile); +} + +/** + * @brief Create a rwops from a packfile. + * @param packfile Packfile to create rwops from. + * @return rwops created from packfile. + */ + +static SDL_RWops* pack_rwopsRaw(Packfile_t* packfile) { + SDL_RWops* rw; + + /* Create the rwops. */ + rw = SDL_AllocRW(); + if(rw == NULL) { + WARN("Unable to allocate SDL_RWops."); + return NULL; + } + + /* Set the functions. */ + rw->seek = packrw_seek; + rw->read = packrw_read; + rw->write = packrw_write; + rw->close = packrw_close; + + /* Set the packfile as the hidden data. */ + rw->hidden.unknown.data1 = packfile; + + return rw; +} + +/** + * @brief Create an rwops for a file in a packfile. + * @param packfile Packfile to get file from. + * @param filename File within packfile to create rwops from. + * @return SDL_RWops interacting with the file in the packfile. + */ +SDL_RWops* pack_rwops(const char* packfile, const char* filename) { + Packfile_t* pack; + + /* Open the packfile. */ + pack = pack_open(packfile, filename); + if(pack == NULL) + return NULL; + + /* Return the rwops. */ + return pack_rwopsRaw(pack); +} + +/** + * @brief Create an rwops for a file in a packcache. + * @param cache Packcache to get file from. + * @param filename File within the cache to create rwops from. + * @return SDL_RWops interacting with the file in the packcache. + */ +SDL_RWops* pack_rwopsCached(Packcache_t* cache, const char* filename) { + Packfile_t* packfile; + + /* Open the packfile. */ + packfile = pack_openFromCache(cache, filename); + if(packfile == NULL) + return NULL; + + /* Return the rwops. */ + return pack_rwopsRaw(packfile); +} + diff --git a/src/pack.h b/src/pack.h index 581dbf5..8539105 100644 --- a/src/pack.h +++ b/src/pack.h @@ -1,5 +1,6 @@ #pragma once +#include "SDL.h" #include "lcompat.h" #include @@ -38,3 +39,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles); void* pack_readfileCached(Packcache_t* cache, const char* filename, uint32_t* filesize); const char** pack_listfilesCached(Packcache_t* cache, uint32_t* nfiles); +/* For rwops. */ +SDL_RWops* pack_rwops(const char* packfile, const char* filename); +SDL_RWops* pack_rwopsCaches(Packcache_t* cache, const char* filename); + diff --git a/utils/pack/Makefile b/utils/pack/Makefile index 67352bc..797f3a7 100644 --- a/utils/pack/Makefile +++ b/utils/pack/Makefile @@ -1,25 +1,31 @@ -ROOTDIR = ../../ -SRCDIR = $(ROOTDIR)src/ -LOCALDIR = utils/pack +ROOTDIR := ../../ +SRCDIR := $(ROOTDIR)src/ +LOCALDIR := utils/pack -COBJS = pack.o md5.o +COBJS = $(SRCDIR)pack.o $(SRCDIR)md5.o main.o -CFLAGS += -W -Wall +CFLAGS += -W -Wall $(shell sdl-config --cflags) ifdef DEBUG CFLAGS += -I$(SRCDIR) -g else CFLAGS += -I$(SRCDIR) -O2 endif +LDFLAGS := $(shell sdl-config --libs) -APPNAME = pack +APPNAME := pack -%.o: $(SRCDIR)%.c +.PHONY: all clean + +%.o: %.c @$(CC) -c $(CFLAGS) -o $@ $< - @echo -e "\tCC $(LOCALDIR)$@" + @echo " CC $(LOCALDIR)$@" -all: $(COBJS) - @$(CC) $(CFLAGS) -o $(ROOTDIR)/bin/$(APPNAME) main.c $(COBJS) - @echo -e "\tLD $(APPNAME)" +all: $(ROOTDIR)$(APPNAME) + +$(ROOTDIR)$(APPNAME): $(COBJS) + @$(CC) $(LDFLAGS) $(CFLAGS) -o $(ROOTDIR)/bin/$(APPNAME) $(COBJS) + @echo " LD $(APPNAME)" clean: rm -rf *.o pack + @echo " Cleaning Pack"