Changeset - r25655:1030dcb7eb52
[Not reviewed]
master
! ! !
rubidium42 - 3 years ago 2021-06-12 07:10:17
rubidium@openttd.org
Codechange: convert printf DEBUG statements to fmt Debug statements
100 files changed:
Changeset was too big and was cut off... Show full diff anyway
0 comments (0 inline, 0 general)
src/ai/ai_core.cpp
Show inline comments
 
@@ -204,13 +204,13 @@
 
	/* Check for both newgame as current game if we can reload the AIInfo inside
 
	 *  the AIConfig. If not, remove the AI from the list (which will assign
 
	 *  a random new AI on reload). */
 
	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 
		if (_settings_game.ai_config[c] != nullptr && _settings_game.ai_config[c]->HasScript()) {
 
			if (!_settings_game.ai_config[c]->ResetInfo(true)) {
 
				DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
 
				Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
 
				_settings_game.ai_config[c]->Change(nullptr);
 
				if (Company::IsValidAiID(c)) {
 
					/* The code belonging to an already running AI was deleted. We can only do
 
					 * one thing here to keep everything sane and that is kill the AI. After
 
					 * killing the offending AI we start a random other one in it's place, just
 
					 * like what would happen if the AI was missing during loading. */
 
@@ -221,13 +221,13 @@
 
				/* Update the reference in the Company struct. */
 
				Company::Get(c)->ai_info = _settings_game.ai_config[c]->GetInfo();
 
			}
 
		}
 
		if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
 
			if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
 
				DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
 
				Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
 
				_settings_newgame.ai_config[c]->Change(nullptr);
 
			}
 
		}
 
	}
 
}
 

	
src/ai/ai_info.cpp
Show inline comments
 
@@ -86,13 +86,13 @@ template <> const char *GetClassName<AII
 
		info->use_as_random = true;
 
	}
 
	/* Try to get the API version the AI is written for. */
 
	if (info->engine->MethodExists(*info->SQ_instance, "GetAPIVersion")) {
 
		if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
 
		if (!CheckAPIVersion(info->api_version)) {
 
			DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
 
			Debug(script, 1, "Loading info.nut from ({}.{}): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
 
			return SQ_ERROR;
 
		}
 
	} else {
 
		info->api_version = stredup("0.7");
 
	}
 

	
src/ai/ai_scanner.cpp
Show inline comments
 
@@ -63,13 +63,13 @@ AIInfo *AIScannerInfo::SelectRandomAI() 
 
	for (const auto &item : info_single_list) {
 
		AIInfo *i = static_cast<AIInfo *>(item.second);
 
		if (i->UseAsRandomAI()) num_random_ais++;
 
	}
 

	
 
	if (num_random_ais == 0) {
 
		DEBUG(script, 0, "No suitable AI found, loading 'dummy' AI.");
 
		Debug(script, 0, "No suitable AI found, loading 'dummy' AI.");
 
		return this->info_dummy;
 
	}
 

	
 
	/* Find a random AI */
 
	uint pos;
 
	if (_networking) {
src/aircraft_cmd.cpp
Show inline comments
 
@@ -1783,13 +1783,13 @@ static void AirportGoToNextPosition(Airc
 

	
 
/* gets pos from vehicle and next orders */
 
static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
 
{
 
	/* error handling */
 
	if (v->pos >= apc->nofelements) {
 
		DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->pos, apc->nofelements-1);
 
		Debug(misc, 0, "[Ap] position {} is not valid for current airport. Max position is {}", v->pos, apc->nofelements-1);
 
		assert(v->pos < apc->nofelements);
 
	}
 

	
 
	const AirportFTA *current = &apc->layout[v->pos];
 
	/* we have arrived in an important state (eg terminal, hangar, etc.) */
 
	if (current->heading == v->state) {
 
@@ -1822,13 +1822,13 @@ static bool AirportMove(Aircraft *v, con
 
			} // move to next position
 
			return false;
 
		}
 
		current = current->next;
 
	} while (current != nullptr);
 

	
 
	DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index);
 
	Debug(misc, 0, "[Ap] cannot move further on Airport! (pos {} state {}) for vehicle {}", v->pos, v->state, v->index);
 
	NOT_REACHED();
 
}
 

	
 
/** returns true if the road ahead is busy, eg. you must wait before proceeding. */
 
static bool AirportHasBlock(Aircraft *v, const AirportFTA *current_pos, const AirportFTAClass *apc)
 
{
src/base_media_func.h
Show inline comments
 
@@ -19,14 +19,14 @@
 
 * Try to read a single piece of metadata and return false if it doesn't exist.
 
 * @param name the name of the item to fetch.
 
 */
 
#define fetch_metadata(name) \
 
	item = metadata->GetItem(name, false); \
 
	if (item == nullptr || !item->value.has_value() || item->value->empty()) { \
 
		DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \
 
		DEBUG(grf, 0, "  Is %s readable for the user running OpenTTD?", full_filename); \
 
		Debug(grf, 0, "Base " SET_TYPE "set detail loading: {} field missing.", name); \
 
		Debug(grf, 0, "  Is {} readable for the user running OpenTTD?", full_filename); \
 
		return false; \
 
	}
 

	
 
/**
 
 * Read the set information from a loaded ini.
 
 * @param ini      the ini to read from
 
@@ -71,13 +71,13 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
	IniGroup *origin = ini->GetGroup("origin");
 
	for (uint i = 0; i < Tnum_files; i++) {
 
		MD5File *file = &this->files[i];
 
		/* Find the filename first. */
 
		item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
 
		if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
 
			DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
 
			Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
 
			return false;
 
		}
 

	
 
		if (!item->value.has_value()) {
 
			file->filename = nullptr;
 
			/* If we list no file, that file must be valid */
 
@@ -89,26 +89,26 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
		const char *filename = item->value->c_str();
 
		file->filename = str_fmt("%s%s", path, filename);
 

	
 
		/* Then find the MD5 checksum */
 
		item = md5s->GetItem(filename, false);
 
		if (item == nullptr || !item->value.has_value()) {
 
			DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename);
 
			Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
 
			return false;
 
		}
 
		const char *c = item->value->c_str();
 
		for (uint i = 0; i < sizeof(file->hash) * 2; i++, c++) {
 
			uint j;
 
			if ('0' <= *c && *c <= '9') {
 
				j = *c - '0';
 
			} else if ('a' <= *c && *c <= 'f') {
 
				j = *c - 'a' + 10;
 
			} else if ('A' <= *c && *c <= 'F') {
 
				j = *c - 'A' + 10;
 
			} else {
 
				DEBUG(grf, 0, "Malformed MD5 checksum specified for: %s (in %s)", filename, full_filename);
 
				Debug(grf, 0, "Malformed MD5 checksum specified for: {} (in {})", filename, full_filename);
 
				return false;
 
			}
 
			if (i % 2 == 0) {
 
				file->hash[i / 2] = j << 4;
 
			} else {
 
				file->hash[i / 2] |= j;
 
@@ -116,13 +116,13 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
		}
 

	
 
		/* Then find the warning message when the file's missing */
 
		item = origin->GetItem(filename, false);
 
		if (item == nullptr) item = origin->GetItem("default", false);
 
		if (item == nullptr || !item->value.has_value()) {
 
			DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
 
			Debug(grf, 1, "No origin warning message specified for: {}", filename);
 
			file->missing_warning = stredup("");
 
		} else {
 
			file->missing_warning = stredup(item->value->c_str());
 
		}
 

	
 
		file->check_result = T::CheckMD5(file, BASESET_DIR);
 
@@ -133,30 +133,30 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
			case MD5File::CR_MATCH:
 
				this->valid_files++;
 
				this->found_files++;
 
				break;
 

	
 
			case MD5File::CR_MISMATCH:
 
				DEBUG(grf, 1, "MD5 checksum mismatch for: %s (in %s)", filename, full_filename);
 
				Debug(grf, 1, "MD5 checksum mismatch for: {} (in {})", filename, full_filename);
 
				this->found_files++;
 
				break;
 

	
 
			case MD5File::CR_NO_FILE:
 
				DEBUG(grf, 1, "The file %s specified in %s is missing", filename, full_filename);
 
				Debug(grf, 1, "The file {} specified in {} is missing", filename, full_filename);
 
				break;
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
template <class Tbase_set>
 
bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
 
{
 
	bool ret = false;
 
	DEBUG(grf, 1, "Checking %s for base " SET_TYPE " set", filename.c_str());
 
	Debug(grf, 1, "Checking {} for base " SET_TYPE " set", filename);
 

	
 
	Tbase_set *set = new Tbase_set();
 
	IniFile *ini = new IniFile();
 
	std::string path{ filename, basepath_length };
 
	ini->LoadFromDisk(path, BASESET_DIR);
 

	
 
@@ -176,13 +176,13 @@ bool BaseMedia<Tbase_set>::AddFile(const
 
			}
 
		}
 
		if (duplicate != nullptr) {
 
			/* The more complete set takes precedence over the version number. */
 
			if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
 
					duplicate->valid_files > set->valid_files) {
 
				DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name.c_str(), set->version,
 
				Debug(grf, 1, "Not adding {} ({}) as base " SET_TYPE " set (duplicate, {})", set->name, set->version,
 
						duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
 
				set->next = BaseMedia<Tbase_set>::duplicate_sets;
 
				BaseMedia<Tbase_set>::duplicate_sets = set;
 
			} else {
 
				Tbase_set **prev = &BaseMedia<Tbase_set>::available_sets;
 
				while (*prev != duplicate) prev = &(*prev)->next;
 
@@ -192,13 +192,13 @@ bool BaseMedia<Tbase_set>::AddFile(const
 

	
 
				/* 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 */
 
				if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
 

	
 
				DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name.c_str(), duplicate->version,
 
				Debug(grf, 1, "Removing {} ({}) as base " SET_TYPE " set (duplicate, {})", duplicate->name, duplicate->version,
 
						duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
 
				duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
 
				BaseMedia<Tbase_set>::duplicate_sets = duplicate;
 
				ret = true;
 
			}
 
		} else {
 
@@ -206,13 +206,13 @@ bool BaseMedia<Tbase_set>::AddFile(const
 
			while (*last != nullptr) last = &(*last)->next;
 

	
 
			*last = set;
 
			ret = true;
 
		}
 
		if (ret) {
 
			DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name.c_str(), set->version);
 
			Debug(grf, 1, "Adding {} ({}) as base " SET_TYPE " set", set->name, set->version);
 
		}
 
	} else {
 
		delete set;
 
	}
 

	
 
	delete ini;
src/blitter/32bpp_anim.cpp
Show inline comments
 
@@ -304,13 +304,13 @@ void Blitter_32bppAnim::DrawColourMappin
 
			udst = udst - width + _screen.pitch;
 
			anim = anim - width + this->anim_buf_pitch;
 
		} while (--height);
 
		return;
 
	}
 

	
 
	DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
 
	Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
 
}
 

	
 
void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
 
{
 
	*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
 

	
src/blitter/32bpp_simple.cpp
Show inline comments
 
@@ -103,13 +103,13 @@ void Blitter_32bppSimple::DrawColourMapp
 
			}
 
			udst = udst - width + _screen.pitch;
 
		} while (--height);
 
		return;
 
	}
 

	
 
	DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
 
	Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
 
}
 

	
 
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
 
{
 
	Blitter_32bppSimple::Pixel *dst;
 
	Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite->height * (size_t)sprite->width * sizeof(*dst));
src/blitter/factory.hpp
Show inline comments
 
@@ -67,13 +67,13 @@ protected:
 
			 * Only add when the blitter is usable. Do not bail out or
 
			 * do more special things since the blitters are always
 
			 * instantiated upon start anyhow and freed upon shutdown.
 
			 */
 
			blitters.insert(Blitters::value_type(this->name, this));
 
		} else {
 
			DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
 
			Debug(driver, 1, "Not registering blitter {} as it is not usable", name);
 
		}
 
	}
 

	
 
	/**
 
	 * Is the blitter usable with the current drivers and hardware config?
 
	 * @return True if the blitter can be instantiated.
 
@@ -101,13 +101,13 @@ public:
 
		if (b == nullptr) return nullptr;
 

	
 
		Blitter *newb = b->CreateInstance();
 
		delete *GetActiveBlitter();
 
		*GetActiveBlitter() = newb;
 

	
 
		DEBUG(driver, 1, "Successfully %s blitter '%s'", name.empty() ? "probed" : "loaded", newb->GetName());
 
		Debug(driver, 1, "Successfully {} blitter '{}'", name.empty() ? "probed" : "loaded", newb->GetName());
 
		return newb;
 
	}
 

	
 
	/**
 
	 * Get the blitter factory with the given name.
 
	 * @param name the blitter factory to select.
src/command.cpp
Show inline comments
 
@@ -693,13 +693,13 @@ CommandCost DoCommandPInternal(TileIndex
 
	 * we bail out here. */
 
	if (res.Failed() || estimate_only ||
 
			(!test_and_exec_can_differ && !CheckCompanyHasMoney(res))) {
 
		if (!_networking || _generating_world || (cmd & CMD_NETWORK_COMMAND) != 0) {
 
			/* Log the failed command as well. Just to be able to be find
 
			 * causes of desyncs due to bad command test implementations. */
 
			DEBUG(desync, 1, "cmdf: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text.c_str(), GetCommandName(cmd));
 
			Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
 
		}
 
		cur_company.Restore();
 
		return_dcpi(res);
 
	}
 

	
 
	/*
 
@@ -713,13 +713,13 @@ CommandCost DoCommandPInternal(TileIndex
 
		/* Don't return anything special here; no error, no costs.
 
		 * This way it's not handled by DoCommand and only the
 
		 * actual execution of the command causes messages. Also
 
		 * reset the storages as we've not executed the command. */
 
		return_dcpi(CommandCost());
 
	}
 
	DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text.c_str(), GetCommandName(cmd));
 
	Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
 

	
 
	/* Actually try and execute the command. If no cost-type is given
 
	 * use the construction one */
 
	_cleared_object_areas.clear();
 
	BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND);
 
	CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text);
src/console.cpp
Show inline comments
 
@@ -268,13 +268,13 @@ static std::string RemoveUnderscores(std
 
 */
 
static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
 
{
 
	char  alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' };
 
	char *alias_stream = alias_buffer;
 

	
 
	DEBUG(console, 6, "Requested command is an alias; parsing...");
 
	Debug(console, 6, "Requested command is an alias; parsing...");
 

	
 
	if (recurse_count > ICON_MAX_RECURSE) {
 
		IConsoleError("Too many alias expansions, recursion limit reached. Aborting");
 
		return;
 
	}
 

	
 
@@ -369,13 +369,13 @@ void IConsoleCmdExec(const char *cmdstr,
 
			IConsoleError("command contains malformed characters, aborting");
 
			IConsolePrintF(CC_ERROR, "ERROR: command was: '%s'", cmdstr);
 
			return;
 
		}
 
	}
 

	
 
	DEBUG(console, 4, "Executing cmdline: '%s'", cmdstr);
 
	Debug(console, 4, "Executing cmdline: '{}'", cmdstr);
 

	
 
	memset(&tokens, 0, sizeof(tokens));
 
	memset(&tokenstream, 0, sizeof(tokenstream));
 

	
 
	/* 1. Split up commandline into tokens, separated by spaces, commands
 
	 * enclosed in "" are taken as one token. We can only go as far as the amount
 
@@ -429,13 +429,13 @@ void IConsoleCmdExec(const char *cmdstr,
 
			}
 
			break;
 
		}
 
	}
 

	
 
	for (uint i = 0; i < lengthof(tokens) && tokens[i] != nullptr; i++) {
 
		DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]);
 
		Debug(console, 8, "Token {} is: '{}'", i, tokens[i]);
 
	}
 

	
 
	if (StrEmpty(tokens[0])) return; // don't execute empty commands
 
	/* 2. Determine type of command (cmd or alias) and execute
 
	 * First try commands, then aliases. Execute
 
	 * the found action taking into account its hooking code
src/core/backup_type.hpp
Show inline comments
 
@@ -48,13 +48,13 @@ struct Backup {
 
	{
 
		/* Check whether restoration was done */
 
		if (this->valid)
 
		{
 
			/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
 
			 * Exceptions are especially used to abort world generation. */
 
			DEBUG(misc, 0, "%s:%d: Backed-up value was not restored!", this->file, this->line);
 
			Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->file, this->line);
 
			this->Restore();
 
		}
 
	}
 

	
 
	/**
 
	 * Checks whether the variable was already restored.
src/core/random_func.cpp
Show inline comments
 
@@ -69,13 +69,13 @@ void SetRandomSeed(uint32 seed)
 
}
 

	
 
#ifdef RANDOM_DEBUG
 
uint32 DoRandom(int line, const char *file)
 
{
 
	if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
 
		DEBUG(random, 0, "%08x; %02x; %04x; %02x; %s:%d", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
 
		Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
 
	}
 

	
 
	return _random.Next();
 
}
 

	
 
uint32 DoRandomRange(uint32 limit, int line, const char *file)
src/debug.h
Show inline comments
 
@@ -102,13 +102,13 @@ const char *GetDebugString();
 
	static uint64 _sum_ = 0;\
 
	static uint32 _i_ = 0;
 

	
 
#define TOC(str, count)\
 
	_sum_ += ottd_rdtsc() - _xxx_;\
 
	if (++_i_ == count) {\
 
		DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " [avg: %.1f]", str, _sum_, _sum_/(double)_i_);\
 
		Debug(misc, 0, "[{}] {} [avg: {:.1f}]", str, _sum_, _sum_/(double)_i_);\
 
		_i_ = 0;\
 
		_sum_ = 0;\
 
	}\
 
}
 

	
 
/* Chrono based version. The output is in microseconds. */
 
@@ -117,13 +117,13 @@ const char *GetDebugString();
 
	static uint64 _sum_ = 0;\
 
	static uint32 _i_ = 0;
 

	
 
#define TOCC(str, _count_)\
 
	_sum_ += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - _start_)).count();\
 
	if (++_i_ == _count_) {\
 
		DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " us [avg: %.1f us]", str, _sum_, _sum_/(double)_i_);\
 
		Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", str, _sum_, _sum_/(double)_i_);\
 
		_i_ = 0;\
 
		_sum_ = 0;\
 
	}\
 
}
 

	
 

	
src/driver.cpp
Show inline comments
 
@@ -118,19 +118,19 @@ bool DriverFactoryBase::SelectDriverImpl
 
				Driver *oldd = *GetActiveDriver(type);
 
				Driver *newd = d->CreateInstance();
 
				*GetActiveDriver(type) = newd;
 

	
 
				const char *err = newd->Start({});
 
				if (err == nullptr) {
 
					DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
 
					Debug(driver, 1, "Successfully probed {} driver '{}'", GetDriverTypeName(type), d->name);
 
					delete oldd;
 
					return true;
 
				}
 

	
 
				*GetActiveDriver(type) = oldd;
 
				DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
 
				Debug(driver, 1, "Probing {} driver '{}' failed with error: {}", GetDriverTypeName(type), d->name, err);
 
				delete newd;
 

	
 
				if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
 
					_video_hw_accel = false;
 
					ErrorMessageData msg(STR_VIDEO_DRIVER_ERROR, STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION);
 
					ScheduleErrorMessage(msg);
 
@@ -167,13 +167,13 @@ bool DriverFactoryBase::SelectDriverImpl
 
			const char *err = newd->Start(parms);
 
			if (err != nullptr) {
 
				delete newd;
 
				usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
 
			}
 

	
 
			DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
 
			Debug(driver, 1, "Successfully loaded {} driver '{}'", GetDriverTypeName(type), d->name);
 
			delete *GetActiveDriver(type);
 
			*GetActiveDriver(type) = newd;
 
			return true;
 
		}
 
		usererror("No such %s driver: %s\n", GetDriverTypeName(type), dname.c_str());
 
	}
src/fileio.cpp
Show inline comments
 
@@ -415,13 +415,13 @@ uint TarScanner::DoScan(Subdirectory sd)
 
	if (sd == BASESET_DIR || sd == NEWGRF_DIR) num += this->Scan(".tar", OLD_DATA_DIR, false);
 
	return num;
 
}
 

	
 
/* static */ uint TarScanner::DoScan(TarScanner::Mode mode)
 
{
 
	DEBUG(misc, 1, "Scanning for tars");
 
	Debug(misc, 1, "Scanning for tars");
 
	TarScanner fs;
 
	uint num = 0;
 
	if (mode & TarScanner::BASESET) {
 
		num += fs.DoScan(BASESET_DIR);
 
	}
 
	if (mode & TarScanner::NEWGRF) {
 
@@ -436,13 +436,13 @@ uint TarScanner::DoScan(Subdirectory sd)
 
		num += fs.DoScan(GAME_LIBRARY_DIR);
 
	}
 
	if (mode & TarScanner::SCENARIO) {
 
		num += fs.DoScan(SCENARIO_DIR);
 
		num += fs.DoScan(HEIGHTMAP_DIR);
 
	}
 
	DEBUG(misc, 1, "Scan complete, found %d files", num);
 
	Debug(misc, 1, "Scan complete, found {} files", num);
 
	return num;
 
}
 

	
 
/**
 
 * Add a single file to the scanned files of a tar, circumventing the scanning code.
 
 * @param sd       The sub directory the file is in.
 
@@ -515,13 +515,13 @@ bool TarScanner::AddFile(const std::stri
 

	
 
		/* Check if we have the new tar-format (ustar) or the old one (a lot of zeros after 'link' field) */
 
		if (strncmp(th.magic, "ustar", 5) != 0 && memcmp(&th.magic, &empty[0], 512 - offsetof(TarHeader, magic)) != 0) {
 
			/* If we have only zeros in the block, it can be an end-of-file indicator */
 
			if (memcmp(&th, &empty[0], 512) == 0) continue;
 

	
 
			DEBUG(misc, 0, "The file '%s' isn't a valid tar-file", filename.c_str());
 
			Debug(misc, 0, "The file '{}' isn't a valid tar-file", filename);
 
			fclose(f);
 
			return false;
 
		}
 

	
 
		name[0] = '\0';
 

	
 
@@ -552,13 +552,13 @@ bool TarScanner::AddFile(const std::stri
 
				entry.size         = skip;
 
				entry.position     = pos;
 

	
 
				/* Convert to lowercase and our PATHSEPCHAR */
 
				SimplifyFileName(name);
 

	
 
				DEBUG(misc, 6, "Found file in tar: %s (" PRINTF_SIZE " bytes, " PRINTF_SIZE " offset)", name, skip, pos);
 
				Debug(misc, 6, "Found file in tar: {} ({} bytes, {} offset)", name, skip, pos);
 
				if (_tar_filelist[this->subdir].insert(TarFileList::value_type(name, entry)).second) num++;
 

	
 
				break;
 
			}
 

	
 
			case '1': // hard links
 
@@ -571,13 +571,13 @@ bool TarScanner::AddFile(const std::stri
 
				/* Convert to lowercase and our PATHSEPCHAR */
 
				SimplifyFileName(name);
 
				SimplifyFileName(link);
 

	
 
				/* Only allow relative links */
 
				if (link[0] == PATHSEPCHAR) {
 
					DEBUG(misc, 1, "Ignoring absolute link in tar: %s -> %s", name, link);
 
					Debug(misc, 1, "Ignoring absolute link in tar: {} -> {}", name, link);
 
					break;
 
				}
 

	
 
				/* Process relative path.
 
				 * Note: The destination of links must not contain any directory-links. */
 
				strecpy(dest, name, lastof(dest));
 
@@ -597,13 +597,13 @@ bool TarScanner::AddFile(const std::stri
 

	
 
					if (strcmp(pos, ".") == 0) {
 
						/* Skip '.' (current dir) */
 
					} else if (strcmp(pos, "..") == 0) {
 
						/* level up */
 
						if (dest[0] == '\0') {
 
							DEBUG(misc, 1, "Ignoring link pointing outside of data directory: %s -> %s", name, link);
 
							Debug(misc, 1, "Ignoring link pointing outside of data directory: {} -> {}", name, link);
 
							break;
 
						}
 

	
 
						/* Truncate 'dest' after last PATHSEPCHAR.
 
						 * This assumes that the truncated part is a real directory and not a link. */
 
						destpos = strrchr(dest, PATHSEPCHAR);
 
@@ -613,52 +613,52 @@ bool TarScanner::AddFile(const std::stri
 
						/* Append at end of 'dest' */
 
						if (destpos != dest) destpos = strecpy(destpos, PATHSEP, lastof(dest));
 
						destpos = strecpy(destpos, pos, lastof(dest));
 
					}
 

	
 
					if (destpos >= lastof(dest)) {
 
						DEBUG(misc, 0, "The length of a link in tar-file '%s' is too large (malformed?)", filename.c_str());
 
						Debug(misc, 0, "The length of a link in tar-file '{}' is too large (malformed?)", filename);
 
						fclose(f);
 
						return false;
 
					}
 

	
 
					pos = next;
 
				}
 

	
 
				/* Store links in temporary list */
 
				DEBUG(misc, 6, "Found link in tar: %s -> %s", name, dest);
 
				Debug(misc, 6, "Found link in tar: {} -> {}", name, dest);
 
				links.insert(TarLinkList::value_type(name, dest));
 

	
 
				break;
 
			}
 

	
 
			case '5': // directory
 
				/* Convert to lowercase and our PATHSEPCHAR */
 
				SimplifyFileName(name);
 

	
 
				/* Store the first directory name we detect */
 
				DEBUG(misc, 6, "Found dir in tar: %s", name);
 
				Debug(misc, 6, "Found dir in tar: {}", name);
 
				if (_tar_list[this->subdir][filename].empty()) _tar_list[this->subdir][filename] = name;
 
				break;
 

	
 
			default:
 
				/* Ignore other types */
 
				break;
 
		}
 

	
 
		/* Skip to the next block.. */
 
		skip = Align(skip, 512);
 
		if (fseek(f, skip, SEEK_CUR) < 0) {
 
			DEBUG(misc, 0, "The file '%s' can't be read as a valid tar-file", filename.c_str());
 
			Debug(misc, 0, "The file '{}' can't be read as a valid tar-file", filename);
 
			fclose(f);
 
			return false;
 
		}
 
		pos += skip;
 
	}
 

	
 
	DEBUG(misc, 1, "Found tar '%s' with " PRINTF_SIZE " new files", filename.c_str(), num);
 
	Debug(misc, 1, "Found tar '{}' with {} new files", filename, num);
 
	fclose(f);
 

	
 
	/* Resolve file links and store directory links.
 
	 * We restrict usage of links to two cases:
 
	 *  1) Links to directories:
 
	 *      Both the source path and the destination path must NOT contain any further links.
 
@@ -690,62 +690,62 @@ bool ExtractTar(const std::string &tar_f
 
	if (it == _tar_list[subdir].end()) return false;
 

	
 
	const auto &dirname = (*it).second;
 

	
 
	/* The file doesn't have a sub directory! */
 
	if (dirname.empty()) {
 
		DEBUG(misc, 1, "Extracting %s failed; archive rejected, the contents must be in a sub directory", tar_filename.c_str());
 
		Debug(misc, 1, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename);
 
		return false;
 
	}
 

	
 
	std::string filename = tar_filename;
 
	auto p = filename.find_last_of(PATHSEPCHAR);
 
	/* The file's path does not have a separator? */
 
	if (p == std::string::npos) return false;
 

	
 
	filename.replace(p + 1, std::string::npos, dirname);
 
	DEBUG(misc, 8, "Extracting %s to directory %s", tar_filename.c_str(), filename.c_str());
 
	Debug(misc, 8, "Extracting {} to directory {}", tar_filename, filename);
 
	FioCreateDirectory(filename);
 

	
 
	for (TarFileList::iterator it2 = _tar_filelist[subdir].begin(); it2 != _tar_filelist[subdir].end(); it2++) {
 
		if (tar_filename != it2->second.tar_filename) continue;
 

	
 
		filename.replace(p + 1, std::string::npos, it2->first);
 

	
 
		DEBUG(misc, 9, "  extracting %s", filename.c_str());
 
		Debug(misc, 9, "  extracting {}", filename);
 

	
 
		/* First open the file in the .tar. */
 
		size_t to_copy = 0;
 
		std::unique_ptr<FILE, FileDeleter> in(FioFOpenFileTar(it2->second, &to_copy));
 
		if (!in) {
 
			DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename.c_str(), tar_filename.c_str());
 
			Debug(misc, 6, "Extracting {} failed; could not open {}", filename, tar_filename);
 
			return false;
 
		}
 

	
 
		/* Now open the 'output' file. */
 
		std::unique_ptr<FILE, FileDeleter> out(fopen(filename.c_str(), "wb"));
 
		if (!out) {
 
			DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename.c_str(), filename.c_str());
 
			Debug(misc, 6, "Extracting {} failed; could not open {}", filename, filename);
 
			return false;
 
		}
 

	
 
		/* Now read from the tar and write it into the file. */
 
		char buffer[4096];
 
		size_t read;
 
		for (; to_copy != 0; to_copy -= read) {
 
			read = fread(buffer, 1, std::min(to_copy, lengthof(buffer)), in.get());
 
			if (read <= 0 || fwrite(buffer, 1, read, out.get()) != read) break;
 
		}
 

	
 
		if (to_copy != 0) {
 
			DEBUG(misc, 6, "Extracting %s failed; still %i bytes to copy", filename.c_str(), (int)to_copy);
 
			Debug(misc, 6, "Extracting {} failed; still {} bytes to copy", filename, to_copy);
 
			return false;
 
		}
 
	}
 

	
 
	DEBUG(misc, 9, "  extraction successful");
 
	Debug(misc, 9, "  extraction successful");
 
	return true;
 
}
 

	
 
#if defined(_WIN32)
 
/**
 
 * Determine the base (personal dir and game data dir) paths
 
@@ -775,13 +775,13 @@ static bool ChangeWorkingDirectoryToExec
 
	if (app_bundle != nullptr) *app_bundle = '\0';
 
#endif /* WITH_COCOA */
 
	char *s = strrchr(tmp, PATHSEPCHAR);
 
	if (s != nullptr) {
 
		*s = '\0';
 
		if (chdir(tmp) != 0) {
 
			DEBUG(misc, 0, "Directory with the binary does not exist?");
 
			Debug(misc, 0, "Directory with the binary does not exist?");
 
		} else {
 
			success = true;
 
		}
 
	}
 
	return success;
 
}
 
@@ -934,13 +934,13 @@ void DetermineBasePaths(const char *exe)
 
		_searchpaths[SP_BINARY_DIR].clear();
 
	}
 

	
 
	if (cwd[0] != '\0') {
 
		/* Go back to the current working directory. */
 
		if (chdir(cwd) != 0) {
 
			DEBUG(misc, 0, "Failed to return to working directory!");
 
			Debug(misc, 0, "Failed to return to working directory!");
 
		}
 
	}
 

	
 
#if !defined(GLOBAL_DATA_DIR)
 
	_searchpaths[SP_INSTALLATION_DIR].clear();
 
#else
 
@@ -987,13 +987,13 @@ void DeterminePaths(const char *exe, boo
 
	}
 
	AppendPathSeparator(config_home);
 
#endif
 

	
 
	for (Searchpath sp : _valid_searchpaths) {
 
		if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
 
		DEBUG(misc, 4, "%s added as search path", _searchpaths[sp].c_str());
 
		Debug(misc, 4, "{} added as search path", _searchpaths[sp]);
 
	}
 

	
 
	std::string config_dir;
 
	if (!_config_file.empty()) {
 
		config_dir = _searchpaths[SP_WORKING_DIR];
 
	} else {
 
@@ -1020,13 +1020,13 @@ void DeterminePaths(const char *exe, boo
 
			}
 
#endif
 
		}
 
		_config_file = config_dir + "openttd.cfg";
 
	}
 

	
 
	DEBUG(misc, 3, "%s found as config directory", config_dir.c_str());
 
	Debug(misc, 3, "{} found as config directory", config_dir);
 

	
 
	_highscore_file = config_dir + "hs.dat";
 
	extern std::string _hotkeys_file;
 
	_hotkeys_file = config_dir + "hotkeys.cfg";
 
	extern std::string _windows_file;
 
	_windows_file = config_dir + "windows.cfg";
 
@@ -1052,25 +1052,25 @@ void DeterminePaths(const char *exe, boo
 
	/* Make the necessary folders */
 
	FioCreateDirectory(config_dir);
 
#if defined(WITH_PERSONAL_DIR)
 
	FioCreateDirectory(_personal_dir);
 
#endif
 

	
 
	DEBUG(misc, 3, "%s found as personal directory", _personal_dir.c_str());
 
	Debug(misc, 3, "{} found as personal directory", _personal_dir);
 

	
 
	static const Subdirectory default_subdirs[] = {
 
		SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR
 
	};
 

	
 
	for (uint i = 0; i < lengthof(default_subdirs); i++) {
 
		FioCreateDirectory(_personal_dir + _subdirs[default_subdirs[i]]);
 
	}
 

	
 
	/* If we have network we make a directory for the autodownloading of content */
 
	_searchpaths[SP_AUTODOWNLOAD_DIR] = _personal_dir + "content_download" PATHSEP;
 
	DEBUG(misc, 4, "%s added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR].c_str());
 
	Debug(misc, 4, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]);
 
	FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]);
 
	FillValidSearchPaths(only_local_path);
 

	
 
	/* Create the directory for each of the types of content */
 
	const Subdirectory dirs[] = { SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR };
 
	for (uint i = 0; i < lengthof(dirs); i++) {
src/fontcache.cpp
Show inline comments
 
@@ -256,22 +256,22 @@ TrueTypeFontCache::GlyphEntry *TrueTypeF
 
	return &this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)];
 
}
 

	
 
void TrueTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate)
 
{
 
	if (this->glyph_to_sprite == nullptr) {
 
		DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs);
 
		Debug(freetype, 3, "Allocating root glyph cache for size {}", this->fs);
 
		this->glyph_to_sprite = CallocT<GlyphEntry*>(256);
 
	}
 

	
 
	if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) {
 
		DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", GB(key, 8, 8), this->fs);
 
		Debug(freetype, 3, "Allocating glyph cache for range 0x{:02X}00, size {}", GB(key, 8, 8), this->fs);
 
		this->glyph_to_sprite[GB(key, 8, 8)] = CallocT<GlyphEntry>(256);
 
	}
 

	
 
	DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, this->fs);
 
	Debug(freetype, 4, "Set glyph for unicode character 0x{:04X}, size {}", key, this->fs);
 
	this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
 
	this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width;
 
	this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate;
 
}
 

	
 

	
 
@@ -465,13 +465,13 @@ void FreeTypeFontCache::SetFontSize(Font
 
		this->units_per_em = this->face->units_per_EM;
 
		this->ascender     = this->face->size->metrics.ascender >> 6;
 
		this->descender    = this->face->size->metrics.descender >> 6;
 
		this->height       = this->ascender - this->descender;
 
	} else {
 
		/* Both FT_Set_Pixel_Sizes and FT_Select_Size failed. */
 
		DEBUG(freetype, 0, "Font size selection failed. Using FontCache defaults.");
 
		Debug(freetype, 0, "Font size selection failed. Using FontCache defaults.");
 
	}
 
}
 

	
 
/**
 
 * Loads the freetype font.
 
 * First type to load the fontname as if it were a path. If that fails,
 
@@ -495,13 +495,13 @@ static void LoadFreeTypeFont(FontSize fs
 
	if (_library == nullptr) {
 
		if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
 
			ShowInfoF("Unable to initialize FreeType, using sprite fonts instead");
 
			return;
 
		}
 

	
 
		DEBUG(freetype, 2, "Initialized");
 
		Debug(freetype, 2, "Initialized");
 
	}
 

	
 
	const char *font_name = settings->font.c_str();
 
	FT_Face face = nullptr;
 

	
 
	/* If font is an absolute path to a ttf, try loading that first. */
 
@@ -524,13 +524,13 @@ static void LoadFreeTypeFont(FontSize fs
 
	}
 

	
 
	/* Try loading based on font face name (OS-wide fonts). */
 
	if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face);
 

	
 
	if (error == FT_Err_Ok) {
 
		DEBUG(freetype, 2, "Requested '%s', using '%s %s'", font_name, face->family_name, face->style_name);
 
		Debug(freetype, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
 

	
 
		/* Attempt to select the unicode character map */
 
		error = FT_Select_Charmap(face, ft_encoding_unicode);
 
		if (error == FT_Err_Ok) goto found_face; // Success
 

	
 
		if (error == FT_Err_Invalid_CharMap_Handle) {
src/game/game_core.cpp
Show inline comments
 
@@ -166,26 +166,26 @@
 
/* static */ void Game::ResetConfig()
 
{
 
	/* Check for both newgame as current game if we can reload the GameInfo inside
 
	 *  the GameConfig. If not, remove the Game from the list. */
 
	if (_settings_game.game_config != nullptr && _settings_game.game_config->HasScript()) {
 
		if (!_settings_game.game_config->ResetInfo(true)) {
 
			DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
 
			Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
 
			_settings_game.game_config->Change(nullptr);
 
			if (Game::instance != nullptr) {
 
				delete Game::instance;
 
				Game::instance = nullptr;
 
				Game::info = nullptr;
 
			}
 
		} else if (Game::instance != nullptr) {
 
			Game::info = _settings_game.game_config->GetInfo();
 
		}
 
	}
 
	if (_settings_newgame.game_config != nullptr && _settings_newgame.game_config->HasScript()) {
 
		if (!_settings_newgame.game_config->ResetInfo(false)) {
 
			DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
 
			Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
 
			_settings_newgame.game_config->Change(nullptr);
 
		}
 
	}
 
}
 

	
 
/* static */ void Game::Rescan()
src/game/game_info.cpp
Show inline comments
 
@@ -72,13 +72,13 @@ template <> const char *GetClassName<Gam
 
		info->is_developer_only = false;
 
	}
 
	/* Try to get the API version the AI is written for. */
 
	if (!info->CheckMethod("GetAPIVersion")) return SQ_ERROR;
 
	if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
 
	if (!CheckAPIVersion(info->api_version)) {
 
		DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
 
		Debug(script, 1, "Loading info.nut from ({}.{}): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
 
		return SQ_ERROR;
 
	}
 

	
 
	/* Remove the link to the real instance, else it might get deleted by RegisterGame() */
 
	sq_setinstanceup(vm, 2, nullptr);
 
	/* Register the Game to the base system */
src/game/game_text.cpp
Show inline comments
 
@@ -29,35 +29,35 @@ void CDECL strgen_warning(const char *s,
 
{
 
	char buf[1024];
 
	va_list va;
 
	va_start(va, s);
 
	vseprintf(buf, lastof(buf), s, va);
 
	va_end(va);
 
	DEBUG(script, 0, "%s:%d: warning: %s", _file, _cur_line, buf);
 
	Debug(script, 0, "{}:{}: warning: {}", _file, _cur_line, buf);
 
	_warnings++;
 
}
 

	
 
void CDECL strgen_error(const char *s, ...)
 
{
 
	char buf[1024];
 
	va_list va;
 
	va_start(va, s);
 
	vseprintf(buf, lastof(buf), s, va);
 
	va_end(va);
 
	DEBUG(script, 0, "%s:%d: error: %s", _file, _cur_line, buf);
 
	Debug(script, 0, "{}:{}: error: {}", _file, _cur_line, buf);
 
	_errors++;
 
}
 

	
 
void NORETURN CDECL strgen_fatal(const char *s, ...)
 
{
 
	char buf[1024];
 
	va_list va;
 
	va_start(va, s);
 
	vseprintf(buf, lastof(buf), s, va);
 
	va_end(va);
 
	DEBUG(script, 0, "%s:%d: FATAL: %s", _file, _cur_line, buf);
 
	Debug(script, 0, "{}:{}: FATAL: {}", _file, _cur_line, buf);
 
	throw std::exception();
 
}
 

	
 
/**
 
 * Read all the raw language strings from the given file.
 
 * @param file The file to read from.
src/gamelog.cpp
Show inline comments
 
@@ -353,13 +353,13 @@ void GamelogPrintConsole()
 
}
 

	
 
static int _gamelog_print_level = 0; ///< gamelog debug level we need to print stuff
 

	
 
static void GamelogPrintDebugProc(const char *s)
 
{
 
	DEBUG(gamelog, _gamelog_print_level, "%s", s);
 
	Debug(gamelog, _gamelog_print_level, "{}", s);
 
}
 

	
 

	
 
/**
 
 * Prints gamelog to debug output. Code is executed even when
 
 * there will be no output. It is called very seldom, so it
src/genworld.cpp
Show inline comments
 
@@ -88,13 +88,13 @@ static void _GenerateWorld()
 
{
 
	/* Make sure everything is done via OWNER_NONE. */
 
	Backup<CompanyID> _cur_company(_current_company, OWNER_NONE, FILE_LINE);
 

	
 
	try {
 
		_generating_world = true;
 
		if (_network_dedicated) DEBUG(net, 3, "Generating map, please wait...");
 
		if (_network_dedicated) Debug(net, 3, "Generating map, please wait...");
 
		/* Set the Random() seed to generation_seed so we produce the same map with the same seed */
 
		if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
 
		_random.SetSeed(_settings_game.game_creation.generation_seed);
 
		SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
 
		SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
 

	
 
@@ -185,14 +185,14 @@ static void _GenerateWorld()
 
		IncreaseGeneratingWorldProgress(GWP_GAME_START);
 

	
 
		CleanupGeneration();
 

	
 
		ShowNewGRFError();
 

	
 
		if (_network_dedicated) DEBUG(net, 3, "Map generated, starting game");
 
		DEBUG(desync, 1, "new_map: %08x", _settings_game.game_creation.generation_seed);
 
		if (_network_dedicated) Debug(net, 3, "Map generated, starting game");
 
		Debug(desync, 1, "new_map: {:08x}", _settings_game.game_creation.generation_seed);
 

	
 
		if (_debug_desync_level > 0) {
 
			char name[MAX_PATH];
 
			seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
 
			SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
 
		}
 
@@ -201,13 +201,13 @@ static void _GenerateWorld()
 

	
 
		BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP, true);
 
		if (_cur_company.IsValid()) _cur_company.Restore();
 

	
 
		if (_network_dedicated) {
 
			/* Exit the game to prevent a return to main menu.  */
 
			DEBUG(net, 0, "Generating map failed; closing server");
 
			Debug(net, 0, "Generating map failed; closing server");
 
			_exit_game = true;
 
		} else {
 
			SwitchToMode(_switch_mode);
 
		}
 
	}
 
}
src/genworld_gui.cpp
Show inline comments
 
@@ -1455,13 +1455,13 @@ static void _SetGeneratingWorldProgress(
 
		if (_gws.percent < last_percent) last_percent = 0;
 
		/* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
 
		if (_gws.percent % 5 != 0 && _gws.percent <= last_percent + 5) return;
 
		/* Never show steps smaller than 2%, even if it is a mod 5% */
 
		if (_gws.percent <= last_percent + 2) return;
 

	
 
		DEBUG(net, 3, "Map generation percentage complete: %d", _gws.percent);
 
		Debug(net, 3, "Map generation percentage complete: {}", _gws.percent);
 
		last_percent = _gws.percent;
 

	
 
		return;
 
	}
 

	
 
	SetWindowDirty(WC_MODAL_PROGRESS, 0);
src/gfx.cpp
Show inline comments
 
@@ -1912,13 +1912,13 @@ bool ChangeResInGame(int width, int heig
 
}
 

	
 
bool ToggleFullScreen(bool fs)
 
{
 
	bool result = VideoDriver::GetInstance()->ToggleFullscreen(fs);
 
	if (_fullscreen != fs && _resolutions.empty()) {
 
		DEBUG(driver, 0, "Could not find a suitable fullscreen resolution");
 
		Debug(driver, 0, "Could not find a suitable fullscreen resolution");
 
	}
 
	return result;
 
}
 

	
 
void SortResolutions()
 
{
src/gfx_layout.cpp
Show inline comments
 
@@ -693,13 +693,13 @@ Layouter::Layouter(const char *str, int 
 

	
 
#ifdef WITH_ICU_LX
 
			GetLayouter<ICUParagraphLayoutFactory>(line, str, state);
 
			if (line.layout == nullptr) {
 
				static bool warned = false;
 
				if (!warned) {
 
					DEBUG(misc, 0, "ICU layouter bailed on the font. Falling back to the fallback layouter");
 
					Debug(misc, 0, "ICU layouter bailed on the font. Falling back to the fallback layouter");
 
					warned = true;
 
				}
 

	
 
				state = old_state;
 
				str = old_str;
 
			}
src/gfxinit.cpp
Show inline comments
 
@@ -46,13 +46,13 @@ static uint LoadGrfFile(const char *file
 
{
 
	uint load_index_org = load_index;
 
	uint sprite_id = 0;
 

	
 
	SpriteFile &file = OpenCachedSpriteFile(filename, BASESET_DIR, needs_palette_remap);
 

	
 
	DEBUG(sprite, 2, "Reading grf-file '%s'", filename);
 
	Debug(sprite, 2, "Reading grf-file '{}'", filename);
 

	
 
	byte container_ver = file.GetContainerVersion();
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename);
 
	ReadGRFSpriteOffsets(file);
 
	if (container_ver >= 2) {
 
		/* Read compression. */
 
@@ -64,13 +64,13 @@ static uint LoadGrfFile(const char *file
 
		load_index++;
 
		sprite_id++;
 
		if (load_index >= MAX_SPRITES) {
 
			usererror("Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
 
		}
 
	}
 
	DEBUG(sprite, 2, "Currently %i sprites are loaded", load_index);
 
	Debug(sprite, 2, "Currently {} sprites are loaded", load_index);
 

	
 
	return load_index - load_index_org;
 
}
 

	
 
/**
 
 * Load an old fashioned GRF file to replace already loaded sprites.
 
@@ -83,13 +83,13 @@ static void LoadGrfFileIndexed(const cha
 
{
 
	uint start;
 
	uint sprite_id = 0;
 

	
 
	SpriteFile &file = OpenCachedSpriteFile(filename, BASESET_DIR, needs_palette_remap);
 

	
 
	DEBUG(sprite, 2, "Reading indexed grf-file '%s'", filename);
 
	Debug(sprite, 2, "Reading indexed grf-file '{}'", filename);
 

	
 
	byte container_ver = file.GetContainerVersion();
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename);
 
	ReadGRFSpriteOffsets(file);
 
	if (container_ver >= 2) {
 
		/* Read compression. */
 
@@ -116,13 +116,13 @@ static void LoadGrfFileIndexed(const cha
 
void CheckExternalFiles()
 
{
 
	if (BaseGraphics::GetUsedSet() == nullptr || BaseSounds::GetUsedSet() == nullptr) return;
 

	
 
	const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
 

	
 
	DEBUG(grf, 1, "Using the %s base graphics set", used_set->name.c_str());
 
	Debug(grf, 1, "Using the {} base graphics set", used_set->name);
 

	
 
	static const size_t ERROR_MESSAGE_LENGTH = 256;
 
	static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
 

	
 
	/* Allocate for a message for each missing file and for one error
 
	 * message per set.
 
@@ -220,13 +220,13 @@ static void LoadSpriteTables()
 
	_grfconfig = master;
 

	
 
	LoadNewGRF(SPR_NEWGRFS_BASE, 2);
 

	
 
	uint total_extra_graphics = SPR_NEWGRFS_BASE - SPR_OPENTTD_BASE;
 
	_missing_extra_graphics = GetSpriteCountForFile(master_filename, SPR_OPENTTD_BASE, SPR_NEWGRFS_BASE);
 
	DEBUG(sprite, 1, "%u extra sprites, %u from baseset, %u from fallback", total_extra_graphics, total_extra_graphics - _missing_extra_graphics, _missing_extra_graphics);
 
	Debug(sprite, 1, "{} extra sprites, {} from baseset, {} from fallback", total_extra_graphics, total_extra_graphics - _missing_extra_graphics, _missing_extra_graphics);
 

	
 
	/* The original baseset extra graphics intentionally make use of the fallback graphics.
 
	 * Let's say everything which provides less than 500 sprites misses the rest intentionally. */
 
	if (500 + _missing_extra_graphics > total_extra_graphics) _missing_extra_graphics = 0;
 

	
 
	/* Free and remove the top element. */
 
@@ -238,16 +238,16 @@ static void LoadSpriteTables()
 

	
 
static void RealChangeBlitter(const char *repl_blitter)
 
{
 
	const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName();
 
	if (strcmp(cur_blitter, repl_blitter) == 0) return;
 

	
 
	DEBUG(driver, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
 
	Debug(driver, 1, "Switching blitter from '{}' to '{}'... ", cur_blitter, repl_blitter);
 
	Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter);
 
	if (new_blitter == nullptr) NOT_REACHED();
 
	DEBUG(driver, 1, "Successfully switched to %s.", repl_blitter);
 
	Debug(driver, 1, "Successfully switched to {}.", repl_blitter);
 

	
 
	if (!VideoDriver::GetInstance()->AfterBlitterChange()) {
 
		/* Failed to switch blitter, let's hope we can return to the old one. */
 
		if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
 
	}
 

	
 
@@ -340,13 +340,13 @@ void CheckBlitter()
 
	ReInitAllWindows(false);
 
}
 

	
 
/** Initialise and load all the sprites. */
 
void GfxLoadSprites()
 
{
 
	DEBUG(sprite, 2, "Loading sprite set %d", _settings_game.game_creation.landscape);
 
	Debug(sprite, 2, "Loading sprite set {}", _settings_game.game_creation.landscape);
 

	
 
	SwitchNewGRFBlitter();
 
	VideoDriver::GetInstance()->ClearSystemSprites();
 
	ClearFontCache();
 
	GfxInitSpriteMem();
 
	LoadSpriteTables();
src/highscore.cpp
Show inline comments
 
@@ -135,13 +135,13 @@ void SaveToHighScore()
 
				byte length = std::min(sizeof(hs->company), StrEmpty(hs->company) ? 0 : strlen(&hs->company[1]) + 1);
 

	
 
				if (fwrite(&length, sizeof(length), 1, fp)       != 1 || // write away string length
 
						fwrite(hs->company, length, 1, fp)           >  1 || // Yes... could be 0 bytes too
 
						fwrite(&hs->score, sizeof(hs->score), 1, fp) != 1 ||
 
						fwrite("  ", 2, 1, fp)                       != 1) { // XXX - placeholder for hs->title, not saved anymore; compatibility
 
					DEBUG(misc, 1, "Could not save highscore.");
 
					Debug(misc, 1, "Could not save highscore.");
 
					i = SP_SAVED_HIGHSCORE_END;
 
					break;
 
				}
 
			}
 
		}
 
		fclose(fp);
 
@@ -163,13 +163,13 @@ void LoadFromHighScore()
 
			for (hs = _highscore_table[i]; hs != endof(_highscore_table[i]); hs++) {
 
				byte length;
 
				if (fread(&length, sizeof(length), 1, fp)                              !=  1 ||
 
						fread(hs->company, std::min<int>(lengthof(hs->company), length), 1, fp) >   1 || // Yes... could be 0 bytes too
 
						fread(&hs->score, sizeof(hs->score), 1, fp)                        !=  1 ||
 
						fseek(fp, 2, SEEK_CUR)                                             == -1) { // XXX - placeholder for hs->title, not saved anymore; compatibility
 
					DEBUG(misc, 1, "Highscore corrupted");
 
					Debug(misc, 1, "Highscore corrupted");
 
					i = SP_SAVED_HIGHSCORE_END;
 
					break;
 
				}
 
				StrMakeValidInPlace(hs->company, lastof(hs->company), SVS_NONE);
 
				hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
 
			}
src/ini.cpp
Show inline comments
 
@@ -109,13 +109,13 @@ bool IniFile::SaveToDisk(const std::stri
 
	shfopt.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOF_SILENT;
 
	shfopt.pFrom  = tfile_new;
 
	shfopt.pTo    = tfilename;
 
	SHFileOperation(&shfopt);
 
#else
 
	if (rename(file_new.c_str(), filename.c_str()) < 0) {
 
		DEBUG(misc, 0, "Renaming %s to %s failed; configuration not saved", file_new.c_str(), filename.c_str());
 
		Debug(misc, 0, "Renaming {} to {} failed; configuration not saved", file_new, filename);
 
	}
 
#endif
 

	
 
#ifdef __EMSCRIPTEN__
 
	EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
 
#endif
src/map.cpp
Show inline comments
 
@@ -44,13 +44,13 @@ void AllocateMap(uint size_x, uint size_
 
			!IsInsideMM(size_y, MIN_MAP_SIZE, MAX_MAP_SIZE + 1) ||
 
			(size_x & (size_x - 1)) != 0 ||
 
			(size_y & (size_y - 1)) != 0) {
 
		error("Invalid map size");
 
	}
 

	
 
	DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y);
 
	Debug(map, 1, "Allocating map of size {}x{}", size_x, size_y);
 

	
 
	_map_log_x = FindFirstBit(size_x);
 
	_map_log_y = FindFirstBit(size_y);
 
	_map_size_x = size_x;
 
	_map_size_y = size_y;
 
	_map_size = size_x * size_y;
src/misc_gui.cpp
Show inline comments
 
@@ -114,23 +114,23 @@ public:
 

	
 
#if defined(_DEBUG)
 
#	define LANDINFOD_LEVEL 0
 
#else
 
#	define LANDINFOD_LEVEL 1
 
#endif
 
		DEBUG(misc, LANDINFOD_LEVEL, "TILE: %#x (%i,%i)", tile, TileX(tile), TileY(tile));
 
		DEBUG(misc, LANDINFOD_LEVEL, "type   = %#x", _m[tile].type);
 
		DEBUG(misc, LANDINFOD_LEVEL, "height = %#x", _m[tile].height);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m1     = %#x", _m[tile].m1);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m2     = %#x", _m[tile].m2);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m3     = %#x", _m[tile].m3);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m4     = %#x", _m[tile].m4);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m5     = %#x", _m[tile].m5);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m6     = %#x", _me[tile].m6);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m7     = %#x", _me[tile].m7);
 
		DEBUG(misc, LANDINFOD_LEVEL, "m8     = %#x", _me[tile].m8);
 
		Debug(misc, LANDINFOD_LEVEL, "TILE: {:#x} ({},{})", tile, TileX(tile), TileY(tile));
 
		Debug(misc, LANDINFOD_LEVEL, "type   = {:#x}", _m[tile].type);
 
		Debug(misc, LANDINFOD_LEVEL, "height = {:#x}", _m[tile].height);
 
		Debug(misc, LANDINFOD_LEVEL, "m1     = {:#x}", _m[tile].m1);
 
		Debug(misc, LANDINFOD_LEVEL, "m2     = {:#x}", _m[tile].m2);
 
		Debug(misc, LANDINFOD_LEVEL, "m3     = {:#x}", _m[tile].m3);
 
		Debug(misc, LANDINFOD_LEVEL, "m4     = {:#x}", _m[tile].m4);
 
		Debug(misc, LANDINFOD_LEVEL, "m5     = {:#x}", _m[tile].m5);
 
		Debug(misc, LANDINFOD_LEVEL, "m6     = {:#x}", _me[tile].m6);
 
		Debug(misc, LANDINFOD_LEVEL, "m7     = {:#x}", _me[tile].m7);
 
		Debug(misc, LANDINFOD_LEVEL, "m8     = {:#x}", _me[tile].m8);
 
#undef LANDINFOD_LEVEL
 
	}
 

	
 
	void OnInit() override
 
	{
 
		Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
src/music.cpp
Show inline comments
 
@@ -138,13 +138,13 @@ bool MusicSet::FillSetDetails(IniFile *i
 
			if (item != nullptr && item->value.has_value() && !item->value->empty()) {
 
				/* Song has a CAT file index, assume it's MPS MIDI format */
 
				this->songinfo[i].filetype = MTT_MPSMIDI;
 
				this->songinfo[i].cat_index = atoi(item->value->c_str());
 
				char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index);
 
				if (songname == nullptr) {
 
					DEBUG(grf, 0, "Base music set song missing from CAT file: %s/%d", filename, this->songinfo[i].cat_index);
 
					Debug(grf, 0, "Base music set song missing from CAT file: {}/{}", filename, this->songinfo[i].cat_index);
 
					this->songinfo[i].songname[0] = '\0';
 
					continue;
 
				}
 
				strecpy(this->songinfo[i].songname, songname, lastof(this->songinfo[i].songname));
 
				free(songname);
 
			} else {
 
@@ -165,13 +165,13 @@ bool MusicSet::FillSetDetails(IniFile *i
 
			}
 

	
 
			if (this->songinfo[i].filetype == MTT_STANDARDMIDI) {
 
				if (item != nullptr && item->value.has_value() && !item->value->empty()) {
 
					strecpy(this->songinfo[i].songname, item->value->c_str(), lastof(this->songinfo[i].songname));
 
				} else {
 
					DEBUG(grf, 0, "Base music set song name missing: %s", filename);
 
					Debug(grf, 0, "Base music set song name missing: {}", filename);
 
					return false;
 
				}
 
			}
 
			this->num_available++;
 

	
 
			/* Number the theme song (if any) track 0, rest are normal */
src/music/allegro_m.cpp
Show inline comments
 
@@ -26,26 +26,26 @@ static MIDI *_midi = nullptr;
 
 */
 
extern int _allegro_instance_count;
 

	
 
const char *MusicDriver_Allegro::Start(const StringList &param)
 
{
 
	if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) {
 
		DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error);
 
		Debug(driver, 0, "allegro: install_allegro failed '{}'", allegro_error);
 
		return "Failed to set up Allegro";
 
	}
 
	_allegro_instance_count++;
 

	
 
	/* Initialise the sound */
 
	if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, nullptr) != 0) {
 
		DEBUG(driver, 0, "allegro: install_sound failed '%s'", allegro_error);
 
		Debug(driver, 0, "allegro: install_sound failed '{}'", allegro_error);
 
		return "Failed to set up Allegro sound";
 
	}
 

	
 
	/* Okay, there's no soundcard */
 
	if (midi_card == MIDI_NONE) {
 
		DEBUG(driver, 0, "allegro: no midi card found");
 
		Debug(driver, 0, "allegro: no midi card found");
 
		return "No sound card found";
 
	}
 

	
 
	return nullptr;
 
}
 

	
src/music/cocoa_m.cpp
Show inline comments
 
@@ -64,13 +64,13 @@ static void DoSetVolume()
 
		if (desc.componentType == kAudioUnitType_Output) {
 
			output_unit = unit;
 
			break;
 
		}
 
	}
 
	if (output_unit == nullptr) {
 
		DEBUG(driver, 1, "cocoa_m: Failed to get output node to set volume");
 
		Debug(driver, 1, "cocoa_m: Failed to get output node to set volume");
 
		return;
 
	}
 

	
 
	Float32 vol = _volume / 127.0f;  // 0 - +127 -> 0.0 - 1.0
 
	AudioUnitSetParameter(output_unit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0);
 
}
 
@@ -116,42 +116,42 @@ void MusicDriver_Cocoa::Stop()
 
 * @param song Description of music to load and play
 
 */
 
void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song)
 
{
 
	std::string filename = MidiFile::GetSMFFile(song);
 

	
 
	DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename.c_str());
 
	Debug(driver, 2, "cocoa_m: trying to play '{}'", filename);
 

	
 
	this->StopSong();
 
	if (_sequence != nullptr) {
 
		DisposeMusicSequence(_sequence);
 
		_sequence = nullptr;
 
	}
 

	
 
	if (filename.empty()) return;
 

	
 
	if (NewMusicSequence(&_sequence) != noErr) {
 
		DEBUG(driver, 0, "cocoa_m: Failed to create music sequence");
 
		Debug(driver, 0, "cocoa_m: Failed to create music sequence");
 
		return;
 
	}
 

	
 
	std::string os_file = OTTD2FS(filename);
 
	CFAutoRelease<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file.c_str(), os_file.length(), false));
 

	
 
	if (MusicSequenceFileLoad(_sequence, url.get(), kMusicSequenceFile_AnyType, 0) != noErr) {
 
		DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file");
 
		Debug(driver, 0, "cocoa_m: Failed to load MIDI file");
 
		return;
 
	}
 

	
 
	/* Construct audio graph */
 
	AUGraph graph = nullptr;
 

	
 
	MusicSequenceGetAUGraph(_sequence, &graph);
 
	AUGraphOpen(graph);
 
	if (AUGraphInitialize(graph) != noErr) {
 
		DEBUG(driver, 0, "cocoa_m: Failed to initialize AU graph");
 
		Debug(driver, 0, "cocoa_m: Failed to initialize AU graph");
 
		return;
 
	}
 

	
 
	/* Figure out sequence length */
 
	UInt32 num_tracks;
 
	MusicSequenceGetTrackCount(_sequence, &num_tracks);
 
@@ -170,13 +170,13 @@ void MusicDriver_Cocoa::PlaySong(const M
 
	DoSetVolume();
 
	MusicPlayerSetSequence(_player, _sequence);
 
	MusicPlayerPreroll(_player);
 
	if (MusicPlayerStart(_player) != noErr) return;
 
	_playing = true;
 

	
 
	DEBUG(driver, 3, "cocoa_m: playing '%s'", filename.c_str());
 
	Debug(driver, 3, "cocoa_m: playing '{}'", filename);
 
}
 

	
 

	
 
/**
 
 * Stops playing the current song, if the player is active.
 
 */
src/music/dmusic.cpp
Show inline comments
 
@@ -226,13 +226,13 @@ bool DLSFile::ReadDLSRegion(FILE *f, DWO
 
			case FOURCC_INFO:
 
				/* We don't care about info stuff. */
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 

	
 
			default:
 
				DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 
		}
 
	}
 

	
 
	return true;
 
@@ -249,17 +249,17 @@ bool DLSFile::ReadDLSRegionList(FILE *f,
 
			FOURCC list_type;
 
			if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false;
 

	
 
			if (list_type == FOURCC_RGN) {
 
				this->ReadDLSRegion(f, chunk.length - sizeof(list_type), instrument.regions);
 
			} else {
 
				DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown list chunk of type {}{}{}{}", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				fseek(f, chunk.length - sizeof(list_type), SEEK_CUR);
 
			}
 
		} else {
 
			DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			Debug(driver, 7, "DLS: Ignoring chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			fseek(f, chunk.length, SEEK_CUR);
 
		}
 
	}
 

	
 
	return true;
 
}
 
@@ -296,13 +296,13 @@ bool DLSFile::ReadDLSInstrument(FILE *f,
 
			case FOURCC_INFO:
 
				/* We don't care about info stuff. */
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 

	
 
			default:
 
				DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 
		}
 
	}
 

	
 
	return true;
 
@@ -317,21 +317,21 @@ bool DLSFile::ReadDLSInstrumentList(FILE
 

	
 
		if (chunk.type == FOURCC_LIST) {
 
			FOURCC list_type;
 
			if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false;
 

	
 
			if (list_type == FOURCC_INS) {
 
				DEBUG(driver, 6, "DLS: Reading instrument %d", (int)instruments.size());
 
				Debug(driver, 6, "DLS: Reading instrument {}", (int)instruments.size());
 

	
 
				if (!this->ReadDLSInstrument(f, chunk.length - sizeof(list_type))) return false;
 
			} else {
 
				DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown list chunk of type {}{}{}{}", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				fseek(f, chunk.length - sizeof(list_type), SEEK_CUR);
 
			}
 
		} else {
 
			DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			Debug(driver, 7, "DLS: Ignoring chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			fseek(f, chunk.length, SEEK_CUR);
 
		}
 
	}
 

	
 
	return true;
 
}
 
@@ -384,13 +384,13 @@ bool DLSFile::ReadDLSWave(FILE *f, DWORD
 
			case FOURCC_INFO:
 
				/* We don't care about info stuff. */
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 

	
 
			default:
 
				DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 
		}
 
	}
 

	
 
	return true;
 
@@ -409,31 +409,31 @@ bool DLSFile::ReadDLSWaveList(FILE *f, D
 

	
 
		if (chunk.type == FOURCC_LIST) {
 
			FOURCC list_type;
 
			if (fread(&list_type, sizeof(list_type), 1, f) != 1) return false;
 

	
 
			if (list_type == FOURCC_wave) {
 
				DEBUG(driver, 6, "DLS: Reading wave %d", (int)waves.size());
 
				Debug(driver, 6, "DLS: Reading wave {}", waves.size());
 

	
 
				if (!this->ReadDLSWave(f, chunk.length - sizeof(list_type), chunk_offset - base_offset)) return false;
 
			} else {
 
				DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown list chunk of type {}{}{}{}", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF));
 
				fseek(f, chunk.length - sizeof(list_type), SEEK_CUR);
 
			}
 
		} else {
 
			DEBUG(driver, 7, "DLS: Ignoring chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			Debug(driver, 7, "DLS: Ignoring chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
			fseek(f, chunk.length, SEEK_CUR);
 
		}
 
	}
 

	
 
	return true;
 
}
 

	
 
bool DLSFile::LoadFile(const wchar_t *file)
 
{
 
	DEBUG(driver, 2, "DMusic: Try to load DLS file %s", FS2OTTD(file).c_str());
 
	Debug(driver, 2, "DMusic: Try to load DLS file {}", FS2OTTD(file));
 

	
 
	FILE *f = _wfopen(file, L"rb");
 
	if (f == nullptr) return false;
 

	
 
	FileCloser f_scope(f);
 

	
 
@@ -443,13 +443,13 @@ bool DLSFile::LoadFile(const wchar_t *fi
 
	if (fread(&hdr, sizeof(hdr), 1, f) != 1) return false;
 
	if (fread(&dls_type, sizeof(dls_type), 1, f) != 1) return false;
 
	if (hdr.type != FOURCC_RIFF || dls_type != FOURCC_DLS) return false;
 

	
 
	hdr.length -= sizeof(FOURCC);
 

	
 
	DEBUG(driver, 2, "DMusic: Parsing DLS file");
 
	Debug(driver, 2, "DMusic: Parsing DLS file");
 

	
 
	DLSHEADER header;
 
	MemSetT(&header, 0);
 

	
 
	/* Iterate over all chunks in the file. */
 
	while (hdr.length > 0) {
 
@@ -492,13 +492,13 @@ bool DLSFile::LoadFile(const wchar_t *fi
 
			case FOURCC_INFO:
 
				/* We don't care about info stuff. */
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 

	
 
			default:
 
				DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				Debug(driver, 7, "DLS: Ignoring unknown chunk {}{}{}{}", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF));
 
				fseek(f, chunk.length, SEEK_CUR);
 
				break;
 
		}
 
	}
 

	
 
	/* Have we read as many instruments as indicated? */
 
@@ -582,13 +582,13 @@ static void TransmitNotesOff(IDirectMusi
 
	/* Wait until message time has passed. */
 
	Sleep(Clamp((block_time - cur_time) / MS_TO_REFTIME, 5, 1000));
 
}
 

	
 
static void MidiThreadProc()
 
{
 
	DEBUG(driver, 2, "DMusic: Entering playback thread");
 
	Debug(driver, 2, "DMusic: Entering playback thread");
 

	
 
	REFERENCE_TIME last_volume_time = 0; // timestamp of the last volume change
 
	REFERENCE_TIME block_time = 0;       // timestamp of the last block sent to the port
 
	REFERENCE_TIME playback_start_time;  // timestamp current file began playback
 
	MidiFile current_file;               // file currently being played from
 
	PlaybackSegment current_segment;     // segment info for current playback
 
@@ -614,13 +614,13 @@ static void MidiThreadProc()
 
		if (_playback.shutdown) {
 
			_playback.playing = false;
 
			break;
 
		}
 

	
 
		if (_playback.do_stop) {
 
			DEBUG(driver, 2, "DMusic thread: Stopping playback");
 
			Debug(driver, 2, "DMusic thread: Stopping playback");
 

	
 
			/* Turn all notes off and wait a bit to allow the messages to be handled. */
 
			clock->GetTime(&cur_time);
 
			TransmitNotesOff(_buffer, block_time, cur_time);
 

	
 
			_playback.playing = false;
 
@@ -629,13 +629,13 @@ static void MidiThreadProc()
 
			next_timeout = 1000;
 
			continue;
 
		}
 

	
 
		if (wfso == WAIT_OBJECT_0) {
 
			if (_playback.do_start) {
 
				DEBUG(driver, 2, "DMusic thread: Starting playback");
 
				Debug(driver, 2, "DMusic thread: Starting playback");
 
				{
 
					/* New scope to limit the time the mutex is locked. */
 
					std::lock_guard<std::mutex> lock(_thread_mutex);
 

	
 
					current_file.MoveFrom(_playback.next_file);
 
					std::swap(_playback.next_segment, current_segment);
 
@@ -666,20 +666,20 @@ static void MidiThreadProc()
 
				size_t preload_bytes = 0;
 
				for (size_t bl = 0; bl < current_file.blocks.size(); bl++) {
 
					MidiFile::DataBlock &block = current_file.blocks[bl];
 
					preload_bytes += block.data.size();
 
					if (block.ticktime >= current_segment.start) {
 
						if (current_segment.loop) {
 
							DEBUG(driver, 2, "DMusic: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes);
 
							Debug(driver, 2, "DMusic: timer: loop from block {} (ticktime {}, realtime {:.3f}, bytes {})", bl, block.ticktime, ((int)block.realtime) / 1000.0, preload_bytes);
 
							current_segment.start_block = bl;
 
							break;
 
						} else {
 
							/* Skip the transmission delay compensation performed in the Win32 MIDI driver.
 
							 * The DMusic driver will most likely be used with the MS softsynth, which is not subject to transmission delays.
 
							 */
 
							DEBUG(driver, 2, "DMusic: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes);
 
							Debug(driver, 2, "DMusic: timer: start from block {} (ticktime {}, realtime {:.3f}, bytes {})", bl, block.ticktime, ((int)block.realtime) / 1000.0, preload_bytes);
 
							playback_start_time -= block.realtime * MIDITIME_TO_REFTIME;
 
							break;
 
						}
 
					}
 
				}
 
			}
 
@@ -688,13 +688,13 @@ static void MidiThreadProc()
 
			REFERENCE_TIME current_time;
 
			clock->GetTime(&current_time);
 

	
 
			/* Check for volume change. */
 
			if (current_volume != _playback.new_volume) {
 
				if (current_time - last_volume_time > 10 * MS_TO_REFTIME) {
 
					DEBUG(driver, 2, "DMusic thread: volume change");
 
					Debug(driver, 2, "DMusic thread: volume change");
 
					current_volume = _playback.new_volume;
 
					last_volume_time = current_time;
 
					for (int ch = 0; ch < 16; ch++) {
 
						int vol = ScaleVolume(channel_volumes[ch], current_volume);
 
						TransmitChannelMsg(_buffer, block_time + 1, MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol);
 
					}
 
@@ -706,13 +706,13 @@ static void MidiThreadProc()
 
			while (current_block < current_file.blocks.size()) {
 
				MidiFile::DataBlock &block = current_file.blocks[current_block];
 

	
 
				/* check that block isn't at end-of-song override */
 
				if (current_segment.end > 0 && block.ticktime >= current_segment.end) {
 
					if (current_segment.loop) {
 
						DEBUG(driver, 2, "DMusic thread: Looping song");
 
						Debug(driver, 2, "DMusic thread: Looping song");
 
						current_block = current_segment.start_block;
 
						playback_start_time = current_time - current_file.blocks[current_block].realtime * MIDITIME_TO_REFTIME;
 
					} else {
 
						_playback.do_stop = true;
 
					}
 
					next_timeout = 0;
 
@@ -720,19 +720,19 @@ static void MidiThreadProc()
 
				}
 
				/* check that block is not in the future */
 
				REFERENCE_TIME playback_time = current_time - playback_start_time;
 
				if (block.realtime * MIDITIME_TO_REFTIME > playback_time +  3 *_playback.preload_time * MS_TO_REFTIME) {
 
					/* Stop the thread loop until we are at the preload time of the next block. */
 
					next_timeout = Clamp(((int64)block.realtime * MIDITIME_TO_REFTIME - playback_time) / MS_TO_REFTIME - _playback.preload_time, 0, 1000);
 
					DEBUG(driver, 9, "DMusic thread: Next event in %lu ms (music %u, ref " OTTD_PRINTF64 ")", next_timeout, block.realtime * MIDITIME_TO_REFTIME, playback_time);
 
					Debug(driver, 9, "DMusic thread: Next event in {} ms (music {}, ref {})", next_timeout, block.realtime * MIDITIME_TO_REFTIME, playback_time);
 
					break;
 
				}
 

	
 
				/* Timestamp of the current block. */
 
				block_time = playback_start_time + block.realtime * MIDITIME_TO_REFTIME;
 
				DEBUG(driver, 9, "DMusic thread: Streaming block " PRINTF_SIZE " (cur=" OTTD_PRINTF64 ", block=" OTTD_PRINTF64 ")", current_block, (long long)(current_time / MS_TO_REFTIME), (long long)(block_time / MS_TO_REFTIME));
 
				Debug(driver, 9, "DMusic thread: Streaming block {} (cur={}, block={})", current_block, (long long)(current_time / MS_TO_REFTIME), (long long)(block_time / MS_TO_REFTIME));
 

	
 
				const byte *data = block.data.data();
 
				size_t remaining = block.data.size();
 
				byte last_status = 0;
 
				while (remaining > 0) {
 
					/* MidiFile ought to have converted everything out of running status,
 
@@ -819,13 +819,13 @@ static void MidiThreadProc()
 
				}
 
				next_timeout = 0;
 
			}
 
		}
 
	}
 

	
 
	DEBUG(driver, 2, "DMusic: Exiting playback thread");
 
	Debug(driver, 2, "DMusic: Exiting playback thread");
 

	
 
	/* Turn all notes off and wait a bit to allow the messages to be handled by real hardware. */
 
	clock->GetTime(&cur_time);
 
	TransmitNotesOff(_buffer, block_time, cur_time);
 
	Sleep(_playback.preload_time * 4);
 

	
 
@@ -864,13 +864,13 @@ static const char *LoadDefaultDLSFile(co
 
			if (SUCCEEDED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\DirectMusic", 0, KEY_READ, &hkDM))) {
 
				wchar_t dls_path[MAX_PATH];
 
				DWORD buf_size = sizeof(dls_path); // Buffer size as to be given in bytes!
 
				if (SUCCEEDED(RegQueryValueEx(hkDM, L"GMFilePath", nullptr, nullptr, (LPBYTE)dls_path, &buf_size))) {
 
					wchar_t expand_path[MAX_PATH * 2];
 
					ExpandEnvironmentStrings(dls_path, expand_path, lengthof(expand_path));
 
					if (!dls_file.LoadFile(expand_path)) DEBUG(driver, 1, "Failed to load default GM DLS file from registry");
 
					if (!dls_file.LoadFile(expand_path)) Debug(driver, 1, "Failed to load default GM DLS file from registry");
 
				}
 
				RegCloseKey(hkDM);
 
			}
 

	
 
			/* If we couldn't load the file from the registry, try again at the default install path of the GM DLS file. */
 
			if (dls_file.instruments.size() == 0) {
 
@@ -1097,16 +1097,16 @@ const char *MusicDriver_DMusic::Start(co
 
		char desc[DMUS_MAX_DESCRIPTION];
 

	
 
		DMUS_PORTCAPS caps;
 
		MemSetT(&caps, 0);
 
		caps.dwSize = sizeof(DMUS_PORTCAPS);
 

	
 
		DEBUG(driver, 1, "Detected DirectMusic ports:");
 
		Debug(driver, 1, "Detected DirectMusic ports:");
 
		for (int i = 0; _music->EnumPort(i, &caps) == S_OK; i++) {
 
			if (caps.dwClass == DMUS_PC_OUTPUTCLASS) {
 
				DEBUG(driver, 1, " %d: %s%s", i, convert_from_fs(caps.wszDescription, desc, lengthof(desc)), i == pIdx ? " (selected)" : "");
 
				Debug(driver, 1, " {}: {}{}", i, convert_from_fs(caps.wszDescription, desc, lengthof(desc)), i == pIdx ? " (selected)" : "");
 
			}
 
		}
 
	}
 

	
 
	GUID guidPort;
 
	if (pIdx >= 0) {
src/music/extmidi.cpp
Show inline comments
 
@@ -107,13 +107,13 @@ bool MusicDriver_ExtMidi::IsSongPlaying(
 
	if (this->pid == -1 && this->song[0] != '\0') this->DoPlay();
 
	return this->pid != -1;
 
}
 

	
 
void MusicDriver_ExtMidi::SetVolume(byte vol)
 
{
 
	DEBUG(driver, 1, "extmidi: set volume not implemented");
 
	Debug(driver, 1, "extmidi: set volume not implemented");
 
}
 

	
 
void MusicDriver_ExtMidi::DoPlay()
 
{
 
	this->pid = fork();
 
	switch (this->pid) {
 
@@ -124,13 +124,13 @@ void MusicDriver_ExtMidi::DoPlay()
 
				execvp(this->params[0], this->params);
 
			}
 
			_exit(1);
 
		}
 

	
 
		case -1:
 
			DEBUG(driver, 0, "extmidi: couldn't fork: %s", strerror(errno));
 
			Debug(driver, 0, "extmidi: couldn't fork: {}", strerror(errno));
 
			FALLTHROUGH;
 

	
 
		default:
 
			this->song[0] = '\0';
 
			break;
 
	}
 
@@ -150,13 +150,13 @@ void MusicDriver_ExtMidi::DoStop()
 
			return;
 
		}
 
		/* Wait 10 milliseconds. */
 
		CSleep(10);
 
	}
 

	
 
	DEBUG(driver, 0, "extmidi: gracefully stopping failed, trying the hard way");
 
	Debug(driver, 0, "extmidi: gracefully stopping failed, trying the hard way");
 
	/* Gracefully stopping failed. Do it the hard way
 
	 * and wait till the process finally died. */
 
	kill(this->pid, SIGKILL);
 
	waitpid(this->pid, nullptr, 0);
 
	this->pid = -1;
 
}
src/music/fluidsynth.cpp
Show inline comments
 
@@ -62,24 +62,24 @@ const char *MusicDriver_FluidSynth::Star
 
{
 
	std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
 

	
 
	const char *sfont_name = GetDriverParam(param, "soundfont");
 
	int sfont_id;
 

	
 
	DEBUG(driver, 1, "Fluidsynth: sf %s", sfont_name);
 
	Debug(driver, 1, "Fluidsynth: sf {}", sfont_name);
 

	
 
	/* Create the settings. */
 
	_midi.settings = new_fluid_settings();
 
	if (_midi.settings == nullptr) return "Could not create midi settings";
 
	/* Don't try to lock sample data in memory, OTTD usually does not run with privileges allowing that */
 
	fluid_settings_setint(_midi.settings, "synth.lock-memory", 0);
 

	
 
	/* Install the music render routine and set up the samplerate */
 
	uint32 samplerate = MxSetMusicSource(RenderMusicStream);
 
	fluid_settings_setnum(_midi.settings, "synth.sample-rate", samplerate);
 
	DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate);
 
	Debug(driver, 1, "Fluidsynth: samplerate {:.0f}", (float)samplerate);
 

	
 
	/* Create the synthesizer. */
 
	_midi.synth = new_fluid_synth(_midi.settings);
 
	if (_midi.synth == nullptr) return "Could not open synth";
 

	
 
	/* Load a SoundFont and reset presets (so that new instruments
 
@@ -140,24 +140,24 @@ void MusicDriver_FluidSynth::PlaySong(co
 
	}
 

	
 
	std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
 

	
 
	_midi.player = new_fluid_player(_midi.synth);
 
	if (_midi.player == nullptr) {
 
		DEBUG(driver, 0, "Could not create midi player");
 
		Debug(driver, 0, "Could not create midi player");
 
		return;
 
	}
 

	
 
	if (fluid_player_add(_midi.player, filename.c_str()) != FLUID_OK) {
 
		DEBUG(driver, 0, "Could not open music file");
 
		Debug(driver, 0, "Could not open music file");
 
		delete_fluid_player(_midi.player);
 
		_midi.player = nullptr;
 
		return;
 
	}
 
	if (fluid_player_play(_midi.player) != FLUID_OK) {
 
		DEBUG(driver, 0, "Could not start midi player");
 
		Debug(driver, 0, "Could not start midi player");
 
		delete_fluid_player(_midi.player);
 
		_midi.player = nullptr;
 
		return;
 
	}
 
}
 

	
 
@@ -191,9 +191,9 @@ void MusicDriver_FluidSynth::SetVolume(b
 
	/* Allowed range of synth.gain is 0.0 to 10.0 */
 
	/* fluidsynth's default gain is 0.2, so use this as "full
 
	 * volume". Set gain using OpenTTD's volume, as a number between 0
 
	 * and 0.2. */
 
	double gain = (1.0 * vol) / (128.0 * 5.0);
 
	if (fluid_settings_setnum(_midi.settings, "synth.gain", gain) != FLUID_OK) {
 
		DEBUG(driver, 0, "Could not set volume");
 
		Debug(driver, 0, "Could not set volume");
 
	}
 
}
src/music/win32_m.cpp
Show inline comments
 
@@ -112,26 +112,26 @@ void CALLBACK TimerCallback(UINT uTimerI
 
	/* Ensure only one timer callback is running at once, and prevent races on status flags */
 
	std::unique_lock<std::mutex> mutex_lock(_midi.lock, std::defer_lock);
 
	if (!mutex_lock.try_lock()) return;
 

	
 
	/* check for stop */
 
	if (_midi.do_stop) {
 
		DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set");
 
		Debug(driver, 2, "Win32-MIDI: timer: do_stop is set");
 
		midiOutReset(_midi.midi_out);
 
		_midi.playing = false;
 
		_midi.do_stop = false;
 
		return;
 
	}
 

	
 
	/* check for start/restart/change song */
 
	if (_midi.do_start != 0) {
 
		/* Have a delay between playback start steps, prevents jumbled-together notes at the start of song */
 
		if (timeGetTime() - _midi.playback_start_time < 50) {
 
			return;
 
		}
 
		DEBUG(driver, 2, "Win32-MIDI: timer: do_start step %d", _midi.do_start);
 
		Debug(driver, 2, "Win32-MIDI: timer: do_start step {}", _midi.do_start);
 

	
 
		if (_midi.do_start == 1) {
 
			/* Send "all notes off" */
 
			midiOutReset(_midi.midi_out);
 
			_midi.playback_start_time = timeGetTime();
 
			_midi.do_start = 2;
 
@@ -162,23 +162,23 @@ void CALLBACK TimerCallback(UINT uTimerI
 
			_midi.current_block = 0;
 

	
 
			MemSetT<byte>(_midi.channel_volumes, 127, lengthof(_midi.channel_volumes));
 
		}
 
	} else if (!_midi.playing) {
 
		/* not playing, stop the timer */
 
		DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer");
 
		Debug(driver, 2, "Win32-MIDI: timer: not playing, stopping timer");
 
		timeKillEvent(uTimerID);
 
		_midi.timer_id = 0;
 
		return;
 
	}
 

	
 
	/* check for volume change */
 
	static int volume_throttle = 0;
 
	if (_midi.current_volume != _midi.new_volume) {
 
		if (volume_throttle == 0) {
 
			DEBUG(driver, 2, "Win32-MIDI: timer: volume change");
 
			Debug(driver, 2, "Win32-MIDI: timer: volume change");
 
			_midi.current_volume = _midi.new_volume;
 
			volume_throttle = 20 / _midi.time_period;
 
			for (int ch = 0; ch < 16; ch++) {
 
				byte vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume);
 
				TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol);
 
			}
 
@@ -195,22 +195,22 @@ void CALLBACK TimerCallback(UINT uTimerI
 
		size_t preload_bytes = 0;
 
		for (size_t bl = 0; bl < _midi.current_file.blocks.size(); bl++) {
 
			MidiFile::DataBlock &block = _midi.current_file.blocks[bl];
 
			preload_bytes += block.data.size();
 
			if (block.ticktime >= _midi.current_segment.start) {
 
				if (_midi.current_segment.loop) {
 
					DEBUG(driver, 2, "Win32-MIDI: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime)/1000.0, (int)preload_bytes);
 
					Debug(driver, 2, "Win32-MIDI: timer: loop from block {} (ticktime {}, realtime {:.3f}, bytes {})", bl, block.ticktime, ((int)block.realtime)/1000.0, preload_bytes);
 
					_midi.current_segment.start_block = bl;
 
					break;
 
				} else {
 
					/* Calculate offset start time for playback.
 
					 * The preload_bytes are used to compensate for delay in transmission over traditional serial MIDI interfaces,
 
					 * which have a bitrate of 31,250 bits/sec, and transmit 1+8+1 start/data/stop bits per byte.
 
					 * The delay compensation is needed to avoid time-compression of following messages.
 
					 */
 
					DEBUG(driver, 2, "Win32-MIDI: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes);
 
					Debug(driver, 2, "Win32-MIDI: timer: start from block {} (ticktime {}, realtime {:.3f}, bytes {})", bl, block.ticktime, ((int)block.realtime) / 1000.0, preload_bytes);
 
					_midi.playback_start_time -= block.realtime / 1000 - (DWORD)(preload_bytes * 1000 / 3125);
 
					break;
 
				}
 
			}
 
		}
 
	}
 
@@ -317,40 +317,40 @@ void CALLBACK TimerCallback(UINT uTimerI
 
		}
 
	}
 
}
 

	
 
void MusicDriver_Win32::PlaySong(const MusicSongInfo &song)
 
{
 
	DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry");
 
	Debug(driver, 2, "Win32-MIDI: PlaySong: entry");
 

	
 
	MidiFile new_song;
 
	if (!new_song.LoadSong(song)) return;
 
	DEBUG(driver, 2, "Win32-MIDI: PlaySong: Loaded song");
 
	Debug(driver, 2, "Win32-MIDI: PlaySong: Loaded song");
 

	
 
	std::lock_guard<std::mutex> mutex_lock(_midi.lock);
 

	
 
	_midi.next_file.MoveFrom(new_song);
 
	_midi.next_segment.start = song.override_start;
 
	_midi.next_segment.end = song.override_end;
 
	_midi.next_segment.loop = song.loop;
 

	
 
	DEBUG(driver, 2, "Win32-MIDI: PlaySong: setting flag");
 
	Debug(driver, 2, "Win32-MIDI: PlaySong: setting flag");
 
	_midi.do_stop = _midi.playing;
 
	_midi.do_start = 1;
 

	
 
	if (_midi.timer_id == 0) {
 
		DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer");
 
		Debug(driver, 2, "Win32-MIDI: PlaySong: starting timer");
 
		_midi.timer_id = timeSetEvent(_midi.time_period, _midi.time_period, TimerCallback, (DWORD_PTR)this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
 
	}
 
}
 

	
 
void MusicDriver_Win32::StopSong()
 
{
 
	DEBUG(driver, 2, "Win32-MIDI: StopSong: entry");
 
	Debug(driver, 2, "Win32-MIDI: StopSong: entry");
 
	std::lock_guard<std::mutex> mutex_lock(_midi.lock);
 
	DEBUG(driver, 2, "Win32-MIDI: StopSong: setting flag");
 
	Debug(driver, 2, "Win32-MIDI: StopSong: setting flag");
 
	_midi.do_stop = true;
 
}
 

	
 
bool MusicDriver_Win32::IsSongPlaying()
 
{
 
	return _midi.playing || (_midi.do_start != 0);
 
@@ -361,33 +361,33 @@ void MusicDriver_Win32::SetVolume(byte v
 
	std::lock_guard<std::mutex> mutex_lock(_midi.lock);
 
	_midi.new_volume = vol;
 
}
 

	
 
const char *MusicDriver_Win32::Start(const StringList &parm)
 
{
 
	DEBUG(driver, 2, "Win32-MIDI: Start: initializing");
 
	Debug(driver, 2, "Win32-MIDI: Start: initializing");
 

	
 
	int resolution = GetDriverParamInt(parm, "resolution", 5);
 
	uint port = (uint)GetDriverParamInt(parm, "port", UINT_MAX);
 
	const char *portname = GetDriverParam(parm, "portname");
 

	
 
	/* Enumerate ports either for selecting port by name, or for debug output */
 
	if (portname != nullptr || _debug_driver_level > 0) {
 
		uint numports = midiOutGetNumDevs();
 
		DEBUG(driver, 1, "Win32-MIDI: Found %d output devices:", numports);
 
		Debug(driver, 1, "Win32-MIDI: Found {} output devices:", numports);
 
		for (uint tryport = 0; tryport < numports; tryport++) {
 
			MIDIOUTCAPS moc{};
 
			if (midiOutGetDevCaps(tryport, &moc, sizeof(moc)) == MMSYSERR_NOERROR) {
 
				char tryportname[128];
 
				convert_from_fs(moc.szPname, tryportname, lengthof(tryportname));
 

	
 
				/* Compare requested and detected port name.
 
				 * If multiple ports have the same name, this will select the last matching port, and the debug output will be confusing. */
 
				if (portname != nullptr && strncmp(tryportname, portname, lengthof(tryportname)) == 0) port = tryport;
 

	
 
				DEBUG(driver, 1, "MIDI port %2d: %s%s", tryport, tryportname, (tryport == port) ? " [selected]" : "");
 
				Debug(driver, 1, "MIDI port {:2d}: {}{}", tryport, tryportname, (tryport == port) ? " [selected]" : "");
 
			}
 
		}
 
	}
 

	
 
	UINT devid;
 
	if (port == UINT_MAX) {
 
@@ -407,13 +407,13 @@ const char *MusicDriver_Win32::Start(con
 
	/* prepare multimedia timer */
 
	TIMECAPS timecaps;
 
	if (timeGetDevCaps(&timecaps, sizeof(timecaps)) == MMSYSERR_NOERROR) {
 
		_midi.time_period = std::min(std::max((UINT)resolution, timecaps.wPeriodMin), timecaps.wPeriodMax);
 
		if (timeBeginPeriod(_midi.time_period) == MMSYSERR_NOERROR) {
 
			/* success */
 
			DEBUG(driver, 2, "Win32-MIDI: Start: timer resolution is %d", (int)_midi.time_period);
 
			Debug(driver, 2, "Win32-MIDI: Start: timer resolution is {}", _midi.time_period);
 
			return nullptr;
 
		}
 
	}
 
	midiOutClose(_midi.midi_out);
 
	return "could not set timer resolution";
 
}
src/network/core/address.cpp
Show inline comments
 
@@ -244,25 +244,25 @@ SOCKET NetworkAddress::Resolve(int famil
 
	static bool _resolve_timeout_error_message_shown = false;
 
	auto start = std::chrono::steady_clock::now();
 
	int e = getaddrinfo(this->hostname.empty() ? nullptr : this->hostname.c_str(), port_name, &hints, &ai);
 
	auto end = std::chrono::steady_clock::now();
 
	std::chrono::seconds duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
 
	if (!_resolve_timeout_error_message_shown && duration >= std::chrono::seconds(5)) {
 
		DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s took %i seconds",
 
				this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count());
 
		DEBUG(net, 0, "  this is likely an issue in the DNS name resolver's configuration causing it to time out");
 
		Debug(net, 0, "getaddrinfo for hostname \"{}\", port {}, address family {} and socket type {} took {} seconds",
 
				this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), duration.count());
 
		Debug(net, 0, "  this is likely an issue in the DNS name resolver's configuration causing it to time out");
 
		_resolve_timeout_error_message_shown = true;
 
	}
 

	
 

	
 
	if (reset_hostname) this->hostname.clear();
 

	
 
	if (e != 0) {
 
		if (func != ResolveLoopProc) {
 
			DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
 
				this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
 
			Debug(net, 0, "getaddrinfo for hostname \"{}\", port {}, address family {} and socket type {} failed: {}",
 
				this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)));
 
		}
 
		return INVALID_SOCKET;
 
	}
 

	
 
	SOCKET sock = INVALID_SOCKET;
 
	for (struct addrinfo *runp = ai; runp != nullptr; runp = runp->ai_next) {
 
@@ -314,52 +314,52 @@ static SOCKET ListenLoopProc(addrinfo *r
 
	std::string address = NetworkAddress(runp->ai_addr, (int)runp->ai_addrlen).GetAddressAsString();
 

	
 
	SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
 
	if (sock == INVALID_SOCKET) {
 
		const char *type = NetworkAddress::SocketTypeAsString(runp->ai_socktype);
 
		const char *family = NetworkAddress::AddressFamilyAsString(runp->ai_family);
 
		DEBUG(net, 0, "Could not create %s %s socket: %s", type, family, NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Could not create {} {} socket: {}", type, family, NetworkError::GetLast().AsString());
 
		return INVALID_SOCKET;
 
	}
 

	
 
	if (runp->ai_socktype == SOCK_STREAM && !SetNoDelay(sock)) {
 
		DEBUG(net, 1, "Setting no-delay mode failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 1, "Setting no-delay mode failed: {}", NetworkError::GetLast().AsString());
 
	}
 

	
 
	int on = 1;
 
	/* The (const char*) cast is needed for windows!! */
 
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) {
 
		DEBUG(net, 0, "Setting reuse-address mode failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Setting reuse-address mode failed: {}", NetworkError::GetLast().AsString());
 
	}
 

	
 
#ifndef __OS2__
 
	if (runp->ai_family == AF_INET6 &&
 
			setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) == -1) {
 
		DEBUG(net, 3, "Could not disable IPv4 over IPv6: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 3, "Could not disable IPv4 over IPv6: {}", NetworkError::GetLast().AsString());
 
	}
 
#endif
 

	
 
	if (bind(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) {
 
		DEBUG(net, 0, "Could not bind socket on %s: %s", address.c_str(), NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Could not bind socket on {}: {}", address, NetworkError::GetLast().AsString());
 
		closesocket(sock);
 
		return INVALID_SOCKET;
 
	}
 

	
 
	if (runp->ai_socktype != SOCK_DGRAM && listen(sock, 1) != 0) {
 
		DEBUG(net, 0, "Could not listen on socket: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Could not listen on socket: {}", NetworkError::GetLast().AsString());
 
		closesocket(sock);
 
		return INVALID_SOCKET;
 
	}
 

	
 
	/* Connection succeeded */
 

	
 
	if (!SetNonBlocking(sock)) {
 
		DEBUG(net, 0, "Setting non-blocking mode failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Setting non-blocking mode failed: {}", NetworkError::GetLast().AsString());
 
	}
 

	
 
	DEBUG(net, 3, "Listening on %s", address.c_str());
 
	Debug(net, 3, "Listening on {}", address);
 
	return sock;
 
}
 

	
 
/**
 
 * Make the given socket listen.
 
 * @param socktype the type of socket (TCP, UDP, etc)
src/network/core/core.cpp
Show inline comments
 
@@ -24,15 +24,15 @@
 
bool NetworkCoreInitialize()
 
{
 
/* Let's load the network in windows */
 
#ifdef _WIN32
 
	{
 
		WSADATA wsa;
 
		DEBUG(net, 5, "Loading windows socket library");
 
		Debug(net, 5, "Loading windows socket library");
 
		if (WSAStartup(MAKEWORD(2, 0), &wsa) != 0) {
 
			DEBUG(net, 0, "WSAStartup failed, network unavailable");
 
			Debug(net, 0, "WSAStartup failed, network unavailable");
 
			return false;
 
		}
 
	}
 
#endif /* _WIN32 */
 

	
 
	return true;
src/network/core/game_info.cpp
Show inline comments
 
@@ -48,13 +48,13 @@ const char *GetNetworkRevisionString()
 
		network_revision = stredup(_openttd_revision);
 
		/* Ensure it's not longer than the packet buffer length. */
 
		if (strlen(network_revision) >= NETWORK_REVISION_LENGTH) network_revision[NETWORK_REVISION_LENGTH - 1] = '\0';
 

	
 
		/* Tag names are not mangled further. */
 
		if (_openttd_revision_tagged) {
 
			DEBUG(net, 3, "Network revision name: %s", network_revision);
 
			Debug(net, 3, "Network revision name: {}", network_revision);
 
			return network_revision;
 
		}
 

	
 
		/* Prepare a prefix of the git hash.
 
		 * Size is length + 1 for terminator, +2 for -g prefix. */
 
		assert(_openttd_revision_modified < 3);
 
@@ -68,13 +68,13 @@ const char *GetNetworkRevisionString()
 
		 * Overwrite from that position, unless that would go past end of packet buffer length. */
 
		ptrdiff_t hashofs = strrchr(_openttd_revision, '-') - _openttd_revision;
 
		if (hashofs + strlen(githash_suffix) + 1 > NETWORK_REVISION_LENGTH) hashofs = strlen(network_revision) - strlen(githash_suffix);
 
		/* Replace the git hash in revision string. */
 
		strecpy(network_revision + hashofs, githash_suffix, network_revision + NETWORK_REVISION_LENGTH);
 
		assert(strlen(network_revision) < NETWORK_REVISION_LENGTH); // strlen does not include terminator, constant does, hence strictly less than
 
		DEBUG(net, 3, "Network revision name: %s", network_revision);
 
		Debug(net, 3, "Network revision name: {}", network_revision);
 
	}
 

	
 
	return network_revision;
 
}
 

	
 
/**
src/network/core/host.cpp
Show inline comments
 
@@ -128,13 +128,13 @@ static void NetworkFindBroadcastIPsInter
 
 */
 
void NetworkFindBroadcastIPs(NetworkAddressList *broadcast)
 
{
 
	NetworkFindBroadcastIPsInternal(broadcast);
 

	
 
	/* Now display to the debug all the detected ips */
 
	DEBUG(net, 3, "Detected broadcast addresses:");
 
	Debug(net, 3, "Detected broadcast addresses:");
 
	int i = 0;
 
	for (NetworkAddress &addr : *broadcast) {
 
		addr.SetPort(NETWORK_DEFAULT_PORT);
 
		DEBUG(net, 3, "  %d) %s", i++, addr.GetHostname());
 
		Debug(net, 3, "  {}) {}", i++, addr.GetHostname());
 
	}
 
}
src/network/core/tcp.cpp
Show inline comments
 
@@ -109,13 +109,13 @@ SendPacketsState NetworkTCPSocketHandler
 
		res = p->TransferOut<int>(send, this->sock, 0);
 
		if (res == -1) {
 
			NetworkError err = NetworkError::GetLast();
 
			if (!err.WouldBlock()) {
 
				/* Something went wrong.. close client! */
 
				if (!closing_down) {
 
					DEBUG(net, 0, "Send failed: %s", err.AsString());
 
					Debug(net, 0, "Send failed: {}", err.AsString());
 
					this->CloseConnection();
 
				}
 
				return SPS_CLOSED;
 
			}
 
			return SPS_PARTLY_SENT;
 
		}
 
@@ -158,13 +158,13 @@ Packet *NetworkTCPSocketHandler::Receive
 
		while (p->RemainingBytesToTransfer() != 0) {
 
			res = p->TransferIn<int>(recv, this->sock, 0);
 
			if (res == -1) {
 
				NetworkError err = NetworkError::GetLast();
 
				if (!err.WouldBlock()) {
 
					/* Something went wrong... */
 
					if (!err.IsConnectionReset()) DEBUG(net, 0, "Recv failed: %s", err.AsString());
 
					if (!err.IsConnectionReset()) Debug(net, 0, "Recv failed: {}", err.AsString());
 
					this->CloseConnection();
 
					return nullptr;
 
				}
 
				/* Connection would block, so stop for now */
 
				return nullptr;
 
			}
 
@@ -186,13 +186,13 @@ Packet *NetworkTCPSocketHandler::Receive
 
	while (p->RemainingBytesToTransfer() != 0) {
 
		res = p->TransferIn<int>(recv, this->sock, 0);
 
		if (res == -1) {
 
			NetworkError err = NetworkError::GetLast();
 
			if (!err.WouldBlock()) {
 
				/* Something went wrong... */
 
				if (!err.IsConnectionReset()) DEBUG(net, 0, "Recv failed: %s", err.AsString());
 
				if (!err.IsConnectionReset()) Debug(net, 0, "Recv failed: {}", err.AsString());
 
				this->CloseConnection();
 
				return nullptr;
 
			}
 
			/* Connection would block */
 
			return nullptr;
 
		}
src/network/core/tcp_admin.cpp
Show inline comments
 
@@ -84,15 +84,15 @@ NetworkRecvStatus NetworkAdminSocketHand
 
		case ADMIN_PACKET_SERVER_CMD_LOGGING:     return this->Receive_SERVER_CMD_LOGGING(p);
 
		case ADMIN_PACKET_SERVER_RCON_END:        return this->Receive_SERVER_RCON_END(p);
 
		case ADMIN_PACKET_SERVER_PONG:            return this->Receive_SERVER_PONG(p);
 

	
 
		default:
 
			if (this->HasClientQuit()) {
 
				DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
 
				Debug(net, 0, "[tcp/admin] Received invalid packet type {} from '{}' ({})", type, this->admin_name, this->admin_version);
 
			} else {
 
				DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name.c_str(), this->admin_version.c_str());
 
				Debug(net, 0, "[tcp/admin] Received illegal packet from '{}' ({})", this->admin_name, this->admin_version);
 
			}
 

	
 
			this->CloseConnection();
 
			return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
	}
 
}
 
@@ -120,13 +120,13 @@ NetworkRecvStatus NetworkAdminSocketHand
 
 * Helper for logging receiving invalid packets.
 
 * @param type The received packet type.
 
 * @return The status the network should have, in this case: "malformed packet error".
 
 */
 
NetworkRecvStatus NetworkAdminSocketHandler::ReceiveInvalidPacket(PacketAdminType type)
 
{
 
	DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
 
	Debug(net, 0, "[tcp/admin] Received illegal packet type {} from admin {} ({})", type, this->admin_name, this->admin_version);
 
	return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
}
 

	
 
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_JOIN); }
 
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_QUIT(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_QUIT); }
 
NetworkRecvStatus NetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENCY(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY); }
src/network/core/tcp_connect.cpp
Show inline comments
 
@@ -53,31 +53,31 @@ TCPConnecter::~TCPConnecter()
 
 * @param address The address to connection to.
 
 */
 
void TCPConnecter::Connect(addrinfo *address)
 
{
 
	SOCKET sock = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
 
	if (sock == INVALID_SOCKET) {
 
		DEBUG(net, 0, "Could not create %s %s socket: %s", NetworkAddress::SocketTypeAsString(address->ai_socktype), NetworkAddress::AddressFamilyAsString(address->ai_family), NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Could not create {} {} socket: {}", NetworkAddress::SocketTypeAsString(address->ai_socktype), NetworkAddress::AddressFamilyAsString(address->ai_family), NetworkError::GetLast().AsString());
 
		return;
 
	}
 

	
 
	if (!SetNoDelay(sock)) {
 
		DEBUG(net, 1, "Setting TCP_NODELAY failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 1, "Setting TCP_NODELAY failed: {}", NetworkError::GetLast().AsString());
 
	}
 
	if (!SetNonBlocking(sock)) {
 
		DEBUG(net, 0, "Setting non-blocking mode failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 0, "Setting non-blocking mode failed: {}", NetworkError::GetLast().AsString());
 
	}
 

	
 
	NetworkAddress network_address = NetworkAddress(address->ai_addr, (int)address->ai_addrlen);
 
	DEBUG(net, 5, "Attempting to connect to %s", network_address.GetAddressAsString().c_str());
 
	Debug(net, 5, "Attempting to connect to {}", network_address.GetAddressAsString());
 

	
 
	int err = connect(sock, address->ai_addr, (int)address->ai_addrlen);
 
	if (err != 0 && !NetworkError::GetLast().IsConnectInProgress()) {
 
		closesocket(sock);
 

	
 
		DEBUG(net, 1, "Could not connect to %s: %s", network_address.GetAddressAsString().c_str(), NetworkError::GetLast().AsString());
 
		Debug(net, 1, "Could not connect to {}: {}", network_address.GetAddressAsString(), NetworkError::GetLast().AsString());
 
		return;
 
	}
 

	
 
	this->sock_to_address[sock] = network_address;
 
	this->sockets.push_back(sock);
 
}
 
@@ -147,15 +147,15 @@ void TCPConnecter::OnResolved(addrinfo *
 
				addresses_ipv4.pop_front();
 
			}
 
		}
 
	}
 

	
 
	if (_debug_net_level >= 6) {
 
		DEBUG(net, 6, "%s resolved in:", this->connection_string.c_str());
 
		Debug(net, 6, "{} resolved in:", this->connection_string);
 
		for (const auto &address : this->addresses) {
 
			DEBUG(net, 6, "- %s", NetworkAddress(address->ai_addr, (int)address->ai_addrlen).GetAddressAsString().c_str());
 
			Debug(net, 6, "- {}", NetworkAddress(address->ai_addr, (int)address->ai_addrlen).GetAddressAsString());
 
		}
 
	}
 

	
 
	this->current_address = 0;
 
}
 

	
 
@@ -185,19 +185,19 @@ void TCPConnecter::Resolve()
 
	addrinfo *ai;
 
	int error = getaddrinfo(address.GetHostname(), port_name, &hints, &ai);
 

	
 
	auto end = std::chrono::steady_clock::now();
 
	auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
 
	if (!getaddrinfo_timeout_error_shown && duration >= std::chrono::seconds(5)) {
 
		DEBUG(net, 0, "getaddrinfo() for address \"%s\" took %i seconds", this->connection_string.c_str(), (int)duration.count());
 
		DEBUG(net, 0, "  This is likely an issue in the DNS name resolver's configuration causing it to time out");
 
		Debug(net, 0, "getaddrinfo() for address \"{}\" took {} seconds", this->connection_string, duration.count());
 
		Debug(net, 0, "  This is likely an issue in the DNS name resolver's configuration causing it to time out");
 
		getaddrinfo_timeout_error_shown = true;
 
	}
 

	
 
	if (error != 0) {
 
		DEBUG(net, 0, "Failed to resolve DNS for %s", this->connection_string.c_str());
 
		Debug(net, 0, "Failed to resolve DNS for {}", this->connection_string);
 
		this->status = Status::FAILURE;
 
		return;
 
	}
 

	
 
	this->ai = ai;
 
	this->OnResolved(ai);
 
@@ -269,13 +269,13 @@ bool TCPConnecter::CheckActivity()
 
	tv.tv_usec = 0;
 
	tv.tv_sec = 0;
 
	int n = select(FD_SETSIZE, NULL, &write_fd, NULL, &tv);
 
	/* select() failed; hopefully next try it doesn't. */
 
	if (n < 0) {
 
		/* select() normally never fails; so hopefully it works next try! */
 
		DEBUG(net, 1, "select() failed: %s", NetworkError::GetLast().AsString());
 
		Debug(net, 1, "select() failed: {}", NetworkError::GetLast().AsString());
 
		return false;
 
	}
 

	
 
	/* No socket updates. */
 
	if (n == 0) {
 
		/* Wait 250ms between attempting another address. */
 
@@ -286,13 +286,13 @@ bool TCPConnecter::CheckActivity()
 

	
 
		/* Wait up to 3 seconds since the last connection we started. */
 
		if (std::chrono::steady_clock::now() < this->last_attempt + std::chrono::milliseconds(3000)) return false;
 

	
 
		/* More than 3 seconds no socket reported activity, and there are no
 
		 * more address to try. Timeout the attempt. */
 
		DEBUG(net, 0, "Timeout while connecting to %s", this->connection_string.c_str());
 
		Debug(net, 0, "Timeout while connecting to {}", this->connection_string);
 

	
 
		for (const auto &socket : this->sockets) {
 
			closesocket(socket);
 
		}
 
		this->sockets.clear();
 
		this->sock_to_address.clear();
 
@@ -302,13 +302,13 @@ bool TCPConnecter::CheckActivity()
 
	}
 

	
 
	/* Check for errors on any of the sockets. */
 
	for (auto it = this->sockets.begin(); it != this->sockets.end(); /* nothing */) {
 
		NetworkError socket_error = GetSocketError(*it);
 
		if (socket_error.HasError()) {
 
			DEBUG(net, 1, "Could not connect to %s: %s", this->sock_to_address[*it].GetAddressAsString().c_str(), socket_error.AsString());
 
			Debug(net, 1, "Could not connect to {}: {}", this->sock_to_address[*it].GetAddressAsString(), socket_error.AsString());
 
			closesocket(*it);
 
			this->sock_to_address.erase(*it);
 
			it = this->sockets.erase(it);
 
		} else {
 
			it++;
 
		}
 
@@ -335,15 +335,15 @@ bool TCPConnecter::CheckActivity()
 
		}
 
		this->sock_to_address.erase(*it);
 
		it = this->sockets.erase(it);
 
	}
 
	assert(connected_socket != INVALID_SOCKET);
 

	
 
	DEBUG(net, 3, "Connected to %s", this->connection_string.c_str());
 
	Debug(net, 3, "Connected to {}", this->connection_string);
 
	if (_debug_net_level >= 5) {
 
		DEBUG(net, 5, "- using %s", NetworkAddress::GetPeerName(connected_socket).c_str());
 
		Debug(net, 5, "- using {}", NetworkAddress::GetPeerName(connected_socket));
 
	}
 

	
 
	this->OnConnect(connected_socket);
 
	return true;
 
}
 

	
src/network/core/tcp_content.cpp
Show inline comments
 
@@ -111,15 +111,15 @@ bool NetworkContentSocketHandler::Handle
 
		case PACKET_CONTENT_SERVER_INFO:           return this->Receive_SERVER_INFO(p);
 
		case PACKET_CONTENT_CLIENT_CONTENT:        return this->Receive_CLIENT_CONTENT(p);
 
		case PACKET_CONTENT_SERVER_CONTENT:        return this->Receive_SERVER_CONTENT(p);
 

	
 
		default:
 
			if (this->HasClientQuit()) {
 
				DEBUG(net, 0, "[tcp/content] Received invalid packet type %d", type);
 
				Debug(net, 0, "[tcp/content] Received invalid packet type {}", type);
 
			} else {
 
				DEBUG(net, 0, "[tcp/content] Received illegal packet");
 
				Debug(net, 0, "[tcp/content] Received illegal packet");
 
			}
 
			return false;
 
	}
 
}
 

	
 
/**
 
@@ -164,13 +164,13 @@ bool NetworkContentSocketHandler::Receiv
 
 * Helper for logging receiving invalid packets.
 
 * @param type The received packet type.
 
 * @return Always false, as it's an error.
 
 */
 
bool NetworkContentSocketHandler::ReceiveInvalidPacket(PacketContentType type)
 
{
 
	DEBUG(net, 0, "[tcp/content] Received illegal packet type %d", type);
 
	Debug(net, 0, "[tcp/content] Received illegal packet type {}", type);
 
	return false;
 
}
 

	
 
bool NetworkContentSocketHandler::Receive_CLIENT_INFO_LIST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_LIST); }
 
bool NetworkContentSocketHandler::Receive_CLIENT_INFO_ID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_ID); }
 
bool NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_EXTID); }
src/network/core/tcp_game.cpp
Show inline comments
 
@@ -114,15 +114,15 @@ NetworkRecvStatus NetworkGameSocketHandl
 
		case PACKET_SERVER_CONFIG_UPDATE:         return this->Receive_SERVER_CONFIG_UPDATE(p);
 

	
 
		default:
 
			this->CloseConnection();
 

	
 
			if (this->HasClientQuit()) {
 
				DEBUG(net, 0, "[tcp/game] Received invalid packet type %d from client %d", type, this->client_id);
 
				Debug(net, 0, "[tcp/game] Received invalid packet type {} from client {}", type, this->client_id);
 
			} else {
 
				DEBUG(net, 0, "[tcp/game] Received illegal packet from client %d", this->client_id);
 
				Debug(net, 0, "[tcp/game] Received illegal packet from client {}", this->client_id);
 
			}
 
			return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
	}
 
}
 

	
 
/**
 
@@ -148,13 +148,13 @@ NetworkRecvStatus NetworkGameSocketHandl
 
 * Helper for logging receiving invalid packets.
 
 * @param type The received packet type.
 
 * @return The status the network should have, in this case: "malformed packet error".
 
 */
 
NetworkRecvStatus NetworkGameSocketHandler::ReceiveInvalidPacket(PacketGameType type)
 
{
 
	DEBUG(net, 0, "[tcp/game] Received illegal packet type %d from client %d", type, this->client_id);
 
	Debug(net, 0, "[tcp/game] Received illegal packet type {} from client {}", type, this->client_id);
 
	return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
}
 

	
 
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_FULL); }
 
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_BANNED); }
 
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_JOIN); }
src/network/core/tcp_http.cpp
Show inline comments
 
@@ -42,13 +42,13 @@ NetworkHTTPSocketHandler::NetworkHTTPSoc
 
	redirect_depth(depth),
 
	sock(s)
 
{
 
	size_t bufferSize = strlen(url) + strlen(host) + strlen(GetNetworkRevisionString()) + (data == nullptr ? 0 : strlen(data)) + 128;
 
	char *buffer = AllocaM(char, bufferSize);
 

	
 
	DEBUG(net, 5, "[tcp/http] Requesting %s%s", host, url);
 
	Debug(net, 5, "[tcp/http] Requesting {}{}", host, url);
 
	if (data != nullptr) {
 
		seprintf(buffer, buffer + bufferSize - 1, "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s\r\n", url, host, GetNetworkRevisionString(), (int)strlen(data), data);
 
	} else {
 
		seprintf(buffer, buffer + bufferSize - 1, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\n\r\n", url, host, GetNetworkRevisionString());
 
	}
 

	
 
@@ -83,13 +83,13 @@ void NetworkHTTPSocketHandler::CloseSock
 
}
 

	
 
/**
 
 * Helper to simplify the error handling.
 
 * @param msg the error message to show.
 
 */
 
#define return_error(msg) { DEBUG(net, 1, msg); return -1; }
 
#define return_error(msg) { Debug(net, 1, msg); return -1; }
 

	
 
static const char * const NEWLINE        = "\r\n";             ///< End of line marker
 
static const char * const END_OF_HEADER  = "\r\n\r\n";         ///< End of header marker
 
static const char * const HTTP_1_0       = "HTTP/1.0 ";        ///< Preamble for HTTP 1.0 servers
 
static const char * const HTTP_1_1       = "HTTP/1.1 ";        ///< Preamble for HTTP 1.1 servers
 
static const char * const CONTENT_LENGTH = "Content-Length: "; ///< Header for the length of the content
 
@@ -139,26 +139,26 @@ int NetworkHTTPSocketHandler::HandleHead
 

	
 
		/* Make sure we're going to download at least something;
 
		 * zero sized files are, for OpenTTD's purposes, always
 
		 * wrong. You can't have gzips of 0 bytes! */
 
		if (len == 0) return_error("[tcp/http] Refusing to download 0 bytes");
 

	
 
		DEBUG(net, 7, "[tcp/http] Downloading %i bytes", len);
 
		Debug(net, 7, "[tcp/http] Downloading {} bytes", len);
 
		return len;
 
	}
 

	
 
	if (strncmp(status, "301", 3) != 0 &&
 
			strncmp(status, "302", 3) != 0 &&
 
			strncmp(status, "303", 3) != 0 &&
 
			strncmp(status, "307", 3) != 0) {
 
		/* We are not going to be redirected :(. */
 

	
 
		/* Search the end of the line. This is safe because the header will
 
		 * always end with two newlines. */
 
		*strstr(status, NEWLINE) = '\0';
 
		DEBUG(net, 1, "[tcp/http] Unhandled status reply %s", status);
 
		Debug(net, 1, "[tcp/http] Unhandled status reply {}", status);
 
		return -1;
 
	}
 

	
 
	if (this->redirect_depth == 5) return_error("[tcp/http] Too many redirects, looping redirects?");
 

	
 
	/* Redirect to other URL */
 
@@ -169,13 +169,13 @@ int NetworkHTTPSocketHandler::HandleHead
 

	
 
	/* Search the end of the line. This is safe because the header will
 
	 * always end with two newlines. */
 
	char *end_of_line = strstr(uri, NEWLINE);
 
	*end_of_line = '\0';
 

	
 
	DEBUG(net, 7, "[tcp/http] Redirecting to %s", uri);
 
	Debug(net, 7, "[tcp/http] Redirecting to {}", uri);
 

	
 
	int ret = NetworkHTTPSocketHandler::Connect(uri, this->callback, this->data, this->redirect_depth + 1);
 
	if (ret != 0) return ret;
 

	
 
	/* We've relinquished control of data now. */
 
	this->data = nullptr;
 
@@ -226,13 +226,13 @@ int NetworkHTTPSocketHandler::Receive()
 
	for (;;) {
 
		ssize_t res = recv(this->sock, (char *)this->recv_buffer + this->recv_pos, lengthof(this->recv_buffer) - this->recv_pos, 0);
 
		if (res == -1) {
 
			NetworkError err = NetworkError::GetLast();
 
			if (!err.WouldBlock()) {
 
				/* Something went wrong... */
 
				if (!err.IsConnectionReset()) DEBUG(net, 0, "Recv failed: %s", err.AsString());
 
				if (!err.IsConnectionReset()) Debug(net, 0, "Recv failed: {}", err.AsString());
 
				return -1;
 
			}
 
			/* Connection would block, so stop for now */
 
			return 1;
 
		}
 

	
 
@@ -254,13 +254,13 @@ int NetworkHTTPSocketHandler::Receive()
 
			this->recv_buffer[end] = '\0';
 
			char *end_of_header = strstr(this->recv_buffer, END_OF_HEADER);
 
			this->recv_buffer[end] = prev;
 

	
 
			if (end_of_header == nullptr) {
 
				if (read == lengthof(this->recv_buffer)) {
 
					DEBUG(net, 1, "[tcp/http] Header too big");
 
					Debug(net, 1, "[tcp/http] Header too big");
 
					return -1;
 
				}
 
				this->recv_pos = read;
 
			} else {
 
				int ret = this->HandleHeader();
 
				if (ret <= 0) return ret;
src/network/core/tcp_listen.h
Show inline comments
 
@@ -46,28 +46,28 @@ public:
 
			sin_len = FixAddrLenForEmscripten(sin);
 
#endif
 

	
 
			SetNonBlocking(s); // XXX error handling?
 

	
 
			NetworkAddress address(sin, sin_len);
 
			DEBUG(net, 3, "[%s] Client connected from %s on frame %d", Tsocket::GetName(), address.GetHostname(), _frame_counter);
 
			Debug(net, 3, "[{}] Client connected from {} on frame {}", Tsocket::GetName(), address.GetHostname(), _frame_counter);
 

	
 
			SetNoDelay(s); // XXX error handling?
 

	
 
			/* Check if the client is banned */
 
			bool banned = false;
 
			for (const auto &entry : _network_ban_list) {
 
				banned = address.IsInNetmask(entry.c_str());
 
				if (banned) {
 
					Packet p(Tban_packet);
 
					p.PrepareToSend();
 

	
 
					DEBUG(net, 2, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
 
					Debug(net, 2, "[{}] Banned ip tried to join ({}), refused", Tsocket::GetName(), entry);
 

	
 
					if (p.TransferOut<int>(send, s, 0) < 0) {
 
						DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
 
						Debug(net, 0, "[{}] send failed: {}", Tsocket::GetName(), NetworkError::GetLast().AsString());
 
					}
 
					closesocket(s);
 
					break;
 
				}
 
			}
 
			/* If this client is banned, continue with next client */
 
@@ -78,13 +78,13 @@ public:
 
				/* no more clients allowed?
 
				 * Send to the client that we are full! */
 
				Packet p(Tfull_packet);
 
				p.PrepareToSend();
 

	
 
				if (p.TransferOut<int>(send, s, 0) < 0) {
 
					DEBUG(net, 0, "[%s] send failed: %s", Tsocket::GetName(), NetworkError::GetLast().AsString());
 
					Debug(net, 0, "[{}] send failed: {}", Tsocket::GetName(), NetworkError::GetLast().AsString());
 
				}
 
				closesocket(s);
 

	
 
				continue;
 
			}
 

	
 
@@ -147,13 +147,13 @@ public:
 

	
 
		for (NetworkAddress &address : addresses) {
 
			address.Listen(SOCK_STREAM, &sockets);
 
		}
 

	
 
		if (sockets.size() == 0) {
 
			DEBUG(net, 0, "Could not start network: could not create listening socket");
 
			Debug(net, 0, "Could not start network: could not create listening socket");
 
			ShowNetworkError(STR_NETWORK_ERROR_SERVER_START);
 
			return false;
 
		}
 

	
 
		return true;
 
	}
 
@@ -162,13 +162,13 @@ public:
 
	static void CloseListeners()
 
	{
 
		for (auto &s : sockets) {
 
			closesocket(s.second);
 
		}
 
		sockets.clear();
 
		DEBUG(net, 5, "[%s] Closed listeners", Tsocket::GetName());
 
		Debug(net, 5, "[{}] Closed listeners", Tsocket::GetName());
 
	}
 
};
 

	
 
template <class Tsocket, PacketType Tfull_packet, PacketType Tban_packet> SocketList TCPListenHandler<Tsocket, Tfull_packet, Tban_packet>::sockets;
 

	
 
#endif /* NETWORK_CORE_TCP_LISTEN_H */
src/network/core/udp.cpp
Show inline comments
 
@@ -86,22 +86,22 @@ void NetworkUDPSocketHandler::SendPacket
 
		p->PrepareToSend();
 

	
 
		if (broadcast) {
 
			/* Enable broadcast */
 
			unsigned long val = 1;
 
			if (setsockopt(s.second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) {
 
				DEBUG(net, 1, "Setting broadcast mode failed: %s", NetworkError::GetLast().AsString());
 
				Debug(net, 1, "Setting broadcast mode failed: {}", NetworkError::GetLast().AsString());
 
			}
 
		}
 

	
 
		/* Send the buffer */
 
		ssize_t res = p->TransferOut<int>(sendto, s.second, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength());
 
		DEBUG(net, 7, "sendto(%s)", send.GetAddressAsString().c_str());
 
		Debug(net, 7, "sendto({})", send.GetAddressAsString());
 

	
 
		/* Check for any errors, but ignore it otherwise */
 
		if (res == -1) DEBUG(net, 1, "sendto(%s) failed: %s", send.GetAddressAsString().c_str(), NetworkError::GetLast().AsString());
 
		if (res == -1) Debug(net, 1, "sendto({}) failed: {}", send.GetAddressAsString(), NetworkError::GetLast().AsString());
 

	
 
		if (!all) break;
 
	}
 
}
 

	
 
/**
 
@@ -131,13 +131,13 @@ void NetworkUDPSocketHandler::ReceivePac
 

	
 
			NetworkAddress address(client_addr, client_len);
 

	
 
			/* If the size does not match the packet must be corrupted.
 
			 * Otherwise it will be marked as corrupted later on. */
 
			if (!p.ParsePacketSize() || (size_t)nbytes != p.Size()) {
 
				DEBUG(net, 1, "Received a packet with mismatching size from %s", address.GetAddressAsString().c_str());
 
				Debug(net, 1, "Received a packet with mismatching size from {}", address.GetAddressAsString());
 
				continue;
 
			}
 
			p.PrepareToRead();
 

	
 
			/* Handle the packet */
 
			this->HandleUDPPacket(&p, &address);
 
@@ -172,28 +172,28 @@ void NetworkUDPSocketHandler::HandleUDPP
 
		case PACKET_UDP_CLIENT_GET_NEWGRFS:   this->Receive_CLIENT_GET_NEWGRFS(p, client_addr);   break;
 
		case PACKET_UDP_SERVER_NEWGRFS:       this->Receive_SERVER_NEWGRFS(p, client_addr);       break;
 
		case PACKET_UDP_MASTER_SESSION_KEY:   this->Receive_MASTER_SESSION_KEY(p, client_addr);   break;
 

	
 
		default:
 
			if (this->HasClientQuit()) {
 
				DEBUG(net, 0, "[udp] Received invalid packet type %d from %s", type, client_addr->GetAddressAsString().c_str());
 
				Debug(net, 0, "[udp] Received invalid packet type {} from {}", type, client_addr->GetAddressAsString());
 
			} else {
 
				DEBUG(net, 0, "[udp] Received illegal packet from %s", client_addr->GetAddressAsString().c_str());
 
				Debug(net, 0, "[udp] Received illegal packet from {}", client_addr->GetAddressAsString());
 
			}
 
			break;
 
	}
 
}
 

	
 
/**
 
 * Helper for logging receiving invalid packets.
 
 * @param type The received packet type.
 
 * @param client_addr The address we received the packet from.
 
 */
 
void NetworkUDPSocketHandler::ReceiveInvalidPacket(PacketUDPType type, NetworkAddress *client_addr)
 
{
 
	DEBUG(net, 0, "[udp] Received packet type %d on wrong port from %s", type, client_addr->GetAddressAsString().c_str());
 
	Debug(net, 0, "[udp] Received packet type {} on wrong port from {}", type, client_addr->GetAddressAsString());
 
}
 

	
 
void NetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_FIND_SERVER, client_addr); }
 
void NetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_RESPONSE, client_addr); }
 
void NetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_DETAIL_INFO, client_addr); }
 
void NetworkUDPSocketHandler::Receive_SERVER_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_DETAIL_INFO, client_addr); }
src/network/network.cpp
Show inline comments
 
@@ -261,13 +261,13 @@ void NetworkTextMessage(NetworkAction ac
 
	 * right-to-left characters depending on the context. As the next text might be an user's name, the
 
	 * user name's characters will influence the direction of the "***" instead of the language setting
 
	 * of the game. Manually set the direction of the "***" by inserting a text-direction marker. */
 
	char *msg_ptr = message + Utf8Encode(message, _current_text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM);
 
	GetString(msg_ptr, strid, lastof(message));
 

	
 
	DEBUG(desync, 1, "msg: %08x; %02x; %s", _date, _date_fract, message);
 
	Debug(desync, 1, "msg: {:08x}; {:02x}; {}", _date, _date_fract, message);
 
	IConsolePrintF(colour, "%s", message);
 
	NetworkAddChatMessage((TextColour)colour, _settings_client.gui.network_chat_timeout, message);
 
}
 

	
 
/* Calculate the frame-lag of a client */
 
uint NetworkCalculateLag(const NetworkClientSocket *cs)
 
@@ -874,20 +874,20 @@ bool NetworkValidateServerName(std::stri
 
 */
 
static void CheckClientAndServerName()
 
{
 
	static const std::string fallback_client_name = "Unnamed Client";
 
	StrTrimInPlace(_settings_client.network.client_name);
 
	if (_settings_client.network.client_name.empty() || _settings_client.network.client_name.compare(fallback_client_name) == 0) {
 
		DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name <new name>\" command", fallback_client_name.c_str());
 
		Debug(net, 1, "No \"client_name\" has been set, using \"{}\" instead. Please set this now using the \"name <new name>\" command", fallback_client_name);
 
		_settings_client.network.client_name = fallback_client_name;
 
	}
 

	
 
	static const std::string fallback_server_name = "Unnamed Server";
 
	StrTrimInPlace(_settings_client.network.server_name);
 
	if (_settings_client.network.server_name.empty() || _settings_client.network.server_name.compare(fallback_server_name) == 0) {
 
		DEBUG(net, 1, "No \"server_name\" has been set, using \"%s\" instead. Please set this now using the \"server_name <new name>\" command", fallback_server_name.c_str());
 
		Debug(net, 1, "No \"server_name\" has been set, using \"{}\" instead. Please set this now using the \"server_name <new name>\" command", fallback_server_name);
 
		_settings_client.network.server_name = fallback_server_name;
 
	}
 
}
 

	
 
bool NetworkServerStart()
 
{
 
@@ -899,23 +899,23 @@ bool NetworkServerStart()
 

	
 
	/* Check for the client and server names to be set, but only after the scripts had a chance to set them.*/
 
	if (_network_dedicated) CheckClientAndServerName();
 

	
 
	NetworkDisconnect(false, false);
 
	NetworkInitialize(false);
 
	DEBUG(net, 5, "Starting listeners for clients");
 
	Debug(net, 5, "Starting listeners for clients");
 
	if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false;
 

	
 
	/* Only listen for admins when the password isn't empty. */
 
	if (!_settings_client.network.admin_password.empty()) {
 
		DEBUG(net, 5, "Starting listeners for admins");
 
		Debug(net, 5, "Starting listeners for admins");
 
		if (!ServerNetworkAdminSocketHandler::Listen(_settings_client.network.server_admin_port)) return false;
 
	}
 

	
 
	/* Try to start UDP-server */
 
	DEBUG(net, 5, "Starting listeners for incoming server queries");
 
	Debug(net, 5, "Starting listeners for incoming server queries");
 
	NetworkUDPServerListen();
 

	
 
	_network_company_states = new NetworkCompanyState[MAX_COMPANIES];
 
	_network_server = true;
 
	_networking = true;
 
	_frame_counter = 0;
 
@@ -1046,13 +1046,13 @@ void NetworkGameLoop()
 
	if (_network_server) {
 
		/* Log the sync state to check for in-syncedness of replays. */
 
		if (_date_fract == 0) {
 
			/* We don't want to log multiple times if paused. */
 
			static Date last_log;
 
			if (last_log != _date) {
 
				DEBUG(desync, 1, "sync: %08x; %02x; %08x; %08x", _date, _date_fract, _random.state[0], _random.state[1]);
 
				Debug(desync, 1, "sync: {:08x}; {:02x}; {:08x}; {:08x}", _date, _date_fract, _random.state[0], _random.state[1]);
 
				last_log = _date;
 
			}
 
		}
 

	
 
#ifdef DEBUG_DUMP_COMMANDS
 
		/* Loading of the debug commands from -ddesync>=1 */
 
@@ -1060,29 +1060,29 @@ void NetworkGameLoop()
 
		static Date next_date = 0;
 
		static uint32 next_date_fract;
 
		static CommandPacket *cp = nullptr;
 
		static bool check_sync_state = false;
 
		static uint32 sync_state[2];
 
		if (f == nullptr && next_date == 0) {
 
			DEBUG(desync, 0, "Cannot open commands.log");
 
			Debug(desync, 0, "Cannot open commands.log");
 
			next_date = 1;
 
		}
 

	
 
		while (f != nullptr && !feof(f)) {
 
			if (_date == next_date && _date_fract == next_date_fract) {
 
				if (cp != nullptr) {
 
					NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text, cp->company);
 
					DEBUG(desync, 0, "Injecting: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text.c_str(), GetCommandName(cp->cmd));
 
					Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd));
 
					delete cp;
 
					cp = nullptr;
 
				}
 
				if (check_sync_state) {
 
					if (sync_state[0] == _random.state[0] && sync_state[1] == _random.state[1]) {
 
						DEBUG(desync, 0, "Sync check: %08x; %02x; match", _date, _date_fract);
 
						Debug(desync, 0, "Sync check: {:08x}; {:02x}; match", _date, _date_fract);
 
					} else {
 
						DEBUG(desync, 0, "Sync check: %08x; %02x; mismatch expected {%08x, %08x}, got {%08x, %08x}",
 
						Debug(desync, 0, "Sync check: {:08x}; {:02x}; mismatch expected {{:08x}, {:08x}}, got {{:08x}, {:08x}}",
 
									_date, _date_fract, sync_state[0], sync_state[1], _random.state[0], _random.state[1]);
 
						NOT_REACHED();
 
					}
 
					check_sync_state = false;
 
				}
 
			}
 
@@ -1118,13 +1118,13 @@ void NetworkGameLoop()
 
				assert(ret == 8 || ret == 7);
 
				cp->company = (CompanyID)company;
 
			} else if (strncmp(p, "join: ", 6) == 0) {
 
				/* Manually insert a pause when joining; this way the client can join at the exact right time. */
 
				int ret = sscanf(p + 6, "%x; %x", &next_date, &next_date_fract);
 
				assert(ret == 2);
 
				DEBUG(desync, 0, "Injecting pause for join at %08x:%02x; please join when paused", next_date, next_date_fract);
 
				Debug(desync, 0, "Injecting pause for join at {:08x}:{:02x}; please join when paused", next_date, next_date_fract);
 
				cp = new CommandPacket();
 
				cp->company = COMPANY_SPECTATOR;
 
				cp->cmd = CMD_PAUSE;
 
				cp->p1 = PM_PAUSED_NORMAL;
 
				cp->p2 = 1;
 
				_ddc_fastforward = false;
 
@@ -1134,22 +1134,22 @@ void NetworkGameLoop()
 
				check_sync_state = true;
 
			} else if (strncmp(p, "msg: ", 5) == 0 || strncmp(p, "client: ", 8) == 0 ||
 
						strncmp(p, "load: ", 6) == 0 || strncmp(p, "save: ", 6) == 0) {
 
				/* A message that is not very important to the log playback, but part of the log. */
 
#ifndef DEBUG_FAILED_DUMP_COMMANDS
 
			} else if (strncmp(p, "cmdf: ", 6) == 0) {
 
				DEBUG(desync, 0, "Skipping replay of failed command: %s", p + 6);
 
				Debug(desync, 0, "Skipping replay of failed command: {}", p + 6);
 
#endif
 
			} else {
 
				/* Can't parse a line; what's wrong here? */
 
				DEBUG(desync, 0, "Trying to parse: %s", p);
 
				Debug(desync, 0, "Trying to parse: {}", p);
 
				NOT_REACHED();
 
			}
 
		}
 
		if (f != nullptr && feof(f)) {
 
			DEBUG(desync, 0, "End of commands.log");
 
			Debug(desync, 0, "End of commands.log");
 
			fclose(f);
 
			f = nullptr;
 
		}
 
#endif /* DEBUG_DUMP_COMMANDS */
 
		if (_frame_counter >= _frame_counter_max) {
 
			/* Only check for active clients just before we're going to send out
 
@@ -1230,18 +1230,18 @@ private:
 

	
 
public:
 
	TCPNetworkDebugConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_DEBUGLOG_PORT), connection_string(connection_string) {}
 

	
 
	void OnFailure() override
 
	{
 
		DEBUG(net, 0, "Failed to open connection to %s for redirecting DEBUG()", this->connection_string.c_str());
 
		Debug(net, 0, "Failed to open connection to {} for redirecting Debug()", this->connection_string);
 
	}
 

	
 
	void OnConnect(SOCKET s) override
 
	{
 
		DEBUG(net, 3, "Redirecting DEBUG() to %s", this->connection_string.c_str());
 
		Debug(net, 3, "Redirecting Debug() to {}", this->connection_string);
 

	
 
		extern SOCKET _debug_socket;
 
		_debug_socket = s;
 
	}
 
};
 

	
 
@@ -1250,36 +1250,36 @@ void NetworkStartDebugLog(const std::str
 
	new TCPNetworkDebugConnecter(connection_string);
 
}
 

	
 
/** This tries to launch the network for a given OS */
 
void NetworkStartUp()
 
{
 
	DEBUG(net, 3, "Starting network");
 
	Debug(net, 3, "Starting network");
 

	
 
	/* Network is available */
 
	_network_available = NetworkCoreInitialize();
 
	_network_dedicated = false;
 
	_network_need_advertise = true;
 

	
 
	/* Generate an server id when there is none yet */
 
	if (_settings_client.network.network_id.empty()) NetworkGenerateServerId();
 

	
 
	_network_game_info = {};
 

	
 
	NetworkInitialize();
 
	DEBUG(net, 3, "Network online, multiplayer available");
 
	Debug(net, 3, "Network online, multiplayer available");
 
	NetworkFindBroadcastIPs(&_broadcast_list);
 
}
 

	
 
/** This shuts the network down */
 
void NetworkShutDown()
 
{
 
	NetworkDisconnect(true);
 
	NetworkUDPClose();
 

	
 
	DEBUG(net, 3, "Shutting down network");
 
	Debug(net, 3, "Shutting down network");
 

	
 
	_network_available = false;
 

	
 
	NetworkCoreShutdown();
 
}
 

	
src/network/network_admin.cpp
Show inline comments
 
@@ -71,13 +71,13 @@ ServerNetworkAdminSocketHandler::ServerN
 
/**
 
 * Clear everything related to this admin.
 
 */
 
ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
 
{
 
	_network_admins_connected--;
 
	DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name.c_str(), this->admin_version.c_str());
 
	Debug(net, 3, "[admin] '{}' ({}) has disconnected", this->admin_name, this->admin_version);
 
	if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
 
}
 

	
 
/**
 
 * Whether a connection is allowed or not at this moment.
 
 * @return Whether the connection is allowed.
 
@@ -94,13 +94,13 @@ ServerNetworkAdminSocketHandler::~Server
 

	
 
/** Send the packets for the server sockets. */
 
/* static */ void ServerNetworkAdminSocketHandler::Send()
 
{
 
	for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) {
 
		if (as->status == ADMIN_STATUS_INACTIVE && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) {
 
			DEBUG(net, 2, "[admin] Admin did not send its authorisation within %d seconds", (uint32)std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
 
			Debug(net, 2, "[admin] Admin did not send its authorisation within {} seconds", std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
 
			as->CloseConnection(true);
 
			continue;
 
		}
 
		if (as->writable) {
 
			as->SendPackets();
 
		}
 
@@ -132,13 +132,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 

	
 
	p->Send_uint8(error);
 
	this->SendPacket(p);
 

	
 
	std::string error_message = GetString(GetNetworkErrorMsg(error));
 

	
 
	DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name.c_str(), this->admin_version.c_str(), error_message.c_str());
 
	Debug(net, 1, "[admin] The admin '{}' ({}) made an error and has been disconnected: '{}'", this->admin_name, this->admin_version, error_message);
 

	
 
	return this->CloseConnection(true);
 
}
 

	
 
/** Send the protocol version to the admin. */
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
 
@@ -497,13 +497,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
 
{
 
	if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
 

	
 
	std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
 

	
 
	DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), command.c_str());
 
	Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
 

	
 
	_redirect_console_to_admin = this->index;
 
	IConsoleCmdExec(command.c_str());
 
	_redirect_console_to_admin = INVALID_ADMIN_ID;
 
	return this->SendRconEnd(command);
 
}
 
@@ -511,25 +511,25 @@ NetworkRecvStatus ServerNetworkAdminSock
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Packet *p)
 
{
 
	if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
 

	
 
	std::string json = p->Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
 

	
 
	DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), json.c_str());
 
	Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
 

	
 
	Game::NewEvent(new ScriptEventAdminPort(json));
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
 
{
 
	if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
 

	
 
	uint32 d1 = p->Recv_uint32();
 

	
 
	DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name.c_str(), this->admin_version.c_str(), d1);
 
	Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
 

	
 
	return this->SendPong(d1);
 
}
 

	
 
/**
 
 * Send console output of other clients.
 
@@ -659,13 +659,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 
		/* no name or version supplied */
 
		return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	this->status = ADMIN_STATUS_ACTIVE;
 

	
 
	DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name.c_str(), this->admin_version.c_str());
 
	Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
 

	
 
	return this->SendProtocol();
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_QUIT(Packet *p)
 
{
 
@@ -679,13 +679,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 

	
 
	AdminUpdateType type = (AdminUpdateType)p->Recv_uint16();
 
	AdminUpdateFrequency freq = (AdminUpdateFrequency)p->Recv_uint16();
 

	
 
	if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
 
		/* The server does not know of this UpdateType. */
 
		DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name.c_str(), this->admin_version.c_str());
 
		Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
 
		return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	this->update_frequency[type] = freq;
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
@@ -747,13 +747,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 
			/* The admin is requesting the names of DoCommands. */
 
			this->SendCmdNames();
 
			break;
 

	
 
		default:
 
			/* An unsupported "poll" update type. */
 
			DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name.c_str(), this->admin_version.c_str());
 
			Debug(net, 1, "[admin] Not supported poll {} ({}) from '{}' ({}).", type, d1, this->admin_name, this->admin_version);
 
			return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
@@ -773,13 +773,13 @@ NetworkRecvStatus ServerNetworkAdminSock
 
		case NETWORK_ACTION_CHAT_COMPANY:
 
		case NETWORK_ACTION_SERVER_MESSAGE:
 
			NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
 
			break;
 

	
 
		default:
 
			DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name.c_str(), this->admin_version.c_str());
 
			Debug(net, 1, "[admin] Invalid chat action {} from admin '{}' ({}).", action, this->admin_name, this->admin_version);
 
			return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
@@ -849,13 +849,13 @@ void NetworkAdminClientError(ClientID cl
 
 * @param company the company of which details will be sent into the admin network.
 
 * @param new_company whether this is a new company or not.
 
 */
 
void NetworkAdminCompanyInfo(const Company *company, bool new_company)
 
{
 
	if (company == nullptr) {
 
		DEBUG(net, 1, "[admin] Empty company given for update");
 
		Debug(net, 1, "[admin] Empty company given for update");
 
		return;
 
	}
 

	
 
	for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
 
		if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
 

	
src/network/network_client.cpp
Show inline comments
 
@@ -133,13 +133,13 @@ struct PacketReader : LoadFilter {
 
void ClientNetworkEmergencySave()
 
{
 
	if (!_settings_client.gui.autosave_on_network_disconnect) return;
 
	if (!_networking) return;
 

	
 
	const char *filename = "netsave.sav";
 
	DEBUG(net, 3, "Performing emergency save: %s", filename);
 
	Debug(net, 3, "Performing emergency save: {}", filename);
 
	SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
 
}
 

	
 

	
 
/**
 
 * Create a new socket for the client side of the game connection.
 
@@ -170,13 +170,13 @@ NetworkRecvStatus ClientNetworkGameSocke
 
	 * connection after cs->SendPackets we will close an already closed
 
	 * connection. This handles that case gracefully without having to make
 
	 * that code any more complex or more aware of the validity of the socket.
 
	 */
 
	if (this->sock == INVALID_SOCKET) return status;
 

	
 
	DEBUG(net, 3, "Closed client connection %d", this->client_id);
 
	Debug(net, 3, "Closed client connection {}", this->client_id);
 

	
 
	this->SendPackets(true);
 

	
 
	/* 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,
 
@@ -282,14 +282,14 @@ void ClientNetworkGameSocketHandler::Cli
 
#ifdef NETWORK_SEND_DOUBLE_SEED
 
			if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
 
#else
 
			if (_sync_seed_1 != _random.state[0]) {
 
#endif
 
				ShowNetworkError(STR_NETWORK_ERROR_DESYNC);
 
				DEBUG(desync, 1, "sync_err: %08x; %02x", _date, _date_fract);
 
				DEBUG(net, 0, "Sync error detected");
 
				Debug(desync, 1, "sync_err: {:08x}; {:02x}", _date, _date_fract);
 
				Debug(net, 0, "Sync error detected");
 
				my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
 
				return false;
 
			}
 

	
 
			/* If this is the first time we have a sync-frame, we
 
			 *   need to let the server know that we are ready and at the same
 
@@ -298,13 +298,13 @@ void ClientNetworkGameSocketHandler::Cli
 
				_network_first_time = false;
 
				SendAck();
 
			}
 

	
 
			_sync_frame = 0;
 
		} else if (_sync_frame < _frame_counter) {
 
			DEBUG(net, 1, "Missed frame for sync-test: %d / %d", _sync_frame, _frame_counter);
 
			Debug(net, 1, "Missed frame for sync-test: {} / {}", _sync_frame, _frame_counter);
 
			_sync_frame = 0;
 
		}
 
	}
 

	
 
	return true;
 
}
 
@@ -774,13 +774,13 @@ NetworkRecvStatus ClientNetworkGameSocke
 
		/* Check whether we know this GRF */
 
		const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum);
 
		if (f == nullptr) {
 
			/* We do not know this GRF, bail out of initialization */
 
			char buf[sizeof(c.md5sum) * 2 + 1];
 
			md5sumToString(buf, lastof(buf), c.md5sum);
 
			DEBUG(grf, 0, "NewGRF %08X not found; checksum %s", BSWAP32(c.grfid), buf);
 
			Debug(grf, 0, "NewGRF {:08X} not found; checksum {}", BSWAP32(c.grfid), buf);
 
			ret = NETWORK_RECV_STATUS_NEWGRF_MISMATCH;
 
		}
 
	}
 

	
 
	if (ret == NETWORK_RECV_STATUS_OKAY) {
 
		/* Start receiving the map */
 
@@ -971,19 +971,19 @@ NetworkRecvStatus ClientNetworkGameSocke
 
#endif
 
	}
 
#endif
 
	/* Receive the token. */
 
	if (p->CanReadFromPacket(sizeof(uint8))) this->token = p->Recv_uint8();
 

	
 
	DEBUG(net, 7, "Received FRAME %d", _frame_counter_server);
 
	Debug(net, 7, "Received FRAME {}", _frame_counter_server);
 

	
 
	/* Let the server know that we received this frame correctly
 
	 *  We do this only once per day, to save some bandwidth ;) */
 
	if (!_network_first_time && last_ack_frame < _frame_counter) {
 
		last_ack_frame = _frame_counter + DAY_TICKS;
 
		DEBUG(net, 7, "Sent ACK at %d", _frame_counter);
 
		Debug(net, 7, "Sent ACK at {}", _frame_counter);
 
		SendAck();
 
	}
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
@@ -1093,13 +1093,13 @@ NetworkRecvStatus ClientNetworkGameSocke
 

	
 
	NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
 
	if (ci != nullptr) {
 
		NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING);
 
		delete ci;
 
	} else {
 
		DEBUG(net, 1, "Unknown client (%d) is leaving the game", client_id);
 
		Debug(net, 1, "Unknown client ({}) is leaving the game", client_id);
 
	}
 

	
 
	InvalidateWindowData(WC_CLIENT_LIST, 0);
 

	
 
	/* If we come here it means we could not locate the client.. strange :s */
 
	return NETWORK_RECV_STATUS_OKAY;
 
@@ -1172,13 +1172,13 @@ NetworkRecvStatus ClientNetworkGameSocke
 
	/* Nothing more in this packet... */
 
	ClientID client_id   = (ClientID)p->Recv_uint32();
 
	CompanyID company_id = (CompanyID)p->Recv_uint8();
 

	
 
	if (client_id == 0) {
 
		/* definitely an invalid client id, debug message and do nothing. */
 
		DEBUG(net, 1, "Received invalid client index = 0");
 
		Debug(net, 1, "Received invalid client index = 0");
 
		return NETWORK_RECV_STATUS_MALFORMED_PACKET;
 
	}
 

	
 
	const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
 
	/* Just make sure we do not try to use a client_index that does not exist */
 
	if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
src/network/network_command.cpp
Show inline comments
 
@@ -329,11 +329,11 @@ void NetworkGameSocketHandler::SendComma
 
	byte callback = 0;
 
	while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {
 
		callback++;
 
	}
 

	
 
	if (callback == lengthof(_callback_table)) {
 
		DEBUG(net, 0, "Unknown callback for command; no callback sent (command: %d)", cp->cmd);
 
		Debug(net, 0, "Unknown callback for command; no callback sent (command: {})", cp->cmd);
 
		callback = 0; // _callback_table[0] == nullptr
 
	}
 
	p->Send_uint8 (callback);
 
}
src/network/network_server.cpp
Show inline comments
 
@@ -280,13 +280,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
		this->savegame = nullptr;
 

	
 
		this->CheckNextClientToSendMap(this);
 
	}
 

	
 
	NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
 
	DEBUG(net, 3, "Closed client connection %d", this->client_id);
 
	Debug(net, 3, "Closed client connection {}", this->client_id);
 

	
 
	/* We just lost one client :( */
 
	if (this->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
 
	extern byte _network_clients_connected;
 
	_network_clients_connected--;
 

	
 
@@ -442,13 +442,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
	/* Only send when the current client was in game */
 
	if (this->status > STATUS_AUTHORIZED) {
 
		char client_name[NETWORK_CLIENT_NAME_LENGTH];
 

	
 
		this->GetClientName(client_name, lastof(client_name));
 

	
 
		DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str());
 
		Debug(net, 1, "'{}' made an error and has been disconnected: {}", client_name, GetString(strid));
 

	
 
		if (error == NETWORK_ERROR_KICKED && !reason.empty()) {
 
			NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid);
 
		} else {
 
			NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
 
		}
 
@@ -463,13 +463,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
				new_cs->SendErrorQuit(this->client_id, error);
 
			}
 
		}
 

	
 
		NetworkAdminClientError(this->client_id, error);
 
	} else {
 
		DEBUG(net, 1, "Client %d made an error and has been disconnected: %s", this->client_id, GetString(strid).c_str());
 
		Debug(net, 1, "Client {} made an error and has been disconnected: {}", this->client_id, GetString(strid));
 
	}
 

	
 
	/* The client made a mistake, so drop the connection now! */
 
	return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
 
}
 

	
 
@@ -922,13 +922,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
	assert(NetworkClientInfo::CanAllocateItem());
 
	NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
 
	this->SetInfo(ci);
 
	ci->join_date = _date;
 
	ci->client_name = client_name;
 
	ci->client_playas = playas;
 
	DEBUG(desync, 1, "client: %08x; %02x; %02x; %02x", _date, _date_fract, (int)ci->client_playas, (int)ci->index);
 
	Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:02x}", _date, _date_fract, (int)ci->client_playas, (int)ci->index);
 

	
 
	/* Make sure companies to which people try to join are not autocleaned */
 
	if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
 

	
 
	this->status = STATUS_NEWGRFS_CHECK;
 

	
 
@@ -1130,13 +1130,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
	}
 

	
 
	this->GetClientName(client_name, lastof(client_name));
 

	
 
	StringID strid = GetNetworkErrorMsg(errorno);
 

	
 
	DEBUG(net, 1, "'%s' reported an error and is closing its connection: %s", client_name, GetString(strid).c_str());
 
	Debug(net, 1, "'{}' reported an error and is closing its connection: {}", client_name, GetString(strid));
 

	
 
	NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
 

	
 
	for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
 
		if (new_cs->status >= STATUS_AUTHORIZED) {
 
			new_cs->SendErrorQuit(this->client_id, errorno);
 
@@ -1320,13 +1320,13 @@ void NetworkServerSendChat(NetworkAction
 
					}
 
				}
 
			}
 
			break;
 
		}
 
		default:
 
			DEBUG(net, 1, "Received unknown chat destination type %d; doing broadcast instead", desttype);
 
			Debug(net, 1, "Received unknown chat destination type {}; doing broadcast instead", desttype);
 
			FALLTHROUGH;
 

	
 
		case DESTTYPE_BROADCAST:
 
			for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
 
				cs->SendChat(action, from_id, false, msg, data);
 
			}
 
@@ -1422,17 +1422,17 @@ NetworkRecvStatus ServerNetworkGameSocke
 
	if (_settings_client.network.rcon_password.empty()) return NETWORK_RECV_STATUS_OKAY;
 

	
 
	std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
 
	std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
 

	
 
	if (_settings_client.network.rcon_password.compare(password) != 0) {
 
		DEBUG(net, 1, "[rcon] Wrong password from client-id %d", this->client_id);
 
		Debug(net, 1, "[rcon] Wrong password from client-id {}", this->client_id);
 
		return NETWORK_RECV_STATUS_OKAY;
 
	}
 

	
 
	DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command.c_str());
 
	Debug(net, 3, "[rcon] Client-id {} executed: {}", this->client_id, command);
 

	
 
	_redirect_console_to_client = this->client_id;
 
	IConsoleCmdExec(command.c_str());
 
	_redirect_console_to_client = INVALID_CLIENT_ID;
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 
@@ -1450,13 +1450,13 @@ NetworkRecvStatus ServerNetworkGameSocke
 
	if (company_id != COMPANY_SPECTATOR && !_network_company_states[company_id].password.empty()) {
 
		/* we need a password from the client - should be in this packet */
 
		std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
 

	
 
		/* Incorrect password sent, return! */
 
		if (_network_company_states[company_id].password.compare(password) != 0) {
 
			DEBUG(net, 2, "Wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
 
			Debug(net, 2, "Wrong password from client-id #{} for company #{}", this->client_id, company_id + 1);
 
			return NETWORK_RECV_STATUS_OKAY;
 
		}
 
	}
 

	
 
	/* if we get here we can move the client */
 
	NetworkServerDoMove(this->client_id, company_id);
 
@@ -1558,13 +1558,13 @@ void NetworkPopulateCompanyStats(Network
 
void NetworkUpdateClientInfo(ClientID client_id)
 
{
 
	NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
 

	
 
	if (ci == nullptr) return;
 

	
 
	DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id);
 
	Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:04x}", _date, _date_fract, (int)ci->client_playas, client_id);
 

	
 
	for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
 
		if (cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
 
			cs->SendClientInfo(ci);
 
		}
 
	}
 
@@ -1573,13 +1573,13 @@ void NetworkUpdateClientInfo(ClientID cl
 
}
 

	
 
/** Check if we want to restart the map */
 
static void NetworkCheckRestartMap()
 
{
 
	if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
 
		DEBUG(net, 3, "Auto-restarting map: year %d reached", _cur_year);
 
		Debug(net, 3, "Auto-restarting map: year {} reached", _cur_year);
 

	
 
		_settings_newgame.game_creation.generation_seed = GENERATE_NEW_SEED;
 
		switch(_file_to_saveload.abstract_ftype) {
 
			case FT_SAVEGAME:
 
			case FT_SCENARIO:
 
				_switch_mode = SM_LOAD_GAME;
src/network/network_udp.cpp
Show inline comments
 
@@ -64,13 +64,13 @@ struct UDPSocket {
 

	
 
	void ReceivePackets()
 
	{
 
		std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
 
		if (!lock.try_lock()) {
 
			if (++receive_iterations_locked % 32 == 0) {
 
				DEBUG(net, 0, "%s background UDP loop processing appears to be blocked. Your OS may be low on UDP send buffers.", name.c_str());
 
				Debug(net, 0, "{} background UDP loop processing appears to be blocked. Your OS may be low on UDP send buffers.", name);
 
			}
 
			return;
 
		}
 

	
 
		receive_iterations_locked.store(0);
 
		socket->ReceivePackets();
 
@@ -130,22 +130,22 @@ public:
 
	virtual ~MasterNetworkUDPSocketHandler() {}
 
};
 

	
 
void MasterNetworkUDPSocketHandler::Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr)
 
{
 
	_network_advertise_retries = 0;
 
	DEBUG(net, 3, "Advertising on master server successful (%s)", NetworkAddress::AddressFamilyAsString(client_addr->GetAddress()->ss_family));
 
	Debug(net, 3, "Advertising on master server successful ({})", NetworkAddress::AddressFamilyAsString(client_addr->GetAddress()->ss_family));
 

	
 
	/* We are advertised, but we don't want to! */
 
	if (!_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(false);
 
}
 

	
 
void MasterNetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr)
 
{
 
	_session_key = p->Recv_uint64();
 
	DEBUG(net, 6, "Received new session key from master server (%s)", NetworkAddress::AddressFamilyAsString(client_addr->GetAddress()->ss_family));
 
	Debug(net, 6, "Received new session key from master server ({})", NetworkAddress::AddressFamilyAsString(client_addr->GetAddress()->ss_family));
 
}
 

	
 
///*** Communication with clients (we are server) ***/
 

	
 
/** Helper class for handling all server side communication. */
 
class ServerNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
 
@@ -172,13 +172,13 @@ void ServerNetworkUDPSocketHandler::Rece
 
	Packet packet(PACKET_UDP_SERVER_RESPONSE);
 
	SerializeNetworkGameInfo(&packet, GetCurrentNetworkServerGameInfo());
 

	
 
	/* Let the client know that we are here */
 
	this->SendPacket(&packet, client_addr);
 

	
 
	DEBUG(net, 7, "Queried from %s", client_addr->GetHostname());
 
	Debug(net, 7, "Queried from {}", client_addr->GetHostname());
 
}
 

	
 
void ServerNetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr)
 
{
 
	/* Just a fail-safe.. should never happen */
 
	if (!_network_udp_server) return;
 
@@ -249,13 +249,13 @@ void ServerNetworkUDPSocketHandler::Rece
 
	uint i;
 

	
 
	const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT];
 
	uint8 in_reply_count = 0;
 
	size_t packet_len = 0;
 

	
 
	DEBUG(net, 7, "NewGRF data request from %s", client_addr->GetAddressAsString().c_str());
 
	Debug(net, 7, "NewGRF data request from {}", client_addr->GetAddressAsString());
 

	
 
	num_grfs = p->Recv_uint8 ();
 
	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
 

	
 
	for (i = 0; i < num_grfs; i++) {
 
		GRFIdentifier c;
 
@@ -311,13 +311,13 @@ void ClientNetworkUDPSocketHandler::Rece
 
{
 
	NetworkGameList *item;
 

	
 
	/* Just a fail-safe.. should never happen */
 
	if (_network_udp_server) return;
 

	
 
	DEBUG(net, 3, "Server response from %s", client_addr->GetAddressAsString().c_str());
 
	Debug(net, 3, "Server response from {}", client_addr->GetAddressAsString());
 

	
 
	/* Find next item */
 
	item = NetworkGameListAddItem(client_addr->GetAddressAsString(false));
 

	
 
	/* Clear any existing GRFConfig chain. */
 
	ClearGRFConfigList(&item->info.grfconfig);
 
@@ -406,13 +406,13 @@ void ClientNetworkUDPSocketHandler::Rece
 
/** The return of the client's request of the names of some NewGRFs */
 
void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr)
 
{
 
	uint8 num_grfs;
 
	uint i;
 

	
 
	DEBUG(net, 7, "NewGRF data reply from %s", client_addr->GetAddressAsString().c_str());
 
	Debug(net, 7, "NewGRF data reply from {}", client_addr->GetAddressAsString());
 

	
 
	num_grfs = p->Recv_uint8 ();
 
	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
 

	
 
	for (i = 0; i < num_grfs; i++) {
 
		GRFIdentifier c;
 
@@ -437,13 +437,13 @@ void ClientNetworkUDPSocketHandler::Rece
 
/** Broadcast to all ips */
 
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
 
{
 
	for (NetworkAddress &addr : _broadcast_list) {
 
		Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
 

	
 
		DEBUG(net, 5, "Broadcasting to %s", addr.GetHostname());
 
		Debug(net, 5, "Broadcasting to {}", addr.GetHostname());
 

	
 
		socket->SendPacket(&p, &addr, true, true);
 
	}
 
}
 

	
 

	
 
@@ -457,33 +457,33 @@ void NetworkUDPQueryMasterServer()
 
	p.Send_uint8(NETWORK_MASTER_SERVER_VERSION);
 
	p.Send_uint8(SLT_AUTODETECT);
 

	
 
	std::lock_guard<std::mutex> lock(_udp_client.mutex);
 
	_udp_client.socket->SendPacket(&p, &out_addr, true);
 

	
 
	DEBUG(net, 6, "Master server queried at %s", out_addr.GetAddressAsString().c_str());
 
	Debug(net, 6, "Master server queried at {}", out_addr.GetAddressAsString());
 
}
 

	
 
/** Find all servers */
 
void NetworkUDPSearchGame()
 
{
 
	/* We are still searching.. */
 
	if (_network_udp_broadcast > 0) return;
 

	
 
	DEBUG(net, 3, "Searching server");
 
	Debug(net, 3, "Searching server");
 

	
 
	NetworkUDPBroadCast(_udp_client.socket);
 
	_network_udp_broadcast = 300; // Stay searching for 300 ticks
 
}
 

	
 
/**
 
 * Thread entry point for de-advertising.
 
 */
 
static void NetworkUDPRemoveAdvertiseThread()
 
{
 
	DEBUG(net, 3, "Removing advertise from master server");
 
	Debug(net, 3, "Removing advertise from master server");
 

	
 
	/* Find somewhere to send */
 
	NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
 

	
 
	/* Send the packet */
 
	Packet p(PACKET_UDP_SERVER_UNREGISTER);
 
@@ -514,28 +514,28 @@ void NetworkUDPRemoveAdvertise(bool bloc
 
 */
 
static void NetworkUDPAdvertiseThread()
 
{
 
	/* Find somewhere to send */
 
	NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
 

	
 
	DEBUG(net, 3, "Advertising to master server");
 
	Debug(net, 3, "Advertising to master server");
 

	
 
	/* Add a bit more messaging when we cannot get a session key */
 
	static byte session_key_retries = 0;
 
	if (_session_key == 0 && session_key_retries++ == 2) {
 
		DEBUG(net, 0, "Advertising to the master server is failing");
 
		DEBUG(net, 0, "  we are not receiving the session key from the server");
 
		DEBUG(net, 0, "  please allow udp packets from %s to you to be delivered", out_addr.GetAddressAsString(false).c_str());
 
		DEBUG(net, 0, "  please allow udp packets from you to %s to be delivered", out_addr.GetAddressAsString(false).c_str());
 
		Debug(net, 0, "Advertising to the master server is failing");
 
		Debug(net, 0, "  we are not receiving the session key from the server");
 
		Debug(net, 0, "  please allow udp packets from {} to you to be delivered", out_addr.GetAddressAsString(false));
 
		Debug(net, 0, "  please allow udp packets from you to {} to be delivered", out_addr.GetAddressAsString(false));
 
	}
 
	if (_session_key != 0 && _network_advertise_retries == 0) {
 
		DEBUG(net, 0, "Advertising to the master server is failing");
 
		DEBUG(net, 0, "  we are not receiving the acknowledgement from the server");
 
		DEBUG(net, 0, "  this usually means that the master server cannot reach us");
 
		DEBUG(net, 0, "  please allow udp and tcp packets to port %u to be delivered", _settings_client.network.server_port);
 
		DEBUG(net, 0, "  please allow udp and tcp packets from port %u to be delivered", _settings_client.network.server_port);
 
		Debug(net, 0, "Advertising to the master server is failing");
 
		Debug(net, 0, "  we are not receiving the acknowledgement from the server");
 
		Debug(net, 0, "  this usually means that the master server cannot reach us");
 
		Debug(net, 0, "  please allow udp and tcp packets to port {} to be delivered", _settings_client.network.server_port);
 
		Debug(net, 0, "  please allow udp and tcp packets from port {} to be delivered", _settings_client.network.server_port);
 
	}
 

	
 
	/* Send the packet */
 
	Packet p(PACKET_UDP_SERVER_REGISTER);
 
	/* Packet is: WELCOME_MESSAGE, Version, server_port */
 
	p.Send_string(NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
 
@@ -585,13 +585,13 @@ void NetworkUDPAdvertise()
 
/** Initialize the whole UDP bit. */
 
void NetworkUDPInitialize()
 
{
 
	/* If not closed, then do it. */
 
	if (_udp_server.socket != nullptr) NetworkUDPClose();
 

	
 
	DEBUG(net, 3, "Initializing UDP listeners");
 
	Debug(net, 3, "Initializing UDP listeners");
 
	assert(_udp_client.socket == nullptr && _udp_server.socket == nullptr && _udp_master.socket == nullptr);
 

	
 
	std::scoped_lock lock(_udp_client.mutex, _udp_server.mutex, _udp_master.mutex);
 

	
 
	_udp_client.socket = new ClientNetworkUDPSocketHandler();
 

	
 
@@ -621,13 +621,13 @@ void NetworkUDPClose()
 
	_udp_client.CloseSocket();
 
	_udp_server.CloseSocket();
 
	_udp_master.CloseSocket();
 

	
 
	_network_udp_server = false;
 
	_network_udp_broadcast = 0;
 
	DEBUG(net, 5, "Closed UDP listeners");
 
	Debug(net, 5, "Closed UDP listeners");
 
}
 

	
 
/** Receive the UDP packets. */
 
void NetworkBackgroundUDPLoop()
 
{
 
	if (_network_udp_server) {
src/newgrf.cpp
Show inline comments
 
@@ -377,14 +377,14 @@ struct GRFLocation {
 

	
 
static std::map<GRFLocation, SpriteID> _grm_sprites;
 
typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
 
static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
 

	
 
/**
 
 * DEBUG() function dedicated to newGRF debugging messages
 
 * Function is essentially the same as DEBUG(grf, severity, ...) with the
 
 * Debug() function dedicated to newGRF debugging messages
 
 * Function is essentially the same as Debug(grf, severity, ...) with the
 
 * addition of file:line information when parsing grf files.
 
 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
 
 * loading/parsing grf files, not for runtime debug messages as there
 
 * is no file information available during that time.
 
 * @param severity debugging severity level, see debug.h
 
 * @param str message in printf() format
 
@@ -395,13 +395,13 @@ void CDECL grfmsg(int severity, const ch
 
	va_list va;
 

	
 
	va_start(va, str);
 
	vseprintf(buf, lastof(buf), str, va);
 
	va_end(va);
 

	
 
	DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
 
	Debug(grf, severity, "[{}:{}] {}", _cur.grfconfig->filename, _cur.nfo_line, buf);
 
}
 

	
 
/**
 
 * Obtain a NewGRF file by its grfID
 
 * @param grfid The grfID to obtain the file for
 
 * @return The file.
 
@@ -546,13 +546,13 @@ static StringID TTDPStringIDToOTTDString
 
		case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
 
	}
 
#undef TEXTID_TO_STRINGID
 

	
 
	if (str == STR_NULL) return STR_EMPTY;
 

	
 
	DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
 
	Debug(grf, 0, "Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
 

	
 
	return STR_EMPTY;
 
}
 

	
 
/**
 
 * Used when setting an object's property to map to the GRF's strings
 
@@ -6728,13 +6728,13 @@ static void ScanInfo(ByteReader *buf)
 
	const char *name  = buf->ReadString();
 

	
 
	_cur.grfconfig->ident.grfid = grfid;
 

	
 
	if (grf_version < 2 || grf_version > 8) {
 
		SetBit(_cur.grfconfig->flags, GCF_INVALID);
 
		DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
 
		Debug(grf, 0, "{}: NewGRF \"{}\" (GRFID {:08X}) uses GRF version {}, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
 
	}
 

	
 
	/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
 
	if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
 

	
 
	AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name);
 
@@ -6765,21 +6765,21 @@ static void GRFInfo(ByteReader *buf)
 
	if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
 
		DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
 
		return;
 
	}
 

	
 
	if (_cur.grffile->grfid != grfid) {
 
		DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
 
		Debug(grf, 0, "GRFInfo: GRFID {:08X} in FILESCAN stage does not match GRFID {:08X} in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
 
		_cur.grffile->grfid = grfid;
 
	}
 

	
 
	_cur.grffile->grf_version = version;
 
	_cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
 

	
 
	/* Do swap the GRFID for displaying purposes since people expect that */
 
	DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
 
	Debug(grf, 1, "GRFInfo: Loaded GRFv{} set {:08X} - {} (palette: {}, version: {})", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
 
}
 

	
 
/* Action 0x0A */
 
static void SpriteReplace(ByteReader *buf)
 
{
 
	/* <0A> <num-sets> <set1> [<set2> ...]
 
@@ -9016,38 +9016,38 @@ static bool IsHouseSpecValid(HouseSpec *
 
	if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
 
				(next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
 
			((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
 
				(next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
 
				next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
 
		hs->enabled = false;
 
		if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
 
		if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
 
		return false;
 
	}
 

	
 
	/* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
 
	 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
 
	 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
 
	if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
 
			((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
 
		hs->enabled = false;
 
		if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
 
		if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
 
		return false;
 
	}
 

	
 
	/* Substitute type is also used for override, and having an override with a different size causes crashes.
 
	 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
 
	if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
 
		hs->enabled = false;
 
		DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
 
		Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
 
		return false;
 
	}
 

	
 
	/* Make sure that additional parts of multitile houses are not available. */
 
	if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
 
		hs->enabled = false;
 
		if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
 
		if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
 
		return false;
 
	}
 

	
 
	return true;
 
}
 

	
 
@@ -9358,17 +9358,17 @@ static void DecodeSpecialSprite(byte *bu
 
 */
 
static void LoadNewGRFFileFromFile(GRFConfig *config, GrfLoadingStage stage, SpriteFile &file)
 
{
 
	_cur.file = &file;
 
	_cur.grfconfig = config;
 

	
 
	DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", config->filename);
 
	Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config->filename);
 

	
 
	byte grf_container_version = file.GetContainerVersion();
 
	if (grf_container_version == 0) {
 
		DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
 
		Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
 
		return;
 
	}
 

	
 
	if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
 
		/* We need the sprite offsets in the init stage for NewGRF sounds
 
		 * and in the activation stage for real sprites. */
 
@@ -9379,25 +9379,25 @@ static void LoadNewGRFFileFromFile(GRFCo
 
	}
 

	
 
	if (grf_container_version >= 2) {
 
		/* Read compression value. */
 
		byte compression = file.ReadByte();
 
		if (compression != 0) {
 
			DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
 
			Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
 
			return;
 
		}
 
	}
 

	
 
	/* Skip the first sprite; we don't care about how many sprites this
 
	 * does contain; newest TTDPatches and George's longvehicles don't
 
	 * neither, apparently. */
 
	uint32 num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
 
	if (num == 4 && file.ReadByte() == 0xFF) {
 
		file.ReadDword();
 
	} else {
 
		DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
 
		Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
 
		return;
 
	}
 

	
 
	_cur.ClearDataForNextFile();
 

	
 
	ReusableBuffer<byte> buf;
 
@@ -9566,13 +9566,13 @@ static void FinalisePriceBaseMultipliers
 
		source->grf_features |= features;
 
		dest->grf_features |= features;
 

	
 
		for (Price p = PR_BEGIN; p < PR_END; p++) {
 
			/* No price defined -> nothing to do */
 
			if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
 
			DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
 
			Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source->filename, p, dest->filename);
 
			dest->price_base_multipliers[p] = source->price_base_multipliers[p];
 
		}
 
	}
 

	
 
	/* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
 
	for (int i = num_grfs - 1; i >= 0; i--) {
 
@@ -9584,13 +9584,13 @@ static void FinalisePriceBaseMultipliers
 
		source->grf_features |= features;
 
		dest->grf_features |= features;
 

	
 
		for (Price p = PR_BEGIN; p < PR_END; p++) {
 
			/* Already a price defined -> nothing to do */
 
			if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
 
			DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
 
			Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source->filename, dest->filename);
 
			dest->price_base_multipliers[p] = source->price_base_multipliers[p];
 
		}
 
	}
 

	
 
	/* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
 
	for (int i = 0; i < num_grfs; i++) {
 
@@ -9602,13 +9602,13 @@ static void FinalisePriceBaseMultipliers
 
		source->grf_features |= features;
 
		dest->grf_features |= features;
 

	
 
		for (Price p = PR_BEGIN; p < PR_END; p++) {
 
			if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
 
			if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
 
				DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
 
				Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest->filename, source->filename);
 
			}
 
			source->price_base_multipliers[p] = dest->price_base_multipliers[p];
 
		}
 
	}
 

	
 
	/* Apply fallback prices for grf version < 8 */
 
@@ -9633,17 +9633,17 @@ static void FinalisePriceBaseMultipliers
 
				/* No multiplier was set; set it to a neutral value */
 
				price_base_multipliers[p] = 0;
 
			} else {
 
				if (!HasBit(file->grf_features, _price_base_specs[p].grf_feature)) {
 
					/* The grf does not define any objects of the feature,
 
					 * so it must be a difficulty setting. Apply it globally */
 
					DEBUG(grf, 3, "'%s' sets global price base multiplier %d", file->filename, p);
 
					Debug(grf, 3, "'{}' sets global price base multiplier {}", file->filename, p);
 
					SetPriceBaseMultiplier(p, price_base_multipliers[p]);
 
					price_base_multipliers[p] = 0;
 
				} else {
 
					DEBUG(grf, 3, "'%s' sets local price base multiplier %d", file->filename, p);
 
					Debug(grf, 3, "'{}' sets local price base multiplier {}", file->filename, p);
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
@@ -9836,31 +9836,31 @@ void LoadNewGRF(uint load_index, uint nu
 
		for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
 
			if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
 
			if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
 

	
 
			Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
 
			if (!FioCheckFileExists(c->filename, subdir)) {
 
				DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
 
				Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
 
				c->status = GCS_NOT_FOUND;
 
				continue;
 
			}
 

	
 
			if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
 

	
 
			if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
 
				if (num_non_static == NETWORK_MAX_GRF_COUNT) {
 
					DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
 
					Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
 
					c->status = GCS_DISABLED;
 
					c->error  = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
 
					continue;
 
				}
 
				num_non_static++;
 
			}
 

	
 
			if (num_grfs >= MAX_GRF_COUNT) {
 
				DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", c->filename);
 
				Debug(grf, 0, "'{}' is not loaded as the maximum number of file slots has been reached", c->filename);
 
				c->status = GCS_DISABLED;
 
				c->error  = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
 
				continue;
 
			}
 
			num_grfs++;
 

	
 
@@ -9869,13 +9869,13 @@ void LoadNewGRF(uint load_index, uint nu
 
				SetBit(c->flags, GCF_RESERVED);
 
			} else if (stage == GLS_ACTIVATION) {
 
				ClrBit(c->flags, GCF_RESERVED);
 
				assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
 
				ClearTemporaryNewGRFData(_cur.grffile);
 
				BuildCargoTranslationMap();
 
				DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
 
				Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur.spriteid);
 
			} else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
 
				/* We're not going to activate this, so free whatever data we allocated */
 
				ClearTemporaryNewGRFData(_cur.grffile);
 
			}
 
		}
 
	}
src/newgrf_airporttiles.cpp
Show inline comments
 
@@ -190,13 +190,13 @@ static uint32 GetAirportTileIDAtOffset(T
 
		}
 

	
 
		/* Get airport tile ID at offset */
 
		case 0x62: return GetAirportTileIDAtOffset(GetNearbyTile(parameter, this->tile), this->st, this->ro.grffile->grfid);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled airport tile variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ uint32 AirportTileScopeResolver::GetRandomBits() const
src/newgrf_canal.cpp
Show inline comments
 
@@ -97,13 +97,13 @@ struct CanalResolverObject : public Reso
 
		}
 

	
 
		/* Random data for river or canal tiles, otherwise zero */
 
		case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
 
	Debug(grf, 1, "Unhandled canal variable 0x{:02X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
GrfSpecFeature CanalResolverObject::GetFeature() const
src/newgrf_commons.cpp
Show inline comments
 
@@ -527,18 +527,18 @@ void ErrorUnknownCallbackResult(uint32 g
 

	
 
	/* debug output */
 
	char buffer[512];
 

	
 
	SetDParamStr(0, grfconfig->GetName());
 
	GetString(buffer, STR_NEWGRF_BUGGY, lastof(buffer));
 
	DEBUG(grf, 0, "%s", buffer + 3);
 
	Debug(grf, 0, "{}", buffer + 3);
 

	
 
	SetDParam(1, cbid);
 
	SetDParam(2, cb_res);
 
	GetString(buffer, STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT, lastof(buffer));
 
	DEBUG(grf, 0, "%s", buffer + 3);
 
	Debug(grf, 0, "{}", buffer + 3);
 
}
 

	
 
/**
 
 * Converts a callback result into a boolean.
 
 * For grf version < 8 the result is checked for zero or non-zero.
 
 * For grf version >= 8 the callback result must be 0 or 1.
src/newgrf_config.cpp
Show inline comments
 
@@ -304,13 +304,13 @@ size_t GRFGetSizeOfDataSection(FILE *f)
 
	byte data[header_len];
 
	if (fread(data, 1, header_len, f) == header_len) {
 
		if (data[0] == 0 && data[1] == 0 && MemCmpT(data + 2, _grf_cont_v2_sig, 8) == 0) {
 
			/* Valid container version 2, get data section size. */
 
			size_t offset = ((size_t)data[13] << 24) | ((size_t)data[12] << 16) | ((size_t)data[11] << 8) | (size_t)data[10];
 
			if (offset >= 1 * 1024 * 1024 * 1024) {
 
				DEBUG(grf, 0, "Unexpectedly large offset for NewGRF");
 
				Debug(grf, 0, "Unexpectedly large offset for NewGRF");
 
				/* Having more than 1 GiB of data is very implausible. Mostly because then
 
				 * all pools in OpenTTD are flooded already. Or it's just Action C all over.
 
				 * In any case, the offsets to graphics will likely not work either. */
 
				return SIZE_MAX;
 
			}
 
			return header_len + offset;
 
@@ -521,13 +521,13 @@ GRFListCompatibility IsGoodGRFConfigList
 

	
 
			/* If we have not found the exactly matching GRF try to find one with the
 
			 * same grfid, as it most likely is compatible */
 
			f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version);
 
			if (f != nullptr) {
 
				md5sumToString(buf, lastof(buf), c->ident.md5sum);
 
				DEBUG(grf, 1, "NewGRF %08X (%s) not found; checksum %s. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, buf);
 
				Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, buf);
 
				if (!HasBit(c->flags, GCF_COMPATIBLE)) {
 
					/* Preserve original_md5sum after it has been assigned */
 
					SetBit(c->flags, GCF_COMPATIBLE);
 
					memcpy(c->original_md5sum, c->ident.md5sum, sizeof(c->original_md5sum));
 
				}
 

	
 
@@ -535,19 +535,19 @@ GRFListCompatibility IsGoodGRFConfigList
 
				if (res != GLC_NOT_FOUND) res = GLC_COMPATIBLE;
 
				goto compatible_grf;
 
			}
 

	
 
			/* No compatible grf was found, mark it as disabled */
 
			md5sumToString(buf, lastof(buf), c->ident.md5sum);
 
			DEBUG(grf, 0, "NewGRF %08X (%s) not found; checksum %s", BSWAP32(c->ident.grfid), c->filename, buf);
 
			Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, buf);
 

	
 
			c->status = GCS_NOT_FOUND;
 
			res = GLC_NOT_FOUND;
 
		} else {
 
compatible_grf:
 
			DEBUG(grf, 1, "Loading GRF %08X from %s", BSWAP32(f->ident.grfid), f->filename);
 
			Debug(grf, 1, "Loading GRF {:08X} from {}", BSWAP32(f->ident.grfid), f->filename);
 
			/* The filename could be the filename as in the savegame. As we need
 
			 * to load the GRF here, we need the correct filename, so overwrite that
 
			 * in any case and set the name and info when it is not set already.
 
			 * When the GCF_COPY flag is set, it is certain that the filename is
 
			 * already a local one, so there is no need to replace it. */
 
			if (!HasBit(c->flags, GCF_COPY)) {
 
@@ -670,16 +670,16 @@ static bool GRFSorter(GRFConfig * const 
 
 */
 
void DoScanNewGRFFiles(NewGRFScanCallback *callback)
 
{
 
	ClearGRFConfigList(&_all_grfs);
 
	TarScanner::DoScan(TarScanner::NEWGRF);
 

	
 
	DEBUG(grf, 1, "Scanning for NewGRFs");
 
	Debug(grf, 1, "Scanning for NewGRFs");
 
	uint num = GRFFileScanner::DoScan();
 

	
 
	DEBUG(grf, 1, "Scan complete, found %d files", num);
 
	Debug(grf, 1, "Scan complete, found {} files", num);
 
	if (num != 0 && _all_grfs != nullptr) {
 
		/* Sort the linked list using quicksort.
 
		 * For that we first have to make an array, then sort and
 
		 * then remake the linked list. */
 
		std::vector<GRFConfig *> to_sort;
 

	
src/newgrf_engine.cpp
Show inline comments
 
@@ -943,13 +943,13 @@ static uint32 VehicleGetVariable(Vehicle
 
			break;
 
		}
 

	
 
		default: break;
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled vehicle variable 0x%X, type 0x%X", variable, (uint)v->type);
 
	Debug(grf, 1, "Unhandled vehicle variable 0x{:X}, type 0x{:X}", variable, (uint)v->type);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
src/newgrf_generic.cpp
Show inline comments
 
@@ -136,13 +136,13 @@ void AddGenericCallback(uint8 feature, c
 
			case 0x88: return this->station_size;
 

	
 
			default: break;
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled generic feature variable 0x%02X", variable);
 
	Debug(grf, 1, "Unhandled generic feature variable 0x{:02X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/**
src/newgrf_house.cpp
Show inline comments
 
@@ -401,13 +401,13 @@ static uint32 GetDistanceFromNearbyHouse
 
			/* Checking the grffile information via HouseSpec doesn't work
 
			 * in case the newgrf was removed. */
 
			return _house_mngr.GetGRFID(house_id);
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled house variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
src/newgrf_industries.cpp
Show inline comments
 
@@ -165,13 +165,13 @@ static uint32 GetCountAndDistanceOfClose
 
			case 0x81: return GB(this->tile, 8, 8);
 

	
 
			/* Pointer to the town the industry is associated with */
 
			case 0x82: return this->industry->town->index;
 
			case 0x83:
 
			case 0x84:
 
			case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 
			case 0x85: Debug(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 

	
 
			/* Number of the layout */
 
			case 0x86: return this->industry->selected_layout;
 

	
 
			/* Ground type */
 
			case 0x87: return GetTerrainType(this->tile);
 
@@ -196,13 +196,13 @@ static uint32 GetCountAndDistanceOfClose
 
		}
 
	}
 

	
 
	const IndustrySpec *indspec = GetIndustrySpec(this->type);
 

	
 
	if (this->industry == nullptr) {
 
		DEBUG(grf, 1, "Unhandled variable 0x%X (no available industry) in callback 0x%x", variable, this->ro.callback);
 
		Debug(grf, 1, "Unhandled variable 0x{:X} (no available industry) in callback 0x{:x}", variable, this->ro.callback);
 

	
 
		*available = false;
 
		return UINT_MAX;
 
	}
 

	
 
	switch (variable) {
 
@@ -349,13 +349,13 @@ static uint32 GetCountAndDistanceOfClose
 
		case 0x80: return this->industry->location.tile;
 
		case 0x81: return GB(this->industry->location.tile, 8, 8);
 
		/* Pointer to the town the industry is associated with */
 
		case 0x82: return this->industry->town->index;
 
		case 0x83:
 
		case 0x84:
 
		case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 
		case 0x85: Debug(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
 
		case 0x86: return this->industry->location.w;
 
		case 0x87: return this->industry->location.h;// xy dimensions
 

	
 
		case 0x88:
 
		case 0x89: return this->industry->produced_cargo[variable - 0x88];
 
		case 0x8A: return this->industry->produced_cargo_waiting[0];
 
@@ -405,13 +405,13 @@ static uint32 GetCountAndDistanceOfClose
 
		case 0xB4: {
 
			Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at));
 
			return Clamp((*latest) - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days)
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled industry variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ uint32 IndustriesScopeResolver::GetRandomBits() const
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -90,13 +90,13 @@ uint32 GetRelativePosition(TileIndex til
 
		}
 

	
 
		/* Get industry tile ID at offset */
 
		case 0x62: return GetIndustryIDAtOffset(GetNearbyTile(parameter, this->tile), this->industry, this->ro.grffile->grfid);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled industry tile variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled industry tile variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ uint32 IndustryTileScopeResolver::GetRandomBits() const
src/newgrf_object.cpp
Show inline comments
 
@@ -332,13 +332,13 @@ static uint32 GetCountAndDistanceOfClose
 

	
 
		/* Count of object, distance of closest instance */
 
		case 0x64: return GetCountAndDistanceOfClosestInstance(parameter, this->ro.grffile->grfid, this->tile, this->obj);
 
	}
 

	
 
unhandled:
 
	DEBUG(grf, 1, "Unhandled object variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled object variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/**
src/newgrf_railtype.cpp
Show inline comments
 
@@ -49,13 +49,13 @@
 
				t = ClosestTownFromTile(this->tile, UINT_MAX);
 
			}
 
			return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled rail type tile variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
GrfSpecFeature RailTypeResolverObject::GetFeature() const
src/newgrf_roadtype.cpp
Show inline comments
 
@@ -49,13 +49,13 @@
 
				t = ClosestTownFromTile(this->tile, UINT_MAX);
 
			}
 
			return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled road type tile variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled road type tile variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
GrfSpecFeature RoadTypeResolverObject::GetFeature() const
src/newgrf_sound.cpp
Show inline comments
 
@@ -83,51 +83,51 @@ bool LoadNewGRFSound(SoundEntry *sound)
 
	uint8 name_len = file.ReadByte();
 
	char *name = AllocaM(char, name_len + 1);
 
	file.ReadBlock(name, name_len + 1);
 

	
 
	/* Test string termination */
 
	if (name[name_len] != 0) {
 
		DEBUG(grf, 2, "LoadNewGRFSound [%s]: Name not properly terminated", file.GetSimplifiedFilename().c_str());
 
		Debug(grf, 2, "LoadNewGRFSound [{}]: Name not properly terminated", file.GetSimplifiedFilename());
 
		return false;
 
	}
 

	
 
	DEBUG(grf, 2, "LoadNewGRFSound [%s]: Sound name '%s'...", file.GetSimplifiedFilename().c_str(), name);
 
	Debug(grf, 2, "LoadNewGRFSound [{}]: Sound name '{}'...", file.GetSimplifiedFilename(), name);
 

	
 
	if (file.ReadDword() != BSWAP32('RIFF')) {
 
		DEBUG(grf, 1, "LoadNewGRFSound [%s]: Missing RIFF header", file.GetSimplifiedFilename().c_str());
 
		Debug(grf, 1, "LoadNewGRFSound [{}]: Missing RIFF header", file.GetSimplifiedFilename());
 
		return false;
 
	}
 

	
 
	uint32 total_size = file.ReadDword();
 
	uint header_size = 11;
 
	if (sound->grf_container_ver >= 2) header_size++; // The first FF in the sprite is only counted for container version >= 2.
 
	if (total_size + name_len + header_size > num) {
 
		DEBUG(grf, 1, "LoadNewGRFSound [%s]: RIFF was truncated", file.GetSimplifiedFilename().c_str());
 
		Debug(grf, 1, "LoadNewGRFSound [{}]: RIFF was truncated", file.GetSimplifiedFilename());
 
		return false;
 
	}
 

	
 
	if (file.ReadDword() != BSWAP32('WAVE')) {
 
		DEBUG(grf, 1, "LoadNewGRFSound [%s]: Invalid RIFF type", file.GetSimplifiedFilename().c_str());
 
		Debug(grf, 1, "LoadNewGRFSound [{}]: Invalid RIFF type", file.GetSimplifiedFilename());
 
		return false;
 
	}
 

	
 
	while (total_size >= 8) {
 
		uint32 tag  = file.ReadDword();
 
		uint32 size = file.ReadDword();
 
		total_size -= 8;
 
		if (total_size < size) {
 
			DEBUG(grf, 1, "LoadNewGRFSound [%s]: Invalid RIFF", file.GetSimplifiedFilename().c_str());
 
			Debug(grf, 1, "LoadNewGRFSound [{}]: Invalid RIFF", file.GetSimplifiedFilename());
 
			return false;
 
		}
 
		total_size -= size;
 

	
 
		switch (tag) {
 
			case ' tmf': // 'fmt '
 
				/* Audio format, must be 1 (PCM) */
 
				if (size < 16 || file.ReadWord() != 1) {
 
					DEBUG(grf, 1, "LoadGRFSound [%s]: Invalid audio format", file.GetSimplifiedFilename().c_str());
 
					Debug(grf, 1, "LoadGRFSound [{}]: Invalid audio format", file.GetSimplifiedFilename());
 
					return false;
 
				}
 
				sound->channels = file.ReadWord();
 
				sound->rate = file.ReadDword();
 
				file.ReadDword();
 
				file.ReadWord();
 
@@ -138,25 +138,25 @@ bool LoadNewGRFSound(SoundEntry *sound)
 
				break;
 

	
 
			case 'atad': // 'data'
 
				sound->file_size   = size;
 
				sound->file_offset = file.GetPos();
 

	
 
				DEBUG(grf, 2, "LoadNewGRFSound [%s]: channels %u, sample rate %u, bits per sample %u, length %u", file.GetSimplifiedFilename().c_str(), sound->channels, sound->rate, sound->bits_per_sample, size);
 
				Debug(grf, 2, "LoadNewGRFSound [{}]: channels {}, sample rate {}, bits per sample {}, length {}", file.GetSimplifiedFilename(), sound->channels, sound->rate, sound->bits_per_sample, size);
 
				return true; // the fmt chunk has to appear before data, so we are finished
 

	
 
			default:
 
				/* Skip unknown chunks */
 
				break;
 
		}
 

	
 
		/* Skip rest of chunk */
 
		if (size > 0) file.SkipBytes(size);
 
	}
 

	
 
	DEBUG(grf, 1, "LoadNewGRFSound [%s]: RIFF does not contain any sound data", file.GetSimplifiedFilename().c_str());
 
	Debug(grf, 1, "LoadNewGRFSound [{}]: RIFF does not contain any sound data", file.GetSimplifiedFilename());
 

	
 
	/* Clear everything that was read */
 
	MemSetT(sound, 0);
 
	return false;
 
}
 

	
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -102,13 +102,13 @@ static inline uint32 GetVariable(const R
 
 * @param parameter Parameter for 60+x variables
 
 * @param[out] available Set to false, in case the variable does not exist.
 
 * @return Value
 
 */
 
/* virtual */ uint32 ScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
 
{
 
	DEBUG(grf, 1, "Unhandled scope variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled scope variable 0x{:X}", variable);
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/**
 
 * Store a value into the persistent storage area (PSA). Default implementation does nothing (for newgrf classes without storage).
src/newgrf_station.cpp
Show inline comments
 
@@ -451,13 +451,13 @@ uint32 Station::GetNewGRFVariable(const 
 
			case 5: return g->cargo.DaysInTransit();
 
			case 6: return g->last_speed;
 
			case 7: return g->last_age;
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled station variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
 
@@ -483,13 +483,13 @@ uint32 Waypoint::GetNewGRFVariable(const
 
			case 3: return INITIAL_STATION_RATING;
 
			case 4: return INVALID_STATION;
 
			default: return 0;
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled station variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ const SpriteGroup *StationResolverObject::ResolveReal(const RealSpriteGroup *group) const
src/newgrf_storage.cpp
Show inline comments
 
@@ -89,11 +89,11 @@ void AddChangedPersistentStorage(BasePer
 

	
 
		default: NOT_REACHED();
 
	}
 

	
 
	/* Discard all temporary changes */
 
	for (std::set<BasePersistentStorageArray*>::iterator it = _changed_storage_arrays->begin(); it != _changed_storage_arrays->end(); it++) {
 
		DEBUG(desync, 1, "Discarding persistent storage changes: Feature %d, GrfID %08X, Tile %d", (*it)->feature, BSWAP32((*it)->grfid), (*it)->tile);
 
		Debug(desync, 1, "Discarding persistent storage changes: Feature {}, GrfID {:08X}, Tile {}", (*it)->feature, BSWAP32((*it)->grfid), (*it)->tile);
 
		(*it)->ClearChanges();
 
	}
 
	_changed_storage_arrays->clear();
 
}
src/newgrf_text.cpp
Show inline comments
 
@@ -881,22 +881,22 @@ uint RemapNewGRFStringControlCode(uint s
 
		case SCC_NEWGRF_PRINT_WORD_WEIGHT_LONG:
 
		case SCC_NEWGRF_PRINT_WORD_WEIGHT_SHORT:
 
		case SCC_NEWGRF_PRINT_WORD_POWER:
 
		case SCC_NEWGRF_PRINT_WORD_STATION_NAME:
 
		case SCC_NEWGRF_PRINT_WORD_CARGO_NAME:
 
			if (argv_size < 1) {
 
				DEBUG(misc, 0, "Too many NewGRF string parameters.");
 
				Debug(misc, 0, "Too many NewGRF string parameters.");
 
				return 0;
 
			}
 
			break;
 

	
 
		case SCC_NEWGRF_PRINT_WORD_CARGO_LONG:
 
		case SCC_NEWGRF_PRINT_WORD_CARGO_SHORT:
 
		case SCC_NEWGRF_PRINT_WORD_CARGO_TINY:
 
			if (argv_size < 2) {
 
				DEBUG(misc, 0, "Too many NewGRF string parameters.");
 
				Debug(misc, 0, "Too many NewGRF string parameters.");
 
				return 0;
 
			}
 
			break;
 
	}
 

	
 
	if (_newgrf_textrefstack.used && modify_argv) {
src/newgrf_town.cpp
Show inline comments
 
@@ -108,13 +108,13 @@
 
		case 0xD2: return this->t->received[TE_WATER].old_act;
 
		case 0xD3: return GB(this->t->received[TE_WATER].old_act, 8, 8);
 
		case 0xD4: return this->t->road_build_months;
 
		case 0xD5: return this->t->fund_buildings_months;
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
 
	Debug(grf, 1, "Unhandled town variable 0x{:X}", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
/* virtual */ void TownScopeResolver::StorePSA(uint pos, int32 value)
src/openttd.cpp
Show inline comments
 
@@ -185,13 +185,13 @@ static void ShowHelp()
 
		"  -g [savegame]       = Start new/save game immediately\n"
 
		"  -G seed             = Set random seed\n"
 
		"  -n [ip:port#company]= Join network game\n"
 
		"  -p password         = Password to join server\n"
 
		"  -P password         = Password to join company\n"
 
		"  -D [ip][:port]      = Start dedicated server\n"
 
		"  -l ip[:port]        = Redirect DEBUG()\n"
 
		"  -l ip[:port]        = Redirect Debug()\n"
 
#if !defined(_WIN32)
 
		"  -f                  = Fork into the background (dedicated only)\n"
 
#endif
 
		"  -I graphics_set     = Force the graphics set (see below)\n"
 
		"  -S sounds_set       = Force the sounds set (see below)\n"
 
		"  -M music_set        = Force the music set (see below)\n"
 
@@ -663,13 +663,13 @@ int openttd_main(int argc, char *argv[])
 
		return ret;
 
	}
 

	
 
	DeterminePaths(argv[0], only_local_path);
 
	TarScanner::DoScan(TarScanner::BASESET);
 

	
 
	if (dedicated) DEBUG(net, 3, "Starting dedicated server, version %s", _openttd_revision);
 
	if (dedicated) Debug(net, 3, "Starting dedicated server, version {}", _openttd_revision);
 
	if (_dedicated_forks && !dedicated) _dedicated_forks = false;
 

	
 
#if defined(UNIX)
 
	/* We must fork here, or we'll end up without some resources we need (like sockets) */
 
	if (_dedicated_forks) DedicatedFork();
 
#endif
 
@@ -712,13 +712,13 @@ int openttd_main(int argc, char *argv[])
 
		}
 
	}
 

	
 
	/* Initialize game palette */
 
	GfxInitPalettes();
 

	
 
	DEBUG(misc, 1, "Loading blitter...");
 
	Debug(misc, 1, "Loading blitter...");
 
	if (blitter.empty() && !_ini_blitter.empty()) blitter = _ini_blitter;
 
	_blitter_autodetected = blitter.empty();
 
	/* Activate the initial blitter.
 
	 * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one.
 
	 *  - Never guess anything, if the user specified a blitter. (_blitter_autodetected)
 
	 *  - Use 32bpp blitter if baseset or 8bpp-support settings says so.
 
@@ -942,13 +942,13 @@ bool SafeLoad(const std::string &filenam
 
				/*
 
				 * We need to reinit a network map...
 
				 * We can't simply load the intro game here as that game has many
 
				 * special cases which make clients desync immediately. So we fall
 
				 * back to just generating a new game with the current settings.
 
				 */
 
				DEBUG(net, 0, "Loading game failed, so a new (random) game will be started");
 
				Debug(net, 0, "Loading game failed, so a new (random) game will be started");
 
				MakeNewGame(false, true);
 
				return false;
 
			}
 
			if (_network_server) {
 
				/* We can't load the intro game as server, so disconnect first. */
 
				NetworkDisconnect();
 
@@ -1133,13 +1133,13 @@ static void CheckCaches()
 
	RebuildTownCaches();
 
	RebuildSubsidisedSourceAndDestinationCache();
 

	
 
	uint i = 0;
 
	for (Town *t : Town::Iterate()) {
 
		if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
 
			DEBUG(desync, 2, "town cache mismatch: town %i", (int)t->index);
 
			Debug(desync, 2, "town cache mismatch: town {}", t->index);
 
		}
 
		i++;
 
	}
 

	
 
	/* Check company infrastructure cache. */
 
	std::vector<CompanyInfrastructure> old_infrastructure;
 
@@ -1148,13 +1148,13 @@ static void CheckCaches()
 
	extern void AfterLoadCompanyStats();
 
	AfterLoadCompanyStats();
 

	
 
	i = 0;
 
	for (const Company *c : Company::Iterate()) {
 
		if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) {
 
			DEBUG(desync, 2, "infrastructure cache mismatch: company %i", (int)c->index);
 
			Debug(desync, 2, "infrastructure cache mismatch: company {}", c->index);
 
		}
 
		i++;
 
	}
 

	
 
	/* Strict checking of the road stop cache entries */
 
	for (const RoadStop *rs : RoadStop::Iterate()) {
 
@@ -1205,29 +1205,29 @@ static void CheckCaches()
 
		}
 

	
 
		length = 0;
 
		for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
 
			FillNewGRFVehicleCache(u);
 
			if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) {
 
				DEBUG(desync, 2, "newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
 
				Debug(desync, 2, "newgrf cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
 
			}
 
			if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) {
 
				DEBUG(desync, 2, "vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
 
				Debug(desync, 2, "vehicle cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
 
			}
 
			switch (u->type) {
 
				case VEH_TRAIN:
 
					if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
 
						DEBUG(desync, 2, "train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
 
						Debug(desync, 2, "train ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
 
					}
 
					if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) {
 
						DEBUG(desync, 2, "train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
 
						Debug(desync, 2, "train cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
 
					}
 
					break;
 
				case VEH_ROAD:
 
					if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
 
						DEBUG(desync, 2, "road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length);
 
						Debug(desync, 2, "road vehicle ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
 
					}
 
					break;
 
				default:
 
					break;
 
			}
 
			length++;
 
@@ -1268,40 +1268,40 @@ static void CheckCaches()
 
		for (TileIndex tile : st->docking_station) {
 
			ta.Add(tile);
 
			docking_tiles[tile] = IsDockingTile(tile);
 
		}
 
		UpdateStationDockingTiles(st);
 
		if (ta.tile != st->docking_station.tile || ta.w != st->docking_station.w || ta.h != st->docking_station.h) {
 
			DEBUG(desync, 2, "station docking mismatch: station %i, company %i", st->index, (int)st->owner);
 
			Debug(desync, 2, "station docking mismatch: station {}, company {}", st->index, st->owner);
 
		}
 
		for (TileIndex tile : ta) {
 
			if (docking_tiles[tile] != IsDockingTile(tile)) {
 
				DEBUG(desync, 2, "docking tile mismatch: tile %i", (int)tile);
 
				Debug(desync, 2, "docking tile mismatch: tile {}", tile);
 
			}
 
		}
 

	
 
		/* Check industries_near */
 
		IndustryList industries_near = st->industries_near;
 
		st->RecomputeCatchment();
 
		if (st->industries_near != industries_near) {
 
			DEBUG(desync, 2, "station industries near mismatch: station %i", st->index);
 
			Debug(desync, 2, "station industries near mismatch: station {}", st->index);
 
		}
 
	}
 

	
 
	/* Check stations_near */
 
	i = 0;
 
	for (Town *t : Town::Iterate()) {
 
		if (t->stations_near != old_town_stations_near[i]) {
 
			DEBUG(desync, 2, "town stations near mismatch: town %i", t->index);
 
			Debug(desync, 2, "town stations near mismatch: town {}", t->index);
 
		}
 
		i++;
 
	}
 
	i = 0;
 
	for (Industry *ind : Industry::Iterate()) {
 
		if (ind->stations_near != old_industry_stations_near[i]) {
 
			DEBUG(desync, 2, "industry stations near mismatch: industry %i", ind->index);
 
			Debug(desync, 2, "industry stations near mismatch: industry {}", ind->index);
 
		}
 
		i++;
 
	}
 
}
 

	
 
/**
 
@@ -1403,13 +1403,13 @@ static void DoAutosave()
 
		/* generate a savegame name and number according to _settings_client.gui.max_num_autosaves */
 
		seprintf(buf, lastof(buf), "autosave%d.sav", _autosave_ctr);
 

	
 
		if (++_autosave_ctr >= _settings_client.gui.max_num_autosaves) _autosave_ctr = 0;
 
	}
 

	
 
	DEBUG(sl, 2, "Autosaving to '%s'", buf);
 
	Debug(sl, 2, "Autosaving to '{}'", buf);
 
	if (SaveOrLoad(buf, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR) != SL_OK) {
 
		ShowErrorMessage(STR_ERROR_AUTOSAVE_FAILED, INVALID_STRING_ID, WL_ERROR);
 
	}
 
}
 

	
 
/**
src/order_cmd.cpp
Show inline comments
 
@@ -617,13 +617,13 @@ void OrderList::DebugCheckSanity() const
 
	VehicleOrderID check_num_orders = 0;
 
	VehicleOrderID check_num_manual_orders = 0;
 
	uint check_num_vehicles = 0;
 
	Ticks check_timetable_duration = 0;
 
	Ticks check_total_duration = 0;
 

	
 
	DEBUG(misc, 6, "Checking OrderList %hu for sanity...", this->index);
 
	Debug(misc, 6, "Checking OrderList {} for sanity...", this->index);
 

	
 
	for (const Order *o = this->first; o != nullptr; o = o->next) {
 
		++check_num_orders;
 
		if (!o->IsType(OT_IMPLICIT)) ++check_num_manual_orders;
 
		check_timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel();
 
		check_total_duration += o->GetWaitTime() + o->GetTravelTime();
 
@@ -635,13 +635,13 @@ void OrderList::DebugCheckSanity() const
 

	
 
	for (const Vehicle *v = this->first_shared; v != nullptr; v = v->NextShared()) {
 
		++check_num_vehicles;
 
		assert(v->orders.list == this);
 
	}
 
	assert(this->num_vehicles == check_num_vehicles);
 
	DEBUG(misc, 6, "... detected %u orders (%u manual), %u vehicles, %i timetabled, %i total",
 
	Debug(misc, 6, "... detected {} orders ({} manual), {} vehicles, {} timetabled, {} total",
 
			(uint)this->num_orders, (uint)this->num_manual_orders,
 
			this->num_vehicles, this->timetable_duration, this->total_duration);
 
}
 

	
 
/**
 
 * Checks whether the order goes to a station or not, i.e. whether the
src/os/macosx/font_osx.cpp
Show inline comments
 
@@ -54,13 +54,13 @@ FT_Error GetFontByFaceName(const char *f
 
		CFAutoRelease<CTFontRef> font(CTFontCreateWithFontDescriptor((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), i), 0.0, nullptr));
 
		CFAutoRelease<CFURLRef> fontURL((CFURLRef)CTFontCopyAttribute(font.get(), kCTFontURLAttribute));
 
		if (CFURLGetFileSystemRepresentation(fontURL.get(), true, file_path, lengthof(file_path))) os_err = noErr;
 
	}
 

	
 
	if (os_err == noErr) {
 
		DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
 
		Debug(freetype, 3, "Font path for {}: {}", font_name, file_path);
 
		err = FT_New_Face(_library, (const char *)file_path, 0, face);
 
	}
 

	
 
	return err;
 
}
 

	
 
@@ -131,13 +131,13 @@ bool SetFallbackFont(FreeTypeSettings *s
 
			 * resort font that aren't usable. Skip them. */
 
			if (name[0] == '.' || strncmp(name, "LastResort", 10) == 0) continue;
 

	
 
			/* Save result. */
 
			callback->SetFontNames(settings, name);
 
			if (!callback->FindMissingGlyphs()) {
 
				DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
 
				Debug(freetype, 2, "CT-Font for {}: {}", language_isocode, name);
 
				result = true;
 
				break;
 
			}
 
		}
 
	}
 

	
 
@@ -218,13 +218,13 @@ void CoreTextFontCache::SetFontSize(int 
 
	/* Get real font name. */
 
	char name[128];
 
	CFAutoRelease<CFStringRef> font_name((CFStringRef)CTFontCopyAttribute(this->font.get(), kCTFontDisplayNameAttribute));
 
	CFStringGetCString(font_name.get(), name, lengthof(name), kCFStringEncodingUTF8);
 
	this->font_name = name;
 

	
 
	DEBUG(freetype, 2, "Loaded font '%s' with size %d", this->font_name.c_str(), pixels);
 
	Debug(freetype, 2, "Loaded font '{}' with size {}", this->font_name, pixels);
 
}
 

	
 
GlyphID CoreTextFontCache::MapCharToGlyph(WChar key)
 
{
 
	assert(IsPrintable(key));
 

	
src/os/os2/os2.cpp
Show inline comments
 
@@ -203,12 +203,12 @@ bool GetClipboardContents(char *buffer, 
 
}
 

	
 

	
 
void OSOpenBrowser(const char *url)
 
{
 
	// stub only
 
	DEBUG(misc, 0, "Failed to open url: %s", url);
 
	Debug(misc, 0, "Failed to open url: {}", url);
 
}
 

	
 
void SetCurrentThreadName(const char *)
 
{
 
}
src/os/unix/font_unix.cpp
Show inline comments
 
@@ -145,13 +145,13 @@ bool SetFallbackFont(FreeTypeSettings *s
 
			FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
 
			if (value <= best_weight) continue;
 

	
 
			callback->SetFontNames(settings, (const char *)file);
 

	
 
			bool missing = callback->FindMissingGlyphs();
 
			DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
 
			Debug(freetype, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no");
 

	
 
			if (!missing) {
 
				best_weight = value;
 
				best_font = (const char *)file;
 
			}
 
		}
src/os/unix/unix.cpp
Show inline comments
 
@@ -161,13 +161,13 @@ static const char *convert_tofrom_fs(ico
 
	char *buf = outbuf;
 

	
 
	strecpy(outbuf, name, outbuf + outlen);
 

	
 
	iconv(convd, nullptr, nullptr, nullptr, nullptr);
 
	if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
 
		DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
 
		Debug(misc, 0, "[iconv] error converting '{}'. Errno {}", name, errno);
 
	}
 

	
 
	*outbuf = '\0';
 
	/* FIX: invalid characters will abort conversion, but they shouldn't occur? */
 
	return buf;
 
}
 
@@ -183,13 +183,13 @@ std::string OTTD2FS(const std::string &n
 
	char buf[1024] = {};
 

	
 
	if (convd == (iconv_t)(-1)) {
 
		const char *env = GetLocalCode();
 
		convd = iconv_open(env, INTERNALCODE);
 
		if (convd == (iconv_t)(-1)) {
 
			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
 
			Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", INTERNALCODE, env);
 
			return name;
 
		}
 
	}
 

	
 
	return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
 
}
 
@@ -205,13 +205,13 @@ std::string FS2OTTD(const std::string &n
 
	char buf[1024] = {};
 

	
 
	if (convd == (iconv_t)(-1)) {
 
		const char *env = GetLocalCode();
 
		convd = iconv_open(INTERNALCODE, env);
 
		if (convd == (iconv_t)(-1)) {
 
			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
 
			Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", env, INTERNALCODE);
 
			return name;
 
		}
 
	}
 

	
 
	return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
 
}
 
@@ -303,13 +303,13 @@ void OSOpenBrowser(const char *url)
 

	
 
	const char *args[3];
 
	args[0] = "xdg-open";
 
	args[1] = url;
 
	args[2] = nullptr;
 
	execvp(args[0], const_cast<char * const *>(args));
 
	DEBUG(misc, 0, "Failed to open url: %s", url);
 
	Debug(misc, 0, "Failed to open url: {}", url);
 
	exit(0);
 
}
 
#endif /* __APPLE__ */
 

	
 
void SetCurrentThreadName(const char *threadName) {
 
#if !defined(NO_THREADS) && defined(__GLIBC__)
src/os/windows/font_win32.cpp
Show inline comments
 
@@ -75,13 +75,13 @@ FT_Error GetFontByFaceName(const char *f
 
	uint index;
 
	size_t path_len;
 

	
 
	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, FONT_DIR_NT, 0, KEY_READ, &hKey);
 

	
 
	if (ret != ERROR_SUCCESS) {
 
		DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
 
		Debug(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
 
		return err;
 
	}
 

	
 
	/* Convert font name to file system encoding. */
 
	wchar_t *font_namep = wcsdup(OTTD2FS(font_name).c_str());
 

	
 
@@ -110,13 +110,13 @@ FT_Error GetFontByFaceName(const char *f
 
		} else {
 
			if (wcsstr(vbuffer, font_namep) != nullptr) break;
 
		}
 
	}
 

	
 
	if (!SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_FONTS, nullptr, SHGFP_TYPE_CURRENT, vbuffer))) {
 
		DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
 
		Debug(freetype, 0, "SHGetFolderPath cannot return fonts directory");
 
		goto folder_error;
 
	}
 

	
 
	/* Some fonts are contained in .ttc files, TrueType Collection fonts. These
 
	 * contain multiple fonts inside this single file. GetFontData however
 
	 * returns the whole file, so we need to check each font inside to get the
 
@@ -331,23 +331,23 @@ static int CALLBACK EnumFontCallback(con
 
#else
 
	const char *english_name = font_name;
 
#endif /* WITH_FREETYPE */
 

	
 
	info->callback->SetFontNames(info->settings, font_name, &logfont->elfLogFont);
 
	if (info->callback->FindMissingGlyphs()) return 1;
 
	DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
 
	Debug(freetype, 1, "Fallback font: {} ({})", font_name, english_name);
 
	return 0; // stop enumerating
 
}
 

	
 
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
 
{
 
	DEBUG(freetype, 1, "Trying fallback fonts");
 
	Debug(freetype, 1, "Trying fallback fonts");
 
	EFCParam langInfo;
 
	if (GetLocaleInfo(MAKELCID(winlangid, SORT_DEFAULT), LOCALE_FONTSIGNATURE, (LPTSTR)&langInfo.locale, sizeof(langInfo.locale) / sizeof(wchar_t)) == 0) {
 
		/* Invalid langid or some other mysterious error, can't determine fallback font. */
 
		DEBUG(freetype, 1, "Can't get locale info for fallback font (langid=0x%x)", winlangid);
 
		Debug(freetype, 1, "Can't get locale info for fallback font (langid=0x{:x})", winlangid);
 
		return false;
 
	}
 
	langInfo.settings = settings;
 
	langInfo.callback = callback;
 

	
 
	LOGFONT font;
 
@@ -436,13 +436,13 @@ void Win32FontCache::SetFontSize(FontSiz
 
	this->ascender = otm->otmTextMetrics.tmAscent;
 
	this->descender = otm->otmTextMetrics.tmDescent;
 
	this->height = this->ascender + this->descender;
 
	this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
 
	this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
 

	
 
	DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)).c_str(), pixels);
 
	Debug(freetype, 2, "Loaded font '{}' with size {}", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
 
}
 

	
 
/**
 
 * Reset cached glyphs.
 
 */
 
void Win32FontCache::ClearFontCache()
src/os/windows/win32.cpp
Show inline comments
 
@@ -468,31 +468,31 @@ void DetermineBasePaths(const char *exe)
 
		_searchpaths[SP_WORKING_DIR] = cwd_s;
 
	} else {
 
		/* Use the folder of the config file as working directory. */
 
		wchar_t config_dir[MAX_PATH];
 
		wcsncpy(path, convert_to_fs(_config_file.c_str(), path, lengthof(path)), lengthof(path));
 
		if (!GetFullPathName(path, lengthof(config_dir), config_dir, nullptr)) {
 
			DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
 
			Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
 
			_searchpaths[SP_WORKING_DIR].clear();
 
		} else {
 
			std::string tmp(FS2OTTD(config_dir));
 
			auto pos = tmp.find_last_of(PATHSEPCHAR);
 
			if (pos != std::string::npos) tmp.erase(pos + 1);
 

	
 
			_searchpaths[SP_WORKING_DIR] = tmp;
 
		}
 
	}
 

	
 
	if (!GetModuleFileName(nullptr, path, lengthof(path))) {
 
		DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
 
		Debug(misc, 0, "GetModuleFileName failed ({})", GetLastError());
 
		_searchpaths[SP_BINARY_DIR].clear();
 
	} else {
 
		wchar_t exec_dir[MAX_PATH];
 
		wcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path));
 
		if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, nullptr)) {
 
			DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
 
			Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
 
			_searchpaths[SP_BINARY_DIR].clear();
 
		} else {
 
			std::string tmp(FS2OTTD(exec_dir));
 
			auto pos = tmp.find_last_of(PATHSEPCHAR);
 
			if (pos != std::string::npos) tmp.erase(pos + 1);
 

	
src/pathfinder/npf/npf.cpp
Show inline comments
 
@@ -175,13 +175,13 @@ static int32 NPFCalcStationOrTileHeurist
 
		dist = DistanceManhattan(from, to) * NPF_TILE_LENGTH;
 
	} else {
 
		/* Ships and trains can also go diagonal, so the minimum distance is shorter */
 
		dist = NPFDistanceTrack(from, to);
 
	}
 

	
 
	DEBUG(npf, 4, "Calculating H for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), dist);
 
	Debug(npf, 4, "Calculating H for: ({}, {}). Result: {}", TileX(current->tile), TileY(current->tile), dist);
 

	
 
	if (dist < ftd->best_bird_dist) {
 
		ftd->best_bird_dist = dist;
 
		ftd->best_trackdir = (Trackdir)current->user_data[NPF_TRACKDIR_CHOICE];
 
	}
 
	return dist;
 
@@ -195,13 +195,13 @@ static void NPFFillTrackdirChoice(AyStar
 
{
 
	if (parent->path.parent == nullptr) {
 
		Trackdir trackdir = current->direction;
 
		/* This is a first order decision, so we'd better save the
 
		 * direction we chose */
 
		current->user_data[NPF_TRACKDIR_CHOICE] = trackdir;
 
		DEBUG(npf, 6, "Saving trackdir: 0x%X", trackdir);
 
		Debug(npf, 6, "Saving trackdir: 0x{:X}", trackdir);
 
	} else {
 
		/* We've already made the decision, so just save our parent's decision */
 
		current->user_data[NPF_TRACKDIR_CHOICE] = parent->path.node.user_data[NPF_TRACKDIR_CHOICE];
 
	}
 
}
 

	
 
@@ -391,13 +391,13 @@ static int32 NPFRoadPathCost(AyStar *as,
 
	 * represented by non-diagonal tracks */
 
	if (!IsDiagonalTrackdir(current->direction)) {
 
		cost += _settings_game.pf.npf.npf_road_curve_penalty;
 
	}
 

	
 
	NPFMarkTile(tile);
 
	DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
 
	Debug(npf, 4, "Calculating G for: ({}, {}). Result: {}", TileX(current->tile), TileY(current->tile), cost);
 
	return cost;
 
}
 

	
 

	
 
/* Determine the cost of this node, for railway tracks */
 
static int32 NPFRailPathCost(AyStar *as, AyStarNode *current, OpenListNode *parent)
 
@@ -543,13 +543,13 @@ static int32 NPFRailPathCost(AyStar *as,
 
	}
 

	
 
	/* Check for occupied track */
 
	cost += NPFReservedTrackCost(current);
 

	
 
	NPFMarkTile(tile);
 
	DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
 
	Debug(npf, 4, "Calculating G for: ({}, {}). Result: {}", TileX(current->tile), TileY(current->tile), cost);
 
	return cost;
 
}
 

	
 
/* Will find any depot */
 
static int32 NPFFindDepot(const AyStar *as, const OpenListNode *current)
 
{
 
@@ -862,23 +862,23 @@ static TrackdirBits GetDriveableTrackdir
 
				break;
 

	
 
			default: break;
 
		}
 
	}
 

	
 
	DEBUG(npf, 4, "Next node: (%d, %d) [%d], possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits);
 
	Debug(npf, 4, "Next node: ({}, {}) [{}], possible trackdirs: 0x{:X}", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits);
 

	
 
	/* Select only trackdirs we can reach from our current trackdir */
 
	trackdirbits &= TrackdirReachesTrackdirs(src_trackdir);
 

	
 
	/* Filter out trackdirs that would make 90 deg turns for trains */
 
	if (type == TRANSPORT_RAIL && Rail90DegTurnDisallowed(GetTileRailType(src_tile), GetTileRailType(dst_tile))) {
 
		trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
 
	}
 

	
 
	DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits);
 
	Debug(npf, 6, "After filtering: ({}, {}), possible trackdirs: 0x{:X}", TileX(dst_tile), TileY(dst_tile), trackdirbits);
 

	
 
	return trackdirbits;
 
}
 

	
 

	
 
/* Will just follow the results of GetTileTrackStatus concerning where we can
 
@@ -898,13 +898,13 @@ static void NPFFollowTrack(AyStar *aysta
 
	/* Information about the vehicle: TransportType (road/rail/water) and SubType (compatible rail/road types) */
 
	TransportType type = user->type;
 
	uint subtype = user->subtype;
 

	
 
	/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
 
	aystar->num_neighbours = 0;
 
	DEBUG(npf, 4, "Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
 
	Debug(npf, 4, "Expanding: ({}, {}, {}) [{}]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
 

	
 
	/* We want to determine the tile we arrive, and which choices we have there */
 
	TileIndex dst_tile;
 
	TrackdirBits trackdirbits;
 

	
 
	/* Find dest tile */
 
@@ -963,13 +963,13 @@ static void NPFFollowTrack(AyStar *aysta
 
	}
 

	
 
	/* Enumerate possible track */
 
	uint i = 0;
 
	while (trackdirbits != TRACKDIR_BIT_NONE) {
 
		Trackdir dst_trackdir = RemoveFirstTrackdir(&trackdirbits);
 
		DEBUG(npf, 5, "Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits);
 
		Debug(npf, 5, "Expanded into trackdir: {}, remaining trackdirs: 0x{:X}", dst_trackdir, trackdirbits);
 

	
 
		/* Tile with signals? */
 
		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TILE_SIGNALS) {
 
			if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(dst_trackdir)) && !HasSignalOnTrackdir(dst_tile, dst_trackdir) && IsOnewaySignal(dst_tile, TrackdirToTrack(dst_trackdir))) {
 
				/* If there's a one-way signal not pointing towards us, stop going in this direction. */
 
				break;
 
@@ -1047,16 +1047,16 @@ static NPFFoundTargetData NPFRouteIntern
 
	/* GO! */
 
	[[maybe_unused]] int r = _npf_aystar.Main();
 
	assert(r != AYSTAR_STILL_BUSY);
 

	
 
	if (result.best_bird_dist != 0) {
 
		if (target != nullptr) {
 
			DEBUG(npf, 1, "Could not find route to tile 0x%X from 0x%X.", target->dest_coords, start1->tile);
 
			Debug(npf, 1, "Could not find route to tile 0x{:X} from 0x{:X}.", target->dest_coords, start1->tile);
 
		} else {
 
			/* Assumption: target == nullptr, so we are looking for a depot */
 
			DEBUG(npf, 1, "Could not find route to a depot from tile 0x%X.", start1->tile);
 
			Debug(npf, 1, "Could not find route to a depot from tile 0x{:X}.", start1->tile);
 
		}
 

	
 
	}
 
	return result;
 
}
 

	
src/pathfinder/yapf/yapf_base.hpp
Show inline comments
 
@@ -143,13 +143,13 @@ public:
 
			UnitID veh_idx = (m_veh != nullptr) ? m_veh->unitnumber : 0;
 
			char ttc = Yapf().TransportTypeChar();
 
			float cache_hit_ratio = (m_stats_cache_hits == 0) ? 0.0f : ((float)m_stats_cache_hits / (float)(m_stats_cache_hits + m_stats_cost_calcs) * 100.0f);
 
			int cost = bDestFound ? m_pBestDestNode->m_cost : -1;
 
			int dist = bDestFound ? m_pBestDestNode->m_estimate - m_pBestDestNode->m_cost : -1;
 

	
 
			DEBUG(yapf, 3, "[YAPF%c]%c%4d- %d rounds - %d open - %d closed - CHR %4.1f%% - C %d D %d",
 
			Debug(yapf, 3, "[YAPF{}]{}{:4d} - {} rounds - {} open - {} closed - CHR {:4.1f}% - C {} D {}",
 
				ttc, bDestFound ? '-' : '!', veh_idx, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(), cache_hit_ratio, cost, dist
 
			);
 
		}
 

	
 
		return bDestFound;
 
	}
src/pathfinder/yapf/yapf_rail.cpp
Show inline comments
 
@@ -238,13 +238,13 @@ public:
 

	
 
		if (_debug_desync_level >= 2) {
 
			Tpf pf2;
 
			pf2.DisableCache(true);
 
			FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
 
			if (result1.tile != result2.tile || (result1.reverse != result2.reverse)) {
 
				DEBUG(desync, 2, "CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]",
 
				Debug(desync, 2, "CACHE ERROR: FindNearestDepotTwoWay() = [{}, {}]",
 
						result1.tile != INVALID_TILE ? "T" : "F",
 
						result2.tile != INVALID_TILE ? "T" : "F");
 
				DumpState(pf1, pf2);
 
			}
 
		}
 

	
 
@@ -322,13 +322,13 @@ public:
 
		} else {
 
			bool result2 = pf1.FindNearestSafeTile(v, t1, td, override_railtype, true);
 
			Tpf pf2;
 
			pf2.DisableCache(true);
 
			result1 = pf2.FindNearestSafeTile(v, t1, td, override_railtype, false);
 
			if (result1 != result2) {
 
				DEBUG(desync, 2, "CACHE ERROR: FindSafeTile() = [%s, %s]", result2 ? "T" : "F", result1 ? "T" : "F");
 
				Debug(desync, 2, "CACHE ERROR: FindSafeTile() = [{}, {}]", result2 ? "T" : "F", result1 ? "T" : "F");
 
				DumpState(pf1, pf2);
 
			}
 
		}
 

	
 
		return result1;
 
	}
 
@@ -406,13 +406,13 @@ public:
 
		} else {
 
			result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr);
 
			Tpf pf2;
 
			pf2.DisableCache(true);
 
			Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target);
 
			if (result1 != result2) {
 
				DEBUG(desync, 2, "CACHE ERROR: ChooseRailTrack() = [%d, %d]", result1, result2);
 
				Debug(desync, 2, "CACHE ERROR: ChooseRailTrack() = [{}, {}]", result1, result2);
 
				DumpState(pf1, pf2);
 
			}
 
		}
 

	
 
		return result1;
 
	}
 
@@ -464,13 +464,13 @@ public:
 

	
 
		if (_debug_desync_level >= 2) {
 
			Tpf pf2;
 
			pf2.DisableCache(true);
 
			bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
 
			if (result1 != result2) {
 
				DEBUG(desync, 2, "CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ? "T" : "F", result2 ? "T" : "F");
 
				Debug(desync, 2, "CACHE ERROR: CheckReverseTrain() = [{}, {}]", result1 ? "T" : "F", result2 ? "T" : "F");
 
				DumpState(pf1, pf2);
 
			}
 
		}
 

	
 
		return result1;
 
	}
src/random_access_file.cpp
Show inline comments
 
@@ -83,13 +83,13 @@ size_t RandomAccessFile::GetPos() const
 
void RandomAccessFile::SeekTo(size_t pos, int mode)
 
{
 
	if (mode == SEEK_CUR) pos += this->GetPos();
 

	
 
	this->pos = pos;
 
	if (fseek(this->file_handle, this->pos, SEEK_SET) < 0) {
 
		DEBUG(misc, 0, "Seeking in %s failed", this->filename.c_str());
 
		Debug(misc, 0, "Seeking in {} failed", this->filename);
 
	}
 

	
 
	/* Reset the buffer, so the next ReadByte will read bytes from the file. */
 
	this->buffer = this->buffer_end = this->buffer_start;
 
}
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -565,14 +565,14 @@ bool AfterLoadGame()
 

	
 
	if (IsSavegameVersionBefore(SLV_98)) GamelogGRFAddList(_grfconfig);
 

	
 
	if (IsSavegameVersionBefore(SLV_119)) {
 
		_pause_mode = (_pause_mode == 2) ? PM_PAUSED_NORMAL : PM_UNPAUSED;
 
	} else if (_network_dedicated && (_pause_mode & PM_PAUSED_ERROR) != 0) {
 
		DEBUG(net, 0, "The loading savegame was paused due to an error state");
 
		DEBUG(net, 0, "  This savegame cannot be used for multiplayer");
 
		Debug(net, 0, "The loading savegame was paused due to an error state");
 
		Debug(net, 0, "  This savegame cannot be used for multiplayer");
 
		/* Restore the signals */
 
		ResetSignalHandlers();
 
		return false;
 
	} else if (!_networking || _network_server) {
 
		/* If we are in singleplayer mode, i.e. not networking, and loading the
 
		 * savegame or we are loading the savegame as network server we do
 
@@ -2305,13 +2305,13 @@ bool AfterLoadGame()
 

	
 
	if (IsSavegameVersionBefore(SLV_128)) {
 
		for (const Depot *d : Depot::Iterate()) {
 
			/* At some point, invalid depots were saved into the game (possibly those removed in the past?)
 
			 * Remove them here, so they don't cause issues further down the line */
 
			if (!IsDepotTile(d->xy)) {
 
				DEBUG(sl, 0, "Removing invalid depot %d at %d, %d", d->index, TileX(d->xy), TileY(d->xy));
 
				Debug(sl, 0, "Removing invalid depot {} at {}, {}", d->index, TileX(d->xy), TileY(d->xy));
 
				delete d;
 
				d = nullptr;
 
				continue;
 
			}
 
			_m[d->xy].m2 = d->index;
 
			if (IsTileType(d->xy, MP_WATER)) _m[GetOtherShipDepotTile(d->xy)].m2 = d->index;
src/saveload/ai_sl.cpp
Show inline comments
 
@@ -83,21 +83,21 @@ static void Load_AIPL()
 
			if (!config->HasScript()) {
 
				/* No version of the AI available that can load the data. Try to load the
 
				 * latest version of the AI instead. */
 
				config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random);
 
				if (!config->HasScript()) {
 
					if (_ai_saveload_name.compare("%_dummy") != 0) {
 
						DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version);
 
						DEBUG(script, 0, "A random other AI will be loaded in its place.");
 
						Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version);
 
						Debug(script, 0, "A random other AI will be loaded in its place.");
 
					} else {
 
						DEBUG(script, 0, "The savegame had no AIs available at the time of saving.");
 
						DEBUG(script, 0, "A random available AI will be loaded now.");
 
						Debug(script, 0, "The savegame had no AIs available at the time of saving.");
 
						Debug(script, 0, "A random available AI will be loaded now.");
 
					}
 
				} else {
 
					DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version);
 
					DEBUG(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible.");
 
					Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version);
 
					Debug(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible.");
 
				}
 
				/* Make sure the AI doesn't get the saveload data, as it was not the
 
				 *  writer of the saveload data in the first place */
 
				_ai_saveload_version = -1;
 
			}
 
		}
src/saveload/game_sl.cpp
Show inline comments
 
@@ -74,21 +74,21 @@ static void Load_GSDT()
 
		if (!config->HasScript()) {
 
			/* No version of the GameScript available that can load the data. Try to load the
 
			 * latest version of the GameScript instead. */
 
			config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random);
 
			if (!config->HasScript()) {
 
				if (_game_saveload_name.compare("%_dummy") != 0) {
 
					DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version);
 
					DEBUG(script, 0, "This game will continue to run without GameScript.");
 
					Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version);
 
					Debug(script, 0, "This game will continue to run without GameScript.");
 
				} else {
 
					DEBUG(script, 0, "The savegame had no GameScript available at the time of saving.");
 
					DEBUG(script, 0, "This game will continue to run without GameScript.");
 
					Debug(script, 0, "The savegame had no GameScript available at the time of saving.");
 
					Debug(script, 0, "This game will continue to run without GameScript.");
 
				}
 
			} else {
 
				DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %d which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version);
 
				DEBUG(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible.");
 
				Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version);
 
				Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible.");
 
			}
 
			/* Make sure the GameScript doesn't get the saveload data, as it was not the
 
			 *  writer of the saveload data in the first place */
 
			_game_saveload_version = -1;
 
		}
 
	}
src/saveload/oldloader.cpp
Show inline comments
 
@@ -53,13 +53,13 @@ static byte ReadByteFromFile(LoadgameSta
 

	
 
		/* Read some new bytes from the file */
 
		int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
 

	
 
		/* We tried to read, but there is nothing in the file anymore.. */
 
		if (count == 0) {
 
			DEBUG(oldloader, 0, "Read past end of file, loading failed");
 
			Debug(oldloader, 0, "Read past end of file, loading failed");
 
			throw std::exception();
 
		}
 

	
 
		ls->buffer_count = count;
 
		ls->buffer_cur   = 0;
 
	}
 
@@ -129,13 +129,13 @@ bool LoadChunk(LoadgameState *ls, void *
 
						/* Call function, with 'i' as parameter to tell which item we
 
						 * are going to read */
 
						if (!chunk->proc(ls, i)) return false;
 
						break;
 

	
 
					case OC_ASSERT:
 
						DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, (uint)(size_t)chunk->ptr + _bump_assert_value);
 
						Debug(oldloader, 4, "Assert point: 0x{:X} / 0x{:X}", ls->total_read, (uint)(size_t)chunk->ptr + _bump_assert_value);
 
						if (ls->total_read != (size_t)chunk->ptr + _bump_assert_value) throw std::exception();
 
					default: break;
 
				}
 
			} else {
 
				uint64 res = 0;
 

	
 
@@ -270,21 +270,21 @@ static SavegameType DetermineOldSavegame
 
typedef bool LoadOldMainProc(LoadgameState *ls);
 

	
 
bool LoadOldSaveGame(const std::string &file)
 
{
 
	LoadgameState ls;
 

	
 
	DEBUG(oldloader, 3, "Trying to load a TTD(Patch) savegame");
 
	Debug(oldloader, 3, "Trying to load a TTD(Patch) savegame");
 

	
 
	InitLoading(&ls);
 

	
 
	/* Open file */
 
	ls.file = FioFOpenFile(file, "rb", NO_DIRECTORY);
 

	
 
	if (ls.file == nullptr) {
 
		DEBUG(oldloader, 0, "Cannot open file '%s'", file.c_str());
 
		Debug(oldloader, 0, "Cannot open file '{}'", file);
 
		return false;
 
	}
 

	
 
	SavegameType type = DetermineOldSavegameType(ls.file, nullptr, nullptr);
 

	
 
	LoadOldMainProc *proc = nullptr;
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -129,13 +129,13 @@ static uint32 RemapOldTownName(uint32 to
 
		case 1: // French
 
			/* For some reason 86 needs to be subtracted from townnameparts
 
			 * 0000 0000 0000 0000 0000 0000 1111 1111 */
 
			return FIXNUM(townnameparts - 86, lengthof(_name_french_real), 0);
 

	
 
		case 2: // German
 
			DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
 
			Debug(misc, 0, "German Townnames are buggy ({})", townnameparts);
 
			return townnameparts;
 

	
 
		case 4: // Latin-American
 
			/* 0000 0000 0000 0000 0000 0000 1111 1111 */
 
			return FIXNUM(townnameparts, lengthof(_name_spanish_real), 0);
 

	
 
@@ -529,15 +529,15 @@ static void ReadTTDPatchFlags()
 
	_old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
 

	
 
	/* Clean the misused places */
 
	for (uint i = 0;       i < 17;      i++) _old_map3[i] = 0;
 
	for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
 

	
 
	if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
 
	if (_savegame_type == SGT_TTDP2) Debug(oldloader, 2, "Found TTDPatch game");
 

	
 
	DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
 
	Debug(oldloader, 3, "Vehicle-multiplier is set to {} ({} vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
 
}
 

	
 
static const OldChunks town_chunk[] = {
 
	OCL_SVAR(   OC_TILE, Town, xy ),
 
	OCL_NULL( 2 ),         ///< population,        no longer in use
 
	OCL_SVAR( OC_UINT16, Town, townnametype ),
 
@@ -1111,13 +1111,13 @@ static bool LoadOldVehicleUnion(Loadgame
 
			case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
 
		}
 
	}
 

	
 
	/* This chunk size should always be 10 bytes */
 
	if (ls->total_read - temp != 10) {
 
		DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
 
		Debug(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
 
		return false;
 
	}
 

	
 
	return res;
 
}
 

	
 
@@ -1324,13 +1324,13 @@ bool LoadOldVehicle(LoadgameState *ls, i
 
			if (v == nullptr) continue;
 

	
 
			_old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
 

	
 
			/* This should be consistent, else we have a big problem... */
 
			if (v->index != _current_vehicle_id) {
 
				DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
 
				Debug(oldloader, 0, "Loading failed - vehicle-array is invalid");
 
				return false;
 
			}
 
		}
 

	
 
		if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
 
			uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
 
@@ -1509,13 +1509,13 @@ static bool LoadOldMapPart2(LoadgameStat
 
}
 

	
 
static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
 
{
 
	ReadTTDPatchFlags();
 

	
 
	DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
 
	Debug(oldloader, 2, "Found {} extra chunk(s)", _old_extra_chunk_nums);
 

	
 
	for (int i = 0; i != _old_extra_chunk_nums; i++) {
 
		uint16 id = ReadUint16(ls);
 
		uint32 len = ReadUint32(ls);
 

	
 
		switch (id) {
 
@@ -1532,33 +1532,33 @@ static bool LoadTTDPatchExtraChunks(Load
 

	
 
					if (ReadByte(ls) == 1) {
 
						GRFConfig *c = new GRFConfig("TTDP game, no information");
 
						c->ident.grfid = grfid;
 

	
 
						AppendToGRFConfigList(&_grfconfig, c);
 
						DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
 
						Debug(oldloader, 3, "TTDPatch game using GRF file with GRFID {:08X}", BSWAP32(c->ident.grfid));
 
					}
 
					len -= 5;
 
				}
 

	
 
				/* Append static NewGRF configuration */
 
				AppendStaticGRFConfigs(&_grfconfig);
 
				break;
 
			}
 

	
 
			/* TTDPatch version and configuration */
 
			case 0x3:
 
				_ttdp_version = ReadUint32(ls);
 
				DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
 
				Debug(oldloader, 3, "Game saved with TTDPatch version {}.{}.{} r{}",
 
					GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
 
				len -= 4;
 
				while (len-- != 0) ReadByte(ls); // skip the configuration
 
				break;
 

	
 
			default:
 
				DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
 
				Debug(oldloader, 4, "Skipping unknown extra chunk {}", id);
 
				while (len-- != 0) ReadByte(ls);
 
				break;
 
		}
 
	}
 

	
 
	return true;
 
@@ -1739,32 +1739,32 @@ static const OldChunks main_chunk[] = {
 

	
 
	OCL_END()
 
};
 

	
 
bool LoadTTDMain(LoadgameState *ls)
 
{
 
	DEBUG(oldloader, 3, "Reading main chunk...");
 
	Debug(oldloader, 3, "Reading main chunk...");
 

	
 
	_read_ttdpatch_flags = false;
 

	
 
	/* Load the biggest chunk */
 
	std::array<byte, OLD_MAP_SIZE * 2> map3;
 
	_old_map3 = map3.data();
 
	_old_vehicle_names = nullptr;
 
	try {
 
		if (!LoadChunk(ls, nullptr, main_chunk)) {
 
			DEBUG(oldloader, 0, "Loading failed");
 
			Debug(oldloader, 0, "Loading failed");
 
			free(_old_vehicle_names);
 
			return false;
 
		}
 
	} catch (...) {
 
		free(_old_vehicle_names);
 
		throw;
 
	}
 

	
 
	DEBUG(oldloader, 3, "Done, converting game data...");
 
	Debug(oldloader, 3, "Done, converting game data...");
 

	
 
	FixTTDMapArray();
 
	FixTTDDepots();
 

	
 
	/* Fix some general stuff */
 
	_settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
 
@@ -1773,45 +1773,45 @@ bool LoadTTDMain(LoadgameState *ls)
 
	FixOldTowns();
 
	FixOldVehicles();
 

	
 
	/* We have a new difficulty setting */
 
	_settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
 

	
 
	DEBUG(oldloader, 3, "Finished converting game data");
 
	DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
 
	Debug(oldloader, 3, "Finished converting game data");
 
	Debug(oldloader, 1, "TTD(Patch) savegame successfully converted");
 

	
 
	free(_old_vehicle_names);
 

	
 
	return true;
 
}
 

	
 
bool LoadTTOMain(LoadgameState *ls)
 
{
 
	DEBUG(oldloader, 3, "Reading main chunk...");
 
	Debug(oldloader, 3, "Reading main chunk...");
 

	
 
	_read_ttdpatch_flags = false;
 

	
 
	std::array<byte, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
 
	_old_engines = (Engine *)engines.data();
 
	std::array<StringID, 800> vehnames;
 
	_old_vehicle_names = vehnames.data();
 

	
 
	/* Load the biggest chunk */
 
	if (!LoadChunk(ls, nullptr, main_chunk)) {
 
		DEBUG(oldloader, 0, "Loading failed");
 
		Debug(oldloader, 0, "Loading failed");
 
		return false;
 
	}
 
	DEBUG(oldloader, 3, "Done, converting game data...");
 
	Debug(oldloader, 3, "Done, converting game data...");
 

	
 
	if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
 

	
 
	_settings_game.game_creation.landscape = 0;
 
	_trees_tick_ctr = 0xFF;
 

	
 
	if (!FixTTOMapArray() || !FixTTOEngines()) {
 
		DEBUG(oldloader, 0, "Conversion failed");
 
		Debug(oldloader, 0, "Conversion failed");
 
		return false;
 
	}
 

	
 
	FixOldTowns();
 
	FixOldVehicles();
 
	FixTTOCompanies();
 
@@ -1822,11 +1822,11 @@ bool LoadTTOMain(LoadgameState *ls)
 
	/* SVXConverter about cargo payment rates correction:
 
	 * "increase them to compensate for the faster time advance in TTD compared to TTO
 
	 * which otherwise would cause much less income while the annual running costs of
 
	 * the vehicles stay the same" */
 
	_economy.inflation_payment = std::min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
 

	
 
	DEBUG(oldloader, 3, "Finished converting game data");
 
	DEBUG(oldloader, 1, "TTO savegame successfully converted");
 
	Debug(oldloader, 3, "Finished converting game data");
 
	Debug(oldloader, 1, "TTO savegame successfully converted");
 

	
 
	return true;
 
}
src/saveload/saveload.cpp
Show inline comments
 
@@ -310,13 +310,13 @@ static void SlNullPointers()
 
	 * during NULLing; especially those that try to get
 
	 * pointers from other pools. */
 
	_sl_version = SAVEGAME_VERSION;
 

	
 
	for (auto &ch : ChunkHandlers()) {
 
		if (ch.ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			ch.ptrs_proc();
 
		}
 
	}
 

	
 
	assert(_sl.action == SLA_NULL);
 
}
 
@@ -653,13 +653,13 @@ int SlIterateArray()
 
		_next_offs = _sl.reader->GetSize() + length;
 

	
 
		switch (_sl.block_mode) {
 
			case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
 
			case CH_ARRAY:        index = _sl.array_index++; break;
 
			default:
 
				DEBUG(sl, 0, "SlIterateArray error");
 
				Debug(sl, 0, "SlIterateArray error");
 
				return -1; // error
 
		}
 

	
 
		if (length != 0) return index;
 
	}
 
}
 
@@ -946,13 +946,13 @@ static void SlString(void *ptr, size_t l
 
				default: NOT_REACHED();
 
				case SLE_VAR_NULL:
 
					SlSkipBytes(len);
 
					return;
 
				case SLE_VAR_STRB:
 
					if (len >= length) {
 
						DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
 
						Debug(sl, 1, "String length in savegame is bigger than buffer, truncating");
 
						SlCopyBytes(ptr, length);
 
						SlSkipBytes(len - length);
 
						len = length - 1;
 
					} else {
 
						SlCopyBytes(ptr, len);
 
					}
 
@@ -1715,13 +1715,13 @@ static void SlSaveChunk(const ChunkHandl
 
	ChunkSaveLoadProc *proc = ch.save_proc;
 

	
 
	/* Don't save any chunk information if there is no save handler. */
 
	if (proc == nullptr) return;
 

	
 
	SlWriteUint32(ch.id);
 
	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
	Debug(sl, 2, "Saving chunk {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 

	
 
	_sl.block_mode = ch.type;
 
	switch (ch.type) {
 
		case CH_RIFF:
 
			_sl.need_length = NL_WANTLENGTH;
 
			proc();
 
@@ -1768,13 +1768,13 @@ static const ChunkHandler *SlFindChunkHa
 
static void SlLoadChunks()
 
{
 
	uint32 id;
 
	const ChunkHandler *ch;
 

	
 
	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
 
		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
 
		Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
 

	
 
		ch = SlFindChunkHandler(id);
 
		if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
 
		SlLoadChunk(*ch);
 
	}
 
}
 
@@ -1783,13 +1783,13 @@ static void SlLoadChunks()
 
static void SlLoadCheckChunks()
 
{
 
	uint32 id;
 
	const ChunkHandler *ch;
 

	
 
	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
 
		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
 
		Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
 

	
 
		ch = SlFindChunkHandler(id);
 
		if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
 
		SlLoadCheckChunk(*ch);
 
	}
 
}
 
@@ -1798,13 +1798,13 @@ static void SlLoadCheckChunks()
 
static void SlFixPointers()
 
{
 
	_sl.action = SLA_PTRS;
 

	
 
	for (auto &ch : ChunkHandlers()) {
 
		if (ch.ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			ch.ptrs_proc();
 
		}
 
	}
 

	
 
	assert(_sl.action == SLA_PTRS);
 
}
 
@@ -1842,13 +1842,13 @@ struct FileReader : LoadFilter {
 
	}
 

	
 
	void Reset() override
 
	{
 
		clearerr(this->file);
 
		if (fseek(this->file, this->begin, SEEK_SET)) {
 
			DEBUG(sl, 1, "Could not reset the file reading");
 
			Debug(sl, 1, "Could not reset the file reading");
 
		}
 
	}
 
};
 

	
 
/** Yes, simply writing to a file. */
 
struct FileWriter : SaveFilter {
 
@@ -2467,13 +2467,13 @@ static SaveOrLoadResult SaveFileToDisk(b
 
		AsyncSaveFinishProc asfp = SaveFileDone;
 

	
 
		/* We don't want to shout when saving is just
 
		 * cancelled due to a client disconnecting. */
 
		if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
 
			/* Skip the "colour" character */
 
			DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
 
			Debug(sl, 0, "{}", GetSaveLoadErrorString() + 3);
 
			asfp = SaveFileError;
 
		}
 

	
 
		if (threaded) {
 
			SetAsyncSaveFinish(asfp);
 
		} else {
 
@@ -2513,13 +2513,13 @@ static SaveOrLoadResult DoSave(SaveFilte
 
	SaveViewportBeforeSaveGame();
 
	SlSaveChunks();
 

	
 
	SaveFileStart();
 

	
 
	if (!threaded || !StartNewThread(&_save_thread, "ottd:savegame", &SaveFileToDisk, true)) {
 
		if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
 
		if (threaded) Debug(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
 

	
 
		SaveOrLoadResult result = SaveFileToDisk(false);
 
		SaveFileDone();
 

	
 
		return result;
 
	}
 
@@ -2566,13 +2566,13 @@ static SaveOrLoadResult DoLoad(LoadFilte
 

	
 
	/* see if we have any loader for this type. */
 
	const SaveLoadFormat *fmt = _saveload_formats;
 
	for (;;) {
 
		/* No loader found, treat as version 0 and use LZO format */
 
		if (fmt == endof(_saveload_formats)) {
 
			DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
 
			Debug(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
 
			_sl.lf->Reset();
 
			_sl_version = SL_MIN_VERSION;
 
			_sl_minor_version = 0;
 

	
 
			/* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
 
			fmt = _saveload_formats;
 
@@ -2592,13 +2592,13 @@ static SaveOrLoadResult DoLoad(LoadFilte
 
			_sl_version = (SaveLoadVersion)(TO_BE32(hdr[1]) >> 16);
 
			/* Minor is not used anymore from version 18.0, but it is still needed
 
			 * in versions before that (4 cases) which can't be removed easy.
 
			 * Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */
 
			_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
 

	
 
			DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
 
			Debug(sl, 1, "Loading savegame version {}", _sl_version);
 

	
 
			/* Is the version higher than the current? */
 
			if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
 
			if (_sl_version >= SLV_START_PATCHPACKS && _sl_version <= SLV_END_PATCHPACKS) SlError(STR_GAME_SAVELOAD_ERROR_PATCHPACK);
 
			break;
 
		}
 
@@ -2772,28 +2772,28 @@ SaveOrLoadResult SaveOrLoad(const std::s
 

	
 
		if (fh == nullptr) {
 
			SlError(fop == SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
 
		}
 

	
 
		if (fop == SLO_SAVE) { // SAVE game
 
			DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename.c_str());
 
			Debug(desync, 1, "save: {:08x}; {:02x}; {}", _date, _date_fract, filename);
 
			if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
 

	
 
			return DoSave(new FileWriter(fh), threaded);
 
		}
 

	
 
		/* LOAD game */
 
		assert(fop == SLO_LOAD || fop == SLO_CHECK);
 
		DEBUG(desync, 1, "load: %s", filename.c_str());
 
		Debug(desync, 1, "load: {}", filename);
 
		return DoLoad(new FileReader(fh), fop == SLO_CHECK);
 
	} catch (...) {
 
		/* This code may be executed both for old and new save games. */
 
		ClearSaveLoadState();
 

	
 
		/* Skip the "colour" character */
 
		if (fop != SLO_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
 
		if (fop != SLO_CHECK) Debug(sl, 0, "{}", GetSaveLoadErrorString());
 

	
 
		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
 
		return (fop == SLO_LOAD) ? SL_REINIT : SL_ERROR;
 
	}
 
}
 

	
src/saveload/waypoint_sl.cpp
Show inline comments
 
@@ -100,16 +100,16 @@ void MoveWaypointsToBaseStations()
 
	/* All saveload conversions have been done. Create the new waypoints! */
 
	for (OldWaypoint &wp : _old_waypoints) {
 
		TileIndex t = wp.xy;
 
		/* Sometimes waypoint (sign) locations became disconnected from their actual location in
 
		 * the map array. If this is the case, try to locate the actual location in the map array */
 
		if (!IsTileType(t, MP_RAILWAY) || GetRailTileType(t) != 2 /* RAIL_TILE_WAYPOINT */ || _m[t].m2 != wp.index) {
 
			DEBUG(sl, 0, "Found waypoint tile %u with invalid position", t);
 
			Debug(sl, 0, "Found waypoint tile {} with invalid position", t);
 
			for (t = 0; t < MapSize(); t++) {
 
				if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp.index) {
 
					DEBUG(sl, 0, "Found actual waypoint position at %u", t);
 
					Debug(sl, 0, "Found actual waypoint position at {}", t);
 
					break;
 
				}
 
			}
 
		}
 
		if (t == MapSize()) {
 
			SlErrorCorrupt("Waypoint with invalid tile");
src/screenshot.cpp
Show inline comments
 
@@ -234,19 +234,19 @@ static bool MakeBMPImage(const char *nam
 
#include "company_base.h"
 
#include "base_media_base.h"
 
#endif /* PNG_TEXT_SUPPORTED */
 

	
 
static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
 
{
 
	DEBUG(misc, 0, "[libpng] error: %s - %s", message, (const char *)png_get_error_ptr(png_ptr));
 
	Debug(misc, 0, "[libpng] error: {} - {}", message, (const char *)png_get_error_ptr(png_ptr));
 
	longjmp(png_jmpbuf(png_ptr), 1);
 
}
 

	
 
static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
 
{
 
	DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (const char *)png_get_error_ptr(png_ptr));
 
	Debug(misc, 1, "[libpng] warning: {} - {}", message, (const char *)png_get_error_ptr(png_ptr));
 
}
 

	
 
/**
 
 * Generic .PNG file image writer.
 
 * @param name        Filename, including extension.
 
 * @param callb       Callback function for generating lines of pixels.
 
@@ -441,13 +441,13 @@ static bool MakePCXImage(const char *nam
 
	uint maxlines;
 
	uint y;
 
	PcxHeader pcx;
 
	bool success;
 

	
 
	if (pixelformat == 32) {
 
		DEBUG(misc, 0, "Can't convert a 32bpp screenshot to PCX format. Please pick another format.");
 
		Debug(misc, 0, "Can't convert a 32bpp screenshot to PCX format. Please pick another format.");
 
		return false;
 
	}
 
	if (pixelformat != 8 || w == 0) return false;
 

	
 
	f = fopen(name, "wb");
 
	if (f == nullptr) return false;
src/script/api/script_list.cpp
Show inline comments
 
@@ -466,13 +466,13 @@ int64 ScriptList::Begin()
 
	return this->sorter->Begin();
 
}
 

	
 
int64 ScriptList::Next()
 
{
 
	if (this->initialized == false) {
 
		DEBUG(script, 0, "Next() is invalid as Begin() is never called");
 
		Debug(script, 0, "Next() is invalid as Begin() is never called");
 
		return 0;
 
	}
 
	return this->sorter->Next();
 
}
 

	
 
bool ScriptList::IsEmpty()
 
@@ -480,13 +480,13 @@ bool ScriptList::IsEmpty()
 
	return this->items.empty();
 
}
 

	
 
bool ScriptList::IsEnd()
 
{
 
	if (this->initialized == false) {
 
		DEBUG(script, 0, "IsEnd() is invalid as Begin() is never called");
 
		Debug(script, 0, "IsEnd() is invalid as Begin() is never called");
 
		return true;
 
	}
 
	return this->sorter->IsEnd();
 
}
 

	
 
int32 ScriptList::Count()
src/script/api/script_log.cpp
Show inline comments
 
@@ -71,13 +71,13 @@
 
		case LOG_WARNING:  logc = 'W'; break;
 
		case LOG_INFO:     logc = 'I'; break;
 
		default:           logc = '?'; break;
 
	}
 

	
 
	/* Also still print to debug window */
 
	DEBUG(script, level, "[%d] [%c] %s", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
 
	Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
 
	InvalidateWindowData(WC_AI_DEBUG, 0, ScriptObject::GetRootCompany());
 
}
 

	
 
/* static */ void ScriptLog::FreeLogPointer()
 
{
 
	LogData *log = (LogData *)ScriptObject::GetLogPointer();
src/script/api/script_log.hpp
Show inline comments
 
@@ -20,13 +20,13 @@ class ScriptLog : public ScriptObject {
 
	/* ScriptController needs access to Enum and Log, in order to keep the flow from
 
	 *  OpenTTD core to script API clear and simple. */
 
	friend class ScriptController;
 

	
 
public:
 
	/**
 
	 * Log levels; The value is also feed to DEBUG() lvl.
 
	 * Log levels; The value is also feed to Debug() lvl.
 
	 *  This has no use for you, as script writer.
 
	 * @api -all
 
	 */
 
	enum ScriptLogType {
 
		LOG_SQ_ERROR = 0, ///< Squirrel printed an error.
 
		LOG_ERROR = 1,    ///< User printed an error.
src/script/api/script_object.cpp
Show inline comments
 
@@ -82,23 +82,23 @@ ScriptObject::ActiveInstance::~ActiveIns
 
	return GetStorage()->mode_instance;
 
}
 

	
 
/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
 
{
 
	ScriptStorage *s = GetStorage();
 
	DEBUG(script, 6, "SetLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
 
	Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd);
 
	s->last_tile = tile;
 
	s->last_p1 = p1;
 
	s->last_p2 = p2;
 
	s->last_cmd = cmd & CMD_ID_MASK;
 
}
 

	
 
/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
 
{
 
	ScriptStorage *s = GetStorage();
 
	DEBUG(script, 6, "CheckLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
 
	Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd);
 
	if (s->last_tile != tile) return false;
 
	if (s->last_p1 != p1) return false;
 
	if (s->last_p2 != p2) return false;
 
	if (s->last_cmd != (cmd & CMD_ID_MASK)) return false;
 
	return true;
 
}
src/script/api/script_order.cpp
Show inline comments
 
@@ -561,13 +561,13 @@ static void _DoCommandReturnSetOrderFlag
 

	
 
/* static */ bool ScriptOrder::_SetOrderFlags()
 
{
 
	/* Make sure we don't go into an infinite loop */
 
	int retry = ScriptObject::GetCallbackVariable(3) - 1;
 
	if (retry < 0) {
 
		DEBUG(script, 0, "Possible infinite loop in SetOrderFlags() detected");
 
		Debug(script, 0, "Possible infinite loop in SetOrderFlags() detected");
 
		return false;
 
	}
 
	ScriptObject::SetCallbackVariable(3, retry);
 

	
 
	VehicleID vehicle_id = (VehicleID)ScriptObject::GetCallbackVariable(0);
 
	OrderPosition order_position = (OrderPosition)ScriptObject::GetCallbackVariable(1);
src/script/api/script_rail.cpp
Show inline comments
 
@@ -192,13 +192,13 @@
 
	);
 
	uint32 p2 = (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16;
 
	if (res != CALLBACK_FAILED) {
 
		int index = 0;
 
		const StationSpec *spec = StationClass::GetByGrf(file->grfid, res, &index);
 
		if (spec == nullptr) {
 
			DEBUG(grf, 1, "%s returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
 
			Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
 
		} else {
 
			/* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */
 
			if (ScriptObject::DoCommand(tile, p1, p2 | spec->cls_id | index << 8, CMD_BUILD_RAIL_STATION)) return true;
 
		}
 
	}
 

	
src/script/script_instance.cpp
Show inline comments
 
@@ -121,13 +121,13 @@ bool ScriptInstance::LoadCompatibilitySc
 
		buf += script_name;
 
		if (!FileExists(buf)) continue;
 

	
 
		if (this->engine->LoadScript(buf.c_str())) return true;
 

	
 
		ScriptLog::Error("Failed to load API compatibility script");
 
		DEBUG(script, 0, "Error compiling / running API compatibility script: %s", buf.c_str());
 
		Debug(script, 0, "Error compiling / running API compatibility script: {}", buf);
 
		return false;
 
	}
 

	
 
	ScriptLog::Warning("API compatibility script not found");
 
	return true;
 
}
 
@@ -149,13 +149,13 @@ void ScriptInstance::Continue()
 
	assert(this->suspend < 0);
 
	this->suspend = -this->suspend - 1;
 
}
 

	
 
void ScriptInstance::Died()
 
{
 
	DEBUG(script, 0, "The script died unexpectedly.");
 
	Debug(script, 0, "The script died unexpectedly.");
 
	this->is_dead = true;
 
	this->in_shutdown = true;
 

	
 
	this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache
 

	
 
	if (this->instance != nullptr) this->engine->ReleaseObject(this->instance);
 
@@ -689,13 +689,13 @@ SQInteger ScriptInstance::GetOpsTillSusp
 

	
 
bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
 
{
 
	ScriptObject::ActiveInstance active(this);
 

	
 
	if (!ScriptObject::CheckLastCommand(tile, p1, p2, cmd)) {
 
		DEBUG(script, 1, "DoCommandCallback terminating a script, last command does not match expected command");
 
		Debug(script, 1, "DoCommandCallback terminating a script, last command does not match expected command");
 
		return false;
 
	}
 

	
 
	ScriptObject::SetLastCommandRes(result.Succeeded());
 

	
 
	if (result.Failed()) {

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)