Logo Search packages:      
Sourcecode: vdrift version File versions

joepack.cpp

#include "model.h"
#include "joepack.h"

#define JPKVERSION "JPK01.00"

#define VERBOSE false

#define DPRINT(text) {if (VERBOSE) cout << text << endl;}

bool JOEPACK::LoadPack(string fn)
{
      ClosePack();
      
      f = fopen(fn.c_str(), "rb");
      
      if (f)
      {
            packpath = utility.GetPathFromFilename(fn);
            
            //load header
            string versionstr = JPKVERSION;
            char versioncstr[versionstr.length()+1];
            fread(versioncstr, 1, versionstr.length(), f);
            versioncstr[versionstr.length()] = '\0';
            string fversionstr = versioncstr;
            if (versioncstr != versionstr)
            {
                  //write out an error?
                  return false;
            }
            
            unsigned int numobjs = 0;
            fread(&numobjs, sizeof(unsigned int), 1, f);
            numobjs = ENDIAN_SWAP_32(numobjs);
            
            DPRINT(numobjs << " objects");
            
            unsigned int maxstrlen = 0;
            fread(&maxstrlen, sizeof(unsigned int), 1, f);
            maxstrlen = ENDIAN_SWAP_32(maxstrlen);
            
            DPRINT(maxstrlen << " max string length");
            
            char fnch[maxstrlen+1];
            
            //load FAT
            for (unsigned int i = 0; i < numobjs; i++)
            {
                  JOEPACK_FADATA fa;
                  fread(&(fa.offset), 1, sizeof(unsigned int), f);
                  fa.offset = ENDIAN_SWAP_32(fa.offset);
                  fread(&(fa.length), 1, sizeof(unsigned int), f);
                  fa.length = ENDIAN_SWAP_32(fa.length);
                  fread(fnch, 1, maxstrlen, f);
                  fnch[maxstrlen] = '\0';
                  string filename = fnch;
                  fat[filename] = fa;
                  
                  DPRINT(filename << ": offest " << fa.offset << " length " << fa.length);
            }
            
            return true;
      }
      else
      {
            //write an error?
            return false;
      }
}

void JOEPACK::ClosePack()
{
      Pack_fclose();
      fat.clear();
      if (f != NULL)
      {
            fclose(f);
            f = NULL;
      }
      packpath.clear();
}

void JOEPACK::Pack_fclose()
{
      curfa = NULL;
}

bool JOEPACK::Pack_fopen(string fn)
{
      if (fn.find(packpath, 0) < fn.length())
      {
            string newfn = fn.substr(packpath.length()+1);
            DPRINT(fn << " -> " << newfn);
            fn = newfn;
      }
      
      DPRINT("Opening " << fn << " by seeking to " << fat[fn].offset);
      
      if (fat[fn].offset == 0)
      {
            curfa = NULL;
            //write an error?
            return false;
      }
      else
      {
            curfa = &(fat[fn]);
            fseek(f, curfa->offset, SEEK_SET);
            return true;
      }
}

int JOEPACK::Pack_fread(void * buffer, unsigned int size, unsigned int count)
{
      if (curfa != NULL)
      {
            unsigned int abspos = ftell(f);
            assert(abspos >= curfa->offset);
            unsigned int relpos = abspos - curfa->offset;
            //DPRINT("relpos: " << relpos);
            assert(curfa->length >= relpos);
            unsigned int fileleft = curfa->length - relpos;
            unsigned int requestedread = size*count;
            
            if (requestedread > fileleft)
            {
                  //overflow
                  requestedread = fileleft;
            }
            
            DPRINT("JOEPACK fread: " << abspos << "," << relpos << "," << fileleft << "," << requestedread);
            
            return fread(buffer, 1, requestedread, f);
      }
      else
      {
            //write error?
            return 0;
      }
}

Generated by  Doxygen 1.6.0   Back to index