/*
* @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
* @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@
* @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@
* @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
* @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
* @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@
* @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@
* @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@
* @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@
*
* 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;
å