diff options
author | Robert Vollmert <rvollmert@gmx.net> | 2009-10-10 23:52:04 +0200 |
---|---|---|
committer | Robert Vollmert <rvollmert@gmx.net> | 2009-10-10 23:52:04 +0200 |
commit | 544a01058590972552e8d66a0641e7128e50ff02 (patch) | |
tree | a95e69304d51e1e9e92360e53889d524a1b673f4 /crawl-ref/source/los.cc | |
parent | 13aacae3ac6afc8437f84527d0b5f564d7558cd1 (diff) | |
download | crawl-ref-544a01058590972552e8d66a0641e7128e50ff02.tar.gz crawl-ref-544a01058590972552e8d66a0641e7128e50ff02.zip |
Further cleanup by converting to bit_array.
Diffstat (limited to 'crawl-ref/source/los.cc')
-rw-r--r-- | crawl-ref/source/los.cc | 101 |
1 files changed, 33 insertions, 68 deletions
diff --git a/crawl-ref/source/los.cc b/crawl-ref/source/los.cc index c46aab2cda..bd32c1af5a 100644 --- a/crawl-ref/source/los.cc +++ b/crawl-ref/source/los.cc @@ -1,6 +1,6 @@ /* - * File: los.cc - * Summary: Line-of-sight algorithm. + * File: los.cc + * Summary: Line-of-sight algorithm. */ #include "AppHdr.h" @@ -11,6 +11,7 @@ REVISION("$Rev$"); #include <cmath> #include <algorithm> +#include "bitary.h" #include "debug.h" #include "directn.h" #include "externs.h" @@ -54,22 +55,22 @@ std::vector<short> compressed_ray_y; // 3D bit array indexed by x coord, y coord, cellray index. // Bit los_blockrays[x][y][i] is set iff a wall at (x,y) blocks // the cellray starting at compressed_ray_{x,y}[i]. -typedef FixedArray<unsigned long*, LOS_MAX_RANGE+1, LOS_MAX_RANGE+1> blockrays_t; +typedef FixedArray<bit_array*, LOS_MAX_RANGE+1, LOS_MAX_RANGE+1> blockrays_t; blockrays_t los_blockrays; // Temporary arrays used in losight() to track which rays // are blocked or have seen a smoke cloud. // Allocated when doing the precomputations. -unsigned long* dead_rays = NULL; -unsigned long* smoke_rays = NULL; +bit_array *dead_rays = NULL; +bit_array *smoke_rays = NULL; void clear_rays_on_exit() { - delete[] dead_rays; - delete[] smoke_rays; - for (int x = 0; x <= LOS_MAX_RANGE; x++) - for (int y = 0; y <= LOS_MAX_RANGE; y++) - delete[] los_blockrays[x][y]; + delete dead_rays; + delete smoke_rays; + for (int x = 0; x <= LOS_MAX_RANGE; x++) + for (int y = 0; y <= LOS_MAX_RANGE; y++) + delete los_blockrays[x][y]; } // pre-squared LOS radius @@ -88,20 +89,6 @@ int get_los_radius_squared() return _los_radius_squared; } -bool _get_bit_in_long_array(const unsigned long* data, int where) -{ - int wordloc = where / LONGSIZE; - int bitloc = where % LONGSIZE; - return ((data[wordloc] & (1UL << bitloc)) != 0); -} - -static void _set_bit_in_long_array(unsigned long* data, int where) -{ - int wordloc = where / LONGSIZE; - int bitloc = where % LONGSIZE; - data[wordloc] |= (1UL << bitloc); -} - bool double_is_zero(const double x) { return (x > -EPSILON_VALUE) && (x < EPSILON_VALUE); @@ -250,20 +237,14 @@ static void _create_blockrays() // determine nonduplicated rays std::vector<int> nondupe_cellrays = _find_nonduped_cellrays(); const int num_nondupe_rays = nondupe_cellrays.size(); - const int num_nondupe_words = - (num_nondupe_rays + LONGSIZE - 1) / LONGSIZE; const int num_cellrays = ray_coord_x.size(); - const int num_words = (num_cellrays + LONGSIZE - 1) / LONGSIZE; blockrays_t full_los_blockrays; - // allocate and initialize for (int x = 0; x <= LOS_MAX_RANGE; ++x) for (int y = 0; y <= LOS_MAX_RANGE; ++y) { - full_los_blockrays[x][y] = new unsigned long[num_words]; - memset((void*)full_los_blockrays[x][y], 0, sizeof(unsigned long) * num_words); - los_blockrays[x][y] = new unsigned long[num_nondupe_words]; - memset((void*)los_blockrays[x][y], 0, sizeof(unsigned long) * num_nondupe_words); + full_los_blockrays[x][y] = new bit_array(num_cellrays); + los_blockrays[x][y] = new bit_array(num_nondupe_rays); } // first build all the rays: easier to do blocking calculations there @@ -277,7 +258,7 @@ static void _create_blockrays() int y = ray_coord_y[cur_offset + i]; // every cell blocks all following cellrays for (int j = i+1; j < raylengths[ray]; ++j) - _set_bit_in_long_array(full_los_blockrays[x][y], cur_offset+j); + full_los_blockrays[x][y]->set(cur_offset+j); } cur_offset += raylengths[ray]; } @@ -296,20 +277,17 @@ static void _create_blockrays() for (int x = 0; x <= LOS_MAX_RANGE; ++x) for (int y = 0; y <= LOS_MAX_RANGE; ++y) - { for (int i = 0; i < num_nondupe_rays; ++i) - if (_get_bit_in_long_array(full_los_blockrays[x][y], - nondupe_cellrays[i])) - _set_bit_in_long_array(los_blockrays[x][y], i); - } + los_blockrays[x][y]->set(i, + full_los_blockrays[x][y]->get(nondupe_cellrays[i])); // we can throw away full_los_blockrays now for (int x = 0; x <= LOS_MAX_RANGE; ++x) for (int y = 0; y <= LOS_MAX_RANGE; ++y) - delete[] full_los_blockrays[x][y]; + delete full_los_blockrays[x][y]; - dead_rays = new unsigned long[num_nondupe_words]; - smoke_rays = new unsigned long[num_nondupe_words]; + dead_rays = new bit_array(num_nondupe_rays); + smoke_rays = new bit_array(num_nondupe_rays); #ifdef DEBUG_DIAGNOSTICS mprf( MSGCH_DIAGNOSTICS, "Cellrays: %d Fullrays: %u Compressed: %u", @@ -742,11 +720,10 @@ bool cell_see_cell(const coord_def& p1, const coord_def& p2) void _losight_quadrant(env_show_grid& sh, const los_param& dat, int sx, int sy) { const unsigned int num_cellrays = compressed_ray_x.size(); - const int num_words = (num_cellrays + LONGSIZE - 1) / LONGSIZE; // clear out the dead rays array - memset((void*)dead_rays, 0, sizeof(unsigned long) * num_words); - memset((void*)smoke_rays, 0, sizeof(unsigned long) * num_words); + dead_rays->reset(); + smoke_rays->reset(); for (int x = 0; x <= LOS_MAX_RANGE; ++x) for (int y = 0; y <= LOS_MAX_RANGE; ++y) @@ -760,16 +737,12 @@ void _losight_quadrant(env_show_grid& sh, const los_param& dat, int sx, int sy) { case OPC_OPAQUE: // then block the appropriate rays - for (int i = 0; i < num_words; ++i) - dead_rays[i] |= los_blockrays[x][y][i]; + *dead_rays |= *los_blockrays[x][y]; break; case OPC_HALF: // block rays which have already seen a cloud - for (int i = 0; i < num_words; ++i) - { - dead_rays[i] |= (smoke_rays[i] & los_blockrays[x][y][i]); - smoke_rays[i] |= los_blockrays[x][y][i]; - } + *dead_rays |= (*smoke_rays & *los_blockrays[x][y]); + *smoke_rays |= *los_blockrays[x][y]; break; default: break; @@ -778,25 +751,17 @@ void _losight_quadrant(env_show_grid& sh, const los_param& dat, int sx, int sy) // Ray calculation done. Now work out which cells in this // quadrant are visible. - unsigned int rayidx = 0; - for (int wordloc = 0; wordloc < num_words; ++wordloc) + for (unsigned int rayidx = 0; rayidx < num_cellrays; ++rayidx) { - const unsigned long curword = dead_rays[wordloc]; - for (unsigned int bitloc = 0; bitloc < LONGSIZE; ++bitloc) + // make the cells seen by this ray at this point visible + if (!dead_rays->get(rayidx)) { - // make the cells seen by this ray at this point visible - if ( ((curword >> bitloc) & 1UL) == 0 ) - { - // this ray is alive! - const coord_def p = coord_def(sx * compressed_ray_x[rayidx], - sy * compressed_ray_y[rayidx]); - // update shadow map - if (dat.los_bounds(p)) - sh(p+sh_o) = dat.appearance(p); - } - ++rayidx; - if (rayidx == num_cellrays) - break; + // this ray is alive! + const coord_def p = coord_def(sx * compressed_ray_x[rayidx], + sy * compressed_ray_y[rayidx]); + // update shadow map + if (dat.los_bounds(p)) + sh(p+sh_o) = dat.appearance(p); } } } |