[Add] We can now create SDL_RWops from packfile.

This commit is contained in:
Allanis 2014-11-15 20:57:45 +00:00
parent 01ad8a2f48
commit 7c81351fda
6 changed files with 168 additions and 66 deletions

View File

@ -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);
}

View File

@ -1,6 +1,8 @@
#pragma once
#include <stdint.h>
#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);

View File

@ -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());

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "SDL.h"
#include "lcompat.h"
#include <fcntl.h>
@ -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);

View File

@ -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"