From: Christopher Lu Date: Wed, 9 Jul 2008 04:24:51 +0000 (-0400) Subject: added mandelsim.c X-Git-Url: http://git.joshuawise.com/mandelfpga.git/commitdiff_plain/bd7800913ecc8740c3c2f99d9c0ccdb8358462a8 added mandelsim.c --- diff --git a/mandelsim.c b/mandelsim.c new file mode 100644 index 0000000..16bdf46 --- /dev/null +++ b/mandelsim.c @@ -0,0 +1,137 @@ +#include +#include + +#define XRES 640 +#define YRES 480 +#define MAX_ITER 66 +#define MAXNUM 0x8000 +#define BITS 14 +#define BAIL (1 << (BITS + 1)) +#define BAIL_A (1 << BITS) + +SDL_Surface *screen; +typedef unsigned short num_t; + +typedef struct { + num_t mag; + num_t sig; +} sigmag_t; + +typedef struct { + sigmag_t r; + sigmag_t i; +} cplx_t; + +static inline cplx_t convert(num_t x, num_t y) +{ + sigmag_t r, i; + r.mag = x > MAXNUM ? -x : x; + r.sig = x > MAXNUM ? 1 : 0; + i.mag = y > MAXNUM ? -y : y; + i.sig = y > MAXNUM ? 1 : 0; + cplx_t res = {r, i}; +// printf("convert: output: x = %d, y = %d\n", res.r.mag, res.i.mag); + return res; +} + +static inline sigmag_t mul(sigmag_t x, sigmag_t y) +{ + num_t xm = x.mag; + num_t ym = y.mag; + num_t mag = + (ym & 0x2000 ? xm : 0) + + (ym & 0x1000 ? xm >> 1 : 0) + + (ym & 0x0800 ? xm >> 2 : 0) + + (ym & 0x0400 ? xm >> 3 : 0) + + (ym & 0x0200 ? xm >> 4 : 0) + + (ym & 0x0100 ? xm >> 5 : 0) + + (ym & 0x0080 ? xm >> 6 : 0) + + (ym & 0x0040 ? xm >> 7 : 0) + + (ym & 0x0020 ? xm >> 8 : 0) + + (ym & 0x0010 ? xm >> 9 : 0) + + (ym & 0x0008 ? xm >> 10 : 0) + + (ym & 0x0004 ? xm >> 11 : 0) + + (ym & 0x0002 ? xm >> 12 : 0) + + (ym & 0x0001 ? xm >> 13 : 0); + + num_t sig = x.sig ^ y.sig; + sigmag_t res = {mag, sig}; + return res; +} + +static inline unsigned int calc_piqsl(num_t x, num_t y) +{ +// printf("calc_piqsl: x = %d, y = %d ############################ \n", x, y); + unsigned int i; + cplx_t c = convert(x, y); + cplx_t z = c; +// printf("xmag = %d, xsig = %d, ymag = %d, ysig = %d\n", c.r.mag, c.r.sig, c.i.mag, c.i.sig); + for(i = 0; i < MAX_ITER; i++) { + sigmag_t r2 = mul(z.r, z.r); + sigmag_t i2 = mul(z.i, z.i); + sigmag_t ri = mul(z.r, z.i); +// printf("r2mag: %d i2mag: %d i: %d\n", r2.mag, i2.mag, i); + if((r2.mag + i2.mag) & BAIL || z.r.mag & BAIL || z.i.mag & BAIL + || z.r.mag & BAIL_A || z.i.mag & BAIL_A) { + break; + } + num_t rmag = r2.mag - i2.mag + (c.r.sig ? -c.r.mag : c.r.mag); + num_t imag = (ri.sig ? -ri.mag << 1 : ri.mag << 1) + (c.i.sig ? -c.i.mag : c.i.mag); + z = convert(rmag, imag); + } + +// printf("bailed at %d\n", i); + return (i == MAX_ITER ? 0 : i); +} + +void run_mandel() +{ + num_t i, j; + int dick = 160; + int zoom = 4; + unsigned int res, *p; + + SDL_LockSurface(screen); + p = screen->pixels; + + for(i = 0; i < XRES; i++) { + for(j = 0; j <3 *dick; j++) { + res = calc_piqsl((i - XRES/2) << zoom, (j - YRES/2) << zoom); + res = res == 0 ? 0 : MAX_ITER - res - 3; + p[i+j*XRES] = ((res & 0x1) << 23) | ((res & 0x8) << 18) | ((res & 0x40) << 13) | + ((res & 0x2) << 14) | ((res & 0x10) << 9) | ((res & 0x80) << 4) | + ((res & 0x4) << 5) | ((res & 0x20)); + + } + } + + SDL_UnlockSurface(screen); + SDL_Flip(screen); +} + +int main() +{ + SDL_Event ev; + screen = NULL; + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("Video init failed.\n"); + return 1; + } + + screen = SDL_SetVideoMode(XRES, YRES, 32, SDL_SWSURFACE); + if(!screen) { + printf("Screen init failed.\n"); + return 1; + } + atexit(SDL_Quit); + + run_mandel(); + while(SDL_WaitEvent(&ev)) { + switch(ev.type) { + case SDL_QUIT: exit(0); + default: break; + } + } + + return 0; +}