#undef FULL_SCREEN		/* def to write entire screen, not just wxh */


/*
 *	file.c - stuff for file operations (flicker file write, etc)
 */

static char *sccsid  = "@(#) file.c 1.0 91/6/15 rosenkra\0\0                ";

#include <stdio.h>
#include <osbind.h>
#include "mgif.h"

#define reg_t		register
#define DBG(x)		/*printf x*/


#define NCHUNK		400
#define FLMAGSZ		10
#define FLHDRSZ		256
#define MAGIC		"FLICKER91a"


/*------------------------------*/
/*	write_fl		*/
/*------------------------------*/
int write_fl (fname, pscrn, w, h)
char   *fname;
int    *pscrn;
int	w;
int	h;
{
	char	       *pbuf;
	register long	i;
	register long	j;
	int		fd;
	int		ival;
	FILE	       *stream;
	char		magic[FLMAGSZ+10];
	char		header[FLHDRSZ+10];
	char	       *pheader;
	char	       *pchar;
	int	       *pint;
	long	       *plong;
	int		nbytes;


	/*
	 *   open the .fl file...
	 */
	if ((stream = fopenb (fname, "w")) == (FILE *) NULL)
	{
		printf ("Error openning %s.\n",
			fname);
		return (0);
	}
	fd = fileno (stream);


	/*
	 *   set up header. start with magic. there is no real header (yet).
	 *   just write nulls in unused portions
	 *
	 *	offset	size	item
	 *	------	----	-----------------------------------------
	 *	0	2	width (pixels)
	 *	2	2	height (pixels)
	 */
	strcpy (magic, MAGIC);
	/* align to word boundary */
	if ((long) (&header[0]) & 1L)	pheader = (char *) (&header[1]);
	else				pheader = (char *) (&header[0]);
	for (i = 0; i < FLHDRSZ; i++)
		pheader[i] = 0;
	if (w > 640)
		w = 640;
	if (h > 400)
		h = 400;
	pint = (int *) (&pheader[0]);	*pint = w;
	pint = (int *) (&pheader[2]);	*pint = h;


	/*
	 *   write .fl header...
	 */
	write (fd, magic, (int) FLMAGSZ);
	write (fd, header, (int) FLHDRSZ);


#ifdef FULL_SCREEN
	/*
	 *   write the screens, sequentially. each screen is 32000 and there
	 *   are 3 screens for a total of 96000 bytes. work with NCHUNK bytes
	 *   at a time.
	 */
	pbuf = (char *) pscrn;
	for (i = 0L; i < 96000L/NCHUNK; i++)	/* number of writes */
	{
		write (fd, pbuf, (int) NCHUNK);

		pbuf += (long) NCHUNK;
	}
#else
	/*
	 *   only write what we need to the file for images smaller than
	 *   the screen...
	 */
	if ((int) w % 8)
		w += 8;
	nbytes = (w >> 3);
	pbuf = (char *) pscrn;
	for (i = 0L; i < h; i++)
	{
		write (fd, pbuf, nbytes);
		pbuf += 80L;
	}

	pbuf = (char *) ((long) pscrn + 32000L);
	for (i = 0L; i < h; i++)
	{
		write (fd, pbuf, nbytes);
		pbuf += 80L;
	}

	pbuf = (char *) ((long) pscrn + 64000L);
	for (i = 0L; i < h; i++)
	{
		write (fd, pbuf, nbytes);
		pbuf += 80L;
	}
#endif

	fclose (stream);

	return (1);
}





/*------------------------------*/
/*	read_fl			*/
/*------------------------------*/
int read_fl (fname, pscrn, w, h)
char   *fname;				/* file name (in) */
int    *pscrn;				/* where to put screen data (out) */
int    *w;				/* size of image, pixels (out) */
int    *h;
{

/*
 *	read the flicker file. return 0 if error else 1.
 */

	reg_t char     *pbuf;
	reg_t int      *pint;
	reg_t int	nbytes;
	reg_t int	nlines;
	reg_t long	ii;
	int		fd;
	FILE	       *stream;
	char		magic[FLMAGSZ+10];
	char		header[FLHDRSZ+10];
	char	       *pheader;


	DBG (("enter read_fl...\n"));

	/*
	 *   open the .fl file, binary...
	 */
	if ((stream = fopenb (fname, "r")) == (FILE *) NULL)
	{
		printf ("Error openning %s.\n", fname);
		return (0);
	}
	fd = fileno (stream);



	/*
	 *   read .fl magic
	 */
	read (fd, magic, (int) FLMAGSZ);
	if (strncmp (magic, MAGIC, 10))
	{
		printf ("Bad magic here...\n");
		fclose (stream);
		return (0);
	}



	/*
	 *   read .fl header:
	 *
	 *	offset	size	item
	 *	------	----	-----------------------------------------
	 *	0	2	width (pixels)
	 *	2	2	height (pixels)
	 */
	if (header & 1)		pheader = (char *) (&header[1]);
	else			pheader = (char *) (&header[0]);

	read (fd, pheader, (int) FLHDRSZ);

	pint = &pheader[0];	*w = *pint;
	pint = &pheader[2];	*h = *pint;



#ifdef FULL_SCREEN
	/*
	 *   read the screens, sequentially. each screen is 32000 and there
	 *   are 3 screens for a total of 96000 bytes. work with NCHUNK bytes
	 *   at a time.
	 */
	pbuf = (char *) pscrn;
	for (ii = 0L; ii < 96000L/NCHUNK; ii++)	/* number of reads */
	{
		read (fd, pbuf, (int) NCHUNK);

		pbuf += (long) NCHUNK;
	}
#else
	/*
	 *   this is space-saver version. we only need the actual pixels,
	 *   not the whole screen saved. find actual byte count for files
	 *   with w not evenly divisible by 8.
	 */
	if ((int) *w % 8)
		nbytes = ((*w + 8) >> 3);
	else
		nbytes = (*w >> 3);
	nlines = *h;

	/* screen 1 */
	for (pbuf = (char *) pscrn, ii = 0L; ii < nlines; ii++)
	{
		read (fd, pbuf, nbytes);
		pbuf += 80L;		/* 640x400 screen has 80 bytes/line */
	}

	/* screen 2 */
	for (pbuf = (char *) ((long) pscrn + 32000L), ii = 0L; ii < nlines; ii++)
	{
		read (fd, pbuf, nbytes);
		pbuf += 80L;
	}

	/* screen 3 */
	for (pbuf = (char *) ((long) pscrn + 64000L), ii = 0L; ii < nlines; ii++)
	{
		read (fd, pbuf, nbytes);
		pbuf += 80L;
	}
#endif


	/*
	 *   done. return success...
	 */
	fclose (stream);
	DBG (("read_fl returning...\n"));

	return (1);
}



