// Font for ATX81

#include <stdio.h>
#include <windows.h>

#pragma warning(disable : 4996) // warning - fopen may be unsafe

#define SPRITEW	8 // sprite width (in pixels)
#define SPRITEH 8 // sprite height (in lines)

unsigned char* Img = NULL; // input file buffer
int W,H; // input file width and height
unsigned char* D; // start of image data

#pragma pack(push,1)
typedef struct _bmpBITMAPFILEHEADER { // size
		WORD	bfType;			// 0:
		DWORD	bfSize;			// 2:
		WORD	bfReserved1;	// 6:
		WORD	bfReserved2;	// 8:
		DWORD	bfOffBits;		// 0x0a:
} bmpBITMAPFILEHEADER;

typedef struct _bmpBITMAPINFOHEADER{
		DWORD	biSize;			// 0x0e:
		long	biWidth;		// 0x12:
		long	biHeight;		// 0x16:
		WORD	biPlanes;		// 0x1a:
		WORD	biBitCount;		// 0x1c:
		DWORD	biCompression;	// 0x1e:
		DWORD	biSizeImage;	// 0x22:
		long	biXPelsPerMeter; // 0x26:
		long	biYPelsPerMeter; // 0x2a:
		DWORD	biClrUsed;		// 0x2e:
		DWORD	biClrImportant; // 0x32:
} bmpBITMAPINFOHEADER; // 0x36:
#pragma pack(pop)

#define bmpBI_RGB	0
#define bmpBI_RLE8	1
#define bmpBI_RLE4	2

int main(int argc, char* argv[])
{
	// check syntax
	if (argc != 3)
	{
		printf("Syntax: input_file output_file\n");
		return 1;
	}

	// open input file
	FILE* f = fopen(argv[1], "rb");
	if (f == NULL)
	{
		printf("Error opening %s\n", argv[1]);
		return 1;
	}

	// size of input file
	fseek(f, 0, SEEK_END);
	int size = ftell(f);
	fseek(f, 0, SEEK_SET);
	if (size < 40)
	{
		printf("Incorrect size of %s\n", argv[1]);
		return 1;
	}

	// create buffer
	Img = (unsigned char*)malloc(size);
	if (Img == NULL)
	{
		printf("Memory error\n");
		return 1;
	}

	// read file
	int size2 = (int)fread(Img, 1, size, f);
	fclose(f);
	if (size2 != size)
	{
		printf("Error reading %s\n", argv[1]);
		return 1;
	}

	// check BMP header
	bmpBITMAPFILEHEADER* bmf = (bmpBITMAPFILEHEADER*)Img;
	bmpBITMAPINFOHEADER* bmi = (bmpBITMAPINFOHEADER*)&bmf[1];
	W = bmi->biWidth;
	H = bmi->biHeight;
	if (H < 0) H = -H;
	if ((bmf->bfType != 0x4d42) ||
		(bmf->bfOffBits != 0x3e) ||
		(W < 8) || (W > 10000) || (H < 1) || (H > 10000) ||
		(bmi->biBitCount != 1))
	{
		printf("Incorrect format of input file %s,\n", argv[1]);
		printf("  must be 1-bit uncompressed.\n");
		return 1;
	}
	D = &Img[bmf->bfOffBits];

	// open output file
	f = fopen(argv[2], "wb");
	if (f == NULL)
	{
		printf("Error creating %s\n", argv[2]);
		return 1;
	}

	// load sprites
	int num = (W+7)/8;
	fprintf(f, "; %u sprites\n", num);
	int i, j;
	unsigned char* s = D;
	for (j = 0; j < H; j++) // lines
	{
		fprintf(f, "\n; line %u", j+1);
		for (i = 0; i < num; i++) // bytes on the line
		{
			if ((i & 0xf) == 0)
				fprintf(f, "\n\t.byte\t");
			else
				fprintf(f, ",");

			fprintf(f, "0x%02X", s[0]);
			s++;
		}
		fprintf(f, "\n");
	}
	fprintf(f, "\n");

	fclose(f);
	free(Img);

	return 0;
}

