git » fp-git.git » commit b923716

detect pop 1 related file types

author ecalot
2005-03-27 01:16:54 UTC
committer ecalot
2005-03-27 01:16:54 UTC
parent dbe2cd58bd639b1e2e61ca918be477f94d9f1dcc

detect pop 1 related file types

PR/doc/changelog.txt +4 -2
PR/src/console/main.c +4 -2
PR/src/include/common.h +1 -1
PR/src/lib/actions/classify.c +77 -2
PR/src/lib/actions/export.c +1 -1
PR/src/lib/layers/dat.c +8 -7

diff --git a/PR/doc/changelog.txt b/PR/doc/changelog.txt
index b9897a8..4b40cdd 100644
--- a/PR/doc/changelog.txt
+++ b/PR/doc/changelog.txt
@@ -144,11 +144,13 @@ Versions:
   - Solved bug in palette buffer initialization for autodetected images
   - Stable version for win32 and unix based systems
   - Using new macros to use an endian-independent layer.
+ * PR v1.1:
+  - Coded file type detection to detect dat subtypes, sav, hof and exe
+    subtypes.
+  x Finish python interface
 
 2) ToDo List & Future Plans:
 
- * PR v1.1:
-  x Finish python interface
  * PR v2.0 beta:
   x Add full pop2 support
  * PR v2.0:
diff --git a/PR/src/console/main.c b/PR/src/console/main.c
index 16ef496..fd7b031 100644
--- a/PR/src/console/main.c
+++ b/PR/src/console/main.c
@@ -211,8 +211,10 @@ int main (int argc, char **argv) {
 				} else {
 					/* classify */
 					fprintf(outputStream,PR_TEXT_TASK_CLASSIFY,file);
-					result=prClassifyDat(file);
-					fprintf(outputStream,PR_TEXT_RESULT,classifyErrors[result+2],result);
+					/*result=prClassifyDat(file);
+					fprintf(outputStream,PR_TEXT_RESULT,classifyErrors[result+2],result);*/
+					result=prClassify(file);
+					fprintf(outputStream,"clasificacion: %d\n",result);
 				}
 				free(file);
 				free(datfile);
diff --git a/PR/src/include/common.h b/PR/src/include/common.h
index b237d9d..bd3fcd2 100644
--- a/PR/src/include/common.h
+++ b/PR/src/include/common.h
@@ -65,7 +65,7 @@ common.h: Princed Resources : Defines and prototypes common to all PR code
 \***************************************************************/
 
 #define PR_URL                    "http://www.princed.com.ar"
-#define PR_VERSION                "v1.0"
+#define PR_VERSION                "v1.1-dev1"
 #define PR_COPY                   "(c) Copyright 2003 - 2005 Princed Development Team"
 
 /***************************************************************\
diff --git a/PR/src/lib/actions/classify.c b/PR/src/lib/actions/classify.c
index 4a6197f..848c6c6 100644
--- a/PR/src/lib/actions/classify.c
+++ b/PR/src/lib/actions/classify.c
@@ -36,6 +36,7 @@ tasks.c: Princed Resources : Classify a DAT file
 #include "memory.h"
 #include "resources.h"
 #include "dat.h"
+#include "disk.h" /* mLoadFileArray */
 #include "common.h"
 
 /***************************************************************\
@@ -55,10 +56,10 @@ int prClassifyDat(const char* vFiledat) {
 	unsigned short int numberOfItems;
 
 	/* Initialize abstract variables to read this new DAT file */
-	if (!mReadBeginDatFile(&numberOfItems,vFiledat)) return -1;
+	if ((id=mReadBeginDatFile(&numberOfItems,vFiledat))) return id+1; /* -1 if not found or empty, 0 if invalid */
 
 	/* main loop */
-	for (indexNumber=0;(indexNumber<numberOfItems)&&(type==RES_TYPE_BINARY);indexNumber++) {
+	for (id=0,indexNumber=0;(indexNumber<numberOfItems)&&(type==RES_TYPE_BINARY);indexNumber++) {
 		id=mReadFileInDatFile(indexNumber,&data,&size);
 		if (id<0) READ_ERROR; /* Read error */
 		if (id==0xFFFF) continue; /* Tammo Jan Bug fix */
@@ -70,3 +71,77 @@ int prClassifyDat(const char* vFiledat) {
 	return pop1?type:(type+10);
 }
 
+typedef struct {
+	unsigned long int checkSum;
+	long size;
+}tExeClassification;
+
+int prClassify(const char* fileName) {
+	int result;
+
+	/* 1) check if it is a dat file */
+	result=prClassifyDat(fileName);
+
+	if (!result) { /* it's not a dat file*/
+		long int fileSize;
+		unsigned char* fileData;
+		
+		/* let's get it's content and see what it is */
+		fileSize=mLoadFileArray(fileName,&fileData);
+		
+		/* 2) let's compare the size with a .sav size */
+		if (fileSize==8) {
+			int framesLeft;
+			/* check that the frames (seconds/12) are in the range [0*12,60*12) */
+			framesLeft=fileData[2]|fileData[3]<<8;
+			if (framesLeft<60*12)
+				result=30; /* sav file */
+		}
+		
+		/* 3) let's compare the size with a .hof size */
+		if (fileSize==176) {
+			int records;
+			/* check that the number of stored records are 6 or less */
+			records=fileData[0]|fileData[1]<<8;
+			if (records<=6) {
+				result=31; /* hof file */
+				while (records) {
+					int framesLeft;
+					/* wrong seconds left format for this record will invalidate the whole file */
+					framesLeft=fileData[29*records-2]|fileData[29*records-1]<<8;
+					if (framesLeft>=60*12) result=0; 
+					records--;
+				}
+			}
+		}
+
+		/* 4) as the last resource, check if it is an exe file */
+		if (!result && fileSize>2 && fileData[0]=='M' && fileData[1]=='Z') {
+			static tExeClassification x[]={
+				/* install.pdm         : 41 */ {717181985,4233},
+				/* prince.exe v1.0 THG : 42 */ {622612442,123335},
+				{0,0}
+			};
+			unsigned long checkSum;
+			int i;
+			result=40; /* generic exe file */
+			/* Now I'll try to recognize some known exe files */
+			/* calculate checksum */
+			for (i=0;i<fileSize;i++) {
+				checkSum+=fileData[i]<<((3-(i%4))*8);
+			}
+			/* printf("{%lu,%ld},\n",checkSum,fileSize); */
+
+			/* compare checksum*/
+			for (i=0;x[i].size;i++)
+				if ((x[i].checkSum==checkSum) && (x[i].size==fileSize)) {
+					result=41+i;
+					break;
+				}
+		}
+		
+		free(fileData);
+	}
+	
+	return result;
+}
diff --git a/PR/src/lib/actions/export.c b/PR/src/lib/actions/export.c
index 52b54e0..941e1cc 100644
--- a/PR/src/lib/actions/export.c
+++ b/PR/src/lib/actions/export.c
@@ -83,7 +83,7 @@ int extract(const char* vFiledat,const char* vDirExt, tResource* r[], int option
 	signed long    int bufferedPalette=0;
 
 	/* Initialize abstract variables to read this new DAT file */
-	if (!mReadBeginDatFile(&numberOfItems,vFiledat)) return -1;
+	if (mReadBeginDatFile(&numberOfItems,vFiledat)) return -1;
 
 	/* Initializes the palette list */
 	initializePaletteList;
diff --git a/PR/src/lib/layers/dat.c b/PR/src/lib/layers/dat.c
index 17f2773..57d05d9 100644
--- a/PR/src/lib/layers/dat.c
+++ b/PR/src/lib/layers/dat.c
@@ -62,16 +62,17 @@ void mReadCloseDatFile() {
 int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 	/*
 		Return Values:
-			0 Wrong Format or file not found
-			1 Ok
+			-1 Wrong Format
+			-2 File not found or empty
+			0 Ok
 	*/
 
 	unsigned char* readDatFilePoint;
 
 	/* Open file */
 	readDatFileSize=mLoadFileArray(vFiledat,&readDatFile);
-	if (!readDatFileSize) return 0;
-	if (readDatFileSize<=6) {free(readDatFile);return 0;}
+	if (!readDatFileSize) return -2;
+	if (readDatFileSize<=6) {free(readDatFile);return -1;}
 
 	readDatFilePoint=readDatFile;
 
@@ -82,7 +83,7 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 
 	if ((indexOffset>readDatFileSize)&&((indexOffset+indexSize)!=readDatFileSize)) {
 		free(readDatFile);
-		return 0; /* this is not a valid prince dat file */
+		return -1; /* this is not a valid prince dat file */
 	}
 
 	indexPointer=readDatFile+indexOffset;
@@ -98,7 +99,7 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 	}
 	recordSize=pop1?8:11;
 
-	return 1;
+	return 0;
 }
 
 int mReadFileInDatFile(int k,unsigned char* *data,unsigned long  int *size) {
@@ -238,7 +239,7 @@ void mWriteCloseDatFile(tResource* r[],int dontSave,int optionflag, const char*
 #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 (mReadBeginDatFile(numberOfItems,vFile)) return -2;
 	if (!mWriteBeginDatFile(vFile,optionflag)) {
 		mReadCloseDatFile();
 		return -1;