Merge branch 'master' into jgrpp
# Conflicts: # src/articulated_vehicles.cpp # src/articulated_vehicles.h # src/base_media_base.h # src/base_media_func.h # src/build_vehicle_gui.cpp # src/dock_gui.cpp # src/main_gui.cpp # src/music_gui.cpp # src/network/network_chat_gui.cpp # src/network/network_content.cpp # src/newgrf.cpp # src/newgrf_roadstop.cpp # src/os/windows/string_uniscribe.h # src/os/windows/win32.cpp # src/rail_gui.cpp # src/road.cpp # src/road_gui.cpp # src/settings.cpp # src/settings_gui.cpp # src/smallmap_gui.cpp # src/strings.cpp # src/terraform_gui.cpp # src/tests/test_script_admin.cpp # src/tests/test_window_desc.cpp # src/timer/timer_game_calendar.h # src/vehicle.cpp # src/vehicle_base.h # src/viewport.cpp # src/widget_type.h # src/window.cpp # src/window_gui.h
This commit is contained in:
		
							
								
								
									
										50
									
								
								.github/windowdesc-ini-key.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.github/windowdesc-ini-key.py
									
									
									
									
										vendored
									
									
								
							@@ -1,50 +0,0 @@
 | 
			
		||||
"""
 | 
			
		||||
Script to scan the OpenTTD source-tree for ini_key issues in WindowDesc entries.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import glob
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def scan_source_files(path, ini_keys=None):
 | 
			
		||||
    if ini_keys is None:
 | 
			
		||||
        ini_keys = set()
 | 
			
		||||
 | 
			
		||||
    errors = []
 | 
			
		||||
 | 
			
		||||
    for new_path in glob.glob(f"{path}/*.cpp"):
 | 
			
		||||
        if os.path.isdir(new_path):
 | 
			
		||||
            errors.append(scan_source_files(new_path, ini_keys))
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        with open(new_path) as fp:
 | 
			
		||||
            output = fp.read()
 | 
			
		||||
 | 
			
		||||
        for (name, ini_key, widgets) in re.findall(r"^static WindowDesc ([a-zA-Z0-9_]*).*?, (?:\"(.*?)\")?.*?,(?:\s+.*?,){6}\s+[^\s]+\((.*?)\)", output, re.S|re.M):
 | 
			
		||||
            if ini_key:
 | 
			
		||||
                if ini_key in ini_keys:
 | 
			
		||||
                    errors.append(f"{new_path}: {name} ini_key is a duplicate")
 | 
			
		||||
                ini_keys.add(ini_key)
 | 
			
		||||
            widget = re.findall("static const (?:struct )?NWidgetPart " + widgets + ".*?(?:WWT_(DEFSIZE|STICKY)BOX.*?)?;", output, re.S)[0]
 | 
			
		||||
            if widget and not ini_key:
 | 
			
		||||
                errors.append(f"{new_path}: {name} has WWT_DEFSIZEBOX/WWT_STICKYBOX without ini_key")
 | 
			
		||||
            if ini_key and not widget:
 | 
			
		||||
                errors.append(f"{new_path}: {name} has ini_key without WWT_DEFSIZEBOX/WWT_STICKYBOX")
 | 
			
		||||
 | 
			
		||||
    return errors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    errors = scan_source_files("src")
 | 
			
		||||
 | 
			
		||||
    if errors:
 | 
			
		||||
        print("\n".join(errors))
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
    print("OK")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										24
									
								
								.github/workflows/windowdesc-ini-key.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/windowdesc-ini-key.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,24 +0,0 @@
 | 
			
		||||
name: WindowDesc ini_key
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches:
 | 
			
		||||
    - master
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
  cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  windowdesc-ini-key:
 | 
			
		||||
    name: WindowDesc ini_key issues
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Checkout
 | 
			
		||||
      uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
    - name: Check for ini_key issues in WindowDesc entries
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        python3 .github/windowdesc-ini-key.py
 | 
			
		||||
@@ -72,8 +72,8 @@ static const NWidgetPart _nested_ai_config_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition for the configure AI window. */
 | 
			
		||||
static WindowDesc _ai_config_desc(
 | 
			
		||||
	WDP_CENTER, "settings_script_config", 0, 0,
 | 
			
		||||
static WindowDesc _ai_config_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_GAME_OPTIONS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_ai_config_widgets), std::end(_nested_ai_config_widgets)
 | 
			
		||||
 
 | 
			
		||||
@@ -199,7 +199,7 @@ static const NWidgetPart _nested_air_toolbar_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _air_toolbar_desc(
 | 
			
		||||
static WindowDesc _air_toolbar_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0,
 | 
			
		||||
	WC_BUILD_TOOLBAR, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -606,7 +606,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_airport_desc(
 | 
			
		||||
static WindowDesc _build_airport_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_BUILD_STATION, WC_BUILD_TOOLBAR,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -318,19 +318,6 @@ CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial
 | 
			
		||||
	return union_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Ands the refit_masks of all articulated parts.
 | 
			
		||||
 * @param engine the first part
 | 
			
		||||
 * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask
 | 
			
		||||
 * @return bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0)
 | 
			
		||||
 */
 | 
			
		||||
CargoTypes GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
 | 
			
		||||
{
 | 
			
		||||
	CargoTypes union_mask, intersection_mask;
 | 
			
		||||
	GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask);
 | 
			
		||||
	return intersection_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get cargo mask of all cargoes carried by an articulated vehicle.
 | 
			
		||||
 * Note: Vehicles not carrying anything are ignored
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ void AddArticulatedParts(Vehicle *first);
 | 
			
		||||
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask);
 | 
			
		||||
std::vector<CargoTypes> GetArticulatedRefitMaskVector(EngineID engine, bool include_initial_cargo_type);
 | 
			
		||||
CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type);
 | 
			
		||||
CargoTypes GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type);
 | 
			
		||||
CargoTypes GetCargoTypesOfArticulatedVehicle(const Vehicle *v, CargoID *cargo_type);
 | 
			
		||||
CargoID GetOverallCargoOfArticulatedVehicle(const Vehicle *v);
 | 
			
		||||
bool IsArticulatedVehicleRefittable(EngineID engine);
 | 
			
		||||
 
 | 
			
		||||
@@ -810,7 +810,7 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _replace_rail_vehicle_desc(
 | 
			
		||||
static WindowDesc _replace_rail_vehicle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "replace_vehicle_train", 500, 140,
 | 
			
		||||
	WC_REPLACE_VEHICLE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -868,7 +868,7 @@ static const NWidgetPart _nested_replace_road_vehicle_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _replace_road_vehicle_desc(
 | 
			
		||||
static WindowDesc _replace_road_vehicle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "replace_vehicle_road", 500, 140,
 | 
			
		||||
	WC_REPLACE_VEHICLE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -922,7 +922,7 @@ static const NWidgetPart _nested_replace_vehicle_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _replace_vehicle_desc(
 | 
			
		||||
static WindowDesc _replace_vehicle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "replace_vehicle", 456, 118,
 | 
			
		||||
	WC_REPLACE_VEHICLE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -96,6 +96,7 @@ struct BaseSet {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
 | 
			
		||||
	void CopyCompatibleConfig([[maybe_unused]] const T &src) {}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the description for the given ISO code.
 | 
			
		||||
@@ -170,9 +171,6 @@ protected:
 | 
			
		||||
	 */
 | 
			
		||||
	static const char *GetExtension();
 | 
			
		||||
public:
 | 
			
		||||
	/** The set as saved in the config file. */
 | 
			
		||||
	static std::string ini_set;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine the graphics pack that has to be used.
 | 
			
		||||
	 * The one with the most correct files wins.
 | 
			
		||||
@@ -191,7 +189,9 @@ public:
 | 
			
		||||
 | 
			
		||||
	static Tbase_set *GetAvailableSets();
 | 
			
		||||
 | 
			
		||||
	static bool SetSet(const std::string &name);
 | 
			
		||||
	static bool SetSet(const Tbase_set *set);
 | 
			
		||||
	static bool SetSetByName(const std::string &name);
 | 
			
		||||
	static bool SetSetByShortname(uint32_t shortname);
 | 
			
		||||
	static char *GetSetsList(char *p, const char *last);
 | 
			
		||||
	static int GetNumSets();
 | 
			
		||||
	static int GetIndexOfUsedSet();
 | 
			
		||||
@@ -207,7 +207,6 @@ public:
 | 
			
		||||
	static bool HasSet(const ContentInfo *ci, bool md5sum);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Tbase_set> /* static */ std::string BaseMedia<Tbase_set>::ini_set;
 | 
			
		||||
template <class Tbase_set> /* static */ const Tbase_set *BaseMedia<Tbase_set>::used_set;
 | 
			
		||||
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::available_sets;
 | 
			
		||||
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplicate_sets;
 | 
			
		||||
@@ -239,12 +238,24 @@ enum BlitterType {
 | 
			
		||||
	BLT_32BPP,      ///< Base set has both 8 bpp and 32 bpp sprites.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct GRFConfig;
 | 
			
		||||
 | 
			
		||||
/** All data of a graphics set. */
 | 
			
		||||
struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
 | 
			
		||||
private:
 | 
			
		||||
	mutable std::unique_ptr<GRFConfig> extra_cfg; ///< Parameters for extra GRF
 | 
			
		||||
public:
 | 
			
		||||
	PaletteType palette;       ///< Palette of this graphics set
 | 
			
		||||
	BlitterType blitter;       ///< Blitter of this graphics set
 | 
			
		||||
 | 
			
		||||
	GraphicsSet();
 | 
			
		||||
	~GraphicsSet();
 | 
			
		||||
 | 
			
		||||
	bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
 | 
			
		||||
	GRFConfig *GetExtraConfig() const { return this->extra_cfg.get(); }
 | 
			
		||||
	GRFConfig &GetOrCreateExtraConfig() const;
 | 
			
		||||
	bool IsConfigurable() const;
 | 
			
		||||
	void CopyCompatibleConfig(const GraphicsSet &src);
 | 
			
		||||
 | 
			
		||||
	static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
 | 
			
		||||
};
 | 
			
		||||
@@ -252,6 +263,15 @@ struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
 | 
			
		||||
/** All data/functions related with replacing the base graphics. */
 | 
			
		||||
class BaseGraphics : public BaseMedia<GraphicsSet> {
 | 
			
		||||
public:
 | 
			
		||||
	/** Values loaded from config file. */
 | 
			
		||||
	struct Ini {
 | 
			
		||||
		std::string name;
 | 
			
		||||
		uint32_t shortname;                 ///< unique key for base set
 | 
			
		||||
		uint32_t extra_version;             ///< version of the extra GRF
 | 
			
		||||
		std::vector<uint32_t> extra_params; ///< parameters for the extra GRF
 | 
			
		||||
	};
 | 
			
		||||
	static inline Ini ini_data;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** All data of a sounds set. */
 | 
			
		||||
@@ -261,6 +281,9 @@ struct SoundsSet : BaseSet<SoundsSet, 1, true> {
 | 
			
		||||
/** All data/functions related with replacing the base sounds */
 | 
			
		||||
class BaseSounds : public BaseMedia<SoundsSet> {
 | 
			
		||||
public:
 | 
			
		||||
	/** The set as saved in the config file. */
 | 
			
		||||
	static inline std::string ini_set;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Maximum number of songs in the 'class' playlists. */
 | 
			
		||||
@@ -307,6 +330,9 @@ struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
 | 
			
		||||
/** All data/functions related with replacing the base music */
 | 
			
		||||
class BaseMusic : public BaseMedia<MusicSet> {
 | 
			
		||||
public:
 | 
			
		||||
	/** The set as saved in the config file. */
 | 
			
		||||
	static inline std::string ini_set;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* BASE_MEDIA_BASE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -197,6 +197,9 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
 | 
			
		||||
				*prev = set;
 | 
			
		||||
				set->next = duplicate->next;
 | 
			
		||||
 | 
			
		||||
				/* Keep baseset configuration, if compatible */
 | 
			
		||||
				set->CopyCompatibleConfig(*duplicate);
 | 
			
		||||
 | 
			
		||||
				/* If the duplicate set is currently used (due to rescanning this can happen)
 | 
			
		||||
				 * update the currently used set to the new one. This will 'lie' about the
 | 
			
		||||
				 * version number until a new game is started which isn't a big problem */
 | 
			
		||||
@@ -225,25 +228,58 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the set to be used.
 | 
			
		||||
 * @param set the set to use
 | 
			
		||||
 * @return true if it could be loaded
 | 
			
		||||
 */
 | 
			
		||||
template <class Tbase_set>
 | 
			
		||||
/* static */ bool BaseMedia<Tbase_set>::SetSet(const Tbase_set *set)
 | 
			
		||||
{
 | 
			
		||||
	if (set == nullptr) {
 | 
			
		||||
		if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false;
 | 
			
		||||
	} else {
 | 
			
		||||
		BaseMedia<Tbase_set>::used_set = set;
 | 
			
		||||
	}
 | 
			
		||||
	CheckExternalFiles();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the set to be used.
 | 
			
		||||
 * @param name of the set to use
 | 
			
		||||
 * @return true if it could be loaded
 | 
			
		||||
 */
 | 
			
		||||
template <class Tbase_set>
 | 
			
		||||
/* static */ bool BaseMedia<Tbase_set>::SetSet(const std::string &name)
 | 
			
		||||
/* static */ bool BaseMedia<Tbase_set>::SetSetByName(const std::string &name)
 | 
			
		||||
{
 | 
			
		||||
	if (name.empty()) {
 | 
			
		||||
		if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false;
 | 
			
		||||
		CheckExternalFiles();
 | 
			
		||||
		return true;
 | 
			
		||||
		return SetSet(nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
 | 
			
		||||
		if (name == s->name) {
 | 
			
		||||
			BaseMedia<Tbase_set>::used_set = s;
 | 
			
		||||
			CheckExternalFiles();
 | 
			
		||||
			return true;
 | 
			
		||||
			return SetSet(s);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the set to be used.
 | 
			
		||||
 * @param shortname of the set to use
 | 
			
		||||
 * @return true if it could be loaded
 | 
			
		||||
 */
 | 
			
		||||
template <class Tbase_set>
 | 
			
		||||
/* static */ bool BaseMedia<Tbase_set>::SetSetByShortname(uint32_t shortname)
 | 
			
		||||
{
 | 
			
		||||
	if (shortname == 0) {
 | 
			
		||||
		return SetSet(nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
 | 
			
		||||
		if (shortname == s->shortname) {
 | 
			
		||||
			return SetSet(s);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
@@ -376,11 +412,12 @@ template <class Tbase_set>
 | 
			
		||||
 * @param set_type  the type of the BaseSet to instantiate
 | 
			
		||||
 */
 | 
			
		||||
#define INSTANTIATE_BASE_MEDIA_METHODS(repl_type, set_type) \
 | 
			
		||||
	template std::string repl_type::ini_set; \
 | 
			
		||||
	template const char *repl_type::GetExtension(); \
 | 
			
		||||
	template bool repl_type::AddFile(const std::string &filename, size_t pathlength, const std::string &tar_filename); \
 | 
			
		||||
	template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \
 | 
			
		||||
	template bool repl_type::SetSet(const std::string &name); \
 | 
			
		||||
	template bool repl_type::SetSet(const set_type *set); \
 | 
			
		||||
	template bool repl_type::SetSetByName(const std::string &name); \
 | 
			
		||||
	template bool repl_type::SetSetByShortname(uint32_t shortname); \
 | 
			
		||||
	template char *repl_type::GetSetsList(char *p, const char *last); \
 | 
			
		||||
	template int repl_type::GetNumSets(); \
 | 
			
		||||
	template int repl_type::GetIndexOfUsedSet(); \
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,6 @@ public:
 | 
			
		||||
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 | 
			
		||||
 | 
			
		||||
	const char *GetName() override { return "32bpp-anim"; }
 | 
			
		||||
	int GetBytesPerPixel() override { return 6; }
 | 
			
		||||
	void PostResize() override;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@ public:
 | 
			
		||||
	size_t BufferSize(uint width, uint height) override;
 | 
			
		||||
	void PaletteAnimate(const Palette &palette) override;
 | 
			
		||||
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 | 
			
		||||
	int GetBytesPerPixel() override { return 4; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Look up the colour in the current palette.
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@ public:
 | 
			
		||||
	bool NeedsAnimationBuffer() override;
 | 
			
		||||
 | 
			
		||||
	const char *GetName()  override { return "40bpp-anim"; }
 | 
			
		||||
	int GetBytesPerPixel()  override { return 5; }
 | 
			
		||||
 | 
			
		||||
	template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,6 @@ public:
 | 
			
		||||
	size_t BufferSize(uint width, uint height) override;
 | 
			
		||||
	void PaletteAnimate(const Palette &palette) override;
 | 
			
		||||
	Blitter::PaletteAnimation UsePaletteAnimation() override;
 | 
			
		||||
	int GetBytesPerPixel() override { return 1; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* BLITTER_8BPP_BASE_HPP */
 | 
			
		||||
 
 | 
			
		||||
@@ -270,11 +270,6 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	virtual const char *GetName() = 0;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get how many bytes are needed to store a pixel.
 | 
			
		||||
	 */
 | 
			
		||||
	virtual int GetBytesPerPixel() = 0;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Post resize event
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,6 @@ public:
 | 
			
		||||
	Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; };
 | 
			
		||||
 | 
			
		||||
	const char *GetName() override { return "null"; }
 | 
			
		||||
	int GetBytesPerPixel() override { return 0; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Factory for the blitter that does nothing. */
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ static const struct NWidgetPart _background_widgets[] = {
 | 
			
		||||
/**
 | 
			
		||||
 * Window description for the background window to prevent smearing.
 | 
			
		||||
 */
 | 
			
		||||
static WindowDesc _background_desc(
 | 
			
		||||
static WindowDesc _background_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_BOOTSTRAP, WC_NONE,
 | 
			
		||||
	WDF_NO_CLOSE,
 | 
			
		||||
@@ -75,7 +75,7 @@ static const NWidgetPart _nested_bootstrap_errmsg_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description for the error window. */
 | 
			
		||||
static WindowDesc _bootstrap_errmsg_desc(
 | 
			
		||||
static WindowDesc _bootstrap_errmsg_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_BOOTSTRAP, WC_NONE,
 | 
			
		||||
	WDF_MODAL | WDF_NO_CLOSE,
 | 
			
		||||
@@ -132,7 +132,7 @@ static const NWidgetPart _nested_bootstrap_download_status_window_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description for the download window */
 | 
			
		||||
static WindowDesc _bootstrap_download_status_window_desc(
 | 
			
		||||
static WindowDesc _bootstrap_download_status_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_STATUS_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_MODAL | WDF_NO_CLOSE,
 | 
			
		||||
@@ -184,7 +184,7 @@ static const NWidgetPart _bootstrap_query_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** The window description for the query. */
 | 
			
		||||
static WindowDesc _bootstrap_query_desc(
 | 
			
		||||
static WindowDesc _bootstrap_query_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_CONFIRM_POPUP_QUERY, WC_NONE,
 | 
			
		||||
	WDF_NO_CLOSE,
 | 
			
		||||
 
 | 
			
		||||
@@ -356,7 +356,7 @@ static const NWidgetPart _nested_build_bridge_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition for the rail bridge selection window. */
 | 
			
		||||
static WindowDesc _build_bridge_desc(
 | 
			
		||||
static WindowDesc _build_bridge_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "build_bridge", 200, 114,
 | 
			
		||||
	WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -3263,7 +3263,7 @@ void CcMoveNewVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1
 | 
			
		||||
	InvalidateWindowClassesData(WC_CREATE_TEMPLATE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_vehicle_desc(
 | 
			
		||||
static WindowDesc _build_vehicle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "build_vehicle", 240, 268,
 | 
			
		||||
	WC_BUILD_VEHICLE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3271,7 +3271,7 @@ static WindowDesc _build_vehicle_desc(
 | 
			
		||||
	&BuildVehicleWindow::hotkeys
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_template_vehicle_desc(
 | 
			
		||||
static WindowDesc _build_template_vehicle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 240, 268,
 | 
			
		||||
	WC_BUILD_VIRTUAL_TRAIN, WC_CREATE_TEMPLATE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3279,7 +3279,7 @@ static WindowDesc _build_template_vehicle_desc(
 | 
			
		||||
	&BuildVehicleWindow::hotkeys, &_build_vehicle_desc
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_vehicle_desc_train_advanced(
 | 
			
		||||
static WindowDesc _build_vehicle_desc_train_advanced(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "build_vehicle_dual", 480, 268,
 | 
			
		||||
	WC_BUILD_VEHICLE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3287,7 +3287,7 @@ static WindowDesc _build_vehicle_desc_train_advanced(
 | 
			
		||||
	&BuildVehicleWindow::hotkeys
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_template_vehicle_desc_advanced(
 | 
			
		||||
static WindowDesc _build_template_vehicle_desc_advanced(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 480, 268,
 | 
			
		||||
	WC_BUILD_VIRTUAL_TRAIN, WC_CREATE_TEMPLATE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -520,7 +520,7 @@ struct CheatWindow : Window {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description of the cheats GUI. */
 | 
			
		||||
static WindowDesc _cheats_desc(
 | 
			
		||||
static WindowDesc _cheats_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "cheats", 0, 0,
 | 
			
		||||
	WC_CHEATS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ static void DoSelectCompanyManagerFace(Window *parent);
 | 
			
		||||
static void ShowCompanyInfrastructure(CompanyID company);
 | 
			
		||||
 | 
			
		||||
/** List of revenues. */
 | 
			
		||||
static ExpensesType _expenses_list_revenue[] = {
 | 
			
		||||
static const std::initializer_list<ExpensesType> _expenses_list_revenue = {
 | 
			
		||||
	EXPENSES_TRAIN_REVENUE,
 | 
			
		||||
	EXPENSES_ROADVEH_REVENUE,
 | 
			
		||||
	EXPENSES_AIRCRAFT_REVENUE,
 | 
			
		||||
@@ -61,7 +61,7 @@ static ExpensesType _expenses_list_revenue[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** List of operating expenses. */
 | 
			
		||||
static ExpensesType _expenses_list_operating_costs[] = {
 | 
			
		||||
static const std::initializer_list<ExpensesType> _expenses_list_operating_costs = {
 | 
			
		||||
	EXPENSES_TRAIN_RUN,
 | 
			
		||||
	EXPENSES_ROADVEH_RUN,
 | 
			
		||||
	EXPENSES_AIRCRAFT_RUN,
 | 
			
		||||
@@ -72,7 +72,7 @@ static ExpensesType _expenses_list_operating_costs[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** List of capital expenses. */
 | 
			
		||||
static ExpensesType _expenses_list_capital_costs[] = {
 | 
			
		||||
static const std::initializer_list<ExpensesType> _expenses_list_capital_costs = {
 | 
			
		||||
	EXPENSES_CONSTRUCTION,
 | 
			
		||||
	EXPENSES_NEW_VEHICLES,
 | 
			
		||||
	EXPENSES_OTHER,
 | 
			
		||||
@@ -80,25 +80,24 @@ static ExpensesType _expenses_list_capital_costs[] = {
 | 
			
		||||
 | 
			
		||||
/** Expense list container. */
 | 
			
		||||
struct ExpensesList {
 | 
			
		||||
	const ExpensesType *et;   ///< Expenses items.
 | 
			
		||||
	const uint length;        ///< Number of items in list.
 | 
			
		||||
	const StringID title; ///< StringID of list title.
 | 
			
		||||
	const std::initializer_list<ExpensesType> &items; ///< List of expenses types.
 | 
			
		||||
 | 
			
		||||
	ExpensesList(ExpensesType *et, int length) : et(et), length(length)
 | 
			
		||||
	ExpensesList(StringID title, const std::initializer_list<ExpensesType> &list) : title(title), items(list)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint GetHeight() const
 | 
			
		||||
	{
 | 
			
		||||
		/* Add up the height of all the lines.  */
 | 
			
		||||
		return this->length * FONT_HEIGHT_NORMAL;
 | 
			
		||||
		return static_cast<uint>(this->items.size()) * FONT_HEIGHT_NORMAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Compute width of the expenses categories in pixels. */
 | 
			
		||||
	uint GetListWidth() const
 | 
			
		||||
	{
 | 
			
		||||
		uint width = 0;
 | 
			
		||||
		for (uint i = 0; i < this->length; i++) {
 | 
			
		||||
			ExpensesType et = this->et[i];
 | 
			
		||||
		for (const ExpensesType &et : this->items) {
 | 
			
		||||
			width = std::max(width, GetStringBoundingBox(STR_FINANCES_SECTION_CONSTRUCTION + et).width);
 | 
			
		||||
		}
 | 
			
		||||
		return width;
 | 
			
		||||
@@ -106,10 +105,10 @@ struct ExpensesList {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Types of expense lists */
 | 
			
		||||
static const ExpensesList _expenses_list_types[] = {
 | 
			
		||||
	ExpensesList(_expenses_list_revenue, lengthof(_expenses_list_revenue)),
 | 
			
		||||
	ExpensesList(_expenses_list_operating_costs, lengthof(_expenses_list_operating_costs)),
 | 
			
		||||
	ExpensesList(_expenses_list_capital_costs, lengthof(_expenses_list_capital_costs)),
 | 
			
		||||
static const std::initializer_list<ExpensesList> _expenses_list_types = {
 | 
			
		||||
	{ STR_FINANCES_REVENUE_TITLE,            _expenses_list_revenue },
 | 
			
		||||
	{ STR_FINANCES_OPERATING_EXPENSES_TITLE, _expenses_list_operating_costs },
 | 
			
		||||
	{ STR_FINANCES_CAPITAL_EXPENSES_TITLE,   _expenses_list_capital_costs },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -121,9 +120,9 @@ static uint GetTotalCategoriesHeight()
 | 
			
		||||
	/* There's an empty line and blockspace on the year row */
 | 
			
		||||
	uint total_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
 | 
			
		||||
	for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
 | 
			
		||||
	for (const ExpensesList &list : _expenses_list_types) {
 | 
			
		||||
		/* Title + expense list + total line + total + blockspace after category */
 | 
			
		||||
		total_height += FONT_HEIGHT_NORMAL + _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
		total_height += FONT_HEIGHT_NORMAL + list.GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Total income */
 | 
			
		||||
@@ -141,11 +140,11 @@ static uint GetMaxCategoriesWidth()
 | 
			
		||||
	uint max_width = 0;
 | 
			
		||||
 | 
			
		||||
	/* Loop through categories to check max widths. */
 | 
			
		||||
	for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
 | 
			
		||||
	for (const ExpensesList &list : _expenses_list_types) {
 | 
			
		||||
		/* Title of category */
 | 
			
		||||
		max_width = std::max(max_width, GetStringBoundingBox(STR_FINANCES_REVENUE_TITLE + i).width);
 | 
			
		||||
		max_width = std::max(max_width, GetStringBoundingBox(list.title).width);
 | 
			
		||||
		/* Entries in category */
 | 
			
		||||
		max_width = std::max(max_width, _expenses_list_types[i].GetListWidth() + WidgetDimensions::scaled.hsep_indent);
 | 
			
		||||
		max_width = std::max(max_width, list.GetListWidth() + WidgetDimensions::scaled.hsep_indent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return max_width;
 | 
			
		||||
@@ -154,15 +153,13 @@ static uint GetMaxCategoriesWidth()
 | 
			
		||||
/**
 | 
			
		||||
 * Draw a category of expenses (revenue, operating expenses, capital expenses).
 | 
			
		||||
 */
 | 
			
		||||
static void DrawCategory(const Rect &r, int start_y, ExpensesList list)
 | 
			
		||||
static void DrawCategory(const Rect &r, int start_y, const ExpensesList &list)
 | 
			
		||||
{
 | 
			
		||||
	Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL);
 | 
			
		||||
 | 
			
		||||
	tr.top = start_y;
 | 
			
		||||
	ExpensesType et;
 | 
			
		||||
 | 
			
		||||
	for (uint i = 0; i < list.length; i++) {
 | 
			
		||||
		et = list.et[i];
 | 
			
		||||
	for (const ExpensesType &et : list.items) {
 | 
			
		||||
		DrawString(tr, STR_FINANCES_SECTION_CONSTRUCTION + et);
 | 
			
		||||
		tr.top += FONT_HEIGHT_NORMAL;
 | 
			
		||||
	}
 | 
			
		||||
@@ -178,14 +175,14 @@ static void DrawCategories(const Rect &r)
 | 
			
		||||
	/* Start with an empty space in the year row, plus the blockspace under the year. */
 | 
			
		||||
	int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
 | 
			
		||||
	for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
 | 
			
		||||
	for (const ExpensesList &list : _expenses_list_types) {
 | 
			
		||||
		/* Draw category title and advance y */
 | 
			
		||||
		DrawString(r.left, r.right, y, (STR_FINANCES_REVENUE_TITLE + i), TC_FROMSTRING, SA_LEFT);
 | 
			
		||||
		DrawString(r.left, r.right, y, list.title, TC_FROMSTRING, SA_LEFT);
 | 
			
		||||
		y += FONT_HEIGHT_NORMAL;
 | 
			
		||||
 | 
			
		||||
		/* Draw category items and advance y */
 | 
			
		||||
		DrawCategory(r, y, _expenses_list_types[i]);
 | 
			
		||||
		y += _expenses_list_types[i].GetHeight();
 | 
			
		||||
		DrawCategory(r, y, list);
 | 
			
		||||
		y += list.GetHeight();
 | 
			
		||||
 | 
			
		||||
		/* Advance y by the height of the horizontal line between amounts and subtotal */
 | 
			
		||||
		y += WidgetDimensions::scaled.vsep_normal;
 | 
			
		||||
@@ -228,14 +225,12 @@ static void DrawPrice(Money amount, int left, int right, int top, TextColour col
 | 
			
		||||
 * Draw a category of expenses/revenues in the year column.
 | 
			
		||||
 * @return The income sum of the category.
 | 
			
		||||
 */
 | 
			
		||||
static Money DrawYearCategory(const Rect &r, int start_y, ExpensesList list, const Expenses &tbl)
 | 
			
		||||
static Money DrawYearCategory(const Rect &r, int start_y, const ExpensesList &list, const Expenses &tbl)
 | 
			
		||||
{
 | 
			
		||||
	int y = start_y;
 | 
			
		||||
	ExpensesType et;
 | 
			
		||||
	Money sum = 0;
 | 
			
		||||
 | 
			
		||||
	for (uint i = 0; i < list.length; i++) {
 | 
			
		||||
		et = list.et[i];
 | 
			
		||||
	for (const ExpensesType &et : list.items) {
 | 
			
		||||
		Money cost = tbl[et];
 | 
			
		||||
		sum += cost;
 | 
			
		||||
		if (cost != 0) DrawPrice(cost, r.left, r.right, y, TC_BLACK);
 | 
			
		||||
@@ -270,11 +265,11 @@ static void DrawYearColumn(const Rect &r, int year, const Expenses &tbl)
 | 
			
		||||
	y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
 | 
			
		||||
	/* Categories */
 | 
			
		||||
	for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
 | 
			
		||||
	for (const ExpensesList &list : _expenses_list_types) {
 | 
			
		||||
		y += FONT_HEIGHT_NORMAL;
 | 
			
		||||
		sum += DrawYearCategory(r, y, _expenses_list_types[i], tbl);
 | 
			
		||||
		sum += DrawYearCategory(r, y, list, tbl);
 | 
			
		||||
		/* Expense list + expense category title + expense category total + blockspace after category */
 | 
			
		||||
		y += _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
		y += list.GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Total income. */
 | 
			
		||||
@@ -584,7 +579,7 @@ struct CompanyFinancesWindow : Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _company_finances_desc(
 | 
			
		||||
static WindowDesc _company_finances_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "company_finances", 0, 0,
 | 
			
		||||
	WC_FINANCES, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1180,7 +1175,7 @@ static const NWidgetPart _nested_select_company_livery_widgets [] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _select_company_livery_desc(
 | 
			
		||||
static WindowDesc _select_company_livery_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_COMPANY_COLOUR, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1797,7 +1792,7 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Company manager face selection window description */
 | 
			
		||||
static WindowDesc _select_company_manager_face_desc(
 | 
			
		||||
static WindowDesc _select_company_manager_face_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_COMPANY_MANAGER_FACE, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -2201,7 +2196,7 @@ struct CompanyInfrastructureWindow : Window
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _company_infrastructure_desc(
 | 
			
		||||
static WindowDesc _company_infrastructure_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "company_infrastructure", 0, 0,
 | 
			
		||||
	WC_COMPANY_INFRASTRUCTURE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -2849,7 +2844,7 @@ struct CompanyWindow : Window
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _company_desc(
 | 
			
		||||
static WindowDesc _company_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "company", 0, 0,
 | 
			
		||||
	WC_COMPANY, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -3002,7 +2997,7 @@ static const NWidgetPart _nested_buy_company_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _buy_company_desc(
 | 
			
		||||
static WindowDesc _buy_company_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_BUY_COMPANY, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,7 @@ static const struct NWidgetPart _nested_console_window_widgets[] = {
 | 
			
		||||
	NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_BACKGROUND), SetResize(1, 1),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _console_window_desc(
 | 
			
		||||
static WindowDesc _console_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_CONSOLE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -540,7 +540,7 @@ void IConsoleGUIPrint(TextColour colour_code, char *str)
 | 
			
		||||
 * all lines in the buffer are aged by one. When a line exceeds both the maximum position
 | 
			
		||||
 * and also the maximum age, it gets removed.
 | 
			
		||||
 * @return true if any lines were removed
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
static bool TruncateBuffer()
 | 
			
		||||
{
 | 
			
		||||
	bool need_truncation = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -427,7 +427,7 @@ static inline T ROR(const T x, const uint8 n)
 | 
			
		||||
 * Iterable ensemble of each set bit in a value.
 | 
			
		||||
 * @tparam Tbitpos Type of the position variable.
 | 
			
		||||
 * @tparam Tbitset Type of the bitset value.
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
template <typename Tbitpos = uint, typename Tbitset = uint>
 | 
			
		||||
struct SetBitIterator {
 | 
			
		||||
	struct Iterator {
 | 
			
		||||
 
 | 
			
		||||
@@ -449,14 +449,14 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Find all items contained within the given rectangle.
 | 
			
		||||
	* @note Start coordinates are inclusive, end coordinates are exclusive. x1<x2 && y1<y2 is a precondition.
 | 
			
		||||
	* @param x1 Start first coordinate, points found are greater or equals to this.
 | 
			
		||||
	* @param y1 Start second coordinate, points found are greater or equals to this.
 | 
			
		||||
	* @param x2 End first coordinate, points found are less than this.
 | 
			
		||||
	* @param y2 End second coordinate, points found are less than this.
 | 
			
		||||
	* @param outputter Callback used to return values from the search.
 | 
			
		||||
	*/
 | 
			
		||||
	 * Find all items contained within the given rectangle.
 | 
			
		||||
	 * @note Start coordinates are inclusive, end coordinates are exclusive. x1<x2 && y1<y2 is a precondition.
 | 
			
		||||
	 * @param x1 Start first coordinate, points found are greater or equals to this.
 | 
			
		||||
	 * @param y1 Start second coordinate, points found are greater or equals to this.
 | 
			
		||||
	 * @param x2 End first coordinate, points found are less than this.
 | 
			
		||||
	 * @param y2 End second coordinate, points found are less than this.
 | 
			
		||||
	 * @param outputter Callback used to return values from the search.
 | 
			
		||||
	 */
 | 
			
		||||
	template <typename Outputter>
 | 
			
		||||
	void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -339,14 +339,14 @@ static const NWidgetPart _nested_set_minutes_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Description of the date setting window. */
 | 
			
		||||
static WindowDesc _set_date_desc(
 | 
			
		||||
static WindowDesc _set_date_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_SET_DATE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_set_date_widgets), std::end(_nested_set_date_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _set_minutes_desc(
 | 
			
		||||
static WindowDesc _set_minutes_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_SET_DATE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,8 @@ static const Year ORIGINAL_MAX_YEAR  = 2090;
 | 
			
		||||
 */
 | 
			
		||||
#define DAYS_TILL_ORIGINAL_BASE_YEAR DAYS_TILL(ORIGINAL_BASE_YEAR)
 | 
			
		||||
 | 
			
		||||
static const Date MIN_DATE = 0;
 | 
			
		||||
 | 
			
		||||
/** The absolute minimum & maximum years in OTTD */
 | 
			
		||||
static const Year MIN_YEAR = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ static const NWidgetPart _nested_departures_list[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _departures_desc(
 | 
			
		||||
static WindowDesc _departures_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 260, 246,
 | 
			
		||||
	WC_DEPARTURES_BOARD, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -84,28 +84,28 @@ static const NWidgetPart _nested_train_depot_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _train_depot_desc(
 | 
			
		||||
static WindowDesc _train_depot_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "depot_train", 362, 123,
 | 
			
		||||
	WC_VEHICLE_DEPOT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _road_depot_desc(
 | 
			
		||||
static WindowDesc _road_depot_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "depot_roadveh", 316, 97,
 | 
			
		||||
	WC_VEHICLE_DEPOT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _ship_depot_desc(
 | 
			
		||||
static WindowDesc _ship_depot_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "depot_ship", 306, 99,
 | 
			
		||||
	WC_VEHICLE_DEPOT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _aircraft_depot_desc(
 | 
			
		||||
static WindowDesc _aircraft_depot_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "depot_aircraft", 332, 99,
 | 
			
		||||
	WC_VEHICLE_DEPOT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -347,7 +347,7 @@ static const NWidgetPart _nested_build_docks_toolbar_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_docks_toolbar_desc(
 | 
			
		||||
static WindowDesc _build_docks_toolbar_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_ALIGN_TOOLBAR, "toolbar_water", 0, 0,
 | 
			
		||||
	WC_BUILD_TOOLBAR, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -391,7 +391,7 @@ static const NWidgetPart _nested_build_docks_scen_toolbar_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition for the build docks in scenario editor window. */
 | 
			
		||||
static WindowDesc _build_docks_scen_toolbar_desc(
 | 
			
		||||
static WindowDesc _build_docks_scen_toolbar_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "toolbar_water_scen", 0, 0,
 | 
			
		||||
	WC_SCEN_BUILD_TOOLBAR, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -494,7 +494,7 @@ static const NWidgetPart _nested_build_dock_station_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_dock_station_desc(
 | 
			
		||||
static WindowDesc _build_dock_station_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_BUILD_STATION, WC_BUILD_TOOLBAR,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -581,21 +581,15 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = {
 | 
			
		||||
		NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_DEPOT_BUILD_SHIP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
	NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BDD_BACKGROUND),
 | 
			
		||||
		NWidget(NWID_SPACER), SetMinimalSize(0, 3),
 | 
			
		||||
		NWidget(NWID_HORIZONTAL_LTR),
 | 
			
		||||
			NWidget(NWID_SPACER), SetMinimalSize(3, 0),
 | 
			
		||||
			NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(NWID_SPACER), SetMinimalSize(2, 0),
 | 
			
		||||
			NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(NWID_SPACER), SetMinimalSize(3, 0),
 | 
			
		||||
		NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 1), SetPadding(WidgetDimensions::unscaled.picker),
 | 
			
		||||
			NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
 | 
			
		||||
			NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
 | 
			
		||||
		EndContainer(),
 | 
			
		||||
		NWidget(NWID_SPACER), SetMinimalSize(0, 3),
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_docks_depot_desc(
 | 
			
		||||
static WindowDesc _build_docks_depot_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -143,7 +143,7 @@ struct EnginePreviewWindow : Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _engine_preview_desc(
 | 
			
		||||
static WindowDesc _engine_preview_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_ENGINE_PREVIEW, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ static const NWidgetPart _nested_errmsg_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _errmsg_desc(
 | 
			
		||||
static WindowDesc _errmsg_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_ERRMSG, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -61,7 +61,7 @@ static const NWidgetPart _nested_errmsg_face_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _errmsg_face_desc(
 | 
			
		||||
static WindowDesc _errmsg_face_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_ERRMSG, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -739,7 +739,7 @@ void ScanScenarios()
 | 
			
		||||
/**
 | 
			
		||||
 * Constructs FiosNumberedSaveName. Initial number is the most recent save, or -1 if not found.
 | 
			
		||||
 * @param prefix The prefix to use to generate a filename.
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(prefix), number(-1)
 | 
			
		||||
{
 | 
			
		||||
	static std::optional<std::string> _autosave_path;
 | 
			
		||||
@@ -776,7 +776,7 @@ FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(p
 | 
			
		||||
/**
 | 
			
		||||
 * Generate a savegame name and number according to _settings_client.gui.max_num_autosaves.
 | 
			
		||||
 * @return A filename in format "<prefix><number>.sav".
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
std::string FiosNumberedSaveName::Filename()
 | 
			
		||||
{
 | 
			
		||||
	return this->FilenameUsingMaxSaves(_settings_client.gui.max_num_autosaves);
 | 
			
		||||
@@ -800,7 +800,7 @@ std::string FiosNumberedSaveName::FilenameUsingNumber(int num, const char *suffi
 | 
			
		||||
/**
 | 
			
		||||
 * Generate an extension for a savegame name.
 | 
			
		||||
 * @return An extension in format "-<prefix>.sav".
 | 
			
		||||
*/
 | 
			
		||||
 */
 | 
			
		||||
std::string FiosNumberedSaveName::Extension()
 | 
			
		||||
{
 | 
			
		||||
	return stdstr_fmt("-%s.sav", this->prefix.c_str());
 | 
			
		||||
 
 | 
			
		||||
@@ -930,7 +930,7 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Load game/scenario */
 | 
			
		||||
static WindowDesc _load_dialog_desc(
 | 
			
		||||
static WindowDesc _load_dialog_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "load_game", 500, 294,
 | 
			
		||||
	WC_SAVELOAD, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -938,7 +938,7 @@ static WindowDesc _load_dialog_desc(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/** Load heightmap */
 | 
			
		||||
static WindowDesc _load_heightmap_dialog_desc(
 | 
			
		||||
static WindowDesc _load_heightmap_dialog_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "load_heightmap", 257, 320,
 | 
			
		||||
	WC_SAVELOAD, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -946,7 +946,7 @@ static WindowDesc _load_heightmap_dialog_desc(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/** Save game/scenario */
 | 
			
		||||
static WindowDesc _save_dialog_desc(
 | 
			
		||||
static WindowDesc _save_dialog_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "save_game", 500, 294,
 | 
			
		||||
	WC_SAVELOAD, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*
 | 
			
		||||
* This file is part of OpenTTD.
 | 
			
		||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 * This file is part of OpenTTD.
 | 
			
		||||
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file framerate_gui.cpp GUI for displaying framerate/game speed information. */
 | 
			
		||||
 | 
			
		||||
@@ -724,7 +724,7 @@ struct FramerateWindow : Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _framerate_display_desc(
 | 
			
		||||
static WindowDesc _framerate_display_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "framerate_display", 0, 0,
 | 
			
		||||
	WC_FRAMERATE_DISPLAY, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -801,7 +801,7 @@ struct FrametimeGraphWindow : Window {
 | 
			
		||||
	void SelectHorizontalScale(TimingMeasurement range)
 | 
			
		||||
	{
 | 
			
		||||
		/* Determine horizontal scale based on period covered by 60 points
 | 
			
		||||
		* (slightly less than 2 seconds at full game speed) */
 | 
			
		||||
		 * (slightly less than 2 seconds at full game speed) */
 | 
			
		||||
		struct ScaleDef { TimingMeasurement range; int scale; };
 | 
			
		||||
		static const ScaleDef hscales[] = {
 | 
			
		||||
			{ 120, 60 },
 | 
			
		||||
@@ -1010,7 +1010,7 @@ struct FrametimeGraphWindow : Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _frametime_graph_window_desc(
 | 
			
		||||
static WindowDesc _frametime_graph_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "frametime_graph", 140, 90,
 | 
			
		||||
	WC_FRAMETIME_GRAPH, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*
 | 
			
		||||
* This file is part of OpenTTD.
 | 
			
		||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 * This file is part of OpenTTD.
 | 
			
		||||
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file framerate_type.h
 | 
			
		||||
 * Types for recording game performance data.
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ static const NWidgetPart _nested_gs_config_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition for the configure GS window. */
 | 
			
		||||
static WindowDesc _gs_config_desc(
 | 
			
		||||
static WindowDesc _gs_config_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "settings_gs_config", 500, 350,
 | 
			
		||||
	WC_GAME_OPTIONS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -1150,14 +1150,14 @@ struct GenerateLandscapeWindow : public Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _generate_landscape_desc(
 | 
			
		||||
static WindowDesc _generate_landscape_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_GENERATE_LANDSCAPE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_generate_landscape_widgets), std::end(_nested_generate_landscape_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _heightmap_load_desc(
 | 
			
		||||
static WindowDesc _heightmap_load_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_GENERATE_LANDSCAPE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1460,7 +1460,7 @@ static const NWidgetPart _nested_create_scenario_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _create_scenario_desc(
 | 
			
		||||
static WindowDesc _create_scenario_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_GENERATE_LANDSCAPE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1486,7 +1486,7 @@ static const NWidgetPart _nested_generate_progress_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static WindowDesc _generate_progress_desc(
 | 
			
		||||
static WindowDesc _generate_progress_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_MODAL_PROGRESS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -260,18 +260,8 @@ static void LoadSpriteTables()
 | 
			
		||||
	ClrBit(master->flags, GCF_INIT_ONLY);
 | 
			
		||||
 | 
			
		||||
	/* Baseset extra graphics */
 | 
			
		||||
	GRFConfig *extra = new GRFConfig(used_set->files[GFT_EXTRA].filename.c_str());
 | 
			
		||||
 | 
			
		||||
	/* We know the palette of the base set, so if the base NewGRF is not
 | 
			
		||||
	 * setting one, use the palette of the base set and not the global
 | 
			
		||||
	 * one which might be the wrong palette for this base NewGRF.
 | 
			
		||||
	 * The value set here might be overridden via action14 later. */
 | 
			
		||||
	switch (used_set->palette) {
 | 
			
		||||
		case PAL_DOS:     extra->palette |= GRFP_GRF_DOS;     break;
 | 
			
		||||
		case PAL_WINDOWS: extra->palette |= GRFP_GRF_WINDOWS; break;
 | 
			
		||||
		default: break;
 | 
			
		||||
	}
 | 
			
		||||
	FillGRFDetails(extra, false, BASESET_DIR);
 | 
			
		||||
	GRFConfig *extra = new GRFConfig(used_set->GetOrCreateExtraConfig());
 | 
			
		||||
	if (extra->num_params == 0) extra->SetParameterDefaults();
 | 
			
		||||
	ClrBit(extra->flags, GCF_INIT_ONLY);
 | 
			
		||||
 | 
			
		||||
	extra->next = top;
 | 
			
		||||
@@ -546,6 +536,17 @@ void GfxLoadSprites()
 | 
			
		||||
	DEBUG(sprite, 2, "Completed loading sprite set %d", _settings_game.game_creation.landscape);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GraphicsSet::GraphicsSet()
 | 
			
		||||
	: BaseSet<GraphicsSet, MAX_GFT, true>{}, palette{}, blitter{}
 | 
			
		||||
{
 | 
			
		||||
	// instantiate here, because unique_ptr needs a complete type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GraphicsSet::~GraphicsSet()
 | 
			
		||||
{
 | 
			
		||||
	// instantiate here, because unique_ptr needs a complete type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GraphicsSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename)
 | 
			
		||||
{
 | 
			
		||||
	bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false);
 | 
			
		||||
@@ -564,6 +565,46 @@ bool GraphicsSet::FillSetDetails(const IniFile &ini, const std::string &path, co
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return configuration for the extra GRF, or lazily create it.
 | 
			
		||||
 * @return NewGRF configuration
 | 
			
		||||
 */
 | 
			
		||||
GRFConfig &GraphicsSet::GetOrCreateExtraConfig() const
 | 
			
		||||
{
 | 
			
		||||
	if (!this->extra_cfg) {
 | 
			
		||||
		this->extra_cfg.reset(new GRFConfig(this->files[GFT_EXTRA].filename));
 | 
			
		||||
 | 
			
		||||
		/* We know the palette of the base set, so if the base NewGRF is not
 | 
			
		||||
		 * setting one, use the palette of the base set and not the global
 | 
			
		||||
		 * one which might be the wrong palette for this base NewGRF.
 | 
			
		||||
		 * The value set here might be overridden via action14 later. */
 | 
			
		||||
		switch (this->palette) {
 | 
			
		||||
			case PAL_DOS:     this->extra_cfg->palette |= GRFP_GRF_DOS;     break;
 | 
			
		||||
			case PAL_WINDOWS: this->extra_cfg->palette |= GRFP_GRF_WINDOWS; break;
 | 
			
		||||
			default: break;
 | 
			
		||||
		}
 | 
			
		||||
		FillGRFDetails(this->extra_cfg.get(), false, BASESET_DIR);
 | 
			
		||||
	}
 | 
			
		||||
	return *this->extra_cfg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GraphicsSet::IsConfigurable() const
 | 
			
		||||
{
 | 
			
		||||
	const GRFConfig &cfg = this->GetOrCreateExtraConfig();
 | 
			
		||||
	/* This check is more strict than the one for NewGRF Settings.
 | 
			
		||||
	 * There are no legacy basesets with parameters, but without Action14 */
 | 
			
		||||
	return !cfg.param_info.empty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsSet::CopyCompatibleConfig(const GraphicsSet &src)
 | 
			
		||||
{
 | 
			
		||||
	const GRFConfig *src_cfg = src.GetExtraConfig();
 | 
			
		||||
	if (src_cfg == nullptr || src_cfg->num_params == 0) return;
 | 
			
		||||
	GRFConfig &dest_cfg = this->GetOrCreateExtraConfig();
 | 
			
		||||
	if (dest_cfg.IsCompatible(src_cfg->version)) return;
 | 
			
		||||
	dest_cfg.CopyParams(*src_cfg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calculate and check the MD5 hash of the supplied GRF.
 | 
			
		||||
 * @param file The file get the hash of.
 | 
			
		||||
 
 | 
			
		||||
@@ -302,7 +302,7 @@ static const NWidgetPart _nested_goals_list_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _goals_list_desc(
 | 
			
		||||
static WindowDesc _goals_list_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_goals", 500, 127,
 | 
			
		||||
	WC_GOALS_LIST, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -512,24 +512,28 @@ static const NWidgetPart _nested_goal_question_widgets_error[] = {
 | 
			
		||||
 | 
			
		||||
static WindowDesc _goal_question_list_desc[] = {
 | 
			
		||||
	{
 | 
			
		||||
		__FILE__, __LINE__,
 | 
			
		||||
		WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
		WC_GOAL_QUESTION, WC_NONE,
 | 
			
		||||
		WDF_CONSTRUCTION,
 | 
			
		||||
		std::begin(_nested_goal_question_widgets_question), std::end(_nested_goal_question_widgets_question),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		__FILE__, __LINE__,
 | 
			
		||||
		WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
		WC_GOAL_QUESTION, WC_NONE,
 | 
			
		||||
		WDF_CONSTRUCTION,
 | 
			
		||||
		std::begin(_nested_goal_question_widgets_info), std::end(_nested_goal_question_widgets_info),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		__FILE__, __LINE__,
 | 
			
		||||
		WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
		WC_GOAL_QUESTION, WC_NONE,
 | 
			
		||||
		WDF_CONSTRUCTION,
 | 
			
		||||
		std::begin(_nested_goal_question_widgets_warning), std::end(_nested_goal_question_widgets_warning),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		__FILE__, __LINE__,
 | 
			
		||||
		WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
		WC_GOAL_QUESTION, WC_NONE,
 | 
			
		||||
		WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,7 @@ static const NWidgetPart _nested_graph_legend_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _graph_legend_desc(
 | 
			
		||||
static WindowDesc _graph_legend_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_legend", 0, 0,
 | 
			
		||||
	WC_GRAPH_LEGEND, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -674,7 +674,7 @@ static const NWidgetPart _nested_operating_profit_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _operating_profit_desc(
 | 
			
		||||
static WindowDesc _operating_profit_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_operating_profit", 0, 0,
 | 
			
		||||
	WC_OPERATING_PROFIT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -725,7 +725,7 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _income_graph_desc(
 | 
			
		||||
static WindowDesc _income_graph_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_income", 0, 0,
 | 
			
		||||
	WC_INCOME_GRAPH, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1032,7 +1032,7 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _delivered_cargo_graph_desc(
 | 
			
		||||
static WindowDesc _delivered_cargo_graph_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_delivered_cargo", 0, 0,
 | 
			
		||||
	WC_DELIVERED_CARGO, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1088,7 +1088,7 @@ static const NWidgetPart _nested_performance_history_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _performance_history_desc(
 | 
			
		||||
static WindowDesc _performance_history_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_performance", 0, 0,
 | 
			
		||||
	WC_PERFORMANCE_HISTORY, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1137,7 +1137,7 @@ static const NWidgetPart _nested_company_value_graph_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _company_value_graph_desc(
 | 
			
		||||
static WindowDesc _company_value_graph_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_company_value", 0, 0,
 | 
			
		||||
	WC_COMPANY_VALUE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1485,7 +1485,7 @@ static const NWidgetPart _nested_cargo_payment_rates_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _cargo_payment_rates_desc(
 | 
			
		||||
static WindowDesc _cargo_payment_rates_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_cargo_payment_rates", 0, 0,
 | 
			
		||||
	WC_PAYMENT_RATES, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1781,7 +1781,7 @@ static const NWidgetPart _nested_performance_rating_detail_widgets[] = {
 | 
			
		||||
	NWidgetFunction(MakePerformanceDetailPanels),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _performance_rating_detail_desc(
 | 
			
		||||
static WindowDesc _performance_rating_detail_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "league_details", 0, 0,
 | 
			
		||||
	WC_PERFORMANCE_DETAIL, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -2055,7 +2055,7 @@ static const NWidgetPart _nested_station_cargo_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _station_cargo_desc(
 | 
			
		||||
static WindowDesc _station_cargo_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "graph_station_cargo", 0, 0,
 | 
			
		||||
	WC_STATION_CARGO, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,6 @@ Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType
 | 
			
		||||
 | 
			
		||||
void SetTrainGroupID(Train *v, GroupID grp);
 | 
			
		||||
void UpdateTrainGroupID(Train *v);
 | 
			
		||||
void RemoveVehicleFromGroup(const Vehicle *v);
 | 
			
		||||
void RemoveAllGroupsForCompany(const CompanyID company);
 | 
			
		||||
bool GroupIsInGroup(GroupID search, GroupID group);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -912,19 +912,6 @@ CommandCost CmdSetGroupFlag(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
 | 
			
		||||
	return CommandCost();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decrease the num_vehicle variable before delete an front engine from a group
 | 
			
		||||
 * @note Called in CmdSellRailWagon and DeleteLasWagon,
 | 
			
		||||
 * @param v     FrontEngine of the train we want to remove.
 | 
			
		||||
 */
 | 
			
		||||
void RemoveVehicleFromGroup(const Vehicle *v)
 | 
			
		||||
{
 | 
			
		||||
	if (!v->IsPrimaryVehicle()) return;
 | 
			
		||||
 | 
			
		||||
	if (!IsDefaultGroupID(v->group_id)) GroupStatistics::CountVehicle(v, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Affect the groupID of a train to new_g.
 | 
			
		||||
 * @note called in CmdAddVehicleGroup and CmdMoveRailVehicle
 | 
			
		||||
 
 | 
			
		||||
@@ -1245,14 +1245,14 @@ public:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static WindowDesc _other_group_desc(
 | 
			
		||||
static WindowDesc _other_group_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_groups", 460, 246,
 | 
			
		||||
	WC_INVALID, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_group_widgets), std::end(_nested_group_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _train_group_desc(
 | 
			
		||||
static WindowDesc _train_group_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_groups_train", 525, 246,
 | 
			
		||||
	WC_TRAINS_LIST, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -205,7 +205,7 @@ static const NWidgetPart _nested_helpwin_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _helpwin_desc(
 | 
			
		||||
static WindowDesc _helpwin_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_HELPWIN, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -211,14 +211,14 @@ static const NWidgetPart _nested_highscore_widgets[] = {
 | 
			
		||||
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_H_BACKGROUND), SetResize(1, 1), EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _highscore_desc(
 | 
			
		||||
static WindowDesc _highscore_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_HIGHSCORE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_highscore_widgets), std::end(_nested_highscore_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _endgame_desc(
 | 
			
		||||
static WindowDesc _endgame_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_ENDSCREEN, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -132,23 +132,27 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
 | 
			
		||||
		return pos - this->accepts_cargo;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Test if this industry accepts any cargo.
 | 
			
		||||
	/**
 | 
			
		||||
	 * Test if this industry accepts any cargo.
 | 
			
		||||
	 * @return true iff the industry accepts any cargo.
 | 
			
		||||
	 */
 | 
			
		||||
	bool IsCargoAccepted() const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
 | 
			
		||||
 | 
			
		||||
	/** Test if this industry produces any cargo.
 | 
			
		||||
	/**
 | 
			
		||||
	 * Test if this industry produces any cargo.
 | 
			
		||||
	 * @return true iff the industry produces any cargo.
 | 
			
		||||
	 */
 | 
			
		||||
	bool IsCargoProduced() const { return std::any_of(std::begin(this->produced_cargo), std::end(this->produced_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
 | 
			
		||||
 | 
			
		||||
	/** Test if this industry accepts a specific cargo.
 | 
			
		||||
	/**
 | 
			
		||||
	 * Test if this industry accepts a specific cargo.
 | 
			
		||||
	 * @param cargo Cargo type to test.
 | 
			
		||||
	 * @return true iff the industry accepts the given cargo type.
 | 
			
		||||
	 */
 | 
			
		||||
	bool IsCargoAccepted(CargoID cargo) const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [&cargo](const auto &cid) { return cid == cargo; }); }
 | 
			
		||||
 | 
			
		||||
	/** Test if this industry produces a specific cargo.
 | 
			
		||||
	/**
 | 
			
		||||
	 * Test if this industry produces a specific cargo.
 | 
			
		||||
	 * @param cargo Cargo type to test.
 | 
			
		||||
	 * @return true iff the industry produces the given cargo types.
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -293,7 +293,7 @@ static const NWidgetPart _nested_build_industry_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition of the dynamic place industries gui */
 | 
			
		||||
static WindowDesc _build_industry_desc(
 | 
			
		||||
static WindowDesc _build_industry_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "build_industry", 170, 212,
 | 
			
		||||
	WC_BUILD_INDUSTRY, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -1205,7 +1205,7 @@ static const NWidgetPart _nested_industry_view_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition of the view industry gui */
 | 
			
		||||
static WindowDesc _industry_view_desc(
 | 
			
		||||
static WindowDesc _industry_view_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_industry", 260, 120,
 | 
			
		||||
	WC_INDUSTRY_VIEW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1228,24 +1228,24 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
	NWidget(NWID_HORIZONTAL),
 | 
			
		||||
		NWidget(NWID_VERTICAL),
 | 
			
		||||
			NWidget(NWID_VERTICAL),
 | 
			
		||||
				NWidget(NWID_HORIZONTAL),
 | 
			
		||||
					NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
 | 
			
		||||
					NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
 | 
			
		||||
					NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_ID_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
 | 
			
		||||
				EndContainer(),
 | 
			
		||||
				NWidget(NWID_HORIZONTAL),
 | 
			
		||||
					NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
 | 
			
		||||
					NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
 | 
			
		||||
					NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
 | 
			
		||||
				EndContainer(),
 | 
			
		||||
			NWidget(NWID_HORIZONTAL),
 | 
			
		||||
				NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
 | 
			
		||||
				NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
 | 
			
		||||
				NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_ID_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(NWID_HORIZONTAL),
 | 
			
		||||
				NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
 | 
			
		||||
				NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
 | 
			
		||||
				NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_VSCROLLBAR),
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_SCROLLBAR), EndContainer(),
 | 
			
		||||
		EndContainer(),
 | 
			
		||||
		NWidget(NWID_VERTICAL),
 | 
			
		||||
			NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_ID_SCROLLBAR),
 | 
			
		||||
			NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
 | 
			
		||||
		EndContainer(),
 | 
			
		||||
		NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_ID_VSCROLLBAR),
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
	NWidget(NWID_HORIZONTAL),
 | 
			
		||||
		NWidget(NWID_HSCROLLBAR, COLOUR_BROWN, WID_ID_HSCROLLBAR),
 | 
			
		||||
		NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -1321,6 +1321,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
	GUIIndustryList industries;
 | 
			
		||||
	Scrollbar *vscroll;
 | 
			
		||||
	Scrollbar *hscroll;
 | 
			
		||||
 | 
			
		||||
	CargoID cargo_filter[NUM_CARGO + 2];        ///< Available cargo filters; CargoID or CF_ANY or CF_NONE
 | 
			
		||||
	StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID
 | 
			
		||||
@@ -1409,6 +1410,19 @@ protected:
 | 
			
		||||
		this->industries.SetFilterState(is_filtering_necessary);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the width needed to draw the longest industry line.
 | 
			
		||||
	 * @return Returns width of the longest industry line, including padding.
 | 
			
		||||
	 */
 | 
			
		||||
	uint GetIndustryListWidth() const
 | 
			
		||||
	{
 | 
			
		||||
		uint width = 0;
 | 
			
		||||
		for (const Industry *i : this->industries) {
 | 
			
		||||
			width = std::max(width, GetStringBoundingBox(this->GetIndustryString(i)).width);
 | 
			
		||||
		}
 | 
			
		||||
		return width + WidgetDimensions::scaled.framerect.Horizontal();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** (Re)Build industries list */
 | 
			
		||||
	void BuildSortIndustriesList()
 | 
			
		||||
	{
 | 
			
		||||
@@ -1427,18 +1441,19 @@ protected:
 | 
			
		||||
 | 
			
		||||
			this->industries.shrink_to_fit();
 | 
			
		||||
			this->industries.RebuildDone();
 | 
			
		||||
 | 
			
		||||
			auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria],
 | 
			
		||||
										this->cargo_filter[this->produced_cargo_filter_criteria]);
 | 
			
		||||
 | 
			
		||||
			this->industries.Filter(filter);
 | 
			
		||||
 | 
			
		||||
			this->hscroll->SetCount(this->GetIndustryListWidth());
 | 
			
		||||
			this->vscroll->SetCount(this->industries.size()); // Update scrollbar as well.
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria],
 | 
			
		||||
		                             this->cargo_filter[this->produced_cargo_filter_criteria]);
 | 
			
		||||
 | 
			
		||||
		this->industries.Filter(filter);
 | 
			
		||||
 | 
			
		||||
		IndustryDirectoryWindow::produced_cargo_filter = this->cargo_filter[this->produced_cargo_filter_criteria];
 | 
			
		||||
		this->industries.Sort();
 | 
			
		||||
 | 
			
		||||
		this->vscroll->SetCount(this->industries.size()); // Update scrollbar as well.
 | 
			
		||||
 | 
			
		||||
		this->SetDirty();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1625,7 +1640,8 @@ public:
 | 
			
		||||
	IndustryDirectoryWindow(WindowDesc *desc, WindowNumber) : Window(desc), industry_editbox(MAX_FILTER_LENGTH * MAX_CHAR_LENGTH, MAX_FILTER_LENGTH)
 | 
			
		||||
	{
 | 
			
		||||
		this->CreateNestedTree();
 | 
			
		||||
		this->vscroll = this->GetScrollbar(WID_ID_SCROLLBAR);
 | 
			
		||||
		this->vscroll = this->GetScrollbar(WID_ID_VSCROLLBAR);
 | 
			
		||||
		this->hscroll = this->GetScrollbar(WID_ID_HSCROLLBAR);
 | 
			
		||||
 | 
			
		||||
		this->industries.SetListing(this->last_sorting);
 | 
			
		||||
		this->industries.SetSortFuncs(IndustryDirectoryWindow::sorter_funcs);
 | 
			
		||||
@@ -1675,16 +1691,28 @@ public:
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case WID_ID_INDUSTRY_LIST: {
 | 
			
		||||
				int n = 0;
 | 
			
		||||
				Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
 | 
			
		||||
 | 
			
		||||
				/* Setup a clipping rectangle... */
 | 
			
		||||
				DrawPixelInfo tmp_dpi;
 | 
			
		||||
				if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return;
 | 
			
		||||
				/* ...but keep coordinates relative to the window. */
 | 
			
		||||
				tmp_dpi.left += ir.left;
 | 
			
		||||
				tmp_dpi.top += ir.top;
 | 
			
		||||
 | 
			
		||||
				AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
 | 
			
		||||
 | 
			
		||||
				ir.left -= this->hscroll->GetPosition();
 | 
			
		||||
				ir.right += this->hscroll->GetCapacity() - this->hscroll->GetPosition();
 | 
			
		||||
 | 
			
		||||
				if (this->industries.empty()) {
 | 
			
		||||
					DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				TextColour tc;
 | 
			
		||||
				int n = 0;
 | 
			
		||||
				const CargoID acf_cid = this->cargo_filter[this->accepted_cargo_filter_criteria];
 | 
			
		||||
				for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) {
 | 
			
		||||
					tc = TC_FROMSTRING;
 | 
			
		||||
					TextColour tc = TC_FROMSTRING;
 | 
			
		||||
					if (acf_cid != CF_ANY && acf_cid != CF_NONE) {
 | 
			
		||||
						Industry *ind = const_cast<Industry *>(this->industries[i]);
 | 
			
		||||
						if (IndustryTemporarilyRefusesCargo(ind, acf_cid)) {
 | 
			
		||||
@@ -1725,9 +1753,6 @@ public:
 | 
			
		||||
 | 
			
		||||
			case WID_ID_INDUSTRY_LIST: {
 | 
			
		||||
				Dimension d = GetStringBoundingBox(STR_INDUSTRY_DIRECTORY_NONE);
 | 
			
		||||
				for (uint i = 0; i < this->industries.size(); i++) {
 | 
			
		||||
					d = maxdim(d, GetStringBoundingBox(this->GetIndustryString(this->industries[i])));
 | 
			
		||||
				}
 | 
			
		||||
				resize->height = d.height;
 | 
			
		||||
				d.height *= 5;
 | 
			
		||||
				d.width += padding.width;
 | 
			
		||||
@@ -1801,6 +1826,7 @@ public:
 | 
			
		||||
	void OnResize() override
 | 
			
		||||
	{
 | 
			
		||||
		this->vscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST);
 | 
			
		||||
		this->hscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void OnEditboxChanged(int wid) override
 | 
			
		||||
@@ -1870,7 +1896,7 @@ CargoID IndustryDirectoryWindow::produced_cargo_filter = CF_ANY;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Window definition of the industry directory gui */
 | 
			
		||||
static WindowDesc _industry_directory_desc(
 | 
			
		||||
static WindowDesc _industry_directory_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_industries", 428, 190,
 | 
			
		||||
	WC_INDUSTRY_DIRECTORY, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1913,7 +1939,7 @@ static const NWidgetPart _nested_industry_cargoes_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description for the industry cargoes window. */
 | 
			
		||||
static WindowDesc _industry_cargoes_desc(
 | 
			
		||||
static WindowDesc _industry_cargoes_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "industry_cargoes", 300, 210,
 | 
			
		||||
	WC_INDUSTRY_CARGOES, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -496,7 +496,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _select_game_desc(
 | 
			
		||||
static WindowDesc _select_game_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_SELECT_GAME, WC_NONE,
 | 
			
		||||
	WDF_NO_CLOSE,
 | 
			
		||||
 
 | 
			
		||||
@@ -3385,6 +3385,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Salvar
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Salva o padrão com o nome selecionado
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Alterar parâmetros dos gráficos base
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Alterar parâmetros NewGRF
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Fechar
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Redefinir parâmetros
 | 
			
		||||
@@ -5189,6 +5190,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Impossí
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Veículos só podem aguardar em estações
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Esse veículo não pára nesta estação
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... horário incompleto
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... o plano de horário ainda não começou
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... existem placas demais
 | 
			
		||||
 
 | 
			
		||||
@@ -3384,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Gem
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Gem forudindstilling til det valgte navn
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Skift grundlæggende grafiske parametre
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Ændre NewGRF parameterne
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Luk
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Nulstil
 | 
			
		||||
 
 | 
			
		||||
@@ -533,6 +533,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD                                    :Over 'OpenTTD'
 | 
			
		||||
STR_ABOUT_MENU_SPRITE_ALIGNER                                   :Sprite-uitlijner
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES                            :Selectiekaders in-uitschakelen
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS                              :Kleuren van vuile blokken in-uitschakelen
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES                           :Widgetkaders in-uitschakelen
 | 
			
		||||
 | 
			
		||||
# Place in highscore window
 | 
			
		||||
###length 15
 | 
			
		||||
@@ -3383,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Opslaan
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Sla de huidige voorkeursinstelling op onder de huidige gekozen naam
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Grafische basisinstellingen wijzigen
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}NewGRF-parameters wijzigen
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Sluiten
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Terugstellen
 | 
			
		||||
@@ -5187,6 +5189,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Kan geen
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Voertuigen kunnen alleen wachten op stations
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Dit voertuig stopt niet op dit station
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... dienstregeling is niet compleet
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... dienstregeling is nog niet gestart
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... te veel bordjes
 | 
			
		||||
 
 | 
			
		||||
@@ -3384,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Save
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Save the preset to the current selected name
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Change base graphics parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Change NewGRF parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Close
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Reset
 | 
			
		||||
@@ -5188,6 +5189,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Can't ti
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Vehicles can only wait at stations
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}This vehicle is not stopping at this station
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... timetable is incomplete
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... timetable has not started yet
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... too many signs
 | 
			
		||||
 
 | 
			
		||||
@@ -3384,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Save
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Save the preset to the current selected name
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Change base graphics parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Change NewGRF parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Close
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Reset
 | 
			
		||||
@@ -5188,6 +5189,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Can't ti
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Vehicles can only wait at stations
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}This vehicle is not stopping at this station
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... timetable is incomplete
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... timetable has not started yet
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... too many signs
 | 
			
		||||
 
 | 
			
		||||
@@ -533,6 +533,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD                                    :About 'OpenTTD'
 | 
			
		||||
STR_ABOUT_MENU_SPRITE_ALIGNER                                   :Sprite aligner
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES                            :Toggle bounding boxes
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS                              :Toggle coloring of dirty blocks
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES                           :Toggle widget outlines
 | 
			
		||||
 | 
			
		||||
# Place in highscore window
 | 
			
		||||
###length 15
 | 
			
		||||
@@ -3383,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Save
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Save the preset to the current selected name
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Change base graphics parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Change NewGRF parameters
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Close
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Reset
 | 
			
		||||
@@ -5187,6 +5189,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Can't ti
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Vehicles can only wait at stations
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}This vehicle is not stopping at this station
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... timetable is incomplete
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... timetable has not started yet
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... too many signs
 | 
			
		||||
 
 | 
			
		||||
@@ -3384,7 +3384,8 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Tallenna
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Tallenna valmislista valitulle nimelle
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Muuta NewGRF-parametrejä
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Muuta perusgrafiikan parametreja
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Muuta NewGRF-parametreja
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Sulje
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Palauta
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET_TOOLTIP                             :{BLACK}Aseta kaikki parametrit oletusarvoihin
 | 
			
		||||
@@ -5188,6 +5189,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Ei voi a
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Kulkuneuvo voi odottaa vain asemalla
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Tämä kulkuneuvo ei pysähdy tällä asemalla
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}… aikataulu on puutteellinen
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}… aikataulu ei ole vielä alkanut
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... liian monta kylttiä.
 | 
			
		||||
 
 | 
			
		||||
@@ -3385,6 +3385,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Sauvegar
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Sauvegarder la présélection sous le nom actuellement sélectionné
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Modifier les paramètres des graphiques de base
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Modifier les paramètres NewGRF
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Fermer
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Réinitialiser
 | 
			
		||||
@@ -5189,6 +5190,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Impossib
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Les véhicules ne peuvent attendre qu'aux stations
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Ce véhicule ne s'arrête pas à cette station
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... l'horaire est incomplet
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... cet horaire n'a pas encore démarré
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... trop de panneaux
 | 
			
		||||
 
 | 
			
		||||
@@ -96,28 +96,28 @@ STR_CARGO_SINGULAR_FIZZY_DRINK                                  :{G=f}탄산음
 | 
			
		||||
STR_QUANTITY_NOTHING                                            :
 | 
			
		||||
STR_QUANTITY_PASSENGERS                                         :승객{NBSP}{COMMA}명
 | 
			
		||||
STR_QUANTITY_COAL                                               :석탄 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_MAIL                                               :우편 {COMMA}{NBSP}자루
 | 
			
		||||
STR_QUANTITY_MAIL                                               :우편 {COMMA}자루
 | 
			
		||||
STR_QUANTITY_OIL                                                :석유 {VOLUME_LONG}
 | 
			
		||||
STR_QUANTITY_LIVESTOCK                                          :가축 {COMMA}{NBSP}마리
 | 
			
		||||
STR_QUANTITY_GOODS                                              :상품 {COMMA}{NBSP}상자
 | 
			
		||||
STR_QUANTITY_LIVESTOCK                                          :가축 {COMMA}마리
 | 
			
		||||
STR_QUANTITY_GOODS                                              :상품 {COMMA}상자
 | 
			
		||||
STR_QUANTITY_GRAIN                                              :곡물 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_WOOD                                               :목재 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_IRON_ORE                                           :철광석 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_STEEL                                              :철 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_VALUABLES                                          :귀금속 {COMMA}{NBSP}자루
 | 
			
		||||
STR_QUANTITY_VALUABLES                                          :귀금속 {COMMA}자루
 | 
			
		||||
STR_QUANTITY_COPPER_ORE                                         :구리 광석 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_MAIZE                                              :옥수수 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_FRUIT                                              :과일 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_DIAMONDS                                           :다이아몬드 {COMMA}{NBSP}자루
 | 
			
		||||
STR_QUANTITY_DIAMONDS                                           :다이아몬드 {COMMA}자루
 | 
			
		||||
STR_QUANTITY_FOOD                                               :식품 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_PAPER                                              :종이 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_GOLD                                               :금 {COMMA}{NBSP}자루
 | 
			
		||||
STR_QUANTITY_GOLD                                               :금 {COMMA}자루
 | 
			
		||||
STR_QUANTITY_WATER                                              :물 {VOLUME_LONG}
 | 
			
		||||
STR_QUANTITY_WHEAT                                              :밀 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_RUBBER                                             :고무 {VOLUME_LONG}
 | 
			
		||||
STR_QUANTITY_SUGAR                                              :설탕 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_TOYS                                               :장난감 {COMMA}{NBSP}상자
 | 
			
		||||
STR_QUANTITY_SWEETS                                             :사탕 {COMMA}{NBSP}자루
 | 
			
		||||
STR_QUANTITY_TOYS                                               :장난감 {COMMA}상자
 | 
			
		||||
STR_QUANTITY_SWEETS                                             :사탕 {COMMA}자루
 | 
			
		||||
STR_QUANTITY_COLA                                               :콜라 {VOLUME_LONG}
 | 
			
		||||
STR_QUANTITY_CANDYFLOSS                                         :솜사탕 {WEIGHT_LONG}
 | 
			
		||||
STR_QUANTITY_BUBBLES                                            :거품 {COMMA}개
 | 
			
		||||
@@ -165,11 +165,11 @@ STR_ABBREV_ALL                                                  :모두
 | 
			
		||||
 | 
			
		||||
# 'Mode' of transport for cargoes
 | 
			
		||||
STR_PASSENGERS                                                  :{G=m}{COMMA}명
 | 
			
		||||
STR_BAGS                                                        :{G=f}{COMMA}{NBSP}자루
 | 
			
		||||
STR_TONS                                                        :{G=m}{COMMA}{NBSP}톤
 | 
			
		||||
STR_LITERS                                                      :{G=f}{COMMA}{NBSP}리터
 | 
			
		||||
STR_ITEMS                                                       :{G=m}{COMMA}{NBSP}마리
 | 
			
		||||
STR_CRATES                                                      :{G=f}{COMMA}{NBSP}상자
 | 
			
		||||
STR_BAGS                                                        :{G=f}{COMMA}자루
 | 
			
		||||
STR_TONS                                                        :{G=m}{COMMA}톤
 | 
			
		||||
STR_LITERS                                                      :{G=f}{COMMA}리터
 | 
			
		||||
STR_ITEMS                                                       :{G=m}{COMMA}마리
 | 
			
		||||
STR_CRATES                                                      :{G=f}{COMMA}상자
 | 
			
		||||
 | 
			
		||||
STR_COLOUR_DEFAULT                                              :기본
 | 
			
		||||
###length 17
 | 
			
		||||
@@ -534,6 +534,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD                                    :'OpenTTD'에 
 | 
			
		||||
STR_ABOUT_MENU_SPRITE_ALIGNER                                   :스프라이트 정렬 도구
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES                            :박스 경계선 보기 전환
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS                              :시각적 업데이트 블록 표시 전환
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES                           :위젯 경계선 켜기/끄기
 | 
			
		||||
 | 
			
		||||
# Place in highscore window
 | 
			
		||||
###length 15
 | 
			
		||||
@@ -1779,7 +1780,7 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT                             :항공기에 
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT                    :항공기에 따로 점검 기간이 설정되어있지 않은 경우에 사용할 기본 점검 기간을 설정합니다.
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_SHIPS                                :선박에 대한 기본 점검 기준: {STRING}
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT                       :선박에 따로 점검 기간이 설정되어있지 않은 경우에 사용할 기본 점검 기간을 설정합니다.
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_VALUE                                :{COMMA}{NBSP}일/%
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_VALUE                                :{COMMA}일/%
 | 
			
		||||
###setting-zero-is-special
 | 
			
		||||
STR_CONFIG_SETTING_SERVINT_DISABLED                             :사용 안 함
 | 
			
		||||
 | 
			
		||||
@@ -3384,6 +3385,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}저장
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}이 프리셋을 선택한 이름으로 저장합니다
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}기본 그래픽 매개 변수를 변경합니다
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}NewGRF 매개 변숫값 변경
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}닫기
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}초기화
 | 
			
		||||
@@ -5188,6 +5190,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}차량
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}차량은 정거장에서만 기다릴 수 있습니다
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}이 차량은 이 정거장에 서지 않습니다
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... 시간표가 모두 작성되지 않았습니다
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... 시간표가 아직 시작되지 않았습니다
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... 팻말 수가 너무 많습니다
 | 
			
		||||
 
 | 
			
		||||
@@ -3764,6 +3764,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Zapisz
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Zapisz schemat z wybraną nazwą
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Zmień parametry grafik podstawowych
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Zmień parametry NewGRF
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Zamknij
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Resetuj
 | 
			
		||||
@@ -5574,6 +5575,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Nie moż
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Pojazdy mogą czekać tylko na stacjach
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Ten pojazd nie zatrzymuje się na tej stacji.
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... rozkład jazdy jest niekompletny
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... rozkład jazdy jeszcze się nie rozpoczął
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... zbyt wiele napisów
 | 
			
		||||
 
 | 
			
		||||
@@ -3385,6 +3385,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Grava
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Grava a predefinição com o nome seleccionado
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Alterar os parâmetros dos gráficos base
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Alterar parâmetros de NewGRF
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Fechar
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Repor
 | 
			
		||||
@@ -5189,6 +5190,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Impossí
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Veículos apenas podem esperar em estações.
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Este veículo não pára nesta estação.
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... horário incompleto
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... o horário ainda não começou
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... demasiados sinais
 | 
			
		||||
 
 | 
			
		||||
@@ -3559,6 +3559,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}Сохр
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}Сохранить набор под выбранным именем
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}Изменение параметров графического пакета
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Изменить параметры NewGRF
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Закрыть
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}Сброс
 | 
			
		||||
@@ -5375,6 +5376,7 @@ STR_ERROR_CAN_T_TIMETABLE_VEHICLE                               :{WHITE}Не у
 | 
			
		||||
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS                       :{WHITE}Транспорт может ждать только на станции
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STOPPING_HERE                           :{WHITE}Это транспортное средство не останавливается на этой станции
 | 
			
		||||
STR_ERROR_TIMETABLE_INCOMPLETE                                  :{WHITE}... график движения неполный
 | 
			
		||||
STR_ERROR_TIMETABLE_NOT_STARTED                                 :{WHITE}... график движения не установлен
 | 
			
		||||
 | 
			
		||||
# Sign related errors
 | 
			
		||||
STR_ERROR_TOO_MANY_SIGNS                                        :{WHITE}... слишком много табличек
 | 
			
		||||
 
 | 
			
		||||
@@ -533,6 +533,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD                                    :关于 'OpenTTD
 | 
			
		||||
STR_ABOUT_MENU_SPRITE_ALIGNER                                   :Sprite 对齐
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES                            :切换边界框
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS                              :切换脏方块的颜色
 | 
			
		||||
STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES                           :调节小组件边框
 | 
			
		||||
 | 
			
		||||
# Place in highscore window
 | 
			
		||||
###length 15
 | 
			
		||||
@@ -924,6 +925,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE                    :{BLACK}新 {STR
 | 
			
		||||
 | 
			
		||||
STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP                             :{BLACK}打开该运输工具所属的组
 | 
			
		||||
 | 
			
		||||
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST                   :{WHITE}{STATION}不再接受:{CARGO_LIST}
 | 
			
		||||
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST                         :{WHITE}{STATION}现在接受:{CARGO_LIST}
 | 
			
		||||
 | 
			
		||||
STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED                               :{BIG_FONT}{BLACK}财政补贴项目到期:{}{}将 {STRING} 从 {STRING} 运送到 {STRING} 将不再获得财政补贴。
 | 
			
		||||
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE                              :{BIG_FONT}{BLACK}财政补贴项目流标:{}{}将 {STRING} 从 {STRING} 运送到 {STRING} 将不是财政补贴项目。
 | 
			
		||||
@@ -2192,6 +2195,7 @@ STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT                                :{WHITE}修改
 | 
			
		||||
STR_CHEAT_CHANGE_DATE                                           :{LTBLUE}改变日期:{ORANGE}{DATE_SHORT}
 | 
			
		||||
STR_CHEAT_CHANGE_DATE_QUERY_CAPT                                :{WHITE}改变当前年份
 | 
			
		||||
STR_CHEAT_SETUP_PROD                                            :{LTBLUE}开启可调整产量模式:{ORANGE}{STRING}
 | 
			
		||||
STR_CHEAT_STATION_RATING                                        :{LTBLUE}车站评价固定为100%:{ORANGE}{STRING}
 | 
			
		||||
 | 
			
		||||
# Livery window
 | 
			
		||||
STR_LIVERY_CAPTION                                              :{WHITE}{COMPANY} 的色彩方案
 | 
			
		||||
@@ -3380,6 +3384,7 @@ STR_SAVE_PRESET_SAVE                                            :{BLACK}保存
 | 
			
		||||
STR_SAVE_PRESET_SAVE_TOOLTIP                                    :{BLACK}以当前选定的名称保存预设值
 | 
			
		||||
 | 
			
		||||
# NewGRF parameters window
 | 
			
		||||
STR_BASEGRF_PARAMETERS_CAPTION                                  :{WHITE}改变基本图形组参数
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}调整 NewGRF 参数
 | 
			
		||||
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}关闭
 | 
			
		||||
STR_NEWGRF_PARAMETERS_RESET                                     :{BLACK}重置
 | 
			
		||||
 
 | 
			
		||||
@@ -197,7 +197,7 @@ static const NWidgetPart _nested_performance_league_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _performance_league_desc(
 | 
			
		||||
static WindowDesc _performance_league_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "performance_league", 0, 0,
 | 
			
		||||
	WC_COMPANY_LEAGUE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -430,7 +430,7 @@ static const NWidgetPart _nested_script_league_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _script_league_desc(
 | 
			
		||||
static WindowDesc _script_league_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "script_league", 0, 0,
 | 
			
		||||
	WC_COMPANY_LEAGUE, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -719,7 +719,7 @@ static const NWidgetPart _nested_linkgraph_legend_widgets[] = {
 | 
			
		||||
static_assert(WID_LGL_SATURATION_LAST - WID_LGL_SATURATION_FIRST ==
 | 
			
		||||
		lengthof(LinkGraphOverlay::LINK_COLOURS[0]) - 1);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _linkgraph_legend_desc(
 | 
			
		||||
static WindowDesc _linkgraph_legend_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "toolbar_linkgraph", 0, 0,
 | 
			
		||||
	WC_LINKGRAPH_LEGEND, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -611,7 +611,7 @@ static Hotkey global_hotkeys[] = {
 | 
			
		||||
};
 | 
			
		||||
HotkeyList MainWindow::hotkeys("global", global_hotkeys);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _main_window_desc(
 | 
			
		||||
static WindowDesc _main_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_MAIN_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_NO_CLOSE,
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ static const NWidgetPart _nested_land_info_widgets[] = {
 | 
			
		||||
	NWidget(WWT_PANEL, COLOUR_GREY, WID_LI_BACKGROUND), EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _land_info_desc(
 | 
			
		||||
static WindowDesc _land_info_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_LAND_INFO, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -430,7 +430,7 @@ static const NWidgetPart _nested_about_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _about_desc(
 | 
			
		||||
static WindowDesc _about_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_GAME_OPTIONS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -696,7 +696,7 @@ static const NWidgetPart _nested_tooltips_widgets[] = {
 | 
			
		||||
	NWidget(WWT_EMPTY, INVALID_COLOUR, WID_TT_BACKGROUND),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _tool_tips_desc(
 | 
			
		||||
static WindowDesc _tool_tips_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
 | 
			
		||||
	WC_TOOLTIPS, WC_NONE,
 | 
			
		||||
	WDF_NO_FOCUS | WDF_NO_CLOSE,
 | 
			
		||||
@@ -1153,7 +1153,7 @@ static const NWidgetPart _nested_query_string_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _query_string_desc(
 | 
			
		||||
static WindowDesc _query_string_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_QUERY_STRING, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1330,7 +1330,7 @@ static const NWidgetPart _nested_query_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _query_desc(
 | 
			
		||||
static WindowDesc _query_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_CONFIRM_POPUP_QUERY, WC_NONE,
 | 
			
		||||
	WDF_MODAL,
 | 
			
		||||
@@ -1463,7 +1463,7 @@ struct ModifierKeyToggleWindow : Window {
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _modifier_key_toggle_desc(
 | 
			
		||||
static WindowDesc _modifier_key_toggle_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "modifier_key_toggle", 0, 0,
 | 
			
		||||
	WC_MODIFIER_KEY_TOGGLE, WC_NONE,
 | 
			
		||||
	WDF_NO_FOCUS,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*
 | 
			
		||||
* This file is part of OpenTTD.
 | 
			
		||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 * This file is part of OpenTTD.
 | 
			
		||||
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* @file midi.h Declarations for MIDI data */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*
 | 
			
		||||
* This file is part of OpenTTD.
 | 
			
		||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 * This file is part of OpenTTD.
 | 
			
		||||
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* @file midifile.cpp Parser for standard MIDI files */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/*
 | 
			
		||||
* This file is part of OpenTTD.
 | 
			
		||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 * This file is part of OpenTTD.
 | 
			
		||||
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | 
			
		||||
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* @file midifile.hpp Parser for standard MIDI files */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,7 @@ void MusicSystem::ChangePlaylist(PlaylistChoices pl)
 | 
			
		||||
void MusicSystem::ChangeMusicSet(const std::string &set_name)
 | 
			
		||||
{
 | 
			
		||||
	if (set_name != "NoMusic") InitMusicDriver(true);
 | 
			
		||||
	BaseMusic::SetSet(set_name);
 | 
			
		||||
	BaseMusic::SetSetByName(set_name);
 | 
			
		||||
	BaseMusic::ini_set = set_name;
 | 
			
		||||
 | 
			
		||||
	this->BuildPlaylists();
 | 
			
		||||
@@ -649,7 +649,7 @@ static const NWidgetPart _nested_music_track_selection_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _music_track_selection_desc(
 | 
			
		||||
static WindowDesc _music_track_selection_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_MUSIC_TRACK_SELECTION, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -908,7 +908,7 @@ static const NWidgetPart _nested_music_window_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _music_window_desc(
 | 
			
		||||
static WindowDesc _music_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "music", 0, 0,
 | 
			
		||||
	WC_MUSIC_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ static std::chrono::steady_clock::time_point _chatmessage_dirty_time;
 | 
			
		||||
 * the left and pixels from the bottom. The height is the maximum height.
 | 
			
		||||
 */
 | 
			
		||||
static PointDimension _chatmsg_box;
 | 
			
		||||
static uint8 *_chatmessage_backup = nullptr; ///< Backup in case text is moved.
 | 
			
		||||
static ReusableBuffer<uint8_t> _chatmessage_backup; ///< Backup in case text is moved.
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test if there are any chat messages to display.
 | 
			
		||||
@@ -112,7 +112,6 @@ void NetworkReInitChatBoxSize()
 | 
			
		||||
{
 | 
			
		||||
	_chatmsg_box.y       = 3 * FONT_HEIGHT_NORMAL;
 | 
			
		||||
	_chatmsg_box.height  = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + ScaleGUITrad(NETWORK_CHAT_LINE_SPACING)) + ScaleGUITrad(4);
 | 
			
		||||
	_chatmessage_backup  = ReallocT(_chatmessage_backup, static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Initialize all buffers of the chat visualisation. */
 | 
			
		||||
@@ -165,7 +164,7 @@ void NetworkUndrawChatMessage()
 | 
			
		||||
 | 
			
		||||
		_chatmessage_visible = false;
 | 
			
		||||
		/* Put our 'shot' back to the screen */
 | 
			
		||||
		blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);
 | 
			
		||||
		blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup.GetBuffer(), width, height);
 | 
			
		||||
		/* And make sure it is updated next time */
 | 
			
		||||
		VideoDriver::GetInstance()->MakeDirty(x, y, width, height);
 | 
			
		||||
 | 
			
		||||
@@ -218,10 +217,9 @@ void NetworkDrawChatMessage()
 | 
			
		||||
	}
 | 
			
		||||
	if (width <= 0 || height <= 0) return;
 | 
			
		||||
 | 
			
		||||
	assert(blitter->BufferSize(width, height) <= static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * blitter->GetBytesPerPixel());
 | 
			
		||||
 | 
			
		||||
	/* Make a copy of the screen as it is before painting (for undraw) */
 | 
			
		||||
	blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);
 | 
			
		||||
	uint8_t *buffer = _chatmessage_backup.Allocate(BlitterFactory::GetCurrentBlitter()->BufferSize(width, height));
 | 
			
		||||
	blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), buffer, width, height);
 | 
			
		||||
 | 
			
		||||
	_cur_dpi = &_screen; // switch to _screen painting
 | 
			
		||||
 | 
			
		||||
@@ -520,7 +518,7 @@ static const NWidgetPart _nested_chat_window_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** The description of the chat window. */
 | 
			
		||||
static WindowDesc _chat_window_desc(
 | 
			
		||||
static WindowDesc _chat_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_SEND_NETWORK_MSG, WC_NONE,
 | 
			
		||||
	WDF_NETWORK,
 | 
			
		||||
 
 | 
			
		||||
@@ -200,9 +200,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
 | 
			
		||||
		ShutdownSocket(this->sock, false, true, 2);
 | 
			
		||||
 | 
			
		||||
		/* Wait a number of ticks so our leave message can reach the server.
 | 
			
		||||
		* This is especially needed for Windows servers as they seem to get
 | 
			
		||||
		* the "socket is closed" message before receiving our leave message,
 | 
			
		||||
		* which would trigger the server to close the connection as well. */
 | 
			
		||||
		 * This is especially needed for Windows servers as they seem to get
 | 
			
		||||
		 * the "socket is closed" message before receiving our leave message,
 | 
			
		||||
		 * which would trigger the server to close the connection as well. */
 | 
			
		||||
		CSleep(3 * MILLISECONDS_PER_TICK);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@ static const NWidgetPart _nested_network_content_download_status_window_widgets[
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description for the download window */
 | 
			
		||||
static WindowDesc _network_content_download_status_window_desc(
 | 
			
		||||
static WindowDesc _network_content_download_status_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_STATUS_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_MODAL,
 | 
			
		||||
@@ -1068,7 +1068,7 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
 | 
			
		||||
					NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NCL_SCROLLBAR),
 | 
			
		||||
				EndContainer(),
 | 
			
		||||
				NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
 | 
			
		||||
					NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE), SetResize(1, 0), SetFill(1, 0),
 | 
			
		||||
					NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE),
 | 
			
		||||
						NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_UPDATE), SetResize(1, 0), SetFill(1, 0),
 | 
			
		||||
												SetDataTip(STR_CONTENT_SELECT_UPDATES_CAPTION, STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP),
 | 
			
		||||
						NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_ALL), SetResize(1, 0), SetFill(1, 0),
 | 
			
		||||
@@ -1113,7 +1113,7 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description of the content list */
 | 
			
		||||
static WindowDesc _network_content_list_desc(
 | 
			
		||||
static WindowDesc _network_content_list_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "list_content", 630, 460,
 | 
			
		||||
	WC_NETWORK_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -133,7 +133,7 @@ public:
 | 
			
		||||
		this->smallest_x = this->head->smallest_x + this->tail->smallest_x; // First and last are always shown, rest not
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override
 | 
			
		||||
	void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
 | 
			
		||||
	{
 | 
			
		||||
		assert(given_width >= this->smallest_x && given_height >= this->smallest_y);
 | 
			
		||||
 | 
			
		||||
@@ -962,7 +962,7 @@ static const NWidgetPart _nested_network_game_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_game_window_desc(
 | 
			
		||||
static WindowDesc _network_game_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "list_servers", 1000, 730,
 | 
			
		||||
	WC_NETWORK_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_NETWORK,
 | 
			
		||||
@@ -1229,7 +1229,7 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_start_server_window_desc(
 | 
			
		||||
static WindowDesc _network_start_server_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_NETWORK,
 | 
			
		||||
@@ -1308,7 +1308,7 @@ static const NWidgetPart _nested_client_list_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _client_list_desc(
 | 
			
		||||
static WindowDesc _client_list_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_clients", 220, 300,
 | 
			
		||||
	WC_CLIENT_LIST, WC_NONE,
 | 
			
		||||
	WDF_NETWORK,
 | 
			
		||||
@@ -2218,7 +2218,7 @@ static const NWidgetPart _nested_network_join_status_window_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_join_status_window_desc(
 | 
			
		||||
static WindowDesc _network_join_status_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_STATUS_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_MODAL | WDF_NETWORK,
 | 
			
		||||
@@ -2340,7 +2340,7 @@ static const NWidgetPart _nested_network_company_password_window_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_company_password_window_desc(
 | 
			
		||||
static WindowDesc _network_company_password_window_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, nullptr, 0, 0,
 | 
			
		||||
	WC_COMPANY_PASSWORD_WINDOW, WC_NONE,
 | 
			
		||||
	WDF_NETWORK,
 | 
			
		||||
@@ -2449,7 +2449,7 @@ static const NWidgetPart _nested_network_ask_relay_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_ask_relay_desc(
 | 
			
		||||
static WindowDesc _network_ask_relay_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_ASK_RELAY, WC_NONE,
 | 
			
		||||
	WDF_MODAL | WDF_NETWORK,
 | 
			
		||||
@@ -2547,7 +2547,7 @@ static const NWidgetPart _nested_network_ask_survey_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _network_ask_survey_desc(
 | 
			
		||||
static WindowDesc _network_ask_survey_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_NETWORK_ASK_SURVEY, WC_NONE,
 | 
			
		||||
	WDF_MODAL,
 | 
			
		||||
 
 | 
			
		||||
@@ -3628,13 +3628,13 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
 | 
			
		||||
							it.ti.x = (int8)GB(it.ti.x, 0, 8);
 | 
			
		||||
							it.ti.y = (int8)GB(it.ti.y, 0, 8);
 | 
			
		||||
 | 
			
		||||
							/* When there were only 256x256 maps, TileIndex was a uint16 and
 | 
			
		||||
								* it.ti was just a TileIndexDiff that was added to it.
 | 
			
		||||
								* As such negative "x" values were shifted into the "y" position.
 | 
			
		||||
								*   x = -1, y = 1 -> x = 255, y = 0
 | 
			
		||||
								* Since GRF version 8 the position is interpreted as pair of independent int8.
 | 
			
		||||
								* For GRF version < 8 we need to emulate the old shifting behaviour.
 | 
			
		||||
								*/
 | 
			
		||||
							/* When there were only 256x256 maps, TileIndex was a uint16_t and
 | 
			
		||||
							 * it.ti was just a TileIndexDiff that was added to it.
 | 
			
		||||
							 * As such negative "x" values were shifted into the "y" position.
 | 
			
		||||
							 *   x = -1, y = 1 -> x = 255, y = 0
 | 
			
		||||
							 * Since GRF version 8 the position is interpreted as pair of independent int8.
 | 
			
		||||
							 * For GRF version < 8 we need to emulate the old shifting behaviour.
 | 
			
		||||
							 */
 | 
			
		||||
							if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
@@ -10999,8 +10999,8 @@ static void FinaliseIndustriesArray()
 | 
			
		||||
 | 
			
		||||
			StringID strid;
 | 
			
		||||
			/* process the conversion of text at the end, so to be sure everything will be fine
 | 
			
		||||
				* and available.  Check if it does not return undefind marker, which is a very good sign of a
 | 
			
		||||
				* substitute industry who has not changed the string been examined, thus using it as such */
 | 
			
		||||
			 * and available.  Check if it does not return undefind marker, which is a very good sign of a
 | 
			
		||||
			 * substitute industry who has not changed the string been examined, thus using it as such */
 | 
			
		||||
			strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
 | 
			
		||||
			if (strid != STR_UNDEFINED) indsp->name = strid;
 | 
			
		||||
 | 
			
		||||
@@ -11018,7 +11018,7 @@ static void FinaliseIndustriesArray()
 | 
			
		||||
 | 
			
		||||
			if (indsp->station_name != STR_NULL) {
 | 
			
		||||
				/* STR_NULL (0) can be set by grf.  It has a meaning regarding assignation of the
 | 
			
		||||
					* station's name. Don't want to lose the value, therefore, do not process. */
 | 
			
		||||
				 * station's name. Don't want to lose the value, therefore, do not process. */
 | 
			
		||||
				strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
 | 
			
		||||
				if (strid != STR_UNDEFINED) indsp->station_name = strid;
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,12 @@ GRFConfig::GRFConfig(const GRFConfig &config) :
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GRFConfig::SetParams(const std::vector<uint32_t> &pars)
 | 
			
		||||
{
 | 
			
		||||
	this->num_params = static_cast<uint8_t>(std::min(this->param.size(), pars.size()));
 | 
			
		||||
	std::copy(pars.begin(), pars.begin() + this->num_params, this->param.begin());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return whether this NewGRF can replace an older version of the same NewGRF.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -180,6 +180,7 @@ struct GRFConfig : ZeroedMemoryAllocator {
 | 
			
		||||
	struct GRFConfig *next;                     ///< NOSAVE: Next item in the linked list
 | 
			
		||||
 | 
			
		||||
	bool IsCompatible(uint32_t old_version) const;
 | 
			
		||||
	void SetParams(const std::vector<uint32_t> &pars);
 | 
			
		||||
	void CopyParams(const GRFConfig &src);
 | 
			
		||||
 | 
			
		||||
	const char *GetTextfile(TextfileType type) const;
 | 
			
		||||
@@ -238,6 +239,7 @@ std::string GRFBuildParamList(const GRFConfig *c);
 | 
			
		||||
 | 
			
		||||
/* In newgrf_gui.cpp */
 | 
			
		||||
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
 | 
			
		||||
void OpenGRFParameterWindow(bool is_baseset, GRFConfig *c, bool editable);
 | 
			
		||||
 | 
			
		||||
void UpdateNewGRFScanStatus(uint num, const char *name);
 | 
			
		||||
void UpdateNewGRFConfigPalette(int32 new_value = 0);
 | 
			
		||||
 
 | 
			
		||||
@@ -1105,14 +1105,14 @@ static const NWidgetPart _nested_newgrf_inspect_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _newgrf_inspect_chain_desc(
 | 
			
		||||
static WindowDesc _newgrf_inspect_chain_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "newgrf_inspect_chain", 400, 300,
 | 
			
		||||
	WC_NEWGRF_INSPECT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_newgrf_inspect_chain_widgets), std::end(_nested_newgrf_inspect_chain_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static WindowDesc _newgrf_inspect_desc(
 | 
			
		||||
static WindowDesc _newgrf_inspect_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "newgrf_inspect", 400, 300,
 | 
			
		||||
	WC_NEWGRF_INSPECT, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1572,7 +1572,7 @@ static const NWidgetPart _nested_sprite_aligner_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _sprite_aligner_desc(
 | 
			
		||||
static WindowDesc _sprite_aligner_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "sprite_aligner", 400, 300,
 | 
			
		||||
	WC_SPRITE_ALIGNER, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -160,7 +160,7 @@ struct NewGRFParametersWindow : public Window {
 | 
			
		||||
	bool action14present;  ///< True if action14 information is present.
 | 
			
		||||
	bool editable;         ///< Allow editing parameters.
 | 
			
		||||
 | 
			
		||||
	NewGRFParametersWindow(WindowDesc *desc, GRFConfig *c, bool editable) : Window(desc),
 | 
			
		||||
	NewGRFParametersWindow(WindowDesc *desc, bool is_baseset, GRFConfig *c, bool editable) : Window(desc),
 | 
			
		||||
		grf_config(c),
 | 
			
		||||
		clicked_button(UINT_MAX),
 | 
			
		||||
		clicked_dropdown(false),
 | 
			
		||||
@@ -171,6 +171,7 @@ struct NewGRFParametersWindow : public Window {
 | 
			
		||||
		this->action14present = (c->num_valid_params != c->param.size() || !c->param_info.empty());
 | 
			
		||||
 | 
			
		||||
		this->CreateNestedTree();
 | 
			
		||||
		this->GetWidget<NWidgetCore>(WID_NP_CAPTION)->SetDataTip(is_baseset ? STR_BASEGRF_PARAMETERS_CAPTION : STR_NEWGRF_PARAMETERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
 | 
			
		||||
		this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR);
 | 
			
		||||
		this->GetWidget<NWidgetStacked>(WID_NP_SHOW_NUMPAR)->SetDisplayedPlane(this->action14present ? SZSP_HORIZONTAL : 0);
 | 
			
		||||
		this->GetWidget<NWidgetStacked>(WID_NP_SHOW_DESCRIPTION)->SetDisplayedPlane(this->action14present ? 0 : SZSP_HORIZONTAL);
 | 
			
		||||
@@ -522,7 +523,7 @@ GRFParameterInfo NewGRFParametersWindow::dummy_parameter_info(0);
 | 
			
		||||
static const NWidgetPart _nested_newgrf_parameter_widgets[] = {
 | 
			
		||||
	NWidget(NWID_HORIZONTAL),
 | 
			
		||||
		NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
 | 
			
		||||
		NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_PARAMETERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 | 
			
		||||
		NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_NP_CAPTION),
 | 
			
		||||
		NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
	NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NP_SHOW_NUMPAR),
 | 
			
		||||
@@ -552,17 +553,17 @@ static const NWidgetPart _nested_newgrf_parameter_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window definition for the change grf parameters window */
 | 
			
		||||
static WindowDesc _newgrf_parameters_desc(
 | 
			
		||||
static WindowDesc _newgrf_parameters_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "settings_newgrf_config", 500, 208,
 | 
			
		||||
	WC_GRF_PARAMETERS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
	std::begin(_nested_newgrf_parameter_widgets), std::end(_nested_newgrf_parameter_widgets)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
static void OpenGRFParameterWindow(GRFConfig *c, bool editable)
 | 
			
		||||
void OpenGRFParameterWindow(bool is_baseset, GRFConfig *c, bool editable)
 | 
			
		||||
{
 | 
			
		||||
	CloseWindowByClass(WC_GRF_PARAMETERS);
 | 
			
		||||
	new NewGRFParametersWindow(&_newgrf_parameters_desc, c, editable);
 | 
			
		||||
	new NewGRFParametersWindow(&_newgrf_parameters_desc, is_baseset, c, editable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Window for displaying the textfile of a NewGRF. */
 | 
			
		||||
@@ -1155,7 +1156,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
 | 
			
		||||
			case WID_NS_SET_PARAMETERS: { // Edit parameters
 | 
			
		||||
				if (this->active_sel == nullptr || !this->show_params || this->active_sel->num_valid_params == 0) break;
 | 
			
		||||
 | 
			
		||||
				OpenGRFParameterWindow(this->active_sel, this->editable);
 | 
			
		||||
				OpenGRFParameterWindow(false, this->active_sel, this->editable);
 | 
			
		||||
				this->InvalidateData(GOID_NEWGRF_CHANGES_MADE);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1688,7 +1689,7 @@ public:
 | 
			
		||||
		this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override
 | 
			
		||||
	void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
 | 
			
		||||
	{
 | 
			
		||||
		this->StoreSizePosition(sizing, x, y, given_width, given_height);
 | 
			
		||||
 | 
			
		||||
@@ -1996,7 +1997,7 @@ static const NWidgetPart _nested_newgrf_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Window definition of the manage newgrfs window */
 | 
			
		||||
static WindowDesc _newgrf_desc(
 | 
			
		||||
static WindowDesc _newgrf_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "settings_newgrf", 300, 263,
 | 
			
		||||
	WC_GAME_OPTIONS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -2087,7 +2088,7 @@ static const NWidgetPart _nested_save_preset_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description of the preset save window. */
 | 
			
		||||
static WindowDesc _save_preset_desc(
 | 
			
		||||
static WindowDesc _save_preset_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, "save_preset", 140, 110,
 | 
			
		||||
	WC_SAVE_PRESET, WC_GAME_OPTIONS,
 | 
			
		||||
	WDF_MODAL,
 | 
			
		||||
@@ -2228,7 +2229,7 @@ static const NWidgetPart _nested_scan_progress_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Description of the widgets and other settings of the window. */
 | 
			
		||||
static WindowDesc _scan_progress_desc(
 | 
			
		||||
static WindowDesc _scan_progress_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_MODAL_PROGRESS, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -371,7 +371,7 @@ void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Drive-in stop */
 | 
			
		||||
		/* Bay stop */
 | 
			
		||||
		if ((draw_mode & ROADSTOP_DRAW_MODE_ROAD) && rti->UsesOverlay()) {
 | 
			
		||||
			SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP);
 | 
			
		||||
			DrawSprite(ground + view, PAL_NONE, x, y);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,12 +21,12 @@ struct RoadTypeScopeResolver : public ScopeResolver {
 | 
			
		||||
	const RoadTypeInfo *rti;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Constructor of the roadtype scope resolvers.
 | 
			
		||||
	* @param ro Surrounding resolver.
 | 
			
		||||
	* @param rti Associated RoadTypeInfo.
 | 
			
		||||
	* @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead.
 | 
			
		||||
	* @param context Are we resolving sprites for the upper halftile, or on a bridge?
 | 
			
		||||
	*/
 | 
			
		||||
	 * Constructor of the roadtype scope resolvers.
 | 
			
		||||
	 * @param ro Surrounding resolver.
 | 
			
		||||
	 * @param rti Associated RoadTypeInfo.
 | 
			
		||||
	 * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead.
 | 
			
		||||
	 * @param context Are we resolving sprites for the upper halftile, or on a bridge?
 | 
			
		||||
	 */
 | 
			
		||||
	RoadTypeScopeResolver(ResolverObject &ro, const RoadTypeInfo *rti, TileIndex tile, TileContext context)
 | 
			
		||||
		: ScopeResolver(ro), tile(tile), context(context), rti(rti)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -820,8 +820,6 @@ struct TextRefStack {
 | 
			
		||||
		this->grffile = grffile;
 | 
			
		||||
		this->used = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void RewindStack() { this->position = 0; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** The stack that is used for TTDP compatible string code parsing */
 | 
			
		||||
@@ -895,11 +893,6 @@ void StopTextRefStackUsage()
 | 
			
		||||
	_newgrf_textrefstack.used = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RewindTextRefStack()
 | 
			
		||||
{
 | 
			
		||||
	_newgrf_textrefstack.RewindStack();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * FormatString for NewGRF specific "magic" string control codes
 | 
			
		||||
 * @param scc   the string control code that has been read
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,6 @@ bool CheckGrfLangID(byte lang_id, byte grf_version);
 | 
			
		||||
 | 
			
		||||
void StartTextRefStackUsage(const struct GRFFile *grffile, byte numEntries, const uint32 *values = nullptr);
 | 
			
		||||
void StopTextRefStackUsage();
 | 
			
		||||
void RewindTextRefStack();
 | 
			
		||||
bool UsingNewGRFTextStack();
 | 
			
		||||
struct TextRefStack *CreateTextRefStackBackup();
 | 
			
		||||
void RestoreTextRefStackBackup(struct TextRefStack *backup);
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,7 @@ static const NWidgetPart _nested_normal_news_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _normal_news_desc(
 | 
			
		||||
static WindowDesc _normal_news_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_NEWS_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -121,7 +121,7 @@ static const NWidgetPart _nested_vehicle_news_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _vehicle_news_desc(
 | 
			
		||||
static WindowDesc _vehicle_news_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_NEWS_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -149,7 +149,7 @@ static const NWidgetPart _nested_company_news_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _company_news_desc(
 | 
			
		||||
static WindowDesc _company_news_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_NEWS_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -172,7 +172,7 @@ static const NWidgetPart _nested_thin_news_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _thin_news_desc(
 | 
			
		||||
static WindowDesc _thin_news_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_NEWS_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -198,7 +198,7 @@ static const NWidgetPart _nested_small_news_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _small_news_desc(
 | 
			
		||||
static WindowDesc _small_news_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_MANUAL, nullptr, 0, 0,
 | 
			
		||||
	WC_NEWS_WINDOW, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
@@ -1235,7 +1235,7 @@ static const NWidgetPart _nested_message_history[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _message_history_desc(
 | 
			
		||||
static WindowDesc _message_history_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "list_news", 400, 140,
 | 
			
		||||
	WC_MESSAGE_HISTORY, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -85,16 +85,6 @@ class BuildObjectWindow : public Window {
 | 
			
		||||
		return objclass->GetSpec(_selected_object_index)->IsAvailable();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Calculate the number of columns of the #WID_BO_SELECT_MATRIX widget.
 | 
			
		||||
	 * @return Number of columns in the matrix.
 | 
			
		||||
	 */
 | 
			
		||||
	uint GetMatrixColumnCount()
 | 
			
		||||
	{
 | 
			
		||||
		const NWidgetBase *matrix = this->GetWidget<NWidgetBase>(WID_BO_SELECT_MATRIX);
 | 
			
		||||
		return 1 + (matrix->current_x - matrix->smallest_x) / matrix->resize_x;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	BuildObjectWindow(WindowDesc *desc, WindowNumber number) : Window(desc), info_height(1), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE)
 | 
			
		||||
	{
 | 
			
		||||
@@ -743,7 +733,7 @@ static const NWidgetPart _nested_build_object_widgets[] = {
 | 
			
		||||
			EndContainer(),
 | 
			
		||||
			NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BO_SELECT_SCROLL),
 | 
			
		||||
				NWidget(NWID_HORIZONTAL),
 | 
			
		||||
					NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BO_SELECT_MATRIX), SetFill(0, 1), SetPIP(0, 2, 0),
 | 
			
		||||
					NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BO_SELECT_MATRIX), SetPIP(0, 2, 0),
 | 
			
		||||
						NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BO_SELECT_IMAGE), SetMinimalSize(66, 60), SetDataTip(0x0, STR_OBJECT_BUILD_TOOLTIP),
 | 
			
		||||
								SetFill(0, 0), SetResize(0, 0), SetScrollbar(WID_BO_SELECT_SCROLL),
 | 
			
		||||
						EndContainer(),
 | 
			
		||||
@@ -762,7 +752,7 @@ static const NWidgetPart _nested_build_object_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _build_object_desc(
 | 
			
		||||
static WindowDesc _build_object_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "build_object", 0, 0,
 | 
			
		||||
	WC_BUILD_OBJECT, WC_BUILD_TOOLBAR,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -945,15 +945,31 @@ int openttd_main(int argc, char *argv[])
 | 
			
		||||
	InitWindowSystem();
 | 
			
		||||
 | 
			
		||||
	BaseGraphics::FindSets();
 | 
			
		||||
	if (graphics_set.empty() && !BaseGraphics::ini_set.empty()) graphics_set = BaseGraphics::ini_set;
 | 
			
		||||
	if (!BaseGraphics::SetSet(graphics_set)) {
 | 
			
		||||
		if (!graphics_set.empty()) {
 | 
			
		||||
			BaseGraphics::SetSet({});
 | 
			
		||||
 | 
			
		||||
			ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
 | 
			
		||||
			msg.SetDParamStr(0, graphics_set);
 | 
			
		||||
			ScheduleErrorMessage(msg);
 | 
			
		||||
	bool valid_graphics_set;
 | 
			
		||||
	if (!graphics_set.empty()) {
 | 
			
		||||
		valid_graphics_set = BaseGraphics::SetSetByName(graphics_set);
 | 
			
		||||
	} else if (BaseGraphics::ini_data.shortname != 0) {
 | 
			
		||||
		graphics_set = BaseGraphics::ini_data.name;
 | 
			
		||||
		valid_graphics_set = BaseGraphics::SetSetByShortname(BaseGraphics::ini_data.shortname);
 | 
			
		||||
		if (valid_graphics_set && !BaseGraphics::ini_data.extra_params.empty()) {
 | 
			
		||||
			GRFConfig &extra_cfg = BaseGraphics::GetUsedSet()->GetOrCreateExtraConfig();
 | 
			
		||||
			if (extra_cfg.IsCompatible(BaseGraphics::ini_data.extra_version)) {
 | 
			
		||||
				extra_cfg.SetParams(BaseGraphics::ini_data.extra_params);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else if (!BaseGraphics::ini_data.name.empty()) {
 | 
			
		||||
		graphics_set = BaseGraphics::ini_data.name;
 | 
			
		||||
		valid_graphics_set = BaseGraphics::SetSetByName(BaseGraphics::ini_data.name);
 | 
			
		||||
	} else {
 | 
			
		||||
		valid_graphics_set = true;
 | 
			
		||||
		BaseGraphics::SetSet(nullptr); // ignore error, continue to bootstrap GUI
 | 
			
		||||
	}
 | 
			
		||||
	if (!valid_graphics_set) {
 | 
			
		||||
		BaseGraphics::SetSet(nullptr);
 | 
			
		||||
 | 
			
		||||
		ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
 | 
			
		||||
		msg.SetDParamStr(0, graphics_set);
 | 
			
		||||
		ScheduleErrorMessage(msg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Initialize game palette */
 | 
			
		||||
@@ -1007,7 +1023,7 @@ int openttd_main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
	BaseSounds::FindSets();
 | 
			
		||||
	if (sounds_set.empty() && !BaseSounds::ini_set.empty()) sounds_set = BaseSounds::ini_set;
 | 
			
		||||
	if (!BaseSounds::SetSet(sounds_set)) {
 | 
			
		||||
	if (!BaseSounds::SetSetByName(sounds_set)) {
 | 
			
		||||
		if (sounds_set.empty() || !BaseSounds::SetSet({})) {
 | 
			
		||||
			usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md.");
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -1019,7 +1035,7 @@ int openttd_main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
	BaseMusic::FindSets();
 | 
			
		||||
	if (music_set.empty() && !BaseMusic::ini_set.empty()) music_set = BaseMusic::ini_set;
 | 
			
		||||
	if (!BaseMusic::SetSet(music_set)) {
 | 
			
		||||
	if (!BaseMusic::SetSetByName(music_set)) {
 | 
			
		||||
		if (music_set.empty() || !BaseMusic::SetSet({})) {
 | 
			
		||||
			usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md.");
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -2265,7 +2281,7 @@ void GameLoopSpecial()
 | 
			
		||||
	extern std::string _switch_baseset;
 | 
			
		||||
	if (!_switch_baseset.empty()) {
 | 
			
		||||
		if (BaseGraphics::GetUsedSet()->name != _switch_baseset) {
 | 
			
		||||
			BaseGraphics::SetSet(_switch_baseset);
 | 
			
		||||
			BaseGraphics::SetSetByName(_switch_baseset);
 | 
			
		||||
 | 
			
		||||
			ReloadNewGRFData();
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -939,9 +939,6 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	inline uint GetNumVehicles() const { return this->num_vehicles; }
 | 
			
		||||
 | 
			
		||||
	bool IsVehicleInSharedOrdersList(const Vehicle *v) const;
 | 
			
		||||
	int GetPositionInSharedOrderList(const Vehicle *v) const;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Adds the given vehicle to this shared order list.
 | 
			
		||||
	 * @note This is supposed to be called after the vehicle has been inserted
 | 
			
		||||
 
 | 
			
		||||
@@ -825,31 +825,6 @@ void OrderList::RemoveVehicle(Vehicle *v)
 | 
			
		||||
	if (v == this->first_shared) this->first_shared = v->NextShared();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a vehicle is part of the shared vehicle chain.
 | 
			
		||||
 * @param v is the vehicle to search in the shared vehicle chain.
 | 
			
		||||
 */
 | 
			
		||||
bool OrderList::IsVehicleInSharedOrdersList(const Vehicle *v) const
 | 
			
		||||
{
 | 
			
		||||
	for (const Vehicle *v_shared = this->first_shared; v_shared != nullptr; v_shared = v_shared->NextShared()) {
 | 
			
		||||
		if (v_shared == v) return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the position of the given vehicle within the shared order vehicle list.
 | 
			
		||||
 * @param v is the vehicle of which to get the position
 | 
			
		||||
 * @return position of v within the shared vehicle chain.
 | 
			
		||||
 */
 | 
			
		||||
int OrderList::GetPositionInSharedOrderList(const Vehicle *v) const
 | 
			
		||||
{
 | 
			
		||||
	int count = 0;
 | 
			
		||||
	for (const Vehicle *v_shared = v->PreviousShared(); v_shared != nullptr; v_shared = v_shared->PreviousShared()) count++;
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether all orders of the list have a filled timetable.
 | 
			
		||||
 * @return whether all orders have a filled timetable.
 | 
			
		||||
 
 | 
			
		||||
@@ -407,7 +407,7 @@ static const NWidgetPart _nested_cargo_type_orders_widgets[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Window description for the 'load' variant of CargoTypeOrdersWindow. */
 | 
			
		||||
static WindowDesc _cargo_type_load_orders_widgets (
 | 
			
		||||
static WindowDesc _cargo_type_load_orders_widgets (__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_cargo_type_load_order", 195, 186,
 | 
			
		||||
	WC_VEHICLE_CARGO_TYPE_LOAD_ORDERS, WC_VEHICLE_ORDERS,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -415,7 +415,7 @@ static WindowDesc _cargo_type_load_orders_widgets (
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/** Window description for the 'unload' variant of CargoTypeOrdersWindow. */
 | 
			
		||||
static WindowDesc _cargo_type_unload_orders_widgets (
 | 
			
		||||
static WindowDesc _cargo_type_unload_orders_widgets (__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_cargo_type_unload_order", 195, 186,
 | 
			
		||||
	WC_VEHICLE_CARGO_TYPE_UNLOAD_ORDERS, WC_VEHICLE_ORDERS,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3746,7 +3746,7 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _orders_train_desc(
 | 
			
		||||
static WindowDesc _orders_train_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_vehicle_orders_train", 384, 100,
 | 
			
		||||
	WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3898,7 +3898,7 @@ static const NWidgetPart _nested_orders_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _orders_desc(
 | 
			
		||||
static WindowDesc _orders_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_vehicle_orders", 384, 100,
 | 
			
		||||
	WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
@@ -3935,7 +3935,7 @@ static const NWidgetPart _nested_other_orders_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _other_orders_desc(
 | 
			
		||||
static WindowDesc _other_orders_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "view_vehicle_orders_competitor", 384, 86,
 | 
			
		||||
	WC_VEHICLE_ORDERS, WC_VEHICLE_VIEW,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
@@ -340,6 +340,31 @@ int MacOSStringCompare(std::string_view s1, std::string_view s2)
 | 
			
		||||
	return (int)CFStringCompareWithOptionsAndLocale(cf1.get(), cf2.get(), CFRangeMake(0, CFStringGetLength(cf1.get())), flags, _osx_locale.get()) + 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Search if a string is contained in another string using the current locale.
 | 
			
		||||
 *
 | 
			
		||||
 * @param str String to search in.
 | 
			
		||||
 * @param value String to search for.
 | 
			
		||||
 * @param case_insensitive Search case-insensitive.
 | 
			
		||||
 * @return 1 if value was found, 0 if it was not found, or -1 if not supported by the OS.
 | 
			
		||||
 */
 | 
			
		||||
int MacOSStringContains(const std::string_view str, const std::string_view value, bool case_insensitive)
 | 
			
		||||
{
 | 
			
		||||
	static bool supported = MacOSVersionIsAtLeast(10, 5, 0);
 | 
			
		||||
	if (!supported) return -1;
 | 
			
		||||
 | 
			
		||||
	CFStringCompareFlags flags = kCFCompareLocalized | kCFCompareWidthInsensitive;
 | 
			
		||||
	if (case_insensitive) flags |= kCFCompareCaseInsensitive;
 | 
			
		||||
 | 
			
		||||
	CFAutoRelease<CFStringRef> cf_str(CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)str.data(), str.size(), kCFStringEncodingUTF8, false));
 | 
			
		||||
	CFAutoRelease<CFStringRef> cf_value(CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)value.data(), value.size(), kCFStringEncodingUTF8, false));
 | 
			
		||||
 | 
			
		||||
	/* If any CFString could not be created (e.g., due to UTF8 invalid chars), return OS unsupported functionality */
 | 
			
		||||
	if (cf_str == nullptr || cf_value == nullptr) return -1;
 | 
			
		||||
 | 
			
		||||
	return CFStringFindWithOptionsAndLocale(cf_str.get(), cf_value.get(), CFRangeMake(0, CFStringGetLength(cf_str.get())), flags, _osx_locale.get(), nullptr) ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* virtual */ void OSXStringIterator::SetString(const char *s)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,7 @@ public:
 | 
			
		||||
void MacOSResetScriptCache(FontSize size);
 | 
			
		||||
void MacOSSetCurrentLocaleName(const char *iso_code);
 | 
			
		||||
int MacOSStringCompare(std::string_view s1, std::string_view s2);
 | 
			
		||||
int MacOSStringContains(const std::string_view str, const std::string_view value, bool case_insensitive);
 | 
			
		||||
 | 
			
		||||
void MacOSRegisterExternalFont(const char *file_path);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -79,8 +79,8 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
 | 
			
		||||
				if (!font_style.empty() && !StrEqualsIgnoreCase(font_style, (char *)style)) continue;
 | 
			
		||||
 | 
			
		||||
				/* Font config takes the best shot, which, if the family name is spelled
 | 
			
		||||
					* wrongly a 'random' font, so check whether the family name is the
 | 
			
		||||
					* same as the supplied name */
 | 
			
		||||
				 * wrongly a 'random' font, so check whether the family name is the
 | 
			
		||||
				 * same as the supplied name */
 | 
			
		||||
				if (StrEqualsIgnoreCase(font_family, (char *)family)) {
 | 
			
		||||
					err = FT_New_Face(_library, (char *)file, index, face);
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -866,7 +866,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
 | 
			
		||||
			/* Convert unix -> dos newlines because the edit box only supports that properly :( */
 | 
			
		||||
			const char *unix_nl = CrashLogWindows::current->crashlog;
 | 
			
		||||
			char *p = dos_nl;
 | 
			
		||||
			WChar c;
 | 
			
		||||
			char32_t c;
 | 
			
		||||
			while ((c = Utf8Consume(&unix_nl)) && p < (dos_nl + dos_nl_length - 1) - 4) { // 4 is max number of bytes per character
 | 
			
		||||
				if (c == '\n') p += Utf8Encode(p, '\r');
 | 
			
		||||
				p += Utf8Encode(p, c);
 | 
			
		||||
 
 | 
			
		||||
@@ -276,7 +276,7 @@ void Win32FontCache::ClearFontCache()
 | 
			
		||||
	return new_glyph.sprite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(WChar key)
 | 
			
		||||
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key)
 | 
			
		||||
{
 | 
			
		||||
	assert(IsPrintable(key));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ public:
 | 
			
		||||
	Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels);
 | 
			
		||||
	~Win32FontCache();
 | 
			
		||||
	void ClearFontCache() override;
 | 
			
		||||
	GlyphID MapCharToGlyph(WChar key) override;
 | 
			
		||||
	GlyphID MapCharToGlyph(char32_t key) override;
 | 
			
		||||
	std::string GetFontName() override { return this->fontname; }
 | 
			
		||||
	const void *GetOSHandle() override { return &this->logfont; }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,7 @@ public:
 | 
			
		||||
		int CountRuns() const override { return (uint)this->size();  }
 | 
			
		||||
		const VisualRun &GetVisualRun(int run) const override { return this->at(run);  }
 | 
			
		||||
 | 
			
		||||
		int GetInternalCharLength(WChar c) const override
 | 
			
		||||
		int GetInternalCharLength(char32_t c) const override
 | 
			
		||||
		{
 | 
			
		||||
			/* Uniscribe uses UTF-16 internally which means we need to account for surrogate pairs. */
 | 
			
		||||
			return c >= 0x010000U ? 2 : 1;
 | 
			
		||||
@@ -537,7 +537,7 @@ const int *UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() con
 | 
			
		||||
	while (*s != '\0') {
 | 
			
		||||
		size_t idx = s - string_base;
 | 
			
		||||
 | 
			
		||||
		WChar c = Utf8Consume(&s);
 | 
			
		||||
		char32_t c = Utf8Consume(&s);
 | 
			
		||||
		if (c < 0x10000) {
 | 
			
		||||
			utf16_str.push_back((wchar_t)c);
 | 
			
		||||
		} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,22 +29,22 @@ public:
 | 
			
		||||
	static const bool SUPPORTS_RTL = true;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Get the actual ParagraphLayout for the given buffer.
 | 
			
		||||
	* @param buff The begin of the buffer.
 | 
			
		||||
	* @param buff_end The location after the last element in the buffer.
 | 
			
		||||
	* @param fontMapping THe mapping of the fonts.
 | 
			
		||||
	* @return The ParagraphLayout instance.
 | 
			
		||||
	*/
 | 
			
		||||
	 * Get the actual ParagraphLayout for the given buffer.
 | 
			
		||||
	 * @param buff The begin of the buffer.
 | 
			
		||||
	 * @param buff_end The location after the last element in the buffer.
 | 
			
		||||
	 * @param fontMapping THe mapping of the fonts.
 | 
			
		||||
	 * @return The ParagraphLayout instance.
 | 
			
		||||
	 */
 | 
			
		||||
	static ParagraphLayouter *GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Append a wide character to the internal buffer.
 | 
			
		||||
	* @param buff        The buffer to append to.
 | 
			
		||||
	* @param buffer_last The end of the buffer.
 | 
			
		||||
	* @param c           The character to add.
 | 
			
		||||
	* @return The number of buffer spaces that were used.
 | 
			
		||||
	*/
 | 
			
		||||
	static size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c)
 | 
			
		||||
	 * Append a wide character to the internal buffer.
 | 
			
		||||
	 * @param buff        The buffer to append to.
 | 
			
		||||
	 * @param buffer_last The end of the buffer.
 | 
			
		||||
	 * @param c           The character to add.
 | 
			
		||||
	 * @return The number of buffer spaces that were used.
 | 
			
		||||
	 */
 | 
			
		||||
	static size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, char32_t c)
 | 
			
		||||
	{
 | 
			
		||||
		assert(buff < buffer_last);
 | 
			
		||||
		if (c >= 0x010000U) {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
#define NO_SHOBJIDL_SORTDIRECTION // Avoid multiple definition of SORT_ASCENDING
 | 
			
		||||
#include <shlobj.h> /* SHGetFolderPath */
 | 
			
		||||
#include <shellapi.h>
 | 
			
		||||
#include <winnls.h>
 | 
			
		||||
#include "win32.h"
 | 
			
		||||
#include "../../fios.h"
 | 
			
		||||
#include "../../core/alloc_func.hpp"
 | 
			
		||||
@@ -715,6 +716,43 @@ int OTTDStringCompare(std::string_view s1, std::string_view s2)
 | 
			
		||||
	return CompareString(MAKELCID(_current_language->winlangid, SORT_DEFAULT), NORM_IGNORECASE, s1_buf, -1, s2_buf, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Search if a string is contained in another string using the current locale.
 | 
			
		||||
 *
 | 
			
		||||
 * @param str String to search in.
 | 
			
		||||
 * @param value String to search for.
 | 
			
		||||
 * @param case_insensitive Search case-insensitive.
 | 
			
		||||
 * @return 1 if value was found, 0 if it was not found, or -1 if not supported by the OS.
 | 
			
		||||
 */
 | 
			
		||||
int Win32StringContains(const std::string_view str, const std::string_view value, bool case_insensitive)
 | 
			
		||||
{
 | 
			
		||||
	typedef int (WINAPI *PFNFINDNLSSTRINGEX)(LPCWSTR, DWORD, LPCWSTR, int, LPCWSTR, int, LPINT, LPNLSVERSIONINFO, LPVOID, LPARAM);
 | 
			
		||||
	static PFNFINDNLSSTRINGEX _FindNLSStringEx = nullptr;
 | 
			
		||||
	static bool first_time = true;
 | 
			
		||||
 | 
			
		||||
	if (first_time) {
 | 
			
		||||
		_FindNLSStringEx = GetProcAddressT<PFNFINDNLSSTRINGEX>(GetModuleHandle(L"Kernel32"), "FindNLSStringEx");
 | 
			
		||||
		first_time = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (_FindNLSStringEx != nullptr) {
 | 
			
		||||
		int len_str = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), nullptr, 0);
 | 
			
		||||
		int len_value = MultiByteToWideChar(CP_UTF8, 0, value.data(), (int)value.size(), nullptr, 0);
 | 
			
		||||
 | 
			
		||||
		if (len_str != 0 && len_value != 0) {
 | 
			
		||||
			std::wstring str_str(len_str, L'\0'); // len includes terminating null
 | 
			
		||||
			std::wstring str_value(len_value, L'\0');
 | 
			
		||||
 | 
			
		||||
			MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), str_str.data(), len_str);
 | 
			
		||||
			MultiByteToWideChar(CP_UTF8, 0, value.data(), (int)value.size(), str_value.data(), len_value);
 | 
			
		||||
 | 
			
		||||
			return _FindNLSStringEx(_cur_iso_locale, FIND_FROMSTART | (case_insensitive ? LINGUISTIC_IGNORECASE : 0), str_str.data(), -1, str_value.data(), -1, nullptr, nullptr, nullptr, 0) >= 0 ? 1 : 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1; // Failure indication.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static DWORD main_thread_id;
 | 
			
		||||
static DWORD game_thread_id;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ wchar_t *convert_to_fs(const std::string_view name, wchar_t *utf16_buf, size_t b
 | 
			
		||||
 | 
			
		||||
void Win32SetCurrentLocaleName(const char *iso_code);
 | 
			
		||||
int OTTDStringCompare(std::string_view s1, std::string_view s2);
 | 
			
		||||
int Win32StringContains(const std::string_view str, const std::string_view value, bool case_insensitive);
 | 
			
		||||
 | 
			
		||||
#ifdef __MINGW32__
 | 
			
		||||
			/* GCC doesn't understand the expected usage of GetProcAddress(). */
 | 
			
		||||
 
 | 
			
		||||
@@ -336,7 +336,7 @@ static const NWidgetPart _nested_osk_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _osk_desc(
 | 
			
		||||
static WindowDesc _osk_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_CENTER, nullptr, 0, 0,
 | 
			
		||||
	WC_OSK, WC_NONE,
 | 
			
		||||
	0,
 | 
			
		||||
 
 | 
			
		||||
@@ -525,12 +525,6 @@ public:
 | 
			
		||||
		return next_trackdir;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static uint stDistanceToTile(const RoadVehicle *v, TileIndex tile)
 | 
			
		||||
	{
 | 
			
		||||
		Tpf pf;
 | 
			
		||||
		return pf.DistanceToTile(v, tile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline uint DistanceToTile(const RoadVehicle *v, TileIndex dst_tile)
 | 
			
		||||
	{
 | 
			
		||||
		/* handle special case - when current tile is the destination tile */
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ static const NWidgetPart _nested_plans_widgets[] = {
 | 
			
		||||
	EndContainer(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static WindowDesc _plans_desc(
 | 
			
		||||
static WindowDesc _plans_desc(__FILE__, __LINE__,
 | 
			
		||||
	WDP_AUTO, "plans", 350, 100,
 | 
			
		||||
	WC_PLANS, WC_NONE,
 | 
			
		||||
	WDF_CONSTRUCTION,
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user