123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /**
- 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;
- }
|