]>
Commit | Line | Data |
---|---|---|
1 | #include <stdio.h> | |
2 | #include <SDL/SDL.h> | |
3 | ||
4 | #define XRES 640 | |
5 | #define YRES 480 | |
6 | #define MAX_ITER 66 | |
7 | #define MAXNUM 0x8000 | |
8 | ||
9 | /* be sure to change the number of bits in the multiplier when doing this | |
10 | * bits > 14 need extension of num_t to unsigned int */ | |
11 | #define BITS 14 | |
12 | #define BAIL (1 << (BITS + 1)) | |
13 | #define BAIL_A (1 << BITS) | |
14 | ||
15 | SDL_Surface *screen; | |
16 | typedef unsigned short num_t; | |
17 | ||
18 | typedef struct { | |
19 | num_t mag; | |
20 | num_t sig; | |
21 | } sigmag_t; | |
22 | ||
23 | typedef struct { | |
24 | sigmag_t r; | |
25 | sigmag_t i; | |
26 | } cplx_t; | |
27 | ||
28 | static inline cplx_t convert(num_t x, num_t y) | |
29 | { | |
30 | sigmag_t r, i; | |
31 | r.mag = x > MAXNUM ? -x : x; | |
32 | r.sig = x > MAXNUM ? 1 : 0; | |
33 | i.mag = y > MAXNUM ? -y : y; | |
34 | i.sig = y > MAXNUM ? 1 : 0; | |
35 | cplx_t res = {r, i}; | |
36 | // printf("convert: output: x = %d, y = %d\n", res.r.mag, res.i.mag); | |
37 | return res; | |
38 | } | |
39 | ||
40 | static inline sigmag_t mul(sigmag_t x, sigmag_t y) | |
41 | { | |
42 | num_t xm = x.mag; | |
43 | num_t ym = y.mag; | |
44 | num_t mag = | |
45 | (ym & 0x2000 ? xm : 0) + | |
46 | (ym & 0x1000 ? xm >> 1 : 0) + | |
47 | (ym & 0x0800 ? xm >> 2 : 0) + | |
48 | (ym & 0x0400 ? xm >> 3 : 0) + | |
49 | (ym & 0x0200 ? xm >> 4 : 0) + | |
50 | (ym & 0x0100 ? xm >> 5 : 0) + | |
51 | (ym & 0x0080 ? xm >> 6 : 0) + | |
52 | (ym & 0x0040 ? xm >> 7 : 0) + | |
53 | (ym & 0x0020 ? xm >> 8 : 0) + | |
54 | (ym & 0x0010 ? xm >> 9 : 0) + | |
55 | (ym & 0x0008 ? xm >> 10 : 0) + | |
56 | (ym & 0x0004 ? xm >> 11 : 0) + | |
57 | (ym & 0x0002 ? xm >> 12 : 0) + | |
58 | (ym & 0x0001 ? xm >> 13 : 0); | |
59 | ||
60 | num_t sig = x.sig ^ y.sig; | |
61 | sigmag_t res = {mag, sig}; | |
62 | return res; | |
63 | } | |
64 | ||
65 | static inline unsigned int calc_piqsl(num_t x, num_t y) | |
66 | { | |
67 | // printf("calc_piqsl: x = %d, y = %d ############################ \n", x, y); | |
68 | unsigned int i; | |
69 | cplx_t c = convert(x, y); | |
70 | cplx_t z = c; | |
71 | // printf("xmag = %d, xsig = %d, ymag = %d, ysig = %d\n", c.r.mag, c.r.sig, c.i.mag, c.i.sig); | |
72 | for(i = 0; i < MAX_ITER; i++) { | |
73 | sigmag_t r2 = mul(z.r, z.r); | |
74 | sigmag_t i2 = mul(z.i, z.i); | |
75 | sigmag_t ri = mul(z.r, z.i); | |
76 | // printf("r2mag: %d i2mag: %d i: %d\n", r2.mag, i2.mag, i); | |
77 | if((r2.mag + i2.mag) & BAIL || z.r.mag & BAIL || z.i.mag & BAIL | |
78 | || z.r.mag & BAIL_A || z.i.mag & BAIL_A) { | |
79 | break; | |
80 | } | |
81 | num_t rmag = r2.mag - i2.mag + (c.r.sig ? -c.r.mag : c.r.mag); | |
82 | num_t imag = (ri.sig ? -ri.mag << 1 : ri.mag << 1) + (c.i.sig ? -c.i.mag : c.i.mag); | |
83 | z = convert(rmag, imag); | |
84 | } | |
85 | ||
86 | // printf("bailed at %d\n", i); | |
87 | return (i == MAX_ITER ? 0 : i); | |
88 | } | |
89 | ||
90 | void run_mandel() | |
91 | { | |
92 | num_t i, j; | |
93 | int dick = 160; | |
94 | int zoom = 4; | |
95 | unsigned int res, *p; | |
96 | ||
97 | SDL_LockSurface(screen); | |
98 | p = screen->pixels; | |
99 | ||
100 | for(i = 0; i < XRES; i++) { | |
101 | for(j = 0; j <3 *dick; j++) { | |
102 | res = calc_piqsl((i - XRES/2) << zoom, (j - YRES/2) << zoom); | |
103 | res = res == 0 ? 0 : MAX_ITER - res - 3; | |
104 | p[i+j*XRES] = ((res & 0x1) << 23) | ((res & 0x8) << 18) | ((res & 0x40) << 13) | | |
105 | ((res & 0x2) << 14) | ((res & 0x10) << 9) | ((res & 0x80) << 4) | | |
106 | ((res & 0x4) << 5) | ((res & 0x20)); | |
107 | ||
108 | } | |
109 | } | |
110 | ||
111 | SDL_UnlockSurface(screen); | |
112 | SDL_Flip(screen); | |
113 | } | |
114 | ||
115 | int main() | |
116 | { | |
117 | SDL_Event ev; | |
118 | screen = NULL; | |
119 | if(SDL_Init(SDL_INIT_VIDEO) < 0) { | |
120 | printf("Video init failed.\n"); | |
121 | return 1; | |
122 | } | |
123 | ||
124 | screen = SDL_SetVideoMode(XRES, YRES, 32, SDL_SWSURFACE); | |
125 | if(!screen) { | |
126 | printf("Screen init failed.\n"); | |
127 | return 1; | |
128 | } | |
129 | atexit(SDL_Quit); | |
130 | ||
131 | run_mandel(); | |
132 | while(SDL_WaitEvent(&ev)) { | |
133 | switch(ev.type) { | |
134 | case SDL_QUIT: exit(0); | |
135 | default: break; | |
136 | } | |
137 | } | |
138 | ||
139 | return 0; | |
140 | } |