Index: display/prepmap.cc =================================================================== --- display/prepmap.cc (nonexistent) +++ display/prepmap.cc (working copy) @@ -0,0 +1,302 @@ +#include "prepmap.h" +#include "../simtypes.h" + +vector_tpl prepmap_t::prepmap_list; + +void prepmap_t::invalidate_all() +{ + prepmap_t *const *const endpointer = prepmap_t::prepmap_list.end(); + for (prepmap_t *const *pointer = prepmap_t::prepmap_list.begin() ; pointer != endpointer ; pointer++) { + (*pointer)->invalidate(); + } +} + +prepmap_t::prepmap_t() + : map(new map_type_t[1]), + map_size_x_bits(0), + map_size_y_bits(0), + min_extent(0, 0), + max_extent(0, 0), + view_min_extent(0, 0), + view_max_extent(0, 0) +{ + prepmap_t::prepmap_list.append(this); +} + + +prepmap_t::~prepmap_t() +{ + prepmap_t::prepmap_list.remove(this); + delete[] map; +} + +void prepmap_t::resize_map(unsigned int const x_bits, unsigned int const y_bits) +{ + if (x_bits == map_size_x_bits && y_bits == map_size_y_bits) { + // size is not changing + return; + } + + sint16 const x_size = 1 << x_bits; + sint16 const y_size = 1 << y_bits; + size_t const new_map_size = 1 << (x_bits + y_bits); + + map_type_t *const new_map = new map_type_t[new_map_size]; + for (size_t index = 0 ; index < new_map_size ; index++) { + new_map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + + if (map != NULL) { + // copy state from old map then delete + sint16 x_copy_len = max_extent.x - min_extent.x + 1; + if (x_copy_len > x_size) { + x_copy_len = x_size; + max_extent.x = (sint16)(x_copy_len + min_extent.x - 1); + } + + sint16 y_copy_len = max_extent.y - min_extent.y + 1; + if (y_copy_len > y_size) { + y_copy_len = y_size; + max_extent.y = (sint16)(y_copy_len + min_extent.y - 1); + } + + sint16 const old_x_mask = (1 << map_size_x_bits) - 1; + sint16 const old_y_mask = (1 << map_size_y_bits) - 1; + sint16 const x_mask = x_size - 1; + sint16 const y_mask = y_size - 1; + + // logically remap the mappings into the new array + // this could be further optimized by remapping row segments of mappings for bulk copy operations + for (sint16 logical_y = min_extent.y ; logical_y <= max_extent.y ; logical_y++) { + sint16 const old_y = logical_y & old_y_mask; + sint16 const y = logical_y & y_mask; + for (sint16 logical_x = min_extent.x ; logical_x <= max_extent.x ; logical_x++) { + sint16 const old_x = logical_x & old_x_mask; + size_t const old_index = (old_y << map_size_x_bits) + old_x; + sint16 const x = logical_x & x_mask; + size_t const index = (y << x_bits) + x; + new_map[index] = map[old_index]; + } + } + + delete[] map; + } + + // update map + map = new_map; + map_size_x_bits = x_bits; + map_size_y_bits = y_bits; +} + +void prepmap_t::set_view(koord const new_min_extent, koord const new_max_extent) +{ + view_min_extent = new_min_extent; + view_max_extent = new_max_extent; + + if (new_min_extent.x >= min_extent.x && new_max_extent.x <= max_extent.x && + new_min_extent.y >= min_extent.y && new_max_extent.y <= max_extent.y) { + // do not do anything if new extents are inside existing extents + return; + } + + sint16 x_size = 1 << map_size_x_bits; + sint16 y_size = 1 << map_size_y_bits; + sint16 const view_size_x = new_max_extent.x - new_min_extent.x + 1; + sint16 const view_size_y = new_max_extent.y - new_min_extent.y + 1; + if (view_size_x > x_size || view_size_y > y_size) { + // resize to fit requested view + unsigned int x_bits = map_size_x_bits; + while ((1 << x_bits) < view_size_x) { + x_bits+= 1; + } + + unsigned int y_bits = map_size_y_bits; + while ((1 << y_bits) < view_size_y) { + y_bits+= 1; + } + + resize_map(x_bits, y_bits); + x_size = 1 << map_size_x_bits; + y_size = 1 << map_size_y_bits; + } + + if ((view_size_x << prepmap_t::OVERSIZE_SHIFT_BITS) < x_size || (view_size_y << prepmap_t::OVERSIZE_SHIFT_BITS) < y_size) { + // shrink to optimize space + unsigned int x_bits = map_size_x_bits; + while ((1 << x_bits) >= view_size_x) { + x_bits-= 1; + } + x_bits+= prepmap_t::OVERSIZE_SHIFT_BITS; + + unsigned int y_bits = map_size_y_bits; + while ((1 << y_bits) >= view_size_y) { + y_bits-= 1; + } + y_bits+= prepmap_t::OVERSIZE_SHIFT_BITS; + + resize_map(x_bits, y_bits); + x_size = 1 << map_size_x_bits; + y_size = 1 << map_size_y_bits; + } + + sint16 const play_x = x_size - view_size_x; + sint16 const play_y = y_size - view_size_y; + + if (new_min_extent.x - max_extent.x <= play_x && + new_min_extent.y - max_extent.y <= play_y && + min_extent.x - new_max_extent.x <= play_x && + min_extent.y - new_max_extent.y <= play_y) { + // some of the map is retained, eg panning operation + koord internal_min_extent = min_extent; + koord internal_max_extent = max_extent; + + if (new_min_extent.y < internal_min_extent.y) { + internal_min_extent.y = new_min_extent.y; + sint16 const new_length = internal_max_extent.y - internal_min_extent.y + 1; + if (new_length > y_size) { + internal_max_extent.y = internal_min_extent.y + y_size - 1; + invalidate(koord(min_extent.x, internal_max_extent.y + 1), max_extent); + max_extent.y = internal_max_extent.y; + } + } + if (new_max_extent.y > internal_max_extent.y) { + internal_max_extent.y = new_max_extent.y; + sint16 const new_length = internal_max_extent.y - internal_min_extent.y + 1; + if (new_length > y_size) { + internal_min_extent.y = internal_max_extent.y - y_size + 1; + invalidate(min_extent, koord(max_extent.x, internal_min_extent.y - 1)); + min_extent.y = internal_min_extent.y; + } + } + + if (new_min_extent.x < internal_min_extent.x) { + internal_min_extent.x = new_min_extent.x; + sint16 const new_length = internal_max_extent.x - internal_min_extent.x + 1; + if (new_length > x_size) { + internal_max_extent.x = internal_min_extent.x + x_size - 1; + invalidate(koord(internal_max_extent.x + 1, min_extent.y), max_extent); + max_extent.x = internal_max_extent.x; + } + } + if (new_max_extent.x > internal_max_extent.x) { + internal_max_extent.x = new_max_extent.x; + sint16 const new_length = internal_max_extent.x - internal_min_extent.x + 1; + if (new_length > x_size) { + internal_min_extent.x = internal_max_extent.x - x_size + 1; + invalidate(min_extent, koord(internal_min_extent.x - 1, max_extent.y)); + min_extent.x = internal_min_extent.x; + } + } + min_extent = internal_min_extent; + max_extent = internal_max_extent; + } else { + // none of the map is retained, eg jump to + invalidate(); + } +} + +void prepmap_t::invalidate() +{ + invalidate(min_extent, max_extent); + min_extent = view_min_extent; + max_extent = view_max_extent; +} + +void prepmap_t::invalidate(koord const min_extent, koord const max_extent) +{ + sint16 const y_mask = (1 << map_size_y_bits) - 1; + sint16 const start_y = min_extent.y & y_mask; + sint16 const end_y = max_extent.y & y_mask; + + sint16 const x_size = 1 << map_size_x_bits; + sint16 const y_size = 1 << map_size_y_bits; + sint16 const extent_x = max_extent.x - min_extent.x + 1; + sint16 const extent_y = max_extent.y - min_extent.y + 1; + if (extent_x == x_size) { + // the following are special cases where bulk memory operations can be + // used for huge blocks covering multiple rows + size_t const map_size = 1 << (map_size_x_bits + map_size_y_bits); + if (extent_y == y_size) { + // clear entire map + size_t const start_index = 0; + size_t const end_index = map_size; + for (size_t index = start_index ; index < end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + } else if (!(start_y > end_y)) { + // single block fill + size_t const start_index = start_y << map_size_x_bits; + size_t const end_index = (end_y + 1) << map_size_x_bits; + for (size_t index = start_index ; index < end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + } else { + // double block fill due to wrap around + size_t const bottom_start_index = 0; + size_t const bottom_end_index = (end_y + 1) << map_size_x_bits; + for (size_t index = bottom_start_index ; index < bottom_end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + + size_t const top_start_index = start_y << map_size_x_bits; + size_t const top_end_index = map_size; + for (size_t index = top_start_index ; index < top_end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + } + } else { + // per row fill + sint16 const x_mask = x_size - 1; + sint16 const start_x = min_extent.x & x_mask; + sint16 const end_x = max_extent.x & x_mask; + bool const x_wrap = start_x > end_x; + for (sint16 y = min_extent.y ; y <= max_extent.y ; y++) { + size_t const index_base = (size_t)(y & y_mask) << map_size_x_bits; + if (!x_wrap) { + // single part row fill + size_t const start_index = index_base + start_x; + size_t const end_index = index_base + end_x + 1; + for (size_t index = start_index ; index < end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + } else { + // row fill split into 2 parts + // there may be a slightly faster way by splitting into 3 operations with a bulk clear spanning rows + size_t start_index = index_base; + size_t end_index = index_base + end_x + 1; + for (size_t index = start_index ; index < end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + + start_index = index_base + start_x; + end_index = index_base + x_size; + for (size_t index = start_index ; index < end_index ; index++) { + map[index] = prepmap_t::MAP_VALUE_DIRTY; + } + } + } + } +} + +bool prepmap_t::prepare_tile(koord const tile) +{ + +#if 0 + // view safety check for debugging purposes + // if all is working well this test should never return + if (tile.x < min_extent.x || tile.x > max_extent.x || + tile.y < min_extent.y || tile.y > max_extent.y) { + return true; + } +#endif + + sint16 const x_mask = (1 << map_size_x_bits) - 1; + sint16 const y_mask = (1 << map_size_y_bits) - 1; + sint16 const x = tile.x & x_mask; + sint16 const y = tile.y & y_mask; + size_t const index = (y << map_size_x_bits) + x; + + bool const prepared = map[index] == prepmap_t::MAP_VALUE_PREPARED; + map[index] = prepmap_t::MAP_VALUE_PREPARED; + return prepared; +} Index: display/prepmap.h =================================================================== --- display/prepmap.h (nonexistent) +++ display/prepmap.h (working copy) @@ -0,0 +1,171 @@ +#ifndef prepmap_h +#define prepmap_h + +#include "../dataobj/koord.h" +#include "../tpl/vector_tpl.h" +#include + +/** + * @brief A map that can be used to efficiently track tiles that have been + * prepared for display. + * + * This is used to calculate ground images and back wall images only when + * comming into view. This saves them from being calculated every time a tile is + * drawn while also removes the need to calculate them for the entire map when + * loading and changing underground view. + */ +class prepmap_t +{ +private: + /** + * @brief Contains a reference to every prepmap_t object. + * + * Used to allow mass invalidating of all prepmaps for cases such as + * changing underground mode and snow levels. + */ + static vector_tpl prepmap_list; + + /** + * @brief Type used for map inicies. + */ + typedef bool map_type_t; + + /** + * @brief Map index is prepared value. + */ + static map_type_t const MAP_VALUE_PREPARED = true; + + /** + * @brief Map index is not prepared value. + */ + static map_type_t const MAP_VALUE_DIRTY = false; + + /** + * @brief Shift factor from veiw size for map dimension to be considered + * oversized. + * + * Oversized map dimensions are downsized when setting a view. This limits + * the computational overhead of performing panning and invalidate + * operations when a large map is no longer required. + */ + static unsigned int const OVERSIZE_SHIFT_BITS = 1; + + /** + * @brief Map representing tiles that have been prepared for display. + * + * An 1 tile per entry map that represents tiles that have been prepared for + * display. A tile is prepared for display if both its ground and back wall + * images have been calculated. + * + * This is not a 2D array for performance purposes. Each axis is power of 2 + * sized so shift can be used instead of multiply. Additionally some bulk + * operations can be performed on rows. + */ + map_type_t *map; + + /** + * @brief The x size of the map array in bits. + */ + unsigned int map_size_x_bits; + + /** + * @brief The y size of the map arrayin bits. + */ + unsigned int map_size_y_bits; + + /** + * @brief The minimum extent covered by the prepared tile map. + * + * The minimum extent covered by the prepared tile map. The prepared tile + * map is interally floating to avoid memory copies when panning. + */ + koord min_extent; + + /** + * @brief The maximum extent covered by the prepared tile map. + * + * The maximum extent covered by the prepared tile map. The prepared tile + * map is interally floating to avoid memory copies when panning. + */ + koord max_extent; + + /** + * @brief The minimum extent being viewed. + * + * The minimum extent being viewed. Cropped to this when invalidating. + */ + koord view_min_extent; + + /** + * @brief The maximum extent being viewed. + * + * The maximum extent being viewed. Cropped to this when invalidating. + */ + koord view_max_extent; + +public: + /** + * @brief Calls invalidate on all prepmaps. + * + * Calls invalidate on all created prepmaps. Used when all views must be + * reprepared such as changing underground mode or slice. This method is + * required because object views use completly separate draw logic from the + * main map view and must also have their prepmap invalidated for correct + * graphic reproduction. + */ + static void invalidate_all(); + + prepmap_t(); + ~prepmap_t(); + + /** + * @brief Set the underlying map array size. + * + * Resizes the underlying map array. Bigger sizes can give better perpare + * performance when panning around the same area but may also increase + * overhead of panning to new areas. + */ + void resize_map(unsigned int const x_bits, unsigned int const y_bits); + + /** + * @brief Set the map view to the given extents. + * + * Set the map view to the given extent. New area covered by this may + * already be prepared if it was recently prepared using this map. This + * operation will resize the map array if there is insufficient space for + * the requested size. Both extents are inclusive. + */ + void set_view(koord const new_min_extent, koord const new_max_extent); + + /** + * @brief Invalidates all made preparations. + * + * After a call to this function all tiles will return unprepared. This is + * useful if all tiles require being prepared again, eg if changing + * underground mode or snow level. + */ + void invalidate(); + + /** + * @brief Invalidates tiles in the specified area of view. + * + * After a call to this function all tiles within the specified square area + * will return unprepared. This is useful if only part of the view require + * being prepared again. Is used internally during view panning. Extents are inclusive. + */ + void invalidate(koord const min_extent, koord const max_extent); + + /** + * @brief Prepares a tile, returning true if the tile was previously + * prepared otherwise false. + * + * Marks that a tile is prepared while returning its previous preparation + * state. Tiles that are prepared return true, ones that are not return + * false. This function is intended to be called and then based on the + * results actual preparation work is done. Behaviour of this method is + * undefined when working on tiles not within the set view area. + */ + bool prepare_tile(koord const tile); +}; + +#endif \ No newline at end of file Index: display/simview.cc =================================================================== --- display/simview.cc (revision 8546) +++ display/simview.cc (working copy) @@ -167,6 +167,49 @@ int y_min = (-const_y_off + 4*tile_raster_scale_y( min(hmax_ground, welt->min_height)*TILE_HEIGHT_STEP, IMG_SIZE ) + 4*(menu_height-IMG_SIZE)-IMG_SIZE/2-1) / IMG_SIZE; + // set preparation view + koord estimated_min(((y_min+(-2-((y_min+dpy_width) & 1))) >> 1) + i_off, + ((y_min-(disp_width - const_x_off) / (IMG_SIZE/2) - 1) >> 1) + j_off); + estimated_min.clip_min(koord(0, 0)); + + sint16 const worst_case_mountain_extra = (welt->max_height - welt->min_height) / 2; + koord estimated_max((((dpy_height+4*4)+(disp_width - const_x_off) / (IMG_SIZE/2) - 1) >> 1) + i_off + worst_case_mountain_extra, + (((dpy_height+4*4)-(-2-(((dpy_height+4*4)+dpy_width) & 1))) >> 1) + j_off + worst_case_mountain_extra); + koord const world_extent = welt->get_size() - koord(1, 1); + estimated_max.clip_max(world_extent); + + viewport->preparation_map.set_view(estimated_min, estimated_max); + + // prepare view area + bool extra = false; + for(sint16 y=y_min; y> 1) + i_off; + const int j = ((y-x) >> 1) + j_off; + const int xpos = x*(IMG_SIZE/2) + const_x_off; + + if( xpos+IMG_SIZE>0 ) { + const planquadrat_t *plan=welt->access(i,j); + + if(plan && plan->get_kartenboden()) { + const grund_t *gr = plan->get_kartenboden(); + + if (!(viewport->preparation_map.prepare_tile(koord(i,j)))) { + plan->update_underground(); + } + + sint16 yypos = ypos - tile_raster_scale_y( min(gr->get_hoehe(),hmax_ground)*TILE_HEIGHT_STEP, IMG_SIZE); + if( yypos-IMG_SIZE=menu_height ) { + extra = true; + } + } + } + } + } + #ifdef MULTI_THREAD if( can_multithreading ) { if( !spawned_threads ) { Index: display/viewport.cc =================================================================== --- display/viewport.cc (revision 8546) +++ display/viewport.cc (working copy) @@ -302,6 +302,7 @@ viewport_t::viewport_t( karte_t *world, const koord ij_off , sint16 x_off , sint16 y_off ) + : preparation_map() { this->world = world; assert(world); Index: display/viewport.h =================================================================== --- display/viewport.h (revision 8546) +++ display/viewport.h (working copy) @@ -12,6 +12,7 @@ #include "../dataobj/koord.h" #include "../dataobj/koord3d.h" #include "../convoihandle_t.h" +#include "prepmap.h" class karte_t; class grund_t; @@ -39,6 +40,16 @@ */ class viewport_t { +public: + /** + * @brief Preparation map used to prepare tiles for drawing by this view. + * + * The preparation map is used to prepare tiles for display. Tiles will only + * be prepared when they are visible by a view port. Tiles will not be + * prepared again based on their state in the preparation map. + */ + prepmap_t preparation_map; + private: /// The simulated world this view is associated to. karte_t *world; Index: gui/components/gui_world_view_t.cc =================================================================== --- gui/components/gui_world_view_t.cc (revision 8546) +++ gui/components/gui_world_view_t.cc (working copy) @@ -23,7 +23,10 @@ world_view_t::world_view_t(scr_size size ) : - raster(get_base_tile_raster_width()) + raster(get_base_tile_raster_width()), + preparation_map(), + offset_extent_min(0, 0), + offset_extent_max(0, 0) { set_size( size ); } @@ -30,7 +33,10 @@ world_view_t::world_view_t() : - raster(get_base_tile_raster_width()) + raster(get_base_tile_raster_width()), + preparation_map(), + offset_extent_min(0, 0), + offset_extent_max(0, 0) { } @@ -70,6 +76,7 @@ fine_here -= scr_coord(x, y); } } + koord const height_offset(y_offset, y_offset); grund_t const* const kb = welt->lookup_kartenboden(here); if(!kb) { @@ -98,6 +105,15 @@ return; } + // set prepare map view + koord prep_extent_min = here + offset_extent_min + height_offset; + prep_extent_min.clip_min(koord(0, 0)); + koord prep_extent_max = here + offset_extent_max + height_offset; + koord const world_extent = welt->get_size() - koord(1, 1); + prep_extent_max.clip_max(world_extent); + preparation_map.set_view(prep_extent_min, prep_extent_max); + + // prepare clip area const int clip_x = max(old_clip.x, pos.x); const int clip_y = max(old_clip.y, pos.y); display_set_clip_wh(clip_x, clip_y, min(old_clip.xx, pos.x + size.w) - clip_x, min(old_clip.yy, pos.y + size.h) - clip_y); @@ -120,7 +136,7 @@ // display grounds FOR(vector_tpl, const& off, offsets) { - const koord k = here + off + koord(y_offset, y_offset); + const koord k = here + off + height_offset; const sint16 off_x = (off.x - off.y) * 32 * raster / 64 + display_off.x; if( off_x + raster < 0 || size.w < off_x || k.x < 0 || k.y < 0 ) { @@ -137,6 +153,10 @@ break; // enough with grounds } else if( 0 <= yypos + raster ) { + if (!preparation_map.prepare_tile(k)) { + welt->access(k.x, k.y)->update_underground(); + } + #ifdef MULTI_THREAD kb->display_if_visible( pos.x + off_x, pos.y + yypos, raster, 0 ); #else @@ -147,7 +167,7 @@ // display things FOR(vector_tpl, const& off, offsets) { - const koord k = here + off + koord(y_offset, y_offset); + const koord k = here + off + height_offset; const sint16 off_x = (off.x - off.y) * 32 * raster / 64 + display_off.x; if( off_x + raster < 0 || size.w < off_x || k.x < 0 || k.y < 0 ) { continue; @@ -218,6 +238,7 @@ const sint16 max_dx = size.w/(raster/2) + 2; const sint16 max_dy = (size.h/(raster/2) + dy_off)&0x0FFE; + // build offset list offsets.clear(); for( sint16 dy = -max_dy; dy <= 5; ) { { @@ -233,4 +254,23 @@ } dy++; } + + // determine preparation extents + offset_extent_min = koord(0, 0); + offset_extent_max = koord(0, 0); + koord const *const iter_end = offsets.end(); + for (koord const *iter = offsets.begin() ; iter != iter_end ; iter++) { + sint16 const x = iter->x; + sint16 const y = iter->y; + if (x < offset_extent_min.x) { + offset_extent_min.x = x; + }else if (x > offset_extent_max.x) { + offset_extent_max.x = x; + } + if (y < offset_extent_min.y) { + offset_extent_min.y = y; + }else if (y > offset_extent_max.y) { + offset_extent_max.y = y; + } + } } Index: gui/components/gui_world_view_t.h =================================================================== --- gui/components/gui_world_view_t.h (revision 8546) +++ gui/components/gui_world_view_t.h (working copy) @@ -12,6 +12,7 @@ #include "../../dataobj/koord3d.h" #include "../../tpl/vector_tpl.h" +#include "../../display/prepmap.h" class obj_t; @@ -23,7 +24,31 @@ class world_view_t : public gui_world_component_t { private: + /** + * @brief Preparation map used to prepare tiles for drawing by this view. + * + * The preparation map is used to prepare tiles for display. Tiles will only + * be prepared when they are visible by a view port. Tiles will not be + * prepared again based on their state in the preparation map. + */ + prepmap_t preparation_map; + vector_tpl offsets; /**< Offsets are stored. */ + + /** + * @brief The minimum offset extent. + * + * The minimum extent that will cover all offsets. + */ + koord offset_extent_min; + + /** + * @brief The maximum offset extent. + * + * The maximum extent that will cover all offsets. + */ + koord offset_extent_max; + sint16 raster; /**< For this rastersize. */ protected: Index: Makefile =================================================================== --- Makefile (revision 8546) +++ Makefile (working copy) @@ -287,6 +287,7 @@ SOURCES += obj/wolke.cc SOURCES += obj/zeiger.cc SOURCES += display/font.cc +SOURCES += display/prepmap.cc SOURCES += display/simgraph$(COLOUR_DEPTH).cc SOURCES += display/simview.cc SOURCES += display/viewport.cc Index: simplan.cc =================================================================== --- simplan.cc (revision 8546) +++ simplan.cc (working copy) @@ -620,7 +620,6 @@ } } - /** * Finds halt belonging to a player * @param player owner of the halts we are interested in. @@ -794,3 +793,15 @@ } return false; } + +void planquadrat_t::update_underground() const +{ + get_kartenboden()->check_update_underground(); + // update tunnel tiles + for(unsigned int i=1; iist_tunnel()) { + gr->check_update_underground(); + } + } +} Index: simplan.h =================================================================== --- simplan.h (revision 8546) +++ simplan.h (working copy) @@ -251,6 +251,17 @@ void display_overlay(sint16 xpos, sint16 ypos) const; static void toggle_horizontal_clip(CLIP_NUM_DEF0); + + /** + * @brief Update this square for underground view. + * + * Updates this square for underground view. This includes calculating + * calculating new back will images as well as water depth texture. + * + * This method does not modify this square object, but does modify the + * grounds it references. + */ + void update_underground() const; }; #endif Index: simworld.cc =================================================================== --- simworld.cc (revision 8546) +++ simworld.cc (working copy) @@ -43,6 +43,7 @@ #include "simunits.h" #include "simversion.h" #include "display/simview.h" +#include "display/prepmap.h" #include "simtool.h" #include "gui/simwin.h" #include "simworld.h" @@ -5778,29 +5779,10 @@ void karte_t::update_underground() { DBG_MESSAGE( "karte_t::update_underground_map()", "" ); - world_xy_loop(&karte_t::update_underground_intern, SYNCX_FLAG); + prepmap_t::invalidate_all(); set_dirty(); } - -void karte_t::update_underground_intern( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max ) -{ - for( int y = y_min; y < y_max; y++ ) { - for( int x = x_min; x < x_max; x++ ) { - const int nr = y * cached_grid_size.x + x; - plan[nr].get_kartenboden()->check_update_underground(); - // update tunnel tiles - for(uint8 i=1; iist_tunnel()) { - gr->check_update_underground(); - } - } - } - } -} - - void karte_t::calc_climate(koord k, bool recalc) { planquadrat_t *pl = access(k); Index: simworld.h =================================================================== --- simworld.h (revision 8546) +++ simworld.h (working copy) @@ -694,11 +694,6 @@ */ void update_map_intern(sint16, sint16, sint16, sint16); - /** - * Updates images after change of underground mode. - */ - void update_underground_intern(sint16, sint16, sint16, sint16); - public: /** * Announce server and current state to listserver.