Give generate constant arrays the const specifier.
authorEric S. Raymond <esr@thyrsus.com>
Sat, 24 Jun 2017 15:07:07 +0000 (11:07 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 24 Jun 2017 15:07:07 +0000 (11:07 -0400)
Also, move the adventure.txt format documentation to dungeon.c to be
removed when that file is.

dungeon.c
init.c
newdungeon.py

index fea3c6d217cda8d48857e75ee6f88e4820190a80..feb98e79be2f7069dbf523049bfd0da20b0e6dde 100644 (file)
--- a/dungeon.c
+++ b/dungeon.c
@@ -1,9 +1,88 @@
 /*
  * The dungeon compiler. Turns adventure.text into a set of C initializers
- * defining (mostly) invariant state.  A couple of slots are messed with
- * at runtime.
+ * defining invariant state.
  */
 
+/*  Current limits:
+ *     12600 words of message text (LINES, LINSIZ).
+ *     885 travel options (TRAVEL, TRVSIZ).
+ *     330 vocabulary words (KTAB, ATAB, TABSIZ).
+ *      35 "action" verbs (ACTSPK, VRBSIZ).
+ *  There are also limits which cannot be exceeded due to the structure of
+ *  the database.  (E.G., The vocabulary uses n/1000 to determine word type,
+ *  so there can't be more than 1000 words.)  These upper limits are:
+ *     1000 non-synonymous vocabulary words
+ *     300 locations
+ *     100 objects
+ */
+
+/*  Description of the database format
+ *
+ *
+ *  The data file contains several sections.  Each begins with a line containing
+ *  a number identifying the section, and ends with a line containing "-1".
+ *
+ *  Section 3: Travel table.  Each line contains a location number (X), a second
+ *     location number (Y), and a list of motion numbers (see section 4).
+ *     each motion represents a verb which will go to Y if currently at X.
+ *     Y, in turn, is interpreted as follows.  Let M=Y/1000, N=Y mod 1000.
+ *             If N<=300       it is the location to go to.
+ *             If 300<N<=500   N-300 is used in a computed goto to
+ *                                     a section of special code.
+ *             If N>500        message N-500 from section 6 is printed,
+ *                                     and he stays wherever he is.
+ *     Meanwhile, M specifies the conditions on the motion.
+ *             If M=0          it's unconditional.
+ *             If 0<M<100      it is done with M% probability.
+ *             If M=100        unconditional, but forbidden to dwarves.
+ *             If 100<M<=200   he must be carrying object M-100.
+ *             If 200<M<=300   must be carrying or in same room as M-200.
+ *             If 300<M<=400   game.prop(M % 100) must *not* be 0.
+ *             If 400<M<=500   game.prop(M % 100) must *not* be 1.
+ *             If 500<M<=600   game.prop(M % 100) must *not* be 2, etc.
+ *     If the condition (if any) is not met, then the next *different*
+ *     "destination" value is used (unless it fails to meet *its* conditions,
+ *     in which case the next is found, etc.).  Typically, the next dest will
+ *     be for one of the same verbs, so that its only use is as the alternate
+ *     destination for those verbs.  For instance:
+ *             15      110022  29      31      34      35      23      43
+ *             15      14      29
+ *     This says that, from loc 15, any of the verbs 29, 31, etc., will take
+ *     him to 22 if he's carrying object 10, and otherwise will go to 14.
+ *             11      303008  49
+ *             11      9       50
+ *     This says that, from 11, 49 takes him to 8 unless game.prop(3)=0, in which
+ *     case he goes to 9.  Verb 50 takes him to 9 regardless of game.prop(3).
+ *  Section 4: Vocabulary.  Each line contains a number (n), a tab, and a
+ *     five-letter word.  Call M=N/1000.  If M=0, then the word is a motion
+ *     verb for use in travelling (see section 3).  Else, if M=1, the word is
+ *     an object.  Else, if M=2, the word is an action verb (such as "carry"
+ *     or "attack").  Else, if M=3, the word is a special case verb (such as
+ *     "dig") and N % 1000 is an index into section 6.  Objects from 50 to
+ *     (currently, anyway) 79 are considered treasures (for pirate, closeout).
+ *  Section 8: Action defaults.  Each line contains an "action-verb" number and
+ *     the index (in section 6) of the default message for the verb.
+ *  Section 0: End of database.
+ *
+ * Other sections are obsolete and ignored */
+
+/*  The various messages (sections 1, 2, 5, 6, etc.) may include certain
+ *  special character sequences to denote that the program must provide
+ *  parameters to insert into a message when the message is printed.  These
+ *  sequences are:
+ *     %S = The letter 'S' or nothing (if a given value is exactly 1)
+ *     %W = A word (up to 10 characters)
+ *     %L = A word mapped to lower-case letters
+ *     %U = A word mapped to upper-case letters
+ *     %C = A word mapped to lower-case, first letter capitalised
+ *     %T = Several words of text, ending with a word of -1
+ *     %1 = A 1-digit number
+ *     %2 = A 2-digit number
+ *     ...
+ *     %9 = A 9-digit number
+ *     %B = Variable number of blanks
+ *     %! = The entire message should be suppressed */
+
 #define LINESIZE 100
 #define CLSMAX 12
 #define LINSIZ 12600
@@ -25,9 +104,9 @@ static long LNLENG;
 static long LNPOSN;
 static char INLINE[LINESIZE + 1];
 static long OLDLOC;
+static long LINUSE;
 
 // Storage for what comes out of the database
-long LINUSE;
 long TRVS;
 long TRNVLS;
 long TABNDX;
diff --git a/init.c b/init.c
index b19e422fd5a9dc7dd5033ba985ec8048d32b957f..aaa3eaff0e7ee03ec65c0a4d751f7956abdf3bf0 100644 (file)
--- a/init.c
+++ b/init.c
  * Initialisation
  */
 
-/*  Current limits:
- *     12600 words of message text (LINES, LINSIZ).
- *     885 travel options (TRAVEL, TRVSIZ).
- *     330 vocabulary words (KTAB, ATAB, TABSIZ).
- *      35 "action" verbs (ACTSPK, VRBSIZ).
- *  There are also limits which cannot be exceeded due to the structure of
- *  the database.  (E.G., The vocabulary uses n/1000 to determine word type,
- *  so there can't be more than 1000 words.)  These upper limits are:
- *     1000 non-synonymous vocabulary words
- *     300 locations
- *     100 objects
- */
-
-/*  Description of the database format
- *
- *
- *  The data file contains several sections.  Each begins with a line containing
- *  a number identifying the section, and ends with a line containing "-1".
- *
- *  Section 1: Long form descriptions.  Each line contains a location number,
- *     a tab, and a line of text.  The set of (necessarily adjacent) lines
- *     whose numbers are X form the long description of location X.
- *  Section 2: Short form descriptions.  Same format as long form.  Not all
- *     places have short descriptions.
- *  Section 3: Travel table.  Each line contains a location number (X), a second
- *     location number (Y), and a list of motion numbers (see section 4).
- *     each motion represents a verb which will go to Y if currently at X.
- *     Y, in turn, is interpreted as follows.  Let M=Y/1000, N=Y mod 1000.
- *             If N<=300       it is the location to go to.
- *             If 300<N<=500   N-300 is used in a computed goto to
- *                                     a section of special code.
- *             If N>500        message N-500 from section 6 is printed,
- *                                     and he stays wherever he is.
- *     Meanwhile, M specifies the conditions on the motion.
- *             If M=0          it's unconditional.
- *             If 0<M<100      it is done with M% probability.
- *             If M=100        unconditional, but forbidden to dwarves.
- *             If 100<M<=200   he must be carrying object M-100.
- *             If 200<M<=300   must be carrying or in same room as M-200.
- *             If 300<M<=400   game.prop(M % 100) must *not* be 0.
- *             If 400<M<=500   game.prop(M % 100) must *not* be 1.
- *             If 500<M<=600   game.prop(M % 100) must *not* be 2, etc.
- *     If the condition (if any) is not met, then the next *different*
- *     "destination" value is used (unless it fails to meet *its* conditions,
- *     in which case the next is found, etc.).  Typically, the next dest will
- *     be for one of the same verbs, so that its only use is as the alternate
- *     destination for those verbs.  For instance:
- *             15      110022  29      31      34      35      23      43
- *             15      14      29
- *     This says that, from loc 15, any of the verbs 29, 31, etc., will take
- *     him to 22 if he's carrying object 10, and otherwise will go to 14.
- *             11      303008  49
- *             11      9       50
- *     This says that, from 11, 49 takes him to 8 unless game.prop(3)=0, in which
- *     case he goes to 9.  Verb 50 takes him to 9 regardless of game.prop(3).
- *  Section 4: Vocabulary.  Each line contains a number (n), a tab, and a
- *     five-letter word.  Call M=N/1000.  If M=0, then the word is a motion
- *     verb for use in travelling (see section 3).  Else, if M=1, the word is
- *     an object.  Else, if M=2, the word is an action verb (such as "carry"
- *     or "attack").  Else, if M=3, the word is a special case verb (such as
- *     "dig") and N % 1000 is an index into section 6.  Objects from 50 to
- *     (currently, anyway) 79 are considered treasures (for pirate, closeout).
- *  Section 5: Object descriptions.  Each line contains a number (N), a tab,
- *     and a message.  If N is from 1 to 100, the message is the "inventory"
- *     message for object n.  Otherwise, N should be 000, 100, 200, etc., and
- *     the message should be the description of the preceding object when its
- *     prop value is N/100.  The N/100 is used only to distinguish multiple
- *     messages from multi-line messages; the prop info actually requires all
- *     messages for an object to be present and consecutive.  Properties which
- *     produce no message should be given the message ">$<". (The magic value
- *     100 is now mostly abstracted out as NOBJECTS.)
- *  Section 6: Arbitrary messages.  Same format as sections 1, 2, and 5, except
- *     the numbers bear no relation to anything (except for special verbs
- *     in section 4).
- *  Section 7: Object locations.  Each line contains an object number and its
- *     initial location (zero (or omitted) if none).  If the object is
- *     immovable, the location is followed by a "-1".  If it has two locations
- *     (e.g. the grate) the first location is followed with the second, and
- *     the object is assumed to be immovable.
- *  Section 8: Action defaults.  Each line contains an "action-verb" number and
- *     the index (in section 6) of the default message for the verb.
- *  Section 9: Location attributes.  Each line contains a number (n) and up to
- *     20 location numbers.  Bit N (where 0 is the units bit) is set in
- *     COND(LOC) for each loc given.  The cond bits currently assigned are:
- *             0       Light
- *             1       If bit 2 is on: on for oil, off for water
- *             2       Liquid asset, see bit 1
- *             3       Pirate doesn't go here unless following player
- *             4       Cannot use "back" to move away
- *     Bits past 10 indicate areas of interest to "hint" routines:
- *             11      Trying to get into cave
- *             12      Trying to catch bird
- *             13      Trying to deal with snake
- *             14      Lost in maze
- *             15      Pondering dark room
- *             16      At witt's end
- *             17      Cliff with urn
- *             18      Lost in forest
- *             19      Trying to deal with ogre
- *             20      Found all treasures except jade
- *     COND(LOC) is set to 2, overriding all other bits, if loc has forced
- *     motion.
- *  Section 10: Class messages.  Each line contains a number (n), a tab, and a
- *     message describing a classification of player.  The scoring section
- *     selects the appropriate message, where each message is considered to
- *     apply to players whose scores are higher than the previous N but not
- *     higher than this N.  Note that these scores probably change with every
- *     modification (and particularly expansion) of the program.
- *  Section 11: Hints.  Each line contains a hint number (add 10 to get cond
- *     bit; see section 9), the number of turns he must be at the right loc(s)
- *     before triggering the hint, the points deducted for taking the hint,
- *     the message number (section 6) of the question, and the message number
- *     of the hint.  These values are stashed in the "hints" array.
- *  Section 12: Unused in this version.
- *  Section 13: Sounds and text.  Each line contains either 2 or 3 numbers.  If
- *     2 (call them N and S), N is a location and message ABS(S) from section
- *     6 is the sound heard there.  If S<0, the sound there drowns out all
- *     other noises.  If 3 numbers (call them N, S, and T), N is an object
- *     number and S+game.prop(N) is the property message (from section 5) if he
- *     listens to the object, and T+game.prop(N) is the text if he reads it.  If
- *     S or T is -1, the object has no sound or text, respectively.  Neither
- *     S nor T is allowed to be 0.
- *  Section 14: Turn threshholds.  Each line contains a number (N), a tab, and
- *     a message berating the player for taking so many turns.  The messages
- *     must be in the proper (ascending) order.  The message gets printed if
- *     the player exceeds N % 100000 turns, at which time N/100000 points
- *     get deducted from his score.
- *  Section 0: End of database. */
-
-/*  The various messages (sections 1, 2, 5, 6, etc.) may include certain
- *  special character sequences to denote that the program must provide
- *  parameters to insert into a message when the message is printed.  These
- *  sequences are:
- *     %S = The letter 'S' or nothing (if a given value is exactly 1)
- *     %W = A word (up to 10 characters)
- *     %L = A word mapped to lower-case letters
- *     %U = A word mapped to upper-case letters
- *     %C = A word mapped to lower-case, first letter capitalised
- *     %T = Several words of text, ending with a word of -1
- *     %1 = A 1-digit number
- *     %2 = A 2-digit number
- *     ...
- *     %9 = A 9-digit number
- *     %B = Variable number of blanks
- *     %! = The entire message should be suppressed */
-
 void initialise(void)
 {
     if (oldstyle)
index 21ac9e64aa223cb1030b1a153dd5875c62ea72d0..df8b19abbfa6303d7984e54c86dcba4181c859b4 100755 (executable)
@@ -62,13 +62,13 @@ typedef struct {{
   const char* hint;
 }} hint_t;
 
-extern location_t locations[];
-extern object_description_t object_descriptions[];
-extern const char* arbitrary_messages[];
-extern const class_t classes[];
-extern turn_threshold_t turn_thresholds[];
-extern obituary_t obituaries[];
-extern hint_t hints[];
+extern const location_t locations[];
+extern const object_description_t object_descriptions[];
+extern const const char* arbitrary_messages[];
+extern const const class_t classes[];
+extern const turn_threshold_t turn_thresholds[];
+extern const obituary_t obituaries[];
+extern const hint_t hints[];
 extern long conditions[];
 
 #define NLOCATIONS             {}
@@ -109,23 +109,23 @@ const class_t classes[] = {{
 {}
 }};
 
-turn_threshold_t turn_thresholds[] = {{
+const turn_threshold_t turn_thresholds[] = {{
 {}
 }};
 
-location_t locations[] = {{
+const location_t locations[] = {{
 {}
 }};
 
-object_description_t object_descriptions[] = {{
+const object_description_t object_descriptions[] = {{
 {}
 }};
 
-obituary_t obituaries[] = {{
+const obituary_t obituaries[] = {{
 {}
 }};
 
-hint_t hints[] = {{
+const hint_t hints[] = {{
 {}
 }};