ncursesw-morphos/test/rain.c

292 lines
6.1 KiB
C
Raw Normal View History

2006-12-18 12:32:42 +08:00
/****************************************************************************
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
2006-12-18 12:32:42 +08:00
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, distribute with modifications, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included *
* in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
* *
* Except as contained in this notice, the name(s) of the above copyright *
* holders shall not be used in advertising or otherwise to promote the *
* sale, use or other dealings in this Software without prior written *
* authorization. *
****************************************************************************/
1997-05-15 12:00:00 +08:00
/*
* $Id: rain.c,v 1.26 2008/03/09 00:17:09 tom Exp $
1997-05-15 12:00:00 +08:00
*/
#include <test.priv.h>
/* rain 11/3/1980 EPS/CITHEP */
#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);
}
1997-05-15 12:00:00 +08:00
2002-10-13 11:35:53 +08:00
static int
next_j(int j)
1998-03-01 12:21:12 +08:00
{
2002-10-13 11:35:53 +08:00
if (j == 0)
j = MAX_DROP - 1;
2002-10-13 11:35:53 +08:00
else
--j;
1998-03-01 12:21:12 +08:00
if (has_colors()) {
2002-10-13 11:35:53 +08:00
int z = (int) (3 * ranf());
1998-03-01 12:21:12 +08:00
chtype color = COLOR_PAIR(z);
if (z)
color |= A_BOLD;
attrset(color);
}
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;
}
1997-05-15 12:00:00 +08:00
int
main(int argc GCC_UNUSED,
char *argv[]GCC_UNUSED)
1997-05-15 12:00:00 +08:00
{
DATA drop;
DATA last[MAX_DROP];
int j = 0;
bool done = FALSE;
2002-10-13 11:35:53 +08:00
setlocale(LC_ALL, "");
1997-05-15 12:00:00 +08:00
2006-12-18 12:32:42 +08:00
CATCHALL(onsig);
1997-05-15 12:00:00 +08:00
initscr();
1998-03-01 12:21:12 +08:00
if (has_colors()) {
int bg = COLOR_BLACK;
start_color();
2000-10-21 12:42:11 +08:00
#if HAVE_USE_DEFAULT_COLORS
1998-03-01 12:21:12 +08:00
if (use_default_colors() == OK)
2002-10-13 11:35:53 +08:00
bg = -1;
1998-03-01 12:21:12 +08:00
#endif
init_pair(1, COLOR_BLUE, bg);
init_pair(2, COLOR_CYAN, bg);
}
1997-05-15 12:00:00 +08:00
nl();
noecho();
curs_set(0);
1998-03-01 12:21:12 +08:00
timeout(0);
1997-05-15 12:00:00 +08:00
for (j = MAX_DROP; --j >= 0;) {
last[j].x = random_x();
last[j].y = random_y();
1997-05-15 12:00:00 +08:00
}
1998-03-01 12:21:12 +08:00
while (!done) {
drop.x = random_x();
drop.y = random_y();
1998-03-01 12:21:12 +08:00
#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);
1998-03-01 12:21:12 +08:00
part2(&last[j]);
1998-03-01 12:21:12 +08:00
j = next_j(j);
part3(&last[j]);
1998-03-01 12:21:12 +08:00
j = next_j(j);
part4(&last[j]);
1998-03-01 12:21:12 +08:00
j = next_j(j);
part5(&last[j]);
1998-03-01 12:21:12 +08:00
j = next_j(j);
part6(&last[j]);
2002-10-13 11:35:53 +08:00
last[j] = drop;
#endif
2002-10-13 11:35:53 +08:00
switch (get_input()) {
2002-10-13 11:35:53 +08:00
case ('q'):
case ('Q'):
done = TRUE;
break;
1999-10-24 12:32:42 +08:00
case 's':
nodelay(stdscr, FALSE);
break;
case ' ':
nodelay(stdscr, TRUE);
break;
1998-03-01 12:21:12 +08:00
#ifdef KEY_RESIZE
2002-10-13 11:35:53 +08:00
case (KEY_RESIZE):
1998-03-01 12:21:12 +08:00
break;
#endif
}
napms(50);
1997-05-15 12:00:00 +08:00
}
curs_set(1);
endwin();
ExitProgram(EXIT_SUCCESS);
1997-05-15 12:00:00 +08:00
}