home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
282_01
/
hod.c
< prev
next >
Wrap
Text File
|
1989-01-13
|
23KB
|
868 lines
/*
TITLE: HODGEPODGE;
DATE: 8/30/88;
DESCRIPTION: "Makes waves.";
VERSION: 1.01;
KEYWORDS: HODGEPODGE, Waves;
FILENAME: HOD.C;
WARNINGS: "Requires Hercules monochrome graphics. Hard disk recommended.";
SEE-ALSO: HOD.DOC;
SYSTEM: MS-DOS;
COMPILERS: Aztec;
AUTHORS: Dan Schechter;
REFERENCES:
AUTHORS: A.K. Dewdney;
TITLE: "Computer Recreations";
CITATION: "Scientific American, 259, pp 104-107 (August 1988)."
ENDREF;
*/
#define VERSION "Version 1.01 8/30/88"
/* Notes to programmers:
This program compiles under Aztec C in large-code/large-data
model. Some functions are used that may not exist or may have
other names in the libraries of other compilers.
scr_getc() causes the program to halt and wait for a key to be
pressed. It then returns that key. Functions keys and arrow keys
which DOS returns as a null followed by a character are returned
as a single character with the high bit set. But that feature
is not used in this program. It differs from getchar() in that
it does not wait for the ENTER key to be pressed. Some compilers
call this function getch().
abstoptr() takes an absolute address in the form of a long
and returns a long pointer in segment:offset form, which can
then be used to directly access memory.
time() returns the DOS time and date packed into a long. In
this program it is used only to seed the random number generator
and to provide a little extra mixing "exercise" for it.
clock() returns the number of hundredths of a second since the
beginning of the present day. In this program it is used only
to provide setmode() with a one-second pause, needed when
re-programming the HGA. The return type is a long.
If the argument to either time() or clock() is non-zero, the return
value will also be placed in the long pointed at by the argument.
bdos() performs INT 21H. AH is set to its first parameter, DX is
set to its second parameter, and CX is set to its third parameter.
It returns the value in AL. In this program it is used as an
inkey() function. inkey() polls the keyboard and returns 0 if
no key has been pressed, otherwise it returns the value of the
key that was pressed. It differs from scr_getc() in that inkey()
does not cause program operation to stop if no key has been pressed.
access() determines the accessibility of a disk file. In this
program it is only used to check the existance of a file, and as
called by this program it returns 0 if the named file does not
exist, and non-zero otherwise.
The first 7 #defines are user-changeable.
HEIGHT should not be greater than 80 and WIDTH
should not be greater than 180, to fit in the
screen area. Making them smaller will result in
faster operation. Set MAXFRAME smaller if you have
limited disk space. If HEIGHT==80 and WIDTH==180
and MAXFRAME==200 then a full length movie will
occupy 1440000 bytes of disk space. A good archiving
program can squeeze that by perhaps half.
K1, K2, and G are the defaults for k1, k2, and g
respectively. They can be changed at compile time
or set at run time on the command line. They
determine the characteristics of the hodgepodge.
Likewise for RANDOM, a Kittensoft innovation.
If you compile this program with TABLETEST defined, it will
display the halftone graphics characters as defined in table.
It will then wait for you to press any key and then exit.
Use this feature to view the characters if you want to change
them.
Exit codes:
0. Normal termination.
1. File load failure.
2. Unrecognized command line option.
3. Invalid command line parameter value.
*/
#include <string.h>
#include <fcntl.h>
#define HEIGHT 80 /* Height of display in 4 X 6 pixel characters. */
#define WIDTH 120 /* Width of display in 4 X 6 pixel characters. */
#define MAXFRAME 200 /* Maximum number of frames in a movie to prevent
over-filling your disk. */
#define K1 2 /* Default. May be changed at run time. */
#define K2 3 /* Default. May be changed at run time. */
#define G 25 /* Default. May be changed at run time. */
#define RANDOM 0 /* Default. May be changed at run time. */
#define STATENUM 128 /* The number of states. Since the state number
is divided by 8 to arrive at a display number
and there are 16 display characters, and since
disk storage of movies uses one nibble per cell
STATENUM should not be changed without revising
the entire display and movie storage schemes. */
#define TEXT 0 /* Used for Hercules display. */
#define GRAPHICS 1 /* Used for Hercules display. */
#define INDEXPORT 0x3B4 /* Used for Hercules display. */
#define CONTROLPORT 0x3b8 /* Used for Hercules display. */
#define DATAPORT 0x3b5 /* Used for Hercules display. */
#define CONFIGPORT 0x3bf /* Used for Hercules display. */
#define G_DELAY 100 /* Used for Hercules display. */
#define FONTADDR 0xffa6e /* ROM font address. */
#define SCREEN 0xb0000 /* Hercules screen 0 address. */
#define SCREEN1 0xb8000 /* Hercules screen 1 address. */
#define HEALTHY 1
#define INFECTED 0
#define ILL -1
long time(long *);
void *abstoptr();
int main(int n,char **arg);
void table_init(void);
void screen_put4c(int c1,int c2,int c3, int c4, int v,int h);
int work(unsigned char o[HEIGHT][WIDTH]);
void screenwrite(unsigned char old[HEIGHT][WIDTH],int count);
void sleep(int n);
int rando(void);
int inkey(void);
int infected_neighbors(unsigned char a[HEIGHT][WIDTH],int v,int h);
int ill_neighbors(unsigned char a[HEIGHT][WIDTH],int v,int h);
int n_sum(unsigned char a[HEIGHT][WIDTH],int v,int h);
int health(int a);
void setmode(int q);
int clearscreen(void);
int g_putch(int c,int y);
char *itoa(int n);
int blank(void);
void newname(char *s,int q);
int playback(char *s);
void sw_scr(void);
void g_printf(int v,char *ctrl,...);
int _kdput(char *p,int v);
void erl(void);
int load(unsigned char old[HEIGHT][WIDTH], unsigned char datbuf[HEIGHT*WIDTH], int *count, char *s);
void prompt(void);
int gdata[12] = { /* Constants for programming Hercules card. */
0x35, 0x2d, 0x2e, 0x7, 0x5b,
0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0
};
int tdata[12] = {
0x61, 0x50, 0x52, 0xf, 0x19,
0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc
};
unsigned char table[16][4] = {
/*0*/ { 0,0,0,0 }, /* This table defines the characters */
/*1*/ { 0,8,0,0 }, /* that will represent the states. Actual */
/*3*/ { 16,2,8,0 }, /* state numbers are divided by 8, */
/*4*/ { 8,1,16,2 }, /* requiring 16 display characters. */
/*6*/ { 40,2,5,16 }, /* Integers in this table must not be */
/*7*/ { 40,18,5,16 }, /* greater than 63. table_init() will */
/*9*/ { 36,18,10,37 }, /* shift all these numbers to create tables */
/*10*/ { 42,20,42,17 }, /* 1, 2, 3, and 4 so that */
/*12*/ { 42,21,42,21 }, /* characters may be quickly OR'd together */
/*13*/ { 42,46,42,42 }, /* and written to the display in full */
/*15*/ { 43,42,43,43 }, /* bytes. You may alter this table */
/*16*/ { 43,53,45,21 }, /* to change the appearance of the display */
/*18*/ { 47,53,43,61 }, /* without otherwise affecting program */
/*20*/ { 47,61,47,61 }, /* operation. */
/*22*/ { 63,61,47,63 },
/*24*/ { 63,63,63,63 }
};
#define CAT "\n\040\040\040\040\057\134\137\057\134\n\040\040\040\050\376\040\322\040\376\051\n\360\360\360\360\040\304\312\304\040\360\360\360\360\n\040\040\040\040\040\042\042\042"
char *HELP = "\
USAGE: HOD [A<k1>] [B<k2>] [G<g>] [M<n>] [I<nn>] [P[<fn>]] [R[<fn>]]\n\
Parameters may be in any order. All are integers.\n\
Defaults: k1=2, k2=3, g=25.\n\n\
<k1> is infected cells divisor.\n\
<k2> is ill cells divisor.\n\
<g> is infection rate.\n\
<nn> is an alternate initializing factor. (1 to number of cells.)\n\
<n> is a randomizing factor. (1 to number of cells.)\n\n\
R tells the program you want to load a file.\n\
P tells the program you want to play back a movie.\n\
<fn> is a file name to load or play back.\n\n\
During program operation:\n\
# (crosshatch) Toggles movie recording.\n\
$ to set