Remove src and unix VISION_TABLES
Remove all references to the unused vision tables in the main source and unix build. Leave makedefs able to generate the vision tables. makdefs will be cleaned up in a different commit, once all ports are clear of dependencies.
This commit is contained in:
715
src/vision.c
715
src/vision.c
@@ -127,15 +127,8 @@ vision_init()
|
||||
g.vision_full_recalc = 0;
|
||||
(void) memset((genericptr_t) could_see, 0, sizeof(could_see));
|
||||
|
||||
/* Initialize the vision algorithm (currently C or D). */
|
||||
/* Initialize the vision algorithm (currently C). */
|
||||
view_init();
|
||||
|
||||
#ifdef VISION_TABLES
|
||||
/* Note: this initializer doesn't do anything except guarantee that
|
||||
* we're linked properly.
|
||||
*/
|
||||
vis_tab_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1083,11 +1076,9 @@ int row, col;
|
||||
|
||||
/*==========================================================================*/
|
||||
/*==========================================================================*/
|
||||
/* Use either algorithm C or D. See the config.h for more details.
|
||||
* =========*/
|
||||
|
||||
/*
|
||||
* Variables local to both Algorithms C and D.
|
||||
* Variables local to Algorithm C.
|
||||
*/
|
||||
static int start_row;
|
||||
static int start_col;
|
||||
@@ -1100,7 +1091,7 @@ static void FDECL((*vis_func), (int, int, genericptr_t));
|
||||
static genericptr_t varg;
|
||||
|
||||
/*
|
||||
* Both Algorithms C and D use the following macros.
|
||||
* Algorithm C uses the following macros:
|
||||
*
|
||||
* good_row(z) - Return TRUE if the argument is a legal row.
|
||||
* set_cs(rowp,col) - Set the local could see array.
|
||||
@@ -1583,704 +1574,6 @@ cleardone:
|
||||
return (boolean) result;
|
||||
}
|
||||
|
||||
#ifdef VISION_TABLES
|
||||
/*==========================================================================*\
|
||||
GENERAL LINE OF SIGHT
|
||||
Algorithm D
|
||||
\*==========================================================================*/
|
||||
|
||||
/*
|
||||
* Indicate caller for the shadow routines.
|
||||
*/
|
||||
#define FROM_RIGHT 0
|
||||
#define FROM_LEFT 1
|
||||
|
||||
/*
|
||||
* Include the table definitions.
|
||||
*/
|
||||
#include "vis_tab.h"
|
||||
|
||||
/* 3D table pointers. */
|
||||
static close2d *close_dy[CLOSE_MAX_BC_DY];
|
||||
static far2d *far_dy[FAR_MAX_BC_DY];
|
||||
|
||||
static void FDECL(right_side, (int, int, int, int, int,
|
||||
int, int, const xchar *));
|
||||
static void FDECL(left_side, (int, int, int, int, int, int, int,
|
||||
const xchar *));
|
||||
static int FDECL(close_shadow, (int, int, int, int));
|
||||
static int FDECL(far_shadow, (int, int, int, int));
|
||||
|
||||
/*
|
||||
* Initialize algorithm D's table pointers. If we don't have these,
|
||||
* then we do 3D table lookups. Verrrry slow.
|
||||
*/
|
||||
static void
|
||||
view_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLOSE_MAX_BC_DY; i++)
|
||||
close_dy[i] = &close_table[i];
|
||||
|
||||
for (i = 0; i < FAR_MAX_BC_DY; i++)
|
||||
far_dy[i] = &far_table[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the far table has an entry of OFF_TABLE, then the far block prevents
|
||||
* us from seeing the location just above/below it. I.e. the first visible
|
||||
* location is one *before* the block.
|
||||
*/
|
||||
#define OFF_TABLE 0xff
|
||||
|
||||
static int
|
||||
close_shadow(side, this_row, block_row, block_col)
|
||||
int side, this_row, block_row, block_col;
|
||||
{
|
||||
register int sdy, sdx, pdy, offset;
|
||||
|
||||
/*
|
||||
* If on the same column (block_row = -1), then we can see it.
|
||||
*/
|
||||
if (block_row < 0)
|
||||
return block_col;
|
||||
|
||||
/* Take explicit absolute values. Adjust. */
|
||||
if ((sdy = (start_row - block_row)) < 0)
|
||||
sdy = -sdy;
|
||||
--sdy; /* src dy */
|
||||
if ((sdx = (start_col - block_col)) < 0)
|
||||
sdx = -sdx; /* src dx */
|
||||
if ((pdy = (block_row - this_row)) < 0)
|
||||
pdy = -pdy; /* point dy */
|
||||
|
||||
if (sdy < 0 || sdy >= CLOSE_MAX_SB_DY || sdx >= CLOSE_MAX_SB_DX
|
||||
|| pdy >= CLOSE_MAX_BC_DY) {
|
||||
impossible("close_shadow: bad value");
|
||||
return block_col;
|
||||
}
|
||||
offset = close_dy[sdy]->close[sdx][pdy];
|
||||
if (side == FROM_RIGHT)
|
||||
return block_col + offset;
|
||||
|
||||
return block_col - offset;
|
||||
}
|
||||
|
||||
static int
|
||||
far_shadow(side, this_row, block_row, block_col)
|
||||
int side, this_row, block_row, block_col;
|
||||
{
|
||||
register int sdy, sdx, pdy, offset;
|
||||
|
||||
/*
|
||||
* Take care of a bug that shows up only on the borders.
|
||||
*
|
||||
* If the block is beyond the border, then the row is negative. Return
|
||||
* the block's column number (should be 0 or COLNO-1).
|
||||
*
|
||||
* Could easily have the column be -1, but then wouldn't know if it was
|
||||
* the left or right border.
|
||||
*/
|
||||
if (block_row < 0)
|
||||
return block_col;
|
||||
|
||||
/* Take explicit absolute values. Adjust. */
|
||||
if ((sdy = (start_row - block_row)) < 0)
|
||||
sdy = -sdy; /* src dy */
|
||||
if ((sdx = (start_col - block_col)) < 0)
|
||||
sdx = -sdx;
|
||||
--sdx; /* src dx */
|
||||
if ((pdy = (block_row - this_row)) < 0)
|
||||
pdy = -pdy;
|
||||
--pdy; /* point dy */
|
||||
|
||||
if (sdy >= FAR_MAX_SB_DY || sdx < 0 || sdx >= FAR_MAX_SB_DX || pdy < 0
|
||||
|| pdy >= FAR_MAX_BC_DY) {
|
||||
impossible("far_shadow: bad value");
|
||||
return block_col;
|
||||
}
|
||||
if ((offset = far_dy[sdy]->far_q[sdx][pdy]) == OFF_TABLE)
|
||||
offset = -1;
|
||||
if (side == FROM_RIGHT)
|
||||
return block_col + offset;
|
||||
|
||||
return block_col - offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* right_side()
|
||||
*
|
||||
* Figure out what could be seen on the right side of the source.
|
||||
*/
|
||||
static void
|
||||
right_side(row, cb_row, cb_col, fb_row, fb_col, left, right_mark, limits)
|
||||
int row; /* current row */
|
||||
int cb_row, cb_col; /* close block row and col */
|
||||
int fb_row, fb_col; /* far block row and col */
|
||||
int left; /* left mark of the previous row */
|
||||
int right_mark; /* right mark of previous row */
|
||||
xchar *limits; /* points at range limit for current row, or NULL */
|
||||
{
|
||||
register int i;
|
||||
register char *rowp = NULL;
|
||||
int hit_stone = 0;
|
||||
int left_shadow, right_shadow, loc_right;
|
||||
int lblock_col; /* local block column (current row) */
|
||||
int nrow, deeper;
|
||||
char *row_min = NULL; /* left most */
|
||||
char *row_max = NULL; /* right most */
|
||||
int lim_max; /* right most limit of circle */
|
||||
|
||||
nrow = row + step;
|
||||
deeper = good_row(nrow) && (!limits || (*limits >= *(limits + 1)));
|
||||
if (!vis_func) {
|
||||
rowp = cs_rows[row];
|
||||
row_min = &cs_left[row];
|
||||
row_max = &cs_right[row];
|
||||
}
|
||||
if (limits) {
|
||||
lim_max = start_col + *limits;
|
||||
if (lim_max > COLNO - 1)
|
||||
lim_max = COLNO - 1;
|
||||
if (right_mark > lim_max)
|
||||
right_mark = lim_max;
|
||||
limits++; /* prepare for next row */
|
||||
} else
|
||||
lim_max = COLNO - 1;
|
||||
|
||||
/*
|
||||
* Get the left shadow from the close block. This value could be
|
||||
* illegal.
|
||||
*/
|
||||
left_shadow = close_shadow(FROM_RIGHT, row, cb_row, cb_col);
|
||||
|
||||
/*
|
||||
* Mark all stone walls as seen before the left shadow. All this work
|
||||
* for a special case.
|
||||
*
|
||||
* NOTE. With the addition of this code in here, it is now *required*
|
||||
* for the algorithm to work correctly. If this is commented out,
|
||||
* change the above assignment so that left and not left_shadow is the
|
||||
* variable that gets the shadow.
|
||||
*/
|
||||
while (left <= right_mark) {
|
||||
loc_right = right_ptrs[row][left];
|
||||
if (loc_right > lim_max)
|
||||
loc_right = lim_max;
|
||||
if (viz_clear_rows[row][left]) {
|
||||
if (loc_right >= left_shadow) {
|
||||
left = left_shadow; /* opening ends beyond shadow */
|
||||
break;
|
||||
}
|
||||
left = loc_right;
|
||||
loc_right = right_ptrs[row][left];
|
||||
if (loc_right > lim_max)
|
||||
loc_right = lim_max;
|
||||
if (left == loc_right)
|
||||
return; /* boundary */
|
||||
|
||||
/* Shadow covers opening, beyond right mark */
|
||||
if (left == right_mark && left_shadow > right_mark)
|
||||
return;
|
||||
}
|
||||
|
||||
if (loc_right > right_mark) /* can't see stone beyond the mark */
|
||||
loc_right = right_mark;
|
||||
|
||||
if (vis_func) {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(left);
|
||||
set_max(loc_right);
|
||||
}
|
||||
|
||||
if (loc_right == right_mark)
|
||||
return; /* all stone */
|
||||
if (loc_right >= left_shadow)
|
||||
hit_stone = 1;
|
||||
left = loc_right + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we are at the first visible clear spot on or beyond
|
||||
* the left shadow, unless the left shadow is an illegal value. If we
|
||||
* have "hit stone" then we have a stone wall just to our left.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the right shadow. Make sure that it is a legal value.
|
||||
*/
|
||||
if ((right_shadow = far_shadow(FROM_RIGHT, row, fb_row, fb_col)) >= COLNO)
|
||||
right_shadow = COLNO - 1;
|
||||
/*
|
||||
* Make vertical walls work the way we want them. In this case, we
|
||||
* note when the close block blocks the column just above/beneath
|
||||
* it (right_shadow < fb_col [actually right_shadow == fb_col-1]). If
|
||||
* the location is filled, then we want to see it, so we put the
|
||||
* right shadow back (same as fb_col).
|
||||
*/
|
||||
if (right_shadow < fb_col && !viz_clear_rows[row][fb_col])
|
||||
right_shadow = fb_col;
|
||||
if (right_shadow > lim_max)
|
||||
right_shadow = lim_max;
|
||||
|
||||
/*
|
||||
* Main loop. Within the range of sight of the previous row, mark all
|
||||
* stone walls as seen. Follow open areas recursively.
|
||||
*/
|
||||
while (left <= right_mark) {
|
||||
/* Get the far right of the opening or wall */
|
||||
loc_right = right_ptrs[row][left];
|
||||
if (loc_right > lim_max)
|
||||
loc_right = lim_max;
|
||||
|
||||
if (!viz_clear_rows[row][left]) {
|
||||
hit_stone = 1; /* use stone on this row as close block */
|
||||
/*
|
||||
* We can see all of the wall until the next open spot or the
|
||||
* start of the shadow caused by the far block (right).
|
||||
*
|
||||
* Can't see stone beyond the right mark.
|
||||
*/
|
||||
if (loc_right > right_mark)
|
||||
loc_right = right_mark;
|
||||
|
||||
if (vis_func) {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(left);
|
||||
set_max(loc_right);
|
||||
}
|
||||
|
||||
if (loc_right == right_mark)
|
||||
return; /* hit the end */
|
||||
left = loc_right + 1;
|
||||
loc_right = right_ptrs[row][left];
|
||||
if (loc_right > lim_max)
|
||||
loc_right = lim_max;
|
||||
/* fall through... we know at least one position is visible */
|
||||
}
|
||||
|
||||
/*
|
||||
* We are in an opening.
|
||||
*
|
||||
* If this is the first open spot since the could see area (this is
|
||||
* true if we have hit stone), get the shadow generated by the wall
|
||||
* just to our left.
|
||||
*/
|
||||
if (hit_stone) {
|
||||
lblock_col = left - 1; /* local block column */
|
||||
left = close_shadow(FROM_RIGHT, row, row, lblock_col);
|
||||
if (left > lim_max)
|
||||
break; /* off the end */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the shadow covers the opening. If it does, then
|
||||
* move to end of the opening. A shadow generated on from a
|
||||
* wall on this row does *not* cover the wall on the right
|
||||
* of the opening.
|
||||
*/
|
||||
if (left >= loc_right) {
|
||||
if (loc_right == lim_max) { /* boundary */
|
||||
if (left == lim_max) {
|
||||
if (vis_func)
|
||||
(*vis_func)(lim_max, row, varg);
|
||||
else {
|
||||
set_cs(rowp, lim_max); /* last pos */
|
||||
set_max(lim_max);
|
||||
}
|
||||
}
|
||||
return; /* done */
|
||||
}
|
||||
left = loc_right;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the far wall of the opening (loc_right) is closer than the
|
||||
* shadow limit imposed by the far block (right) then use the far
|
||||
* wall as our new far block when we recurse.
|
||||
*
|
||||
* If the limits are the same, and the far block really exists
|
||||
* (fb_row >= 0) then do the same as above.
|
||||
*
|
||||
* Normally, the check would be for the far wall being closer OR EQUAL
|
||||
* to the shadow limit. However, there is a bug that arises from the
|
||||
* fact that the clear area pointers end in an open space (if it
|
||||
* exists) on a boundary. This then makes a far block exist where it
|
||||
* shouldn't --- on a boundary. To get around that, I had to
|
||||
* introduce the concept of a non-existent far block (when the
|
||||
* row < 0). Next I have to check for it. Here is where that check
|
||||
* exists.
|
||||
*/
|
||||
if ((loc_right < right_shadow)
|
||||
|| (fb_row >= 0 && loc_right == right_shadow)) {
|
||||
if (vis_func) {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = left; i <= loc_right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(left);
|
||||
set_max(loc_right);
|
||||
}
|
||||
|
||||
if (deeper) {
|
||||
if (hit_stone)
|
||||
right_side(nrow, row, lblock_col, row, loc_right, left,
|
||||
loc_right, limits);
|
||||
else
|
||||
right_side(nrow, cb_row, cb_col, row, loc_right, left,
|
||||
loc_right, limits);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following line, setting hit_stone, is needed for those
|
||||
* walls that are only 1 wide. If hit stone is *not* set and
|
||||
* the stone is only one wide, then the close block is the old
|
||||
* one instead one on the current row. A way around having to
|
||||
* set it here is to make left = loc_right (not loc_right+1) and
|
||||
* let the outer loop take care of it. However, if we do that
|
||||
* then we then have to check for boundary conditions here as
|
||||
* well.
|
||||
*/
|
||||
hit_stone = 1;
|
||||
|
||||
left = loc_right + 1;
|
||||
|
||||
/*
|
||||
* The opening extends beyond the right mark. This means that
|
||||
* the next far block is the current far block.
|
||||
*/
|
||||
} else {
|
||||
if (vis_func) {
|
||||
for (i = left; i <= right_shadow; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = left; i <= right_shadow; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(left);
|
||||
set_max(right_shadow);
|
||||
}
|
||||
|
||||
if (deeper) {
|
||||
if (hit_stone)
|
||||
right_side(nrow, row, lblock_col, fb_row, fb_col, left,
|
||||
right_shadow, limits);
|
||||
else
|
||||
right_side(nrow, cb_row, cb_col, fb_row, fb_col, left,
|
||||
right_shadow, limits);
|
||||
}
|
||||
|
||||
return; /* we're outta here */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* left_side()
|
||||
*
|
||||
* This routine is the mirror image of right_side(). Please see right_side()
|
||||
* for blow by blow comments.
|
||||
*/
|
||||
static void
|
||||
left_side(row, cb_row, cb_col, fb_row, fb_col, left_mark, right, limits)
|
||||
int row; /* the current row */
|
||||
int cb_row, cb_col; /* close block row and col */
|
||||
int fb_row, fb_col; /* far block row and col */
|
||||
int left_mark; /* left mark of previous row */
|
||||
int right; /* right mark of the previous row */
|
||||
const xchar *limits;
|
||||
{
|
||||
register int i;
|
||||
register char *rowp = NULL;
|
||||
int hit_stone = 0;
|
||||
int left_shadow, right_shadow, loc_left;
|
||||
int lblock_col; /* local block column (current row) */
|
||||
int nrow, deeper;
|
||||
char *row_min = NULL; /* left most */
|
||||
char *row_max = NULL; /* right most */
|
||||
int lim_min;
|
||||
|
||||
nrow = row + step;
|
||||
deeper = good_row(nrow) && (!limits || (*limits >= *(limits + 1)));
|
||||
if (!vis_func) {
|
||||
rowp = cs_rows[row];
|
||||
row_min = &cs_left[row];
|
||||
row_max = &cs_right[row];
|
||||
}
|
||||
if (limits) {
|
||||
lim_min = start_col - *limits;
|
||||
if (lim_min < 0)
|
||||
lim_min = 0;
|
||||
if (left_mark < lim_min)
|
||||
left_mark = lim_min;
|
||||
limits++; /* prepare for next row */
|
||||
} else
|
||||
lim_min = 0;
|
||||
|
||||
/* This value could be illegal. */
|
||||
right_shadow = close_shadow(FROM_LEFT, row, cb_row, cb_col);
|
||||
|
||||
while (right >= left_mark) {
|
||||
loc_left = left_ptrs[row][right];
|
||||
if (loc_left < lim_min)
|
||||
loc_left = lim_min;
|
||||
if (viz_clear_rows[row][right]) {
|
||||
if (loc_left <= right_shadow) {
|
||||
right = right_shadow; /* opening ends beyond shadow */
|
||||
break;
|
||||
}
|
||||
right = loc_left;
|
||||
loc_left = left_ptrs[row][right];
|
||||
if (loc_left < lim_min)
|
||||
loc_left = lim_min;
|
||||
if (right == loc_left)
|
||||
return; /* boundary */
|
||||
}
|
||||
|
||||
if (loc_left < left_mark) /* can't see beyond the left mark */
|
||||
loc_left = left_mark;
|
||||
|
||||
if (vis_func) {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(loc_left);
|
||||
set_max(right);
|
||||
}
|
||||
|
||||
if (loc_left == left_mark)
|
||||
return; /* all stone */
|
||||
if (loc_left <= right_shadow)
|
||||
hit_stone = 1;
|
||||
right = loc_left - 1;
|
||||
}
|
||||
|
||||
/* At first visible clear spot on or beyond the right shadow. */
|
||||
|
||||
if ((left_shadow = far_shadow(FROM_LEFT, row, fb_row, fb_col)) < 0)
|
||||
left_shadow = 0;
|
||||
|
||||
/* Do vertical walls as we want. */
|
||||
if (left_shadow > fb_col && !viz_clear_rows[row][fb_col])
|
||||
left_shadow = fb_col;
|
||||
if (left_shadow < lim_min)
|
||||
left_shadow = lim_min;
|
||||
|
||||
while (right >= left_mark) {
|
||||
loc_left = left_ptrs[row][right];
|
||||
|
||||
if (!viz_clear_rows[row][right]) {
|
||||
hit_stone = 1; /* use stone on this row as close block */
|
||||
|
||||
/* We can only see walls until the left mark */
|
||||
if (loc_left < left_mark)
|
||||
loc_left = left_mark;
|
||||
|
||||
if (vis_func) {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(loc_left);
|
||||
set_max(right);
|
||||
}
|
||||
|
||||
if (loc_left == left_mark)
|
||||
return; /* hit end */
|
||||
right = loc_left - 1;
|
||||
loc_left = left_ptrs[row][right];
|
||||
if (loc_left < lim_min)
|
||||
loc_left = lim_min;
|
||||
/* fall through...*/
|
||||
}
|
||||
|
||||
/* We are in an opening. */
|
||||
if (hit_stone) {
|
||||
lblock_col = right + 1; /* stone block (local) */
|
||||
right = close_shadow(FROM_LEFT, row, row, lblock_col);
|
||||
if (right < lim_min)
|
||||
return; /* off the end */
|
||||
}
|
||||
|
||||
/* Check if the shadow covers the opening. */
|
||||
if (right <= loc_left) {
|
||||
/* Make a boundary condition work. */
|
||||
if (loc_left == lim_min) { /* at boundary */
|
||||
if (right == lim_min) {
|
||||
if (vis_func)
|
||||
(*vis_func)(lim_min, row, varg);
|
||||
else {
|
||||
set_cs(rowp, lim_min); /* caught the last pos */
|
||||
set_min(lim_min);
|
||||
}
|
||||
}
|
||||
return; /* and break out the loop */
|
||||
}
|
||||
|
||||
right = loc_left;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the far wall of the opening is closer than the shadow limit. */
|
||||
if ((loc_left > left_shadow)
|
||||
|| (fb_row >= 0 && loc_left == left_shadow)) {
|
||||
if (vis_func) {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = loc_left; i <= right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(loc_left);
|
||||
set_max(right);
|
||||
}
|
||||
|
||||
if (deeper) {
|
||||
if (hit_stone)
|
||||
left_side(nrow, row, lblock_col, row, loc_left, loc_left,
|
||||
right, limits);
|
||||
else
|
||||
left_side(nrow, cb_row, cb_col, row, loc_left, loc_left,
|
||||
right, limits);
|
||||
}
|
||||
|
||||
hit_stone = 1; /* needed for walls of width 1 */
|
||||
right = loc_left - 1;
|
||||
|
||||
/* The opening extends beyond the left mark. */
|
||||
} else {
|
||||
if (vis_func) {
|
||||
for (i = left_shadow; i <= right; i++)
|
||||
(*vis_func)(i, row, varg);
|
||||
} else {
|
||||
for (i = left_shadow; i <= right; i++)
|
||||
set_cs(rowp, i);
|
||||
set_min(left_shadow);
|
||||
set_max(right);
|
||||
}
|
||||
|
||||
if (deeper) {
|
||||
if (hit_stone)
|
||||
left_side(nrow, row, lblock_col, fb_row, fb_col,
|
||||
left_shadow, right, limits);
|
||||
else
|
||||
left_side(nrow, cb_row, cb_col, fb_row, fb_col,
|
||||
left_shadow, right, limits);
|
||||
}
|
||||
|
||||
return; /* we're outta here */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* view_from
|
||||
*
|
||||
* Calculate a view from the given location. Initialize and fill a
|
||||
* ROWNOxCOLNO array (could_see) with all the locations that could be
|
||||
* seen from the source location. Initialize and fill the left most
|
||||
* and right most boundaries of what could be seen.
|
||||
*/
|
||||
static void
|
||||
view_from(srow, scol, loc_cs_rows, left_most, right_most, range, func, arg)
|
||||
int srow, scol; /* source row and column */
|
||||
xchar **loc_cs_rows; /* could_see array (row pointers) */
|
||||
xchar *left_most, *right_most; /* limits of what could be seen */
|
||||
int range; /* 0 if unlimited */
|
||||
void FDECL((*func), (int, int, genericptr_t));
|
||||
genericptr_t arg;
|
||||
{
|
||||
register int i;
|
||||
char *rowp;
|
||||
int nrow, left, right, left_row, right_row;
|
||||
char *limits;
|
||||
|
||||
/* Set globals for near_shadow(), far_shadow(), etc. to use. */
|
||||
start_col = scol;
|
||||
start_row = srow;
|
||||
cs_rows = loc_cs_rows;
|
||||
cs_left = left_most;
|
||||
cs_right = right_most;
|
||||
vis_func = func;
|
||||
varg = arg;
|
||||
|
||||
/* Find the left and right limits of sight on the starting row. */
|
||||
if (viz_clear_rows[srow][scol]) {
|
||||
left = left_ptrs[srow][scol];
|
||||
right = right_ptrs[srow][scol];
|
||||
} else {
|
||||
left = (!scol) ? 0 : (viz_clear_rows[srow][scol - 1]
|
||||
? left_ptrs[srow][scol - 1]
|
||||
: scol - 1);
|
||||
right = (scol == COLNO - 1) ? COLNO - 1
|
||||
: (viz_clear_rows[srow][scol + 1]
|
||||
? right_ptrs[srow][scol + 1]
|
||||
: scol + 1);
|
||||
}
|
||||
|
||||
if (range) {
|
||||
if (range > MAX_RADIUS || range < 1)
|
||||
panic("view_from called with range %d", range);
|
||||
limits = circle_ptr(range) + 1; /* start at next row */
|
||||
if (left < scol - range)
|
||||
left = scol - range;
|
||||
if (right > scol + range)
|
||||
right = scol + range;
|
||||
} else
|
||||
limits = (char *) 0;
|
||||
|
||||
if (func) {
|
||||
for (i = left; i <= right; i++)
|
||||
(*func)(i, srow, arg);
|
||||
} else {
|
||||
/* Row optimization */
|
||||
rowp = cs_rows[srow];
|
||||
|
||||
/* We know that we can see our row. */
|
||||
for (i = left; i <= right; i++)
|
||||
set_cs(rowp, i);
|
||||
cs_left[srow] = left;
|
||||
cs_right[srow] = right;
|
||||
}
|
||||
|
||||
/* The far block has a row number of -1 if we are on an edge. */
|
||||
right_row = (right == COLNO - 1) ? -1 : srow;
|
||||
left_row = (!left) ? -1 : srow;
|
||||
|
||||
/*
|
||||
* Check what could be seen in quadrants.
|
||||
*/
|
||||
if ((nrow = srow + 1) < ROWNO) {
|
||||
step = 1; /* move down */
|
||||
if (scol < COLNO - 1)
|
||||
right_side(nrow, -1, scol, right_row, right, scol, right, limits);
|
||||
if (scol)
|
||||
left_side(nrow, -1, scol, left_row, left, left, scol, limits);
|
||||
}
|
||||
|
||||
if ((nrow = srow - 1) >= 0) {
|
||||
step = -1; /* move up */
|
||||
if (scol < COLNO - 1)
|
||||
right_side(nrow, -1, scol, right_row, right, scol, right, limits);
|
||||
if (scol)
|
||||
left_side(nrow, -1, scol, left_row, left, left, scol, limits);
|
||||
}
|
||||
}
|
||||
|
||||
#else /*===== End of algorithm D =====*/
|
||||
|
||||
/*==========================================================================*\
|
||||
GENERAL LINE OF SIGHT
|
||||
Algorithm C
|
||||
@@ -2723,7 +2016,7 @@ genericptr_t arg;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*===== End of algorithm C =====*/
|
||||
/*===== End of algorithm C =====*/
|
||||
|
||||
/*
|
||||
* AREA OF EFFECT "ENGINE"
|
||||
|
||||
Reference in New Issue
Block a user