File diff r9183:200d86a0cdf3 → r9184:cdb864f70553
src/openttd.cpp
Show inline comments
 
@@ -1047,98 +1047,98 @@ void StateGameLoop()
 
		RunTileLoop();
 
		CallVehicleTicks();
 
		CallLandscapeTick();
 
		ClearStorageChanges(true);
 

	
 
		AI_RunGameLoop();
 

	
 
		CallWindowTickEvent();
 
		NewsLoop();
 
		_current_player = p;
 
	}
 
}
 

	
 
/** Create an autosave. The default name is "autosave#.sav". However with
 
 * the patch setting 'keep_all_autosave' the name defaults to company-name + date */
 
static void DoAutosave()
 
{
 
	char buf[MAX_PATH];
 

	
 
#if defined(PSP)
 
	/* Autosaving in networking is too time expensive for the PSP */
 
	if (_networking) return;
 
#endif /* PSP */
 

	
 
	if (_patches.keep_all_autosave && _local_player != PLAYER_SPECTATOR) {
 
		SetDParam(0, _local_player);
 
		SetDParam(1, _date);
 
		GetString(buf, STR_4004, lastof(buf));
 
		ttd_strlcat(buf, ".sav", lengthof(buf));
 
	} else {
 
		/* generate a savegame name and number according to _patches.max_num_autosaves */
 
		snprintf(buf, sizeof(buf), "autosave%d.sav", _autosave_ctr);
 

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

	
 
	DEBUG(sl, 2, "Autosaving to '%s'", buf);
 
	if (SaveOrLoad(buf, SL_SAVE, AUTOSAVE_DIR) != SL_OK) {
 
		ShowErrorMessage(INVALID_STRING_ID, STR_AUTOSAVE_FAILED, 0, 0);
 
	}
 
}
 

	
 
static void ScrollMainViewport(int x, int y)
 
{
 
	if (_game_mode != GM_MENU) {
 
		Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
 
		assert(w);
 

	
 
		WP(w, vp_d).dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
 
		WP(w, vp_d).dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
 
		w->viewport->dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
 
		w->viewport->dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
 
	}
 
}
 

	
 
/**
 
 * Describes all the different arrow key combinations the game allows
 
 * when it is in scrolling mode.
 
 * The real arrow keys are bitwise numbered as
 
 * 1 = left
 
 * 2 = up
 
 * 4 = right
 
 * 8 = down
 
 */
 
static const int8 scrollamt[16][2] = {
 
	{ 0,  0}, ///<  no key specified
 
	{-2,  0}, ///<  1 : left
 
	{ 0, -2}, ///<  2 : up
 
	{-2, -1}, ///<  3 : left  + up
 
	{ 2,  0}, ///<  4 : right
 
	{ 0,  0}, ///<  5 : left  + right = nothing
 
	{ 2, -1}, ///<  6 : right + up
 
	{ 0, -2}, ///<  7 : right + left  + up = up
 
	{ 0  ,2}, ///<  8 : down
 
	{-2  ,1}, ///<  9 : down  + left
 
	{ 0,  0}, ///< 10 : down  + up    = nothing
 
	{-2,  0}, ///< 11 : left  + up    +  down = left
 
	{ 2,  1}, ///< 12 : down  + right
 
	{ 0,  2}, ///< 13 : left  + right +  down = down
 
	{ 2,  0}, ///< 14 : right + up    +  down = right
 
	{ 0,  0}, ///< 15 : left  + up    +  right + down  = nothing
 
};
 

	
 
static void HandleKeyScrolling()
 
{
 
	if (_dirkeys && !_no_scroll) {
 
		int factor = _shift_pressed ? 50 : 10;
 
		ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
 
	}
 
}
 

	
 
void GameLoop()
 
{
 
	ProcessAsyncSaveFinish();
 

	
 
	/* autosave game? */
 
	if (_do_autosave) {
 
		_do_autosave = false;
 
		DoAutosave();
 
		RedrawAutosave();
 
@@ -1158,98 +1158,98 @@ void GameLoop()
 

	
 
	IncreaseSpriteLRU();
 
	InteractiveRandom();
 

	
 
	if (_scroller_click_timeout > 3) {
 
		_scroller_click_timeout -= 3;
 
	} else {
 
		_scroller_click_timeout = 0;
 
	}
 

	
 
	_caret_timer += 3;
 
	_palette_animation_counter += 8;
 
	CursorTick();
 

	
 
#ifdef ENABLE_NETWORK
 
	/* Check for UDP stuff */
 
	if (_network_available) NetworkUDPGameLoop();
 

	
 
	if (_networking && !IsGeneratingWorld()) {
 
		/* Multiplayer */
 
		NetworkGameLoop();
 
	} else {
 
		if (_network_reconnect > 0 && --_network_reconnect == 0) {
 
			/* This means that we want to reconnect to the last host
 
			 * We do this here, because it means that the network is really closed */
 
			NetworkClientConnectGame(_network_last_host, _network_last_port);
 
		}
 
		/* Singleplayer */
 
		StateGameLoop();
 
	}
 
#else
 
	StateGameLoop();
 
#endif /* ENABLE_NETWORK */
 

	
 
	if (!_pause_game && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();
 

	
 
	if (!_pause_game || _cheats.build_in_pause.value) MoveAllTextEffects();
 

	
 
	InputLoop();
 

	
 
	MusicLoop();
 
}
 

	
 
void BeforeSaveGame()
 
{
 
	const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
 

	
 
	if (w != NULL) {
 
		_saved_scrollpos_x = WP(w, const vp_d).scrollpos_x;
 
		_saved_scrollpos_y = WP(w, const vp_d).scrollpos_y;
 
		_saved_scrollpos_x = w->viewport->scrollpos_x;
 
		_saved_scrollpos_y = w->viewport->scrollpos_y;
 
		_saved_scrollpos_zoom = w->viewport->zoom;
 
	}
 
}
 

	
 
static void ConvertTownOwner()
 
{
 
	for (TileIndex tile = 0; tile != MapSize(); tile++) {
 
		switch (GetTileType(tile)) {
 
			case MP_ROAD:
 
				if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m4, 7)) {
 
					_m[tile].m4 = OWNER_TOWN;
 
				}
 
				/* FALLTHROUGH */
 

	
 
			case MP_TUNNELBRIDGE:
 
				if (GetTileOwner(tile) & 0x80) SetTileOwner(tile, OWNER_TOWN);
 
				break;
 

	
 
			default: break;
 
		}
 
	}
 
}
 

	
 
/* before savegame version 4, the name of the company determined if it existed */
 
static void CheckIsPlayerActive()
 
{
 
	Player *p;
 

	
 
	FOR_ALL_PLAYERS(p) {
 
		if (p->name_1 != 0) p->is_active = true;
 
	}
 
}
 

	
 
/* since savegame version 4.1, exclusive transport rights are stored at towns */
 
static void UpdateExclusiveRights()
 
{
 
	Town *t;
 

	
 
	FOR_ALL_TOWNS(t) {
 
		t->exclusivity = INVALID_PLAYER;
 
	}
 

	
 
	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
 
	 *   could be implemented this way:
 
	 * 1.) Go through all stations
 
	 *     Build an array town_blocked[ town_id ][ player_id ]
 
	 *     that stores if at least one station in that town is blocked for a player
 
	 * 2.) Go through that array, if you find a town that is not blocked for
 
@@ -1271,100 +1271,100 @@ static void UpdateCurrencies()
 
}
 

	
 
/* Up to revision 1413 the invisible tiles at the southern border have not been
 
 * MP_VOID, even though they should have. This is fixed by this function
 
 */
 
static void UpdateVoidTiles()
 
{
 
	uint i;
 

	
 
	for (i = 0; i < MapMaxY(); ++i) MakeVoid(i * MapSizeX() + MapMaxX());
 
	for (i = 0; i < MapSizeX(); ++i) MakeVoid(MapSizeX() * MapMaxY() + i);
 
}
 

	
 
/* since savegame version 6.0 each sign has an "owner", signs without owner (from old games are set to 255) */
 
static void UpdateSignOwner()
 
{
 
	Sign *si;
 

	
 
	FOR_ALL_SIGNS(si) si->owner = OWNER_NONE;
 
}
 

	
 
extern void UpdateOldAircraft();
 

	
 

	
 
static inline RailType UpdateRailType(RailType rt, RailType min)
 
{
 
	return rt >= min ? (RailType)(rt + 1): rt;
 
}
 

	
 
/**
 
 * Initialization of the windows and several kinds of caches.
 
 * This is not done directly in AfterLoadGame because these
 
 * functions require that all saveload conversions have been
 
 * done. As people tend to add savegame conversion stuff after
 
 * the intialization of the windows and caches quite some bugs
 
 * had been made.
 
 * Moving this out of there is both cleaner and less bug-prone.
 
 *
 
 * @return true if everything went according to plan, otherwise false.
 
 */
 
static bool InitializeWindowsAndCaches()
 
{
 
	/* Initialize windows */
 
	ResetWindowSystem();
 
	SetupColorsAndInitialWindow();
 

	
 
	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
 

	
 
	WP(w, vp_d).scrollpos_x = _saved_scrollpos_x;
 
	WP(w, vp_d).scrollpos_y = _saved_scrollpos_y;
 
	WP(w, vp_d).dest_scrollpos_x = _saved_scrollpos_x;
 
	WP(w, vp_d).dest_scrollpos_y = _saved_scrollpos_y;
 
	w->viewport->scrollpos_x = _saved_scrollpos_x;
 
	w->viewport->scrollpos_y = _saved_scrollpos_y;
 
	w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
 
	w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
 

	
 
	ViewPort *vp = w->viewport;
 
	vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
 
	vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
 
	vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
 

	
 
	DoZoomInOutWindow(ZOOM_NONE, w); // update button status
 
	MarkWholeScreenDirty();
 

	
 
	/* Update coordinates of the signs. */
 
	UpdateAllStationVirtCoord();
 
	UpdateAllSignVirtCoords();
 
	UpdateAllTownVirtCoords();
 
	UpdateAllWaypointSigns();
 

	
 
	/* Recalculate */
 
	Group *g;
 
	FOR_ALL_GROUPS(g) {
 
		g->num_engines = CallocT<uint16>(GetEnginePoolSize());
 

	
 
		const Vehicle *v;
 
		FOR_ALL_VEHICLES(v) {
 
			if (!IsEngineCountable(v)) continue;
 

	
 
			if (v->group_id != g->index || v->type != g->vehicle_type || v->owner != g->owner) continue;
 

	
 
			g->num_engines[v->engine_type]++;
 
		}
 
	}
 

	
 
	/* Set up the engine count for all players */
 
	Player *players[MAX_PLAYERS];
 
	const Vehicle *v;
 

	
 
	for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) {
 
		players[i] = GetPlayer(i);
 

	
 
		/* For each player, verify (while loading a scenario) that the inauguration date is the current year and set it
 
		 * accordingly if it is not the case.  No need to set it on players that are not been used already,
 
		 * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
 
		if (_file_to_saveload.filetype == FT_SCENARIO && players[i]->inaugurated_year != MIN_YEAR)
 
			players[i]->inaugurated_year = _cur_year;
 

	
 
		free(players[i]->num_engines);
 
		players[i]->num_engines = CallocT<uint16>(GetEnginePoolSize());
 
	}
 

	
 
	FOR_ALL_VEHICLES(v) {