]> git.sur5r.net Git - cc65/blob - samples/mandelbrot.c
Don't fiddle with foreign files.
[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 SCREEN_X        (tgi_getxres())
18 #define SCREEN_Y        (tgi_getyres())
19 #define MAXCOL          (tgi_getcolorcount())
20
21 #define maxiterations   32
22 #define fpshift         (10)
23 #define tofp(_x)        ((_x)<<fpshift)
24 #define fromfp(_x)      ((_x)>>fpshift)
25 #define fpabs(_x)       (abs(_x))
26
27 #define mulfp(_a,_b)    ((((signed long)_a)*(_b))>>fpshift)
28 #define divfp(_a,_b)    ((((signed long)_a)<<fpshift)/(_b))
29
30 /* Workaround missing clock stuff */
31 #ifdef __APPLE2__
32 #  define clock()       0
33 #  define CLK_TCK       1
34 #endif
35
36 /* Use dynamically loaded driver by default */
37 #ifndef DYN_DRV
38 #  define DYN_DRV       1
39 #endif
40
41 /* Use static local variables for speed */
42 #pragma static-locals (1);
43
44
45
46 void mandelbrot (signed short x1, signed short y1, signed short x2,
47                  signed short y2)
48 {
49     register unsigned char count;
50     register signed short r, r1, i;
51     register signed short xs, ys, xx, yy;
52     register signed short x, y;
53
54     /* calc stepwidth */
55     xs = ((x2 - x1) / (SCREEN_X));
56     ys = ((y2 - y1) / (SCREEN_Y));
57
58     yy = y1;
59     for (y = 0; y < (SCREEN_Y); y++) {
60         yy += ys;
61         xx = x1;
62         for (x = 0; x < (SCREEN_X); x++) {
63             xx += xs;
64             /* do iterations */
65             r = 0;
66             i = 0;
67             for (count = 0; (count < maxiterations) &&
68                  (fpabs (r) < tofp (2)) && (fpabs (i) < tofp (2));
69                  ++count) {
70                 r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
71                 /* i = (mulfp(mulfp(r,i),tofp(2)))+yy; */
72                 i = (((signed long) r * i) >> (fpshift - 1)) + yy;
73                 r = r1;
74             }
75             if (count == maxiterations) {
76                 tgi_setcolor (0);
77             } else {
78                 if (MAXCOL == 2)
79                     tgi_setcolor (1);
80                 else
81                     tgi_setcolor (count % MAXCOL);
82             }
83             /* set pixel */
84             tgi_setpixel (x, y);
85         }
86     }
87 }
88
89 int main (void)
90 {
91     clock_t t;
92     unsigned long sec;
93     unsigned sec10;
94     unsigned char err;
95
96     clrscr ();
97
98 #if DYN_DRV
99     /* Load the graphics driver */
100     cprintf ("initializing... mompls\r\n");
101     tgi_load_driver (tgi_stddrv);
102 #else
103     /* Install the graphics driver */
104     tgi_install (tgi_static_stddrv);
105 #endif
106     err = tgi_geterror ();
107     if (err  != TGI_ERR_OK) {
108         cprintf ("Error #%d initializing graphics.\r\n%s\r\n",
109                  err, tgi_geterrormsg (err));
110         exit (EXIT_FAILURE);
111     };
112     cprintf ("ok.\n\r");
113
114     /* Initialize graphics */
115     tgi_init ();
116     tgi_clear ();
117
118     t = clock ();
119
120     /* calc mandelbrot set */
121     mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
122
123     t = clock () - t;
124
125     /* Fetch the character from the keyboard buffer and discard it */
126     (void) cgetc ();
127
128     /* shut down gfx mode and return to textmode */
129     tgi_done ();
130
131     /* Calculate stats */
132     sec = (t * 10) / CLK_TCK;
133     sec10 = sec % 10;
134     sec /= 10;
135
136     /* Output stats */
137     cprintf ("time  : %lu.%us\n\r", sec, sec10);
138
139     /* Wait for a key, then end */
140     cputs ("Press any key when done...\n\r");
141     (void) cgetc ();
142
143     /* Done */
144     return EXIT_SUCCESS;
145 }