/************************************************************************\
* C64 FLI to portable pixmap converter 26-Sep-92                         *
* By Pasi 'Albert' Ojala ) 1991,1992                                     *
*    po87553@cs.tut.fi  albert@cc.tut.fi                                 *
*                                                                        *
* Compile with SAS/C: lc -. -ctf -L -ba -r -v -y -NODEBUG FLItoppm.c     *
*                                                                        *
* 26-Sep-92	Changed the palette a bit                                    *
*                                                                        *
\************************************************************************/
 
/* #define AMIGA */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef	AMIGA

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/libraries.h>
#include <exec/interrupts.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <proto/dos.h>
#include <proto/exec.h>

#else

typedef unsigned char UBYTE;

#endif
 
char *vers="\0$VER: FLItoppm 1.02 26-Sep-92\n";

UBYTE	gfxmem[8192];
UBYTE	chrmem[8][1024];
UBYTE	colmem[1024];
UBYTE	bgcol[256];

const UBYTE col[16][3]=
{
	0,0,0,
	240,240,240,
	240,0,0,
	0,240,240,
	240,0,240,
	0,240,0,
	0,0,240,
	240,240,64,
	240,128,0,
	128,64,0,
	240,128,128,
	64,64,64,
	128,128,128,
	128,240,128,
	128,128,240,
	192,192,192
};


void Convert(char *name);

void main(int argc,char *argv[])
{	UBYTE temp[10];
	int i=0;
#if AMIGA
	long handle;
#else
	FILE *handle;
#endif

	if(argc==3 || argc==2)
	{
#if AMIGA
		if(handle=Open(argv[1],MODE_OLDFILE))
		{
			Read(handle,temp,2);	/* remove load address */

			Read(handle,bgcol,256);
			Read(handle,colmem,1024);

			Read(handle,chrmem[0],1024);
			Read(handle,chrmem[1],1024);
			Read(handle,chrmem[2],1024);
			Read(handle,chrmem[3],1024);
			Read(handle,chrmem[4],1024);
			Read(handle,chrmem[5],1024);
			Read(handle,chrmem[6],1024);
			Read(handle,chrmem[7],1024);

			i=Read(handle,gfxmem,8192);
			Close(handle);
#else
		if(handle=fopen(argv[1],"rb"))
		{
			fread(temp,2,sizeof(UBYTE),handle);

			fread(bgcol,256,sizeof(UBYTE),handle);
			fread(colmem,1024,sizeof(UBYTE),handle);

			fread(chrmem[0],1024,sizeof(UBYTE),handle);
			fread(chrmem[1],1024,sizeof(UBYTE),handle);
			fread(chrmem[2],1024,sizeof(UBYTE),handle);
			fread(chrmem[3],1024,sizeof(UBYTE),handle);
			fread(chrmem[4],1024,sizeof(UBYTE),handle);
			fread(chrmem[5],1024,sizeof(UBYTE),handle);
			fread(chrmem[6],1024,sizeof(UBYTE),handle);
			i=fread(chrmem[7],1024,sizeof(UBYTE),handle);

			fclose(handle);
#endif
			if(i && argc==2)
			{
				fprintf(stderr,"No output filename - using stdout\n");
				Convert(NULL);
			}
			else
			if(i && argc==3)
				Convert(argv[2]);
			else
				fprintf(stderr,"Short file!\n");
		}
		else
		{	fprintf(stderr,"Could not access %s\n",argv[1]);
			exit(20);
		}
	}
	else
	{	fprintf(stderr,"%s",vers+7);
		fprintf(stderr,"Usage: flitoppm flifile ppmfile\n");
		exit(10);
	}
}


void Convert(char *name)
{	int x,y,ind,pos,bits;
	UBYTE a,b,buffer[3*160];
	const UBYTE bitmask[4]={0xc0,0x30,0x0c,0x03};
	const UBYTE bitshift[4]={0x40,0x10,0x04,0x01};
#ifdef AMIGA
	long handle;
#else
	FILE *handle;
#endif

	fprintf(stderr,"Converting picture\n");
#ifdef AMIGA
	if((!name) || (handle=Open(name,MODE_NEWFILE)))
	{
		if(name)
			Write(handle,"P6\n160 200\n255\n",15);	/* ppm byte-model ident */
#else
	if((!name) || (handle=fopen(name,"wb")))
	{
		if(name)
			fwrite("P6\n160 200\n255\n",15,sizeof(char),handle);
#endif
		else
			fwrite("P6\n160 200\n255\n",15,sizeof(char),stdout);
			
		for(y=0;y<200;y++)
		{	for(x=0;x<160;x++)
			{	ind=x/4+(y/8)*40;			/* color memory index */
				pos=y%8+(x/4)*8+(y/8)*320;	/* grafix memory byte */
				bits=(x%4);					/* bit numbers */

				a=(gfxmem[pos] & bitmask[bits])/bitshift[bits];

				switch(a)
				{	case 0:
						b=bgcol[y+6];
						break;
					case 1:
						b=chrmem[y%8][ind]/16;
						break;
					case 2:
						b=chrmem[y%8][ind]%16;
						break;
					case 3:
						b=colmem[ind]%16;
						break;
				}

				buffer[3*x]=col[b][0];
				buffer[3*x+1]=col[b][1];
				buffer[3*x+2]=col[b][2];
			}
			if(name)
#ifdef AMIGA
				Write(handle,buffer,3*160);
#else
				fwrite(buffer,3*160,sizeof(char),handle);
#endif
			else
				fwrite(buffer,3*160,sizeof(char),stdout);
		}
		if(name)
#ifdef AMIGA
			Close(handle);
#else
			fclose(handle);
#endif
	}
	else
		fprintf(stderr,"Could not open %s\n",name);
}
