#define QTXT_I_FILE "quest.txt"
#define QTXT_O_FILE "quest.dat"
#endif
-#define VIS_TAB_H "vis_tab.h"
-#define VIS_TAB_C "vis_tab.c"
#define GITINFO_FILE "gitinfo.txt"
/* locations for those files */
#ifdef AMIGA
static struct version_info version;
-/* definitions used for vision tables */
-#define TEST_WIDTH COLNO
-#define TEST_HEIGHT ROWNO
-#define BLOCK_WIDTH (TEST_WIDTH + 10)
-#define BLOCK_HEIGHT TEST_HEIGHT /* don't need extra spaces */
-#define MAX_ROW (BLOCK_HEIGHT + TEST_HEIGHT)
-#define MAX_COL (BLOCK_WIDTH + TEST_WIDTH)
-/* Use this as an out-of-bound value in the close table. */
-#define CLOSE_OFF_TABLE_STRING "99" /* for the close table */
-#define FAR_OFF_TABLE_STRING "0xff" /* for the far table */
#define FLG_TEMPFILE 0x01 /* flag for temp file */
-
-#define sign(z) ((z) < 0 ? -1 : ((z) ? 1 : 0))
-#ifdef VISION_TABLES
-static char xclear[MAX_ROW][MAX_COL];
-#endif
-/*-end of vision defs-*/
-
#define MAXFNAMELEN 600
static char filename[MAXFNAMELEN];
void NDECL(do_questtxt);
void NDECL(do_rumors);
void NDECL(do_oracles);
-void NDECL(do_vision);
void NDECL(do_date);
extern void NDECL(monst_globals_init); /* monst.c */
static boolean FDECL(h_filter, (char *));
static void FDECL(opt_out_words, (char *, int *));
-#ifdef VISION_TABLES
-static void NDECL(H_close_gen);
-static void NDECL(H_far_gen);
-static void NDECL(C_close_gen);
-static void NDECL(C_far_gen);
-static int FDECL(clear_path, (int, int, int, int));
-#endif
-
static char *FDECL(fgetline, (FILE*));
static char *FDECL(tmpdup, (const char *));
static char *FDECL(limit, (char *, int));
case 'H':
do_oracles();
break;
- case 'z':
- case 'Z':
- do_vision();
- break;
default:
Fprintf(stderr, "Unknown option '%c'.\n", *options);
return buf;
}
-/*
- * macro used to control vision algorithms:
- * VISION_TABLES => generate tables
- */
-
-void
-do_vision()
-{
-#ifdef VISION_TABLES
- int i, j;
-
- /* Everything is clear. xclear may be malloc'ed.
- * Block the upper left corner (BLOCK_HEIGHTxBLOCK_WIDTH)
- */
- for (i = 0; i < MAX_ROW; i++)
- for (j = 0; j < MAX_COL; j++)
- if (i < BLOCK_HEIGHT && j < BLOCK_WIDTH)
- xclear[i][j] = '\000';
- else
- xclear[i][j] = '\001';
-#endif /* VISION_TABLES */
-
- SpinCursor(3);
-
- /*
- * create the include file, "vis_tab.h"
- */
- filename[0] = '\0';
-#ifdef FILE_PREFIX
- Strcat(filename, file_prefix);
-#endif
- Sprintf(eos(filename), INCLUDE_TEMPLATE, VIS_TAB_H);
- if (!(ofp = fopen(filename, WRTMODE))) {
- perror(filename);
- exit(EXIT_FAILURE);
- }
- Fprintf(ofp, "%s", Dont_Edit_Code);
- Fprintf(ofp, "#ifdef VISION_TABLES\n");
-#ifdef VISION_TABLES
- H_close_gen();
- H_far_gen();
-#endif /* VISION_TABLES */
- Fprintf(ofp, "\n#endif /* VISION_TABLES */\n");
- Fclose(ofp);
-
- SpinCursor(3);
-
- /*
- * create the source file, "vis_tab.c"
- */
- filename[0] = '\0';
-#ifdef FILE_PREFIX
- Strcat(filename, file_prefix);
-#endif
- Sprintf(eos(filename), SOURCE_TEMPLATE, VIS_TAB_C);
- if (!(ofp = fopen(filename, WRTMODE))) {
- perror(filename);
- /* creating vis_tab.c failed; remove the vis_tab.h we just made */
- filename[0] = '\0';
-#ifdef FILE_PREFIX
- Strcat(filename, file_prefix);
-#endif
- Sprintf(eos(filename), INCLUDE_TEMPLATE, VIS_TAB_H);
- Unlink(filename);
- exit(EXIT_FAILURE);
- }
- Fprintf(ofp, "%s", Dont_Edit_Code);
- Fprintf(ofp, "#include \"config.h\"\n");
- Fprintf(ofp, "#ifdef VISION_TABLES\n");
- Fprintf(ofp, "#include \"vis_tab.h\"\n");
-
- SpinCursor(3);
-
-#ifdef VISION_TABLES
- C_close_gen();
- C_far_gen();
- Fprintf(ofp, "\nvoid vis_tab_init() { return; }\n");
-#endif /* VISION_TABLES */
-
- SpinCursor(3);
-
- Fprintf(ofp, "\n#endif /* VISION_TABLES */\n");
- Fprintf(ofp, "\n/*vis_tab.c*/\n");
-
- Fclose(ofp);
- return;
-}
-
-#ifdef VISION_TABLES
-
-/*-------------- vision tables --------------*\
- *
- * Generate the close and far tables. This is done by setting up a
- * fake dungeon and moving our source to different positions relative
- * to a block and finding the first/last visible position. The fake
- * dungeon is all clear execpt for the upper left corner (BLOCK_HEIGHT
- * by BLOCK_WIDTH) is blocked. Then we move the source around relative
- * to the corner of the block. For each new position of the source
- * we check positions on rows "kittycorner" from the source. We check
- * positions until they are either in sight or out of sight (depends on
- * which table we are generating). The picture below shows the setup
- * for the generation of the close table. The generation of the far
- * table would switch the quadrants of the '@' and the "Check rows
- * here".
- *
- *
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,, Check rows here ,,,,,,,,,,,,
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXB,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
- * ...............................
- * ...............................
- * .........@.....................
- * ...............................
- *
- * Table generation figure (close_table). The 'X's are blocked points.
- * The 'B' is a special blocked point. The '@' is the source. The ','s
- * are the target area. The '.' are just open areas.
- *
- *
- * Example usage of close_table[][][].
- *
- * The table is as follows:
- *
- * dy = |row of '@' - row of 'B'| - 1
- * dx = |col of '@' - col of 'B'|
- *
- * The first indices are the deltas from the source '@' and the block 'B'.
- * You must check for the value inside the abs value bars being zero. If
- * so then the block is on the same row and you don't need to do a table
- * lookup. The last value:
- *
- * dcy = |row of block - row to be checked|
- *
- * Is the value of the first visible spot on the check row from the
- * block column. So
- *
- * first visible col = close_table[dy][dx][dcy] + col of 'B'
- *
-\*-------------- vision tables --------------*/
-
-static void
-H_close_gen()
-{
- Fprintf(ofp, "\n/* Close */\n");
- Fprintf(ofp,
- "#define CLOSE_MAX_SB_DY %2d\t/* |src row - block row| - 1\t*/\n",
- TEST_HEIGHT - 1);
- Fprintf(ofp,
- "#define CLOSE_MAX_SB_DX %2d\t/* |src col - block col|\t*/\n",
- TEST_WIDTH);
- Fprintf(ofp,
- "#define CLOSE_MAX_BC_DY %2d\t/* |block row - check row|\t*/\n",
- TEST_HEIGHT);
- Fprintf(ofp, "typedef struct {\n");
- Fprintf(ofp,
- " unsigned char close[CLOSE_MAX_SB_DX][CLOSE_MAX_BC_DY];\n");
- Fprintf(ofp, "} close2d;\n");
- Fprintf(ofp, "extern close2d close_table[CLOSE_MAX_SB_DY];\n");
- return;
-}
-
-static void
-H_far_gen()
-{
- Fprintf(ofp, "\n/* Far */\n");
- Fprintf(ofp, "#define FAR_MAX_SB_DY %2d\t/* |src row - block row|\t*/\n",
- TEST_HEIGHT);
- Fprintf(ofp,
- "#define FAR_MAX_SB_DX %2d\t/* |src col - block col| - 1\t*/\n",
- TEST_WIDTH - 1);
- Fprintf(ofp,
- "#define FAR_MAX_BC_DY %2d\t/* |block row - check row| - 1\t*/\n",
- TEST_HEIGHT - 1);
- Fprintf(ofp, "typedef struct {\n");
- Fprintf(ofp, " unsigned char far_q[FAR_MAX_SB_DX][FAR_MAX_BC_DY];\n");
- Fprintf(ofp, "} far2d;\n");
- Fprintf(ofp, "extern far2d far_table[FAR_MAX_SB_DY];\n");
- return;
-}
-
-static void
-C_close_gen()
-{
- int i, dx, dy;
- int src_row, src_col; /* source */
- int block_row, block_col; /* block */
- int this_row;
- int no_more;
- const char *delim;
-
- block_row = BLOCK_HEIGHT - 1;
- block_col = BLOCK_WIDTH - 1;
-
- Fprintf(ofp, "\n#ifndef FAR_TABLE_ONLY\n");
- Fprintf(ofp, "\nclose2d close_table[CLOSE_MAX_SB_DY] = {\n");
-#ifndef no_vision_progress
- Fprintf(stderr, "\nclose:");
-#endif
-
- for (dy = 1; dy < TEST_HEIGHT; dy++) {
- src_row = block_row + dy;
- Fprintf(ofp, "/* DY = %2d (- 1)*/\n {{\n", dy);
-#ifndef no_vision_progress
- Fprintf(stderr, " %2d", dy), (void) fflush(stderr);
-#endif
- for (dx = 0; dx < TEST_WIDTH; dx++) {
- src_col = block_col - dx;
- Fprintf(ofp, " /*%2d*/ {", dx);
-
- no_more = 0;
- for (this_row = 0; this_row < TEST_HEIGHT; this_row++) {
- delim = (this_row < TEST_HEIGHT - 1) ? "," : "";
- if (no_more) {
- Fprintf(ofp, "%s%s", CLOSE_OFF_TABLE_STRING, delim);
- continue;
- }
- SpinCursor(3);
-
- /* Find the first column that we can see. */
- for (i = block_col + 1; i < MAX_COL; i++) {
- if (clear_path(src_row, src_col, block_row - this_row, i))
- break;
- }
-
- if (i == MAX_COL)
- no_more = 1;
- Fprintf(ofp, "%2d%s", i - block_col, delim);
- }
- Fprintf(ofp, "}%s", (dx < TEST_WIDTH - 1) ? ",\n" : "\n");
- }
- Fprintf(ofp, " }},\n");
- }
-
- Fprintf(ofp, "}; /* close_table[] */\n"); /* closing brace for table */
- Fprintf(ofp, "#endif /* !FAR_TABLE_ONLY */\n");
-#ifndef no_vision_progress
- Fprintf(stderr, "\n");
-#endif
- return;
-}
-
-static void
-C_far_gen()
-{
- int i, dx, dy;
- int src_row, src_col; /* source */
- int block_row, block_col; /* block */
- int this_row;
- const char *delim;
-
- block_row = BLOCK_HEIGHT - 1;
- block_col = BLOCK_WIDTH - 1;
-
- Fprintf(ofp, "\n#ifndef CLOSE_TABLE_ONLY\n");
- Fprintf(ofp, "\nfar2d far_table[FAR_MAX_SB_DY] = {\n");
-#ifndef no_vision_progress
- Fprintf(stderr, "\n_far_:");
-#endif
-
- for (dy = 0; dy < TEST_HEIGHT; dy++) {
- src_row = block_row - dy;
- Fprintf(ofp, "/* DY = %2d */\n {{\n", dy);
-#ifndef no_vision_progress
- Fprintf(stderr, " %2d", dy), (void) fflush(stderr);
-#endif
- for (dx = 1; dx < TEST_WIDTH; dx++) {
- src_col = block_col + dx;
- Fprintf(ofp, " /*%2d(-1)*/ {", dx);
-
- for (this_row = block_row + 1; this_row < block_row + TEST_HEIGHT;
- this_row++) {
- delim = (this_row < block_row + TEST_HEIGHT - 1) ? "," : "";
-
- SpinCursor(3);
- /* Find first col that we can see. */
- for (i = 0; i <= block_col; i++) {
- if (clear_path(src_row, src_col, this_row, i))
- break;
- }
-
- if (block_col - i < 0)
- Fprintf(ofp, "%s%s", FAR_OFF_TABLE_STRING, delim);
- else
- Fprintf(ofp, "%2d%s", block_col - i, delim);
- }
- Fprintf(ofp, "}%s", (dx < TEST_WIDTH - 1) ? ",\n" : "\n");
- }
- Fprintf(ofp, " }},\n");
- }
-
- Fprintf(ofp, "}; /* far_table[] */\n"); /* closing brace for table */
- Fprintf(ofp, "#endif /* !CLOSE_TABLE_ONLY */\n");
-#ifndef no_vision_progress
- Fprintf(stderr, "\n");
-#endif
- return;
-}
-
-/*
- * "Draw" a line from the hero to the given location. Stop if we hit a
- * wall.
- *
- * Generalized integer Bresenham's algorithm (fast line drawing) for
- * all quadrants. From _Procedural Elements for Computer Graphics_, by
- * David F. Rogers. McGraw-Hill, 1985.
- *
- * I have tried a little bit of optimization by pulling compares out of
- * the inner loops.
- *
- * NOTE: This had better *not* be called from a position on the
- * same row as the hero.
- */
-static int
-clear_path(you_row, you_col, y2, x2)
-int you_row, you_col, y2, x2;
-{
- int dx, dy, s1, s2;
- register int i, error, x, y, dxs, dys;
-
- x = you_col;
- y = you_row;
- dx = abs(x2 - you_col);
- dy = abs(y2 - you_row);
- s1 = sign(x2 - you_col);
- s2 = sign(y2 - you_row);
-
- if (s1 == 0) { /* same column */
- if (s2 == 1) { /* below (larger y2 value) */
- for (i = you_row + 1; i < y2; i++)
- if (!xclear[i][you_col])
- return 0;
- } else { /* above (smaller y2 value) */
- for (i = y2 + 1; i < you_row; i++)
- if (!xclear[i][you_col])
- return 0;
- }
- return 1;
- }
-
- /*
- * Lines at 0 and 90 degrees have been weeded out.
- */
- if (dy > dx) {
- error = dx;
- dx = dy;
- dy = error; /* swap the values */
- dxs = dx << 1; /* save the shifted values */
- dys = dy << 1;
- error = dys - dx; /* NOTE: error is used as a temporary above */
-
- for (i = 0; i < dx; i++) {
- if (!xclear[y][x])
- return 0; /* plot point */
-
- while (error >= 0) {
- x += s1;
- error -= dxs;
- }
- y += s2;
- error += dys;
- }
- } else {
- dxs = dx << 1; /* save the shifted values */
- dys = dy << 1;
- error = dys - dx;
-
- for (i = 0; i < dx; i++) {
- if (!xclear[y][x])
- return 0; /* plot point */
-
- while (error >= 0) {
- y += s2;
- error -= dxs;
- }
- x += s1;
- error += dys;
- }
- }
- return 1;
-}
-#endif /* VISION_TABLES */
-
#ifdef STRICT_REF_DEF
NEARDATA struct flag flags;
#ifdef ATTRIB_H