summaryrefslogtreecommitdiff
path: root/jeu-test/lemmings_level_designer_source/tap2lem.c
diff options
context:
space:
mode:
Diffstat (limited to 'jeu-test/lemmings_level_designer_source/tap2lem.c')
-rw-r--r--jeu-test/lemmings_level_designer_source/tap2lem.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/jeu-test/lemmings_level_designer_source/tap2lem.c b/jeu-test/lemmings_level_designer_source/tap2lem.c
new file mode 100644
index 0000000..0d8c827
--- /dev/null
+++ b/jeu-test/lemmings_level_designer_source/tap2lem.c
@@ -0,0 +1,223 @@
+/* TAP2LEM.C: convert a .TAP file containing Lemmings levels to pairs
+ of .LEM and .BMP files
+ Copyright (c) 1997,9 Philip Kendall
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Author contact information:
+
+ E-mail: pak21@cam.ac.uk (until at least June 2002)
+ Postal address: 15 Crescent Road, Wokingham, Berks, RG40 2DB, England
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *InFName="lemmings.tap";
+const unsigned LevelLen=8405;
+const char *OutFBase="level";
+const char *OutFExt1=".lem";
+const char *OutFExt2=".bmp";
+#define OutFLen 13
+#define BufLen 256
+const unsigned BMPHeight=128;
+const unsigned BMPWidth=512;
+
+const unsigned char BMPHeader[] = {
+
+0x42,0x4D,0x3E,0x20,0x00,0x00,0x00,0x00,
+0x00,0x00,0x3E,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,
+0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xFF,0xFF,0xFF,0x00
+
+};
+
+const unsigned BMPHeaderLen=sizeof(BMPHeader)/sizeof(unsigned char);
+
+int DoLevel(FILE *f);
+unsigned int ReadInt(FILE *f);
+unsigned long ReadLong(FILE *f);
+
+int main(int argc,char **argv)
+{FILE *f;
+
+ if(argc<2) {fprintf(stderr,"Syntax: tap2lem tapefile\n"); return 4;}
+
+ f=fopen(argv[1],"rb");
+ if(ferror(f))
+ {fprintf(stderr,"Error opening %s for input\n",argv[1]); return 1;}
+
+ while( !feof(f) && !ferror(f) ) if(DoLevel(f)) {fclose(f); return 2;}
+
+ if(ferror(f))
+ {fprintf(stderr,"Error reading from %s\n",InFName); fclose(f);
+ return 3;
+ }
+
+ fclose(f);
+
+ return 0;
+}
+
+int DoLevel(FILE *f)
+{unsigned Length,Good=0,i;
+ unsigned char ch,HLevel,*LevelData,CheckSum,OutFName[OutFLen],
+ OutFName2[OutFLen],Buffer[BufLen];
+ FILE *f2;
+
+ LevelData=(unsigned char*)malloc(LevelLen);
+ if(!LevelData)
+ {fprintf(stderr,"Not enough memory for LevelData\n"); return 1;}
+
+ /* For a Lemmings level, we're looking for a block of length 3 followed block
+ of length 8407
+ */
+
+ while(!Good && !feof(f) && !ferror(f))
+ {
+ /* If the first block doesn't have length 3, get the next block */
+ if((Length=ReadInt(f))!=3)
+ {if(!feof(f) && !ferror(f)) fseek(f,Length,SEEK_CUR); continue;}
+
+ /* If the flag byte isn't 00h (header), get the next block */
+ if((ch=fgetc(f))!=0)
+ {if(!feof(f) && !ferror(f)) fseek(f,2,SEEK_CUR); continue;}
+
+ /* Get the level number as stored in the header, and the checksum */
+ HLevel=fgetc(f); ch=fgetc(f);
+
+ /* See if the next block has the right length; if it has, assume we have
+ a Lemmings level */
+ if((Length=ReadInt(f))!=LevelLen+2)
+ {if(!feof(f) && !ferror(f)) fseek(f,Length,SEEK_CUR); continue;}
+
+ /* If header checksum is wrong, print a warning */
+ if(ch!=HLevel)
+ fprintf(stderr,"Warning: header checksum for level %u is wrong\n",
+ (unsigned)HLevel );
+
+ /* Read in the level data's flag byte, and give up if it is not 0xff */
+ if((ch=fgetc(f))!=0xff)
+ {if(!feof(f) && !ferror(f)) fseek(f,LevelLen+1,SEEK_CUR); continue;}
+
+ /* Read in the level data */
+ fread(LevelData,LevelLen,1,f);
+
+ /* Finally, read in the checksum */
+ CheckSum=fgetc(f); ch=0xff;
+ for(i=0;i<LevelLen;i++) ch^=LevelData[i];
+ if(ch!=CheckSum)
+ fprintf(stderr,"Warning: data checksum for level %u is wrong\n",
+ (unsigned)LevelData[0] );
+
+ /* And say we're happy with this level */
+ Good=1;
+
+ }
+
+ /* If we didn't find anything, return */
+ if(!Good) {free(LevelData); return 0;}
+
+ /* If the two level numbers don't match up, print a warning */
+ if(HLevel!=LevelData[0])
+ fprintf(stderr,"Warning: level numbers specified in header and in data"
+ "differ\n In header: %u\n In data: %u\nUsing %u\n",
+ (unsigned)HLevel,(unsigned)LevelData[0],(unsigned)LevelData[0] );
+
+ /* Set up the output filenames */
+ strcpy(OutFName,OutFBase);
+ if(LevelData[0]<10) strcat(OutFName,"0");
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x00]);
+ strcat(OutFName,Buffer); strcpy(OutFName2,OutFName);
+ strcat(OutFName,OutFExt1); strcat(OutFName2,OutFExt2);
+
+ /* Open the .LEM file */
+ f2=fopen(OutFName,"wt");
+ if(ferror(f2))
+ {fprintf(stderr,"Error opening %s for output\n",OutFName);
+ free(LevelData); return 2;
+ }
+
+ /* Buffer already contains the text version of the level number */
+ strcat(Buffer,","); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x14]); /* Rating */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x01]); /* Number of lemmings */
+ strcat(Buffer,","); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x10]); /* Number to save */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x02]); /* Initial release rate */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x06]+1); /* Time/minutes */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ for(i=0x07;i<=0x0e;i++) /* Skills */
+ {sprintf(Buffer,"%u",(unsigned)LevelData[i]);
+ strcat(Buffer,(i==0x0e?"\n":",")); fputs(Buffer,f2);
+ }
+ fwrite(&LevelData[0x15],32,1,f2); fputc('\n',f2); /* Level name */
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x04]*0x100+LevelData[0x03]);
+ strcat(Buffer,","); fputs(Buffer,f2); /* Trapdoor X */
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x05]); /* Trapdoor Y */
+ strcat(Buffer,","); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x12]*0x100+LevelData[0x11]);
+ strcat(Buffer,","); fputs(Buffer,f2); /* Home X */
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x13]); /* Home Y */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[0x0f]); /* Colours */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ for(i=0x35;i<0x5d;i+=4) /* Hazards */
+ {sprintf(Buffer,"%u",(unsigned)LevelData[i]); /* Type */
+ strcat(Buffer,","); fputs(Buffer,f2);
+ sprintf(Buffer,"%u",(unsigned)LevelData[i+2]*0x100+LevelData[i+1]);
+ strcat(Buffer,","); fputs(Buffer,f2); /* X */
+ sprintf(Buffer,"%u",(unsigned)LevelData[i+3]); /* Y */
+ strcat(Buffer,"\n"); fputs(Buffer,f2);
+ }
+ fputs(OutFName2,f2); /* .BMP file name */
+
+ fclose(f2);
+
+ /* Open the .BMP file */
+ f2=fopen(OutFName2,"wb");
+ if(ferror(f2))
+ {fprintf(stderr,"Error opening %s for output\n",OutFName2);
+ free(LevelData); return 3;
+ }
+
+ /* Write out the .BMP header */
+ for(i=0;i<BMPHeaderLen;i++) fputc(BMPHeader[i],f2);
+
+ /* And the data */
+ for(i=1;i<=BMPHeight;i++)
+ fwrite(&LevelData[0xd5+(BMPHeight-i)*(BMPWidth/8)],(BMPWidth/8),1,f2);
+
+ fclose(f2);
+
+ free(LevelData);
+
+ return 0;
+
+}
+
+unsigned ReadInt(FILE *f) {return fgetc(f)+fgetc(f)*0x100;}
+
+unsigned long ReadLong(FILE *f)
+{return fgetc(f)+fgetc(f)*0x100+fgetc(f)*0x10000+fgetc(f)*0x1000000;}