~rabbits/orca-toy

1d8b9c64be654a76d837f4a6731f66fca55ed68f — neauoire 9 months ago d2a54b4
Merged font in source
6 files changed, 216 insertions(+), 149 deletions(-)

M build.sh
D font-bold.chr
D font.chr
A nasu-export.chr
M orca.c
M sim.c
M build.sh => build.sh +2 -2
@@ 15,8 15,8 @@ rm -f ./orca
# ./cli demo.orca

# client
# cc -std=c89 -DDEBUG -Wall -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined -L/usr/local/lib -lSDL2 -lportmidi orca.c sim.c -o orca
cc -std=c89 -O2 -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lportmidi orca.c sim.c -o orca
cc -std=c89 -DDEBUG -Wall -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined -L/usr/local/lib -lSDL2 -lportmidi orca.c sim.c -o orca
# cc -std=c89 -O2 -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lportmidi orca.c sim.c -o orca

# Size
echo "Size: $(du -sk ./orca)"

D font-bold.chr => font-bold.chr +0 -0
D font.chr => font.chr +0 -0
A nasu-export.chr => nasu-export.chr +0 -0
M orca.c => orca.c +213 -146
@@ 51,11 51,11 @@ Uint32 theme[] = {
	0xffb545};

Uint8 icons[][8] = {
	{0x86, 0xc6, 0xe6, 0xf6, 0xe6, 0xc6, 0x86, 0x00}, /* play */
	{0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* pause */
	{0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00},
	{0x06, 0x18, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00},
	{0x02, 0x02, 0x04, 0x38, 0x40, 0x80, 0x80, 0x00},
	{0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00}, /* play */
	{0x38, 0x7c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x00}, /* stop */
	{0x86, 0xc6, 0xe6, 0xf6, 0xe6, 0xc6, 0x86, 0x00}, /* step */
	{0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x00, 0x00}, /* bang */
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* null */
	{0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00},
	{0x1e, 0x06, 0x0a, 0x12, 0x20, 0x40, 0x80, 0x00},
	{0x06, 0x18, 0x22, 0x40, 0x42, 0x80, 0xaa, 0x00},


@@ 63,8 63,80 @@ Uint8 icons[][8] = {
	{0x00, 0x38, 0x44, 0x92, 0x28, 0x10, 0x00, 0x00}  /* eye closed */
};

Uint8 font[][8] = {
	{0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00},
	{0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x00},
	{0x00, 0x00, 0x7c, 0x02, 0x3c, 0x40, 0x7e, 0x00},
	{0x00, 0x00, 0x7c, 0x02, 0x7c, 0x02, 0x7c, 0x00},
	{0x00, 0x00, 0x12, 0x22, 0x42, 0x7e, 0x02, 0x00},
	{0x00, 0x00, 0x7e, 0x40, 0x3c, 0x02, 0x7e, 0x00},
	{0x00, 0x00, 0x3e, 0x40, 0x7c, 0x42, 0x3c, 0x00},
	{0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x00},
	{0x00, 0x00, 0x7e, 0x42, 0x3c, 0x42, 0x7e, 0x00},
	{0x00, 0x00, 0x7e, 0x42, 0x3e, 0x02, 0x02, 0x00},
	{0x00, 0x00, 0x7c, 0x02, 0x3e, 0x42, 0x7a, 0x00},
	{0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x7c, 0x00},
	{0x00, 0x00, 0x00, 0x3e, 0x40, 0x40, 0x3e, 0x00},
	{0x00, 0x00, 0x02, 0x02, 0x3e, 0x42, 0x3e, 0x00},
	{0x00, 0x00, 0x3c, 0x42, 0x7c, 0x40, 0x3e, 0x00},
	{0x00, 0x00, 0x3c, 0x42, 0x70, 0x40, 0x40, 0x00},
	{0x00, 0x00, 0x3e, 0x42, 0x3e, 0x02, 0x7c, 0x00},
	{0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00},
	{0x00, 0x00, 0x7e, 0x04, 0x04, 0x44, 0x38, 0x00},
	{0x00, 0x00, 0x42, 0x44, 0x78, 0x44, 0x42, 0x00},
	{0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x3e, 0x00},
	{0x00, 0x00, 0x6c, 0x52, 0x52, 0x52, 0x52, 0x00},
	{0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x1c, 0x22, 0x42, 0x44, 0x38, 0x00},
	{0x00, 0x00, 0x7c, 0x42, 0x7c, 0x40, 0x40, 0x00},
	{0x00, 0x00, 0x3e, 0x42, 0x3e, 0x02, 0x02, 0x00},
	{0x00, 0x00, 0x5c, 0x62, 0x40, 0x40, 0x40, 0x00},
	{0x00, 0x00, 0x3e, 0x40, 0x3c, 0x02, 0x7c, 0x00},
	{0x00, 0x00, 0x7e, 0x10, 0x10, 0x10, 0x08, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x52, 0x52, 0x6c, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x3e, 0x02, 0x7c, 0x00},
	{0x00, 0x00, 0x7e, 0x04, 0x18, 0x20, 0x7e, 0x00},
	{0x00, 0x00, 0x3c, 0x42, 0x7e, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x7c, 0x42, 0x7c, 0x42, 0x7c, 0x00},
	{0x00, 0x00, 0x3e, 0x40, 0x40, 0x40, 0x3e, 0x00},
	{0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x00},
	{0x00, 0x00, 0x7e, 0x40, 0x7e, 0x40, 0x7e, 0x00},
	{0x00, 0x00, 0x7e, 0x40, 0x70, 0x40, 0x40, 0x00},
	{0x00, 0x00, 0x3e, 0x40, 0x5c, 0x42, 0x3e, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00},
	{0x00, 0x00, 0x7e, 0x02, 0x02, 0x42, 0x3c, 0x00},
	{0x00, 0x00, 0x46, 0x48, 0x70, 0x48, 0x46, 0x00},
	{0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00},
	{0x00, 0x00, 0x6e, 0x52, 0x52, 0x52, 0x52, 0x00},
	{0x00, 0x00, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x00},
	{0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00},
	{0x00, 0x00, 0x7e, 0x42, 0x7c, 0x40, 0x40, 0x00},
	{0x00, 0x00, 0x3c, 0x42, 0x4a, 0x44, 0x3a, 0x00},
	{0x00, 0x00, 0x7e, 0x42, 0x7c, 0x42, 0x42, 0x00},
	{0x00, 0x00, 0x3e, 0x40, 0x7e, 0x02, 0x7c, 0x00},
	{0x00, 0x00, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00},
	{0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00},
	{0x00, 0x00, 0x52, 0x52, 0x52, 0x52, 0x6e, 0x00},
	{0x00, 0x00, 0x42, 0x24, 0x18, 0x24, 0x42, 0x00},
	{0x00, 0x00, 0x42, 0x24, 0x10, 0x10, 0x10, 0x00},
	{0x00, 0x00, 0x7e, 0x02, 0x3c, 0x40, 0x7e, 0x00},
	{0x00, 0x00, 0x5a, 0x24, 0x42, 0x24, 0x5a, 0x00},
	{0x00, 0x00, 0x24, 0x7e, 0x24, 0x7e, 0x24, 0x00},
	{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00},
	{0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00},
	{0x00, 0x00, 0x66, 0x5a, 0x24, 0x5a, 0x66, 0x00},
	{0x00, 0x00, 0x00, 0x32, 0x42, 0x4c, 0x00, 0x00},
	{0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};

char clip[1024];
Uint8 font[1200];
Note playing[16];

SDL_Window *gWindow = NULL;


@@ 85,15 157,6 @@ selected(int x, int y)
	return x < cursor.x + cursor.w && x >= cursor.x && y < cursor.y + cursor.h && y >= cursor.y;
}

void
insert(char c)
{
	int x, y;
	for(x = 0; x < cursor.w; ++x)
		for(y = 0; y < cursor.h; ++y)
			set(&g, cursor.x + x, cursor.y + y, c);
}

/* misc */

int


@@ 136,24 199,6 @@ getstyle(int clr, int type, int sel)
	return clr == 0 ? 0 : 3;
}

void
drawtile(Uint32 *dst, int x, int y, char c, int type)
{
	int v, h;
	int sel = selected(x, y);
	int offset = getfont(x, y, c, type, sel) * 8 * 2;
	for(v = 0; v < 8; v++)
		for(h = 0; h < 8; h++) {
			int px = (x * 8) + (8 - h);
			int py = (y * 8) + v;
			int ch1 = font[offset + v];
			int ch2 = font[offset + v + 8];
			int clr = ((ch1 >> h) & 0x1) + ((ch2 << h) & 0x1);
			int key = (py + PAD) * WIDTH + (px + PAD);
			dst[key] = theme[getstyle(clr, type, sel)];
		}
}

int
keypixel(int x, int y)
{


@@ 168,6 213,20 @@ putpixel(Uint32 *dst, int x, int y, int color)
}

void
drawtile(Uint32 *dst, int x, int y, char c, int type)
{
	int v, h;
	int sel = selected(x, y);
	int offset = getfont(x, y, c, type, sel);
	Uint8 *icon = font[offset];
	for(v = 0; v < 8; v++)
		for(h = 0; h < 8; h++) {
			int style = getstyle((icon[v] >> (7 - h)) & 0x1, type, sel);
			putpixel(dst, x * 8 + h, y * 8 + v, style);
		}
}

void
drawicon(Uint32 *dst, int x, int y, Uint8 *icon, int color)
{
	int v, h;


@@ 182,7 241,9 @@ void
drawui(Uint32 *dst)
{
	int bottom = VER * 8 + 8;
	drawicon(dst, 0, bottom, icons[PAUSE == 1 ? 1 : 0], 1);
	drawicon(dst, 0, bottom, icons[0], PAUSE ? 3 : 1);
	drawicon(dst, 8, bottom, icons[2], PAUSE ? 1 : 3);
	drawicon(dst, 8 * 3, bottom, icons[(g.f - 1) % 8 == 0 ? 3 : 4], 2);
}

void


@@ 199,6 260,101 @@ redraw(Uint32 *dst)
	SDL_RenderPresent(gRenderer);
}

/* midi */

int
nteval(int o, char c)
{
	switch(c) {
	case 'A': return 9;
	case 'a': return 10;
	case 'B': return 11;
	case 'b':
	case 'C': return 0;
	case 'c': return 1;
	case 'D': return 2;
	case 'd': return 3;
	case 'E': return 4;
	case 'e':
	case 'F': return 5;
	case 'f': return 6;
	case 'G': return 7;
	case 'g': return 8;
	default:
		if(c >= '0' && c <= '9')
			return c - '0';
		else
			return nteval(o + 12, c - 7);
	}
	return 0;
}

Note *
sendmidi(int chn, int val, int vel, int len)
{
	int i = 0;
	for(i = 0; i < 16; ++i) {
		Note *n = &playing[i];
		if(n->length < 1) {
			n->channel = chn;
			n->value = val;
			n->velocity = vel;
			n->length = len;
			Pm_WriteShort(midi,
				Pt_Time(),
				Pm_Message(0x90 + chn, val, vel * 3));
			return n;
		}
	}
	return NULL;
}

void
parsemidi(char *msg, int msglen)
{
	char chn, oct, nte, vel = 'z', len = '1';
	if(msglen < 3)
		return;
	chn = msg[0];
	oct = msg[1];
	nte = msg[2];
	if(msglen > 3)
		vel = msg[3];
	if(msglen > 4)
		len = msg[4];
	sendmidi(
		base36(chn),
		12 * base36(oct) + nteval(0, nte),
		base36(vel),
		base36(len));
}

void
runmsg(void)
{
	int i, j = 0;
	char buf[128];
	/* release */
	for(i = 0; i < 16; ++i) {
		Note *n = &playing[i];
		if(n->length > 0) {
			n->length--;
			if(n->length == 0)
				Pm_WriteShort(midi,
					Pt_Time(),
					Pm_Message(0x90 + n->channel, n->value, 0));
		}
	}
	/* split messages */
	for(i = 0; i < g.msglen + 1; ++i)
		if(!g.msg[i] || cisp(g.msg[i])) {
			buf[j] = '\0';
			parsemidi(buf, j);
			j = 0;
		} else
			buf[j++] = g.msg[i];
}

/* options */

int


@@ 235,6 391,16 @@ select(int x, int y, int w, int h)
}

void
insert(char c)
{
	int x, y;
	for(x = 0; x < cursor.w; ++x)
		for(y = 0; y < cursor.h; ++y)
			set(&g, cursor.x + x, cursor.y + y, c);
	redraw(pixels);
}

void
move(int x, int y)
{
	select(cursor.x + x, cursor.y + y, cursor.w, cursor.h);


@@ 247,10 413,22 @@ scale(int w, int h)
}

void
frame(void)
{
	rungrid(&g);
	runmsg();
	redraw(pixels);
}

void
selectoption(int option)
{
	switch(option) {
	case 0: setplay(!PAUSE); break;
	case 1:
		setplay(1);
		frame();
		break;
	}
}



@@ 313,101 491,6 @@ moveclip(Rect2d *r, char *c, int x, int y)
	pasteclip(r, c);
}

/* midi */

int
nteval(int o, char c)
{
	switch(c) {
	case 'A': return 9;
	case 'a': return 10;
	case 'B': return 11;
	case 'b':
	case 'C': return 0;
	case 'c': return 1;
	case 'D': return 2;
	case 'd': return 3;
	case 'E': return 4;
	case 'e':
	case 'F': return 5;
	case 'f': return 6;
	case 'G': return 7;
	case 'g': return 8;
	default:
		if(c >= '0' && c <= '9')
			return c - '0';
		else
			return nteval(o + 12, c - 7);
	}
	return 0;
}

Note *
sendmidi(int chn, int val, int vel, int len)
{
	int i = 0;
	for(i = 0; i < 16; ++i) {
		Note *n = &playing[i];
		if(n->length < 1) {
			n->channel = chn;
			n->value = val;
			n->velocity = vel;
			n->length = len;
			Pm_WriteShort(midi,
				Pt_Time(),
				Pm_Message(0x90 + chn, val, vel * 3));
			return n;
		}
	}
	return NULL;
}

void
parsemidi(char *msg, int msglen)
{
	char chn, oct, nte, vel = 'z', len = '1';
	if(msglen < 3)
		return;
	chn = msg[0];
	oct = msg[1];
	nte = msg[2];
	if(msglen > 3)
		vel = msg[3];
	if(msglen > 4)
		len = msg[4];
	sendmidi(
		base36(chn),
		12 * base36(oct) + nteval(0, nte),
		base36(vel),
		base36(len));
}

void
runmsg(void)
{
	int i, j = 0;
	char buf[128];
	/* release */
	for(i = 0; i < 16; ++i) {
		Note *n = &playing[i];
		if(n->length > 0) {
			n->length--;
			if(n->length == 0)
				Pm_WriteShort(midi,
					Pt_Time(),
					Pm_Message(0x90 + n->channel, n->value, 0));
		}
	}
	/* split messages */
	for(i = 0; i < g.msglen + 1; ++i)
		if(!g.msg[i] || cisp(g.msg[i])) {
			buf[j] = '\0';
			parsemidi(buf, j);
			j = 0;
		} else
			buf[j++] = g.msg[i];
}

/* triggers */

void


@@ 574,26 657,12 @@ init(void)
}

int
loadfont(void)
{
	FILE *f = fopen("font.chr", "rb");
	if(f == NULL)
		return error("Font", "Invalid font file");
	if(!fread(font, sizeof(font), 1, f))
		return error("Font", "Invalid font size");
	fclose(f);
	return 1;
}

int
main(int argc, char *argv[])
{
	int ticknext = 0, tickrun = 0;

	if(!init())
		return error("Init", "Failure");
	if(!loadfont())
		return error("Font", "Failure");

	initgrid(&g, HOR, VER);
	select(0, 0, 1, 1);


@@ 612,9 681,7 @@ main(int argc, char *argv[])
		ticknext = tick + (1000 / FPS);

		if(!PAUSE && tickrun >= 8) {
			rungrid(&g);
			runmsg();
			redraw(pixels);
			frame();
			tickrun = 0;
		}
		tickrun++;

M sim.c => sim.c +1 -1
@@ 46,7 46,7 @@ cchr(int v, int cap)
int
valid(Grid *g, int x, int y)
{
	return x >= 0 && x <= g->w - 1 && y >= 0 && y <= g->h;
	return x >= 0 && x <= g->w - 1 && y >= 0 && y <= g->h - 1;
}

int