summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bin/.gitignore1
-rw-r--r--bin/Makefile5
-rw-r--r--bin/brot.c90
3 files changed, 95 insertions, 1 deletions
diff --git a/bin/.gitignore b/bin/.gitignore
index d3450745..c84d690b 100644
--- a/bin/.gitignore
+++ b/bin/.gitignore
@@ -1,6 +1,7 @@
 *.o
 tags
 atch
+brot
 dtch
 gfxx
 glitch
diff --git a/bin/Makefile b/bin/Makefile
index bbcc8c4b..b6d13697 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -1,4 +1,4 @@
-ANY_BINS = atch dtch gfxx glitch hnel pbcopy pbd pbpaste pngo scheme wake xx
+ANY_BINS = atch brot dtch gfxx glitch hnel pbcopy pbd pbpaste pngo scheme wake xx
 BSD_BINS = klon watch
 LIN_BINS = bri fbatt fbclock
 ALL_BINS = $(ANY_BINS) $(BSD_BINS) $(LIN_BINS)
@@ -24,6 +24,9 @@ tags: *.c
 atch: dtch
 	ln -f dtch atch
 
+brot: brot.o gfx/$(GFX).o
+	$(CC) $(LDFLAGS) brot.o gfx/$(GFX).o $(LDLIBS) $(LDLIBS_$(GFX)) -o $@
+
 gfxx: gfxx.o gfx/$(GFX).o
 	$(CC) $(LDFLAGS) gfxx.o gfx/$(GFX).o $(LDLIBS) $(LDLIBS_$(GFX)) -o $@
 
diff --git a/bin/brot.c b/bin/brot.c
new file mode 100644
index 00000000..cd2f44c3
--- /dev/null
+++ b/bin/brot.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2018  Curtis McEnroe <june@causal.agency>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <complex.h>
+#include <err.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+
+#include "gfx/gfx.h"
+
+static double absSq(double complex z) {
+    return creal(z) * creal(z) + cimag(z) * cimag(z);
+}
+
+static uint32_t depth = 50;
+
+static uint32_t mandelbrot(double complex c) {
+    double complex z = 0;
+    for (uint32_t i = 0; i < depth; ++i) {
+        if (absSq(z) > 4.0) return i;
+        z = z * z + c;
+    }
+    return 0;
+}
+
+static double complex origin = -0.75 + 0.0 * I;
+static double complex scale = 3.5 + 2.0 * I;
+static double complex rotate = 1;
+
+void draw(uint32_t *buf, size_t width, size_t height) {
+    for (size_t y = 0; y < height; ++y) {
+        double complex zy = ((double)y / (double)height - 0.5) * cimag(scale) * I;
+        for (size_t x = 0; x < width; ++x) {
+            double complex zx = ((double)x / (double)width - 0.5) * creal(scale);
+            uint64_t n = mandelbrot((origin + zx + zy) * rotate);
+            uint32_t g = (double)n / (double)depth * 255.0;
+            buf[y * width + x] = g << 16 | g << 8 | g;
+        }
+    }
+}
+
+bool input(char in) {
+    switch (in) {
+        case 'q': return false;
+        case '.': depth++; break;
+        case ',': if (depth) depth--; break;
+        case '+': scale *= 0.9; break;
+        case '-': scale *= 1.1; break;
+        case 'l': origin += creal(scale) * 0.01; break;
+        case 'h': origin -= creal(scale) * 0.01; break;
+        case 'j': origin += cimag(scale) * 0.01 * I; break;
+        case 'k': origin -= cimag(scale) * 0.01 * I; break;
+    }
+    return true;
+}
+
+const char *status(void) {
+    static char buf[256];
+    snprintf(
+        buf, sizeof(buf),
+        "(%u) (%g + %gi) (%g + %gi)",
+        depth,
+        creal(origin), cimag(origin),
+        creal(scale), cimag(scale)
+    );
+    return buf;
+}
+
+int init(int argc, char *argv[]) {
+    (void)argc;
+    (void)argv;
+    return EX_OK;
+}