~rabbits/orca-toy

c1af5c018ec6f0c8c9b729d3233f0d326eea8cf9 — rekkabell 2 years ago 1e27cf9 + 880a122
Merge branch 'master' of git.sr.ht:~rabbits/orca-toy
4 files changed, 266 insertions(+), 123 deletions(-)

M README.md
M font.chr
M sim.c
M toy.c
M README.md => README.md +18 -2
@@ 45,6 45,22 @@ To display the list of operators inside of Orca, use `CmdOrCtrl+G`.
- `4` port(right)
- `5` port(output)

## TODOs
## Notes

- Default values
### SDL Mod Codes

```
KMOD_NONE = 0x0000,
KMOD_LSHIFT = 0x0001,
KMOD_RSHIFT = 0x0002,
KMOD_LCTRL = 0x0040,
KMOD_RCTRL = 0x0080,
KMOD_LALT = 0x0100,
KMOD_RALT = 0x0200,
KMOD_LGUI = 0x0400,
KMOD_RGUI = 0x0800,
KMOD_NUM = 0x1000,
KMOD_CAPS = 0x2000,
KMOD_MODE = 0x4000,
KMOD_RESERVED = 0x8000
```

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

int


@@ 183,9 183,15 @@ opb(Grid *g, int x, int y, char c)
void
opc(Grid *g, int x, int y, char c)
{
	char mod = getport(g, x + 1, y, 0);
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, cchr(g->f / rate % mod, ciuc(mod)));
	int mod_ = cint(mod);
	int rate_ = cint(rate);
	if(!rate_)
		rate_ = 1;
	if(!mod_)
		mod_ = 8;
	setport(g, x, y + 1, cchr(g->f / rate_ % mod_, ciuc(mod)));
	(void)c;
}



@@ 193,37 199,50 @@ void
opd(Grid *g, int x, int y, char c)
{
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, g->f % (rate * mod) == 0 ? '*' : '.');
	char mod = getport(g, x + 1, y, 0);
	int rate_ = cint(rate);
	int mod_ = cint(mod);
	if(!rate_)
		rate_ = 1;
	if(!mod_)
		mod_ = 8;
	setport(g, x, y + 1, g->f % (rate_ * mod_) == 0 ? '*' : '.');
	(void)c;
}

void
ope(Grid *g, int x, int y, char c)
{
	if(x == g->w || get(g, x + 1, y) != '.')
	if(!valid(g, x + 1, y) || get(g, x + 1, y) != '.')
		set(g, x, y, '*');
	else {
		set(g, x, y, '.');
		settype(g, x, y, 0);
		setport(g, x + 1, y, c);
		lock(g, x + 1, y);
	}
}

void
opf(Grid *g, int x, int y, char c)
{
	setport(g, x, y + 1, getport(g, x - 1, y, 0) == getport(g, x + 1, y, 1) ? '*' : '.');
	char a = getport(g, x - 1, y, 0);
	char b = getport(g, x + 1, y, 1);
	setport(g, x, y + 1, a == b ? '*' : '.');
	(void)c;
}

void
opg(Grid *g, int x, int y, char c)
{
	int tx = cint(getport(g, x - 3, y, 0));
	int ty = cint(getport(g, x - 2, y, 0));
	int i, len = cint(getport(g, x - 1, y, 0));
	for(i = 0; i < len; ++i)
		setport(g, x + i + tx, y + 1 + ty, getport(g, x + 1 + i, y, 1));
	char px = getport(g, x - 3, y, 0);
	char py = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		setport(g, x + i + cint(px), y + 1 + cint(py), getport(g, x + 1 + i, y, 1));
	(void)c;
}



@@ 237,18 256,24 @@ oph(Grid *g, int x, int y, char c)
void
opi(Grid *g, int x, int y, char c)
{
	char step = getport(g, x - 1, y, 0);
	char rate = getport(g, x - 1, y, 0);
	char mod = getport(g, x + 1, y, 1);
	char val = getport(g, x, y + 1, 1);
	setport(g, x, y + 1, cchr((cint(val) + cint(step)) % (cint(mod) || 1), ciuc(mod)));
	int rate_ = cint(rate);
	int mod_ = cint(mod);
	if(!rate_)
		rate_ = 1;
	if(!mod_)
		mod_ = 36;
	setport(g, x, y + 1, cchr((cint(val) + rate_) % mod_, ciuc(mod)));
	(void)c;
}

void
opj(Grid *g, int x, int y, char c)
{
	int i;
	char link = getport(g, x, y - 1, 0);
	int i;
	if(link != c) {
		for(i = 1; y + i < g->h; ++i)
			if(get(g, x, y + i) != c)


@@ 260,12 285,14 @@ opj(Grid *g, int x, int y, char c)
void
opk(Grid *g, int x, int y, char c)
{
	int i, len = cint(getport(g, x - 1, y, 0));
	for(i = 0; i < len; ++i) {
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i) {
		char key = getport(g, x + 1 + i, y, 1);
		if(key == '.')
			continue;
		setport(g, x + 1 + i, y + 1, load(g, key));
		if(key != '.')
			setport(g, x + 1 + i, y + 1, load(g, key));
	}
	(void)c;
}


@@ 291,43 318,51 @@ opm(Grid *g, int x, int y, char c)
void
opn(Grid *g, int x, int y, char c)
{
	if(y == 0 || get(g, x, y - 1) != '.')
	if(!valid(g, x, y - 1) || get(g, x, y - 1) != '.')
		set(g, x, y, '*');
	else {
		set(g, x, y, '.');
		settype(g, x, y, 0);
		setport(g, x, y - 1, c);
		lock(g, x, y - 1);
	}
}

void
opo(Grid *g, int x, int y, char c)
{
	int tx = cint(getport(g, x - 2, y, 0));
	int ty = cint(getport(g, x - 1, y, 0));
	setport(g, x, y + 1, getport(g, x + 1 + tx, y + ty, 1));
	char px = getport(g, x - 2, y, 0);
	char py = getport(g, x - 1, y, 0);
	setport(g, x, y + 1, getport(g, x + 1 + cint(px), y + cint(py), 1));
	(void)c;
}

void
opp(Grid *g, int x, int y, char c)
{
	int key = cint(getport(g, x - 2, y, 0));
	int i, len = cint(getport(g, x - 1, y, 0));
	/* TODO */
	for(i = 0; i < len; ++i)
	char key = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	char val = getport(g, x + 1, y, 1);
	int i, len_ = cint(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		lock(g, x + i, y + 1);
	setport(g, x + (key % len), y + 1, get(g, x + 1, y));
	setport(g, x + (cint(key) % len_), y + 1, val);
	(void)c;
}

void
opq(Grid *g, int x, int y, char c)
{
	int tx = cint(getport(g, x - 3, y, 0));
	int ty = cint(getport(g, x - 2, y, 0));
	int i, len = cint(getport(g, x - 1, y, 0));
	for(i = 0; i < len; ++i)
		setport(g, x + 1 - len + i, y + 1, getport(g, x + 1 + tx + i, y + ty, 1));
	char px = getport(g, x - 3, y, 0);
	char py = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + cint(px) + i, y + cint(py), 1));
	(void)c;
}



@@ 343,22 378,27 @@ opr(Grid *g, int x, int y, char c)
void
ops(Grid *g, int x, int y, char c)
{
	if(y == g->h || get(g, x, y + 1) != '.')
	if(!valid(g, x, y + 1) || get(g, x, y + 1) != '.')
		set(g, x, y, '*');
	else {
		set(g, x, y, '.');
		setport(g, x, y + 1, c);
		settype(g, x, y, 0);
		set(g, x, y + 1, c);
		lock(g, x, y + 1);
	}
}

void
opt(Grid *g, int x, int y, char c)
{
	int key = cint(getport(g, x - 2, y, 0));
	int i, len = cint(getport(g, x - 1, y, 0));
	for(i = 0; i < len; ++i)
	char key = getport(g, x - 2, y, 0);
	char len = getport(g, x - 1, y, 0);
	int i, len_ = cint(len);
	if(!len_)
		len_ = 1;
	for(i = 0; i < len_; ++i)
		lock(g, x + 1 + i, y);
	setport(g, x, y + 1, getport(g, x + 1 + (key % len), y, 1));
	setport(g, x, y + 1, getport(g, x + 1 + (cint(key) % len_), y, 1));
	(void)c;
}



@@ 387,28 427,31 @@ opv(Grid *g, int x, int y, char c)
void
opw(Grid *g, int x, int y, char c)
{
	if(x == 0 || get(g, x - 1, y) != '.')
	if(!valid(g, x - 1, y) || get(g, x - 1, y) != '.')
		set(g, x, y, '*');
	else {
		set(g, x, y, '.');
		settype(g, x, y, 0);
		setport(g, x - 1, y, c);
		lock(g, x - 1, y);
	}
}

void
opx(Grid *g, int x, int y, char c)
{
	int tx = cint(getport(g, x - 2, y, 0));
	int ty = cint(getport(g, x - 1, y, 0));
	setport(g, x + tx, y + ty + 1, getport(g, x + 1, y, 1));
	char px = getport(g, x - 2, y, 0);
	char py = getport(g, x - 1, y, 0);
	char val = getport(g, x + 1, y, 1);
	setport(g, x + cint(px), y + cint(py) + 1, val);
	(void)c;
}

void
opy(Grid *g, int x, int y, char c)
{
	int i;
	char link = getport(g, x - 1, y, 0);
	int i;
	if(link != c) {
		for(i = 1; x + i < g->w; ++i)
			if(get(g, x + i, y) != c)


@@ 420,12 463,13 @@ opy(Grid *g, int x, int y, char c)
void
opz(Grid *g, int x, int y, char c)
{
	int rate = cint(getport(g, x - 1, y, 0));
	char rate = getport(g, x - 1, y, 0);
	char target = getport(g, x + 1, y, 1);
	char val = cint(getport(g, x, y + 1, 1));
	int t = cint(target);
	int mod = val < t ? rate : val > t ? -rate : 0;
	setport(g, x, y + 1, cchr(val + mod, ciuc(target)));
	char val = getport(g, x, y + 1, 1);
	int rate_ = cint(rate);
	int target_ = cint(target);
	int val_ = cint(val);
	setport(g, x, y + 1, cchr(val_ + val_ < target_ ? rate_ : val_ > target_ ? -rate_ : 0, ciuc(target)));
	(void)c;
}



@@ 458,6 502,7 @@ opspecial(Grid *g, int x, int y)
void
operate(Grid *g, int x, int y, char c)
{
	settype(g, x, y, 3);
	switch(clca(c)) {
	case 'a': opa(g, x, y, c); break;
	case 'b': opb(g, x, y, c); break;


@@ 489,7 534,6 @@ operate(Grid *g, int x, int y, char c)
	case '#': opcomment(g, x, y); break;
	default: opspecial(g, x, y);
	}
	settype(g, x, y, 3);
}

/* General */


@@ 529,6 573,8 @@ run(Grid *g)
		y = i / g->w;
		if(c == '.' || g->lock[i])
			continue;
		if(cinu(c))
			continue;
		if(cilc(c) && !bang(g, x, y))
			continue;
		operate(g, x, y, c);

M toy.c => toy.c +151 -70
@@ 5,12 5,12 @@
#define HOR 32
#define VER 16
#define PAD 8
#define ZOOM 1
#define ZOOM 2
#define color1 0x000000
#define color2 0x72DEC2
#define color3 0x888888
#define color4 0xFFFFFF
#define color0 0x222222
#define color3 0xFFFFFF
#define color4 0x444444
#define color0 0xffb545

#define PLIMIT 256
#define SZ (HOR * VER * 16)


@@ 23,7 23,7 @@ typedef struct {
	int x, y, w, h;
} Rect2d;

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


@@ 36,7 36,6 @@ SDL_Texture *gTexture = NULL;
uint32_t *pixels;

Rect2d selection;

Grid g;

Point2d


@@ 56,36 55,27 @@ clampt(Point2d p, int step)
	return p;
}

void
select(int x, int y, int w, int h)
int
clamp(int val, int min, int max)
{
	selection.x = x;
	selection.y = y;
	selection.w = w;
	selection.h = h;
	draw(pixels);
	return (val >= min) ? (val <= max) ? val : max : min;
}

int
selected(int x, int y)
{
	return selection.x == x && selection.y == y;
	return x < selection.x + selection.w && x >= selection.x && y < selection.y + selection.h && y >= selection.y;
}

void
move(int x, int y)
insert(char c)
{
	int reqdraw = 0;
	if((x < 0 && selection.x > 0) || (x > 0 && selection.x < HOR - 1)) {
		selection.x += x;
		reqdraw = 1;
	}
	if((y < 0 && selection.y > 0) || (y > 0 && selection.y < VER - 1)) {
		selection.y += y;
		reqdraw = 1;
	int x, y;
	for(x = 0; x < selection.w; ++x) {
		for(y = 0; y < selection.h; ++y) {
			set(&g, selection.x + x, selection.y + y, c);
		}
	}
	if(reqdraw)
		draw(pixels);
}

/* misc */


@@ 102,20 92,65 @@ guide(int x, int y)
	return 0;
}

int
getfont(int x, int y, char c, int type, int sel)
{
	if(c >= 'A' && c <= 'Z')
		return c - 'A' + 36;
	if(c >= 'a' && c <= 'z')
		return c - 'a' + 10;
	if(c >= '0' && c <= '9')
		return c - '0';
	if(c == '*')
		return 62;
	if(c == '#')
		return 63;
	if(c == ':')
		return 65;
	if(x % 8 == 0 && y % 8 == 0)
		return 68;
	if(c == '.' && type)
		return 64;
	if(c == '.' && !sel)
		return 70;
	if(selection.x == x && selection.y == y)
		return 66;
	if(sel)
		return 64;
	return 70;
}

int
getstyle(int clr, int type, int sel)
{
	if(sel)
		return colors[clr == 0 ? 4 : 0];
	if(type == 2)
		return colors[clr == 0 ? 0 : 1];
	if(type == 3)
		return colors[clr == 0 ? 1 : 0];
	if(type == 4)
		return colors[clr == 0 ? 0 : 2];
	if(type == 5)
		return colors[clr == 0 ? 2 : 0];
	return colors[clr == 0 ? 0 : 3];
}

void
drawtile(uint32_t *dst, int x, int y, char c, int type)
{
	int v, h;
	int target = 0;
	int sel = selected(x, y);
	int offset = getfont(x, y, c, type, sel) * 8 * 2;
	for(v = 0; v < 8; v++)
		for(h = 7; h >= 0; h--) {
			int px = (x * 8) + h;
		for(h = 0; h < 8; h++) {
			int px = (x * 8) + (8 - h);
			int py = (y * 8) + v;
			int ch1 = font[v];
			int ch2 = font[v + 8];
			int clr = ((ch1 >> h) & 0x1) + (((ch2 >> h) & 0x1) << 1);
			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] = selected(x, y) ? colors[(clr + 1) % 5] : colors[clr];
			dst[key] = getstyle(clr, type, sel);
		}
}



@@ 132,6 167,36 @@ draw(uint32_t *dst)
	SDL_RenderPresent(gRenderer);
}

void
select(int x, int y, int w, int h)
{
	selection.x = x;
	selection.y = y;
	selection.w = w;
	selection.h = h;
	draw(pixels);
}

void
move(int x, int y)
{
	selection.x += x;
	selection.y += y;
	selection.x = clamp(selection.x, 0, HOR);
	selection.y = clamp(selection.y, 0, VER);
	draw(pixels);
}

void
scale(int w, int h)
{
	selection.w += w;
	selection.h += h;
	selection.w = clamp(selection.w, 1, 8);
	selection.h = clamp(selection.h, 1, 8);
	draw(pixels);
}

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


@@ 164,17 229,15 @@ domouse(SDL_Event *event)
{
	Point2d touch = clampt(
		Pt2d(
			(event->motion.x - (PAD * ZOOM)) / ZOOM,
			(event->motion.y - (PAD * ZOOM)) / ZOOM),
			(event->motion.x - (PAD * ZOOM) - (8 * ZOOM / 2)) / ZOOM,
			(event->motion.y - (PAD * ZOOM) - (8 * ZOOM / 2)) / ZOOM),
		8);
	switch(event->type) {
	case SDL_MOUSEBUTTONUP:
		printf("mouse-up\n");
		select(selection.x, selection.y, touch.x / 8 - selection.x + 1, touch.y / 8 - selection.y + 1);
		break;
	case SDL_MOUSEBUTTONDOWN:
		printf("%d,%d\n", touch.x / 8, touch.y / 8);
		select(touch.x / 8, touch.y / 8, 1, 1);
		printf("mouse-down\n");
		break;
	case SDL_MOUSEMOTION:
		break;


@@ 184,29 247,55 @@ domouse(SDL_Event *event)
void
dokey(SDL_Event *event)
{
	int shift = SDL_GetModState() & KMOD_LSHIFT || SDL_GetModState() & KMOD_RSHIFT;
	switch(event->key.keysym.sym) {
	case SDLK_s:
		set(&g, selection.x, selection.y, 'S');
		break;
	case SDLK_0:
		set(&g, selection.x, selection.y, '0');
		break;
	case SDLK_UP:
		move(0, -1);
		printf("up\n");
		break;
	case SDLK_DOWN:
		move(0, 1);
		printf("down\n");
		break;
	case SDLK_LEFT:
		move(-1, 0);
		printf("left\n");
		break;
	case SDLK_RIGHT:
		move(1, 0);
		printf("right\n");
		break;
	case SDLK_BACKSPACE: insert('.'); break;
	case SDLK_ASTERISK: insert('*'); break;
	case SDLK_HASH: insert('#'); break;
	case SDLK_PERIOD: insert('.'); break;
	case SDLK_COLON: insert(':'); break;
	case SDLK_SEMICOLON: insert(':'); break;
	case SDLK_ESCAPE: select(selection.x, selection.y, 1, 1); break;
	case SDLK_0: insert('0'); break;
	case SDLK_1: insert('1'); break;
	case SDLK_2: insert('2'); break;
	case SDLK_3: insert(shift ? '#' : '3'); break;
	case SDLK_4: insert('4'); break;
	case SDLK_5: insert('5'); break;
	case SDLK_6: insert('6'); break;
	case SDLK_7: insert('7'); break;
	case SDLK_8: insert('8'); break;
	case SDLK_9: insert('9'); break;
	case SDLK_a: insert(shift ? 'A' : 'a'); break;
	case SDLK_b: insert(shift ? 'B' : 'b'); break;
	case SDLK_c: insert(shift ? 'C' : 'c'); break;
	case SDLK_d: insert(shift ? 'D' : 'd'); break;
	case SDLK_e: insert(shift ? 'E' : 'e'); break;
	case SDLK_f: insert(shift ? 'F' : 'f'); break;
	case SDLK_g: insert(shift ? 'G' : 'g'); break;
	case SDLK_h: insert(shift ? 'H' : 'h'); break;
	case SDLK_i: insert(shift ? 'I' : 'i'); break;
	case SDLK_j: insert(shift ? 'J' : 'j'); break;
	case SDLK_k: insert(shift ? 'K' : 'k'); break;
	case SDLK_l: insert(shift ? 'L' : 'l'); break;
	case SDLK_m: insert(shift ? 'M' : 'm'); break;
	case SDLK_n: insert(shift ? 'N' : 'n'); break;
	case SDLK_o: insert(shift ? 'O' : 'o'); break;
	case SDLK_p: insert(shift ? 'P' : 'p'); break;
	case SDLK_q: insert(shift ? 'Q' : 'q'); break;
	case SDLK_r: insert(shift ? 'R' : 'r'); break;
	case SDLK_s: insert(shift ? 'S' : 's'); break;
	case SDLK_t: insert(shift ? 'T' : 't'); break;
	case SDLK_u: insert(shift ? 'U' : 'u'); break;
	case SDLK_v: insert(shift ? 'V' : 'v'); break;
	case SDLK_w: insert(shift ? 'W' : 'w'); break;
	case SDLK_x: insert(shift ? 'X' : 'x'); break;
	case SDLK_y: insert(shift ? 'Y' : 'y'); break;
	case SDLK_z: insert(shift ? 'Z' : 'z'); break;
	case SDLK_UP: shift ? scale(0, -1) : move(0, -1); break;
	case SDLK_DOWN: shift ? scale(0, 1) : move(0, 1); break;
	case SDLK_LEFT: shift ? scale(-1, 0) : move(-1, 0); break;
	case SDLK_RIGHT: shift ? scale(1, 0) : move(1, 0); break;
	}
	/* update(); */
}


@@ 217,7 306,7 @@ init(void)
	int i, j;
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		return error("Init", SDL_GetError());
	gWindow = SDL_CreateWindow("Toy",
	gWindow = SDL_CreateWindow("Orca",
		SDL_WINDOWPOS_UNDEFINED,
		SDL_WINDOWPOS_UNDEFINED,
		WIDTH * ZOOM,


@@ 247,7 336,6 @@ init(void)
int
loadfont(void)
{
	int i;
	FILE *f = fopen("font.chr", "rb");
	if(f == NULL)
		return error("Font", "Invalid input file");


@@ 269,14 357,7 @@ main(int argc, char *argv[])
		return error("Font", "Failure");

	create(&g, HOR, VER);
	set(&g, 3, 3, 'S');
	set(&g, 3, 6, 'A');
	set(&g, 4, 6, 'a');
	set(&g, 7, 2, '0');
	set(&g, 8, 7, '0');
	run(&g);

	select(0, 0, 0, 0);
	select(0, 0, 1, 1);
	draw(pixels);

	while(1) {


@@ 286,7 367,7 @@ main(int argc, char *argv[])
			SDL_Delay(ticknext - tick);
		ticknext = tick + (1000 / FPS);

		if(tickrun == 10) {
		if(tickrun == 8) {
			run(&g);
			draw(pixels);
			tickrun = 0;