
/* This program takes a .XBM as produced by xv(1) and turns it
 * into Z80 source. 
 *
 * The comments it adds to the Z80 source are controlled by the second 
 * argument -- "64" for a 64-column Spectrum font, "32" for an 8x8 PCW font.
 *
 * Seriously rewritten for ZXZVM v1.11:
 *  - Added the font type argument, so it gets the comments right.
 *  - Correctly handles XBM files generated by the GIMP.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int width, height;
int mode = 0;
char buf[90];
int byte[20];

int mirror(int c)
{
	int d, n;
	for (n = d = 0; n < 8; n++)
	{
		d = d << 1;
		if (c & 1) d |= 1;
		c = c >> 1;
	}
	return d;

}

int scan_commas(char *s)
{
	int n,c;
	char *s1 = s;
	int l = strlen(s);

	for (n = c = 0; (n < l && s[n] != '\n'); ++n)
	{
		if (s[n] == ',' || s[n] == '}')
		{
			if (sscanf(s1," 0x%02x,", &byte[c]))
			{
				++c;
				s1 = s + n + 1;
			}
			else if (sscanf(s1, " 0x%02x", &byte[c]))
			{
				++c;
				s1 = s + n;
			}
		}
	}
	return c;
}



int main(int argc, char **argv)
{
	int ch;
       	int step;
	int count, cur;
	int c = 0, b;
	int lc = 0;
	char * s;
	FILE *fp;

 	if (argc < 3)
	{
		fprintf(stderr, "Syntax: %s fontfile {64 | 32}\n", argv[0]);
		return EXIT_FAILURE;
	}
	mode = atoi(argv[2]);

	fp = fopen(argv[1], "r");
	if (!fp)
	{
		perror(argv[1]);
		return EXIT_FAILURE;
	}
	fgets(buf, 90, fp); printf(";%s", buf);	/* 1st line */
	s = strstr(buf, "_width");
	if (s) width = atoi(s + 7);
	fgets(buf, 90, fp); printf(";%s", buf); /* 2nd line */
	s = strstr(buf, "_height");
	if (s) height = atoi(s + 7);
	fgets(buf, 90, fp); printf(";%s", buf); /* 3rd line */

	cur = 0;
	count = (width*height) / 8;
	switch(mode)
	{
		case 64: ch = 32; step = 6; break; 
		case 32: ch = 0; step = 8; break;
	}
	do
	{
		s = fgets(buf, 90, fp);
		if (!s) continue;
		b = scan_commas(buf);
		if (lc == 0) printf("\tDEFB\t");	
		for (c = 0; c < b; c++)
		{
			cur++;
			printf("0%02xh",mirror(byte[c]));
			++lc;
			if (lc == step || lc == 2*step) 
			{
				switch(mode)
				{
					case 64:
					if (ch < 126) printf("\t;%c %c", 
							ch, ch+1);
					else	      printf("\t;%02x %02x", 
							ch, ch+1);
					ch+=2;
					break;

					case 32: 
					if (ch >= 32 && ch < 127)
							printf("\t;%c", ch);
					else		printf("\t;%02x", ch);		
					ch++;
					break;
				}
				if (cur < count) printf("\n\tDEFB\t");	
				lc = step;
			}
			else /*if (c < (b-1)) */printf(", ");
		}
	} while (s);

	printf("\n;\n");

	fclose(fp);

	return 0;
}
