]> git.sur5r.net Git - cc65/blob - samples/mandelbrot.c
Fixed minor issues with the modifiers: Some modifiers where accepted (and
[cc65] / samples / mandelbrot.c
1 /*****************************************************************************
2  * mandelbrot sample program for cc65.                                       *
3  *                                                                           *
4  * (w)2002 by groepaz/hitmen, TGI support by Stefan Haubenthal               *
5  *****************************************************************************/
6
7
8
9 #include <stdlib.h>
10 #include <time.h>
11 #include <conio.h>
12 #include <tgi.h>
13
14
15
16 /* Graphics definitions */
17 #define GRAPHMODE       TGI_MODE_320_200_2
18 #define SCREEN_X        (tgi_getmaxx()+1)
19 #define SCREEN_Y        (tgi_getmaxy()+1)
20 #define MAXCOL          (tgi_getmaxcolor()+1)
21
22 #define maxiterations   32
23 #define fpshift         (10)
24 #define tofp(_x)        ((_x)<<fpshift)
25 #define fromfp(_x)      ((_x)>>fpshift)
26 #define fpabs(_x)       (abs(_x))
27
28 #define mulfp(_a,_b)    ((((signed long)_a)*(_b))>>fpshift)
29 #define divfp(_a,_b)    ((((signed long)_a)<<fpshift)/(_b))
30
31 /* Use static local variables for speed */
32 #pragma staticlocals (1);
33
34
35
36 void mandelbrot (signed short x1, signed short y1, signed short x2,
37                  signed short y2)
38 {
39     register unsigned char count;
40     register signed short r, r1, i;
41     register signed short xs, ys, xx, yy;
42     register signed short x, y;
43
44     /* calc stepwidth */
45     xs = ((x2 - x1) / (SCREEN_X));
46     ys = ((y2 - y1) / (SCREEN_Y));
47
48     yy = y1;
49     for (y = 0; y < (SCREEN_Y); y++) {
50         yy += ys;
51         xx = x1;
52         for (x = 0; x < (SCREEN_X); x++) {
53             xx += xs;
54             /* do iterations */
55             r = 0;
56             i = 0;
57             for (count = 0; (count < maxiterations) &&
58                  (fpabs (r) < tofp (2)) && (fpabs (i) < tofp (2));
59                  ++count) {
60                 r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
61                 /* i = (mulfp(mulfp(r,i),tofp(2)))+yy; */
62                 i = (((signed long) r * i) >> (fpshift - 1)) + yy;
63                 r = r1;
64             }
65             if (count == maxiterations) {
66                 tgi_setcolor (0);
67             } else {
68                 if (MAXCOL == 2)
69                     tgi_setcolor (1);
70                 else
71                     tgi_setcolor (count % MAXCOL);
72             }
73             /* set pixel */
74             tgi_setpixel (x, y);
75         }
76     }
77 }
78
79 int main (void)
80 {
81     clock_t t;
82     unsigned long sec;
83     unsigned sec10;
84     unsigned char err;
85
86     clrscr ();
87
88     /* Load the graphics driver */                       
89     cprintf ("initializing... mompls\r\n");
90     tgi_load (GRAPHMODE);
91     err = tgi_geterror ();
92     if (err  != TGI_ERR_OK) {
93         cprintf ("Error #%d initializing graphics.\r\n%s\r\n",
94                  err, tgi_geterrormsg (err));
95         exit (EXIT_FAILURE);
96     };
97     cprintf ("ok.\n\r");
98
99     /* Initialize graphics */
100     tgi_init ();
101     tgi_clear ();
102
103     t = clock ();
104
105     /* calc mandelbrot set */
106     mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
107
108     t = clock () - t;
109
110     /* Fetch the character from the keyboard buffer and discard it */
111     (void) cgetc ();
112
113     /* shut down gfx mode and return to textmode */
114     tgi_done ();
115
116     /* Calculate stats */
117     sec = (t * 10) / CLK_TCK;
118     sec10 = sec % 10;
119     sec /= 10;
120
121     /* Output stats */
122     cprintf ("time  : %lu.%us\n\r", sec, sec10);
123
124     /* Wait for a key, then end */
125     cputs ("Press any key when done...\n\r");
126     (void) cgetc ();
127
128     /* Done */
129     return EXIT_SUCCESS;
130
131 }