]> git.sur5r.net Git - cc65/blob - samples/mandelbrot.c
The _printf routine does not return anything.
[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 #if defined(__APPLE2__) || defined(__APPLE2ENH__)
18 #  define GRAPHMODE     TGI_MODE_280_192_8
19 #else
20 #  define GRAPHMODE     TGI_MODE_320_200_2
21 #endif
22 #define SCREEN_X        (tgi_getxres())
23 #define SCREEN_Y        (tgi_getyres())
24 #define MAXCOL          (tgi_getcolorcount())
25
26 #define maxiterations   32
27 #define fpshift         (10)
28 #define tofp(_x)        ((_x)<<fpshift)
29 #define fromfp(_x)      ((_x)>>fpshift)
30 #define fpabs(_x)       (abs(_x))
31
32 #define mulfp(_a,_b)    ((((signed long)_a)*(_b))>>fpshift)
33 #define divfp(_a,_b)    ((((signed long)_a)<<fpshift)/(_b))
34
35 /* Workaround missing clock stuff */
36 #if defined(__APPLE2__) || defined(__APPLE2ENH__)
37 #  define clock()       0
38 #  define CLK_TCK       1
39 #endif
40
41 /* Use static local variables for speed */
42 #pragma staticlocals (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     /* Load the graphics driver */                       
99     cprintf ("initializing... mompls\r\n");
100     tgi_load (GRAPHMODE);
101     err = tgi_geterror ();
102     if (err  != TGI_ERR_OK) {
103         cprintf ("Error #%d initializing graphics.\r\n%s\r\n",
104                  err, tgi_geterrormsg (err));
105         exit (EXIT_FAILURE);
106     };
107     cprintf ("ok.\n\r");
108
109     /* Initialize graphics */
110     tgi_init ();
111     tgi_clear ();
112
113     t = clock ();
114
115     /* calc mandelbrot set */
116     mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
117
118     t = clock () - t;
119
120     /* Fetch the character from the keyboard buffer and discard it */
121     (void) cgetc ();
122
123     /* shut down gfx mode and return to textmode */
124     tgi_done ();
125
126     /* Calculate stats */
127     sec = (t * 10) / CLK_TCK;
128     sec10 = sec % 10;
129     sec /= 10;
130
131     /* Output stats */
132     cprintf ("time  : %lu.%us\n\r", sec, sec10);
133
134     /* Wait for a key, then end */
135     cputs ("Press any key when done...\n\r");
136     (void) cgetc ();
137
138     /* Done */
139     return EXIT_SUCCESS;
140
141 }