magic numbers, show usage, fixed linty warnings
Show usage when using bad parameter with ./advent Converted magic numbers to enums for BUG(). Also bug now shows stringify'ed version of bug enumeration (not just a number).
This commit is contained in:
parent
65e2e472dd
commit
04eca720d9
10 changed files with 140 additions and 116 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,10 +5,10 @@ dungeon
|
||||||
*.o
|
*.o
|
||||||
*.html
|
*.html
|
||||||
database.h
|
database.h
|
||||||
database.c
|
|
||||||
advent.6
|
advent.6
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
MANIFEST
|
MANIFEST
|
||||||
*.adv
|
*.adv
|
||||||
|
.*~
|
||||||
newdb.h
|
newdb.h
|
||||||
newdb.c
|
newdb.c
|
||||||
|
|
22
Makefile
22
Makefile
|
@ -24,6 +24,8 @@
|
||||||
#
|
#
|
||||||
# To build with save/resume disabled, pass CCFLAGS="-D ADVENT_NOSAVE"
|
# To build with save/resume disabled, pass CCFLAGS="-D ADVENT_NOSAVE"
|
||||||
|
|
||||||
|
.PHONY: debug indent release refresh dist linty html clean
|
||||||
|
|
||||||
VERS=1.0
|
VERS=1.0
|
||||||
|
|
||||||
CC?=gcc
|
CC?=gcc
|
||||||
|
@ -118,7 +120,25 @@ refresh: advent.html
|
||||||
|
|
||||||
dist: advent-$(VERS).tar.gz
|
dist: advent-$(VERS).tar.gz
|
||||||
|
|
||||||
linty: CCFLAGS += -W -Wall -Wextra -Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wfloat-equal -Wcast-align -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-enum -Wwrite-strings -Wunreachable-code -Winit-self -Wpointer-arith -O2
|
linty: CCFLAGS += -W
|
||||||
|
linty: CCFLAGS += -Wall
|
||||||
|
linty: CCFLAGS += -Wextra
|
||||||
|
linty: CCFLAGS += -Wundef
|
||||||
|
linty: CCFLAGS += -Wstrict-prototypes
|
||||||
|
linty: CCFLAGS += -Wmissing-prototypes
|
||||||
|
linty: CCFLAGS += -Wmissing-declarations
|
||||||
|
linty: CCFLAGS += -Wshadow
|
||||||
|
linty: CCFLAGS += -Wfloat-equal
|
||||||
|
linty: CCFLAGS += -Wcast-align
|
||||||
|
linty: CCFLAGS += -Wwrite-strings
|
||||||
|
linty: CCFLAGS += -Waggregate-return
|
||||||
|
linty: CCFLAGS += -Wcast-qual
|
||||||
|
linty: CCFLAGS += -Wswitch-enum
|
||||||
|
linty: CCFLAGS += -Wwrite-strings
|
||||||
|
linty: CCFLAGS += -Wunreachable-code
|
||||||
|
linty: CCFLAGS += -Winit-self
|
||||||
|
linty: CCFLAGS += -Wpointer-arith
|
||||||
|
linty: CCFLAGS +=-O2
|
||||||
linty: advent
|
linty: advent
|
||||||
|
|
||||||
debug: CCFLAGS += -O0 --coverage -g
|
debug: CCFLAGS += -O0 --coverage -g
|
||||||
|
|
20
actions.c
20
actions.c
|
@ -789,7 +789,7 @@ static int pour(token_t verb, token_t obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int quit(FILE *input)
|
static int quit(void)
|
||||||
/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */
|
/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */
|
||||||
{
|
{
|
||||||
if (YES(REALLY_QUIT, OK_MAN, OK_MAN))
|
if (YES(REALLY_QUIT, OK_MAN, OK_MAN))
|
||||||
|
@ -797,7 +797,7 @@ static int quit(FILE *input)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read(FILE *input, token_t verb, token_t obj)
|
static int read(token_t verb, token_t obj)
|
||||||
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */
|
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */
|
||||||
{
|
{
|
||||||
int spk = ACTSPK[verb];
|
int spk = ACTSPK[verb];
|
||||||
|
@ -1100,7 +1100,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
|
||||||
case 16: /* TOSS */
|
case 16: /* TOSS */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 17: /* QUIT */
|
case 17: /* QUIT */
|
||||||
return quit(input);
|
return quit();
|
||||||
case 18: /* FIND */
|
case 18: /* FIND */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 19: /* INVEN */
|
case 19: /* INVEN */
|
||||||
|
@ -1120,15 +1120,15 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
|
||||||
case 25: /* BRIEF */
|
case 25: /* BRIEF */
|
||||||
return brief();
|
return brief();
|
||||||
case 26: /* READ */
|
case 26: /* READ */
|
||||||
return read(input, verb, INTRANSITIVE);
|
return read(verb, INTRANSITIVE);
|
||||||
case 27: /* BREAK */
|
case 27: /* BREAK */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 28: /* WAKE */
|
case 28: /* WAKE */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 29: /* SUSP */
|
case 29: /* SUSP */
|
||||||
return suspend(input);
|
return suspend();
|
||||||
case 30: /* RESU */
|
case 30: /* RESU */
|
||||||
return resume(input);
|
return resume();
|
||||||
case 31: /* FLY */
|
case 31: /* FLY */
|
||||||
return fly(verb, INTRANSITIVE);
|
return fly(verb, INTRANSITIVE);
|
||||||
case 32: /* LISTE */
|
case 32: /* LISTE */
|
||||||
|
@ -1136,7 +1136,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
|
||||||
case 33: /* ZZZZ */
|
case 33: /* ZZZZ */
|
||||||
return reservoir();
|
return reservoir();
|
||||||
}
|
}
|
||||||
BUG(23);
|
BUG(INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
|
||||||
}
|
}
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case transitive:
|
case transitive:
|
||||||
|
@ -1210,7 +1210,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 26: /* READ */
|
case 26: /* READ */
|
||||||
return read(input, verb, obj);
|
return read(verb, obj);
|
||||||
case 27: /* BREAK */
|
case 27: /* BREAK */
|
||||||
return vbreak(verb, obj);
|
return vbreak(verb, obj);
|
||||||
case 28: /* WAKE */
|
case 28: /* WAKE */
|
||||||
|
@ -1232,13 +1232,13 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj)
|
||||||
case 33: /* ZZZZ */
|
case 33: /* ZZZZ */
|
||||||
return reservoir();
|
return reservoir();
|
||||||
}
|
}
|
||||||
BUG(24);
|
BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
|
||||||
case unknown:
|
case unknown:
|
||||||
/* Unknown verb, couldn't deduce object - might need hint */
|
/* Unknown verb, couldn't deduce object - might need hint */
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, WD1, WD1X);
|
||||||
RSPEAK(WHAT_DO);
|
RSPEAK(WHAT_DO);
|
||||||
return GO_CHECKHINT;
|
return GO_CHECKHINT;
|
||||||
default:
|
default:
|
||||||
BUG(99);
|
BUG(SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
advent.h
6
advent.h
|
@ -1,4 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -106,7 +107,6 @@ extern long ATDWRF(long);
|
||||||
extern long SETBIT(long);
|
extern long SETBIT(long);
|
||||||
extern bool TSTBIT(long,int);
|
extern bool TSTBIT(long,int);
|
||||||
extern long RNDVOC(long,long);
|
extern long RNDVOC(long,long);
|
||||||
extern void BUG(long) __attribute__((noreturn));
|
|
||||||
extern bool MAPLIN(FILE *);
|
extern bool MAPLIN(FILE *);
|
||||||
extern void DATIME(long*, long*);
|
extern void DATIME(long*, long*);
|
||||||
|
|
||||||
|
@ -117,8 +117,8 @@ extern unsigned long get_next_lcg_value(void);
|
||||||
extern long randrange(long);
|
extern long randrange(long);
|
||||||
extern long score(enum termination);
|
extern long score(enum termination);
|
||||||
extern void terminate(enum termination) __attribute__((noreturn));
|
extern void terminate(enum termination) __attribute__((noreturn));
|
||||||
extern int suspend(FILE *);
|
extern int suspend(void);
|
||||||
extern int resume(FILE *);
|
extern int resume(void);
|
||||||
extern int restore(FILE *);
|
extern int restore(FILE *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
2
common.c
2
common.c
|
@ -1,3 +1,5 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
const char advent_to_ascii[] = {
|
const char advent_to_ascii[] = {
|
||||||
|
|
40
common.h
40
common.h
|
@ -1,3 +1,5 @@
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
/* maximum size limits shared by dungeon compiler and runtime */
|
/* maximum size limits shared by dungeon compiler and runtime */
|
||||||
|
|
||||||
#define LOCSIZ 185
|
#define LOCSIZ 185
|
||||||
|
@ -6,3 +8,41 @@
|
||||||
|
|
||||||
extern const char advent_to_ascii[128];
|
extern const char advent_to_ascii[128];
|
||||||
extern const char ascii_to_advent[128];
|
extern const char ascii_to_advent[128];
|
||||||
|
|
||||||
|
enum bug_e {
|
||||||
|
MESSAGE_LINE_GT_70_CHARACTERS, // 0
|
||||||
|
NULL_LINE_IN_MESSAGE, // 1
|
||||||
|
TOO_MANY_WORDS_OF_MESSAGES, // 2
|
||||||
|
TOO_MANY_TRAVEL_OPTIONS, // 3
|
||||||
|
TOO_MANY_VOCABULARY_WORDS, // 4
|
||||||
|
REQUIRED_VOCABULARY_WORD_NOT_FOUND, // 5
|
||||||
|
TOO_MANY_RTEXT_MESSAGES, // 6
|
||||||
|
TOO_MANY_HINTS, // 7
|
||||||
|
LOCATION_HAS_CONDITION_BIT_BEING_SET_TWICE, // 8
|
||||||
|
INVALID_SECTION_NUMBER_IN_DATABASE, // 9
|
||||||
|
TOO_MANY_LOCATIONS, // 10
|
||||||
|
TOO_MANY_CLASS_OR_TURN_MESSAGES, // 11
|
||||||
|
SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST = 20, // 20
|
||||||
|
RAN_OFF_END_OF_VOCABULARY_TABLE, // 21
|
||||||
|
VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3, // 22
|
||||||
|
INTRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, // 23
|
||||||
|
TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST, // 24
|
||||||
|
CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION, // 25
|
||||||
|
LOCATION_HAS_NO_TRAVEL_ENTRIES, // 26
|
||||||
|
HINT_NUMBER_EXCEEDS_GOTO_LIST, // 27
|
||||||
|
INVALID_MOTH_RETURNED_BY_DATA_FUNCTION, // 28
|
||||||
|
TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM, // 29
|
||||||
|
SPEECHPART_NOT_TRANSITIVE_OR_INTRANSITIVE_OR_UNKNOWN=99, // 99
|
||||||
|
ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH, // 100
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void bug(enum bug_e num, const char *error_string) __attribute__((__noreturn__));
|
||||||
|
static inline void bug(enum bug_e num, const char *error_string)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Fatal error %d, %s.\n", num, error_string);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BUG(x) bug(x, #x)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
68
dungeon.c
68
dungeon.c
|
@ -3,7 +3,6 @@
|
||||||
* defining (mostly) invariant state. A couple of slots are messed with
|
* defining (mostly) invariant state. A couple of slots are messed with
|
||||||
* at runtime.
|
* at runtime.
|
||||||
*/
|
*/
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#define LINESIZE 100
|
#define LINESIZE 100
|
||||||
#define RTXSIZ 277
|
#define RTXSIZ 277
|
||||||
|
@ -20,6 +19,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
// Global variables for use in functions below that can gradually disappear as code is cleaned up
|
// Global variables for use in functions below that can gradually disappear as code is cleaned up
|
||||||
static long LNLENG;
|
static long LNLENG;
|
||||||
|
@ -114,38 +114,6 @@ static long GETTXT(long SKIP, long ONEWRD, long UPPER)
|
||||||
return (TEXT);
|
return (TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BUG(long NUM)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* The following conditions are currently considered fatal bugs. Numbers < 20
|
|
||||||
* are detected while reading the database; the others occur at "run time".
|
|
||||||
* 0 Message line > 70 characters
|
|
||||||
* 1 Null line in message
|
|
||||||
* 2 Too many words of messages
|
|
||||||
* 3 Too many travel options
|
|
||||||
* 4 Too many vocabulary words
|
|
||||||
* 5 Required vocabulary word not found
|
|
||||||
* 6 Too many RTEXT messages
|
|
||||||
* 7 Too many hints
|
|
||||||
* 8 Location has cond bit being set twice
|
|
||||||
* 9 Invalid section number in database
|
|
||||||
* 10 Too many locations
|
|
||||||
* 11 Too many class or turn messages
|
|
||||||
* 20 Special travel (500>L>300) exceeds goto list
|
|
||||||
* 21 Ran off end of vocabulary table
|
|
||||||
* 22 Vocabulary type (N/1000) not between 0 and 3
|
|
||||||
* 23 Intransitive action verb exceeds goto list
|
|
||||||
* 24 Transitive action verb exceeds goto list
|
|
||||||
* 25 Conditional travel entry with no alternative
|
|
||||||
* 26 Location has no travel entries
|
|
||||||
* 27 Hint number exceeds goto list
|
|
||||||
* 28 Invalid month returned by date function
|
|
||||||
* 29 Too many parameters given to SETPRM */
|
|
||||||
|
|
||||||
fprintf(stderr, "Fatal error %ld. See source code for interpretation.\n", NUM);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MAPLIN(FILE *OPENED)
|
static void MAPLIN(FILE *OPENED)
|
||||||
{
|
{
|
||||||
/* Read a line of input, from the specified input source,
|
/* Read a line of input, from the specified input source,
|
||||||
|
@ -236,12 +204,15 @@ static void read_messages(FILE* database, long sect)
|
||||||
long loc;
|
long loc;
|
||||||
LINUSE = KK;
|
LINUSE = KK;
|
||||||
loc = GETNUM(database);
|
loc = GETNUM(database);
|
||||||
if (LNLENG >= LNPOSN + 70)BUG(0);
|
if (LNLENG >= LNPOSN + 70)
|
||||||
|
BUG(MESSAGE_LINE_GT_70_CHARACTERS);
|
||||||
if (loc == -1) return;
|
if (loc == -1) return;
|
||||||
if (LNLENG < LNPOSN)BUG(1);
|
if (LNLENG < LNPOSN)
|
||||||
|
BUG(NULL_LINE_IN_MESSAGE);
|
||||||
do {
|
do {
|
||||||
KK = KK + 1;
|
KK = KK + 1;
|
||||||
if (KK >= LINSIZ)BUG(2);
|
if (KK >= LINSIZ)
|
||||||
|
BUG(TOO_MANY_WORDS_OF_MESSAGES);
|
||||||
LINES[KK] = GETTXT(false, false, false);
|
LINES[KK] = GETTXT(false, false, false);
|
||||||
} while (LINES[KK] != -1);
|
} while (LINES[KK] != -1);
|
||||||
LINES[LINUSE] = KK;
|
LINES[LINUSE] = KK;
|
||||||
|
@ -250,20 +221,23 @@ static void read_messages(FILE* database, long sect)
|
||||||
LINES[LINUSE] = -KK;
|
LINES[LINUSE] = -KK;
|
||||||
if (sect == 14) {
|
if (sect == 14) {
|
||||||
TRNVLS = TRNVLS + 1;
|
TRNVLS = TRNVLS + 1;
|
||||||
if (TRNVLS > TRNSIZ)BUG(11);
|
if (TRNVLS > TRNSIZ)
|
||||||
|
BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES);
|
||||||
TTEXT[TRNVLS] = LINUSE;
|
TTEXT[TRNVLS] = LINUSE;
|
||||||
TRNVAL[TRNVLS] = loc;
|
TRNVAL[TRNVLS] = loc;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sect == 10) {
|
if (sect == 10) {
|
||||||
CLSSES = CLSSES + 1;
|
CLSSES = CLSSES + 1;
|
||||||
if (CLSSES > CLSMAX)BUG(11);
|
if (CLSSES > CLSMAX)
|
||||||
|
BUG(TOO_MANY_CLASS_OR_TURN_MESSAGES);
|
||||||
CTEXT[CLSSES] = LINUSE;
|
CTEXT[CLSSES] = LINUSE;
|
||||||
CVAL[CLSSES] = loc;
|
CVAL[CLSSES] = loc;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sect == 6) {
|
if (sect == 6) {
|
||||||
if (loc > RTXSIZ)BUG(6);
|
if (loc > RTXSIZ)
|
||||||
|
BUG(TOO_MANY_RTEXT_MESSAGES);
|
||||||
RTEXT[loc] = LINUSE;
|
RTEXT[loc] = LINUSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +245,8 @@ static void read_messages(FILE* database, long sect)
|
||||||
if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE;
|
if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (loc > LOCSIZ)BUG(10);
|
if (loc > LOCSIZ)
|
||||||
|
BUG(TOO_MANY_LOCATIONS);
|
||||||
if (sect == 1) {
|
if (sect == 1) {
|
||||||
LTEXT[loc] = LINUSE;
|
LTEXT[loc] = LINUSE;
|
||||||
continue;
|
continue;
|
||||||
|
@ -300,7 +275,8 @@ static void read_section3_stuff(FILE* database)
|
||||||
while ((L = GETNUM(NULL)) != 0) {
|
while ((L = GETNUM(NULL)) != 0) {
|
||||||
TRAVEL[TRVS] = newloc * 1000 + L;
|
TRAVEL[TRVS] = newloc * 1000 + L;
|
||||||
TRVS = TRVS + 1;
|
TRVS = TRVS + 1;
|
||||||
if (TRVS == TRVSIZ)BUG(3);
|
if (TRVS == TRVSIZ)
|
||||||
|
BUG(TOO_MANY_TRAVEL_OPTIONS);
|
||||||
}
|
}
|
||||||
TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1];
|
TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1];
|
||||||
}
|
}
|
||||||
|
@ -316,7 +292,7 @@ static void read_vocabulary(FILE* database)
|
||||||
if (KTAB[TABNDX] == -1) return;
|
if (KTAB[TABNDX] == -1) return;
|
||||||
ATAB[TABNDX] = GETTXT(true, true, true);
|
ATAB[TABNDX] = GETTXT(true, true, true);
|
||||||
} /* end loop */
|
} /* end loop */
|
||||||
BUG(4);
|
BUG(TOO_MANY_VOCABULARY_WORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in the initial locations for each object. Also the immovability info.
|
/* Read in the initial locations for each object. Also the immovability info.
|
||||||
|
@ -347,7 +323,8 @@ static void read_conditions(FILE* database)
|
||||||
while ((K = GETNUM(database)) != -1) {
|
while ((K = GETNUM(database)) != -1) {
|
||||||
long loc;
|
long loc;
|
||||||
while ((loc = GETNUM(NULL)) != 0) {
|
while ((loc = GETNUM(NULL)) != 0) {
|
||||||
if (is_set(COND[loc], K)) BUG(8);
|
if (is_set(COND[loc], K))
|
||||||
|
BUG(LOCATION_HAS_CONDITION_BIT_BEING_SET_TWICE);
|
||||||
COND[loc] = COND[loc] + (1l << K);
|
COND[loc] = COND[loc] + (1l << K);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +337,8 @@ static void read_hints(FILE* database)
|
||||||
long K;
|
long K;
|
||||||
HNTMAX = 0;
|
HNTMAX = 0;
|
||||||
while ((K = GETNUM(database)) != -1) {
|
while ((K = GETNUM(database)) != -1) {
|
||||||
if (K <= 0 || K > HNTSIZ)BUG(7);
|
if (K <= 0 || K > HNTSIZ)
|
||||||
|
BUG(TOO_MANY_HINTS);
|
||||||
for (int I = 1; I <= 4; I++) {
|
for (int I = 1; I <= 4; I++) {
|
||||||
HINTS[K][I] = GETNUM(NULL);
|
HINTS[K][I] = GETNUM(NULL);
|
||||||
} /* end loop */
|
} /* end loop */
|
||||||
|
@ -473,7 +451,7 @@ static int read_database(FILE* database)
|
||||||
read_messages(database, sect);
|
read_messages(database, sect);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BUG(9);
|
BUG(INVALID_SECTION_NUMBER_IN_DATABASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
50
main.c
50
main.c
|
@ -66,7 +66,7 @@ static void sig_handler(int signo)
|
||||||
* 15-treasure version (adventure) by Don Woods, April-June 1977
|
* 15-treasure version (adventure) by Don Woods, April-June 1977
|
||||||
* 20-treasure version (rev 2) by Don Woods, August 1978
|
* 20-treasure version (rev 2) by Don Woods, August 1978
|
||||||
* Errata fixed: 78/12/25
|
* Errata fixed: 78/12/25
|
||||||
* Revived 2017 as Open Advebture.
|
* Revived 2017 as Open Adventure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool do_command(FILE *);
|
static bool do_command(FILE *);
|
||||||
|
@ -102,6 +102,19 @@ int main(int argc, char *argv[])
|
||||||
case 's':
|
case 's':
|
||||||
editline = false;
|
editline = false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s [-l logfilename] [-o] [-r restorefilename] [-s] \n", argv[0]);
|
||||||
|
fprintf(stderr,
|
||||||
|
" where -l creates a log file of your game named as specified'\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" -o 'oldstyle' (no prompt, no command editing, displays 'Initialising...')\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" -r indicates restoring from specified saved game file\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" -s indicates playing with command editing suppressed\n");
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +187,7 @@ static bool fallback_handler(char *buf)
|
||||||
* all come back here eventually to finish the loop. Ignore
|
* all come back here eventually to finish the loop. Ignore
|
||||||
* "HINTS" < 4 (special stuff, see database notes).
|
* "HINTS" < 4 (special stuff, see database notes).
|
||||||
*/
|
*/
|
||||||
static void checkhints(FILE *cmdin)
|
static void checkhints(void)
|
||||||
{
|
{
|
||||||
if (COND[game.loc] >= game.conds) {
|
if (COND[game.loc] >= game.conds) {
|
||||||
for (int hint = 1; hint <= HNTMAX; hint++) {
|
for (int hint = 1; hint <= HNTMAX; hint++) {
|
||||||
|
@ -245,7 +258,7 @@ static void checkhints(FILE *cmdin)
|
||||||
game.hintlc[hint] = 0;
|
game.hintlc[hint] = 0;
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
BUG(27);
|
BUG(HINT_NUMBER_EXCEEDS_GOTO_LIST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +487,7 @@ static bool dwarfmove(void)
|
||||||
* without the lamp!). game.oldloc is zapped so he can't just
|
* without the lamp!). game.oldloc is zapped so he can't just
|
||||||
* "retreat". */
|
* "retreat". */
|
||||||
|
|
||||||
static void croak(FILE *cmdin)
|
static void croak(void)
|
||||||
/* Okay, he's dead. Let's get on with it. */
|
/* Okay, he's dead. Let's get on with it. */
|
||||||
{
|
{
|
||||||
++game.numdie;
|
++game.numdie;
|
||||||
|
@ -511,12 +524,12 @@ static void croak(FILE *cmdin)
|
||||||
* him, so we need game.oldlc2, which is the last place he was
|
* him, so we need game.oldlc2, which is the last place he was
|
||||||
* safe.) */
|
* safe.) */
|
||||||
|
|
||||||
static bool playermove(FILE *cmdin, token_t verb, int motion)
|
static bool playermove(token_t verb, int motion)
|
||||||
{
|
{
|
||||||
int scratchloc, k2, kk = KEY[game.loc];
|
int scratchloc, k2, kk = KEY[game.loc];
|
||||||
game.newloc = game.loc;
|
game.newloc = game.loc;
|
||||||
if (kk == 0)
|
if (kk == 0)
|
||||||
BUG(26);
|
BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES);
|
||||||
if (motion == NUL)
|
if (motion == NUL)
|
||||||
return true;
|
return true;
|
||||||
else if (motion == BACK) {
|
else if (motion == BACK) {
|
||||||
|
@ -625,7 +638,8 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
|
||||||
break;
|
break;
|
||||||
L12:
|
L12:
|
||||||
do {
|
do {
|
||||||
if (TRAVEL[kk] < 0)BUG(25);
|
if (TRAVEL[kk] < 0)
|
||||||
|
BUG(CONDITIONAL_TRAVEL_ENTRY_WITH_NO_ALTERATION);
|
||||||
++kk;
|
++kk;
|
||||||
game.newloc = labs(TRAVEL[kk]) / 1000;
|
game.newloc = labs(TRAVEL[kk]) / 1000;
|
||||||
} while
|
} while
|
||||||
|
@ -687,10 +701,10 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
|
||||||
game.fixed[BEAR] = -1;
|
game.fixed[BEAR] = -1;
|
||||||
game.prop[BEAR] = 3;
|
game.prop[BEAR] = 3;
|
||||||
game.oldlc2 = game.newloc;
|
game.oldlc2 = game.newloc;
|
||||||
croak(cmdin);
|
croak();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BUG(20);
|
BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST);
|
||||||
}
|
}
|
||||||
} while
|
} while
|
||||||
(false);
|
(false);
|
||||||
|
@ -928,13 +942,13 @@ static bool do_command(FILE *cmdin)
|
||||||
game.loc = game.newloc;
|
game.loc = game.newloc;
|
||||||
|
|
||||||
if (!dwarfmove())
|
if (!dwarfmove())
|
||||||
croak(cmdin);
|
croak();
|
||||||
|
|
||||||
/* Describe the current location and (maybe) get next command. */
|
/* Describe the current location and (maybe) get next command. */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (game.loc == 0)
|
if (game.loc == 0)
|
||||||
croak(cmdin);
|
croak();
|
||||||
const char* msg = locations[game.loc].description.small;
|
const char* msg = locations[game.loc].description.small;
|
||||||
if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0)
|
if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0)
|
||||||
msg = locations[game.loc].description.big;
|
msg = locations[game.loc].description.big;
|
||||||
|
@ -944,7 +958,7 @@ static bool do_command(FILE *cmdin)
|
||||||
if (game.wzdark && PCT(35)) {
|
if (game.wzdark && PCT(35)) {
|
||||||
RSPEAK(PIT_FALL);
|
RSPEAK(PIT_FALL);
|
||||||
game.oldlc2 = game.loc;
|
game.oldlc2 = game.loc;
|
||||||
croak(cmdin);
|
croak();
|
||||||
continue; /* back to top of main interpreter loop */
|
continue; /* back to top of main interpreter loop */
|
||||||
}
|
}
|
||||||
msg = arbitrary_messages[PITCH_DARK];
|
msg = arbitrary_messages[PITCH_DARK];
|
||||||
|
@ -952,7 +966,7 @@ static bool do_command(FILE *cmdin)
|
||||||
if (TOTING(BEAR))RSPEAK(TAME_BEAR);
|
if (TOTING(BEAR))RSPEAK(TAME_BEAR);
|
||||||
speak(msg);
|
speak(msg);
|
||||||
if (FORCED(game.loc)) {
|
if (FORCED(game.loc)) {
|
||||||
if (playermove(cmdin, verb, 1))
|
if (playermove(verb, 1))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
continue; /* back to top of main interpreter loop */
|
continue; /* back to top of main interpreter loop */
|
||||||
|
@ -967,7 +981,7 @@ L2012:
|
||||||
obj = 0;
|
obj = 0;
|
||||||
|
|
||||||
L2600:
|
L2600:
|
||||||
checkhints(cmdin);
|
checkhints();
|
||||||
|
|
||||||
/* If closing time, check for any objects being toted with
|
/* If closing time, check for any objects being toted with
|
||||||
* game.prop < 0 and set the prop to -1-game.prop. This way
|
* game.prop < 0 and set the prop to -1-game.prop. This way
|
||||||
|
@ -1062,7 +1076,7 @@ Lookup:
|
||||||
kmod = MOD(defn, 1000);
|
kmod = MOD(defn, 1000);
|
||||||
switch (defn / 1000) {
|
switch (defn / 1000) {
|
||||||
case 0:
|
case 0:
|
||||||
if (playermove(cmdin, verb, kmod))
|
if (playermove(verb, kmod))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
continue; /* back to top of main interpreter loop */
|
continue; /* back to top of main interpreter loop */
|
||||||
|
@ -1078,7 +1092,7 @@ Lookup:
|
||||||
RSPEAK(kmod);
|
RSPEAK(kmod);
|
||||||
goto L2012;
|
goto L2012;
|
||||||
default:
|
default:
|
||||||
BUG(22);
|
BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Laction:
|
Laction:
|
||||||
|
@ -1086,7 +1100,7 @@ Laction:
|
||||||
case GO_TERMINATE:
|
case GO_TERMINATE:
|
||||||
return true;
|
return true;
|
||||||
case GO_MOVE:
|
case GO_MOVE:
|
||||||
playermove(cmdin, verb, NUL);
|
playermove(verb, NUL);
|
||||||
return true;
|
return true;
|
||||||
case GO_TOP:
|
case GO_TOP:
|
||||||
continue; /* back to top of main interpreter loop */
|
continue; /* back to top of main interpreter loop */
|
||||||
|
@ -1116,7 +1130,7 @@ Laction:
|
||||||
RSPEAK(DWARVES_AWAKEN);
|
RSPEAK(DWARVES_AWAKEN);
|
||||||
terminate(endgame);
|
terminate(endgame);
|
||||||
default:
|
default:
|
||||||
BUG(99);
|
BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
misc.c
42
misc.c
|
@ -153,7 +153,7 @@ void SETPRM(long first, long p1, long p2)
|
||||||
* are stored into PARMS(first) and PARMS(first+1). */
|
* are stored into PARMS(first) and PARMS(first+1). */
|
||||||
{
|
{
|
||||||
if (first >= MAXPARMS)
|
if (first >= MAXPARMS)
|
||||||
BUG(29);
|
BUG(TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM);
|
||||||
else {
|
else {
|
||||||
PARMS[first] = p1;
|
PARMS[first] = p1;
|
||||||
PARMS[first + 1] = p2;
|
PARMS[first + 1] = p2;
|
||||||
|
@ -228,7 +228,7 @@ char* get_input()
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
if (isatty(0))
|
if (isatty(0))
|
||||||
printf("%s", input_prompt);
|
printf("%s", input_prompt);
|
||||||
getline(&input, &n, stdin);
|
IGNORE(getline(&input, &n, stdin));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input == NULL) // Got EOF; quit.
|
if (input == NULL) // Got EOF; quit.
|
||||||
|
@ -268,7 +268,7 @@ bool YES(vocab_t question, vocab_t yes_response, vocab_t no_response)
|
||||||
char* firstword = (char*) xmalloc(strlen(reply));
|
char* firstword = (char*) xmalloc(strlen(reply));
|
||||||
sscanf(reply, "%s", firstword);
|
sscanf(reply, "%s", firstword);
|
||||||
|
|
||||||
for (int i = 0; i < strlen(firstword); ++i)
|
for (int i = 0; i < (int)strlen(firstword); ++i)
|
||||||
firstword[i] = tolower(firstword[i]);
|
firstword[i] = tolower(firstword[i]);
|
||||||
|
|
||||||
int yes = strncmp("yes", firstword, sizeof("yes") - 1);
|
int yes = strncmp("yes", firstword, sizeof("yes") - 1);
|
||||||
|
@ -384,7 +384,7 @@ long VOCAB(long id, long init)
|
||||||
lexeme = -1;
|
lexeme = -1;
|
||||||
if (init < 0)
|
if (init < 0)
|
||||||
return (lexeme);
|
return (lexeme);
|
||||||
BUG(5);
|
BUG(REQUIRED_VOCABULARY_WORD_NOT_FOUND);
|
||||||
}
|
}
|
||||||
if (init >= 0 && KTAB[i] / 1000 != init)
|
if (init >= 0 && KTAB[i] / 1000 != init)
|
||||||
continue;
|
continue;
|
||||||
|
@ -395,7 +395,7 @@ long VOCAB(long id, long init)
|
||||||
return (lexeme);
|
return (lexeme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BUG(21);
|
BUG(RAN_OFF_END_OF_VOCABULARY_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JUGGLE(long object)
|
void JUGGLE(long object)
|
||||||
|
@ -497,7 +497,7 @@ long ATDWRF(long where)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value,
|
/* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value,
|
||||||
* randrange, RNDVOC, BUG) */
|
* randrange, RNDVOC) */
|
||||||
|
|
||||||
long SETBIT(long bit)
|
long SETBIT(long bit)
|
||||||
/* Returns 2**bit for use in constructing bit-masks. */
|
/* Returns 2**bit for use in constructing bit-masks. */
|
||||||
|
@ -559,36 +559,6 @@ long RNDVOC(long second, long force)
|
||||||
return rnd;
|
return rnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BUG(long num)
|
|
||||||
/* The following conditions are currently considered fatal bugs. Numbers < 20
|
|
||||||
* are detected while reading the database; the others occur at "run time".
|
|
||||||
* 0 Message line > 70 characters
|
|
||||||
* 1 Null line in message
|
|
||||||
* 2 Too many words of messages
|
|
||||||
* 3 Too many travel options
|
|
||||||
* 4 Too many vocabulary words
|
|
||||||
* 5 Required vocabulary word not found
|
|
||||||
* 6 Too many RTEXT messages
|
|
||||||
* 7 Too many hints
|
|
||||||
* 8 Location has cond bit being set twice
|
|
||||||
* 9 Invalid section number in database
|
|
||||||
* 10 Too many locations
|
|
||||||
* 11 Too many class or turn messages
|
|
||||||
* 20 Special travel (500>L>300) exceeds goto list
|
|
||||||
* 21 Ran off end of vocabulary table
|
|
||||||
* 22 Vocabulary type (N/1000) not between 0 and 3
|
|
||||||
* 23 Intransitive action verb exceeds goto list
|
|
||||||
* 24 Transitive action verb exceeds goto list
|
|
||||||
* 25 Conditional travel entry with no alternative
|
|
||||||
* 26 Location has no travel entries
|
|
||||||
* 27 Hint number exceeds goto list
|
|
||||||
* 28 Invalid month returned by date function
|
|
||||||
* 29 Too many parameters given to SETPRM */
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("Fatal error %ld. See source code for interpretation.\n", num);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Machine dependent routines (MAPLIN, SAVEIO) */
|
/* Machine dependent routines (MAPLIN, SAVEIO) */
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct save_t {
|
||||||
struct save_t save;
|
struct save_t save;
|
||||||
|
|
||||||
/* Suspend and resume */
|
/* Suspend and resume */
|
||||||
int suspend(FILE *input)
|
int suspend(void)
|
||||||
{
|
{
|
||||||
/* Suspend. Offer to save things in a file, but charging
|
/* Suspend. Offer to save things in a file, but charging
|
||||||
* some points (so can't win by using saved games to retry
|
* some points (so can't win by using saved games to retry
|
||||||
|
@ -71,7 +71,7 @@ int suspend(FILE *input)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int resume(FILE *input)
|
int resume(void)
|
||||||
{
|
{
|
||||||
/* Resume. Read a suspended game back from a file.
|
/* Resume. Read a suspended game back from a file.
|
||||||
* If ADVENT_NOSAVE is defined, do nothing instead. */
|
* If ADVENT_NOSAVE is defined, do nothing instead. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue