2e44111f58c6cea5cf795c2c378939da70bfc744
[fp-git.git] / PR / src / console / main.c
1 /*  Princed V3 - Prince of Persia Level Editor for PC Version
2     Copyright (C) 2003 Princed Development Team
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18     The authors of this program may be contacted at http://forum.princed.com.ar
19 */
20
21 /*
22 pr.c: Main source file for Princed Resources
23 ¯¯¯¯
24         Princed Resources editor
25         (c) Copyright 2003, Princed Development Team
26
27         Authors
28          Coding & main routines
29           Enrique Calot
30
31          Graphic compression algorithms
32           Tammo Jan Dijkema
33           Enrique Calot
34
35          Graphic format development
36           Tammo Jan Dijkema
37           Anke Balderer
38
39          MID Sound format development
40           Christian Lundheim
41
42          Resources.xml edition
43           Steven Fayers
44
45  Note:
46   DO NOT remove this copyright notice
47 */
48
49 //Headers
50 #include <stdio.h>
51 #include <string.h>
52
53 #include "pr.h"
54
55 #include "compress.h"
56
57 #include "extract.h"
58 #include "compile.h"
59 #include "tasks.h"
60
61 #include "memory.h"    /* getMemory, free */
62 #include "disk.h"      /* getFileNameFromPath */
63
64 #ifndef DLL
65  #ifdef UNIX
66   #include <unistd.h>
67  #else
68   #include "getopt.h"
69  #endif
70 #endif
71
72 /***************************************************************\
73 |                      Main working functions                   |
74 \***************************************************************/
75
76 int prExportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
77         return prExportDatOpt(vDatFile,vDirName,vResFile,0,NULL,NULL,"");
78 }
79
80 int prExportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName,const char* datAuthor, const char* backupExtension) {
81         /*
82                 Arguments:
83                         char* vDatFile        - full Path to the dat file;
84                                                 if file use it, if dir, perform it for
85                                                 all files
86                         char* vDirName        - full Path to the extracting folder
87                                                 (doesn't need to exist)
88                         char* vResFile        - full Path to the resources XML file
89                                                 (resources.xml by default)
90                                                 No NULL
91                         char opt              - program options, see below
92                         char * vDatFileName   - name of the file to be extracted
93                                                 NULL means predict it from vDatFile (DISABLED!!!)
94                         const char* datAuthor - Author's name when extracting PLV's,
95                                                 NULL is default
96                         const char* backupExtension
97                                               - If backup_flag is set, the string to attach
98                                                 to the backup files
99
100                 Options:
101                         unknown_flag   - generate the unknown file without performing
102                        any extraction
103                         raw_flag       - uses raw format
104                         verbose_flag   - explain what is being done
105                         recursive_flag - searches for all dat files (only if vDatFile
106                                          is not a dat file and vDatFileName is NULL)
107 x                       force_flag     - default option, you cannot disable it,
108                                          so please make a backup of your files
109 x                       backup_flag    - backup your files
110
111
112                 Return values:
113                         00 Ok
114                         -1 Error accessing the file DAT
115                         -2 Memory error in extraction
116                         -3 Invalid DAT file
117                         -4 XML Parse error
118                         -5 Memory error in parsing
119                         -6 XML Attribute not recognized
120                         -7 XML File not found
121         */
122
123         //Declare variables
124         tResource* r[MAX_RES_COUNT];
125         int a;
126         const char defaultXmlFile[]=RES_XML_RESOURC_XML;
127         //Set default values
128         if (vResFile==NULL) vResFile=defaultXmlFile; //TODO: Send to prMain or main
129
130         //Parse XML and extract the file //TODO: XML parser outside the function
131         a=parseFile(vResFile,vDatFileName,r);
132         if (a<0) return a-3; //parsing errors
133         a=extract(vDatFile,vDirName,r,opt,vDatFileName,datAuthor);
134         return a; //extracting errors/no errors
135 }
136
137 int prImportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
138         return prImportDatOpt(vDatFile,vDirName,vResFile,0,NULL,"");
139 }
140
141 int prImportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName, const char* backupExtension) {
142         /*
143                 Arguments:
144                         char* vDatFile        - full Path to the dat file;
145                                                 if file use it, if dir, perform it for
146                                                 all files
147                         char* vDirName        - full Path to the extracting folder
148                                                 (doesn't need to exist)
149                         char* vResFile        - full Path to the resources XML file
150                                                 (resources.xml by default)
151                                                 No NULL
152                         char opt              - program options, see below
153                         char * vDatFileName   - name of the file to be extracted
154                                                 NULL means predict it from vDatFile
155                         const char* backupExtension
156                                               - If backup_flag is set, the string to attach
157                                                 to the backup files
158
159                 Options:
160                         raw_flag       - uses raw format
161                         verbose_flag   - explain what is being done
162                         recursive_flag - searches for all dat files (only if vDatFile
163                                          is not a dat file and vDatFileName is NULL)
164 x                       force_flag     - default option, you cannot disable it,
165                                          so please make a backup of your files
166 x                       backup_flag    - backup your files
167
168
169                 Return values:
170                         -1 DAT File couldn't be open for writing
171                         -2 XML Parse error
172                         -3 No memory
173                         -4 XML Attribute not recognized
174                         -5 XML File not found
175                         00 File succesfully compiled
176                         positive number: number of missing files
177         */
178
179         //Declare variables
180         tResource* r[MAX_RES_COUNT];
181         int a;
182         const char defaultXmlFile[]=RES_XML_RESOURC_XML;
183
184         //Set default values
185         if (vResFile==NULL) vResFile=defaultXmlFile;
186
187         //Parse XML and compile files
188         a=parseFile     (vResFile,vDatFileName,r);
189         if (a<0) return a-1;
190         a=compile (vDatFile, vDirName,r,opt,vDatFileName);
191         return a;
192 }
193
194
195 /***************************************************************\
196 |                     M A I N   P R O G R A M                   |
197 \***************************************************************/
198
199 void syntax(FILE* output) {
200         fprintf(output,PARSING_HELP);
201 }
202
203 int prMain(int* pOption, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
204
205         //declare variables
206         int returnValue=1;
207         char* currentDatFileName;
208         const char* aux;
209
210         if (datfilename==NULL) {
211                 aux=getFileNameFromPath(datfile);
212         } else {
213                 aux=datfilename;
214         }
215
216         currentDatFileName=strallocandcopy(aux);
217
218         //do selected tasks
219         if (optionflag&export_flag) {
220                 char* array[]=PR_TEXT_EXPORT_ARRAY;
221                 fprintf(output,"Extracting '%s' to '%s' with %04x\r\n",datfile,dirName,optionflag);
222                 returnValue=prExportDatOpt(datfile,dirName,resFile,optionflag,currentDatFileName,datAuthor,extension);
223                 fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
224         }       else if (optionflag&classify_flag) {
225                 char* array[]=PR_TEXT_CLASSIFY_ARRAY;
226                 fprintf(output,"Classifing '%s'\r\n",datfile);
227                 returnValue=prVerifyDatType(datfile);
228                 fprintf(output,PR_TEXT_RESULT,array[2+returnValue],returnValue);
229         }       else if (optionflag&import_flag) {
230                 char* array[]=PR_TEXT_IMPORT_ARRAY;
231                 fprintf(output,"Compiling '%s' from '%s' with %04x\r\n",datfile,dirName,optionflag);
232                 returnValue=prImportDatOpt(datfile,dirName,resFile,optionflag,currentDatFileName,extension);
233                 if (returnValue<=0) {
234                         fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
235                 } else {
236                         fprintf(output,PR_TEXT_RESULT_ERR,returnValue);
237                 }
238         } else {
239                 syntax(output);
240                 returnValue=-1;
241         }
242         if (currentDatFileName) free(currentDatFileName);
243         return returnValue;
244 }
245
246 //Main program
247 #ifndef DLL
248
249 /***************************************************************\
250 |             Standard executable specific functions            |
251 \***************************************************************/
252
253 int prStart(int* pOption, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
254         int result=1;
255
256         //Do CGI tasks
257         if (optionflag&cgi_flag) {
258                 optionflag&=(~classify_flag);
259                 if (!(optionflag&first_flag)) {
260                         fprintf(output,PR_CGI_TEXT1);
261                         optionflag|=first_flag;
262                 }
263                 if (optionflag==cgi_flag) {
264                         fprintf(output,PR_CGI_TEXT2,prVerifyDatType(datfile));
265                         return 1;
266                 } else {
267                         optionflag=help_flag;
268                 }
269         }
270
271         //Show about
272         if (!(optionflag&first_flag)) {
273                 fprintf(output,PR_ABOUT);
274                 optionflag|=first_flag;
275         }
276
277         //If bad syntax or help screen requested
278         if (optionflag&help_flag) {
279                 syntax(output);
280                 return -1;
281         }
282
283         //If version asked, stop
284         if (optionflag&version_flag) {
285                 return -1;
286         }
287
288         //Perform tasks depending on the argument
289         if (optionflag&import_flag) {
290                 //Check out the xml file to get the files to me compiled
291                 if (datfile==NULL) {
292                         fprintf(output,"Importing all valid dat files from the currect directory\n");
293                         importDir(dirName,resFile,pOption,extension,".",output);
294                 } else if (isDir(datfile)!=eFile) {
295                         fprintf(output,"Importing all valid files from given directory\n");
296                         importDir(dirName,resFile,pOption,extension,datfile,output);
297                 } else {
298                         result=prMain(pOption,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
299                 }
300         } else {
301
302                 //Recursive testing for export/classify
303                 if (datfile==NULL) {
304                         fprintf(output,PR_TEXT_SCANNING_CURRENT);
305                         recurseDirectory(".",pOption,extension,dirName,resFile,datfilename,datAuthor,output);
306                 } else if (isDir(datfile)==eDirectory) {
307                         fprintf(output,PR_TEXT_SCANNING_GIVEN);
308                         recurseDirectory(datfile,pOption,extension,dirName,resFile,datfilename,datAuthor,output);
309                 } else if (isDir(datfile)==eNotFound) {
310                         fprintf(output,PR_TEXT_FILE_NOT_FOUND,datfile);
311                         return 0;
312                 } else {
313
314                         result=prMain(pOption,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
315                 }
316         }
317
318         freeParsedStructure();
319         return result;
320 }
321
322 /***************************************************************\
323 |      Standard executable command line parsing function        |
324 \***************************************************************/
325
326 int main (int argc, char **argv) {
327         //declare variables
328         char* datFileName=NULL;
329         char  dirName[MAX_FILENAME_SIZE]=".";
330         char  extension[MAX_EXTENSION_SIZE]=DEFAULT_BACKUP_EXTENSION;
331         char  resFile[MAX_FILENAME_SIZE]=RES_XML_RESOURC_XML;
332         char* datFilePath=NULL;
333         char* datAuthor=NULL;
334         int   c;
335         int   flag=0;
336
337         //Parse options
338         while (1) {
339                 static struct option long_options[] = PARSING_OPTIONS;
340
341                 /* getopt_long stores the option index here. */
342                 int junk = 0;
343                 c = getopt_long (argc, argv, PARSING_CHARS,long_options,&junk);
344
345                 /* Detect the end of the options. */
346                 if (c == -1) break;
347
348                 switch (c) {
349                                 case 'c':
350                                         if (flag&(classify_flag|export_flag)) flag|=help_flag;
351                                         flag|=import_flag;
352                                         if (optarg) strncpy(dirName,optarg,MAX_FILENAME_SIZE);
353                                         break;
354                                 case 'd':
355                                         if (flag&(import_flag|export_flag)) flag|=help_flag;
356                                         flag|=classify_flag;
357                                         break;
358                                 case 'x':
359                                 case 'e':
360                                         if (flag&(classify_flag|import_flag)) flag|=help_flag;
361                                         flag|=export_flag;
362                                         if (optarg) strncpy(dirName,optarg,MAX_FILENAME_SIZE);
363                                         break;
364                                 case 'b':
365                                         flag|=backup_flag;
366                                         if (optarg) strncpy(extension,optarg,MAX_FILENAME_SIZE);
367                                         break;
368                                 case 'f':
369                                         flag|=force_flag;
370                                         break;
371                                 case 'g':
372                                         flag|=cgi_flag;
373                                         break;
374                                 case 'm':
375                                         strncpy(resFile,optarg,MAX_FILENAME_SIZE);
376                                         break;
377                                 case 'r':
378                                         flag|=raw_flag;
379                                         break;
380                                 case 'R':
381                                         flag|=recursive_flag;
382                                         break;
383                                 case 't':
384                                         if (datFileName!=NULL) free(datFileName);
385                                         datFileName=strallocandcopy(optarg);
386                                         break;
387                                 case 'a':
388                                         if (datAuthor!=NULL) free(datAuthor);
389                                         datAuthor=strallocandcopy(optarg);
390                                         break;
391                                 case 'v':
392                                         flag|=verbose_flag;
393                                         break;
394                                 case 1:
395                                         flag|=version_flag;
396                                         break;
397                                 case 2:
398                                         flag|=unknown_flag;
399                                         break;
400                                 default:
401                                         flag|=help_flag;
402                 }
403         }
404
405         if (optind < argc) {
406                 datFilePath=argv[optind];
407         }
408
409         if (!flag) flag=help_flag;
410
411         //Run main program
412 fld("a");
413         prStart(&flag,extension,dirName,resFile,datFilePath,datFileName,datAuthor,stdout);
414 fld("b");
415         //Free memory and exit
416         if (datAuthor!=NULL) free(datAuthor);
417         if (datFileName!=NULL) free(datFileName);
418   return 0;
419 }
420
421 #endif
422
423 /***************************************************************\
424 |              Main Library start dummy function                |
425 \***************************************************************/
426
427 #ifdef SO
428 //When compiling in Unix SO libraries
429 void start() {}
430 #endif
431
432