summaryrefslogtreecommitdiffstats
path: root/atc
diff options
context:
space:
mode:
Diffstat (limited to 'atc')
-rw-r--r--atc/BUGS4
-rw-r--r--atc/Makefile18
-rw-r--r--atc/atc.6598
-rw-r--r--atc/def.h80
-rw-r--r--atc/extern.c75
-rw-r--r--atc/extern.h62
-rw-r--r--atc/games/ATC_scores5
-rw-r--r--atc/games/Game_List5
-rw-r--r--atc/games/Killer21
-rw-r--r--atc/games/crossover14
-rw-r--r--atc/games/default21
-rw-r--r--atc/games/easy15
-rw-r--r--atc/games/game_222
-rw-r--r--atc/grammar.y389
-rw-r--r--atc/graphics.c418
-rw-r--r--atc/include.h86
-rw-r--r--atc/input.c663
-rw-r--r--atc/lex.l69
-rw-r--r--atc/list.c115
-rw-r--r--atc/log.c247
-rw-r--r--atc/main.c326
-rw-r--r--atc/pathnames.h39
-rw-r--r--atc/struct.h111
-rw-r--r--atc/tunable.c56
-rw-r--r--atc/tunable.h48
-rw-r--r--atc/update.c410
26 files changed, 3917 insertions, 0 deletions
diff --git a/atc/BUGS b/atc/BUGS
new file mode 100644
index 00000000..7d2af294
--- /dev/null
+++ b/atc/BUGS
@@ -0,0 +1,4 @@
+log restarts if interrupted
+Still refreshes after exit
+Should ^Z be disabled?
+does not exit after hup
diff --git a/atc/Makefile b/atc/Makefile
new file mode 100644
index 00000000..df37f741
--- /dev/null
+++ b/atc/Makefile
@@ -0,0 +1,18 @@
+# @(#)Makefile 5.7 (Berkeley) 6/27/90
+
+PROG= atc
+CFLAGS+=-DBSD -I${.CURDIR} -I.
+SRCS= extern.c grammar.c graphics.c input.c lex.c list.c log.c \
+ main.c tunable.c update.c
+MAN6= atc.0
+DPADD= ${usr/lib/libl.a ${LIBM} ${LIBTERM} ${LIBCURSES} ${LIBCOMPAT}
+LDADD= -ll -lm -lcurses -ltermcap -lcompat
+GAMES= ATC_scores Game_List Killer crossover default easy game_2
+CLEANFILES=grammar.c y.tab.h lex.c
+HIDEGAME=hidegame
+
+beforeinstall:
+ (cd ${.CURDIR}/games; install -c -o ${BINOWN} -g ${BINGRP} -m 400 \
+ ${GAMES} ${DESTDIR}/usr/share/games/atc)
+
+.include <bsd.prog.mk>
diff --git a/atc/atc.6 b/atc/atc.6
new file mode 100644
index 00000000..09a14f26
--- /dev/null
+++ b/atc/atc.6
@@ -0,0 +1,598 @@
+.\" Copyright (c) 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Ed James.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)atc.6 5.4 (Berkeley) 6/23/90
+.\"
+. \" XP - exdented paragraph
+.de XP
+.RT
+.if \\n(1T .sp \\n(PDu
+.ne 1.1
+.if !\\n(IP .nr IP +1
+.in +\\n(I\\n(IRu
+.ti -\\n(I\\n(IRu
+..
+.\" Copyright (c) 1986 Ed James. All rights reserved.
+.\"
+.TH ATC 6 "June 23, 1990"
+.UC
+.SH NAME
+atc \- Air Traffic Controller Game
+.SH SYNOPSIS
+.B atc
+-[u?lstp] [-[gf] game_name] [-r random seed]
+.SH DESCRIPTION
+.LP
+.I Atc
+lets you try your hand at the nerve wracking duties of the air traffic
+controller without endangering the lives of millions of
+travelers each year.
+Your responsibilities require you to direct the flight of jets
+and prop planes into and out of the flight arena and airports.
+The speed (update time) and frequency of the planes depend on the
+difficulty of the chosen arena.
+.SH OPTIONS
+.LP
+.TP 8
+.B \-u
+Print the usage line and exit.
+.TP
+.B \-?
+Same as
+.B \-u.
+.TP
+.B \-l
+Print a list of available games and exit.
+The first game name printed is the default game.
+.TP
+.B \-s
+Print the score list (formerly the Top Ten list).
+.TP
+.B \-t
+Same as
+.B \-s.
+.TP
+.B \-p
+Print the path to the special directory where
+.I atc
+expects to find its private files. This is used during the
+installation of the program.
+.TP
+.B "\-g game"
+Play the named game. If the game listed is not one of the
+ones printed from the
+.B \-l
+option, the default game is played.
+.TP
+.B "\-f game"
+Same as
+.B \-g.
+.TP
+.B "\-r seed"
+Set the random seed. The purpose of this flag is questionable.
+.SH GOALS
+.LP
+Your goal in
+.I atc
+is to keep the game going as long as possible.
+There is no winning state, except to beat the times of other players.
+You will need to: launch planes at airports (by instructing them to
+increase their altitude); land planes at airports (by instructing them to
+go to altitude zero when exactly over the airport); and maneuver planes
+out of exit points.
+.LP
+Several things will cause the end of the game.
+Each plane has a destination (see information area), and
+sending a plane to the wrong destination is an error.
+Planes can run out of fuel, or can collide. Collision is defined as
+adjacency in any of the three dimensions. A plane leaving the arena
+in any other way than through its destination exit is an error as well.
+.LP
+Scores are sorted in order of the number of planes safe. The other
+statistics are provided merely for fun. There is no penalty for
+taking longer than another player (except in the case of ties).
+.LP
+Suspending a game is not permitted. If you get a talk message, tough.
+When was the last time an Air Traffic Controller got called away to
+the phone?
+.SH "THE DISPLAY"
+.LP
+Depending on the terminal you run
+.I atc
+on, the screen will be divided into 4 areas.
+It should be stressed that the terminal driver portion of the
+game was designed to be reconfigurable, so the display format can vary
+depending the version you are playing. The descriptions here are based
+on the ascii version
+of the game. The game rules and input format, however,
+should remain consistent.
+Control-L redraws the screen, should it become muddled.
+.SS RADAR
+.IP
+The first screen area is the radar display, showing the relative locations
+of the planes, airports, standard entry/exit points, radar
+beacons, and "lines" which simply serve to aid you in guiding
+the planes.
+.IP
+Planes are shown as a single letter with an altitude. If
+the numerical altitude is a single digit, then it represents
+thousands of feet.
+Some distinction is made between the prop
+planes and the jets. On ascii terminals, prop planes are
+represented by a upper case letter, jets by a lower case letter.
+.IP
+Airports are shown as a number and some indication of the direction
+planes must be going to land at the airport.
+On ascii terminals, this is one of '^', '>', '<', and 'v', to indicate
+north (0 degrees), east (90), west (270) and south (180), respectively.
+The planes will also
+take off in this direction.
+.IP
+Beacons are represented as circles or asterisks and a number.
+Their purpose is to offer a place of easy reference to the plane pilots.
+See 'the delay command' under the input section of this manual.
+.IP
+Entry/exit points are displayed as numbers along the border of the
+radar screen. Planes will enter the arena from these points without
+warning. These points have a direction associated with them, and
+planes will always enter the arena from this direction. On the
+ascii version of
+.I atc,
+this direction is not displayed. It will become apparent
+what this direction is as the game progresses.
+.IP
+Incoming planes will always enter at the same altitude: 7000 feet.
+For a plane to successfully depart through an entry/exit point,
+it must be flying at 9000 feet.
+It is not necessary for the planes to be flying in any particular
+direction when they leave the arena (yet).
+.SS "INFORMATION AREA"
+.IP
+The second area of the display is the information area, which lists
+the time (number of updates since start), and the number of planes you
+have directed safely out of the arena.
+Below this is a list of planes currently in the air, followed by a
+blank line, and then a list of planes on the ground (at airports).
+Each line lists the plane name and its current altitude,
+an optional asterisk indicating low fuel, the plane's destination,
+and the plane's current command. Changing altitude is not considered
+to be a command and is therefore not displayed. The following are
+some possible information lines:
+.IP
+ B4*A0: Circle @ b1
+.br
+ g7 E4: 225
+.IP
+The first example shows a prop plane named 'B' that is flying at 4000
+feet. It is low on fuel (note the '*'). It's destination is
+Airport #0.
+The next command it expects
+to do is circle when it reaches Beacon #1.
+The second example shows a jet named 'g' at 7000 feet, destined for
+Exit #4. It is just now executing a turn to 225 degrees (South-West).
+.SS "INPUT AREA"
+.IP
+The third area of the display is the input area. It is here that
+your input is reflected. See the INPUT heading of this manual
+for more details.
+.SS "AUTHOR AREA"
+.IP
+This area is used simply to give credit where credit is due. :-)
+.SH INPUT
+.LP
+A command completion interface is built into
+the game. At any time, typing '?' will list possible input characters.
+Typing a backspace (your erase character) backs up, erasing the last part
+of the command. When a command is complete, a return enters it, and
+any semantic checking is done at that time. If no errors are detected,
+the command is sent to the appropriate plane. If an error is discovered
+during the check, the offending statement will be underscored and a
+(hopefully) descriptive message will be printed under it.
+.LP
+The command syntax is broken into two parts:
+.I "Immediate Only"
+and
+.I Delayable
+commands.
+.I "Immediate Only"
+commands happen on the next
+update.
+.I Delayable
+commands also happen on the next update unless they
+are followed by an optional predicate called the
+.I Delay
+command.
+.LP
+In the following tables, the syntax
+.B [0\-9]
+means any single digit, and
+.B <dir>
+refers to the keys around the 's' key, namely ``wedcxzaq''.
+In absolute references, 'q' refers to North-West or 315 degrees, and 'w'
+refers to North, or 0 degrees.
+In relative references, 'q' refers to -45 degrees or 45 degrees left, and 'w'
+refers to 0 degrees, or no change in direction.
+.LP
+All commands start with a plane letter. This indicates the recipient
+of the command. Case is ignored.
+.SS "IMMEDIATE ONLY COMMANDS"
+.RS
+.B "\- a Altitude:"
+.RS
+Affect a plane's altitude (and take off).
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Go to the given altitude (thousands of feet).
+.RE
+.B "\- c/+ Climb:"
+.RS
+Relative altitude change.
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Difference in thousands of feet.
+.RE
+.RE
+.B "\- d/\- Descend:"
+.RS
+Relative altitude change.
+.RE
+.RS
+.B "\- [0\-9] Number:"
+.RS
+Difference in thousands of feet.
+.RE
+.RE
+.RE
+.B "\- m Mark:"
+.RS
+Display in highlighted mode. Command is displayed normally.
+.RE
+.B "\- i Ignore:"
+.RS
+Do not display highlighted. Command is displayed as a
+line of dashes if there is no command.
+.RE
+.B "\- u Unmark:"
+.RS
+Same as ignore, but if a delayed command is processed,
+the plane will become marked. This is useful if you want
+to forget about a plane during part, but not all, of its
+journey.
+.RE
+.RE
+.SS "DELAYABLE COMMANDS"
+.RS
+.B "\- c Circle:"
+.RS
+Have the plane circle (clockwise by default).
+.RE
+.RS
+.B "\- l Left:"
+.RS
+Circle counterclockwise.
+.RE
+.B "\- r Right:"
+.RS
+Circle clockwise.
+.RE
+.RE
+.B "\- t Turn:"
+.RS
+Change direction.
+.RE
+.RS
+.B "\- l Left:"
+.RS
+Turn counterclockwise (45 degrees by default).
+.RE
+.RS
+.B "\- <dir> Direction:"
+.RS
+Turn ccw the given number of degrees.
+Zero degrees is no turn. A ccw turn
+of -45 degrees is 45 cw.
+.RE
+.RE
+.B "\- r Right:"
+.RS
+Turn clockwise (45 degrees by default).
+.RE
+.RS
+.B "\- <dir> Direction:"
+.RS
+Same as turn left <dir>.
+.RE
+.RE
+.B "\- L Left 90:"
+.RS
+Turn counterclockwise 90 degrees.
+.RE
+.B "\- R Right 90:"
+.RS
+Turn clockwise 90 degrees.
+.RE
+.B "\- <dir> Direction:"
+.RS
+Turn to the absolute compass heading given.
+The shortest turn will be taken.
+.RE
+.B "\- t Towards:"
+.RS
+Turn towards a beacon, airport or exit. The turn is
+just an estimate.
+.RE
+.RS
+.B "\- b/* Beacon:"
+.RS
+Turn towards the beacon.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The beacon number.
+.RE
+.RE
+.B "\- e Exit:"
+.RS
+Turn towards the exit.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The exit number.
+.RE
+.RE
+.B "\- a Airport:"
+.RS
+Turn towards the airport.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The airport number.
+.RE
+.RE
+.RE
+.RE
+.RE
+.SS THE DELAY COMMAND
+.LP
+The
+.B Delay
+(a/@)
+command may be appended to any
+.B Delayable
+command. It allows the controller to instruct a plane to do an action
+when the plane reaches a particular beacon (or other objects in future
+versions).
+.sp
+.RS
+.B "\- a/@ At:"
+.RS
+Do the given delayable command when the plane reaches the given beacon.
+.RE
+.RS
+.B "\- b/* Beacon:"
+.RS
+This is redundant to allow for expansion.
+.RE
+.RS
+.B "\- [0-9] Number:"
+.RS
+The beacon number.
+.RE
+.RE
+.RE
+.RE
+.SS "MARKING, UNMARKING AND IGNORING"
+.LP
+Planes are
+.B marked
+when they enter the arena. This means they are displayed in highlighted
+mode on the radar display. A plane may also be either
+.B unmarked
+or
+.B ignored.
+An
+.B unmarked
+plane is drawn in unhighlighted mode, and a line of dashes is displayed in
+the command field of the information area. The plane will remain this
+way until a mark command has been issued. Any other command will be issued,
+but the command line will return to a line of dashes when the command
+is completed.
+.LP
+An
+.B ignored
+plane is treated the same as an unmarked plane, except that it will
+automatically switch to
+.B marked
+status when a delayed command has been processed. This is useful if
+you want to forget about a plane for a while, but its flight path has
+not yet been completely set.
+.LP
+As with all of the commands, marking, unmarking and ignoring will take effect
+at the beginning of the next update. Do not be surprised if the plane does
+not immediately switch to unhighlighted mode.
+.SS EXAMPLES
+.RS
+.TP 16
+atlab1
+a: turn left at beacon #1
+.TP 16
+cc
+C: circle
+.TP 16
+gtte4ab2
+g: turn towards exit #4 at beacon #2
+.TP 16
+ma+2
+m: altitude: climb 2000 feet
+.TP 16
+stq
+S: turn to 315
+.TP 16
+xi
+x: ignore
+.RE
+.SH "OTHER INFORMATION"
+.LP
+Jets move every update; prop planes move every other update.
+.LP
+All planes turn a most 90 degrees per movement.
+.LP
+Planes enter at 7000 feet and leave at 9000 feet.
+.LP
+Planes flying at an altitude of 0 crash if they are not over an airport.
+.LP
+Planes waiting at airports can only be told to take off (climb in altitude).
+.SH "NEW GAMES"
+.LP
+The
+.B Game_List
+file lists the currently available play fields. New field description
+file names must be placed in this file to be 'playable'. If a player
+specifies a game not in this file, his score will not be logged.
+.LP
+The game field description files are broken into two parts. The first
+part is the definition section. Here, the four tunable game parameters
+must be set. These variables are set with the syntax:
+.IP
+variable = number;
+.LP
+Variable may be one of:
+.B update,
+indicating the number of seconds between forced updates;
+.B newplane,
+indicating (about) the number of updates between new plane entries;
+.B width,
+indicating the width of the play field; and
+.B height,
+indicating the height of the play field.
+.LP
+The second part of the field description files describes the locations
+of the exits, the beacons, the airports and the lines.
+The syntax is as follows:
+.IP
+beacon: (x y) ... ;
+.br
+airport: (x y direction) ... ;
+.br
+exit: (x y direction) ... ;
+.br
+line: [ (x1 y1) (x2 y2) ] ... ;
+.LP
+For beacons, a simple x, y coordinate pair is used (enclosed in parenthesis).
+Airports and exits require a third value, a direction, which is one
+of
+.B wedcxzaq.
+For airports, this is the direction that planes must be going to take
+off and land, and for exits, this is the direction that planes will going
+when they
+.B enter
+the arena. This may not seem intuitive, but as there is no restriction on
+direction of exit, this is appropriate.
+Lines are slightly different, since they need two coordinate pairs to
+specify the line endpoints. These endpoints must be enclosed in
+square brackets.
+.LP
+All statements are semi-colon (;) terminated. Multiple item statements
+accumulate. Each definition must occur exactly once, before any
+item statements. Comments begin with a hash (#) symbol
+and terminate with a newline.
+The coordinates are between zero and width-1 and height-1
+inclusive. All of the exit coordinates must lie on the borders, and
+all of the beacons and airports must lie inside of the borders.
+Line endpoints may be anywhere within the field, so long as
+the lines are horizontal, vertical or
+.B "exactly diagonal."
+.SS "FIELD FILE EXAMPLE"
+.RS
+.sp
+.nf
+.TA 1i 1i
+.ta 1i 1i
+# This is the default game.
+
+update = 5;
+newplane = 5;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ;
+
+airport: ( 20 15 w ) ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
+.fi
+.RE
+.SH FILES
+.LP
+Files are kept in a special directory. See the OPTIONS for a way to
+print this path out.
+.TP 16
+.B ATC_score
+Where the scores are kept.
+.TP 16
+.B Game_List
+The list of playable games.
+.SH AUTHOR
+.LP
+Ed James, UC Berkeley: edjames@ucbvax.berkeley.edu, ucbvax!edjames
+.LP
+This game is based on someone's description of the overall flavor
+of a game written for some unknown PC many years ago, maybe.
+.SH BUGS
+.LP
+The screen sometimes refreshes after you have quit.
+.LP
+Yet Another Curses Bug was discovered during the development of this game.
+If your curses library clrtobot.o is version 5.1 or earlier,
+you will have erase problems with the backspace operator in the input
+window.
+
diff --git a/atc/def.h b/atc/def.h
new file mode 100644
index 00000000..257cdb41
--- /dev/null
+++ b/atc/def.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)def.h 5.2 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#define AUTHOR_STR "ATC - by Ed James"
+
+#define PI 3.14159654
+
+#define LOWFUEL 15
+
+#define REALLOC 10
+
+#define SGN(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
+#define ABS(x) ((x < 0) ? -(x) : (x))
+#define DIR_FROM_DXDY(dx,dy) ((int) (atan2((double)(dy), (double)(dx)) \
+ * MAXDIR / (2 * PI) + 2.5 + MAXDIR) % MAXDIR)
+
+#define MAXDIR 8
+
+#define D_LEFT 1
+#define D_RIGHT 2
+#define D_UP 3
+#define D_DOWN 4
+
+#define T_NODEST 0
+#define T_BEACON 1
+#define T_EXIT 2
+#define T_AIRPORT 3
+
+#define S_NONE 0
+#define S_GONE 1
+#define S_MARKED 2
+#define S_UNMARKED 3
+#define S_IGNORED 4
+
+#define INPUT_LINES 3
+#define PLANE_COLS 20
diff --git a/atc/extern.c b/atc/extern.c
new file mode 100644
index 00000000..a69252f3
--- /dev/null
+++ b/atc/extern.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)extern.c 5.4 (Berkeley) 10/30/90";
+#endif /* not lint */
+
+#include "include.h"
+
+char GAMES[] = "Game_List";
+
+int clck, safe_planes, start_time, test_mode;
+
+char *file;
+
+FILE *filein, *fileout;
+
+C_SCREEN screen, *sp = &screen;
+
+LIST air, ground;
+
+struct sgttyb tty_start, tty_new;
+
+DISPLACEMENT displacement[MAXDIR] = {
+ { 0, -1 },
+ { 1, -1 },
+ { 1, 0 },
+ { 1, 1 },
+ { 0, 1 },
+ { -1, 1 },
+ { -1, 0 },
+ { -1, -1 }
+};
diff --git a/atc/extern.h b/atc/extern.h
new file mode 100644
index 00000000..950dbb40
--- /dev/null
+++ b/atc/extern.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 5.4 (Berkeley) 10/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+extern char GAMES[], *file;
+
+extern int clck, safe_planes, start_time, test_mode;
+
+extern FILE *filein, *fileout;
+
+extern C_SCREEN screen, *sp;
+
+extern LIST air, ground;
+
+extern struct sgttyb tty_start, tty_new;
+
+extern DISPLACEMENT displacement[MAXDIR];
+
+extern PLANE *findplane(), *newplane();
diff --git a/atc/games/ATC_scores b/atc/games/ATC_scores
new file mode 100644
index 00000000..bbffeb25
--- /dev/null
+++ b/atc/games/ATC_scores
@@ -0,0 +1,5 @@
+schumann puff game_2 171 1414 195
+schumann puff default 18 220 59
+schumann puff easy 13 182 146
+schumann puff crossover 11 74 448
+schumann puff Killer 0 38 27
diff --git a/atc/games/Game_List b/atc/games/Game_List
new file mode 100644
index 00000000..0117385b
--- /dev/null
+++ b/atc/games/Game_List
@@ -0,0 +1,5 @@
+default
+easy
+crossover
+Killer
+game_2
diff --git a/atc/games/Killer b/atc/games/Killer
new file mode 100644
index 00000000..f15d0602
--- /dev/null
+++ b/atc/games/Killer
@@ -0,0 +1,21 @@
+update = 1;
+newplane = 4;
+width = 30;
+height = 21;
+
+exit: ( 29 7 a ) ( 29 17 a )
+ ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ( 14 10 ) ( 20 15 ) ;
+
+airport: ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/crossover b/atc/games/crossover
new file mode 100644
index 00000000..d2689ffd
--- /dev/null
+++ b/atc/games/crossover
@@ -0,0 +1,14 @@
+update = 5;
+newplane = 5;
+width = 29;
+height = 21;
+
+exit: ( 0 0 c ) ( 8 0 c ) ( 20 0 z ) ( 28 0 z )
+ ( 28 20 q ) ( 20 20 q ) ( 8 20 e ) ( 0 20 e );
+
+beacon: ( 14 6 ) ( 18 10 ) ( 14 14 ) ( 10 10 );
+
+line: [ ( 0 0 ) ( 20 20 ) ]
+ [ ( 8 0 ) ( 28 20 ) ]
+ [ ( 20 0 ) ( 0 20 ) ]
+ [ ( 28 0 ) ( 8 20 ) ];
diff --git a/atc/games/default b/atc/games/default
new file mode 100644
index 00000000..e19ef9d2
--- /dev/null
+++ b/atc/games/default
@@ -0,0 +1,21 @@
+update = 5;
+newplane = 10;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
+
+beacon: ( 12 7 ) ( 12 17 ) ;
+
+airport: ( 20 15 w ) ( 20 18 d ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 12 1 ) ( 12 6 ) ]
+ [ ( 13 7 ) ( 28 7 ) ]
+ [ ( 28 1 ) ( 13 16 ) ]
+ [ ( 1 13 ) ( 11 13 ) ]
+ [ ( 12 8 ) ( 12 16 ) ]
+ [ ( 11 18 ) ( 10 19 ) ]
+ [ ( 13 17 ) ( 28 17 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/easy b/atc/games/easy
new file mode 100644
index 00000000..4ab8eac0
--- /dev/null
+++ b/atc/games/easy
@@ -0,0 +1,15 @@
+update = 7;
+newplane = 12;
+width = 15;
+height = 15;
+
+exit: ( 7 0 x ) ( 14 0 z ) ( 12 14 q ) ( 0 14 e ) ;
+
+beacon: ( 12 7 ) ;
+
+airport: ( 7 8 w ) ;
+
+line: [ ( 1 1 ) ( 6 6 ) ]
+ [ ( 7 9 ) ( 12 14 ) ]
+ [ ( 7 0 ) ( 7 14 ) ]
+ [ ( 1 7 ) ( 11 7 ) ] ;
diff --git a/atc/games/game_2 b/atc/games/game_2
new file mode 100644
index 00000000..5788c8a2
--- /dev/null
+++ b/atc/games/game_2
@@ -0,0 +1,22 @@
+update = 5;
+newplane = 8;
+width = 30;
+height = 21;
+
+exit: ( 12 0 x ) ( 29 0 z ) ( 29 6 a ) ( 29 13 a )
+ ( 9 20 e ) ( 0 13 d ) ( 0 6 d ) ( 0 0 c ) ;
+
+beacon: ( 12 17 ) ( 23 6 ) ( 23 13 ) ( 25 17 )
+ ( 12 6 ) ( 12 13 ) ( 6 6 ) ;
+
+airport: ( 18 17 d ) ;
+
+line: [ ( 1 1 ) ( 16 16 ) ]
+ [ ( 1 6 ) ( 28 6 ) ]
+ [ ( 12 1 ) ( 12 17 ) ]
+ [ ( 10 19 ) ( 28 1 ) ]
+ [ ( 13 17 ) ( 17 17 ) ]
+ [ ( 1 13 ) ( 28 13 ) ]
+ [ ( 19 17 ) ( 24 17 ) ]
+ [ ( 19 17 ) ( 22 14 ) ]
+ [ ( 26 16 ) ( 28 14 ) ] ;
diff --git a/atc/grammar.y b/atc/grammar.y
new file mode 100644
index 00000000..a59a3820
--- /dev/null
+++ b/atc/grammar.y
@@ -0,0 +1,389 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+%token <ival> HeightOp
+%token <ival> WidthOp
+%token <ival> UpdateOp
+%token <ival> NewplaneOp
+%token <cval> DirOp
+%token <ival> ConstOp
+%token <ival> LineOp
+%token <ival> AirportOp
+%token <ival> BeaconOp
+%token <ival> ExitOp
+%union {
+ int ival;
+ char cval;
+}
+
+%{
+#include "include.h"
+
+#ifndef lint
+static char sccsid[] = "@(#)grammar.y 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+int errors = 0;
+int line = 1;
+%}
+
+%%
+file:
+ bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
+ {
+ if (sp->num_exits + sp->num_airports < 2)
+ yyerror("Need at least 2 airports and/or exits.");
+ return (errors);
+ }
+ ;
+
+bunch_of_defs:
+ def bunch_of_defs
+ | def
+ ;
+
+def:
+ udef
+ | ndef
+ | wdef
+ | hdef
+ ;
+
+udef:
+ UpdateOp '=' ConstOp ';'
+ {
+ if (sp->update_secs != 0)
+ return (yyerror("Redefinition of 'update'."));
+ else if ($3 < 1)
+ return (yyerror("'update' is too small."));
+ else
+ sp->update_secs = $3;
+ }
+ ;
+
+ndef:
+ NewplaneOp '=' ConstOp ';'
+ {
+ if (sp->newplane_time != 0)
+ return (yyerror("Redefinition of 'newplane'."));
+ else if ($3 < 1)
+ return (yyerror("'newplane' is too small."));
+ else
+ sp->newplane_time = $3;
+ }
+ ;
+
+hdef:
+ HeightOp '=' ConstOp ';'
+ {
+ if (sp->height != 0)
+ return (yyerror("Redefinition of 'height'."));
+ else if ($3 < 3)
+ return (yyerror("'height' is too small."));
+ else
+ sp->height = $3;
+ }
+ ;
+
+wdef:
+ WidthOp '=' ConstOp ';'
+ {
+ if (sp->height != 0)
+ return (yyerror("Redefinition of 'width'."));
+ else if ($3 < 3)
+ return (yyerror("'width' is too small."));
+ else
+ sp->width = $3;
+ }
+ ;
+
+bunch_of_lines:
+ line bunch_of_lines
+ {}
+ | line
+ {}
+ ;
+
+line:
+ BeaconOp ':' Bpoint_list ';'
+ {}
+ | ExitOp ':' Epoint_list ';'
+ {}
+ | LineOp ':' Lline_list ';'
+ {}
+ | AirportOp ':' Apoint_list ';'
+ {}
+ ;
+
+Bpoint_list:
+ Bpoint Bpoint_list
+ {}
+ | Bpoint
+ {}
+ ;
+
+Bpoint:
+ '(' ConstOp ConstOp ')'
+ {
+ if (sp->num_beacons % REALLOC == 0) {
+ if (sp->beacon == NULL)
+ sp->beacon = (BEACON *) malloc((sp->num_beacons
+ + REALLOC) * sizeof (BEACON));
+ else
+ sp->beacon = (BEACON *) realloc(sp->beacon,
+ (sp->num_beacons + REALLOC) *
+ sizeof (BEACON));
+ if (sp->beacon == NULL)
+ return (yyerror("No memory available."));
+ }
+ sp->beacon[sp->num_beacons].x = $2;
+ sp->beacon[sp->num_beacons].y = $3;
+ check_point($2, $3);
+ sp->num_beacons++;
+ }
+ ;
+
+Epoint_list:
+ Epoint Epoint_list
+ {}
+ | Epoint
+ {}
+ ;
+
+Epoint:
+ '(' ConstOp ConstOp DirOp ')'
+ {
+ int dir;
+
+ if (sp->num_exits % REALLOC == 0) {
+ if (sp->exit == NULL)
+ sp->exit = (EXIT *) malloc((sp->num_exits +
+ REALLOC) * sizeof (EXIT));
+ else
+ sp->exit = (EXIT *) realloc(sp->exit,
+ (sp->num_exits + REALLOC) *
+ sizeof (EXIT));
+ if (sp->exit == NULL)
+ return (yyerror("No memory available."));
+ }
+ dir = dir_no($4);
+ sp->exit[sp->num_exits].x = $2;
+ sp->exit[sp->num_exits].y = $3;
+ sp->exit[sp->num_exits].dir = dir;
+ check_edge($2, $3);
+ check_edir($2, $3, dir);
+ sp->num_exits++;
+ }
+ ;
+
+Apoint_list:
+ Apoint Apoint_list
+ {}
+ | Apoint
+ {}
+ ;
+
+Apoint:
+ '(' ConstOp ConstOp DirOp ')'
+ {
+ int dir;
+
+ if (sp->num_airports % REALLOC == 0) {
+ if (sp->airport == NULL)
+ sp->airport=(AIRPORT *)malloc((sp->num_airports
+ + REALLOC) * sizeof(AIRPORT));
+ else
+ sp->airport = (AIRPORT *) realloc(sp->airport,
+ (sp->num_airports + REALLOC) *
+ sizeof(AIRPORT));
+ if (sp->airport == NULL)
+ return (yyerror("No memory available."));
+ }
+ dir = dir_no($4);
+ sp->airport[sp->num_airports].x = $2;
+ sp->airport[sp->num_airports].y = $3;
+ sp->airport[sp->num_airports].dir = dir;
+ check_point($2, $3);
+ check_adir($2, $3, dir);
+ sp->num_airports++;
+ }
+ ;
+
+Lline_list:
+ Lline Lline_list
+ {}
+ | Lline
+ {}
+ ;
+
+Lline:
+ '[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
+ {
+ if (sp->num_lines % REALLOC == 0) {
+ if (sp->line == NULL)
+ sp->line = (LINE *) malloc((sp->num_lines +
+ REALLOC) * sizeof (LINE));
+ else
+ sp->line = (LINE *) realloc(sp->line,
+ (sp->num_lines + REALLOC) *
+ sizeof (LINE));
+ if (sp->line == NULL)
+ return (yyerror("No memory available."));
+ }
+ sp->line[sp->num_lines].p1.x = $3;
+ sp->line[sp->num_lines].p1.y = $4;
+ sp->line[sp->num_lines].p2.x = $7;
+ sp->line[sp->num_lines].p2.y = $8;
+ check_line($3, $4, $7, $8);
+ sp->num_lines++;
+ }
+ ;
+%%
+
+check_edge(x, y)
+{
+ if (!(x == 0) && !(x == sp->width - 1) &&
+ !(y == 0) && !(y == sp->height - 1))
+ yyerror("edge value not on edge.");
+}
+
+check_point(x, y)
+{
+ if (x < 1 || x >= sp->width - 1)
+ yyerror("X value out of range.");
+ if (y < 1 || y >= sp->height - 1)
+ yyerror("Y value out of range.");
+}
+
+check_linepoint(x, y)
+{
+ if (x < 0 || x >= sp->width)
+ yyerror("X value out of range.");
+ if (y < 0 || y >= sp->height)
+ yyerror("Y value out of range.");
+}
+
+check_line(x1, y1, x2, y2)
+{
+ int d1, d2;
+
+ check_linepoint(x1, y1);
+ check_linepoint(x2, y2);
+
+ d1 = ABS(x2 - x1);
+ d2 = ABS(y2 - y1);
+
+ if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
+ yyerror("Bad line endpoints.");
+}
+
+yyerror(s)
+{
+ fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
+ errors++;
+
+ return (errors);
+}
+
+check_edir(x, y, dir)
+{
+ int bad = 0;
+
+ if (x == sp->width - 1)
+ x = 2;
+ else if (x != 0)
+ x = 1;
+ if (y == sp->height - 1)
+ y = 2;
+ else if (y != 0)
+ y = 1;
+
+ switch (x * 10 + y) {
+ case 00: if (dir != 3) bad++; break;
+ case 01: if (dir < 1 || dir > 3) bad++; break;
+ case 02: if (dir != 1) bad++; break;
+ case 10: if (dir < 3 || dir > 5) bad++; break;
+ case 11: break;
+ case 12: if (dir > 1 && dir < 7) bad++; break;
+ case 20: if (dir != 5) bad++; break;
+ case 21: if (dir < 5) bad++; break;
+ case 22: if (dir != 7) bad++; break;
+ default:
+ yyerror("Unknown value in checkdir! Get help!");
+ break;
+ }
+ if (bad)
+ yyerror("Bad direction for entrance at exit.");
+}
+
+check_adir(x, y, dir)
+{
+}
+
+checkdefs()
+{
+ int err = 0;
+
+ if (sp->width == 0) {
+ yyerror("'width' undefined.");
+ err++;
+ }
+ if (sp->height == 0) {
+ yyerror("'height' undefined.");
+ err++;
+ }
+ if (sp->update_secs == 0) {
+ yyerror("'update' undefined.");
+ err++;
+ }
+ if (sp->newplane_time == 0) {
+ yyerror("'newplane' undefined.");
+ err++;
+ }
+ if (err)
+ return (-1);
+ else
+ return (0);
+}
diff --git a/atc/graphics.c b/atc/graphics.c
new file mode 100644
index 00000000..1d7d39d8
--- /dev/null
+++ b/atc/graphics.c
@@ -0,0 +1,418 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)graphics.c 5.3 (Berkeley) 10/30/90";
+#endif /* not lint */
+
+#include "include.h"
+#ifdef SYSV
+#include <errno.h>
+#endif
+
+#define C_TOPBOTTOM '-'
+#define C_LEFTRIGHT '|'
+#define C_AIRPORT '='
+#define C_LINE '+'
+#define C_BACKROUND '.'
+#define C_BEACON '*'
+#define C_CREDIT '*'
+
+WINDOW *radar, *cleanradar, *credit, *input, *planes;
+
+getAChar()
+{
+#ifdef BSD
+ return (getchar());
+#endif
+#ifdef SYSV
+ int c;
+
+ while ((c = getchar()) == -1 && errno == EINTR) ;
+ return(c);
+#endif
+}
+
+erase_all()
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ wmove(cleanradar, pp->ypos, pp->xpos * 2);
+ wmove(radar, pp->ypos, pp->xpos * 2);
+ waddch(radar, winch(cleanradar));
+ wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
+ wmove(radar, pp->ypos, pp->xpos * 2 + 1);
+ waddch(radar, winch(cleanradar));
+ }
+}
+
+draw_all()
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ if (pp->status == S_MARKED)
+ wstandout(radar);
+ wmove(radar, pp->ypos, pp->xpos * 2);
+ waddch(radar, name(pp));
+ waddch(radar, '0' + pp->altitude);
+ if (pp->status == S_MARKED)
+ wstandend(radar);
+ }
+ wrefresh(radar);
+ planewin();
+ wrefresh(input); /* return cursor */
+ fflush(stdout);
+}
+
+init_gr()
+{
+ static char buffer[BUFSIZ];
+
+ initscr();
+ setbuf(stdout, buffer);
+ input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
+ credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
+ COLS - PLANE_COLS);
+ planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
+}
+
+setup_screen(scp)
+ C_SCREEN *scp;
+{
+ register int i, j;
+ char str[3], *airstr;
+
+ str[2] = '\0';
+
+ if (radar != NULL)
+ delwin(radar);
+ radar = newwin(scp->height, scp->width * 2, 0, 0);
+
+ if (cleanradar != NULL)
+ delwin(cleanradar);
+ cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
+
+ /* minus one here to prevent a scroll */
+ for (i = 0; i < PLANE_COLS - 1; i++) {
+ wmove(credit, 0, i);
+ waddch(credit, C_CREDIT);
+ wmove(credit, INPUT_LINES - 1, i);
+ waddch(credit, C_CREDIT);
+ }
+ wmove(credit, INPUT_LINES / 2, 1);
+ waddstr(credit, AUTHOR_STR);
+
+ for (i = 1; i < scp->height - 1; i++) {
+ for (j = 1; j < scp->width - 1; j++) {
+ wmove(radar, i, j * 2);
+ waddch(radar, C_BACKROUND);
+ }
+ }
+
+ /*
+ * Draw the lines first, since people like to draw lines
+ * through beacons and exit points.
+ */
+ str[0] = C_LINE;
+ for (i = 0; i < scp->num_lines; i++) {
+ str[1] = ' ';
+ draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
+ scp->line[i].p2.x, scp->line[i].p2.y, str);
+ }
+
+ str[0] = C_TOPBOTTOM;
+ str[1] = C_TOPBOTTOM;
+ wmove(radar, 0, 0);
+ for (i = 0; i < scp->width - 1; i++)
+ waddstr(radar, str);
+ waddch(radar, C_TOPBOTTOM);
+
+ str[0] = C_TOPBOTTOM;
+ str[1] = C_TOPBOTTOM;
+ wmove(radar, scp->height - 1, 0);
+ for (i = 0; i < scp->width - 1; i++)
+ waddstr(radar, str);
+ waddch(radar, C_TOPBOTTOM);
+
+ for (i = 1; i < scp->height - 1; i++) {
+ wmove(radar, i, 0);
+ waddch(radar, C_LEFTRIGHT);
+ wmove(radar, i, (scp->width - 1) * 2);
+ waddch(radar, C_LEFTRIGHT);
+ }
+
+ str[0] = C_BEACON;
+ for (i = 0; i < scp->num_beacons; i++) {
+ str[1] = '0' + i;
+ wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
+ waddstr(radar, str);
+ }
+
+ for (i = 0; i < scp->num_exits; i++) {
+ wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
+ waddch(radar, '0' + i);
+ }
+
+ airstr = "^?>?v?<?";
+ for (i = 0; i < scp->num_airports; i++) {
+ str[0] = airstr[scp->airport[i].dir];
+ str[1] = '0' + i;
+ wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
+ waddstr(radar, str);
+ }
+
+ overwrite(radar, cleanradar);
+ wrefresh(radar);
+ wrefresh(credit);
+ fflush(stdout);
+}
+
+draw_line(w, x, y, lx, ly, s)
+ WINDOW *w;
+ char *s;
+{
+ int dx, dy;
+
+ dx = SGN(lx - x);
+ dy = SGN(ly - y);
+ for (;;) {
+ wmove(w, y, x * 2);
+ waddstr(w, s);
+ if (x == lx && y == ly)
+ break;
+ x += dx;
+ y += dy;
+ }
+}
+
+ioclrtoeol(pos)
+{
+ wmove(input, 0, pos);
+ wclrtoeol(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+iomove(pos)
+{
+ wmove(input, 0, pos);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioaddstr(pos, str)
+ char *str;
+{
+ wmove(input, 0, pos);
+ waddstr(input, str);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioclrtobot()
+{
+ wclrtobot(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+ioerror(pos, len, str)
+ char *str;
+{
+ int i;
+
+ wmove(input, 1, pos);
+ for (i = 0; i < len; i++)
+ waddch(input, '^');
+ wmove(input, 2, 0);
+ waddstr(input, str);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+quit()
+{
+ int c, y, x;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+
+ getyx(input, y, x);
+ wmove(input, 2, 0);
+ waddstr(input, "Really quit? (y/n) ");
+ wclrtobot(input);
+ wrefresh(input);
+ fflush(stdout);
+
+ c = getchar();
+ if (c == EOF || c == 'y') {
+ /* disable timer */
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+ fflush(stdout);
+ clear();
+ refresh();
+ endwin();
+ log_score(0);
+ exit(0);
+ }
+ wmove(input, 2, 0);
+ wclrtobot(input);
+ wmove(input, y, x);
+ wrefresh(input);
+ fflush(stdout);
+ return;
+}
+
+planewin()
+{
+ PLANE *pp;
+ char *command();
+ int warning = 0;
+
+#ifdef BSD
+ wclear(planes);
+#endif
+
+ wmove(planes, 0,0);
+
+#ifdef SYSV
+ wclrtobot(planes);
+#endif
+ wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
+ wmove(planes, 2, 0);
+
+ waddstr(planes, "pl dt comm");
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ if (waddch(planes, '\n') == ERR) {
+ warning++;
+ break;
+ }
+ waddstr(planes, command(pp));
+ }
+ waddch(planes, '\n');
+ for (pp = ground.head; pp != NULL; pp = pp->next) {
+ if (waddch(planes, '\n') == ERR) {
+ warning++;
+ break;
+ }
+ waddstr(planes, command(pp));
+ }
+ if (warning) {
+ wmove(planes, LINES - INPUT_LINES - 1, 0);
+ waddstr(planes, "---- more ----");
+ wclrtoeol(planes);
+ }
+ wrefresh(planes);
+ fflush(stdout);
+}
+
+loser(p, s)
+ PLANE *p;
+ char *s;
+{
+ int c;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+
+ /* disable timer */
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+
+ wmove(input, 0, 0);
+ wclrtobot(input);
+ wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
+ name(p), s);
+ wrefresh(input);
+ fflush(stdout);
+ while ((c = getchar()) != EOF && c != ' ')
+ ;
+ clear(); /* move to top of screen */
+ refresh();
+ endwin();
+ log_score(0);
+ exit(0);
+}
+
+redraw()
+{
+ clear();
+ refresh();
+
+ touchwin(radar);
+ wrefresh(radar);
+ touchwin(planes);
+ wrefresh(planes);
+ touchwin(credit);
+ wrefresh(credit);
+
+ /* refresh input last to get cursor in right place */
+ touchwin(input);
+ wrefresh(input);
+ fflush(stdout);
+}
+
+
+done_screen()
+{
+ clear();
+ refresh();
+ endwin(); /* clean up curses */
+}
diff --git a/atc/include.h b/atc/include.h
new file mode 100644
index 00000000..aa77562f
--- /dev/null
+++ b/atc/include.h
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)include.h 5.3 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+
+#ifdef BSD
+#include <sgtty.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#endif
+
+#ifdef SYSV
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/utsname.h>
+#endif
+
+#include <signal.h>
+#include <math.h>
+
+#include <curses.h>
+
+#ifdef SYSV
+#define index strchr
+#define rindex strrchr
+#define bcopy(a,b,c) memcpy((b), (a), (c))
+#define bzero(a,b) memset((a), '\0', (b))
+#define srandom srand
+#define random rand
+#define sgttyb termio
+#define sg_erase c_cc[2]
+#define sg_kill c_cc[3]
+#endif
+
+#include "def.h"
+#include "struct.h"
+#include "extern.h"
+#include "tunable.h"
diff --git a/atc/input.c b/atc/input.c
new file mode 100644
index 00000000..693a7a3a
--- /dev/null
+++ b/atc/input.c
@@ -0,0 +1,663 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 4/30/90";
+#endif not lint
+
+#include "include.h"
+#include "pathnames.h"
+
+#define MAXRULES 6
+#define MAXDEPTH 15
+
+#define RETTOKEN '\n'
+#ifdef SYSV
+#define CRTOKEN '\r'
+#endif
+#define REDRAWTOKEN '\014' /* CTRL(L) */
+#define SHELLTOKEN '!'
+#define HELPTOKEN '?'
+#define ALPHATOKEN 256
+#define NUMTOKEN 257
+
+typedef struct {
+ int token;
+ int to_state;
+ char *str;
+ char *(*func)();
+} RULE;
+
+typedef struct {
+ int num_rules;
+ RULE *rule;
+} STATE;
+
+typedef struct {
+ char str[20];
+ int state;
+ int rule;
+ int ch;
+ int pos;
+} STACK;
+
+#define T_RULE stack[level].rule
+#define T_STATE stack[level].state
+#define T_STR stack[level].str
+#define T_POS stack[level].pos
+#define T_CH stack[level].ch
+
+#define NUMELS(a) (sizeof (a) / sizeof (*(a)))
+
+#define NUMSTATES NUMELS(st)
+
+char *setplane(), *circle(), *left(), *right(), *Left(), *Right(),
+ *beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(),
+ *benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(),
+ *airport(), *turn(), *ignore();
+
+RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane},
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " [a-z]<ret>", NULL }},
+ state1[] = { { 't', 2, " turn", turn },
+ { 'a', 3, " altitude:", NULL },
+ { 'c', 4, " circle", circle },
+ { 'm', 7, " mark", mark },
+ { 'u', 7, " unmark", unmark },
+ { 'i', 7, " ignore", ignore },
+ { HELPTOKEN, 12, " tacmui", NULL }},
+ state2[] = { { 'l', 6, " left", left },
+ { 'r', 6, " right", right },
+ { 'L', 4, " left 90", Left },
+ { 'R', 4, " right 90", Right },
+ { 't', 11, " towards", NULL },
+ { 'w', 4, " to 0", to_dir },
+ { 'e', 4, " to 45", to_dir },
+ { 'd', 4, " to 90", to_dir },
+ { 'c', 4, " to 135", to_dir },
+ { 'x', 4, " to 180", to_dir },
+ { 'z', 4, " to 225", to_dir },
+ { 'a', 4, " to 270", to_dir },
+ { 'q', 4, " to 315", to_dir },
+ { HELPTOKEN, 12, " lrLRt<dir>", NULL }},
+ state3[] = { { '+', 10, " climb", climb },
+ { 'c', 10, " climb", climb },
+ { '-', 10, " descend", descend },
+ { 'd', 10, " descend", descend },
+ { NUMTOKEN, 7, " %c000 feet", setalt },
+ { HELPTOKEN, 12, " +-cd[0-9]", NULL }},
+ state4[] = { { '@', 9, " at", NULL },
+ { 'a', 9, " at", NULL },
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " @a<ret>", NULL }},
+ state5[] = { { NUMTOKEN, 7, "%c", delayb },
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state6[] = { { '@', 9, " at", NULL },
+ { 'a', 9, " at", NULL },
+ { 'w', 4, " 0", rel_dir },
+ { 'e', 4, " 45", rel_dir },
+ { 'd', 4, " 90", rel_dir },
+ { 'c', 4, " 135", rel_dir },
+ { 'x', 4, " 180", rel_dir },
+ { 'z', 4, " 225", rel_dir },
+ { 'a', 4, " 270", rel_dir },
+ { 'q', 4, " 315", rel_dir },
+ { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " @a<dir><ret>",NULL }},
+ state7[] = { { RETTOKEN, -1, "", NULL },
+#ifdef SYSV
+ { CRTOKEN, -1, "", NULL },
+#endif
+ { HELPTOKEN, 12, " <ret>", NULL }},
+ state8[] = { { NUMTOKEN, 4, "%c", benum },
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state9[] = { { 'b', 5, " beacon #", NULL },
+ { '*', 5, " beacon #", NULL },
+ { HELPTOKEN, 12, " b*", NULL }},
+ state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt},
+ { HELPTOKEN, 12, " [0-9]", NULL }},
+ state11[] = { { 'b', 8, " beacon #", beacon },
+ { '*', 8, " beacon #", beacon },
+ { 'e', 8, " exit #", ex_it },
+ { 'a', 8, " airport #", airport },
+ { HELPTOKEN, 12, " b*ea", NULL }},
+ state12[] = { { -1, -1, "", NULL }};
+
+#define DEF_STATE(s) { NUMELS(s), (s) }
+
+STATE st[] = {
+ DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
+ DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
+ DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
+ DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
+ DEF_STATE(state12)
+};
+
+PLANE p;
+STACK stack[MAXDEPTH];
+int level;
+int tval;
+int dest_type, dest_no, dir;
+
+pop()
+{
+ if (level == 0)
+ return (-1);
+ level--;
+
+ ioclrtoeol(T_POS);
+
+ strcpy(T_STR, "");
+ T_RULE = -1;
+ T_CH = -1;
+ return (0);
+}
+
+rezero()
+{
+ iomove(0);
+
+ level = 0;
+ T_STATE = 0;
+ T_RULE = -1;
+ T_CH = -1;
+ T_POS = 0;
+ strcpy(T_STR, "");
+}
+
+push(ruleno, ch)
+{
+ int newstate, newpos;
+
+ (void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
+ T_RULE = ruleno;
+ T_CH = ch;
+ newstate = st[T_STATE].rule[ruleno].to_state;
+ newpos = T_POS + strlen(T_STR);
+
+ ioaddstr(T_POS, T_STR);
+
+ if (level == 0)
+ ioclrtobot();
+ level++;
+ T_STATE = newstate;
+ T_POS = newpos;
+ T_RULE = -1;
+ strcpy(T_STR, "");
+}
+
+getcommand()
+{
+ int c, i, done;
+ char *s, *(*func)();
+ PLANE *pp;
+
+ rezero();
+
+ do {
+ c = gettoken();
+ if (c == tty_new.sg_erase) {
+ if (pop() < 0)
+ noise();
+ } else if (c == tty_new.sg_kill) {
+ while (pop() >= 0)
+ ;
+ } else {
+ done = 0;
+ for (i = 0; i < st[T_STATE].num_rules; i++) {
+ if (st[T_STATE].rule[i].token == c ||
+ st[T_STATE].rule[i].token == tval) {
+ push(i, (c >= ALPHATOKEN) ? tval : c);
+ done = 1;
+ break;
+ }
+ }
+ if (!done)
+ noise();
+ }
+ } while (T_STATE != -1);
+
+ if (level == 1)
+ return (1); /* forced update */
+
+ dest_type = T_NODEST;
+
+ for (i = 0; i < level; i++) {
+ func = st[stack[i].state].rule[stack[i].rule].func;
+ if (func != NULL)
+ if ((s = (*func)(stack[i].ch)) != NULL) {
+ ioerror(stack[i].pos, strlen(stack[i].str), s);
+ return (-1);
+ }
+ }
+
+ pp = findplane(p.plane_no);
+ if (pp->new_altitude != p.new_altitude)
+ pp->new_altitude = p.new_altitude;
+ else if (pp->status != p.status)
+ pp->status = p.status;
+ else {
+ pp->new_dir = p.new_dir;
+ pp->delayd = p.delayd;
+ pp->delayd_no = p.delayd_no;
+ }
+ return (0);
+}
+
+noise()
+{
+ putchar('\07');
+ fflush(stdout);
+}
+
+gettoken()
+{
+ while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
+ {
+ if (tval == SHELLTOKEN)
+ {
+#ifdef BSD
+ struct itimerval itv;
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ int aval;
+ aval = alarm(0);
+#endif
+ if (fork() == 0) /* child */
+ {
+ char *shell, *base, *getenv(), *strrchr();
+
+ setuid(getuid()); /* turn off setuid bit */
+ done_screen();
+
+ /* run user's favorite shell */
+ if ((shell = getenv("SHELL")) != NULL)
+ {
+ base = strrchr(shell, '/');
+ if (base == NULL)
+ base = shell;
+ else
+ base++;
+ execl(shell, base, 0);
+ }
+ else
+ execl(_PATH_BSHELL, "sh", 0);
+
+ exit(0); /* oops */
+ }
+
+ wait(0);
+#ifdef BSD
+ ioctl(fileno(stdin), TIOCSETP, &tty_new);
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 1;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ ioctl(fileno(stdin), TCSETAW, &tty_new);
+ alarm(aval);
+#endif
+ }
+ redraw();
+ }
+
+ if (isdigit(tval))
+ return (NUMTOKEN);
+ else if (isalpha(tval))
+ return (ALPHATOKEN);
+ else
+ return (tval);
+}
+
+char *
+setplane(c)
+{
+ PLANE *pp;
+
+ pp = findplane(number(c));
+ if (pp == NULL)
+ return ("Unknown Plane");
+ bcopy(pp, &p, sizeof (p));
+ p.delayd = 0;
+ return (NULL);
+}
+
+char *
+turn(c)
+{
+ if (p.altitude == 0)
+ return ("Planes at airports may not change direction");
+ return (NULL);
+}
+
+char *
+circle(c)
+{
+ if (p.altitude == 0)
+ return ("Planes cannot circle on the ground");
+ p.new_dir = MAXDIR;
+ return (NULL);
+}
+
+char *
+left(c)
+{
+ dir = D_LEFT;
+ p.new_dir = p.dir - 1;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ return (NULL);
+}
+
+char *
+right(c)
+{
+ dir = D_RIGHT;
+ p.new_dir = p.dir + 1;
+ if (p.new_dir > MAXDIR)
+ p.new_dir -= MAXDIR;
+ return (NULL);
+}
+
+char *
+Left(c)
+{
+ p.new_dir = p.dir - 2;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ return (NULL);
+}
+
+char *
+Right(c)
+{
+ p.new_dir = p.dir + 2;
+ if (p.new_dir > MAXDIR)
+ p.new_dir -= MAXDIR;
+ return (NULL);
+}
+
+char *
+delayb(c)
+{
+ int xdiff, ydiff;
+
+ c -= '0';
+
+ if (c >= sp->num_beacons)
+ return ("Unknown beacon");
+ xdiff = sp->beacon[c].x - p.xpos;
+ xdiff = SGN(xdiff);
+ ydiff = sp->beacon[c].y - p.ypos;
+ ydiff = SGN(ydiff);
+ if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
+ return ("Beacon is not in flight path");
+ p.delayd = 1;
+ p.delayd_no = c;
+
+ if (dest_type != T_NODEST) {
+ switch (dest_type) {
+ case T_BEACON:
+ xdiff = sp->beacon[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->beacon[dest_no].y - sp->beacon[c].y;
+ break;
+ case T_EXIT:
+ xdiff = sp->exit[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->exit[dest_no].y - sp->beacon[c].y;
+ break;
+ case T_AIRPORT:
+ xdiff = sp->airport[dest_no].x - sp->beacon[c].x;
+ ydiff = sp->airport[dest_no].y - sp->beacon[c].y;
+ break;
+ default:
+ return ("Bad case in delayb! Get help!");
+ break;
+ }
+ if (xdiff == 0 && ydiff == 0)
+ return ("Would already be there");
+ p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
+ if (p.new_dir == p.dir)
+ return ("Already going in that direction");
+ }
+ return (NULL);
+}
+
+char *
+beacon(c)
+{
+ dest_type = T_BEACON;
+ return (NULL);
+}
+
+char *
+ex_it(c)
+{
+ dest_type = T_EXIT;
+ return (NULL);
+}
+
+char *
+airport(c)
+{
+ dest_type = T_AIRPORT;
+ return (NULL);
+}
+
+char *
+climb(c)
+{
+ dir = D_UP;
+ return (NULL);
+}
+
+char *
+descend(c)
+{
+ dir = D_DOWN;
+ return (NULL);
+}
+
+char *
+setalt(c)
+{
+ if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
+ return ("Already at that altitude");
+ p.new_altitude = c - '0';
+ return (NULL);
+}
+
+char *
+setrelalt(c)
+{
+ if (c == 0)
+ return ("altitude not changed");
+
+ switch (dir) {
+ case D_UP:
+ p.new_altitude = p.altitude + c - '0';
+ break;
+ case D_DOWN:
+ p.new_altitude = p.altitude - (c - '0');
+ break;
+ default:
+ return ("Unknown case in setrelalt! Get help!");
+ break;
+ }
+ if (p.new_altitude < 0)
+ return ("Altitude would be too low");
+ else if (p.new_altitude > 9)
+ return ("Altitude would be too high");
+ return (NULL);
+}
+
+char *
+benum(c)
+{
+ dest_no = c -= '0';
+
+ switch (dest_type) {
+ case T_BEACON:
+ if (c >= sp->num_beacons)
+ return ("Unknown beacon");
+ p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos,
+ sp->beacon[c].y - p.ypos);
+ break;
+ case T_EXIT:
+ if (c >= sp->num_exits)
+ return ("Unknown exit");
+ p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos,
+ sp->exit[c].y - p.ypos);
+ break;
+ case T_AIRPORT:
+ if (c >= sp->num_airports)
+ return ("Unknown airport");
+ p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos,
+ sp->airport[c].y - p.ypos);
+ break;
+ default:
+ return ("Unknown case in benum! Get help!");
+ break;
+ }
+ return (NULL);
+}
+
+char *
+to_dir(c)
+{
+ p.new_dir = dir_no(c);
+ return (NULL);
+}
+
+char *
+rel_dir(c)
+{
+ int angle;
+
+ angle = dir_no(c);
+ switch (dir) {
+ case D_LEFT:
+ p.new_dir = p.dir - angle;
+ if (p.new_dir < 0)
+ p.new_dir += MAXDIR;
+ break;
+ case D_RIGHT:
+ p.new_dir = p.dir + angle;
+ if (p.new_dir >= MAXDIR)
+ p.new_dir -= MAXDIR;
+ break;
+ default:
+ return ("Bizarre direction in rel_dir! Get help!");
+ break;
+ }
+ return (NULL);
+}
+
+char *
+mark(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot mark planes on the ground");
+ if (p.status == S_MARKED)
+ return ("Already marked");
+ p.status = S_MARKED;
+ return (NULL);
+}
+
+char *
+unmark(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot unmark planes on the ground");
+ if (p.status == S_UNMARKED)
+ return ("Already unmarked");
+ p.status = S_UNMARKED;
+ return (NULL);
+}
+
+char *
+ignore(c)
+{
+ if (p.altitude == 0)
+ return ("Cannot ignore planes on the ground");
+ if (p.status == S_IGNORED)
+ return ("Already ignored");
+ p.status = S_IGNORED;
+ return (NULL);
+}
+
+dir_no(ch)
+ char ch;
+{
+ int dir;
+
+ switch (ch) {
+ case 'w': dir = 0; break;
+ case 'e': dir = 1; break;
+ case 'd': dir = 2; break;
+ case 'c': dir = 3; break;
+ case 'x': dir = 4; break;
+ case 'z': dir = 5; break;
+ case 'a': dir = 6; break;
+ case 'q': dir = 7; break;
+ default:
+ fprintf(stderr, "bad character in dir_no\n");
+ break;
+ }
+ return (dir);
+}
diff --git a/atc/lex.l b/atc/lex.l
new file mode 100644
index 00000000..65e0ad54
--- /dev/null
+++ b/atc/lex.l
@@ -0,0 +1,69 @@
+%{
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lex.l 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+#include "y.tab.h"
+extern int line;
+
+%}
+%%
+[0-9]+ { yylval.ival = atoi(yytext); return(ConstOp); }
+height { return(HeightOp); }
+width { return(WidthOp); }
+newplane { return(NewplaneOp); }
+update { return(UpdateOp); }
+airport { return(AirportOp); }
+line { return(LineOp); }
+exit { return(ExitOp); }
+beacon { return(BeaconOp); }
+[wedcxzaq] { yylval.cval = *yytext; return (DirOp); }
+[ \t]+ { }
+#[^\n]*\n { line++; }
+\n { line++; }
+. { return *yytext; }
diff --git a/atc/list.c b/atc/list.c
new file mode 100644
index 00000000..8da9da2f
--- /dev/null
+++ b/atc/list.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)list.c 5.2 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+#include "include.h"
+
+PLANE *
+newplane()
+{
+ return ((PLANE *) calloc(1, sizeof (PLANE)));
+}
+
+append(l, p)
+ LIST *l;
+ PLANE *p;
+{
+ PLANE *q = NULL, *r = NULL;
+
+ if (l->head == NULL) {
+ p->next = p->prev = NULL;
+ l->head = l->tail = p;
+ } else {
+ q = l -> head;
+
+ while (q != NULL && q->plane_no < p->plane_no) {
+ r = q;
+ q = q -> next;
+ }
+
+ if (q) {
+ if (r) {
+ p->prev = r;
+ r->next = p;
+ p->next = q;
+ q->prev = p;
+ } else {
+ p->next = q;
+ p->prev = NULL;
+ q->prev = p;
+ l->head = p;
+ }
+ } else {
+ l->tail->next = p;
+ p->next = NULL;
+ p->prev = l->tail;
+ l->tail = p;
+ }
+ }
+}
+
+delete(l, p)
+ LIST *l;
+ PLANE *p;
+{
+ if (l->head == NULL)
+ loser(p, "deleted a non-existant plane! Get help!");
+
+ if (l->head == p && l->tail == p)
+ l->head = l->tail = NULL;
+ else if (l->head == p) {
+ l->head = p->next;
+ l->head->prev = NULL;
+ } else if (l->tail == p) {
+ l->tail = p->prev;
+ l->tail->next = NULL;
+ } else {
+ p->prev->next = p->next;
+ p->next->prev = p->prev;
+ }
+}
diff --git a/atc/log.c b/atc/log.c
new file mode 100644
index 00000000..5872583f
--- /dev/null
+++ b/atc/log.c
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c 5.7 (Berkeley) 10/30/90";
+#endif not lint
+
+#include "include.h"
+#include "pathnames.h"
+
+compar(a, b)
+ SCORE *a, *b;
+{
+ if (b->planes == a->planes)
+ return (b->time - a->time);
+ else
+ return (b->planes - a->planes);
+}
+
+#define SECAMIN 60
+#define MINAHOUR 60
+#define HOURADAY 24
+#define SECAHOUR (SECAMIN * MINAHOUR)
+#define SECADAY (SECAHOUR * HOURADAY)
+#define DAY(t) ((t) / SECADAY)
+#define HOUR(t) (((t) % SECADAY) / SECAHOUR)
+#define MIN(t) (((t) % SECAHOUR) / SECAMIN)
+#define SEC(t) ((t) % SECAMIN)
+
+char *
+timestr(t)
+{
+ static char s[80];
+
+ if (DAY(t) > 0)
+ (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t));
+ else if (HOUR(t) > 0)
+ (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t));
+ else if (MIN(t) > 0)
+ (void)sprintf(s, "%d:%02d", MIN(t), SEC(t));
+ else if (SEC(t) > 0)
+ (void)sprintf(s, ":%02d", SEC(t));
+ else
+ *s = '\0';
+
+ return (s);
+}
+
+log_score(list_em)
+{
+ register int i, fd, num_scores = 0, good, changed = 0, found = 0;
+ struct passwd *pw;
+ FILE *fp;
+ char *cp, *index(), *rindex();
+ SCORE score[100], thisscore;
+#ifdef SYSV
+ struct utsname name;
+#endif
+
+ umask(0);
+ fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644);
+ if (fd < 0) {
+ perror(_PATH_SCORE);
+ return (-1);
+ }
+ /*
+ * This is done to take advantage of stdio, while still
+ * allowing a O_CREAT during the open(2) of the log file.
+ */
+ fp = fdopen(fd, "r+");
+ if (fp == NULL) {
+ perror(_PATH_SCORE);
+ return (-1);
+ }
+#ifdef BSD
+ if (flock(fileno(fp), LOCK_EX) < 0)
+#endif
+#ifdef SYSV
+ while (lockf(fileno(fp), F_LOCK, 1) < 0)
+#endif
+ {
+ perror("flock");
+ return (-1);
+ }
+ for (;;) {
+ good = fscanf(fp, "%s %s %s %d %d %d",
+ score[num_scores].name,
+ score[num_scores].host,
+ score[num_scores].game,
+ &score[num_scores].planes,
+ &score[num_scores].time,
+ &score[num_scores].real_time);
+ if (good != 6 || ++num_scores >= NUM_SCORES)
+ break;
+ }
+ if (!test_mode && !list_em) {
+ if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
+ fprintf(stderr,
+ "getpwuid failed for uid %d. Who are you?\n",
+ getuid());
+ return (-1);
+ }
+ strcpy(thisscore.name, pw->pw_name);
+#ifdef BSD
+ if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) {
+ perror("gethostname");
+ return (-1);
+ }
+#endif
+#ifdef SYSV
+ uname(&name);
+ strcpy(thisscore.host, name.sysname);
+#endif
+
+ cp = rindex(file, '/');
+ if (cp == NULL) {
+ fprintf(stderr, "log: where's the '/' in %s?\n", file);
+ return (-1);
+ }
+ cp++;
+ strcpy(thisscore.game, cp);
+
+ thisscore.time = clck;
+ thisscore.planes = safe_planes;
+ thisscore.real_time = time(0) - start_time;
+
+ for (i = 0; i < num_scores; i++) {
+ if (strcmp(thisscore.name, score[i].name) == 0 &&
+ strcmp(thisscore.host, score[i].host) == 0 &&
+ strcmp(thisscore.game, score[i].game) == 0) {
+ if (thisscore.time > score[i].time) {
+ score[i].time = thisscore.time;
+ score[i].planes = thisscore.planes;
+ score[i].real_time =
+ thisscore.real_time;
+ changed++;
+ }
+ found++;
+ break;
+ }
+ }
+ if (!found) {
+ for (i = 0; i < num_scores; i++) {
+ if (thisscore.time > score[i].time) {
+ if (num_scores < NUM_SCORES)
+ num_scores++;
+ bcopy(&score[i],
+ &score[num_scores - 1],
+ sizeof (score[i]));
+ bcopy(&thisscore, &score[i],
+ sizeof (score[i]));
+ changed++;
+ break;
+ }
+ }
+ }
+ if (!found && !changed && num_scores < NUM_SCORES) {
+ bcopy(&thisscore, &score[num_scores],
+ sizeof (score[num_scores]));
+ num_scores++;
+ changed++;
+ }
+
+ if (changed) {
+ if (found)
+ puts("You beat your previous score!");
+ else
+ puts("You made the top players list!");
+ qsort(score, num_scores, sizeof (*score), compar);
+ rewind(fp);
+ for (i = 0; i < num_scores; i++)
+ fprintf(fp, "%s %s %s %d %d %d\n",
+ score[i].name, score[i].host,
+ score[i].game, score[i].planes,
+ score[i].time, score[i].real_time);
+ } else {
+ if (found)
+ puts("You didn't beat your previous score.");
+ else
+ puts("You didn't make the top players list.");
+ }
+ putchar('\n');
+ }
+#ifdef BSD
+ flock(fileno(fp), LOCK_UN);
+#endif
+#ifdef SYSV
+ /* lock will evaporate upon close */
+#endif
+ fclose(fp);
+ printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host",
+ "game", "time", "real time", "planes safe");
+ puts("-------------------------------------------------------------------------------");
+ for (i = 0; i < num_scores; i++) {
+ cp = index(score[i].host, '.');
+ if (cp != NULL)
+ *cp = '\0';
+ printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1,
+ score[i].name, score[i].host, score[i].game,
+ score[i].time, timestr(score[i].real_time),
+ score[i].planes);
+ }
+ putchar('\n');
+ return (0);
+}
diff --git a/atc/main.c b/atc/main.c
new file mode 100644
index 00000000..e4ce3d0f
--- /dev/null
+++ b/atc/main.c
@@ -0,0 +1,326 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 3/5/91";
+#endif /* not lint */
+
+#include "include.h"
+#include "pathnames.h"
+
+main(ac, av)
+ char *av[];
+{
+ int seed;
+ int f_usage = 0, f_list = 0, f_showscore = 0;
+ int f_printpath = 0;
+ char *file = NULL;
+ char *name, *ptr;
+#ifdef BSD
+ struct itimerval itv;
+#endif
+ extern char *default_game(), *okay_game();
+ extern void log_score(), quit(), update();
+
+ start_time = seed = time(0);
+
+ name = *av++;
+ while (*av) {
+#ifndef SAVEDASH
+ if (**av == '-')
+ *++*av;
+ else
+ break;
+#endif
+ ptr = *av++;
+ while (*ptr) {
+ switch (*ptr) {
+ case '?':
+ case 'u':
+ f_usage++;
+ break;
+ case 'l':
+ f_list++;
+ break;
+ case 's':
+ case 't':
+ f_showscore++;
+ break;
+ case 'p':
+ f_printpath++;
+ break;
+ case 'r':
+ seed = atoi(*av);
+ av++;
+ break;
+ case 'f':
+ case 'g':
+ file = *av;
+ av++;
+ break;
+ default:
+ fprintf(stderr, "Unknown option '%c'\n", *ptr,
+ name);
+ f_usage++;
+ break;
+ }
+ ptr++;
+ }
+ }
+ srandom(seed);
+
+ if (f_usage)
+ fprintf(stderr,
+ "Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
+ name);
+ if (f_showscore)
+ log_score(1);
+ if (f_list)
+ list_games();
+ if (f_printpath) {
+ char buf[100];
+
+ strcpy(buf, _PATH_GAMES);
+ buf[strlen(buf) - 1] = '\0';
+ puts(buf);
+ }
+
+ if (f_usage || f_showscore || f_list || f_printpath)
+ exit(0);
+
+ if (file == NULL)
+ file = default_game();
+ else
+ file = okay_game(file);
+
+ if (file == NULL || read_file(file) < 0)
+ exit(1);
+
+ init_gr();
+ setup_screen(sp);
+
+ addplane();
+
+ signal(SIGINT, quit);
+ signal(SIGQUIT, quit);
+#ifdef BSD
+ signal(SIGTSTP, SIG_IGN);
+ signal(SIGSTOP, SIG_IGN);
+#endif
+ signal(SIGHUP, log_score);
+ signal(SIGTERM, log_score);
+
+#ifdef BSD
+ ioctl(fileno(stdin), TIOCGETP, &tty_start);
+ bcopy(&tty_start, &tty_new, sizeof(tty_new));
+ tty_new.sg_flags |= CBREAK;
+ tty_new.sg_flags &= ~ECHO;
+ ioctl(fileno(stdin), TIOCSETP, &tty_new);
+#endif
+
+#ifdef SYSV
+ ioctl(fileno(stdin), TCGETA, &tty_start);
+ bcopy(&tty_start, &tty_new, sizeof(tty_new));
+ tty_new.c_lflag &= ~ICANON;
+ tty_new.c_lflag &= ~ECHO;
+ tty_new.c_cc[VMIN] = 1;
+ tty_new.c_cc[VTIME] = 0;
+ ioctl(fileno(stdin), TCSETAW, &tty_new);
+#endif
+
+ signal(SIGALRM, update);
+
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 1;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+
+ for (;;) {
+ if (getcommand() != 1)
+ planewin();
+ else {
+#ifdef BSD
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(0);
+#endif
+
+ update();
+
+#ifdef BSD
+ itv.it_value.tv_sec = sp->update_secs;
+ itv.it_value.tv_usec = 0;
+ itv.it_interval.tv_sec = sp->update_secs;
+ itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, NULL);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+ }
+ }
+}
+
+read_file(s)
+ char *s;
+{
+ extern FILE *yyin;
+ int retval;
+
+ file = s;
+ yyin = fopen(s, "r");
+ if (yyin == NULL) {
+ perror(s);
+ return (-1);
+ }
+ retval = yyparse();
+ fclose(yyin);
+
+ if (retval != 0)
+ return (-1);
+ else
+ return (0);
+}
+
+char *
+default_game()
+{
+ FILE *fp;
+ static char file[256];
+ char line[256], games[256];
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (NULL);
+ }
+ if (fgets(line, sizeof(line), fp) == NULL) {
+ fprintf(stderr, "%s: no default game available\n", games);
+ return (NULL);
+ }
+ fclose(fp);
+ line[strlen(line) - 1] = '\0';
+ strcpy(file, _PATH_GAMES);
+ strcat(file, line);
+ return (file);
+}
+
+char *
+okay_game(s)
+ char *s;
+{
+ FILE *fp;
+ static char file[256];
+ char *ret = NULL, line[256], games[256];
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (NULL);
+ }
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ line[strlen(line) - 1] = '\0';
+ if (strcmp(s, line) == 0) {
+ strcpy(file, _PATH_GAMES);
+ strcat(file, line);
+ ret = file;
+ break;
+ }
+ }
+ fclose(fp);
+ if (ret == NULL) {
+ test_mode = 1;
+ ret = s;
+ fprintf(stderr, "%s: %s: game not found\n", games, s);
+ fprintf(stderr, "Your score will not be logged.\n");
+ sleep(2); /* give the guy time to read it */
+ }
+ return (ret);
+}
+
+list_games()
+{
+ FILE *fp;
+ char line[256], games[256];
+ int num_games = 0;
+
+ strcpy(games, _PATH_GAMES);
+ strcat(games, GAMES);
+
+ if ((fp = fopen(games, "r")) == NULL) {
+ perror(games);
+ return (-1);
+ }
+ puts("available games:");
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ printf(" %s", line);
+ num_games++;
+ }
+ fclose(fp);
+ if (num_games == 0) {
+ fprintf(stderr, "%s: no games available\n", games);
+ return (-1);
+ }
+ return (0);
+}
diff --git a/atc/pathnames.h b/atc/pathnames.h
new file mode 100644
index 00000000..72aae534
--- /dev/null
+++ b/atc/pathnames.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 5.4 (Berkeley) 4/30/90
+ */
+
+#include <paths.h>
+
+#define _PATH_GAMES "/usr/share/games/atc/"
+#define _PATH_SCORE "/var/games/atc_score"
diff --git a/atc/struct.h b/atc/struct.h
new file mode 100644
index 00000000..3a5ab490
--- /dev/null
+++ b/atc/struct.h
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)struct.h 5.2 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+typedef struct {
+ int x, y;
+ int dir; /* used only sometimes */
+} SCREEN_POS;
+
+typedef struct {
+ SCREEN_POS p1, p2;
+} LINE;
+
+typedef SCREEN_POS EXIT;
+typedef SCREEN_POS BEACON;
+typedef SCREEN_POS AIRPORT;
+
+typedef struct {
+ int width, height;
+ int update_secs;
+ int newplane_time;
+ int num_exits;
+ int num_lines;
+ int num_beacons;
+ int num_airports;
+ EXIT *exit;
+ LINE *line;
+ BEACON *beacon;
+ AIRPORT *airport;
+} C_SCREEN;
+
+typedef struct plane {
+ struct plane *next, *prev;
+ int status;
+ int plane_no;
+ int plane_type;
+ int orig_no;
+ int orig_type;
+ int dest_no;
+ int dest_type;
+ int altitude;
+ int new_altitude;
+ int dir;
+ int new_dir;
+ int fuel;
+ int xpos;
+ int ypos;
+ int delayd;
+ int delayd_no;
+} PLANE;
+
+typedef struct {
+ PLANE *head, *tail;
+} LIST;
+
+typedef struct {
+ char name[10];
+ char host[256];
+ char game[256];
+ int planes;
+ int time;
+ int real_time;
+} SCORE;
+
+typedef struct displacement {
+ int dx;
+ int dy;
+} DISPLACEMENT;
diff --git a/atc/tunable.c b/atc/tunable.c
new file mode 100644
index 00000000..b6eb4559
--- /dev/null
+++ b/atc/tunable.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tunable.c 5.4 (Berkeley) 4/30/90";
+#endif /* not lint */
+
+/*
+ * NUM_SCORES - Number of scores that are kept track of.
+ * Keep this greater than 0, but less than 100.
+ * 4 lines are printed above the score, one below + your prompt, so
+ * to prevent scrolling: 6 + NUM_SCORES <= 24 (lines on an average terminal).
+ */
+int NUM_SCORES = 18;
diff --git a/atc/tunable.h b/atc/tunable.h
new file mode 100644
index 00000000..8ae00b02
--- /dev/null
+++ b/atc/tunable.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tunable.h 5.3 (Berkeley) 4/30/90
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+extern int NUM_SCORES;
diff --git a/atc/update.c b/atc/update.c
new file mode 100644
index 00000000..4e8a4edb
--- /dev/null
+++ b/atc/update.c
@@ -0,0 +1,410 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ed James.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
+ *
+ * Copy permission is hereby granted provided that this notice is
+ * retained on all partial or complete copies.
+ *
+ * For more info on this and all of my stuff, mail edjames@berkeley.edu.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)update.c 5.5 (Berkeley) 10/30/90";
+#endif not lint
+
+#include "include.h"
+
+update()
+{
+ int i, dir_diff, mask, unclean;
+ PLANE *pp, *p1, *p2, *p;
+
+#ifdef BSD
+ mask = sigblock(sigmask(SIGINT));
+#endif
+#ifdef SYSV
+ alarm(0);
+ signal(SIGALRM, update);
+#endif
+
+ clck++;
+
+ erase_all();
+
+ /* put some planes in the air */
+ do {
+ unclean = 0;
+ for (pp = ground.head; pp != NULL; pp = pp->next) {
+ if (pp->new_altitude > 0) {
+ delete(&ground, pp);
+ append(&air, pp);
+ unclean = 1;
+ break;
+ }
+ }
+ } while (unclean);
+
+ /* do altitude change and basic movement */
+ for (pp = air.head; pp != NULL; pp = pp->next) {
+ /* type 0 only move every other turn */
+ if (pp->plane_type == 0 && clck & 1)
+ continue;
+
+ pp->fuel--;
+ if (pp->fuel < 0)
+ loser(pp, "ran out of fuel.");
+
+ pp->altitude += SGN(pp->new_altitude - pp->altitude);
+
+ if (!pp->delayd) {
+ dir_diff = pp->new_dir - pp->dir;
+ /*
+ * Allow for circle commands
+ */
+ if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
+ if (dir_diff > MAXDIR/2)
+ dir_diff -= MAXDIR;
+ else if (dir_diff < -(MAXDIR/2))
+ dir_diff += MAXDIR;
+ }
+ if (dir_diff > 2)
+ dir_diff = 2;
+ else if (dir_diff < -2)
+ dir_diff = -2;
+ pp->dir += dir_diff;
+ if (pp->dir >= MAXDIR)
+ pp->dir -= MAXDIR;
+ else if (pp->dir < 0)
+ pp->dir += MAXDIR;
+ }
+ pp->xpos += displacement[pp->dir].dx;
+ pp->ypos += displacement[pp->dir].dy;
+
+ if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
+ pp->ypos == sp->beacon[pp->delayd_no].y) {
+ pp->delayd = 0;
+ if (pp->status == S_UNMARKED)
+ pp->status = S_MARKED;
+ }
+
+ switch (pp->dest_type) {
+ case T_AIRPORT:
+ if (pp->xpos == sp->airport[pp->dest_no].x &&
+ pp->ypos == sp->airport[pp->dest_no].y &&
+ pp->altitude == 0) {
+ if (pp->dir != sp->airport[pp->dest_no].dir)
+ loser(pp, "landed in the wrong direction.");
+ else {
+ pp->status = S_GONE;
+ continue;
+ }
+ }
+ break;
+ case T_EXIT:
+ if (pp->xpos == sp->exit[pp->dest_no].x &&
+ pp->ypos == sp->exit[pp->dest_no].y) {
+ if (pp->altitude != 9)
+ loser(pp, "exited at the wrong altitude.");
+ else {
+ pp->status = S_GONE;
+ continue;
+ }
+ }
+ break;
+ default:
+ loser(pp, "has a bizarre destination, get help!");
+ }
+ if (pp->altitude > 9)
+ /* "this is impossible" */
+ loser(pp, "exceded flight ceiling.");
+ if (pp->altitude <= 0) {
+ for (i = 0; i < sp->num_airports; i++)
+ if (pp->xpos == sp->airport[i].x &&
+ pp->ypos == sp->airport[i].y) {
+ if (pp->dest_type == T_AIRPORT)
+ loser(pp,
+ "landed at the wrong airport.");
+ else
+ loser(pp,
+ "landed instead of exited.");
+ }
+ loser(pp, "crashed on the ground.");
+ }
+ if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
+ pp->ypos < 1 || pp->ypos >= sp->height - 1) {
+ for (i = 0; i < sp->num_exits; i++)
+ if (pp->xpos == sp->exit[i].x &&
+ pp->ypos == sp->exit[i].y) {
+ if (pp->dest_type == T_EXIT)
+ loser(pp,
+ "exited via the wrong exit.");
+ else
+ loser(pp,
+ "exited instead of landed.");
+ }
+ loser(pp, "illegally left the flight arena.");
+ }
+ }
+
+ /*
+ * Traverse the list once, deleting the planes that are gone.
+ */
+ for (pp = air.head; pp != NULL; pp = p2) {
+ p2 = pp->next;
+ if (pp->status == S_GONE) {
+ safe_planes++;
+ delete(&air, pp);
+ }
+ }
+
+ draw_all();
+
+ for (p1 = air.head; p1 != NULL; p1 = p1->next)
+ for (p2 = p1->next; p2 != NULL; p2 = p2->next)
+ if (too_close(p1, p2, 1)) {
+ static char buf[80];
+
+ (void)sprintf(buf, "collided with plane '%c'.",
+ name(p2));
+ loser(p1, buf);
+ }
+ /*
+ * Check every other update. Actually, only add on even updates.
+ * Otherwise, prop jobs show up *on* entrance. Remember that
+ * we don't update props on odd updates.
+ */
+ if ((rand() % sp->newplane_time) == 0)
+ addplane();
+
+#ifdef BSD
+ sigsetmask(mask);
+#endif
+#ifdef SYSV
+ alarm(sp->update_secs);
+#endif
+}
+
+char *
+command(pp)
+ PLANE *pp;
+{
+ static char buf[50], *bp, *comm_start;
+ char *index();
+
+ buf[0] = '\0';
+ bp = buf;
+ (void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,
+ (pp->fuel < LOWFUEL) ? '*' : ' ',
+ (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
+
+ comm_start = bp = index(buf, '\0');
+ if (pp->altitude == 0)
+ (void)sprintf(bp, "Holding @ A%d", pp->orig_no);
+ else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
+ strcpy(bp, "Circle");
+ else if (pp->new_dir != pp->dir)
+ (void)sprintf(bp, "%d", dir_deg(pp->new_dir));
+
+ bp = index(buf, '\0');
+ if (pp->delayd)
+ (void)sprintf(bp, " @ B%d", pp->delayd_no);
+
+ bp = index(buf, '\0');
+ if (*comm_start == '\0' &&
+ (pp->status == S_UNMARKED || pp->status == S_IGNORED))
+ strcpy(bp, "---------");
+ return (buf);
+}
+
+/* char */
+name(p)
+ PLANE *p;
+{
+ if (p->plane_type == 0)
+ return ('A' + p->plane_no);
+ else
+ return ('a' + p->plane_no);
+}
+
+number(l)
+{
+ if (l < 'a' && l > 'z' && l < 'A' && l > 'Z')
+ return (-1);
+ else if (l >= 'a' && l <= 'z')
+ return (l - 'a');
+ else
+ return (l - 'A');
+}
+
+next_plane()
+{
+ static int last_plane = -1;
+ PLANE *pp;
+ int found, start_plane = last_plane;
+
+ do {
+ found = 0;
+ last_plane++;
+ if (last_plane >= 26)
+ last_plane = 0;
+ for (pp = air.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == last_plane) {
+ found++;
+ break;
+ }
+ if (!found)
+ for (pp = ground.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == last_plane) {
+ found++;
+ break;
+ }
+ } while (found && last_plane != start_plane);
+ if (last_plane == start_plane)
+ return (-1);
+ return (last_plane);
+}
+
+addplane()
+{
+ PLANE p, *pp, *p1;
+ int i, num_starts, close, rnd, rnd2, pnum;
+
+ bzero(&p, sizeof (p));
+
+ p.status = S_MARKED;
+ p.plane_type = random() % 2;
+
+ num_starts = sp->num_exits + sp->num_airports;
+ rnd = random() % num_starts;
+
+ if (rnd < sp->num_exits) {
+ p.dest_type = T_EXIT;
+ p.dest_no = rnd;
+ } else {
+ p.dest_type = T_AIRPORT;
+ p.dest_no = rnd - sp->num_exits;
+ }
+
+ /* loop until we get a plane not near another */
+ for (i = 0; i < num_starts; i++) {
+ /* loop till we get a different start point */
+ while ((rnd2 = random() % num_starts) == rnd)
+ ;
+ if (rnd2 < sp->num_exits) {
+ p.orig_type = T_EXIT;
+ p.orig_no = rnd2;
+ p.xpos = sp->exit[rnd2].x;
+ p.ypos = sp->exit[rnd2].y;
+ p.new_dir = p.dir = sp->exit[rnd2].dir;
+ p.altitude = p.new_altitude = 7;
+ close = 0;
+ for (p1 = air.head; p1 != NULL; p1 = p1->next)
+ if (too_close(p1, &p, 4)) {
+ close++;
+ break;
+ }
+ if (close)
+ continue;
+ } else {
+ p.orig_type = T_AIRPORT;
+ p.orig_no = rnd2 - sp->num_exits;
+ p.xpos = sp->airport[p.orig_no].x;
+ p.ypos = sp->airport[p.orig_no].y;
+ p.new_dir = p.dir = sp->airport[p.orig_no].dir;
+ p.altitude = p.new_altitude = 0;
+ }
+ p.fuel = sp->width + sp->height;
+ break;
+ }
+ if (i >= num_starts)
+ return (-1);
+ pnum = next_plane();
+ if (pnum < 0)
+ return (-1);
+ p.plane_no = pnum;
+
+ pp = newplane();
+ bcopy(&p, pp, sizeof (p));
+
+ if (pp->orig_type == T_AIRPORT)
+ append(&ground, pp);
+ else
+ append(&air, pp);
+
+ return (pp->dest_type);
+}
+
+PLANE *
+findplane(n)
+{
+ PLANE *pp;
+
+ for (pp = air.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == n)
+ return (pp);
+ for (pp = ground.head; pp != NULL; pp = pp->next)
+ if (pp->plane_no == n)
+ return (pp);
+ return (NULL);
+}
+
+too_close(p1, p2, dist)
+ PLANE *p1, *p2;
+{
+ if (ABS(p1->altitude - p2->altitude) <= dist &&
+ ABS(p1->xpos - p2->xpos) <= dist && ABS(p1->ypos - p2->ypos) <= dist)
+ return (1);
+ else
+ return (0);
+}
+
+dir_deg(d)
+{
+ switch (d) {
+ case 0: return (0);
+ case 1: return (45);
+ case 2: return (90);
+ case 3: return (135);
+ case 4: return (180);
+ case 5: return (225);
+ case 6: return (270);
+ case 7: return (315);
+ default:
+ return (-1);
+ }
+}