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.

138 lines
4.2 KiB

#include <stdio.h>
#include <string.h>
#include <ulib.h>
#include <unistd.h>
#include <syscall.h>
#if defined(__mips__) || defined(__x86_64__)
#if defined(__x86_64__)
#define WIDTH 1024
#define HEIGHT 768
#else
#define WIDTH 800
#define HEIGHT 600
#endif
char buf[WIDTH];
volatile char* frame_buf = (volatile char*) 0xA2000000;
int w = WIDTH, h = HEIGHT, x, y;
//each iteration, it calculates: newz = oldz*oldz + p, where p is the current pixel, and oldz stars at the origin
float pr, pi; //real and imaginary part of the pixel p
float newRe, newIm, oldRe, oldIm; //real and imaginary parts of new and old z
void plot(float moveX, float moveY, float zoom, int maxIterations, int skip) {
cprintf("plot\n");
//loop through every pixel
volatile char *line_addr = frame_buf;
for (y = 0; y < h; y++) {
if (y % skip) {
memcpy(line_addr, line_addr - WIDTH, WIDTH);
line_addr += WIDTH;
continue;
}
for (x = 0; x < w; x++) {
if (x % skip) {
buf[x] = buf[x - 1];
continue;
}
// calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values
pr = 1.5f * (x - w / 2) / (0.5f * zoom * w) + moveX;
pi = (y - h / 2) / (0.5f * zoom * h) + moveY;
newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0
//"i" will represent the number of iterations
int i;
//start the iteration process
for (i = 0; i < maxIterations; i++) {
//remember value of previous iteration
oldRe = newRe;
oldIm = newIm;
//the actual iteration, the real and imaginary part are calculated
newRe = oldRe * oldRe - oldIm * oldIm + pr;
newIm = 2.0f * oldRe * oldIm + pi;
//if the point is outside the circle with radius 2: stop
if ((newRe * newRe + newIm * newIm) > 4)
break;
}
int color = i * 255 / maxIterations;
buf[x] = (color << 5) | (color << 2) | (color >> 1);
}
memcpy(line_addr, buf, WIDTH);
line_addr += WIDTH;
}
}
int main(void) {
#if defined(__x86_64__)
int fd = sys_open("/dev/fb0", O_WRONLY);
frame_buf = (volatile char *)sys_mmap(0, WIDTH * HEIGHT * 3, PROT_WRITE, 0, fd, 0);
#endif
float zoom = 1, moveX = -0.5, moveY = 0; //you can change these to zoom and change position
int maxIterations = 255; //after how much iterations the function should stop
int skip = 4;
int c;
plot(moveX, moveY, zoom, maxIterations, skip);
while ((c = getchar()) > 0) {
cprintf(" %d\n", c);
if (c == 'x') {
skip = 1;
} else if (c == 'h') {
moveX -= 0.2f / zoom;
cprintf("moveX left\n");
} else if (c == 'l') {
moveX += 0.2f / zoom;
cprintf("moveX right\n");
} else if (c == 'j') {
moveY += 0.2f / zoom;
cprintf("moveX down\n");
} else if (c == 'k') {
moveY -= 0.2f / zoom;
cprintf("moveX up\n");
} else if (c == ']') {
zoom += 3;
} else if (c == '[') {
zoom -= 3;
if (zoom <= 1)
zoom = 1;
} else if (c == 'q') {
break;
} else if (c == 'r') {
zoom = 1;
moveX = -0.5;
moveY = 0;
} else if (c == 'p') {
cprintf("x - HD\n");
cprintf("h - Move left\n");
cprintf("j - Move down\n");
cprintf("k - Move up\n");
cprintf("l - Move right\n");
cprintf("[ - Zoom out\n");
cprintf("] - Zoom in\n");
cprintf("q - Quit\n");
cprintf("r - Reset\n");
cprintf("p - Print this help\n");
} else {
cprintf("Unrecognized input: %d.\n", c);
}
plot(moveX, moveY, zoom, maxIterations, skip);
skip = 4;
c = 0;
cprintf(">");
}
return 0;
}
#else
int main(void) {
cprintf("This program can only run on platforms with floating point support.\n");
return 0;
}
#endif