]> git.sur5r.net Git - cc65/blob - samples/plasma.c
Added the plasma sample to the README file.
[cc65] / samples / plasma.c
1 /*****************************************************************************\r
2  * plasma test program for cc65.                                             *\r
3  *                                                                           *\r
4  * (w)2001 by groepaz/hitmen                                                 *\r
5  *                                                                           *\r
6  * Cleanup and porting by Ullrich von Bassewitz.                             *\r
7  *                                                                           *\r
8  *****************************************************************************/\r
9 \r
10 \r
11 \r
12 #include <stdlib.h>\r
13 #include <time.h>\r
14 #include <conio.h>\r
15 \r
16 \r
17 \r
18 #if defined(__C64__)\r
19 #  define SCREEN1               0xE000\r
20 #  define SCREEN2               0xE400\r
21 #  define CHARSET               0xE800\r
22 #  define outb(addr,val)        (*(addr)) = (val)\r
23 #  define inb(addr)             (*(addr))\r
24 #elif defined(__CBM510__)\r
25 #  define SCREEN1               0xF000\r
26 #  define SCREEN2               0xF400\r
27 #  define CHARSET               0xE000\r
28 #  define outb(addr,val)        pokebsys ((unsigned)(addr), val)\r
29 #  define inb(addr)             peekbsys ((unsigned)(addr))\r
30 #endif\r
31 \r
32 \r
33 \r
34 /* Values for the VIC address register to switch between the two pages */\r
35 #define PAGE1                   ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)\r
36 #define PAGE2                   ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)\r
37 \r
38 \r
39 \r
40 /* Use static local variables for speed */\r
41 #pragma staticlocals (1);\r
42 \r
43 \r
44 \r
45 static const unsigned char sinustable[0x100] = {\r
46     0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,\r
47     0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,\r
48     0x4f, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3f, 0x3c,\r
49     0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28,\r
50     0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x18,\r
51     0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x0d, 0x0c,\r
52     0x0b, 0x0a, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,\r
53     0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,\r
54     0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,\r
55     0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0a,\r
56     0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x15,\r
57     0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24,\r
58     0x26, 0x28, 0x2b, 0x2d, 0x2f, 0x32, 0x34, 0x37,\r
59     0x39, 0x3c, 0x3f, 0x41, 0x44, 0x47, 0x4a, 0x4d,\r
60     0x4f, 0x52, 0x55, 0x58, 0x5b, 0x5e, 0x61, 0x64,\r
61     0x67, 0x6a, 0x6d, 0x70, 0x74, 0x77, 0x7a, 0x7d,\r
62     0x80, 0x83, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96,\r
63     0x99, 0x9c, 0x9f, 0xa2, 0xa5, 0xa8, 0xab, 0xae,\r
64     0xb1, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc1, 0xc4,\r
65     0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8,\r
66     0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8,\r
67     0xea, 0xeb, 0xed, 0xef, 0xf0, 0xf1, 0xf3, 0xf4,\r
68     0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc,\r
69     0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,\r
70     0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfd,\r
71     0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf6,\r
72     0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xed, 0xeb,\r
73     0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc,\r
74     0xda, 0xd8, 0xd5, 0xd3, 0xd1, 0xce, 0xcc, 0xc9,\r
75     0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9, 0xb6, 0xb3,\r
76     0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c,\r
77     0x99, 0x96, 0x93, 0x90, 0x8c, 0x89, 0x86, 0x83\r
78 };\r
79 \r
80 \r
81 \r
82 static unsigned char *scrn;\r
83 \r
84 \r
85 \r
86 static void doplasma (void)\r
87 {\r
88     unsigned char xbuf[40];\r
89     unsigned char ybuf[25];\r
90     unsigned char i,ii;\r
91     unsigned char c1a,c1b;\r
92     unsigned char c2a,c2b;\r
93     unsigned char c1A,c1B;\r
94     unsigned char c2A,c2B;\r
95 \r
96     c1a = c1A;\r
97     c1b = c1B;\r
98     for (ii = 0; ii < 25; ++ii) {\r
99         ybuf[ii] = (sinustable[c1a] + sinustable[c1b]);\r
100         c1a += 4;\r
101         c1b += 9;\r
102     }\r
103     c1A += 3;\r
104     c1B -= 5;\r
105     c2a = c2A;\r
106     c2b = c2B;\r
107     for (i = 0; i < 40; ++i) {\r
108         xbuf[i] = (sinustable[c2a] + sinustable[c2b]);\r
109         c2a += 3;\r
110         c2b += 7;\r
111     }\r
112     c2A += 2;\r
113     c2B -= 3;\r
114     for (ii = 0; ii < 25; ++ii) {\r
115         /* Unrolling the following loop will give a speed increase of\r
116          * nearly 100% (~24fps), but it will also increase the code \r
117          * size a lot.\r
118          */\r
119         for (i = 0; i < 40; ++i, ++scrn) {\r
120             *scrn = (xbuf[i] + ybuf[ii]);\r
121         }\r
122     }\r
123 }\r
124 \r
125 \r
126 \r
127 static void makechar (void)\r
128 {\r
129     static const unsigned char bittab[8] = {\r
130         0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80\r
131     };\r
132     unsigned char i, ii, b, s;\r
133     unsigned c;\r
134 \r
135     gotoxy (0, 1);\r
136     for (c = 0; c < 0x100; ++c) {\r
137         s = sinustable[c];\r
138         for (i = 0; i < 8; ++i){\r
139             b = 0;\r
140             for (ii = 0; ii < 8; ++ii) {\r
141                 if ((rand() & 0xFF) > s) {\r
142                     b |= bittab[ii];\r
143                 }\r
144             }\r
145             ((unsigned char*)CHARSET) [(c*8) + i] = b;\r
146         }\r
147         if ((c & 0x07) == 0) {\r
148             cputc ('.');\r
149         }\r
150     }\r
151 }\r
152 \r
153 \r
154 \r
155 int main (void)\r
156 {\r
157     unsigned char border;\r
158     unsigned char background;\r
159     unsigned char text;\r
160     unsigned char v;\r
161     clock_t       t;\r
162     unsigned long f = 0;\r
163     unsigned long sec;\r
164     unsigned      sec10;\r
165     unsigned long fps;\r
166     unsigned      fps10;\r
167 \r
168 \r
169     clrscr ();\r
170     cprintf ("Making charset, mompls");\r
171     makechar();\r
172 \r
173     /* Set the border and background colors */\r
174     border     = bordercolor (COLOR_BLUE);\r
175     background = bgcolor (COLOR_BLUE);\r
176     text       = textcolor (COLOR_BLACK);\r
177     clrscr ();\r
178 \r
179 #if defined(__C64__)\r
180     /* Move the VIC 16K block */\r
181     outb (&CIA2.pra, 0x00);\r
182 #endif\r
183 \r
184     /* Remember the VIC address register */\r
185     v = inb (&VIC.addr);\r
186 \r
187     /* Run the demo until a key was hit */\r
188     t = clock ();\r
189     while (!kbhit()) {\r
190         /* Build page 1, then make it visible */\r
191         scrn = (unsigned char*)SCREEN1;\r
192         doplasma();\r
193         outb (&VIC.addr, PAGE1);\r
194 \r
195         /* Build page 2, then make it visible */\r
196         scrn = (unsigned char*)SCREEN2;\r
197         doplasma();\r
198         outb (&VIC.addr, PAGE2);\r
199 \r
200         /* Count frames */\r
201         f += 2;\r
202     };\r
203     t = clock() - t;\r
204 \r
205     /* Switch back the VIC screen */\r
206     outb (&VIC.addr, v);\r
207 \r
208 #if defined(__C64__)\r
209     /* Move back the VIC 16K block */\r
210     outb (&CIA2.pra, 0x03);\r
211 #endif\r
212 \r
213     /* Fetch the character from the keyboard buffer and discard it */\r
214     (void) cgetc();\r
215 \r
216     /* Reset screen colors */\r
217     bordercolor (border);\r
218     bgcolor (background);\r
219     textcolor (text);\r
220     clrscr();\r
221 \r
222     /* Calculate stats */\r
223     sec   = (t * 10) / CLK_TCK;\r
224     sec10 = sec % 10;\r
225     sec  /= 10;\r
226     fps   = (f * (CLK_TCK * 10)) / t;\r
227     fps10 = fps % 10;\r
228     fps  /= 10;\r
229 \r
230     /* Output stats */\r
231     gotoxy (0, 0); cprintf ("time  : %lu.%us", sec, sec10);\r
232     gotoxy (0, 1); cprintf ("frames: %lu", f);\r
233     gotoxy (0, 2); cprintf ("fps   : %lu.%u", fps, fps10);\r
234 \r
235     /* Wait for a key, then end */\r
236     cputsxy (0, 4, "Press any key when done...");\r
237     (void) cgetc ();\r
238 \r
239     /* Done */\r
240     return EXIT_SUCCESS;\r
241 }\r
242 \r
243 \r