Minimal abstract interface for simple games
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

#### 133 lines 2.7 KiB Raw Permalink Blame History

 `/**` ` Simple SAF program for exploring the Mandelbrot set, arrows to move, A/B to` ` zoom.` ` by drummyfish, released under CC0 1.0, public domain` `*/` `#define SAF_PROGRAM_NAME "Mandelbrot"` `#define SAF_SETTING_ENABLE_SOUND 0` `#include "../saf.h"` `/*` ` Checks whether the point is in the mandelbrot set, returns number of` ` iterations, up until 255, to which the point did not diverge to infinity, i.e.` ` 255 means probably inside the set.` `*/` `uint8_t iteratePoint(double x, double y)` `{` ` // writing this without floats is left as an excercise for the reader` ` double current[2];` ` current[0] = x;` ` current[1] = y;` ` uint8_t iterations = 0;` ` while (1)` ` {` ` double ` ` newX = current[0] * current[0] - current[1] * current[1] + x,` ` newY = 2 * current[0] * current[1] + y;` ` current[0] = newX;` ` current[1] = newY;` `#define INF 999999999999` ` if (iterations == 255 ||` ` current[0] > INF || current[0] < -INF ||` ` current[1] > INF || current[1] < -INF)` ` break;` `#undef INF` ` iterations++;` ` }` ` return iterations;` `}` `double` ` cx = -1,` ` cy = -1,` ` step = 2.0 / SAF_SCREEN_WIDTH; ` `void draw(void)` `{` ` double dx, dy = cy, halfStep = step / 2;` ` for (int y = 0; y < SAF_SCREEN_HEIGHT; ++y)` ` {` ` dx = cx;` ` for (int x = 0; x < SAF_SCREEN_WIDTH; ++x)` ` {` ` // antialias (sample at 4 points):` ` uint8_t r = 0,g = 0,b = 0;` ` uint16_t rr = 0, gg = 0, bb = 0;` ` SAF_colorToRGB(iteratePoint(dx,dy), &r, &g, &b);` ` rr = r; gg = g; bb = b;` ` SAF_colorToRGB(iteratePoint(dx + halfStep,dy), &r, &g, &b);` ` rr += r; gg += g; bb += b;` ` SAF_colorToRGB(iteratePoint(dx,dy + halfStep), &r, &g, &b);` ` rr += r; gg += g; bb += b;` ` SAF_colorToRGB(iteratePoint(dx + halfStep,dy + halfStep), &r, &g, &b);` ` rr += r; gg += g; bb += b;` ` SAF_drawPixel(x,y,SAF_colorFromRGB(rr / 4, gg / 4, bb / 4));` ` dx += step;` ` }` ` dy += step;` ` }` `}` `void SAF_init(void)` `{` ` draw();` `}` `uint8_t SAF_loop(void)` `{` ` uint8_t redraw = 1;` `#define STEP 10` ` if (SAF_buttonJustPressed(SAF_BUTTON_LEFT))` ` cx -= step * STEP;` ` else if (SAF_buttonJustPressed(SAF_BUTTON_RIGHT))` ` cx += step * STEP;` ` else if (SAF_buttonJustPressed(SAF_BUTTON_UP))` ` cy -= step * STEP;` ` else if (SAF_buttonJustPressed(SAF_BUTTON_DOWN))` ` cy += step * STEP;` ` else if (SAF_buttonJustPressed(SAF_BUTTON_A))` ` {` ` // zoom and shift` ` step /= 2;` ` cx += step / 2 * SAF_SCREEN_WIDTH;` ` cy += step / 2 * SAF_SCREEN_HEIGHT;` ` }` ` else if (SAF_buttonJustPressed(SAF_BUTTON_B))` ` {` ` step *= 2;` ` cx -= step / 4 * SAF_SCREEN_WIDTH;` ` cy -= step / 4 * SAF_SCREEN_HEIGHT;` ` }` ` else` ` redraw = 0;` `#undef STEP` ` if (redraw) // only redraw when needed, it's expensive` ` draw();` ` return 1;` ```} ``` ``` ```