| author | ecalot
<ecalot> 2004-06-12 02:48:12 UTC |
| committer | ecalot
<ecalot> 2004-06-12 02:48:12 UTC |
| parent | 538204ad507c53074e1489fc4750b4fa8de739d5 |
| FP/src/res/dat.c | +249 | -0 |
| FP/src/res/disk.c | +457 | -0 |
| FP/src/res/resources.c | +186 | -0 |
diff --git a/FP/src/res/dat.c b/FP/src/res/dat.c new file mode 100644 index 0000000..070ba99 --- /dev/null +++ b/FP/src/res/dat.c @@ -0,0 +1,249 @@ +/* Princed V3 - Prince of Persia Level Editor for PC Version + Copyright (C) 2003 Princed Development Team + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + The authors of this program may be contacted at http://forum.princed.com.ar +*/ + +/* +dat.c: Princed Resources : DAT library +\xaf\xaf\xaf\xaf\xaf + Copyright 2004 Princed Development Team + Created: 15 Mar 2004 + + Author: Enrique Calot <ecalot.cod@princed.com.ar> + Version: 1.00 (2004-Mar-15) + + Note: + DO NOT remove this copyright notice +*/ + +#include <stdio.h> +#include <string.h> +#include "pr.h" + +#include "disk.h" +#include "dat.h" + +/***************************************************************\ +| DAT reading primitives | +\***************************************************************/ + +#ifdef PR_DAT_INCLUDE_DATREAD + +char recordSize; +int ofk=0; +int pop1; +unsigned char* indexPointer; +unsigned long int indexOffset; +unsigned long int offset; +unsigned short int indexSize; +unsigned char* readDatFile; +int readDatFileSize; + +void mReadCloseDatFile() { + free(readDatFile); +} + +int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){ + /* + Return Values: + 0 Wrong Format or file not found + 1 Ok + */ + + int ok; + unsigned char* readDatFilePoint; + + /* Open file */ + readDatFileSize=mLoadFileArray(vFiledat,&readDatFile); + if (!readDatFileSize) return 0; + if (readDatFileSize<=6) {free(readDatFile);return 0;} + + readDatFilePoint=readDatFile; + + /* verify dat format */ + indexOffset=array2long(readDatFilePoint); + readDatFilePoint+=4; + indexSize=array2short(readDatFilePoint); + + if ((indexOffset>readDatFileSize)&&((indexOffset+indexSize)!=readDatFileSize)) { + free(readDatFile); + return 0; /* this is not a valid prince dat file */ + } + + indexPointer=readDatFile+indexOffset; + *numberOfItems=array2short(indexPointer); + indexPointer+=2; + pop1=(((*numberOfItems)*8+2)==indexSize); + + if (!pop1) { /* verify if pop2 */ + ofk=(*numberOfItems)*6+2+((*numberOfItems)-2)*13; + (*numberOfItems)=((indexSize-6-((*numberOfItems)*6)-(((*numberOfItems)-2)*13))/11); + } else { + ofk=0; + } + recordSize=pop1?8:11; + + return 1; +} + +int mReadFileInDatFile(int k,unsigned char* *data,unsigned long int *size) { + int ok=1; /* TODO: rename mRead* for mRead* and mWrite for mWrite */ + unsigned short int id; + + /* for each archived file the index is read */ + id= array2short(indexPointer+ofk+k*recordSize);//(indexPointer[ofk+k*recordSize])+(indexPointer[ofk+k*recordSize+1]<<8); + printf("a ver: %d %d\n",id,(indexPointer[ofk+k*recordSize])+(indexPointer[ofk+k*recordSize+1]<<8)); + + offset=array2long(indexPointer+ofk+k*recordSize+2);//indexPointer[ofk+k*recordSize+2])+(indexPointer[ofk+k*recordSize+3]<<8)+(indexPointer[ofk+k*recordSize+4]<<16)+(indexPointer[ofk+k*recordSize+5]<<24); + *size= array2short(indexPointer+ofk+k*recordSize+6);//indexPointer[ofk+k*recordSize+6])+(indexPointer[ofk+k*recordSize+7]<<8)+1; + if ((!pop1)&&(!(indexPointer[ofk+k*recordSize+8]==0x40)&&(!indexPointer[ofk+k*recordSize+9])&&(!indexPointer[ofk+k*recordSize+10]))) return -1; + if (offset+indexSize>readDatFileSize) return -1; + *data=readDatFile+offset; + return ok?id:-1; +} + +int mReadInitResource(tResource** res,const unsigned char* data,long size) { + if ((*res)==NULL) { + (*res)=(tResource*)malloc(sizeof(tResource)); + if ((*res)==NULL) return -1; /* no memory */ + (*res)->path=NULL; + (*res)->palAux=NULL; + (*res)->desc=NULL; + (*res)->name=NULL; + (*res)->palette=0; + (*res)->number=0; + (*res)->size=(unsigned short int)size; + (*res)->offset=(unsigned short)offset; /* TODO delete this line */ + (*res)->type=verifyHeader(data,(unsigned short int)size); + } else { /* If resource type is invalid or 0, the type will be decided by PR */ + if (!((*res)->type)) (*res)->type=verifyHeader(data,(unsigned short int)size); + } + return 0; +} +#endif + +/***************************************************************\ +| DAT Writing primitives | +\***************************************************************/ + +#ifdef PR_DAT_INCLUDE_DATWRITE +FILE* writeDatFile; + +int mWriteBeginDatFile(const char* vFile, int optionflag) { + /* + Opens safely a dat file for writing mode and + reserves space for the headers + + Return Values: + 1 Ok + 0 File couldn't be open + + */ + if (writeOpen(vFile,&writeDatFile,optionflag|backup_flag)) { + fseek(writeDatFile,6,SEEK_SET); + return 1; + } else { + return 0; + } +} + +void mWriteInitResource(tResource** res) { + if ((*res)==NULL) { + (*res)=(tResource*)malloc(sizeof(tResource)); + (*res)->path=NULL; + (*res)->palAux=NULL; + (*res)->desc=NULL; + (*res)->name=NULL; + } + (*res)->offset=(unsigned long)ftell(writeDatFile); +} + +void mWriteFileInDatFile(const unsigned char* data, int size) { + /* + Adds a data resource to a dat file keeping + abstractly the checksum ver ifications + */ + + /* Declare variables */ + int k = size; + unsigned char checksum = 0; + const unsigned char* dataAux = data; + + /* calculates the checksum */ + while (k--) checksum+=*(dataAux++); + checksum=~checksum; + + /* writes the checksum and the data content */ + fwritechar(&checksum,writeDatFile); + fwrite(data,size,1,writeDatFile); +} + +void mWriteFileInDatFileIgnoreChecksum(unsigned char* data, int size) { + fwrite(data,size,1,writeDatFile); +} + +void mWriteCloseDatFile(tResource* r[],int dontSave,int optionflag, const char* backupExtension) { + /* + Closes a dat file filling the index and other structures + */ + unsigned short int id=1; + unsigned short int totalItems=0; + unsigned short int size2=2; + unsigned long int size1=ftell(writeDatFile); + + /* Write index */ + fwriteshort(&totalItems,writeDatFile); /* Junk total items count to reserve 2 bytes */ + for (;id!=MAX_RES_COUNT;id++) { + if (r[id]!=NULL) { + /* the file is in the archive, so i'll add it to the index */ + totalItems++; + fwriteshort(&id,writeDatFile); + fwritelong(&(r[id]->offset),writeDatFile); + fwriteshort(&(r[id]->size),writeDatFile); + } + } + size2+=totalItems<<3; + fseek(writeDatFile,size1,SEEK_SET); + fwriteshort(&totalItems,writeDatFile); /* Definitive total items count */ + + /* Write first 6 bytes header */ + fseek(writeDatFile,0,SEEK_SET); + fwritelong(&size1,writeDatFile); + fwriteshort(&size2,writeDatFile); + + /* Closes the file and flushes the buffer */ + writeClose(writeDatFile,dontSave,optionflag,backupExtension); +} +#endif + +/***************************************************************\ +| DAT R/W primitives | +\***************************************************************/ + +#ifdef PR_DAT_INCLUDE_DATREAD +#ifdef PR_DAT_INCLUDE_DATWRITE +int mRWBeginDatFile(const char* vFile, unsigned short int *numberOfItems, int optionflag) { + if (!mReadBeginDatFile(numberOfItems,vFile)) return -2; + if (!mWriteBeginDatFile(vFile,optionflag)) { + mReadCloseDatFile(); + return -1; + } + return 0; +} +#endif +#endif diff --git a/FP/src/res/disk.c b/FP/src/res/disk.c new file mode 100644 index 0000000..afb01d2 --- /dev/null +++ b/FP/src/res/disk.c @@ -0,0 +1,457 @@ +/* Princed V3 - Prince of Persia Level Editor for PC Version + Copyright (C) 2003 Princed Development Team + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + The authors of this program may be contacted at http://forum.princed.com.ar +*/ + +/* +disk.c: Princed Resources : Disk Access & File handling functions +\xaf\xaf\xaf\xaf\xaf\xaf + Copyright 2003 Princed Development Team + Created: 29 Oct 2003 + + Author: Enrique Calot <ecalot.cod@princed.com.ar> + Version: 1.00 (2003-Oct-29) + + Modified by: Enrique Calot <ecalot.cod@princed.com.ar> + Version: 1.10 (2003-Dec-03) + Modified by: Santiago Zamora <drkzight@users.sourceforge.net> + Version: 1.20 (2004-Jan-06) + + Note: + DO NOT remove this copyright notice +*/ + +/* Defines */ +#include "memory.h" +#include <string.h> +#include "pr.h" +#include "disk.h" +//#include "xmlparse.h" /* equalsIgnoreCase */ +#define IGNORERECURSIVEFUNCTIONS + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef UNIX + #define defmkdir(a) mkdir (a,(mode_t)0755) + #include <dirent.h> + #include <termios.h> + #include <unistd.h> + #include <fcntl.h> + #define osIndepGetCharacter() getchar() +#else + #include <direct.h> + #include "direntwin.h" + #define defmkdir(a) mkdir (a) + #include <conio.h> + #define osIndepGetCharacter() getche() +#endif + +extern FILE* outputStream; + +/***************************************************************\ +| Disk Access & File handling functions | +\***************************************************************/ + +/* Repair folders */ +const char *repairFolders(const char* a) { + int i,k; + static char result[MAX_FILENAME_SIZE]; +fld("rf1"); + + for (i=0,k=0;a[i]&&(k<MAX_FILENAME_SIZE);) { + if (isDirSep(a,i)) { + result[k]=DIR_SEPARATOR; + i++; + while (isDirSep(a,i)) i++; + } else { + result[k]=a[i]; + i++; + } + k++; + } +fld("rf2"); + result[k]=0; +fld("rf3"); + return result; +} + + +/* Create base directory of a file */ +int makebase(const char* p) { + /* + Creates the base directory of the given file "p" + Returns 0 if created + Returns -1 if an error occurred + + Note: if the base directory already exists it will return -1! + */ + + /* Declare variables */ + static char old[MAX_FILENAME_SIZE]; + int i,a,equal=1; + int size; + char* aux; + + /* Initialize variables */ + size=(strlen(p)+1); + aux=(char*)malloc(size); + + /* Make directories */ + for (i=0;i<size;i++) { + aux[i]=0; + equal=equal&&(old[i]==p[i]); + if ((!equal)&&(p[i]==DIR_SEPARATOR)) a=defmkdir(aux); + old[i]=p[i]; + aux[i]=p[i]; + } + + free(aux); + return a; +} + +#if 0 +static tOpenFiles* openFilesList=NULL; + +void addFileToOpenFilesList(const char* fileName,int hasBackup) { + /* + Add a recently safe open file to the file pointer dynamic table + using the LIFO philosophy. + */ + + tOpenFiles* newNode; + + /* Create the new node and fill in the fields */ + newNode=(tOpenFiles*)malloc(sizeof(tOpenFiles)); + newNode->next=openFilesList; + newNode->name=strallocandcopy(fileName); + if (hasBackup) { + newNode->size=mLoadFileArray(fileName,&(newNode->content)); + } else { + newNode->size=0; + } + openFilesList=newNode; +} + +void addPointerToOpenFilesList(FILE* fp) { /* TODO: use a define */ + openFilesList->file=fp; +} + +int getFromOpenFilesList(FILE* fp, char** fileName, unsigned char** content, unsigned long int *size) { + tOpenFiles* currentNode; + tOpenFiles* priorNode=NULL; + + /* Search using FILE* file as key */ + if (openFilesList==NULL) return 0; /* Empty list */ + currentNode=openFilesList; + while ((currentNode->file!=fp)&&(currentNode->next!=NULL)) { + priorNode=currentNode; + currentNode=currentNode->next; + } + if (currentNode->file!=fp) return 0; /* Not found */ + + /* Return results */ + *fileName=currentNode->name; + *content=currentNode->content; + *size=currentNode->size; + + /* free node and set prior pointer to the next */ + if (priorNode==NULL) { + openFilesList=currentNode->next; + } else { + priorNode->next=currentNode->next; + } + free(currentNode); + + return 1; +} + +#endif +int writeClose(FILE* fp,int dontSave,int optionflag,const char* backupExtension) { + unsigned char* content; + char* fileName; + unsigned long int size; + + if (getFromOpenFilesList(fp,&fileName,&content,&size)) { + if (dontSave) { + fclose(fp); + if (size) { + fp=fopen(fileName,"wb"); + if (fp==NULL) return -1; + fwrite(content,1,size,fp); + } else { + remove(fileName); + } + } else { + /* File Existed before and we need to back it up */ + if (hasFlag(backup_flag)) { + char aux[MAX_FILENAME_SIZE]; + static const char defaultbackupExtension[]=DEFAULT_BACKUP_EXTENSION; + /* Set default values if there isn't */ + if (backupExtension==NULL) backupExtension=defaultbackupExtension; + /* generate the file name */ + sprintf(aux,"%s.%s",fileName, backupExtension); + fclose(fp); + fp=fopen(aux,"wb"); + if (fp==NULL) return -2; + fwrite(content,1,size,fp); + } + } + + free(fileName); + if (size) free(content); + } + + return fclose(fp); +} + +int writeOpen(const char* vFileext, FILE* *fp, int optionflag) { + /* + Opens vFileext for write access + if the path doesn't exist it is created + if the file doesn't exist it is created + if the file does exist it is overwritten + + Sets the file pointer and returns 1 if Ok or 0 if error + + Returns + 0 if error + 1 if ok + */ + const char* file; + whatIs fileType; + int result; + + /* Create base directory and save file */ + file=repairFolders(vFileext); + + /* Verify if file already exists. */ + fileType=isDir(vFileext); + if (fileType==eDirectory) return 0; + + if (fileType==eFile) { + /* File exists. We need to ask */ + } else { + makebase(file); + } + + /* + If the file exists, we need to remember the old content in memory + if not, we need to know the name in case we need to delete it + */ + + addFileToOpenFilesList(file,hasFlag(backup_flag)); + if ((result=((*fp=fopen(file,"wb"))!=NULL))) addPointerToOpenFilesList(*fp); + return result; +} + + +int writeData(const unsigned char* data, int ignoreChars, char* vFileext, int size, int optionflag,const char* backupExtension) { + /* + Creates vFileext and saves data in it. In case the directory doesn't + exist it will be created. + + Data is read from ignoreChars to size. + Example: + if data="123456789", ignoreChars=3, size=8 + saved file will contain "45678" + + Returns + 0 if error + 1 if ok + */ + + /* Declare variables */ + FILE* target; + char ok; + + /* Verify parameters */ + size-=ignoreChars; + if (size<0) return 0; + //if (size==0) return 1; /* Wrote 0 bytes */ + + /* Save file */ + ok=writeOpen(vFileext,&target,optionflag); + ok=ok&&((!size)||fwrite(data+ignoreChars,size,1,target)); + ok=ok&&(!writeCloseOk(target,optionflag,backupExtension)); + return ok; +} + +int mLoadFileArray(const char* vFile,unsigned char** array) { + /* + Using the string in vFile, it opens the file and returns the + number of bytes in it and the content of the file in array. + In case the file couldn't be open or memory allocated returns 0. + */ + + /* declare variables */ + FILE *fp; + int aux; + + /* Open the file */ + fp=fopen(repairFolders(vFile),"rb"); + if ((fp=fopen(repairFolders(vFile),"rb"))==NULL) { + return 0; + } else { + /* get file size */ + fseek(fp,0,SEEK_END); + aux=ftell(fp); + if ( !aux || (aux>SIZE_OF_FILE) || ( ((*array=(unsigned char*)malloc(sizeof(char)*aux))==NULL) ) ) { + /* if the file was null or bigger than the max size or couldn't allocate the file in memory */ + fclose(fp); + return 0; + } else { + /* if the file was successfully open */ + fseek(fp,0,SEEK_SET); + aux=fread (*array,1,aux,fp); + fclose(fp); + return aux; + } + } +} + +#ifdef PR_FUTURE_CODE +int mDiskVealidateFileHeader(unsigned char* text, int size, FILE* fp) { + /* + Validates if the file contains the following text in the stream. + 1 if it does + 0 if error or doesn't + + Moves the file pointer to the next position + */ + + /* Declare variables */ + int i; + unsigned char* readText; + + /* Reserves memory to allocate the read bytes */ + readText=getMemory(size); + if (readText==NULL) return 0; /* memory error, abort */ + + /* Read the file and move the file pointer */ + if (!fread(readText,size,1,fp)) { + free(readText); + return 0; + } + + /* Make the binary compare */ + for (i=0;(i<size)&&(readText[i]==text[i]);i++); + + /* Frees memory and returns the result */ + free(readText); + return (i==size); /* 0 if the compare for was stopped before end reached */ +} +#endif + +const char* getFileNameFromPath(const char* path) { + /* + If you give a path you get the filename, + if you give a filename, you get the same filename + */ + int size; + size=strlen(path); + while (size) { + if (isDirSep(path,size)) { + return path+size+1; + } + size--; + } + return path; +} + +whatIs isDir(const char *path) { + /* + eDirectory if path is a directory + eNotFound if path isn't a directory or doesn't exist + eFile if it is a file + */ + struct stat buf; + + if(stat(path,&buf)==-1) return eNotFound; + return (S_IFDIR&buf.st_mode)?eDirectory:eFile; +} + +#ifndef IGNORERECURSIVEFUNCTIONS + +int recurseDirectory(const char* path,int optionflag, const char* extension,const char* dirName,const char* resFile, const char* datfilename,const char* datAuthor,FILE* output) { + /* + Search for all .dat files in the directory + if recursive flag is set search over the subdirectories + if verbose flag is set shows some messages in the screen + when .dat files are found it runs prMain form each of them + */ + + /* Declare variables */ + char* recursive; + struct dirent* directoryStructure; + DIR* dir; + + /* Opens directory */ + if ((dir = opendir(path))==NULL) { + return 0; + } + + /* Shows some messages */ + if ((hasFlag(recursive_flag))&&(hasFlag(verbose_flag))) { /* Only recourse if recursive and verbose flags are set */ + fprintf(outputStream,PR_TEXT_DISK_PROCESSING,path); + } + + /* Main loop: while there are still more files left */ + while ((directoryStructure = readdir(dir))!=NULL) { + if /* Don't look over the system directories */ + ( + strcmp(directoryStructure->d_name,".")&& + strcmp(directoryStructure->d_name,"..") + ) { + /* Declare variables */ + int sizeOfPath=strlen(path); + int sizeOfFile=strlen(directoryStructure->d_name); + + /* Generate recursive path */ + recursive=(char*)malloc(sizeOfPath+2+sizeOfFile); + memcpy(recursive,path,sizeOfPath); + recursive[sizeOfPath]=DIR_SEPARATOR; + memcpy(recursive+sizeOfPath+1,directoryStructure->d_name,sizeOfFile+1); + + /* + If recursive path is a directory and recursive flag is set recourse into it + if recursive path is a directory and recursive flag wasn't set, just ignore + if recursive path is not a directory and is a dat file, do prMain + if recursive path is not a directory and is not a dat file, ignore + */ + if (isDir(recursive)==eDirectory) { + if (hasFlag(recursive_flag)) { /* Only recourse if recursive flag is set */ + recurseDirectory(recursive,optionflag,extension,dirName,resFile,datfilename,datAuthor,output); + } + } else { + char aux[]=".dat"; + if (sizeOfFile>4) { + if (equalsIgnoreCase(aux,directoryStructure->d_name+sizeOfFile-4)) { + prMain(optionflag,extension,dirName,resFile,recursive,directoryStructure->d_name,datAuthor,output); + } + } + } + /* Free all allocated memory */ + free(recursive); + } + } + return 1; +} + +#endif + diff --git a/FP/src/res/resources.c b/FP/src/res/resources.c new file mode 100644 index 0000000..dbd9217 --- /dev/null +++ b/FP/src/res/resources.c @@ -0,0 +1,186 @@ +/* Princed V3 - Prince of Persia Level Editor for PC Version + Copyright (C) 2003 Princed Development Team + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + The authors of this program may be contacted at http://forum.princed.com.ar +*/ + +/* +extract.c: Princed Resources : DAT Extractor +\xaf\xaf\xaf\xaf\xaf\xaf\xaf\xaf\xaf + Copyright 2003, 2004 Princed Development Team + Created: 24 Aug 2003 + + Author: Enrique Calot <ecalot.cod@princed.com.ar> + Version: 1.01 (2003-Oct-23) + Version: 1.20 (2004-Mar-07) + Version: 1.30 (2004-Mar-15) + + Note: + DO NOT remove this copyright notice +*/ + +#include <stdio.h> +#include <string.h> +#include "freeprince.h" + +#include "dat.h" +#include "disk.h" + +/***************************************************************\ +| I M P L E M E N T A T I O N | +\***************************************************************/ + +#define initializePaletteList \ +for (id=0;id<MAX_RES_COUNT;id++) {\ + if (r[id]!=NULL) {\ + r[id]->palAux=NULL;\ + }\ +} + +/***************************************************************\ +| M A I N E X T R A C T | +\***************************************************************/ + + +/* + Extracts a dat file + For parameter documentation, see pr.c +*/ + +int extract(const char* vFiledat,const char* vDirExt, tResource* r[], int optionflag, const char* vDatFileName, const char* vDatAuthor,const char* backupExtension) { + char vFileext[MAX_FILENAME_SIZE]; + int indexNumber; + int ok=1; + long int id; + tImage image; /* this is used to make a persistent palette */ + unsigned char* data; + unsigned long int size; + unsigned short int numberOfItems; + unsigned short int paletteId=0; + + /* Initialize abstract variables to read this new DAT file */ + if (!mReadBeginDatFile(&numberOfItems,vFiledat)) return -1; +fld("a"); + /* Initializes the palette list */ + initializePaletteList; +fld("b"); + + /* main loop */ + for (indexNumber=0;ok&&(indexNumber<numberOfItems);indexNumber++) { + id=mReadFileInDatFile(indexNumber,&data,&size); +fld("c"); +printf("*K) id=%d size=%d %d:%d:%d:%d:%d:%d\n",id,size,data[0],data[1],data[2],data[3],data[4],data[5]); + + if (id<0) return -3; /* Read error */ + if (id==0xFFFF) continue; /* Tammo Jan Bug fix */ + if (id>=MAX_RES_COUNT) return -3; /* A file with an ID out of range will be treated as invalid */ +fld("d"); + + /* set resource information on this index entry */ + if (mReadInitResource(r+id,data,size)) return -2; +fld("e"); +printf("z->%d\n",r[id]->type); + if ((r[id]->type==RES_TYPE_PALETTE)||isInThePartialList(r[id]->path,id)) { /* If the resource was specified or is a palette, do the tasks */ + if (!(hasFlag(unknown_flag))) { /* If unknown flag is set do nothing but generate the unknown.xml file */ + if (hasFlag(raw_flag)) r[id]->type=0; /* If "extract as raw" is set, type is 0 */ + + /* get save file name (if unknown document it in the xml) */ + getFileName(vFileext,vDirExt,r[id],(unsigned short)id,vFiledat,vDatFileName,optionflag,backupExtension); +fld("f"); + switch (r[id]->type) { + case RES_TYPE_LEVEL: + ok=ok&&mFormatExportPlv(data,vFileext,size,r[id]->number,vDatFileName,r[id]->name,r[id]->desc,vDatAuthor,optionflag,backupExtension); + break; + case RES_TYPE_BINARY: /* Binary files */ + case RES_TYPE_RAW: /* Raw files */ + ok=ok&&writeData(data,1,vFileext,size,optionflag,backupExtension); /* Ignore checksum */ + break; + case RES_TYPE_PALETTE: /* save and remember palette file */ + /* This will remember the palette for the next images */ + r[id]->palAux=getMemory(size); + memcpy(r[id]->palAux,data,size); + if (!paletteId) { /* In case there is no loaded palettes load immediately the first found palette to clear garbage */ + mLoadPalette(data,image); + paletteId=id; + } + /* This will export the palette */ + if (isInThePartialList(r[id]->path,id)) /* If the palette was specified extract it */ + ok=ok&&mFormatExportPal(data,vFileext,size,optionflag,backupExtension); + break; + case RES_TYPE_PCSPEAKER: /* save pcs file */ + case RES_TYPE_MIDI: /* save midi file */ +printf("a->%d\n",ok); + ok=ok&&mFormatExportMid(data,vFileext,size,optionflag,backupExtension); +printf("b->%d\n",ok); + break; + case RES_TYPE_WAVE: /* save wav file */ + ok=ok&&mFormatExportWav(data,vFileext,size,optionflag,backupExtension); + break; + case RES_TYPE_IMAGE: /* save image */ + /* Palette handling */ +fld("Z1"); + if (r[id]->palette!=paletteId) { /* The palette isn't the already loaded */ + if (r[id]->palette) { /* We need a palette */ + /* + We need a palette and it is not the palette we have loaded in memory + So a new palette is going to be loaded. + */ + if ((r[r[id]->palette]->palAux)!=NULL) { /* If this palette wasn't loaded, it becomes loaded */ + mLoadPalette(r[r[id]->palette]->palAux,image); + paletteId=r[id]->palette; /* sets the new palette loaded */ + } + } + } + /* Export bitmap */ +fld("Z2"); + ok=ok&&mFormatExportBmp(data,vFileext,size,image,optionflag,backupExtension); +fld("Z3"); + break; + } + /* Verbose information */ + if (hasFlag(verbose_flag)) { + if (ok) { + fprintf(outputStream,PR_TEXT_EXPORT_WORKING,getFileNameFromPath(vFileext)); + } else { + fprintf(outputStream,PR_TEXT_EXPORT_ERROR,getFileNameFromPath(vFileext)); + } + } + } else { + /* if the dat file is unknown, add it in the xml */ + getFileName(vFileext,vDirExt,r[id],(unsigned short)id,vFiledat,vDatFileName,optionflag,backupExtension); + } + /*freeAllocation(data);*/ + } + } + + /* Free allocated resources, dynamic strings and the index */ + for (id=0;id<MAX_RES_COUNT;id++) { + if (r[id]!=NULL) { + freeAllocation(r[id]->palAux); + freeAllocation(r[id]->desc); + freeAllocation(r[id]->name); + freeAllocation(r[id]->path); + free(r[id]); + } + } + mReadCloseDatFile(); + + /* Close unknownXML */ + endUnknownXml(optionflag,backupExtension); + return ok-1; +} +