~rabbits/nasu

3e07ed8216ca27ea47dc0fa10b5bbefa97563ec5 — Devine Lu Linvega 2 years ago 5f24efe
Cleanup
1 files changed, 63 insertions(+), 95 deletions(-)

M nasu.c
M nasu.c => nasu.c +63 -95
@@ 3,7 3,7 @@

#define HOR 32
#define VER 16
#define PAD 16
#define PAD 8
#define ZOOM 4
#define color1 0x000000
#define color2 0x72DEC2


@@ 13,20 13,15 @@

#define SZ (HOR * VER * 16)

typedef struct Point {
	int x;
	int y;
} Point;

typedef struct Brush {
	int x, y;
	int px, py;
	int mode;
	int size;
	int color;
	int down;
	int edit;
	int mode;
	int size;
	int erase;
	Point pos;
	Point prev;
} Brush;

char* modes[] = {


@@ 39,7 34,7 @@ char* modes[] = {
    "exes",
    "fixe"};

unsigned char buffer[SZ];
unsigned char chrbuf[SZ];
int colors[] = {color1, color2, color3, color4, color0};
int WIDTH = 8 * HOR + PAD * 2;
int HEIGHT = 8 * VER + PAD * 2;


@@ 50,47 45,33 @@ SDL_Renderer* gRenderer = NULL;
SDL_Texture* gTexture = NULL;
uint32_t* pixels;

Point*
setpt(Point* p, int x, int y)
{
	p->x = x;
	p->y = y;
	return p;
}

int
dispt(Point* a, Point* b)
{
	return (b->x - a->x) * (b->x - a->x) + (b->y - a->y) * (b->y - a->y);
}

void
pixel(uint32_t* dst, int x, int y, int c)
distance(int ax, int ay, int bx, int by)
{
	dst[(y + PAD) * WIDTH + (x + PAD)] = c;
	return (bx - ax) * (bx - ax) + (by - ay) * (by - ay);
}

void
draw(uint32_t* dst, int id, int color)
edit(uint32_t* dst, int id, int color)
{
	int ti = id / 64;
	int odd = (ti + (ti / HOR + 2)) % 2 == 0;
	int px = (ti / (HOR * VER)) * (8 * HOR) + (ti % HOR) * 8 + (id % 8);
	int py = ((ti / HOR) * 8) + ((id % 64) / 8);
	pixel(dst, px, py, colors[GUIDES && odd && color == 0 ? 4 : color]);
	dst[(py + PAD) * WIDTH + (px + PAD)] = colors[GUIDES && odd && color == 0 ? 4 : color];
}

void
redraw(uint32_t* dst)
{
	int b, i, j, id = 0, ch1, ch2, color;
	int b, i, j, id = 0;
	for(b = 0; b < SZ; b += 16)
		for(i = 0; i < 8; i++)
			for(j = 7; j >= 0; j--) {
				ch1 = buffer[b + i];
				ch2 = buffer[b + i + 8];
				color = ((ch1 >> j) & 0x1) + (((ch2 >> j) & 0x1) << 1);
				draw(dst, id, color);
				int ch1 = chrbuf[b + i];
				int ch2 = chrbuf[b + i + 8];
				int color = ((ch1 >> j) & 0x1) + (((ch2 >> j) & 0x1) << 1);
				edit(dst, id, color);
				id++;
			}
	SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(uint32_t));


@@ 100,39 81,43 @@ redraw(uint32_t* dst)
}

int
row(int x, int y)
{
	return (y % 8) + ((x / 8 + y / 8 * HOR) * 16);
}

int
get(int x, int y)
{
	int ch1, ch2;
	int id = (x / 8) + (y / 8) * HOR;
	int row = (y % 8) + (id * 16);
	int r = row(x, y);
	int px = x % 8;
	if(row < 0 || row > SZ - 8)
	if(r < 0 || r > SZ - 8)
		return 0;
	ch1 = (buffer[row] >> (7 - px)) & 1;
	ch2 = (buffer[row + 8] >> (7 - px)) & 1;
	ch1 = (chrbuf[r] >> (7 - px)) & 1;
	ch2 = (chrbuf[r + 8] >> (7 - px)) & 1;
	return ch1 && !ch2 ? 1 : !ch1 && ch2 ? 2 : ch1 && ch2 ? 3 : 0;
}

void
put(int x, int y, int color)
{
	int id = (x / 8) + (y / 8) * HOR;
	int row = (y % 8) + (id * 16);
	int r = row(x, y);
	int px = x % 8;
	if(x < 0 || y < 0 || x > 8 * HOR || y > 8 * VER || row > SZ - 8)
	if(x < 0 || y < 0 || x > 8 * HOR || y > 8 * VER || r > SZ - 8)
		return;
	if(color == 0) {
		buffer[row] &= ~(1UL << (7 - px));
		buffer[row + 8] &= ~(1UL << (7 - px));
		chrbuf[r] &= ~(1UL << (7 - px));
		chrbuf[r + 8] &= ~(1UL << (7 - px));
	} else if(color == 2) {
		buffer[row] |= 1UL << (7 - px);
		buffer[row + 8] &= ~(1UL << (7 - px));
		chrbuf[r] |= 1UL << (7 - px);
		chrbuf[r + 8] &= ~(1UL << (7 - px));
	} else if(color == 1) {
		buffer[row] &= ~(1UL << (7 - px));
		buffer[row + 8] |= 1UL << (7 - px);
		chrbuf[r] &= ~(1UL << (7 - px));
		chrbuf[r + 8] |= 1UL << (7 - px);
	} else if(color == 3) {
		buffer[row] |= 1UL << (7 - px);
		buffer[row + 8] |= 1UL << (7 - px);
		chrbuf[r] |= 1UL << (7 - px);
		chrbuf[r + 8] |= 1UL << (7 - px);
	}
}



@@ 174,57 159,42 @@ patt(int x, int y, int mode, int size)
}

void
fill(int mode, int size, Point p0, int color)
fill(int x, int y, int mode, int size, int color)
{
	int x, y;
	Point p;
	for(x = -size / 2; x < size; ++x)
		for(y = -size / 2; y < size; ++y) {
			setpt(&p, p0.x + x, p0.y + y);
			if(patt(p.x, p.y, mode, size) && dispt(&p0, &p) < size)
				put(p.x, p.y, color);
		}
	int ox, oy;
	for(ox = x - (size / 2); ox < x + size; ++ox)
		for(oy = y - (size / 2); oy < y + size; ++oy)
			if(mode == 7 && jagg(ox, oy))
				put(ox, oy, 0);
			else if(patt(ox, oy, mode, size) && distance(x, y, ox, oy) < size)
				put(ox, oy, color);
	redraw(pixels);
}

void
line(Point* p0, Point* p1, int color)
line(int ax, int ay, int bx, int by, int color)
{
	int dx = abs(p1->x - p0->x), sx = p0->x < p1->x ? 1 : -1;
	int dy = -abs(p1->y - p0->y), sy = p0->y < p1->y ? 1 : -1;
	int dx = abs(bx - ax), sx = ax < bx ? 1 : -1;
	int dy = -abs(by - ay), sy = ay < by ? 1 : -1;
	int err = dx + dy, e2;
	for(;;) {
		put(p0->x, p0->y, color);
		if(p0->x == p1->x && p0->y == p1->y)
		put(ax, ay, color);
		if(ax == bx && ay == by)
			break;
		e2 = 2 * err;
		if(e2 >= dy) {
			err += dy;
			p0->x += sx;
			ax += sx;
		}
		if(e2 <= dx) {
			err += dx;
			p0->y += sy;
			ay += sy;
		}
	}
	redraw(pixels);
}

void
fixe(int size, Point p0)
{
	int x, y;
	Point p;
	for(x = -size / 2; x < size; ++x)
		for(y = -size / 2; y < size; ++y) {
			setpt(&p, p0.x + x, p0.y + y);
			if(jagg(p.x, p.y))
				put(p.x, p.y, 0);
		}
	redraw(pixels);
}

void
update(Brush* b)
{
	char title[512];


@@ 251,7 221,7 @@ create(void)
{
	int i;
	for(i = 0; i < SZ; ++i)
		buffer[i] = 0x00;
		chrbuf[i] = 0x00;
	redraw(pixels);
}



@@ 259,7 229,7 @@ void
save(Brush* b)
{
	FILE* f = fopen("export.chr", "wb");
	if(!fwrite(buffer, sizeof(buffer), 1, f))
	if(!fwrite(chrbuf, sizeof(chrbuf), 1, f))
		error("Save", "Invalid output file");
	fclose(f);
	b->edit = 0;


@@ 271,7 241,7 @@ load(char* path)
	FILE* f = fopen(path, "rb");
	if(f == NULL)
		error("Load", "Invalid input file");
	if(!fread(buffer, sizeof(buffer), 1, f))
	if(!fread(chrbuf, sizeof(chrbuf), 1, f))
		error("Load", "Invalid input size");
	fclose(f);
	redraw(pixels);


@@ 313,7 283,8 @@ domouse(SDL_Event* event, Brush* b)
	case SDL_MOUSEBUTTONUP:
		if(event->button.button == SDL_BUTTON_LEFT) {
			b->down = 0;
			setpt(&b->prev, 0, 0);
			b->px = 0;
			b->py = 0;
		}
		if(event->button.button == SDL_BUTTON_RIGHT)
			b->erase = 0;


@@ 323,24 294,21 @@ domouse(SDL_Event* event, Brush* b)
	case SDL_MOUSEBUTTONDOWN:
		if(event->button.button == SDL_BUTTON_LEFT) {
			b->down = 1;
			setpt(&b->prev,
			      (event->motion.x - (PAD * ZOOM)) / ZOOM,
			      (event->motion.y - (PAD * ZOOM)) / ZOOM);
			b->px = (event->motion.x - (PAD * ZOOM)) / ZOOM;
			b->py = (event->motion.y - (PAD * ZOOM)) / ZOOM;
		}
		if(event->button.button == SDL_BUTTON_RIGHT)
			b->erase = 1;
	case SDL_MOUSEMOTION:
		if(b->down) {
			setpt(&b->pos,
			      (event->motion.x - (PAD * ZOOM)) / ZOOM,
			      (event->motion.y - (PAD * ZOOM)) / ZOOM);
			b->x = (event->motion.x - (PAD * ZOOM)) / ZOOM;
			b->y = (event->motion.y - (PAD * ZOOM)) / ZOOM;
			if(b->mode == 0)
				line(&b->prev, &b->pos, b->erase ? 0 : b->color);
			else if(b->mode == 7)
				fixe(b->size, b->pos);
				line(b->px, b->py, b->x, b->y, b->erase ? 0 : b->color);
			else
				fill(b->mode, b->size, b->pos, b->erase ? 0 : b->color);
			setpt(&b->prev, b->pos.x, b->pos.y);
				fill(b->x, b->y, b->mode, b->size, b->erase ? 0 : b->color);
			b->px = b->x;
			b->py = b->y;
		}
		break;
	}