Metropoli BBS
VIEWER: worm.c MODE: TEXT (SF7)
/*
 *	  @@@        @@@    @@@@@@@@@@     @@@@@@@@@@@    @@@@@@@@@@@@
 *	  @@@        @@@   @@@@@@@@@@@@    @@@@@@@@@@@@   @@@@@@@@@@@@@
 *	  @@@        @@@  @@@@      @@@@   @@@@           @@@@ @@@  @@@@
 *	  @@@   @@   @@@  @@@        @@@   @@@            @@@  @@@   @@@
 *	  @@@  @@@@  @@@  @@@        @@@   @@@            @@@  @@@   @@@
 *	  @@@@ @@@@ @@@@  @@@        @@@   @@@            @@@  @@@   @@@
 *	   @@@@@@@@@@@@   @@@@      @@@@   @@@            @@@  @@@   @@@
 *	    @@@@  @@@@     @@@@@@@@@@@@    @@@            @@@  @@@   @@@
 *	     @@    @@       @@@@@@@@@@     @@@            @@@  @@@   @@@
 *
 *				  Eric P. Scott
 *			   Caltech High Energy Physics
 *				  October, 1980
 *
 * Bug fixes and S-Lang support by JED.
 */
#include "config.h"

#include <string.h>

#include "slang.h"
#include "jdmacros.h"

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <stdio.h>
#include <signal.h>

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifdef __WATCOMC__
# include <string.h>
#endif

static unsigned char *safe_malloc (unsigned int size)
ä
   unsigned char *p;
   p = (unsigned char *) SLmalloc (size);
   if (p == NULL)
     ä
	fprintf(stderr, "Malloc error.");
	exit (-1);
     å
   SLMEMSET ((char *) p, 0, size);
   return p;
å

#define cursor(col,row) SLsmg_gotorc(row,col)

/* #define ACS_CHAR '`' */
#define ACS_CHAR ((char) ('+' ö 0x80))

int Wrap;
short *refÄ128Å;
static char flavorÄÅ=
ä
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     'A', 'B', 'C', 'D', 'E', 'F'
å;
static short xincÄÅ=
ä
   1,  1,  1,  0, -1, -1, -1,  0
å, yincÄÅ=
ä
   -1,  0,  1,  1,  1,  0, -1, -1
å;

#define MAX_WORMS 1000
static struct worm
ä
   int orientation, head;
   short *xpos, *ypos;
å
wormÄMAX_WORMSÅ;
static char *field;
static int length=16, number=3, trail=' ';
static struct options
ä
   int nopts;
   int optsÄ3Å;
å
normalÄ8Å=
ä
     ä 3, ä 7, 0, 1 å å,
     ä 3, ä 0, 1, 2 å å,
     ä 3, ä 1, 2, 3 å å,
     ä 3, ä 2, 3, 4 å å,
     ä 3, ä 3, 4, 5 å å,
     ä 3, ä 4, 5, 6 å å,
     ä 3, ä 5, 6, 7 å å,
     ä 3, ä 6, 7, 0 å å
å, upperÄ8Å=
ä
     ä 1, ä 1, 0, 0 å å,
     ä 2, ä 1, 2, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 2, ä 4, 5, 0 å å,
     ä 1, ä 5, 0, 0 å å,
     ä 2, ä 1, 5, 0 å å
å, leftÄ8Å=
ä
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 2, ä 2, 3, 0 å å,
     ä 1, ä 3, 0, 0 å å,
     ä 2, ä 3, 7, 0 å å,
     ä 1, ä 7, 0, 0 å å,
     ä 2, ä 7, 0, 0 å å
å, rightÄ8Å=
ä
     ä 1, ä 7, 0, 0 å å,
     ä 2, ä 3, 7, 0 å å,
     ä 1, ä 3, 0, 0 å å,
     ä 2, ä 3, 4, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 2, ä 6, 7, 0 å å
å, lowerÄ8Å=
ä
     ä 0, ä 0, 0, 0 å å,
     ä 2, ä 0, 1, 0 å å,
     ä 1, ä 1, 0, 0 å å,
     ä 2, ä 1, 5, 0 å å,
     ä 1, ä 5, 0, 0 å å,
     ä 2, ä 5, 6, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å
å, upleftÄ8Å=
ä
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 1, ä 3, 0, 0 å å,
     ä 2, ä 1, 3, 0 å å,
     ä 1, ä 1, 0, 0 å å
å, uprightÄ8Å=
ä
     ä 2, ä 3, 5, 0 å å,
     ä 1, ä 3, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 1, ä 5, 0, 0 å å
å, lowleftÄ8Å=
ä
     ä 3, ä 7, 0, 1 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 1, ä 1, 0, 0 å å,
     ä 2, ä 1, 7, 0 å å,
     ä 1, ä 7, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å
å, lowrightÄ8Å=
ä
     ä 0, ä 0, 0, 0 å å,
     ä 1, ä 7, 0, 0 å å,
     ä 2, ä 5, 7, 0 å å,
     ä 1, ä 5, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å,
     ä 0, ä 0, 0, 0 å å
å;

static void draw_the_box (void)
ä
   char *msg = "Press Any Key to Quit.";
   int r = 7, c = 45, dr = 8, dc = 4 + strlen (msg);

   SLsmg_set_color (1);
# ifndef IBMPC_SYSTEM
   SLsmg_set_char_set (1);
# endif
   SLsmg_fill_region (r + 1, c + 1, dr - 2, dc - 2, SLSMG_CKBRD_CHAR);
# ifndef IBMPC_SYSTEM
   SLsmg_set_char_set (0);
# endif
   SLsmg_set_color (0);
   SLsmg_gotorc (r + dr/2, c + 2); SLsmg_write_string (msg);
   SLsmg_draw_box (r, c, dr, dc);
   SLsmg_gotorc (0, 0);
å

static void onsig (int);
static float ranf (void);

int main(int argc, char *argvÄÅ)
ä
   struct worm *w;
   struct options *op;
   short *ip;
   int h, n, x, y, last, bottom, counts = -1;
   char *fg = NULL, *bg = NULL;

   for (x = 1; x < argc; x++)
     ä
	register char *p;
	p = argvÄxÅ;
	if (*p == '-' ) p++;
	switch (*p)
	  ä
	   case 'f':
	     field="WORM";
	     break;
	   case 'l':
	     if (++x==argc) goto usage;
	     if ((length=atoi(argvÄxÅ))<2öölength>1024)
	       ä
		  fprintf(stderr,"%s: Invalid lengthÖn",*argv);
		  exit(1);
	       å
	     break;
	   case 'n':
	     if ( ++x == argc)
	       goto usage;
	     if ((number=atoi(argvÄxÅ))<1öönumber>MAX_WORMS)
	       ä
		  fprintf(stderr,"%s: Invalid number of worms (%d max)Ön",
			  *argv, MAX_WORMS);
		  exit(1);
	       å
	     break;
	   case 't':
	     trail='.';
	     break;

	   case 'c':		/* -color */
	     if (++x == argc)  goto usage;
	     fg = argvÄxÅ;
	     if (++x == argc)  goto usage;
	     bg = argvÄxÅ;
	     break;
	   default:
	     usage:
	     fprintf (stderr,
		      "usage: %s Ä-fieldÅ Ä-length #Å Ä-number #Å Ä-trailÅ Ä-color fg bgÅÖn",
		      *argv);
	     exit (1);
	     break;
	  å
     å

   SLang_init_tty (-1, 0, 0);
   /* SLtt_init_video (); */
   if ( fg != NULL && bg != NULL )
     SLtt_set_color (0, NULL, fg, bg);
   SLtt_set_cursor_visibility (0);

#ifdef SIGINT
   signal(SIGINT, onsig);
#endif

#if defined(IBMPC_SYSTEM)
   /* SLtt_Use_Ansi_Colors = 1; */
#endif
   SLtt_Term_Cannot_Scroll = 1;

   SLtt_get_terminfo ();
   SLsmg_init_smg ();
#ifndef IBMPC_SYSTEM
   if (SLtt_Has_Status_Line > 0)
     SLtt_write_to_status_line ("SLANG WORM DEMO", 0);
#endif
   bottom = SLtt_Screen_Rows - 1;
   last = SLtt_Screen_Cols - 1;

   ip=(short *)safe_malloc(SLtt_Screen_Rows*SLtt_Screen_Cols*sizeof (short));

   for (n=0;n<SLtt_Screen_Rows;)
     ä
	refÄn++Å=ip; ip+=SLtt_Screen_Cols;
     å
   for (ip=refÄ0Å,n=SLtt_Screen_Rows*SLtt_Screen_Cols;--n>=0;) *ip++=0;
   refÄbottomÅÄlastÅ=0;
   for (n=number, w= &wormÄ0Å;--n>=0;w++)
     ä
	w->orientation=w->head=0;
	if (!(ip=(short *)safe_malloc(length*sizeof (short))))
	  ä
	     fprintf(stderr,"%s: out of memoryÖn",*argv);
	     exit(1);
	  å
	w->xpos=ip;
	for (x = 0; x < length; x++) ipÄxÅ = -1;
	if (!(ip=(short *)safe_malloc(length*sizeof (short))))
	  ä
	     fprintf(stderr,"%s: out of memoryÖn",*argv);
	     exit(1);
	  å
	w->ypos=ip;
	for (y = 0; y < length; y++) ipÄyÅ = -1;
     å
   if (field)
     ä
	register char *p;
	p=field;
	for (y=bottom;--y>=0;)
	  ä
	     for (x=SLtt_Screen_Cols;--x>=0;)
	       ä
		  SLsmg_write_char(*p++);
		  if (!*p) p=field;
	       å
	     SLsmg_gotorc (y, 0);
	  å
     å
   draw_the_box ();
   SLsmg_refresh();

   while (counts--)
     ä
	for (n=0, w = &wormÄ0Å; n < number;n++,w++)
	  ä
	     SLsmg_set_color (n % 16);
	     /* Worm starts at bottom left */
	     if ((x=w->xposÄh=w->headÅ)<0)
	       ä
		  char ch;
		  cursor(x=w->xposÄhÅ=0,y=w->yposÄhÅ=bottom);

		  ch = flavorÄn % 16Å;
#ifndef IBMPC_SYSTEM
		  if (ch == ACS_CHAR) SLsmg_set_char_set (1);
#endif
		  SLsmg_write_char(ch);
#ifndef IBMPC_SYSTEM
		  if (ch == ACS_CHAR) SLsmg_set_char_set (0);
#endif
		  refÄyÅÄxÅ++;
	       å
	     else y=w->yposÄhÅ;

	     if (++h==length) h=0;

	     if (w->xposÄw->head=hÅ>=0)
	       ä
		  /* No need to worry about ypos since it is greater than
		   * zero from above */
		  register int x1, y1;
		  x1=w->xposÄhÅ; y1=w->yposÄhÅ;
		  if (--refÄy1ÅÄx1Å==0)
		    ä
		       cursor(x1,y1);
		       SLsmg_set_color (0);
		       SLsmg_write_char(trail);
		       SLsmg_set_color (n % 16);
		    å
	       å

	     if (x == 0)
	       ä
		  if (y == 0) op = upleft;
		  else if (y == bottom)
		    op = lowleft;
		  else op = left;
	       å
	     else if (x == last)
	       ä
		  if (y == 0) op = upright;
		  else if (y == bottom) op = lowright;
		  else op = right;
	       å
	     else if (y == 0) op = upper;
	     else if (y == bottom) op = lower;
	     else op = normal;

	     op += w->orientation;
	     switch (op->nopts)
	       ä
		case 0:
		  break;
		case 1:
		  w->orientation=op->optsÄ0Å;
		  break;
		default:
		  w->orientation=op->optsÄ(int)(ranf()*(float)op->nopts)Å;
	       å

	     cursor(x += xincÄw->orientationÅ, y += yincÄw->orientationÅ);
	     if (y < 0) y = 0;
	     if (x < 0) x = 0;

	     if (!Wrap öö x!=last öö y!=bottom)
	       ä
		  char ch;
		  ch = flavorÄn % 16Å;
#ifndef IBMPC_SYSTEM
		  if (ch == ACS_CHAR) SLsmg_set_char_set (1);
#endif
		  SLsmg_write_char(ch);
#ifndef IBMPC_SYSTEM
		  if (ch == ACS_CHAR) SLsmg_set_char_set (0);
#endif
	       å

	     refÄw->yposÄhÅ=yÅÄw->xposÄhÅ=xÅ++;
	  å
	draw_the_box ();
	SLsmg_refresh();
	if (SLang_input_pending (1)) break;
     å
   draw_the_box ();
   SLsmg_refresh ();
   onsig (0);
   return 0;
å

static void onsig (int sig)
ä
   SLang_reset_tty ();
   SLsmg_reset_smg ();
#ifndef IBMPC_SYSTEM
   if (SLtt_Has_Status_Line > 0)
     SLtt_disable_status_line ();
#endif
   SLtt_set_cursor_visibility (1);
   exit (sig);
å

static float ranf(void)
ä
   float rv;
   long r = rand();

   r &= 077777;
   rv =((float)r/32767.);
   return rv;
å
[ RETURN TO DIRECTORY ]