File diff r25654:e264fd698eb2 → r25655:1030dcb7eb52
src/openttd.cpp
Show inline comments
 
@@ -179,25 +179,25 @@ static void ShowHelp()
 
		"  -b drv              = Set the blitter to use (see below)\n"
 
		"  -r res              = Set resolution (for instance 800x600)\n"
 
		"  -h                  = Display this help text\n"
 
		"  -t year             = Set starting year\n"
 
		"  -d [[fac=]lvl[,...]]= Debug mode\n"
 
		"  -e                  = Start Editor\n"
 
		"  -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"
 
		"  -c config_file      = Use 'config_file' instead of 'openttd.cfg'\n"
 
		"  -x                  = Never save configuration changes to disk\n"
 
		"  -X                  = Don't use global folders to search for files\n"
 
		"  -q savegame         = Write some information about the savegame and exit\n"
 
		"\n",
 
		lastof(buf)
 
@@ -657,25 +657,25 @@ int openttd_main(int argc, char *argv[])
 
		DeterminePaths(argv[0], only_local_path);
 
		TarScanner::DoScan(TarScanner::BASESET);
 
		BaseGraphics::FindSets();
 
		BaseSounds::FindSets();
 
		BaseMusic::FindSets();
 
		ShowHelp();
 
		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
 

	
 
	LoadFromConfig(true);
 

	
 
	if (resolution.width != 0) _cur_resolution = resolution;
 

	
 
	/* Limit width times height times bytes per pixel to fit a 32 bit
 
@@ -706,25 +706,25 @@ int openttd_main(int argc, char *argv[])
 
		if (!graphics_set.empty()) {
 
			BaseGraphics::SetSet({});
 

	
 
			ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
 
			msg.SetDParamStr(0, graphics_set);
 
			ScheduleErrorMessage(msg);
 
		}
 
	}
 

	
 
	/* 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.
 
	 *  - Use 8bpp blitter otherwise.
 
	 */
 
	if (!_blitter_autodetected ||
 
			(_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) ||
 
			BlitterFactory::SelectBlitter("32bpp-anim") == nullptr) {
 
		if (BlitterFactory::SelectBlitter(blitter) == nullptr) {
 
@@ -936,25 +936,25 @@ bool SafeLoad(const std::string &filenam
 

	
 
	switch (lf == nullptr ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) {
 
		case SL_OK: return true;
 

	
 
		case SL_REINIT:
 
			if (_network_dedicated) {
 
				/*
 
				 * 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();
 
			}
 

	
 
			switch (ogm) {
 
				default:
 
				case GM_MENU:   LoadIntroGame();      break;
 
				case GM_EDITOR: MakeNewEditorWorld(); break;
 
@@ -1127,40 +1127,40 @@ static void CheckCaches()
 
	std::vector<TownCache> old_town_caches;
 
	for (const Town *t : Town::Iterate()) {
 
		old_town_caches.push_back(t->cache);
 
	}
 

	
 
	extern void RebuildTownCaches();
 
	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;
 
	for (const Company *c : Company::Iterate()) old_infrastructure.push_back(c->infrastructure);
 

	
 
	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()) {
 
		if (IsStandardRoadStopTile(rs->xy)) continue;
 

	
 
		assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW));
 
		rs->GetEntry(DIAGDIR_NE)->CheckIntegrity(rs);
 
		rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs);
 
	}
 
@@ -1199,41 +1199,41 @@ static void CheckCaches()
 
		switch (v->type) {
 
			case VEH_TRAIN:    Train::From(v)->ConsistChanged(CCF_TRACK); break;
 
			case VEH_ROAD:     RoadVehUpdateCache(RoadVehicle::From(v)); break;
 
			case VEH_AIRCRAFT: UpdateAircraftCache(Aircraft::From(v));   break;
 
			case VEH_SHIP:     Ship::From(v)->UpdateCache();             break;
 
			default: break;
 
		}
 

	
 
		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++;
 
		}
 

	
 
		free(grf_cache);
 
		free(veh_cache);
 
		free(gro_cache);
 
		free(tra_cache);
 
@@ -1262,52 +1262,52 @@ static void CheckCaches()
 
			assert(memcmp(&st->goods[c].cargo, buff, sizeof(StationCargoList)) == 0);
 
		}
 

	
 
		/* Check docking tiles */
 
		TileArea ta;
 
		std::map<TileIndex, bool> docking_tiles;
 
		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++;
 
	}
 
}
 

	
 
/**
 
 * State controlling game loop.
 
 * The state must not be changed from anywhere but here.
 
 * That check is enforced in DoCommand.
 
 */
 
void StateGameLoop()
 
{
 
@@ -1397,25 +1397,25 @@ static void DoAutosave()
 
	if (_settings_client.gui.keep_all_autosave) {
 
		GenerateDefaultSaveName(buf, lastof(buf));
 
		strecat(buf, ".sav", lastof(buf));
 
	} else {
 
		static int _autosave_ctr = 0;
 

	
 
		/* 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);
 
	}
 
}
 

	
 
/**
 
 * Request a new NewGRF scan. This will be executed on the next game-tick.
 
 * This is mostly needed to ensure NewGRF scans (which are blocking) are
 
 * done in the game-thread, and not in the draw-thread (which most often
 
 * triggers this request).
 
 * @param callback Optional callback to call when NewGRF scan is completed.
 
 * @return True when the NewGRF scan was actually requested, false when the scan was already running.