shithub: cursexp

ref: 044014910f2ffded4bebadbd729d76aa4dea2111
dir: /cursexp.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>

void
usage(void)
{
	fprint(2, "usage: %s [-g] [-c]\n", argv0);
	exits("usage");
}

#define UNPACK(a, n) (((*a)>>n)&0x3)

uchar byte = 0;
uchar num = 0;
uchar numforrow = 0;

void
condwrite(int one)
{
	uchar new = byte<<1 | one;
	byte = new;
	num++;
	if (num == 8) {
		if (numforrow == 0)
			print("\t");
		print("0x%02x,", byte);
		num = 0;
		byte = 0;
		numforrow++;
		if (numforrow != 8)
			print(" ");
	}
	if (numforrow == 8) {
		numforrow = 0;
		print("\n");
	}
}

void
i2c(Memimage *img)
{
	Point pt;
	uchar *b;
	uchar v;
	int x, y;
	
	for (y = 0; y < 16; y++) {
		for (x = 0; x < 4; x++) {
			pt.x = x*4;
			pt.y = y;
			b = byteaddr(img, pt);
			v = UNPACK(b, 6);
			condwrite(v == 3);
			v = UNPACK(b, 4);
			condwrite(v == 3);
			v = UNPACK(b, 2);
			condwrite(v == 3);
			v = UNPACK(b, 0);
			condwrite(v == 3);
		}
	}
	print("\n");
	for (y = 0; y < 16; y++) {
		for (x = 0; x < 4; x++) {
			pt.x = x*4;
			pt.y = y;
			b = byteaddr(img, pt);
			v = UNPACK(b, 6);
			condwrite(v == 0);
			v = UNPACK(b, 4);
			condwrite(v == 0);
			v = UNPACK(b, 2);
			condwrite(v == 0);
			v = UNPACK(b, 0);
			condwrite(v == 0);
		}
	}
}

char hex[] = "0123456789abcdef";
char HEX[] = "0123456789ABCDEF";
char ign[] = " \t\n,";
char Eformat[] = "invalid format";

uchar
readbyte(void)
{
	char buf;
	uchar v = 0;
	int stage = 0;
	char *p;
	ulong nbytes = 0;
	int n;
	
	for (;;) {
		n = read(0, &buf, 1);
		if (n < 0)
			sysfatal("read: %r");
		if (n == 0) {
			fprint(2, "read: eof at %uld\n", nbytes);
			exits("eof");
		}
		nbytes++;
		switch (stage) {
		case 0: /* ign */
			if (buf == '0') {
				stage++;
				break;
			}
			if (strchr(ign, buf))
				break;
			fprint(2, "invalid character: '%c' at %uld\n", buf, nbytes);
			exits(Eformat);
		case 1: /* '0' */
			if (buf == 'x') {
				stage++;
				break;
			}
			goto Errnohex;
		case 2: /* 'x' */
			p = strchr(hex, buf);
			if (!p)
				p = strchr(HEX, buf);
			if (!p)
				goto Errnohex;
			v = ((p-hex)<<4)&0xf0;
			stage++;
			break;
		case 3: /* 'N' */
			p = strchr(hex, buf);
			if (!p)
				p = strchr(HEX, buf);
			if (!p)
				goto Errnohex;
			v |= (p-hex)&0x0f;
			stage++;
			break;
		case 4: /* 'N' */
			return v;
		}
	}
	
Errnohex:
	fprint(2, "invalid format: no valid hex (got '%c' at %uld)\n", buf, nbytes);
	exits(Eformat);
}

void
c2i(void)
{
	Memimage *white, *black, *img;
	int x, y;
	uchar *b;
	uchar r;
	Point pt;
	
	white = allocmemimage(Rect(0, 0, 16, 16), GREY1);
	black = allocmemimage(Rect(0, 0, 16, 16), GREY1);
	img = allocmemimage(Rect(0, 0, 16, 16), GREY2);
	
	for (y = 0; y < 16; y++) {
		for (x = 0; x < 4; x++) {
			pt.x = x*4;
			pt.y = y;
			b = byteaddr(img, pt);
			/* 10 or 01 would both work, but 10 is visually easier to read */
			*b = 0b10101010;
		}
	}
	
	for (y = 0; y < 16; y++) {
		for (x = 0; x < 2; x++) {
			pt.x = x*8;
			pt.y = y;
			r = readbyte();
			b = byteaddr(white, pt);
			*b = r;
		}
	}
	for (y = 0; y < 16; y++) {
		for (x = 0; x < 2; x++) {
			pt.x = x*8;
			pt.y = y;
			r = readbyte();
			b = byteaddr(black, pt);
			*b = r;
		}
	}
	memimagedraw(img, img->r, memwhite, ZP, white, ZP, SatopD);
	memimagedraw(img, img->r, memblack, ZP, black, ZP, SatopD);
	writememimage(1, img);
	freememimage(img);
}

void
gentemplate(void)
{
	Memimage *img;
	
	if (memimageinit())
		sysfatal("%r");
	
	img = allocmemimage(Rect(0, 0, 16, 16), GREY2);
	memfillcolor(img, 0xaaaaaaff);
	writememimage(1, img);
	freememimage(img);
}

void
main(int argc, char **argv)
{
	int gentempl = 0;
	int reverse = 0;
	Memimage *img;
	
	ARGBEGIN {
	case 'h':
		usage();
		break;
	case 'g':
		gentempl++;
		break;
	case 'c':
		reverse++;
		break;
	} ARGEND;
	
	if (memimageinit())
		sysfatal("%r");
	
	if (gentempl) {
		gentemplate();
		exits(nil);
	}
	
	if (reverse) {
		c2i();
		exits(nil);
	}
	
	img = readmemimage(0);
	if (!img)
		sysfatal("invalid image format: %r");
	
	i2c(img);
	exits(nil);
}