]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/rain.c
ncurses 5.6 - patch 20080308
[ncurses.git] / test / rain.c
index f2c748eafb599354ed244900378c35dc3c2e4f6b..3f6c39fc8f19a066e52b4e5f871c4e62b7949203 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2002,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: rain.c,v 1.22 2006/05/20 15:34:27 tom Exp $
+ * $Id: rain.c,v 1.26 2008/03/09 00:17:09 tom Exp $
  */
 #include <test.priv.h>
 
 /* rain 11/3/1980 EPS/CITHEP */
 
-static float ranf(void);
-static void onsig(int sig);
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
+WANT_USE_WINDOW();
+
+#define MAX_DROP 5
+
+struct DATA;
+
+typedef void (*DrawPart) (struct DATA *);
+
+typedef struct DATA {
+    int y, x;
+#ifdef USE_PTHREADS
+    pthread_t thread;
+    DrawPart func;
+    int state;
+#endif
+} DATA;
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    curs_set(1);
+    endwin();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+static int
+random_x(void)
+{
+    return (((float) (COLS - 4) * ranf()) + 2);
+}
+
+static int
+random_y(void)
+{
+    return (((float) (LINES - 4) * ranf()) + 2);
+}
 
 static int
 next_j(int j)
 {
     if (j == 0)
-       j = 4;
+       j = MAX_DROP - 1;
     else
        --j;
     if (has_colors()) {
@@ -52,15 +97,117 @@ next_j(int j)
     return j;
 }
 
+static void
+part1(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, '.');
+}
+
+static void
+part2(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, 'o');
+}
+
+static void
+part3(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, 'O');
+}
+
+static void
+part4(DATA * drop)
+{
+    mvaddch(drop->y - 1, drop->x, '-');
+    mvaddstr(drop->y, drop->x - 1, "|.|");
+    mvaddch(drop->y + 1, drop->x, '-');
+}
+
+static void
+part5(DATA * drop)
+{
+    mvaddch(drop->y - 2, drop->x, '-');
+    mvaddstr(drop->y - 1, drop->x - 1, "/ \\");
+    mvaddstr(drop->y, drop->x - 2, "| O |");
+    mvaddstr(drop->y + 1, drop->x - 1, "\\ /");
+    mvaddch(drop->y + 2, drop->x, '-');
+}
+
+static void
+part6(DATA * drop)
+{
+    mvaddch(drop->y - 2, drop->x, ' ');
+    mvaddstr(drop->y - 1, drop->x - 1, "   ");
+    mvaddstr(drop->y, drop->x - 2, "     ");
+    mvaddstr(drop->y + 1, drop->x - 1, "   ");
+    mvaddch(drop->y + 2, drop->x, ' ');
+}
+
+#ifdef USE_PTHREADS
+static void
+napsome(void)
+{
+    refresh();
+    napms(60);
+}
+
+/*
+ * This runs inside the mutex.
+ */
+static int
+really_draw(WINDOW *win, void *arg)
+{
+    DATA *data = (DATA *) arg;
+
+    (void) win;
+    next_j(data->state);
+    data->func(data);
+    return OK;
+}
+
+static void
+draw_part(void (*func) (DATA *), int state, DATA * data)
+{
+    data->func = func;
+    data->state = state;
+    use_window(stdscr, really_draw, (void *) data);
+    napsome();
+}
+
+static void *
+draw_drop(void *arg)
+{
+    DATA mydata;
+
+    mydata = *(DATA *) arg;    /* make a copy of caller's data */
+
+    draw_part(part1, 0, &mydata);
+    draw_part(part2, 1, &mydata);
+    draw_part(part3, 2, &mydata);
+    draw_part(part4, 3, &mydata);
+    draw_part(part5, 4, &mydata);
+    draw_part(part6, 0, &mydata);
+
+    return NULL;
+}
+#endif
+
+static int
+get_input(void)
+{
+    int ch;
+    ch = USING_WINDOW(stdscr, wgetch);
+    return ch;
+}
+
 int
-main(
-       int argc GCC_UNUSED,
-       char *argv[]GCC_UNUSED)
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
 {
-    int x, y, j;
-    static int xpos[5], ypos[5];
-    float r;
-    float c;
+    DATA drop;
+    DATA last[MAX_DROP];
+    int j = 0;
+    bool done = FALSE;
 
     setlocale(LC_ALL, "");
 
@@ -82,52 +229,49 @@ main(
     curs_set(0);
     timeout(0);
 
-    r = (float) (LINES - 4);
-    c = (float) (COLS - 4);
-    for (j = 5; --j >= 0;) {
-       xpos[j] = (int) (c * ranf()) + 2;
-       ypos[j] = (int) (r * ranf()) + 2;
+    for (j = MAX_DROP; --j >= 0;) {
+       last[j].x = random_x();
+       last[j].y = random_y();
     }
 
-    for (j = 0;;) {
-       x = (int) (c * ranf()) + 2;
-       y = (int) (r * ranf()) + 2;
+    while (!done) {
+       drop.x = random_x();
+       drop.y = random_y();
 
-       mvaddch(y, x, '.');
+#ifdef USE_PTHREADS
+       if (pthread_create(&(drop.thread), NULL, draw_drop, &drop)) {
+           beep();
+           done = TRUE;
+           continue;
+       }
+#else
+       /*
+        * The non-threaded code draws parts of each drop on each loop.
+        */
+       part1(&drop);
 
-       mvaddch(ypos[j], xpos[j], 'o');
+       part2(&last[j]);
 
        j = next_j(j);
-       mvaddch(ypos[j], xpos[j], 'O');
+       part3(&last[j]);
 
        j = next_j(j);
-       mvaddch(ypos[j] - 1, xpos[j], '-');
-       mvaddstr(ypos[j], xpos[j] - 1, "|.|");
-       mvaddch(ypos[j] + 1, xpos[j], '-');
+       part4(&last[j]);
 
        j = next_j(j);
-       mvaddch(ypos[j] - 2, xpos[j], '-');
-       mvaddstr(ypos[j] - 1, xpos[j] - 1, "/ \\");
-       mvaddstr(ypos[j], xpos[j] - 2, "| O |");
-       mvaddstr(ypos[j] + 1, xpos[j] - 1, "\\ /");
-       mvaddch(ypos[j] + 2, xpos[j], '-');
+       part5(&last[j]);
 
        j = next_j(j);
-       mvaddch(ypos[j] - 2, xpos[j], ' ');
-       mvaddstr(ypos[j] - 1, xpos[j] - 1, "   ");
-       mvaddstr(ypos[j], xpos[j] - 2, "     ");
-       mvaddstr(ypos[j] + 1, xpos[j] - 1, "   ");
-       mvaddch(ypos[j] + 2, xpos[j], ' ');
+       part6(&last[j]);
 
-       xpos[j] = x;
-       ypos[j] = y;
+       last[j] = drop;
+#endif
 
-       switch (getch()) {
+       switch (get_input()) {
        case ('q'):
        case ('Q'):
-           curs_set(1);
-           endwin();
-           ExitProgram(EXIT_SUCCESS);
+           done = TRUE;
+           break;
        case 's':
            nodelay(stdscr, FALSE);
            break;
@@ -136,26 +280,12 @@ main(
            break;
 #ifdef KEY_RESIZE
        case (KEY_RESIZE):
-           r = (float) (LINES - 4);
-           c = (float) (COLS - 4);
            break;
 #endif
        }
        napms(50);
     }
-}
-
-static void
-onsig(int n GCC_UNUSED)
-{
     curs_set(1);
     endwin();
-    ExitProgram(EXIT_FAILURE);
-}
-
-static float
-ranf(void)
-{
-    long r = (rand() & 077777);
-    return ((float) r / 32768.);
+    ExitProgram(EXIT_SUCCESS);
 }