diff --git dataobj/environment.cc dataobj/environment.cc index a1be2c4e0..752483220 100644 --- dataobj/environment.cc +++ dataobj/environment.cc @@ -17,7 +17,7 @@ void rdwr_win_settings(loadsave_t *file); // simwin sint8 env_t::pak_tile_height_step = 16; sint8 env_t::pak_height_conversion_factor = 1; -bool env_t::new_height_map_conversion = false; +env_t::height_conversion_mode env_t::height_conv_mode = env_t::HEIGHT_CONV_LINEAR; bool env_t::simple_drawing = false; bool env_t::simple_drawing_fast_forward = true; @@ -480,8 +480,20 @@ void env_t::rdwr(loadsave_t *file) file->rdwr_str( default_theme ); } if( file->is_version_atleast(120, 2) ) { - file->rdwr_bool( new_height_map_conversion ); + if( file->is_version_atleast(122, 1)) { + sint32 conv_mode = height_conv_mode; + file->rdwr_long( conv_mode ); + if (file->is_loading()) { + height_conv_mode = (env_t::height_conversion_mode)::clamp(conv_mode, 0, (int)env_t::NUM_HEIGHT_CONV_MODES-1); + } + } + else { + bool new_convert = height_conv_mode != env_t::HEIGHT_CONV_LEGACY_SMALL; + file->rdwr_bool( new_convert ); + height_conv_mode = new_convert ? env_t::HEIGHT_CONV_LEGACY_LARGE : env_t::HEIGHT_CONV_LEGACY_SMALL; + } } + if( file->is_version_atleast(120, 5) ) { file->rdwr_long( background_color_rgb ); file->rdwr_long( tooltip_color_rgb ); diff --git dataobj/environment.h dataobj/environment.h index 45e4eee3b..3570fe082 100644 --- dataobj/environment.h +++ dataobj/environment.h @@ -329,8 +329,16 @@ public: /// Only use during loading of old games! static sint8 pak_height_conversion_factor; - // load old height maps (false) or use as many available height levels as possible - static bool new_height_map_conversion; + enum height_conversion_mode + { + HEIGHT_CONV_LEGACY_SMALL, ///< Old (fixed) height conversion, small height difference + HEIGHT_CONV_LEGACY_LARGE, ///< Old (fixed) height conversion, larger height difference + HEIGHT_CONV_LINEAR, ///< linear interpolation between min_/max_allowed_height + HEIGHT_CONV_CLAMP, ///< Use 1 height level per 1 greyscale level, clamp to allowed height (cut off mountains) + NUM_HEIGHT_CONV_MODES + }; + + static height_conversion_mode height_conv_mode; /// use the faster drawing routine (and allow for clipping errors) static bool simple_drawing; diff --git dataobj/height_map_loader.cc dataobj/height_map_loader.cc index 014eb3e5a..f0791a566 100644 --- dataobj/height_map_loader.cc +++ dataobj/height_map_loader.cc @@ -3,246 +3,428 @@ * (see LICENSE.txt) */ -/* code for loading heightmaps */ - -#include -#include -#include +#include "height_map_loader.h" #include "environment.h" -#include "height_map_loader.h" + #include "../simio.h" #include "../sys/simsys.h" +#include "../simmem.h" +#include "../macros.h" + +#include +#include +#include -height_map_loader_t::height_map_loader_t(bool new_format): - height_map_conversion_version_new(new_format) - { +#define BMPINFOHEADER_OFFSET (14) + + +height_map_loader_t::height_map_loader_t(sint8 min_height, sint8 max_height, env_t::height_conversion_mode mode) : + min_allowed_height(min_height), + max_allowed_height(max_height), + conv_mode(mode) +{ } // read height data from bmp or ppm files bool height_map_loader_t::get_height_data_from_file( const char *filename, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values ) { - if (FILE* const file = dr_fopen(filename, "rb")) { - char id[3]; - // parsing the header of this mixed file format is nottrivial ... - id[0] = fgetc(file); - id[1] = fgetc(file); - id[2] = 0; - if(strcmp(id, "P6")) { - if(strcmp(id, "BM")) { - fclose(file); - dbg->error("height_map_loader_t::load_heightfield()","Heightfield has wrong image type %s instead P6/BM", id); - return false; + hfield = NULL; + + FILE *const file = dr_fopen(filename, "rb"); + if( !file ) { + dbg->error("height_map_loader_t::get_height_data_from_file()", "Cannot open heightmap file"); + return false; + } + + char id[3] = {0, 0, 0}; + // parsing the header of this mixed file format is non-trivial ... + if( fgets(id, 3, file) == NULL ) { + fclose(file); + dbg->error("height_map_loader_t::get_height_data_from_file()", "Cannot read magic number"); + return false; + } + + const bool is_bmp = strcmp(id, "BM") == 0; + const bool is_ppm = strcmp(id, "P6") == 0; + + if( !is_bmp && !is_ppm ) { + fclose(file); + dbg->error("height_map_loader_t::get_height_data_from_file()", "Unsupported height map format (must be bmp or ppm)"); + return false; + } + + const char *err = NULL; + if( is_bmp ) { + err = read_bmp(file, groundwater, hfield, ww, hh, update_only_values); + } + else { + err = read_ppm(file, groundwater, hfield, ww, hh, update_only_values); + } + + // success ... (or not) + fclose(file); + + if( err ) { + dbg->error("height_map_loader_t::get_height_data_from_file()", + "Error while reading %s file: %s", is_bmp ? "bmp" : "ppm", err); + + if( hfield ) { + free(hfield); + hfield = NULL; + } + } + + return err == NULL; +} + + +const char *height_map_loader_t::read_bmp( FILE *file, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values ) +{ + sint32 sl; + uint32 ul; + uint16 us; + + if( fseek( file, 10, SEEK_SET ) != 0 || fread(&ul, sizeof(uint32), 1, file) != 1 ) { + return "Malformed bmp file"; + } + const uint32 image_data_offset = endian(ul); + + // Read BITMAPINFOHEADER + if( fseek( file, BMPINFOHEADER_OFFSET + 0, SEEK_SET ) != 0 || fread(&ul, sizeof(uint32), 1, file) != 1 ) { + return "Malformed BMP file"; + } + const uint32 bmpinfoheader_size = endian(ul); + + if (bmpinfoheader_size < 36) { + return "Malformed BMP file"; + } + + if( fseek( file, BMPINFOHEADER_OFFSET + 4, SEEK_SET ) != 0 || fread(&sl, sizeof(sint32), 1, file) != 1 ) { + return "Malformed BMP file"; + } + sint32 width = endian(sl); + + if( fseek( file, BMPINFOHEADER_OFFSET + 8, SEEK_SET ) != 0 || fread(&sl, sizeof(sint32), 1, file) != 1 ) { + return "Malformed BMP file"; + } + sint32 height = endian(sl); + + if( fseek( file, BMPINFOHEADER_OFFSET + 14, SEEK_SET ) != 0 || fread(&us, sizeof(uint16), 1, file) != 1 ) { + return "Malformed BMP file"; + } + const uint16 bit_depth = endian(us); + + if( fseek( file, BMPINFOHEADER_OFFSET + 16, SEEK_SET ) != 0 || fread(&ul, sizeof(uint32), 1, file) != 1 ) { + return "Malformed BMP file"; + } + const uint32 format = endian(ul); + + if( fseek( file, BMPINFOHEADER_OFFSET + 32, SEEK_SET ) != 0 || fread(&ul, sizeof(uint32), 1, file) != 1 ) { + return "Malformed BMP file"; + } + uint32 table = endian(ul); + + // We only allow the following image formats: + // 8 bit: BI_RGB (uncompressed) + // BI_RLE8 (8 bit RLE) + // 24 bit: BI_RGB + if( (bit_depth!=8 || format>1) && (bit_depth!=24 || format!=0) ) { + return "Can only use 8 bit (RLE or normal) or 24 bit bitmaps!"; + } + + // skip parsing body + if( update_only_values ) { + ww = abs(width); + hh = abs(height); + return NULL; + } + + // now read the data and convert them on the fly + hfield = MALLOCN(sint8, abs(width) * abs(height)); + + if (!hfield) { + return "Not enough memory"; + } + + memset( hfield, groundwater, abs(width) * abs(height) ); + + if( bit_depth==8 ) { + // convert color tables to height levels + if( table==0 ) { + table = 256; + } + + const uint32 colortable_offset = BMPINFOHEADER_OFFSET + bmpinfoheader_size; + + if( fseek( file, colortable_offset, SEEK_SET ) != 0 ) { + return "Malformed bmp file"; + } + + sint8 h_table[256]; + for( uint32 i=0; i1) { - if(!update_only_values) { - dbg->fatal("height_map_loader_t::get_height_data_from_file()","Can only use 8Bit (RLE or normal) or 24 bit bitmaps!"); + + h_table[i] = height_map_loader_t::rgb_to_height(R, G, B); + } + + // now read the data + if( fseek( file, image_data_offset, SEEK_SET ) != 0 ) { + return "Malformed bmp file"; + } + + if( format==0 ) { + // uncompressed (usually mirrored, if h<0) + const bool mirror = (height<0); + height = abs(height); + width = abs(width); + + for( sint32 y=0; y0 ) { + for( sint32 k=0; k0) - bool mirror = (h<0); - h = abs(h); - for( sint32 y=0; y 0) { - for( sint32 k = 0; k < Count; k++, x++ ) { - hfield[x+(y*w)] = h_table[ColorIndex]; - } - } else if (Count == 0) { - sint32 Flag = ColorIndex; - if (Flag == 0) { - // goto next line - x = 0; - y--; - } - else if (Flag == 1) { - // end of bitmap - break; - } - else if (Flag == 2) { - // skip with cursor - x += (uint8)fgetc(file); - y -= (uint8)fgetc(file); - } - else { - // uncompressed run - Count = Flag; - for( sint32 k = 0; k < Count; k++, x++ ) { - hfield[x+y*w] = h_table[(uint8)fgetc(file)]; - } - if (ftell(file) & 1) { // always even offset in file - fseek(file, 1, SEEK_CUR); - } + else { + // uncompressed run + Count = Flag; + for( sint32 k=0; k='0' && *c<='9') { - c++; + } + else { + // uncompressed 24 bits + const bool mirror = (height<0); + height = abs(height); + + // Now read the data + if( fseek( file, image_data_offset, SEEK_SET ) != 0 ) { + return "Malformed bmp file"; + } + + for( sint32 y=0; yfatal("height_map_loader_t::load_heightfield()","Heightfield has wrong color depth %d", param[2] ); + + // skip padding to 4 bytes at the end of each scanline + const int padding = (4 - ((width * 3) & 3)) & 3; + if( padding != 0 && fseek( file, padding, SEEK_CUR ) != 0 ) { + // Allow missing padding at end of file + if (y != height-1) { + return "Malformed bmp file"; } - return false; } + } + } + + ww = width; + hh = height; + + return NULL; +} + + +const char *height_map_loader_t::read_ppm( FILE *file, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values ) +{ + // ppm format + char buf[255]; + const char *c = ""; + sint32 param[3] = {0, 0, 0}; - // report only values - if(update_only_values) { - fclose(file); - ww = w; - hh = h; - return true; + for( int index=0; index<3; ) { + // the format is "P6[whitespace]width[whitespace]height[[whitespace bitdepth]]newline] + // however, Photoshop is the first program that uses space for the first whitespace + // so we cater for Photoshop too + while( *c!=0 && *c<=32 ) { + c++; + } + + // usually, after P6 there comes a comment with the maker + // but comments can be anywhere + if( *c==0 ) { + if( read_line(buf, sizeof(buf), file) == NULL ) { + return "Malformed ppm file"; } - // ok, now read them in - hfield = new sint8[w*h]; - memset( hfield, groundwater, w*h ); + c = buf; + continue; + } - for(sint16 y=0; y='0' && *c<='9' ) { + c++; + } + } + + // now the data + const sint32 w = param[0]; + const sint32 h = param[1]; + + if( param[2]!=255 ) { + return "Heightfield has wrong color depth (must be 255)"; + } + + // report only values + if( update_only_values ) { + ww = w; + hh = h; + return NULL; + } + + // ok, now read them in + hfield = MALLOCN(sint8, w*h); + + if (!hfield) { + return "Not enough memory"; + } + + memset( hfield, groundwater, w*h ); + + for( sint16 y=0; y(h0/32 - 28, min_allowed_height, max_allowed_height); // -28..19 + } + else { + return ::clamp(h0/64 - 14, min_allowed_height, max_allowed_height); // -14..9 + } + } + case env_t::HEIGHT_CONV_LEGACY_LARGE: { + // new style, heights more spread out + if( env_t::pak_height_conversion_factor == 2 ) { + return ::clamp(h0/24 - 34, min_allowed_height, max_allowed_height); // -34..29 + } + else { + return ::clamp(h0/48 - 18, min_allowed_height, max_allowed_height); // -18..13 } } - return false; + case env_t::HEIGHT_CONV_LINEAR: { + return min_allowed_height + (h0*(max_allowed_height-min_allowed_height)) / 0x5FA; + } + case env_t::HEIGHT_CONV_CLAMP: { + return ::clamp((sint8)(((h0 * 0xFF) / 0x5FA) - 128), min_allowed_height, max_allowed_height); + } + default: + dbg->fatal("height_map_loader_t::rgb_to_height", "Unhandled height conversion mode %d", conv_mode); + } + + return 0; } diff --git dataobj/height_map_loader.h dataobj/height_map_loader.h index 4c4640e87..00c253995 100644 --- dataobj/height_map_loader.h +++ dataobj/height_map_loader.h @@ -10,43 +10,39 @@ #include "../simtypes.h" #include "environment.h" -/* code for loading heightmaps */ -class height_map_loader_t { + +/** + * Loads height data from BMP or PPM files. + */ +class height_map_loader_t +{ public: - height_map_loader_t(bool height_map_conversion_version); + height_map_loader_t(sint8 min_allowed_height, sint8 max_allowed_height, env_t::height_conversion_mode conv_mode); /** - * Reads height data from 8 or 25 bit bmp or ppm files. - * @return Either pointer to heightfield (use delete [] for it) or NULL. + * Reads height data from 8 or 24 bit bmp or ppm files. + * + * @param filename the file to load the height data from. + * @param[out] hfield 2d array of height values. + * @param[out] ww,hh width and height of @p hfield. On failure, these values are undefined. + * @param update_only_values When true, do not allocate the height field; instead, only update @p ww and @p hh + * + * @return true on success, false on failure. On success, @p hfield contains + * the height field data (must be free()'d by the caller unless @p update_only_values is set). + * On failure, @p hfield is set to NULL (Does not need to be free()'d) */ bool get_height_data_from_file( const char *filename, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values ); private: - inline sint8 rgb_to_height( const int r, const int g, const int b ) { - const sint16 h0 = (r*2+g*3+b); - if( !height_map_conversion_version_new ) { - // old style - if( env_t::pak_height_conversion_factor == 2 ) { - // was: return (((r*2+g*3+b)/4 - 224) & 0xFFF8)/8; - return h0/32 - 28; - } - else { - // was: return (( ((r*2+g*3+b)/4 - 224)) & 0xFFF0)/16; - return h0/64 - 14; - } - } - else { - // new style, heights more spread out - if( env_t::pak_height_conversion_factor == 2 ) { - return h0/24 - 34; - } - else { - return h0/48 - 18; - } - } - } - - const bool height_map_conversion_version_new; + sint8 rgb_to_height( const int r, const int g, const int b ); + + const char *read_bmp(FILE *file, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values); + const char *read_ppm(FILE *file, sint8 groundwater, sint8 *&hfield, sint16 &ww, sint16 &hh, bool update_only_values); + +private: + const sint8 min_allowed_height; + const sint8 max_allowed_height; + const env_t::height_conversion_mode conv_mode; }; #endif diff --git dataobj/settings.cc dataobj/settings.cc index df63330b2..3afdfb57d 100644 --- dataobj/settings.cc +++ dataobj/settings.cc @@ -890,6 +890,9 @@ void settings_t::rdwr(loadsave_t *file) if( file->is_version_atleast(120, 7) ) { file->rdwr_byte(world_maximum_height); file->rdwr_byte(world_minimum_height); + + world_maximum_height = clamp(world_maximum_height, 16, 127); + world_minimum_height = clamp(world_minimum_height, -127, -12); } if( file->is_version_atleast(120, 9) ) { file->rdwr_long(allow_merge_distant_halt); @@ -1372,7 +1375,8 @@ void settings_t::parse_simuconf( tabfile_t& simuconf, sint16& disp_width, sint16 starting_year = contents.get_int( "starting_year", starting_year ); starting_month = contents.get_int( "starting_month", starting_month + 1 ) - 1; - env_t::new_height_map_conversion = contents.get_int( "new_height_map_conversion", env_t::new_height_map_conversion ); + env_t::height_conv_mode = (env_t::height_conversion_mode)::clamp(contents.get_int("new_height_map_conversion", (int)env_t::height_conv_mode ), 0, env_t::NUM_HEIGHT_CONV_MODES-1); + river_number = contents.get_int( "river_number", river_number ); min_river_length = contents.get_int( "river_min_length", min_river_length ); max_river_length = contents.get_int( "river_max_length", max_river_length ); @@ -1543,13 +1547,11 @@ void settings_t::parse_simuconf( tabfile_t& simuconf, sint16& disp_width, sint16 max_rail_convoi_length = contents.get_int("max_rail_convoi_length",max_rail_convoi_length); max_road_convoi_length = contents.get_int("max_road_convoi_length",max_road_convoi_length); max_ship_convoi_length = contents.get_int("max_ship_convoi_length",max_ship_convoi_length); - max_air_convoi_length = contents.get_int("max_air_convoi_length",max_air_convoi_length); + max_air_convoi_length = contents.get_int("max_air_convoi_length",max_air_convoi_length); - world_maximum_height = contents.get_int("world_maximum_height",world_maximum_height); - world_minimum_height = contents.get_int("world_minimum_height",world_minimum_height); - if( world_minimum_height>=world_maximum_height ) { - world_minimum_height = world_maximum_height-1; - } + // note: no need to check for min_height < max_height, since -12 < 16 + world_maximum_height = clamp(contents.get_int("world_maximum_height",world_maximum_height), 16, 127); + world_minimum_height = clamp(contents.get_int("world_minimum_height",world_minimum_height), -127, -12); // Default pak file path objfilename = ltrim(contents.get_string("pak_file_path", "" ) ); diff --git gui/load_relief_frame.cc gui/load_relief_frame.cc index 913da7bb3..2d7708ed3 100644 --- gui/load_relief_frame.cc +++ gui/load_relief_frame.cc @@ -14,6 +14,32 @@ #include "../dataobj/settings.h" #include "../dataobj/environment.h" #include "../dataobj/height_map_loader.h" +#include "components/gui_scrolled_list.h" + + +static const char *load_mode_texts[env_t::NUM_HEIGHT_CONV_MODES] = +{ + "legacy (small heights)", + "legacy (large heights)", + "linear", + "clamp" +}; + + +class load_relief_mode_scrollitem_t : public gui_scrolled_list_t::const_text_scrollitem_t +{ +public: + load_relief_mode_scrollitem_t(env_t::height_conversion_mode mode) : + gui_scrolled_list_t::const_text_scrollitem_t(translator::translate(load_mode_texts[(int)mode]), SYSCOL_TEXT), + mode(mode) + {} + + env_t::height_conversion_mode get_mode() const { return mode; } + +private: + env_t::height_conversion_mode mode; +}; + /** * Action, started on button pressing @@ -23,17 +49,33 @@ bool load_relief_frame_t::item_action(const char *fullpath) sets->heightfield = fullpath; if (gui_frame_t *new_world_gui = win_get_magic( magic_welt_gui_t )) { + const gui_scrolled_list_t::scrollitem_t *selected = load_mode.get_selected_item(); + if (selected) { + env_t::height_conv_mode = static_cast(selected)->get_mode(); + } + static_cast(new_world_gui)->update_preview(true); } + return false; } load_relief_frame_t::load_relief_frame_t(settings_t* const sets) : savegame_frame_t( NULL, false, "maps/", env_t::show_delete_buttons ) { - new_format.init( button_t::square_automatic, "Maximize height levels"); - new_format.pressed = env_t::new_height_map_conversion; - bottom_left_frame.add_component( &new_format ); + gui_aligned_container_t *table = bottom_left_frame.add_table(2, 1); + load_mode_label.init(translator::translate("Load mode:"), scr_coord(0, 0)); + load_mode_label.set_visible(true); + table->add_component( &load_mode_label ); + + load_mode.init(scr_coord(0, 0)); + load_mode.new_component(env_t::HEIGHT_CONV_LEGACY_SMALL); + load_mode.new_component(env_t::HEIGHT_CONV_LEGACY_LARGE); + load_mode.new_component(env_t::HEIGHT_CONV_LINEAR); + load_mode.new_component(env_t::HEIGHT_CONV_CLAMP); + load_mode.set_selection(env_t::HEIGHT_CONV_LINEAR); + table->add_component( &load_mode ); + bottom_left_frame.end_table(); const std::string extra_path = env_t::data_dir + env_t::objfilename + "maps/"; this->add_path(extra_path.c_str()); @@ -49,27 +91,48 @@ const char *load_relief_frame_t::get_info(const char *fullpath) static char size[64]; sint16 w, h; - sint8 *h_field ; - height_map_loader_t hml(new_format.pressed); + sint8 *h_field = NULL; + const sint8 min_h = world()->get_settings().get_minimumheight(); + const sint8 max_h = world()->get_settings().get_maximumheight(); + + const gui_scrolled_list_t::scrollitem_t *selected = load_mode.get_selected_item(); + env_t::height_conversion_mode new_mode = env_t::height_conv_mode; + if (selected) { + new_mode = static_cast(selected)->get_mode(); + } + + height_map_loader_t hml(min_h, max_h, env_t::height_conv_mode); if(hml.get_height_data_from_file(fullpath, (sint8)sets->get_groundwater(), h_field, w, h, true )) { sprintf( size, "%i x %i", w, h ); - env_t::new_height_map_conversion = new_format.pressed; + env_t::height_conv_mode = new_mode; return size; } + return ""; } bool load_relief_frame_t::check_file( const char *fullpath, const char * ) { + const sint8 min_h = world()->get_settings().get_minimumheight(); + const sint8 max_h = world()->get_settings().get_maximumheight(); + + const gui_scrolled_list_t::scrollitem_t *selected = load_mode.get_selected_item(); + env_t::height_conversion_mode new_mode = env_t::height_conv_mode; + + if (selected) { + new_mode = static_cast(selected)->get_mode(); + } + + height_map_loader_t hml(min_h, max_h, env_t::height_conv_mode); sint16 w, h; - sint8 *h_field; + sint8 *h_field = NULL; - height_map_loader_t hml(new_format.pressed); if(hml.get_height_data_from_file(fullpath, (sint8)sets->get_groundwater(), h_field, w, h, true )) { + env_t::height_conv_mode = new_mode; return w>0 && h>0; - env_t::new_height_map_conversion = new_format.pressed; } + return false; } diff --git gui/load_relief_frame.h gui/load_relief_frame.h index 971df2c0c..79b79d93b 100644 --- gui/load_relief_frame.h +++ gui/load_relief_frame.h @@ -7,17 +7,20 @@ #define GUI_LOAD_RELIEF_FRAME_H +#include "components/gui_combobox.h" #include "savegame_frame.h" class settings_t; + class load_relief_frame_t : public savegame_frame_t { private: settings_t* sets; - button_t new_format; + gui_label_t load_mode_label; + gui_combobox_t load_mode; protected: bool item_action(const char *fullpath) OVERRIDE; diff --git gui/loadfont_frame.cc gui/loadfont_frame.cc index 950c08b6f..ff848ad8c 100644 --- gui/loadfont_frame.cc +++ gui/loadfont_frame.cc @@ -253,7 +253,6 @@ void loadfont_frame_t::rdwr( loadsave_t *file ) } - bool loadfont_frame_t::action_triggered(gui_action_creator_t *component, value_t v) { if( &unicode_only==component ) { diff --git gui/welt.cc gui/welt.cc index 215091b22..189ac323e 100644 --- gui/welt.cc +++ gui/welt.cc @@ -274,9 +274,13 @@ bool welt_gui_t::update_from_heightfield(const char *filename) { DBG_MESSAGE("welt_gui_t::update_from_heightfield()", "%s", filename); + const sint8 min_h = env_t::default_settings.get_minimumheight(); + const sint8 max_h = env_t::default_settings.get_maximumheight(); + + height_map_loader_t hml(min_h, max_h, env_t::height_conv_mode); sint16 w, h; sint8 *h_field=NULL; - height_map_loader_t hml(sets); + if(hml.get_height_data_from_file(filename, (sint8)sets->get_groundwater(), h_field, w, h, false )) { sets->set_size_x(w); sets->set_size_y(h); @@ -295,8 +299,10 @@ bool welt_gui_t::update_from_heightfield(const char *filename) } } map_preview.set_map_data(&map); + free(h_field); return true; } + return false; } diff --git simworld.cc simworld.cc index 92577473c..3ea6fac86 100644 --- simworld.cc +++ simworld.cc @@ -6577,13 +6577,17 @@ uint8 karte_t::sp2num(player_t *player) void karte_t::load_heightfield(settings_t* const sets) { sint16 w, h; - sint8 *h_field; - height_map_loader_t hml(sets); + sint8 *h_field = NULL; + const sint8 min_h = sets->get_minimumheight(); + const sint8 max_h = sets->get_maximumheight(); + + height_map_loader_t hml(min_h, max_h, env_t::height_conv_mode); + if(hml.get_height_data_from_file(sets->heightfield.c_str(), (sint8)(sets->get_groundwater()), h_field, w, h, false )) { sets->set_size(w,h); // create map init(sets,h_field); - delete [] h_field; + free(h_field); } else { dbg->error("karte_t::load_heightfield()","Cant open file '%s'", sets->heightfield.c_str());