M build.sh => build.sh +1 -5
@@ 1,12 1,8 @@
#!/bin/bash
-clang-format -i sim.c
-clang-format -i sim.h
-clang-format -i cli.c
clang-format -i orca.c
## Cleanup
-rm -f ./cli
rm -f ./orca
# cli
@@ 16,7 12,7 @@ rm -f ./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 -O2 -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lportmidi orca.c -o orca
# Size
echo "Size: $(du -sk ./orca)"
D cli.c => cli.c +0 -75
@@ 1,75 0,0 @@
-#include <stdio.h>
-#include "sim.h"
-
-int
-error(char *name)
-{
- printf("Error: %s\n", name);
- return 0;
-}
-
-void
-printgrid(Grid *g)
-{
- /* TODO: only print once, merge into a single buf */
- int x, y, i = 0;
- for(y = 0; y < g->h; ++y)
- for(x = 0; x < g->w; ++x) {
- putchar(get(g, x, y));
- if(x == g->w - 1)
- putchar('\n');
- }
- putchar('\n');
- for(y = 0; y < g->h; ++y)
- for(x = 0; x < g->w; ++x) {
- printf("%d", gettype(g, x, y));
- if(x == g->w - 1)
- putchar('\n');
- }
- putchar('\n');
- while(g->msg[i])
- putchar(g->msg[i++]);
- putchar('\n');
-}
-
-int
-opengrid(Grid *g, FILE *f)
-{
- char c;
- g->l = 0;
- while((c = fgetc(f)) != EOF && g->l < MAXSZ) {
- if(c == '\n') {
- if(g->w == 0)
- g->w = g->l;
- g->h = g->l / g->w;
- } else {
- g->type[g->l] = 0;
- g->data[g->l++] = c;
- }
- }
- return g->w > 2 && g->h > 2;
-}
-
-int
-main(int argc, char *argv[])
-{
- FILE *f;
- int limit = 3;
- Grid g;
- g.w = 0;
- g.h = 0;
- g.f = 0;
- g.r = 1;
- if(argc < 2)
- return error("No input.");
- f = fopen(argv[1], "r");
- if(!f)
- return error("Missing input.");
- if(!opengrid(&g, f))
- return error("Invalid grid");
- while(g.f < limit) {
- rungrid(&g);
- printgrid(&g);
- }
- return 0;
-}
M demo.orca => demo.orca +4 -5
@@ 2,16 2,15 @@
.#.DEMO.......................#.
................................
..1AC..1BC..1CC..1DC..1FC...G...
-................................
+...D....B....0....*.............
................................
...H...1IC...J....K...1LC..1MC..
-................................
+........1..............1....C...
................................
...O....P....Q...1RC...T...1UC..
-................................
+..................1.........*...
................................
...V....X....Y...1ZC............
-................................
+..................C.............
.....................D..........
......................:23E......
-................................>
\ No newline at end of file
M orca.c => orca.c +638 -4
@@ 2,7 2,6 @@
#include <SDL2/SDL.h>
#include <portmidi.h>
#include <porttime.h>
-#include "sim.h"
/*
Copyright (c) 2020 Devine Lu Linvega
@@ 23,9 22,17 @@ WITH REGARD TO THIS SOFTWARE.
#define SZ (HOR * VER * 16)
#define CLIPSZ 1024
+#define MSGSZ 64
+#define MAXSZ 128 * 128
typedef unsigned char Uint8;
+typedef struct Grid {
+ int w, h, l, f, r, msglen;
+ int lock[MAXSZ], type[MAXSZ];
+ char data[MAXSZ], var[36], msg[MSGSZ];
+} Grid;
+
typedef struct {
char name[256];
Grid grid;
@@ 150,6 157,613 @@ SDL_Texture *gTexture = NULL;
Uint32 *pixels;
PmStream *midi;
+/* core */
+
+int
+ciuc(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+int
+cilc(char c)
+{
+ return c >= 'a' && c <= 'z';
+}
+
+int
+cinu(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+int
+cisp(char c)
+{
+ return !ciuc(c) && !cilc(c) && !cinu(c) && c != '.';
+}
+
+int
+clca(int c)
+{
+ return ciuc(c) ? c + ('a' - 'A') : c;
+}
+
+char
+cchr(int v, int cap)
+{
+ v %= 36;
+ v *= v < 0 ? -1 : 1;
+ if(v >= 0 && v <= 9)
+ return '0' + v;
+ if(cap)
+ return 'A' + (v - 10);
+ return 'a' + (v - 10);
+}
+
+int
+cb36(char c)
+{
+ if(c >= 'A' && c <= 'Z')
+ return c - 'A' + 10;
+ if(c >= 'a' && c <= 'z')
+ return c - 'a' + 10;
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ return 0;
+}
+
+int
+valid(Grid *g, int x, int y)
+{
+ return x >= 0 && x <= g->w - 1 && y >= 0 && y <= g->h - 1;
+}
+
+int
+random(Grid *g)
+{
+ (void)g;
+ return 0;
+ /* TODO
+ g->r *= 1103515245;
+ return ((g->r / 65536 * g->f) % 32768) ^ g->f;
+ */
+}
+
+/* IO */
+
+char
+get(Grid *g, int x, int y)
+{
+ if(valid(g, x, y))
+ return g->data[x + (y * g->w)];
+ return '.';
+}
+
+void
+set(Grid *g, int x, int y, char c)
+{
+ if(valid(g, x, y))
+ g->data[x + (y * g->w)] = c;
+}
+
+/* Variables */
+
+void
+save(Grid *g, char key, char val)
+{
+ g->var[cb36(key)] = val;
+}
+
+char
+load(Grid *g, char key)
+{
+ return g->var[cb36(key)];
+}
+
+/* Syntax */
+
+int
+gettype(Grid *g, int x, int y)
+{
+ if(valid(g, x, y))
+ return g->type[x + (y * g->w)];
+ return 0;
+}
+
+void
+settype(Grid *g, int x, int y, int t)
+{
+ if(valid(g, x, y))
+ g->type[x + (y * g->w)] = t;
+}
+
+/* Locks */
+
+void
+lock(Grid *g, int x, int y)
+{
+ if(valid(g, x, y)) {
+ g->lock[x + (y * g->w)] = 1;
+ if(!gettype(g, x, y))
+ settype(g, x, y, 1);
+ }
+}
+
+/* Port Setters */
+
+void
+setport(Grid *g, int x, int y, char c)
+{
+ lock(g, x, y);
+ settype(g, x, y, 5);
+ set(g, x, y, c);
+}
+
+int
+getport(Grid *g, int x, int y, int l)
+{
+ if(l) {
+ lock(g, x, y);
+ settype(g, x, y, 4);
+ } else
+ settype(g, x, y, 2);
+ return get(g, x, y);
+}
+
+int
+bang(Grid *g, int x, int y)
+{
+ return get(g, x - 1, y) == '*' || get(g, x + 1, y) == '*' || get(g, x, y - 1) == '*' || get(g, x, y + 1) == '*';
+}
+
+/* Library */
+
+void
+opa(Grid *g, int x, int y, char c)
+{
+ char a = getport(g, x - 1, y, 0);
+ char b = getport(g, x + 1, y, 1);
+ setport(g, x, y + 1, cchr(cb36(a) + cb36(b), ciuc(b)));
+ (void)c;
+}
+
+void
+opb(Grid *g, int x, int y, char c)
+{
+ char a = getport(g, x - 1, y, 0);
+ char b = getport(g, x + 1, y, 1);
+ setport(g, x, y + 1, cchr(cb36(a) - cb36(b), ciuc(b)));
+ (void)c;
+}
+
+void
+opc(Grid *g, int x, int y, char c)
+{
+ char rate = getport(g, x - 1, y, 0);
+ char mod = getport(g, x + 1, y, 1);
+ int mod_ = cb36(mod);
+ int rate_ = cb36(rate);
+ if(!rate_)
+ rate_ = 1;
+ if(!mod_)
+ mod_ = 8;
+ setport(g, x, y + 1, cchr(g->f / rate_ % mod_, ciuc(mod)));
+ (void)c;
+}
+
+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);
+ int rate_ = cb36(rate);
+ int mod_ = cb36(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(!valid(g, x + 1, y) || get(g, x + 1, y) != '.')
+ set(g, x, y, '*');
+ else {
+ set(g, x, y, '.');
+ setport(g, x + 1, y, c);
+ settype(g, x + 1, y, 0);
+ }
+ settype(g, x, y, 0);
+}
+
+void
+opf(Grid *g, int x, int y, char c)
+{
+ 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)
+{
+ 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_ = cb36(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
+ setport(g, x + i + cb36(px), y + 1 + cb36(py), getport(g, x + 1 + i, y, 1));
+ (void)c;
+}
+
+void
+oph(Grid *g, int x, int y, char c)
+{
+ getport(g, x, y + 1, 1);
+ (void)c;
+}
+
+void
+opi(Grid *g, int x, int y, char c)
+{
+ char rate = getport(g, x - 1, y, 0);
+ char mod = getport(g, x + 1, y, 1);
+ char val = getport(g, x, y + 1, 1);
+ int rate_ = cb36(rate);
+ int mod_ = cb36(mod);
+ if(!rate_)
+ rate_ = 1;
+ if(!mod_)
+ mod_ = 36;
+ setport(g, x, y + 1, cchr((cb36(val) + rate_) % mod_, ciuc(mod)));
+ (void)c;
+}
+
+void
+opj(Grid *g, int x, int y, char c)
+{
+ char link = getport(g, x, y - 1, 0);
+ int i;
+ if(link != c) {
+ for(i = 1; y + i < 256; ++i)
+ if(get(g, x, y + i) != c)
+ break;
+ setport(g, x, y + i, link);
+ }
+}
+
+void
+opk(Grid *g, int x, int y, char c)
+{
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cb36(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i) {
+ char key = getport(g, x + 1 + i, y, 1);
+ if(key != '.')
+ setport(g, x + 1 + i, y + 1, load(g, key));
+ }
+ (void)c;
+}
+
+void
+opl(Grid *g, int x, int y, char c)
+{
+ char a = getport(g, x - 1, y, 0);
+ char b = getport(g, x + 1, y, 1);
+ setport(g, x, y + 1, cb36(a) < cb36(b) ? a : b);
+ (void)c;
+}
+
+void
+opm(Grid *g, int x, int y, char c)
+{
+ char a = getport(g, x - 1, y, 0);
+ char b = getport(g, x + 1, y, 1);
+ setport(g, x, y + 1, cchr(cb36(a) * cb36(b), ciuc(b)));
+ (void)c;
+}
+
+void
+opn(Grid *g, int x, int y, char c)
+{
+ 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 - 1, 0);
+ }
+ settype(g, x, y, 0);
+}
+
+void
+opo(Grid *g, int x, int y, char c)
+{
+ 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 + cb36(px), y + cb36(py), 1));
+ (void)c;
+}
+
+void
+opp(Grid *g, int x, int y, char c)
+{
+ 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_ = cb36(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
+ lock(g, x + i, y + 1);
+ setport(g, x + (cb36(key) % len_), y + 1, val);
+ (void)c;
+}
+
+void
+opq(Grid *g, int x, int y, char c)
+{
+ 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_ = cb36(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
+ setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + cb36(px) + i, y + cb36(py), 1));
+ (void)c;
+}
+
+void
+opr(Grid *g, int x, int y, char c)
+{
+ char min = getport(g, x - 1, y, 0);
+ char max = getport(g, x + 1, y, 1);
+ int min_ = cb36(min);
+ int max_ = cb36(max);
+ setport(g, x, y + 1, cchr((random(g) % ((cb36(max_) - min_) || 1)) + min_, ciuc(max)));
+ (void)c;
+}
+
+void
+ops(Grid *g, int x, int y, char c)
+{
+ 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 + 1, 0);
+ }
+ settype(g, x, y, 0);
+}
+
+void
+opt(Grid *g, int x, int y, char c)
+{
+ char key = getport(g, x - 2, y, 0);
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cb36(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 + (cb36(key) % len_), y, 1));
+ (void)c;
+}
+
+void
+opu(Grid *g, int x, int y, char c)
+{
+ char step = getport(g, x - 1, y, 1);
+ char max = getport(g, x + 1, y, 1);
+ int step_ = cb36(step);
+ int max_ = cb36(max);
+ int bucket;
+ if(!step_)
+ step_ = 1;
+ if(!max_)
+ max_ = 8;
+ bucket = (step_ * (g->f + max_ - 1)) % max_ + step_;
+ setport(g, x, y + 1, bucket >= max_ ? '*' : '.');
+ (void)c;
+}
+
+void
+opv(Grid *g, int x, int y, char c)
+{
+ char w = getport(g, x - 1, y, 0);
+ char r = getport(g, x + 1, y, 1);
+ if(w != '.')
+ save(g, w, r);
+ else if(w == '.' && r != '.')
+ setport(g, x, y + 1, load(g, r));
+ (void)c;
+}
+
+void
+opw(Grid *g, int x, int y, char c)
+{
+ if(!valid(g, x - 1, y) || get(g, x - 1, y) != '.')
+ set(g, x, y, '*');
+ else {
+ set(g, x, y, '.');
+ setport(g, x - 1, y, c);
+ settype(g, x - 1, y, 0);
+ }
+ settype(g, x, y, 0);
+}
+
+void
+opx(Grid *g, int x, int y, char c)
+{
+ 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 + cb36(px), y + cb36(py) + 1, val);
+ (void)c;
+}
+
+void
+opy(Grid *g, int x, int y, char c)
+{
+ char link = getport(g, x - 1, y, 0);
+ int i;
+ if(link != c) {
+ for(i = 1; x + i < 256; ++i)
+ if(get(g, x + i, y) != c)
+ break;
+ setport(g, x + i, y, link);
+ }
+}
+
+void
+opz(Grid *g, int x, int y, char c)
+{
+ char rate = getport(g, x - 1, y, 0);
+ char target = getport(g, x + 1, y, 1);
+ char val = getport(g, x, y + 1, 1);
+ int rate_ = cb36(rate);
+ int target_ = cb36(target);
+ int val_ = cb36(val);
+ int mod;
+ if(!rate_)
+ rate_ = 1;
+ if(val_ <= target_ - rate_)
+ mod = rate_;
+ else if(val_ >= target_ + rate_)
+ mod = -rate;
+ else
+ mod = target_ - val_;
+ setport(g, x, y + 1, cchr(val_ + mod, ciuc(target)));
+ (void)c;
+}
+
+void
+opcomment(Grid *g, int x, int y)
+{
+ int i;
+ for(i = 1; x + i < 256; ++i) {
+ lock(g, x + i, y);
+ if(get(g, x + i, y) == '#')
+ break;
+ }
+ settype(g, x, y, 1);
+}
+
+void
+opspecial(Grid *g, int x, int y)
+{
+ int i, b = bang(g, x, y);
+ for(i = 0; x + i < MSGSZ; ++i) {
+ char c = getport(g, x + i, y, 1);
+ if(c == '.')
+ break;
+ if(b && g->msglen < MSGSZ) {
+ g->msg[g->msglen++] = c;
+ g->msg[g->msglen] = '\0';
+ }
+ }
+ settype(g, x, y, b ? 3 : 2);
+}
+
+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;
+ case 'c': opc(g, x, y, c); break;
+ case 'd': opd(g, x, y, c); break;
+ case 'e': ope(g, x, y, c); break;
+ case 'f': opf(g, x, y, c); break;
+ case 'g': opg(g, x, y, c); break;
+ case 'h': oph(g, x, y, c); break;
+ case 'i': opi(g, x, y, c); break;
+ case 'k': opk(g, x, y, c); break;
+ case 'j': opj(g, x, y, c); break;
+ case 'l': opl(g, x, y, c); break;
+ case 'm': opm(g, x, y, c); break;
+ case 'n': opn(g, x, y, c); break;
+ case 'o': opo(g, x, y, c); break;
+ case 'p': opp(g, x, y, c); break;
+ case 'q': opq(g, x, y, c); break;
+ case 'r': opr(g, x, y, c); break;
+ case 's': ops(g, x, y, c); break;
+ case 't': opt(g, x, y, c); break;
+ case 'u': opu(g, x, y, c); break;
+ case 'v': opv(g, x, y, c); break;
+ case 'w': opw(g, x, y, c); break;
+ case 'x': opx(g, x, y, c); break;
+ case 'y': opy(g, x, y, c); break;
+ case 'z': opz(g, x, y, c); break;
+ case '*': set(g, x, y, '.'); break;
+ case '#': opcomment(g, x, y); break;
+ default: opspecial(g, x, y);
+ }
+}
+
+/* General */
+
+void
+initframe(Grid *g)
+{
+ int i;
+ for(i = 0; i < g->l; ++i) {
+ g->lock[i] = 0;
+ g->type[i] = 0;
+ }
+ for(i = 0; i < 36; ++i)
+ g->var[i] = '\0';
+ g->msg[0] = '\0';
+ g->msglen = 0;
+}
+
+int
+rungrid(Grid *g)
+{
+ int i, x, y;
+ initframe(g);
+ for(i = 0; i < g->l; ++i) {
+ char c = g->data[i];
+ x = i % g->w;
+ 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);
+ }
+ g->f++;
+ return 1;
+}
+
+void
+initgrid(Grid *g, int w, int h)
+{
+ int i;
+ g->w = w;
+ g->h = h;
+ g->l = w * h;
+ g->f = 0;
+ g->r = 1;
+ for(i = 0; i < g->l; ++i)
+ g->data[i] = '.';
+ initframe(g);
+}
+
/* helpers */
int
@@ 401,9 1015,21 @@ makedoc(Document *d, char *name)
int
opendoc(Document *d, char *name)
{
- initgrid(&d->grid, HOR, VER);
- if(!loadgrid(&d->grid, name))
+ int x = 0, y = 0;
+ char c;
+ FILE *f = fopen(name, "r");
+ if(!f)
return error("Load", "Invalid input file");
+ initgrid(&d->grid, HOR, VER);
+ while((c = fgetc(f)) != EOF && d->grid.l < MAXSZ) {
+ if(c == '\n') {
+ x = 0;
+ y++;
+ } else {
+ set(&d->grid, x, y, c);
+ x++;
+ }
+ }
scpy(name, d->name, 256);
redraw(pixels);
return 1;
@@ 412,8 1038,16 @@ opendoc(Document *d, char *name)
void
savedoc(Document *d, char *name)
{
- savegrid(&d->grid, d->name);
+ int x, y;
+ FILE *f = fopen(name, "w");
+ for(y = 0; y < d->grid.h; ++y) {
+ for(x = 0; x < d->grid.w; ++x)
+ fputc(get(&d->grid, x, y), f);
+ fputc('\n', f);
+ }
+ fclose(f);
scpy(name, d->name, 256);
+ printf("Saved: %s\n", name);
}
void
D sim.c => sim.c +0 -641
@@ 1,641 0,0 @@
-#include <stdio.h>
-#include "sim.h"
-
-int
-ciuc(char c)
-{
- return c >= 'A' && c <= 'Z';
-}
-
-int
-cilc(char c)
-{
- return c >= 'a' && c <= 'z';
-}
-
-int
-cinu(char c)
-{
- return c >= '0' && c <= '9';
-}
-
-int
-cisp(char c)
-{
- return !ciuc(c) && !cilc(c) && !cinu(c) && c != '.';
-}
-
-int
-clca(int c)
-{
- return ciuc(c) ? c + ('a' - 'A') : c;
-}
-
-char
-cchr(int v, int cap)
-{
- v %= 36;
- v *= v < 0 ? -1 : 1;
- if(v >= 0 && v <= 9)
- return '0' + v;
- if(cap)
- return 'A' + (v - 10);
- return 'a' + (v - 10);
-}
-
-int
-valid(Grid *g, int x, int y)
-{
- return x >= 0 && x <= g->w - 1 && y >= 0 && y <= g->h - 1;
-}
-
-int
-random(Grid *g)
-{
- (void)g;
- return 0;
- /*
- g->r *= 1103515245;
- return ((g->r / 65536 * g->f) % 32768) ^ g->f;
- */
-}
-
-int
-cb36(char c)
-{
- if(c >= 'A' && c <= 'Z')
- return c - 'A' + 10;
- if(c >= 'a' && c <= 'z')
- return c - 'a' + 10;
- if(c >= '0' && c <= '9')
- return c - '0';
- return 0;
-}
-
-/* IO */
-
-char
-get(Grid *g, int x, int y)
-{
- if(valid(g, x, y))
- return g->data[x + (y * g->w)];
- return '.';
-}
-
-void
-set(Grid *g, int x, int y, char c)
-{
- if(valid(g, x, y))
- g->data[x + (y * g->w)] = c;
-}
-
-/* Variables */
-
-void
-save(Grid *g, char key, char val)
-{
- g->var[cb36(key)] = val;
-}
-
-char
-load(Grid *g, char key)
-{
- return g->var[cb36(key)];
-}
-
-/* Syntax */
-
-int
-gettype(Grid *g, int x, int y)
-{
- if(valid(g, x, y))
- return g->type[x + (y * g->w)];
- return 0;
-}
-
-void
-settype(Grid *g, int x, int y, int t)
-{
- if(valid(g, x, y))
- g->type[x + (y * g->w)] = t;
-}
-
-/* Locks */
-
-void
-lock(Grid *g, int x, int y)
-{
- if(valid(g, x, y)) {
- g->lock[x + (y * g->w)] = 1;
- if(!gettype(g, x, y))
- settype(g, x, y, 1);
- }
-}
-
-/* Port Setters */
-
-void
-setport(Grid *g, int x, int y, char c)
-{
- lock(g, x, y);
- settype(g, x, y, 5);
- set(g, x, y, c);
-}
-
-int
-getport(Grid *g, int x, int y, int l)
-{
- if(l) {
- lock(g, x, y);
- settype(g, x, y, 4);
- } else
- settype(g, x, y, 2);
- return get(g, x, y);
-}
-
-int
-bang(Grid *g, int x, int y)
-{
- return get(g, x - 1, y) == '*' || get(g, x + 1, y) == '*' || get(g, x, y - 1) == '*' || get(g, x, y + 1) == '*';
-}
-
-/* Library */
-
-void
-opa(Grid *g, int x, int y, char c)
-{
- char a = getport(g, x - 1, y, 0);
- char b = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, cchr(cb36(a) + cb36(b), ciuc(b)));
- (void)c;
-}
-
-void
-opb(Grid *g, int x, int y, char c)
-{
- char a = getport(g, x - 1, y, 0);
- char b = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, cchr(cb36(a) - cb36(b), ciuc(b)));
- (void)c;
-}
-
-void
-opc(Grid *g, int x, int y, char c)
-{
- char rate = getport(g, x - 1, y, 0);
- char mod = getport(g, x + 1, y, 1);
- int mod_ = cb36(mod);
- int rate_ = cb36(rate);
- if(!rate_)
- rate_ = 1;
- if(!mod_)
- mod_ = 8;
- setport(g, x, y + 1, cchr(g->f / rate_ % mod_, ciuc(mod)));
- (void)c;
-}
-
-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);
- int rate_ = cb36(rate);
- int mod_ = cb36(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(!valid(g, x + 1, y) || get(g, x + 1, y) != '.')
- set(g, x, y, '*');
- else {
- set(g, x, y, '.');
- setport(g, x + 1, y, c);
- settype(g, x + 1, y, 0);
- }
- settype(g, x, y, 0);
-}
-
-void
-opf(Grid *g, int x, int y, char c)
-{
- 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)
-{
- 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_ = cb36(len);
- if(!len_)
- len_ = 1;
- for(i = 0; i < len_; ++i)
- setport(g, x + i + cb36(px), y + 1 + cb36(py), getport(g, x + 1 + i, y, 1));
- (void)c;
-}
-
-void
-oph(Grid *g, int x, int y, char c)
-{
- getport(g, x, y + 1, 1);
- (void)c;
-}
-
-void
-opi(Grid *g, int x, int y, char c)
-{
- char rate = getport(g, x - 1, y, 0);
- char mod = getport(g, x + 1, y, 1);
- char val = getport(g, x, y + 1, 1);
- int rate_ = cb36(rate);
- int mod_ = cb36(mod);
- if(!rate_)
- rate_ = 1;
- if(!mod_)
- mod_ = 36;
- setport(g, x, y + 1, cchr((cb36(val) + rate_) % mod_, ciuc(mod)));
- (void)c;
-}
-
-void
-opj(Grid *g, int x, int y, char c)
-{
- char link = getport(g, x, y - 1, 0);
- int i;
- if(link != c) {
- for(i = 1; y + i < 256; ++i)
- if(get(g, x, y + i) != c)
- break;
- setport(g, x, y + i, link);
- }
-}
-
-void
-opk(Grid *g, int x, int y, char c)
-{
- char len = getport(g, x - 1, y, 0);
- int i, len_ = cb36(len);
- if(!len_)
- len_ = 1;
- for(i = 0; i < len_; ++i) {
- char key = getport(g, x + 1 + i, y, 1);
- if(key != '.')
- setport(g, x + 1 + i, y + 1, load(g, key));
- }
- (void)c;
-}
-
-void
-opl(Grid *g, int x, int y, char c)
-{
- char a = getport(g, x - 1, y, 0);
- char b = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, cb36(a) < cb36(b) ? a : b);
- (void)c;
-}
-
-void
-opm(Grid *g, int x, int y, char c)
-{
- char a = getport(g, x - 1, y, 0);
- char b = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, cchr(cb36(a) * cb36(b), ciuc(b)));
- (void)c;
-}
-
-void
-opn(Grid *g, int x, int y, char c)
-{
- 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 - 1, 0);
- }
- settype(g, x, y, 0);
-}
-
-void
-opo(Grid *g, int x, int y, char c)
-{
- 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 + cb36(px), y + cb36(py), 1));
- (void)c;
-}
-
-void
-opp(Grid *g, int x, int y, char c)
-{
- 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_ = cb36(len);
- if(!len_)
- len_ = 1;
- for(i = 0; i < len_; ++i)
- lock(g, x + i, y + 1);
- setport(g, x + (cb36(key) % len_), y + 1, val);
- (void)c;
-}
-
-void
-opq(Grid *g, int x, int y, char c)
-{
- 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_ = cb36(len);
- if(!len_)
- len_ = 1;
- for(i = 0; i < len_; ++i)
- setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + cb36(px) + i, y + cb36(py), 1));
- (void)c;
-}
-
-void
-opr(Grid *g, int x, int y, char c)
-{
- char min = getport(g, x - 1, y, 0);
- char max = getport(g, x + 1, y, 1);
- int min_ = cb36(min);
- int max_ = cb36(max);
- setport(g, x, y + 1, cchr((random(g) % ((cb36(max_) - min_) || 1)) + min_, ciuc(max)));
- (void)c;
-}
-
-void
-ops(Grid *g, int x, int y, char c)
-{
- 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 + 1, 0);
- }
- settype(g, x, y, 0);
-}
-
-void
-opt(Grid *g, int x, int y, char c)
-{
- char key = getport(g, x - 2, y, 0);
- char len = getport(g, x - 1, y, 0);
- int i, len_ = cb36(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 + (cb36(key) % len_), y, 1));
- (void)c;
-}
-
-void
-opu(Grid *g, int x, int y, char c)
-{
- char step = getport(g, x - 1, y, 1);
- char max = getport(g, x + 1, y, 1);
- int step_ = cb36(step);
- int max_ = cb36(max);
- int bucket;
- if(!step_)
- step_ = 1;
- if(!max_)
- max_ = 8;
- bucket = (step_ * (g->f + max_ - 1)) % max_ + step_;
- setport(g, x, y + 1, bucket >= max_ ? '*' : '.');
- (void)c;
-}
-
-void
-opv(Grid *g, int x, int y, char c)
-{
- char w = getport(g, x - 1, y, 0);
- char r = getport(g, x + 1, y, 1);
- if(w != '.')
- save(g, w, r);
- else if(w == '.' && r != '.')
- setport(g, x, y + 1, load(g, r));
- (void)c;
-}
-
-void
-opw(Grid *g, int x, int y, char c)
-{
- if(!valid(g, x - 1, y) || get(g, x - 1, y) != '.')
- set(g, x, y, '*');
- else {
- set(g, x, y, '.');
- setport(g, x - 1, y, c);
- settype(g, x - 1, y, 0);
- }
- settype(g, x, y, 0);
-}
-
-void
-opx(Grid *g, int x, int y, char c)
-{
- 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 + cb36(px), y + cb36(py) + 1, val);
- (void)c;
-}
-
-void
-opy(Grid *g, int x, int y, char c)
-{
- char link = getport(g, x - 1, y, 0);
- int i;
- if(link != c) {
- for(i = 1; x + i < 256; ++i)
- if(get(g, x + i, y) != c)
- break;
- setport(g, x + i, y, link);
- }
-}
-
-void
-opz(Grid *g, int x, int y, char c)
-{
- char rate = getport(g, x - 1, y, 0);
- char target = getport(g, x + 1, y, 1);
- char val = getport(g, x, y + 1, 1);
- int rate_ = cb36(rate);
- int target_ = cb36(target);
- int val_ = cb36(val);
- int mod;
- if(!rate_)
- rate_ = 1;
- if(val_ <= target_ - rate_)
- mod = rate_;
- else if(val_ >= target_ + rate_)
- mod = -rate;
- else
- mod = target_ - val_;
- setport(g, x, y + 1, cchr(val_ + mod, ciuc(target)));
- (void)c;
-}
-
-void
-opcomment(Grid *g, int x, int y)
-{
- int i;
- for(i = 1; x + i < 256; ++i) {
- lock(g, x + i, y);
- if(get(g, x + i, y) == '#')
- break;
- }
- settype(g, x, y, 1);
-}
-
-void
-opspecial(Grid *g, int x, int y)
-{
- int i, b = bang(g, x, y);
- for(i = 0; x + i < MSGSZ; ++i) {
- char c = getport(g, x + i, y, 1);
- if(c == '.')
- break;
- if(b && g->msglen < MSGSZ) {
- g->msg[g->msglen++] = c;
- g->msg[g->msglen] = '\0';
- }
- }
- settype(g, x, y, b ? 3 : 2);
-}
-
-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;
- case 'c': opc(g, x, y, c); break;
- case 'd': opd(g, x, y, c); break;
- case 'e': ope(g, x, y, c); break;
- case 'f': opf(g, x, y, c); break;
- case 'g': opg(g, x, y, c); break;
- case 'h': oph(g, x, y, c); break;
- case 'i': opi(g, x, y, c); break;
- case 'k': opk(g, x, y, c); break;
- case 'j': opj(g, x, y, c); break;
- case 'l': opl(g, x, y, c); break;
- case 'm': opm(g, x, y, c); break;
- case 'n': opn(g, x, y, c); break;
- case 'o': opo(g, x, y, c); break;
- case 'p': opp(g, x, y, c); break;
- case 'q': opq(g, x, y, c); break;
- case 'r': opr(g, x, y, c); break;
- case 's': ops(g, x, y, c); break;
- case 't': opt(g, x, y, c); break;
- case 'u': opu(g, x, y, c); break;
- case 'v': opv(g, x, y, c); break;
- case 'w': opw(g, x, y, c); break;
- case 'x': opx(g, x, y, c); break;
- case 'y': opy(g, x, y, c); break;
- case 'z': opz(g, x, y, c); break;
- case '*': set(g, x, y, '.'); break;
- case '#': opcomment(g, x, y); break;
- default: opspecial(g, x, y);
- }
-}
-
-/* General */
-
-void
-initframe(Grid *g)
-{
- int i;
- for(i = 0; i < g->l; ++i) {
- g->lock[i] = 0;
- g->type[i] = 0;
- }
- for(i = 0; i < 36; ++i)
- g->var[i] = '\0';
- g->msg[0] = '\0';
- g->msglen = 0;
-}
-
-int
-rungrid(Grid *g)
-{
- int i, x, y;
- initframe(g);
- for(i = 0; i < g->l; ++i) {
- char c = g->data[i];
- x = i % g->w;
- 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);
- }
- g->f++;
- return 1;
-}
-
-int
-loadgrid(Grid *g, char *name)
-{
- int x = 0, y = 0;
- char c;
- FILE *f = fopen(name, "r");
- if(!f)
- return 0;
- while((c = fgetc(f)) != EOF && g->l < MAXSZ) {
- if(c == '\n') {
- x = 0;
- y++;
- } else {
- set(g, x, y, c);
- x++;
- }
- }
- return 1;
-}
-
-void
-savegrid(Grid *g, char *name)
-{
- int x, y;
- FILE *f = fopen(name, "w");
- for(y = 0; y < g->h; ++y) {
- for(x = 0; x < g->w; ++x)
- fputc(get(g, x, y), f);
- fputc('\n', f);
- }
- fclose(f);
- printf("Saved: %s\n", name);
-}
-
-void
-initgrid(Grid *g, int w, int h)
-{
- int i;
- g->w = w;
- g->h = h;
- g->l = w * h;
- g->f = 0;
- g->r = 1;
- for(i = 0; i < g->l; ++i)
- g->data[i] = '.';
- initframe(g);
-}
D sim.h => sim.h +0 -24
@@ 1,24 0,0 @@
-#pragma once
-
-#include <stdio.h>
-
-#define MSGSZ 64
-#define MAXSZ 128 * 128
-
-typedef struct Grid {
- int w, h, l, f, r, msglen;
- int lock[MAXSZ], type[MAXSZ];
- char data[MAXSZ], var[36], msg[MSGSZ];
-} Grid;
-
-int cb36(char c);
-int cisp(char c);
-
-char get(Grid *g, int x, int y);
-void set(Grid *g, int x, int y, char c);
-int gettype(Grid *g, int x, int y);
-
-int rungrid(Grid *g);
-int loadgrid(Grid *g, char *name);
-void savegrid(Grid *g, char *name);
-void initgrid(Grid *g, int w, int h);