ncurses 5.5
[ncurses.git] / test / newdemo.c
1 /*
2  *  newdemo.c   -       A demo program using PDCurses. The program illustrate
3  *                      the use of colours for text output.
4  *
5  * $Id: newdemo.c,v 1.27 2005/05/28 21:40:00 tom Exp $
6  */
7
8 #include <test.priv.h>
9
10 #include <time.h>
11
12 #define delay_output(x) napms(x)
13
14 /*
15  *  The Australian map
16  */
17 static const char *AusMap[16] =
18 {
19     "           A           A ",
20     "    N.T. AAAAA       AAAA ",
21     "     AAAAAAAAAAA  AAAAAAAA ",
22     "   AAAAAAAAAAAAAAAAAAAAAAAAA Qld.",
23     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
24     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
25     " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
26     "   AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.",
27     "W.A. AAAAAAAAA      AAAAAA Vic.",
28     "       AAA   S.A.     AA",
29     "                       A  Tas.",
30     ""
31 };
32
33 /*
34  *  Funny messages
35  */
36 #define NMESSAGES   6
37
38 static NCURSES_CONST char *messages[] =
39 {
40     "Hello from the Land Down Under",
41     "The Land of crocs. and a big Red Rock",
42     "Where the sunflower runs along the highways",
43     "the dusty red roads lead one to loneliness",
44     "Blue sky in the morning and",
45     "freezing nights and twinkling stars",
46     ""
47 };
48
49 /*
50  *  Trap interrupt
51  */
52 static RETSIGTYPE
53 trap(int sig GCC_UNUSED)
54 {
55     endwin();
56     ExitProgram(EXIT_FAILURE);
57 }
58
59 /*
60  *  Wait for user
61  */
62 static int
63 WaitForUser(WINDOW *win)
64 {
65     time_t t;
66     chtype key;
67
68     nodelay(win, TRUE);
69     t = time((time_t *) 0);
70     while (1) {
71         if ((int) (key = wgetch(win)) != ERR) {
72             if (key == 'q' || key == 'Q')
73                 return 1;
74             else
75                 return 0;
76         }
77         if (time((time_t *) 0) - t > 5)
78             return 0;
79     }
80 }
81
82 static void
83 set_colors(WINDOW *win, int pair, int foreground, int background)
84 {
85     if (has_colors()) {
86         if (pair > COLOR_PAIRS)
87             pair = COLOR_PAIRS;
88         init_pair(pair, foreground, background);
89         wattrset(win, COLOR_PAIR(pair));
90     }
91 }
92
93 static chtype
94 use_colors(WINDOW *win, int pair, chtype attrs)
95 {
96     if (has_colors()) {
97         if (pair > COLOR_PAIRS)
98             pair = COLOR_PAIRS;
99         attrs |= COLOR_PAIR(pair);
100     }
101     wattrset(win, attrs);
102     return attrs;
103 }
104
105 /*
106  * Test sub windows
107  */
108 static int
109 SubWinTest(WINDOW *win)
110 {
111     int w, h, sw, sh, bx, by;
112     WINDOW *swin1, *swin2, *swin3;
113
114     getmaxyx(win, h, w);
115     getbegyx(win, by, bx);
116     sw = w / 3;
117     sh = h / 3;
118     if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL)
119         return 1;
120     if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL)
121         return 1;
122     if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL)
123         return 1;
124
125     set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
126     werase(swin1);
127     mvwaddstr(swin1, 0, 3, "Sub-window 1");
128     wrefresh(swin1);
129
130     set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
131     werase(swin2);
132     mvwaddstr(swin2, 0, 3, "Sub-window 2");
133     wrefresh(swin2);
134
135     set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
136     werase(swin3);
137     mvwaddstr(swin3, 0, 3, "Sub-window 3");
138     wrefresh(swin3);
139
140     delwin(swin1);
141     delwin(swin2);
142     delwin(swin3);
143     WaitForUser(win);
144     return 0;
145 }
146
147 static int
148 bounce(int n, int *dir, int len)
149 {
150     if (*dir > 0)
151         ++n;
152     else
153         --n;
154     if (n <= 1 || n >= len - 2)
155         *dir = *dir ? 0 : 1;
156     return n;
157 }
158
159 /*
160  *  Bouncing balls
161  */
162 static int
163 BouncingBalls(WINDOW *win)
164 {
165     int w, h;
166     int x1, y1, xd1, yd1;
167     int x2, y2, xd2, yd2;
168     int x3, y3, xd3, yd3;
169
170     getmaxyx(win, h, w);
171
172     x1 = 2 + rand() % (w - 4);
173     y1 = 2 + rand() % (h - 4);
174     x2 = 2 + rand() % (w - 4);
175     y2 = 2 + rand() % (h - 4);
176     x3 = 2 + rand() % (w - 4);
177     y3 = 2 + rand() % (h - 4);
178
179     xd1 = 1;
180     yd1 = 1;
181     xd2 = 1;
182     yd2 = 0;
183     xd3 = 0;
184     yd3 = 1;
185
186     nodelay(win, TRUE);
187
188     while (wgetch(win) == ERR) {
189         x1 = bounce(x1, &xd1, w);
190         y1 = bounce(y1, &yd1, h);
191         x2 = bounce(x2, &xd2, w);
192         y2 = bounce(y2, &yd2, h);
193         x3 = bounce(x3, &xd3, w);
194         y3 = bounce(y3, &yd3, h);
195
196         set_colors(win, 11, COLOR_RED, COLOR_BLUE);
197         mvwaddch(win, y1, x1, 'O');
198
199         set_colors(win, 12, COLOR_BLUE, COLOR_RED);
200         mvwaddch(win, y2, x2, '*');
201
202         set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
203         mvwaddch(win, y3, x3, '@');
204
205         wmove(win, 0, 0);
206         wrefresh(win);
207         delay_output(100);
208     }
209     return 0;
210 }
211
212 /*
213  *  Main driver
214  */
215 int
216 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
217 {
218     WINDOW *win;
219     int w, x, y, i, j, k;
220     char buffer[200];
221     const char *message;
222     int width, height;
223     chtype save[80];
224     chtype c;
225
226     setlocale(LC_ALL, "");
227
228     initscr();
229     if (has_colors())
230         start_color();
231     cbreak();
232     curs_set(0);
233     signal(SIGINT, trap);
234     width = 48;
235     height = 14;                /* Create a drawing window */
236     win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
237     if (win == NULL) {
238         endwin();
239         ExitProgram(EXIT_FAILURE);
240     }
241
242     while (1) {
243         set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
244         werase(win);
245
246         set_colors(win, 2, COLOR_RED, COLOR_RED);
247         box(win, ACS_VLINE, ACS_HLINE);
248         wrefresh(win);
249         /* Do ramdom output of a character */
250         use_colors(win, 1, A_NORMAL);
251         c = 'a';
252         for (i = 0; i < 5000; ++i) {
253             x = rand() % (width - 2) + 1;
254             y = rand() % (height - 2) + 1;
255             mvwaddch(win, y, x, c);
256             wrefresh(win);
257             nodelay(win, TRUE);
258             if (wgetch(win) != ERR)
259                 break;
260             if (i == 2000) {
261                 c = 'b';
262                 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
263             }
264         }
265
266         SubWinTest(win);
267         /* Erase and draw green window */
268         set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
269         wbkgd(win, use_colors(win, 4, A_BOLD));
270         werase(win);
271         wrefresh(win);
272         /* Draw RED bounding box */
273         use_colors(win, 2, A_NORMAL);
274         box(win, ' ', ' ');
275         wrefresh(win);
276         /* Display Australia map */
277         use_colors(win, 4, A_BOLD);
278         i = 0;
279         while (*AusMap[i]) {
280             mvwaddstr(win, i + 1, 8, AusMap[i]);
281             wrefresh(win);
282             delay_output(50);
283             ++i;
284         }
285
286         set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
287         use_colors(win, 5, A_BLINK);
288         mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
289         wrefresh(win);
290
291         /* Draw running messages */
292         set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
293         message = messages[j = 0];
294         i = 1;
295         w = width - 2;
296         strcpy(buffer, message);
297         while (j < NMESSAGES) {
298             while ((int) strlen(buffer) < w) {
299                 strcat(buffer, " ... ");
300                 strcat(buffer, messages[++j % NMESSAGES]);
301             }
302
303             if (i < w)
304                 mvwaddnstr(win, height / 2, w - i, buffer, i);
305             else
306                 mvwaddnstr(win, height / 2, 1, buffer, w);
307
308             wrefresh(win);
309             nodelay(win, TRUE);
310             if (wgetch(win) != ERR) {
311                 flushinp();
312                 break;
313             }
314             if (i++ >= w) {
315                 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
316             }
317             delay_output(100);
318         }
319
320         j = 0;
321         /*  Draw running As across in RED */
322         set_colors(win, 7, COLOR_RED, COLOR_GREEN);
323         for (i = 2; i < width - 4; ++i) {
324             k = mvwinch(win, 4, i);
325             if (k == ERR)
326                 break;
327             save[j++] = c = k;
328             c &= A_CHARTEXT;
329             mvwaddch(win, 4, i, c);
330         }
331         wrefresh(win);
332
333         /* Put a message up wait for a key */
334         i = height - 2;
335         use_colors(win, 5, A_NORMAL);
336         mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
337         wrefresh(win);
338
339         if (WaitForUser(win) == 1)
340             break;
341
342         j = 0;                  /* Restore the old line */
343         for (i = 2; i < width - 4; ++i)
344             mvwaddch(win, 4, i, save[j++]);
345         wrefresh(win);
346
347         BouncingBalls(win);
348         /* Put a message up wait for a key */
349         i = height - 2;
350         use_colors(win, 5, A_NORMAL);
351         mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
352         wrefresh(win);
353         if (WaitForUser(win) == 1)
354             break;
355     }
356     endwin();
357     ExitProgram(EXIT_SUCCESS);
358 }