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