src/openttd.cpp
changeset 5838 9c3129cb019b
parent 5835 e0ff603ae0b7
child 5860 7fdc9b423ba1
equal deleted inserted replaced
5837:96b4b92b86ae 5838:9c3129cb019b
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #include "stdafx.h"
     3 #include "stdafx.h"
       
     4 #define VARDEF
     4 #include "string.h"
     5 #include "string.h"
     5 #include "table/strings.h"
     6 #include "table/strings.h"
     6 #include "debug.h"
     7 #include "debug.h"
     7 #include "driver.h"
     8 #include "driver.h"
     8 #include "saveload.h"
     9 #include "saveload.h"
     9 #include "strings.h"
    10 #include "strings.h"
    10 #include "map.h"
    11 #include "map.h"
    11 #include "tile.h"
    12 #include "tile.h"
    12 #include "void_map.h"
    13 #include "void_map.h"
    13 
    14 #include "helpers.hpp"
    14 #define VARDEF
    15 
    15 #include "openttd.h"
    16 #include "openttd.h"
    16 #include "bridge_map.h"
    17 #include "bridge_map.h"
    17 #include "functions.h"
    18 #include "functions.h"
    18 #include "mixer.h"
    19 #include "mixer.h"
    19 #include "spritecache.h"
    20 #include "spritecache.h"
    71 void ResetMusic(void);
    72 void ResetMusic(void);
    72 void InitializeStations(void);
    73 void InitializeStations(void);
    73 void DeleteAllPlayerStations(void);
    74 void DeleteAllPlayerStations(void);
    74 
    75 
    75 extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
    76 extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
    76 extern void DoStartupNewPlayer(bool is_ai);
    77 extern Player* DoStartupNewPlayer(bool is_ai);
    77 extern void ShowOSErrorBox(const char *buf);
    78 extern void ShowOSErrorBox(const char *buf);
    78 
    79 
    79 /* TODO: usrerror() for errors which are not of an internal nature but
    80 /* TODO: usrerror() for errors which are not of an internal nature but
    80  * caused by the user, i.e. missing files or fatal configuration errors.
    81  * caused by the user, i.e. missing files or fatal configuration errors.
    81  * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */
    82  * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */
   117 	if (in == NULL) return NULL;
   118 	if (in == NULL) return NULL;
   118 
   119 
   119 	fseek(in, 0, SEEK_END);
   120 	fseek(in, 0, SEEK_END);
   120 	len = ftell(in);
   121 	len = ftell(in);
   121 	fseek(in, 0, SEEK_SET);
   122 	fseek(in, 0, SEEK_SET);
   122 	if (len > maxsize || (mem = malloc(len + 1)) == NULL) {
   123 	if (len > maxsize || !MallocT(&mem, len + 1)) {
   123 		fclose(in);
   124 		fclose(in);
   124 		return NULL;
   125 		return NULL;
   125 	}
   126 	}
   126 	mem[len] = 0;
   127 	mem[len] = 0;
   127 	if (fread(mem, len, 1, in) != 1) {
   128 	if (fread(mem, len, 1, in) != 1) {
   133 
   134 
   134 	*lenp = len;
   135 	*lenp = len;
   135 	return mem;
   136 	return mem;
   136 }
   137 }
   137 
   138 
       
   139 extern const char _openttd_revision[];
   138 static void showhelp(void)
   140 static void showhelp(void)
   139 {
   141 {
   140 	extern const char _openttd_revision[];
       
   141 	char buf[4096], *p;
   142 	char buf[4096], *p;
   142 
   143 
   143 	p = buf;
   144 	p = buf;
   144 
   145 
   145 	p += snprintf(p, lengthof(buf), "OpenTTD %s\n", _openttd_revision);
   146 	p += snprintf(p, lengthof(buf), "OpenTTD %s\n", _openttd_revision);
   173 
   174 
   174 	ShowInfo(buf);
   175 	ShowInfo(buf);
   175 }
   176 }
   176 
   177 
   177 
   178 
   178 typedef struct {
   179 struct MyGetOptData {
   179 	char *opt;
   180 	char *opt;
   180 	int numleft;
   181 	int numleft;
   181 	char **argv;
   182 	char **argv;
   182 	const char *options;
   183 	const char *options;
   183 	char *cont;
   184 	const char *cont;
   184 } MyGetOptData;
   185 
   185 
   186 	MyGetOptData(int argc, char **argv, const char *options)
   186 static void MyGetOptInit(MyGetOptData *md, int argc, char **argv, const char *options)
   187 	{
   187 {
   188 		opt = NULL;
   188 	md->cont = NULL;
   189 		numleft = argc;
   189 	md->numleft = argc;
   190 		this->argv = argv;
   190 	md->argv = argv;
   191 		this->options = options;
   191 	md->options = options;
   192 		cont = NULL;
   192 }
   193 	}
       
   194 };
   193 
   195 
   194 static int MyGetOpt(MyGetOptData *md)
   196 static int MyGetOpt(MyGetOptData *md)
   195 {
   197 {
   196 	char *s,*r,*t;
   198 	const char *s,*r,*t;
   197 
   199 
   198 	s = md->cont;
   200 	s = md->cont;
   199 	if (s != NULL)
   201 	if (s != NULL)
   200 		goto md_continue_here;
   202 		goto md_continue_here;
   201 
   203 
   224 							t = NULL;
   226 							t = NULL;
   225 						} else {
   227 						} else {
   226 							md->argv++;
   228 							md->argv++;
   227 						}
   229 						}
   228 					}
   230 					}
   229 					md->opt = t;
   231 					md->opt = (char*)t;
   230 					md->cont = NULL;
   232 					md->cont = NULL;
   231 					return *s;
   233 					return *s;
   232 				}
   234 				}
   233 				md->opt = NULL;
   235 				md->opt = NULL;
   234 				md->cont = s;
   236 				md->cont = s;
   242 }
   244 }
   243 
   245 
   244 
   246 
   245 static void ParseResolution(int res[2], const char *s)
   247 static void ParseResolution(int res[2], const char *s)
   246 {
   248 {
   247 	char *t = strchr(s, 'x');
   249 	const char *t = strchr(s, 'x');
   248 	if (t == NULL) {
   250 	if (t == NULL) {
   249 		ShowInfoF("Invalid resolution '%s'", s);
   251 		ShowInfoF("Invalid resolution '%s'", s);
   250 		return;
   252 		return;
   251 	}
   253 	}
   252 
   254 
   306 		GenerateWorld(GW_EMPTY, 64, 64); // if failed loading, make empty world.
   308 		GenerateWorld(GW_EMPTY, 64, 64); // if failed loading, make empty world.
   307 		WaitTillGeneratedWorld();
   309 		WaitTillGeneratedWorld();
   308 	}
   310 	}
   309 
   311 
   310 	_pause = 0;
   312 	_pause = 0;
   311 	SetLocalPlayer(0);
   313 	SetLocalPlayer(PLAYER_FIRST);
   312 	/* Make sure you can't scroll in the menu */
   314 	/* Make sure you can't scroll in the menu */
   313 	_scrolling_viewport = 0;
   315 	_scrolling_viewport = 0;
   314 	_cursor.fix_at = false;
   316 	_cursor.fix_at = false;
   315 	MarkWholeScreenDirty();
   317 	MarkWholeScreenDirty();
   316 
   318 
   322 extern void DedicatedFork(void);
   324 extern void DedicatedFork(void);
   323 #endif
   325 #endif
   324 
   326 
   325 int ttd_main(int argc, char *argv[])
   327 int ttd_main(int argc, char *argv[])
   326 {
   328 {
   327 	MyGetOptData mgo;
       
   328 	int i;
   329 	int i;
   329 	const char *optformat;
   330 	const char *optformat;
   330 	char musicdriver[16], sounddriver[16], videodriver[16];
   331 	char musicdriver[16], sounddriver[16], videodriver[16];
   331 	int resolution[2] = {0,0};
   332 	int resolution[2] = {0,0};
   332 	Year startyear = INVALID_YEAR;
   333 	Year startyear = INVALID_YEAR;
   354 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
   355 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
   355 		"f"
   356 		"f"
   356 #endif
   357 #endif
   357 	;
   358 	;
   358 
   359 
   359 	MyGetOptInit(&mgo, argc-1, argv+1, optformat);
   360 	MyGetOptData mgo(argc-1, argv+1, optformat);
       
   361 
   360 	while ((i = MyGetOpt(&mgo)) != -1) {
   362 	while ((i = MyGetOpt(&mgo)) != -1) {
   361 		switch (i) {
   363 		switch (i) {
   362 		case 'm': ttd_strlcpy(musicdriver, mgo.opt, sizeof(musicdriver)); break;
   364 		case 'm': ttd_strlcpy(musicdriver, mgo.opt, sizeof(musicdriver)); break;
   363 		case 's': ttd_strlcpy(sounddriver, mgo.opt, sizeof(sounddriver)); break;
   365 		case 's': ttd_strlcpy(sounddriver, mgo.opt, sizeof(sounddriver)); break;
   364 		case 'v': ttd_strlcpy(videodriver, mgo.opt, sizeof(videodriver)); break;
   366 		case 'v': ttd_strlcpy(videodriver, mgo.opt, sizeof(videodriver)); break;
   510 			_network_playas = PLAYER_NEW_COMPANY;
   512 			_network_playas = PLAYER_NEW_COMPANY;
   511 
   513 
   512 			ParseConnectionString(&player, &port, network_conn);
   514 			ParseConnectionString(&player, &port, network_conn);
   513 
   515 
   514 			if (player != NULL) {
   516 			if (player != NULL) {
   515 				_network_playas = atoi(player);
   517 				_network_playas = (PlayerID)atoi(player);
   516 
   518 
   517 				if (_network_playas != PLAYER_SPECTATOR) {
   519 				if (_network_playas != PLAYER_SPECTATOR) {
   518 					_network_playas--;
   520 					_network_playas--;
   519 					if (!IsValidPlayer(_network_playas)) return false;
   521 					if (!IsValidPlayer(_network_playas)) return false;
   520 				}
   522 				}
   626 	}
   628 	}
   627 
   629 
   628 	/* Create a single player */
   630 	/* Create a single player */
   629 	DoStartupNewPlayer(false);
   631 	DoStartupNewPlayer(false);
   630 
   632 
   631 	SetLocalPlayer(0);
   633 	SetLocalPlayer(PLAYER_FIRST);
   632 	_current_player = _local_player;
   634 	_current_player = _local_player;
   633 	DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
   635 	DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
   634 
   636 
   635 	SettingsDisableElrail(_patches.disable_elrails);
   637 	SettingsDisableElrail(_patches.disable_elrails);
   636 
   638 
   706 	StartupEconomy();
   708 	StartupEconomy();
   707 	StartupPlayers();
   709 	StartupPlayers();
   708 	StartupEngines();
   710 	StartupEngines();
   709 	StartupDisasters();
   711 	StartupDisasters();
   710 
   712 
   711 	SetLocalPlayer(0);
   713 	SetLocalPlayer(PLAYER_FIRST);
   712 	_current_player = _local_player;
   714 	_current_player = _local_player;
   713 	DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
   715 	DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
   714 
   716 
   715 	MarkWholeScreenDirty();
   717 	MarkWholeScreenDirty();
   716 }
   718 }
   797 			LoadIntroGame();
   799 			LoadIntroGame();
   798 			ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
   800 			ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
   799 		} else {
   801 		} else {
   800 			/* Update the local player for a loaded game. It is either always
   802 			/* Update the local player for a loaded game. It is either always
   801 			 * player #1 (eg 0) or in the case of a dedicated server a spectator */
   803 			 * player #1 (eg 0) or in the case of a dedicated server a spectator */
   802 			SetLocalPlayer(_network_dedicated ? PLAYER_SPECTATOR : 0);
   804 			SetLocalPlayer(_network_dedicated ? PLAYER_SPECTATOR : PLAYER_FIRST);
   803 			DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
   805 			DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
   804 #ifdef ENABLE_NETWORK
   806 #ifdef ENABLE_NETWORK
   805 			if (_network_server) {
   807 			if (_network_server) {
   806 				snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
   808 				snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
   807 			}
   809 			}
  1094 static void UpdateExclusiveRights(void)
  1096 static void UpdateExclusiveRights(void)
  1095 {
  1097 {
  1096 	Town *t;
  1098 	Town *t;
  1097 
  1099 
  1098 	FOR_ALL_TOWNS(t) {
  1100 	FOR_ALL_TOWNS(t) {
  1099 		t->exclusivity = (byte)-1;
  1101 		t->exclusivity = INVALID_PLAYER;
  1100 	}
  1102 	}
  1101 
  1103 
  1102 	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
  1104 	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
  1103 	 *   could be implemented this way:
  1105 	 *   could be implemented this way:
  1104 	 * 1.) Go through all stations
  1106 	 * 1.) Go through all stations
  1310 		 * However, in a dedicated server we are a spectator, so nothing needs to
  1312 		 * However, in a dedicated server we are a spectator, so nothing needs to
  1311 		 * happen. In case we are not a dedicated server, the local player always
  1313 		 * happen. In case we are not a dedicated server, the local player always
  1312 		 * becomes player 0, unless we are in the scenario editor where all the
  1314 		 * becomes player 0, unless we are in the scenario editor where all the
  1313 		 * players are 'invalid'.
  1315 		 * players are 'invalid'.
  1314 		 */
  1316 		 */
  1315 		if (!_network_dedicated && IsValidPlayer(0)) {
  1317 		if (!_network_dedicated && IsValidPlayer(PLAYER_FIRST)) {
  1316 			p = GetPlayer(0);
  1318 			p = GetPlayer(PLAYER_FIRST);
  1317 			p->engine_renew        = _patches.autorenew;
  1319 			p->engine_renew        = _patches.autorenew;
  1318 			p->engine_renew_months = _patches.autorenew_months;
  1320 			p->engine_renew_months = _patches.autorenew_months;
  1319 			p->engine_renew_money  = _patches.autorenew_money;
  1321 			p->engine_renew_money  = _patches.autorenew_money;
  1320 		}
  1322 		}
  1321 	}
  1323 	}
  1385 				v->tile = GetNorthernBridgeEnd(v->tile);
  1387 				v->tile = GetNorthernBridgeEnd(v->tile);
  1386 			} else {
  1388 			} else {
  1387 				continue;
  1389 				continue;
  1388 			}
  1390 			}
  1389 			if (v->type == VEH_Train) {
  1391 			if (v->type == VEH_Train) {
  1390 				v->u.rail.track = 0x40;
  1392 				v->u.rail.track = TRACK_BIT_WORMHOLE;
  1391 			} else {
  1393 			} else {
  1392 				v->u.road.state = 0xFF;
  1394 				v->u.road.state = 0xFF;
  1393 			}
  1395 			}
  1394 		}
  1396 		}
  1395 	}
  1397 	}
  1565 	if (!CheckSavegameVersion(27)) AfterLoadStations();
  1567 	if (!CheckSavegameVersion(27)) AfterLoadStations();
  1566 
  1568 
  1567 	{
  1569 	{
  1568 		/* Set up the engine count for all players */
  1570 		/* Set up the engine count for all players */
  1569 		Player *players[MAX_PLAYERS];
  1571 		Player *players[MAX_PLAYERS];
  1570 		int i;
       
  1571 		const Vehicle *v;
  1572 		const Vehicle *v;
  1572 
  1573 
  1573 		for (i = 0; i < MAX_PLAYERS; i++) players[i] = GetPlayer(i);
  1574 		for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) players[i] = GetPlayer(i);
  1574 
  1575 
  1575 		FOR_ALL_VEHICLES(v) {
  1576 		FOR_ALL_VEHICLES(v) {
  1576 			if (!IsEngineCountable(v)) continue;
  1577 			if (!IsEngineCountable(v)) continue;
  1577 			players[v->owner]->num_engines[v->engine_type]++;
  1578 			players[v->owner]->num_engines[v->engine_type]++;
  1578 		}
  1579 		}
  1700 	AfterLoadWaypoints();
  1701 	AfterLoadWaypoints();
  1701 	AfterLoadStations();
  1702 	AfterLoadStations();
  1702 	/* redraw the whole screen */
  1703 	/* redraw the whole screen */
  1703 	MarkWholeScreenDirty();
  1704 	MarkWholeScreenDirty();
  1704 }
  1705 }
       
  1706 
       
  1707 HalMusicDriver *_music_driver;
       
  1708 HalSoundDriver *_sound_driver;
       
  1709 HalVideoDriver *_video_driver;
       
  1710 
       
  1711 byte _dirkeys;        // 1 = left, 2 = up, 4 = right, 8 = down
       
  1712 bool _fullscreen;
       
  1713 CursorVars _cursor;
       
  1714 bool _ctrl_pressed;   // Is Ctrl pressed?
       
  1715 bool _shift_pressed;  // Is Shift pressed?
       
  1716 byte _fast_forward;
       
  1717 bool _left_button_down;
       
  1718 bool _left_button_clicked;
       
  1719 bool _right_button_down;
       
  1720 bool _right_button_clicked;
       
  1721 DrawPixelInfo _screen;
       
  1722 bool _exit_game;
       
  1723 bool _networking;         ///< are we in networking mode?
       
  1724 byte _game_mode;
       
  1725 byte _pause;
       
  1726 int _pal_first_dirty;
       
  1727 int _pal_last_dirty;