~rabbits/nasu

2c8605141da846fcdf226e3c114db22a96558cbd — Devine Lu Linvega 2 years ago 1e36326
Cleanup
2 files changed, 107 insertions(+), 180 deletions(-)

M README.md
M nasu6.c
M README.md => README.md +1 -1
@@ 26,7 26,7 @@ sudo apt-get install libsdl1.2-dev
### Paint

- `mouse1` Paint
- `mouse2` Erase(Color1)
- `mouse1+mouse2` Erase(Color1)

## TODO


M nasu6.c => nasu6.c +106 -179
@@ 2,44 2,32 @@
#include <stdio.h>

#define PAD 32
#define ZOOM 4
#define color1 0x000000
#define color2 0x72DEC2
#define color3 0xFFFFFF
#define color4 0x333333

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

typedef struct Size {
	int w;
	int h;
} Size;

typedef struct Brush {
	int mode;
	int size;
	int erase;
	int color;
	int down;
	int button;
	Point pos;
	Point prev;
} Brush;

/* TODO: Remove globals, set as arg */

static int SCREEN_WIDTH = 512 + PAD * 2;
static int SCREEN_HEIGHT = 512 + PAD * 2;
static int FPS = 30;

unsigned char buffer[1024 * 4];
int ZOOM = 4;
int clr = 0;

uint32_t* pixels;

unsigned char buffer[4096];
int colors[] = {color1, color2, color3, color4};
int WIDTH = 128 * ZOOM + PAD * 2;
int HEIGHT = 128 * ZOOM + PAD * 2;
int FPS = 30;
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
SDL_Texture* gTexture = NULL;

/* helpers */
uint32_t* pixels;

Point*
setpt(Point* p, int x, int y)


@@ 49,120 37,97 @@ setpt(Point* p, int x, int y)
	return p;
}

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

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

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

/* noodle */

void
pixel(uint32_t* dst, Point p, int c)
{
	int x, y;
	mulpt(&p, ZOOM);
	addpt(&p, PAD);
	for(x = 0; x < ZOOM; ++x) {
		for(y = 0; y < ZOOM; ++y) {
			dst[(p.y + y) * SCREEN_WIDTH + (p.x + x)] = c;
		}
	}
	p.x = (p.x * ZOOM) + PAD;
	p.y = (p.y * ZOOM) + PAD;
	for(x = 0; x < ZOOM; ++x)
		for(y = 0; y < ZOOM; ++y)
			dst[(p.y + y) * WIDTH + (p.x + x)] = c;
}

void
paint(uint32_t* dst, int id, int color)
draw(uint32_t* dst, int id, int color)
{
	int ti = id / 64;
	int px = (ti / 256) * 128;
	int py = 0;
	int tx = (ti % 16) * 8;
	int ty = ((ti / 16) * 8) % 128;
	Point p;
	p.x = px + tx + (id % 8);
	p.y = py + ty + ((id % 64) / 8);
	if(color == 1)
		pixel(dst, p, 0x72DEC2);
	else if(color == 2)
		pixel(dst, p, 0xFFFFFF);
	else if(color == 3)
		pixel(dst, p, 0x333333);
	else
		pixel(dst, p, 0x000000);
	p.y = ty + ((id % 64) / 8);
	pixel(dst, p, colors[color]);
}

void
update(void)
redraw(void)
{
	int b, i, j, id = 0, ch1, ch2, color;
	for(b = 0; b < 1024 * 4; b += 16)
	for(b = 0; b < 4096; 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);
				paint(pixels, id, color);
				draw(pixels, id, color);
				id++;
			}
}

void
write(int tx, int ty, int px, int py)
write(int tx, int ty, int px, int py, int color)
{
	int id = tx + ty * 16;
	int pid = px + py * 8;
	int row = id * 16 + py;

	if(clr == 0) {
	int row = py + id * 16;
	if(id > 255)
		return;
	if(color == 0) {
		buffer[row] &= ~(1UL << (7 - px));
		buffer[row + 8] &= ~(1UL << (7 - px));
	} else if(clr == 2) {
	} else if(color == 2) {
		buffer[row] |= 1UL << (7 - px);
		buffer[row + 8] &= ~(1UL << (7 - px));
	} else if(clr == 1) {
	} else if(color == 1) {
		buffer[row] &= ~(1UL << (7 - px));
		buffer[row + 8] |= 1UL << (7 - px);
	} else if(clr == 3) {
	} else if(color == 3) {
		buffer[row] |= 1UL << (7 - px);
		buffer[row + 8] |= 1UL << (7 - px);
	}

	update();
}

void
edit(Point* p)
edit(Brush* b)
{
	int tx, ty, px, py;
	Point aligned;
	addpt(setpt(&aligned, p->x, p->y), -PAD);
	if(aligned.x < 0 || aligned.y < 0 || aligned.x > 8 * 16 * ZOOM || aligned.y > 8 * 16 * ZOOM)
	Point p1;
	setpt(&p1, b->pos.x - PAD, b->pos.y - PAD);
	if(p1.x < 0 || p1.y < 0 || p1.x > 8 * 16 * ZOOM || p1.y > 8 * 16 * ZOOM)
		return;
	write(
	    p1.x / (8 * ZOOM),
	    p1.y / (8 * ZOOM),
	    (p1.x / ZOOM) % 8,
	    (p1.y / ZOOM) % 8,
	    b->color);
	redraw();
}

	/* convert screen to texture pos */
	tx = aligned.x / (8 * ZOOM);
	ty = aligned.y / (8 * ZOOM);
	px = (aligned.x / ZOOM) % 8;
	py = (aligned.y / ZOOM) % 8;
	write(tx, ty, px, py);
void
erase(Brush* b)
{
	int i, id;
	Point p1;
	setpt(&p1, b->pos.x - PAD, b->pos.y - PAD);
	if(p1.x < 0 || p1.y < 0 || p1.x > 8 * 16 * ZOOM || p1.y > 8 * 16 * ZOOM)
		return;
	id = (p1.x / (8 * ZOOM)) + (p1.y / (8 * ZOOM)) * 16;
	for(i = 0; i < 8; ++i) {
		buffer[(id * 16) + i] = 0x00;
		buffer[(id * 16) + i + 8] = 0x00;
	}
	redraw();
}

void export(uint32_t* dst)


@@ 170,8 135,6 @@ void export(uint32_t* dst)
	/* TODO: chr file export */
}

/* SDL */

int
error(char* msg, const char* err)
{


@@ 179,52 142,6 @@ error(char* msg, const char* err)
	return 0;
}

int
init_array(void)
{
	int i, j;
	pixels = (uint32_t*)malloc(SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(uint32_t));

	if(pixels == NULL)
		return error("init_array", "could not allocate memory for pixels");

	for(i = 0; i < SCREEN_HEIGHT; i++)
		for(j = 0; j < SCREEN_WIDTH; j++)
			pixels[i * SCREEN_WIDTH + j] = 0x000000;

	return 1;
}

int
init(void)
{
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		return error("init", SDL_GetError());

	gWindow = SDL_CreateWindow("nasu6", SDL_WINDOWPOS_UNDEFINED,
	                           SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
	                           SCREEN_HEIGHT, SDL_WINDOW_SHOWN);

	if(gWindow == NULL)
		return error("window", SDL_GetError());

	gRenderer = SDL_CreateRenderer(gWindow, -1, 0);

	if(gRenderer == NULL)
		return error("renderer", SDL_GetError());

	gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888,
	                             SDL_TEXTUREACCESS_STATIC, SCREEN_WIDTH,
	                             SCREEN_HEIGHT);

	if(gTexture == NULL)
		return error("texture", SDL_GetError());

	init_array();

	return 1;
}

void
quit(void)
{


@@ 247,56 164,41 @@ handle_mouse(SDL_Event* event, Brush* b)
		if(event->button.button == SDL_BUTTON_LEFT)
			b->down = 0;
		if(event->button.button == SDL_BUTTON_RIGHT)
			b->erase = 0;
		setpt(&b->prev, 0, 0);
			erase(b);
		break;
	case SDL_MOUSEBUTTONDOWN:
		if(event->button.button == SDL_BUTTON_LEFT)
			b->down = 1;
		if(event->button.button == SDL_BUTTON_RIGHT)
			b->erase = 1;
		setpt(&b->prev, event->motion.x, event->motion.y);
	case SDL_MOUSEMOTION:
		if(b->down) {
			setpt(&b->pos, event->motion.x, event->motion.y);
			edit(&b->pos);
			setpt(&b->prev, b->pos.x, b->pos.y);

			/*
			
			addpt(&b->pos, -PAD);
			divpt(&b->pos, ZOOM);
			pixel(pixels, b->pos, 0xFFFFFF);
			setpt(&b->prev, b->pos.x, b->pos.y);
			*/
			edit(b);
		}
		break;
	}
}

void
handle_keypress(SDL_Event* event, Brush* b, Point* o)
handle_keypress(SDL_Event* event, Brush* b)
{
	switch(event->key.keysym.sym) {
	case SDLK_ESCAPE:
		quit();
		break;
	/* I/O */
	case SDLK_e:
		export(pixels);
		break;
	/* Mode */
	case SDLK_1:
		clr = 0;
		b->color = 0;
		break;
	case SDLK_2:
		clr = 1;
		b->color = 1;
		break;
	case SDLK_3:
		clr = 2;
		b->color = 2;
		break;
	case SDLK_4:
		clr = 3;
		b->color = 3;
		break;
	}
}


@@ 306,7 208,40 @@ load(FILE* f)
{
	if(!fread(buffer, sizeof(buffer), 1, f))
		return error("Invalid size file", "");
	update();
	redraw();
	return 1;
}

int
init(void)
{
	int i, j;
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		return error("init", SDL_GetError());
	gWindow = SDL_CreateWindow("nasu6",
	                           SDL_WINDOWPOS_UNDEFINED,
	                           SDL_WINDOWPOS_UNDEFINED,
	                           WIDTH,
	                           HEIGHT,
	                           SDL_WINDOW_SHOWN);
	if(gWindow == NULL)
		return error("window", SDL_GetError());
	gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
	if(gRenderer == NULL)
		return error("renderer", SDL_GetError());
	gTexture = SDL_CreateTexture(gRenderer,
	                             SDL_PIXELFORMAT_ARGB8888,
	                             SDL_TEXTUREACCESS_STATIC,
	                             WIDTH,
	                             HEIGHT);
	if(gTexture == NULL)
		return error("texture", SDL_GetError());
	pixels = (uint32_t*)malloc(WIDTH * HEIGHT * sizeof(uint32_t));
	if(pixels == NULL)
		return error("pixels", "failed to allocate memory");
	for(i = 0; i < HEIGHT; i++)
		for(j = 0; j < WIDTH; j++)
			pixels[i * WIDTH + j] = 0x000000;
	return 1;
}



@@ 315,11 250,10 @@ main(int argc, char** argv)
{
	int ticknext = 0;
	Brush brush;
	Point offset;
	FILE* f;

	if(!init())
		return error("Could not initialize SDL", "");
		return error("SDL", "failure");

	if(argc < 2)
		return error("Missing input file", "");


@@ 331,37 265,30 @@ main(int argc, char** argv)

	load(f);

	/* main game loop */
	/* main loop */

	while(1) {

		int tick = SDL_GetTicks();
		SDL_Event event;

		if(SDL_QUIT == event.type)
			exit(0);

		if(event.type == SDL_QUIT)
			quit();
		if(tick < ticknext)
			SDL_Delay(ticknext - tick);

		ticknext = tick + (1000 / FPS);

		SDL_UpdateTexture(gTexture, NULL, pixels, SCREEN_WIDTH * sizeof(uint32_t));

		SDL_UpdateTexture(gTexture, NULL,
		                  pixels, WIDTH * sizeof(uint32_t));
		while(SDL_PollEvent(&event) != 0) {
			if(event.type == SDL_MOUSEBUTTONUP ||
			   event.type == SDL_MOUSEBUTTONDOWN ||
			   event.type == SDL_MOUSEMOTION) {
				handle_mouse(&event, &brush);
			} else if(event.type == SDL_KEYDOWN) {
				handle_keypress(&event, &brush, &offset);
			}
			} else if(event.type == SDL_KEYDOWN)
				handle_keypress(&event, &brush);
		}
		SDL_RenderClear(gRenderer);
		SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
		SDL_RenderPresent(gRenderer);
	}

	quit();
	return 0;
}