#include <stdio.h>
#include <malloc.h>

typedef         unsigned char   BYTE;
typedef         unsigned int    WORD;
typedef         unsigned long   DWORD;

#define         NO_ARGS         -1
#define         BAD_FILENAME    -2
#undef          DEBUG

typedef         struct FCINFO
		{
		    char filename[16];
		    long offset,
			 filesize;
		} FCINFO;

void main(int argc, char *argv[])
{
    FILE *infile, *outfile;
    int  i;
    long bytesleft, numfiles;
    BYTE *buffer;
    FCINFO *myptr;

    printf("%c[2J",27);
    printf("     Data file extractor for Future Crew demos\n");
    printf("       Written by Patch - hamell@cs.pdx.edu\n");
    printf("              Coder for Avalanche\n");
    printf("Call Dead Man's Hand - 503.288.9264 - USR 16.8k DS\n");
    printf("          Grafx/sound programming only\n");
    printf("ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");

    if (argc < 2)
    {
	printf("Usage: FCDEMOEX filename.exe\n");
	printf("example: FISHTRO.EXE is from Fishtro\n");
	printf("         UNREAL.EXE  is from Unreal\n");
	printf("         PANIC.EXE   is from Panic\n");
	exit(NO_ARGS);
    }

    infile = fopen(argv[1],"rb");
    if (infile == NULL)
    {
	printf("Can't find %s!\n",argv[1]);
	exit(BAD_FILENAME);
    }

    // set to spot that holds byte offset in file where data starts
    fseek(infile,-4,SEEK_END);
    fread(& bytesleft, 4, 1, infile);

    // seek to start of file data to get # of files present
    fseek(infile,bytesleft + 4,0);
    fread(& numfiles, 4, 1, infile);

    // skip over something ... don't know what it is
    fseek(infile, 4, 1);

    // allocate space for the struct info
    myptr = (FCINFO *) malloc((WORD) (sizeof(FCINFO) * numfiles));

    // read in all of the data
    for (i = 0; i < numfiles; i++)
	fread(& myptr[i], 1, sizeof(FCINFO), infile);

    #ifdef DEBUG
	for (i = 0; i < numfiles; i++)
	{
	    printf("[%s] [%ld] [%ld]\n",
		   myptr[i].filename, myptr[i].offset, myptr[i].filesize);
	    getch();
	}
    #endif

    // allocate a buffer space
    buffer = (BYTE *) malloc((WORD) 64000);

    // loop and rip the info out
    for (i = 0; i < numfiles; i++)
    {
	outfile = fopen(myptr[i].filename,"wb");

	fseek(infile, myptr[i].offset, 0);
	bytesleft = myptr[i].filesize;
	printf("Reading %12s, %7lu bytes ",
	       myptr[i].filename, myptr[i].filesize);

        while (bytesleft > 0)
        {
	    fread(buffer, 1,
	      (WORD) (bytesleft > 64000 ? 64000 : bytesleft),infile);
	    fwrite(buffer, 1,
	       (WORD) (bytesleft > 64000 ? 64000 : bytesleft),outfile);
            printf(".");
            bytesleft -= 64000;
        }

        printf(" done writing.\n");
        fclose(outfile);
    }

    free(buffer);
    free(myptr);
    fclose(infile);
}
