A mandelbrot renderer for the pokitto.

Dependencies:   PokittoLib

Revision:
0:8a49a4178a0e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jun 17 18:44:38 2018 +0000
@@ -0,0 +1,159 @@
+#include "Pokitto.h"
+
+Pokitto::Core game;
+
+#define RGB888_565(r, g, b) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11))
+#define GRAY888_565(g) ((g >> 3) | ((g >> 2) << 5) | ((g >> 3) << 11))
+
+// TODO: need more colors, palette is always PALETTE_SIZE=256
+const uint16_t palette[] =
+{
+    GRAY888_565(0x00),
+    GRAY888_565(0x10),
+    GRAY888_565(0x20),
+    GRAY888_565(0x30),
+    GRAY888_565(0x40),
+    GRAY888_565(0x50),
+    GRAY888_565(0x60),
+    GRAY888_565(0x70),
+    GRAY888_565(0x80),
+    GRAY888_565(0x90),
+    GRAY888_565(0xA0),
+    GRAY888_565(0xB0),
+    GRAY888_565(0xC0),
+    GRAY888_565(0xD0),
+    GRAY888_565(0xE0),
+    GRAY888_565(0xF0),
+};
+
+/* calculate mandelbrot/julia set
+ * KEYS
+ * - color cycle: left, right
+ * - zoom-in/out: up, down
+ * - move center: A + up/down/left/right
+ *
+ * TODO:
+ * - increase/decrease max iter: B + up/down 
+ * - switch between mandel/julia: C
+ *   - will also reset x1/x2/y1/y2 and max-iter
+ */
+
+static const uint8_t width = (POK_LCD_W / 2);
+static const uint8_t height = (POK_LCD_H / 2);
+ 
+static float x1 = -2.2;
+static float x2 = 1.5;
+static float xd = x2 - x1;
+static float xs = xd / width;
+static float y1 = -1.5;
+static float y2 = 1.5;
+static float yd = y2 - y1;
+static float ys = yd / height;
+
+static uint16_t mandel_pixel(float startReal, float startImag) {
+    float zReal = startReal;
+    float zImag = startImag;
+
+    for (uint16_t counter = 0; counter < 50; counter++) {
+        // z := z*z + c
+        float r2 = zReal * zReal;
+        float i2 = zImag * zImag;
+        if (r2 + i2 > 4.0) {
+            return counter;
+        }
+        zImag = 2.0 * zReal * zImag + startImag;
+        zReal = r2 - i2 + startReal;
+    }
+    return 0;
+}
+
+static void mandel_screen(void) {
+    for (uint8_t ypos = 0; ypos < height; ypos++) {
+        float startImag = y1 + (ys * ypos);    
+        for (uint8_t xpos = 0; xpos < width; xpos++) {
+            float startReal = x1 + (xs * xpos);
+            uint8_t color = mandel_pixel(startReal, startImag) % 0x0f;
+            game.display.drawPixel(xpos, ypos, color);
+        }
+        game.display.update();
+    }
+}
+
+int main () {
+    game.begin();
+    game.display.load565Palette(palette);
+
+    // don't clear the screen
+    game.display.persistence = 1;
+    bool recalc = true;
+    
+    while (game.isRunning()) {
+        if (game.update()) {
+            if (game.aBtn()) {
+                // scroll
+                if (game.leftBtn()) {
+                    float mx = 10.0 * xs;
+                    x1 -= mx;
+                    x2 -= mx;
+                    recalc = true;
+                } else if (game.rightBtn()) {
+                    float mx = 10.0 * xs;
+                    x1 += mx;
+                    x2 += mx;
+                    recalc = true;
+                } else if (game.upBtn()) {
+                    float my = 10.0 * ys;
+                    y1 -= my;
+                    y2 -= my;
+                    recalc = true;
+                } else if (game.downBtn()) {
+                    float my = 10.0 * ys;
+                    y1 += my;
+                    y2 += my;
+                    recalc = true;
+                }
+            } else {
+                // cycle colors & zoom
+                if (game.leftBtn()) {
+                    game.display.rotatePalette(-1);
+                } else if (game.rightBtn()) {
+                    game.display.rotatePalette(1);
+                } else if (game.upBtn()) {
+                    // zoom in
+                    xd /= 2.0;
+                    float xm = x1 + xd;
+                    x1 = xm - xd / 2.0;
+                    x2 = xm + xd / 2.0;
+                    xs = xd / width;
+                    
+                    yd /= 2.0;
+                    float ym = y1 + yd;
+                    y1 = ym - yd / 2.0;
+                    y2 = ym + yd / 2.0;
+                    ys = yd / height;
+
+                    recalc = true;
+                } else if (game.downBtn()) {
+                    // zoom out
+                    float xm = x1 + xd / 2.0;
+                    x1 = xm - xd;
+                    x2 = xm + xd;
+                    xd *= 2.0;
+                    xs = xd / width;
+                    
+                    float ym = y1 + yd / 2.0;
+                    y1 = ym - yd;
+                    y2 = ym + yd;
+                    yd *= 2.0;
+                    ys = yd / height;
+                    
+                    recalc = true;
+                }
+            }
+            if (recalc) {
+                mandel_screen();
+                recalc = false;
+            }
+        }
+    }
+}
\ No newline at end of file