lua files in idf too

This commit is contained in:
p.kosyh 2011-04-18 12:32:21 +00:00
parent f14228d063
commit 84a05211af
3 changed files with 116 additions and 34 deletions

View file

@ -10,11 +10,11 @@ typedef struct _idfd_t {
idf_t idf;
} idfd_t;
typedef struct _idff_t {
struct _idff_t {
idfd_t *dir;
unsigned long pos;
FILE *fd;
} idff_t;
};
struct _idf_t {
unsigned long size;
@ -294,10 +294,9 @@ err:
return rc;
}
static int idfrw_seek(struct SDL_RWops *context, int offset, int whence)
int idf_seek(idff_t fil, int offset, int whence)
{
idff_t *fil = (idff_t *)context->hidden.unknown.data1;
idfd_t *dir = fil->dir;
switch (whence) {
case SEEK_SET:
@ -324,34 +323,37 @@ static int idfrw_seek(struct SDL_RWops *context, int offset, int whence)
return -1;
}
static int idfrw_read(struct SDL_RWops *context, void *ptr, int size, int maxnum)
static int idfrw_seek(struct SDL_RWops *context, int offset, int whence)
{
idff_t fil = (idff_t)context->hidden.unknown.data1;
return idf_seek(fil, offset, whence);
}
int idf_read(idff_t fil, void *ptr, int size, int maxnum)
{
int rc = 0;
long pos;
idff_t *fil = (idff_t *)context->hidden.unknown.data1;
idfd_t *dir = fil->dir;
if (fseek(fil->fd, dir->offset + fil->pos, SEEK_SET) < 0) {
return 0;
}
#if 0
#if 1
while (maxnum) {
pos = ftell(dir->idf->fd);
dir->pos = pos - dir->offset;
pos = ftell(fil->fd);
fil->pos = pos - dir->offset;
if (dir->pos + size > dir->size) {
if (fil->pos + size > dir->size) {
break;
}
if (fread(ptr, size, 1, dir->idf->fd) != 1) {
fprintf(stderr, "read 2 err\n");
if (fread(ptr, size, 1, fil->fd) != 1)
break;
}
// dir->pos += size;
// fil->pos += size;
ptr += size;
maxnum --;
rc ++;
}
#else
rc = fread(ptr, size, maxnum, fil->fd);
@ -361,15 +363,31 @@ static int idfrw_read(struct SDL_RWops *context, void *ptr, int size, int maxnum
return rc;
}
static int idfrw_close(struct SDL_RWops *context)
static int idfrw_read(struct SDL_RWops *context, void *ptr, int size, int maxnum)
{
if (context) {
idff_t *fil = (idff_t *)context->hidden.unknown.data1;
idff_t fil = (idff_t)context->hidden.unknown.data1;
return idf_read(fil, ptr, size, maxnum);
}
int idf_close(idff_t fil)
{
if (fil) {
fclose(fil->fd);
SDL_FreeRW(context);
free(fil);
}
return 0; /* nothing todo */
}
static int idfrw_close(struct SDL_RWops *context)
{
if (context) {
idff_t fil = (idff_t)context->hidden.unknown.data1;
idf_close(fil);
SDL_FreeRW(context);
}
return 0;
}
#if 0
int idf_extract(idf_t idf, const char *fname)
{
@ -398,26 +416,56 @@ int idf_extract(idf_t idf, const char *fname)
return 0;
}
#endif
SDL_RWops *RWFromIdf(idf_t idf, const char *fname)
int idf_eof(idff_t idf)
{
if (!idf)
return 1;
if (idf->pos >= idf->dir->size)
return 1;
return 0;
}
int idf_error(idff_t idf)
{
if (!idf || !idf->fd)
return -1;
return ferror(idf->fd);
}
idff_t idf_open(idf_t idf, const char *fname)
{
idfd_t *dir = NULL;
idff_t *fil = NULL;
SDL_RWops *n;
idff_t fil = NULL;
if (idf)
dir = cache_lookup(idf->dir, fname);
if (!dir)
return SDL_RWFromFile(dirpath(fname), "rb");
fil = malloc(sizeof(idff_t));
return NULL;
fil = malloc(sizeof(struct _idff_t));
if (!fil)
return NULL;
n = SDL_AllocRW();
if (!n)
goto err;
fil->dir = dir;
fil->pos = 0;
fil->fd = fopen(dirpath(idf->path), "rb");
if (!fil->fd)
goto err;
return fil;
err:
free(fil);
return NULL;
}
SDL_RWops *RWFromIdf(idf_t idf, const char *fname)
{
idff_t fil = NULL;
SDL_RWops *n;
fil = idf_open(idf, fname);
if (!fil)
return SDL_RWFromFile(dirpath(fname), "rb");
n = SDL_AllocRW();
if (!n)
goto err;
n->seek = idfrw_seek;
n->read = idfrw_read;
n->close = idfrw_close;

View file

@ -2,7 +2,9 @@
#define __IDF_H_INCLUDED
struct _idf_t;
struct _idff_t;
typedef struct _idf_t *idf_t;
typedef struct _idff_t *idff_t;
extern idf_t idf_init(const char *path);
extern void idf_shrink(idf_t idf);
@ -10,5 +12,13 @@ extern void idf_done(idf_t idf);
extern SDL_RWops *RWFromIdf(idf_t idf, const char *fname);
extern int idf_create(const char *file, const char *path);
extern idff_t idf_open(idf_t idf, const char *fname);
extern int idf_seek(idff_t fil, int offset, int whence);
extern int idf_read(idff_t fil, void *ptr, int size, int maxnum);
extern int idf_close(idff_t fil);
extern int idf_eof(idff_t idf);
extern int idf_error(idff_t idf);
#endif

View file

@ -1,6 +1,7 @@
#include "externals.h"
#include "internals.h"
#include "list.h"
#include "idf.h"
#ifndef STEAD_PATH
#define STEAD_PATH "./stead"
@ -329,6 +330,7 @@ typedef struct LoadF {
int extraline;
unsigned char byte;
FILE *f;
idff_t idff;
int enc;
unsigned char buff[4096];
} LoadF;
@ -342,8 +344,17 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
*size = 1;
return "\n";
}
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
if (lf->f && feof(lf->f))
return NULL;
if (lf->idff && idf_eof(lf->idff))
return NULL;
if (lf->idff)
*size = idf_read(lf->idff, lf->buff, 1, sizeof(lf->buff));
else
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
if (lf->enc) {
for (i = 0; i < *size; i ++) {
unsigned char b = lf->buff[i];
@ -369,13 +380,26 @@ static int loadfile (lua_State *L, const char *filename, int enc) {
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "rb");
lf.idff = idf_open(game_idf, filename);
if (!lf.idff)
lf.f = fopen(filename, "rb");
else
lf.f = NULL;
lf.byte = 0xcc;
lf.enc = enc;
if (lf.f == NULL) return errfile(L, "open", fnameindex);
if (lf.f == NULL && lf.idff == NULL) return errfile(L, "open", fnameindex);
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (lf.f)
readstatus = ferror(lf.f);
else
readstatus = idf_error(lf.idff);
if (filename) {
if (lf.f)
fclose(lf.f); /* close file (even in case of errors) */
idf_close(lf.idff);
}
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);