/*
 *	mkdl -- create a sample dl file
 */

#include <stdio.h>
#include <stdlib.h>		/* for malloc */
#include <string.h>		/* for bzero */
#include <sys/types.h>
#include <sys/time.h>



typedef struct {
	int	version;
	int	format;
	int	images_per_screen;
	char	title[21];
	char	author[21];
	int	num_screen;
	int	num_command;
} DL_info;



int		__default_mode__ = _IOBIN;	/* force stdin binary (gcc) */
char	       *myname = "mkdl";


void		colormap_setup (FILE *, int);



/*------------------------------*/
/*	main			*/
/*------------------------------*/
void main (int argc, char *argv[])
{
	DL_info		dlinfo;		/* dl file info */
	char	       *filename;
	FILE	       *fp;
	unsigned char  *image_data;	/* space for 1 screen from file */
	int	       *cmd;		/* space for command list */
	int		i, j;




	/*
	 *   if no files, use stdin. otherwise open file
	 */
	argv++, argc--;
	if (argc < 1)
	{
		fprintf(stderr, "%s: need file name\n", myname);
		exit(1);
	}
	else if ((fp = fopen (*argv, "wb")) == NULL)
	{
		fprintf(stderr, "%s: can't open %s\n", myname, argv[1]);
		exit(1);
	}
	filename = *argv;



	/*
	 *   set up parameters...
	 */
	dlinfo.version           = 2;
	dlinfo.format            = 1;
	dlinfo.images_per_screen = 4;
	dlinfo.num_screen        = 1;
	dlinfo.num_command       = 16;
	for (i = 0; i < 20; i++)
	{
		dlinfo.title[i]  = 0;
		dlinfo.author[i] = 0;
	}



	/*
	 *   write the version number...
	 */
	fputc (dlinfo.version, fp);

    

	/*
	 *   ...and the format.
	 */
	fputc (dlinfo.format, fp);



	/*
	 *   put title and author
	 */
	for (i = 0; i < 20; i++)
		fputc ((int)(dlinfo.title[i] ^ 255), fp);
	for (i = 0; i < 20; i++)
		fputc ((int)(dlinfo.author[i] ^ 255), fp);
    


	/*
	 *   number of screens and commands.
	 */
	fputc(dlinfo.num_screen, fp);
	fputc(dlinfo.num_command, fp);
    


	/*
	 *   Display what we know so far.
	 */
	printf("%s is a %s sized version %d .DL file.\n",
		filename,
		(dlinfo.format == 0 ? "large" : "medium"), 
		dlinfo.version);
	printf("It contains %d images (num_screen=%d * images_per_screen=%d)\n",
		dlinfo.num_screen * dlinfo.images_per_screen,
		dlinfo.num_screen,
		dlinfo.images_per_screen);
	printf("in a %d frame (num_command) loop.\n",
		dlinfo.num_command);



	/*
	 *   do the color map
	 */
	colormap_setup(fp, dlinfo.version);



	/*
	 *   Allocate memory for the commands, the image data, etc
	 */
	printf ("Allocating memory:\n");

	/* command list: */
	printf ("   command list (%d bytes)\n",
		dlinfo.num_command * sizeof(int));
	if (!(cmd = (int *)malloc(dlinfo.num_command * sizeof(int))))
	{
		fprintf(stderr, "%s: out of memory (commands)", myname);
		exit(1);
	}

	/* one screen (file): */
	printf ("   single screen from file (64000 bytes)\n");
	if (NULL == (image_data = (unsigned char *)malloc(320 * 200)))
	{
		fprintf(stderr, "%s: not enough memory (image data).", myname);
		exit(1);
	}



	/*
	 *   Build the pixmaps for the animation.
	 */
	printf("Building pixmaps, wait..."); fflush(stdout);
	for (j = 0; j < dlinfo.num_screen; j++)
	{
		/*
		 *   image is stored in 'screens' which can have 1 or 4
		 *   images. with 'medium' format in version 2, layout is:
		 *
		 *      0 <-------row------>319
		 *	 _____________________  0
		 *	|          |          | ^
		 *	| screen 0 | screen 1 | |
		 *	|          |          | |
		 *	|__________|__________| col
		 *	|          |          | |
		 *	| screen 2 | screen 3 | |
		 *	|          |          | v
		 *	|__________|__________| 199
		 *
		 *   otherwise there is a single image per screen. we try
		 *   and save space for this test.
		 *
		 *   the image here is just a white vertical bar on a black
		 *   background that moves right in each successive screen.
		 *   the commands will animate it.
		 */
		unsigned char  *dst;
		int		row;
		int		col;

		dst = (unsigned char *) image_data;

		/* set everything black first */
		bzero (dst, (size_t)(320*200));

/* image 0 */	for (row = 30; row < 60; row++)
		{
		  for (col = 20; col < 30; col++)   dst[row*320 + col] = 255;
		}
/* image 1 */	for (row = 30; row < 60; row++)
		{
		  for (col = 185; col < 195; col++) dst[row*320 + col] = 255;
		}
/* image 2 */	for (row = 130; row < 160; row++)
		{
		  for (col = 30; col < 40; col++)   dst[row*320 + col] = 255;
		}
/* image 3 */	for (row = 130; row < 160; row++)
		{
		  for (col = 195; col < 205; col++) dst[row*320 + col] = 255;
		}


		/*
		 *   one screen of data.
		 */
		fwrite(image_data, 1, 320 * 200, fp);

	}
	printf("done\n");



	/*
	 *   write the commands.
	 */
	cmd[0]  = 0;
	cmd[1]  = 1;
	cmd[2]  = 2;
	cmd[3]  = 3;
	cmd[4]  = 2;
	cmd[5]  = 1;
	cmd[6]  = 2;
	cmd[7]  = 3;
	cmd[8]  = 2;
	cmd[9]  = 3;
	cmd[10] = 2;
	cmd[11] = 3;
	cmd[12] = 2;
	cmd[13] = 1;
	cmd[14] = 2;
	cmd[15] = 1;

	for (i = 0; i < dlinfo.num_command; i++)
	{
		if (dlinfo.version == 2)
		{
			fputc(cmd[i], fp);
			fputc(0, fp);		/* as long as number < 255 */
		}
		else
		{
			/*
			 *   unknown???   here is the way it is read:
			 *
			 *	j = fgetc(fp);
			 *	cmd[i] = (j % 10) - 1 + ((j / 10) - 1) * 4;
			 */
			fputc(cmd[i], fp);
		}
	}

	fclose (fp);

	exit (0);
}





/*------------------------------*/
/*	colormap_setup		*/
/*------------------------------*/
void colormap_setup (FILE *fp, int version)
{
	unsigned char	pal[768];
	int		i;


	/*
	 *   set up palette (continuous gray)...
	 */
	for (i = 0; i < 256; i++)
	{
		pal[3*i    ] = i;
		pal[3*i + 1] = i;
		pal[3*i + 2] = i;
	}


	/*
	 *   Is this the border colour? mdl ignores this anyway...
	 */
	if (version == 2)
	{
		for (i = 0; i < 3; i++)
			fputc(0, fp);
	}
	else
		fputc(0, fp);



	/*
	 *   write the colormap. 3 bytes per each of 256 colors.
	 */
	fwrite(pal, 1, 768, fp);

	return;
}



