summaryrefslogtreecommitdiff
path: root/ttd.c
diff options
context:
space:
mode:
authorDarkvater <darkvater@openttd.org>2005-06-02 19:30:21 +0000
committerDarkvater <darkvater@openttd.org>2005-06-02 19:30:21 +0000
commitb438b1248cc14d0a290c36ad486cc34bb6b6f81b (patch)
tree243253abb7dad04a2f8a7113f263dfec2836344e /ttd.c
parent62c96b52a0d3ff1bafd6a0ef84c2c807f725f2a6 (diff)
downloadopenttd-b438b1248cc14d0a290c36ad486cc34bb6b6f81b.tar.xz
(svn r2397) - CodeChange: rename all "ttd" files to "openttd" files.
Diffstat (limited to 'ttd.c')
-rw-r--r--ttd.c1415
1 files changed, 0 insertions, 1415 deletions
diff --git a/ttd.c b/ttd.c
deleted file mode 100644
index ba8f241f0..000000000
--- a/ttd.c
+++ /dev/null
@@ -1,1415 +0,0 @@
-#include "stdafx.h"
-#include "string.h"
-#include "table/strings.h"
-#include "debug.h"
-#include "strings.h"
-#include "map.h"
-#include "tile.h"
-
-#define VARDEF
-#include "ttd.h"
-#include "mixer.h"
-#include "spritecache.h"
-#include "gfx.h"
-#include "gui.h"
-#include "station.h"
-#include "vehicle.h"
-#include "viewport.h"
-#include "window.h"
-#include "player.h"
-#include "command.h"
-#include "town.h"
-#include "industry.h"
-#include "news.h"
-#include "engine.h"
-#include "sound.h"
-#include "economy.h"
-#include "fileio.h"
-#include "hal.h"
-#include "airport.h"
-#include "ai.h"
-#include "console.h"
-#include "screenshot.h"
-#include "network.h"
-#include "signs.h"
-#include "depot.h"
-#include "waypoint.h"
-
-#include <stdarg.h>
-
-void GenerateWorld(int mode, uint log_x, uint log_y);
-void CallLandscapeTick(void);
-void IncreaseDate(void);
-void RunOtherPlayersLoop(void);
-void DoPaletteAnimations(void);
-void MusicLoop(void);
-void ResetMusic(void);
-void InitializeStations(void);
-void DeleteAllPlayerStations(void);
-
-extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
-extern void DoStartupNewPlayer(bool is_ai);
-extern void ShowOSErrorBox(const char *buf);
-
-bool LoadSavegame(const char *filename);
-
-extern void HalGameLoop(void);
-
-uint32 _pixels_redrawn;
-bool _dbg_screen_rect;
-bool disable_computer; // We should get ride of this thing.. is only used for a debug-cheat
-static byte _os_version = 0;
-
-/* TODO: usrerror() for errors which are not of an internal nature but
- * caused by the user, i.e. missing files or fatal configuration errors.
- * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */
-
-void CDECL error(const char *s, ...) {
- va_list va;
- char buf[512];
- va_start(va, s);
- vsprintf(buf, s, va);
- va_end(va);
-
- ShowOSErrorBox(buf);
- if (_video_driver)
- _video_driver->stop();
-
- assert(0);
- exit(1);
-}
-
-void CDECL ShowInfoF(const char *str, ...)
-{
- va_list va;
- char buf[1024];
- va_start(va, str);
- vsprintf(buf, str, va);
- va_end(va);
- ShowInfo(buf);
-}
-
-char * CDECL str_fmt(const char *str, ...)
-{
- char buf[4096];
- va_list va;
- int len;
- char *p;
-
- va_start(va, str);
- len = vsprintf(buf, str, va);
- va_end(va);
- p = malloc(len + 1);
- if (p)
- memcpy(p, buf, len + 1);
- return p;
-}
-
-
-// NULL midi driver
-static const char *NullMidiStart(const char * const *parm) { return NULL; }
-static void NullMidiStop(void) {}
-static void NullMidiPlaySong(const char *filename) {}
-static void NullMidiStopSong(void) {}
-static bool NullMidiIsSongPlaying(void) { return true; }
-static void NullMidiSetVolume(byte vol) {}
-
-const HalMusicDriver _null_music_driver = {
- NullMidiStart,
- NullMidiStop,
- NullMidiPlaySong,
- NullMidiStopSong,
- NullMidiIsSongPlaying,
- NullMidiSetVolume,
-};
-
-// NULL video driver
-static void *_null_video_mem;
-static const char *NullVideoStart(const char * const *parm)
-{
- _screen.width = _screen.pitch = _cur_resolution[0];
- _screen.height = _cur_resolution[1];
- _null_video_mem = malloc(_cur_resolution[0]*_cur_resolution[1]);
- return NULL;
-}
-static void NullVideoStop(void) { free(_null_video_mem); }
-static void NullVideoMakeDirty(int left, int top, int width, int height) {}
-static int NullVideoMainLoop(void)
-{
- int i = 1000;
- do {
- GameLoop();
- _screen.dst_ptr = _null_video_mem;
- UpdateWindows();
- } while (--i);
- return ML_QUIT;
-}
-
-static bool NullVideoChangeRes(int w, int h) { return false; }
-static void NullVideoFullScreen(bool fs) {}
-
-const HalVideoDriver _null_video_driver = {
- NullVideoStart,
- NullVideoStop,
- NullVideoMakeDirty,
- NullVideoMainLoop,
- NullVideoChangeRes,
- NullVideoFullScreen,
-};
-
-// NULL sound driver
-static const char *NullSoundStart(const char * const *parm) { return NULL; }
-static void NullSoundStop(void) {}
-const HalSoundDriver _null_sound_driver = {
- NullSoundStart,
- NullSoundStop,
-};
-
-enum {
- DF_PRIORITY_MASK = 0xf,
-};
-
-typedef struct {
- const DriverDesc *descs;
- const char *name;
- void *var;
-} DriverClass;
-
-static DriverClass _driver_classes[] = {
- {_video_driver_descs, "video", &_video_driver},
- {_sound_driver_descs, "sound", &_sound_driver},
- {_music_driver_descs, "music", &_music_driver},
-};
-
-static const DriverDesc *GetDriverByName(const DriverDesc *dd, const char *name)
-{
- do {
- if (!strcmp(dd->name, name))
- return dd;
- } while ((++dd)->name);
- return NULL;
-}
-
-static const DriverDesc *ChooseDefaultDriver(const DriverDesc *dd)
-{
- const DriverDesc *best = NULL;
- int best_pri = -1;
- do {
- if ((int)(dd->flags&DF_PRIORITY_MASK) > best_pri && _os_version >= (byte)dd->flags) {
- best_pri = dd->flags&DF_PRIORITY_MASK;
- best = dd;
- }
- } while ((++dd)->name);
- return best;
-}
-
-
-void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize)
-{
- FILE *in;
- byte *mem;
- size_t len;
-
- in = fopen(filename, "rb");
- if (in == NULL)
- return NULL;
-
- fseek(in, 0, SEEK_END);
- len = ftell(in);
- fseek(in, 0, SEEK_SET);
- if (len > maxsize || (mem = malloc(len + 1)) == NULL) {
- fclose(in);
- return NULL;
- }
- mem[len] = 0;
- if (fread(mem, len, 1, in) != 1) {
- fclose(in);
- free(mem);
- return NULL;
- }
- fclose(in);
-
- *lenp = len;
- return mem;
-}
-
-void LoadDriver(int driver, const char *name)
-{
- const DriverClass *dc = &_driver_classes[driver];
- const DriverDesc *dd;
- const void **var;
- const void *drv;
- const char *err;
- char *parm;
- char buffer[256];
- const char *parms[32];
-
- parms[0] = NULL;
-
- if (!*name) {
- dd = ChooseDefaultDriver(dc->descs);
- } else {
- // Extract the driver name and put parameter list in parm
- ttd_strlcpy(buffer, name, sizeof(buffer));
- parm = strchr(buffer, ':');
- if (parm) {
- uint np = 0;
- // Tokenize the parm.
- do {
- *parm++ = 0;
- if (np < lengthof(parms) - 1)
- parms[np++] = parm;
- while (*parm != 0 && *parm != ',')
- parm++;
- } while (*parm == ',');
- parms[np] = NULL;
- }
- dd = GetDriverByName(dc->descs, buffer);
- if (dd == NULL)
- error("No such %s driver: %s\n", dc->name, buffer);
- }
- var = dc->var;
- if (*var != NULL) ((const HalCommonDriver*)*var)->stop();
- *var = NULL;
- drv = dd->drv;
- if ((err=((const HalCommonDriver*)drv)->start(parms)) != NULL)
- error("Unable to load driver %s(%s). The error was: %s\n", dd->name, dd->longname, err);
- *var = drv;
-}
-
-static void showhelp(void)
-{
- char buf[4096], *p;
- const DriverClass *dc = _driver_classes;
- const DriverDesc *dd;
- int i;
-
- p = strecpy(buf,
- "Command line options:\n"
- " -v drv = Set video driver (see below)\n"
- " -s drv = Set sound driver (see below)\n"
- " -m drv = Set music driver (see below)\n"
- " -r res = Set resolution (for instance 800x600)\n"
- " -h = Display this help text\n"
- " -t date = Set starting date\n"
- " -d [[fac=]lvl[,...]]= Debug mode\n"
- " -l lng = Select Language\n"
- " -e = Start Editor\n"
- " -g [savegame] = Start new/save game immediately\n"
- " -G seed = Set random seed\n"
- " -n [ip#player:port] = Start networkgame\n"
- " -D = Start dedicated server\n"
- #if !defined(__MORPHOS__) && !defined(__AMIGA__)
- " -f = Fork into the background (dedicated only)\n"
- #endif
- " -i = Force to use the DOS palette (use this if you see a lot of pink)\n"
- " -p #player = Player as #player (deprecated) (network only)\n"
- " -c config_file = Use 'config_file' instead of 'openttd.cfg'\n",
- lastof(buf)
- );
-
- for(i=0; i!=lengthof(_driver_classes); i++,dc++) {
- p += sprintf(p, "List of %s drivers:\n", dc->name);
- dd = dc->descs;
- do {
- p += sprintf(p, "%10s: %s\n", dd->name, dd->longname);
- } while ((++dd)->name);
- }
-
- ShowInfo(buf);
-}
-
-
-const char *GetDriverParam(const char * const *parm, const char *name)
-{
- const char *p;
- int len = strlen(name);
- while ((p = *parm++) != NULL) {
- if (!strncmp(p,name,len)) {
- if (p[len] == '=') return p + len + 1;
- if (p[len] == 0) return p + len;
- }
- }
- return NULL;
-}
-
-bool GetDriverParamBool(const char * const *parm, const char *name)
-{
- const char *p = GetDriverParam(parm, name);
- return p != NULL;
-}
-
-int GetDriverParamInt(const char * const *parm, const char *name, int def)
-{
- const char *p = GetDriverParam(parm, name);
- return p != NULL ? atoi(p) : def;
-}
-
-typedef struct {
- char *opt;
- int numleft;
- char **argv;
- const char *options;
- char *cont;
-} MyGetOptData;
-
-static void MyGetOptInit(MyGetOptData *md, int argc, char **argv, const char *options)
-{
- md->cont = NULL;
- md->numleft = argc;
- md->argv = argv;
- md->options = options;
-}
-
-static int MyGetOpt(MyGetOptData *md)
-{
- char *s,*r,*t;
-
- if ((s=md->cont) != NULL)
- goto md_continue_here;
-
- while(true) {
- if (--md->numleft < 0)
- return -1;
-
- s = *md->argv++;
- if (*s == '-') {
-md_continue_here:;
- s++;
- if (*s != 0) {
- // Found argument, try to locate it in options.
- if (*s == ':' || (r = strchr(md->options, *s)) == NULL) {
- // ERROR!
- return -2;
- }
- if (r[1] == ':') {
- // Item wants an argument. Check if the argument follows, or if it comes as a separate arg.
- if (!*(t = s + 1)) {
- // It comes as a separate arg. Check if out of args?
- if (--md->numleft < 0 || *(t = *md->argv) == '-') {
- // Check if item is optional?
- if (r[2] != ':')
- return -2;
- md->numleft++;
- t = NULL;
- } else {
- md->argv++;
- }
- }
- md->opt = t;
- md->cont = NULL;
- return *s;
- }
- md->opt = NULL;
- md->cont = s;
- return *s;
- }
- } else {
- // This is currently not supported.
- return -2;
- }
- }
-}
-
-
-static void ParseResolution(int res[2], char *s)
-{
- char *t = strchr(s, 'x');
- if (t == NULL) {
- ShowInfoF("Invalid resolution '%s'", s);
- return;
- }
-
- res[0] = clamp(strtoul(s, NULL, 0), 64, MAX_SCREEN_WIDTH);
- res[1] = clamp(strtoul(t + 1, NULL, 0), 64, MAX_SCREEN_HEIGHT);
-}
-
-static void InitializeDynamicVariables(void)
-{
- /* Dynamic stuff needs to be initialized somewhere... */
- _station_sort = NULL;
- _vehicle_sort = NULL;
- _town_sort = NULL;
- _industry_sort = NULL;
-}
-
-static void UnInitializeDynamicVariables(void)
-{
- /* Dynamic stuff needs to be free'd somewhere... */
- CleanPool(&_town_pool);
- CleanPool(&_industry_pool);
- CleanPool(&_station_pool);
- CleanPool(&_vehicle_pool);
- CleanPool(&_sign_pool);
- CleanPool(&_order_pool);
-
- free(_station_sort);
- free(_vehicle_sort);
- free(_town_sort);
- free(_industry_sort);
-}
-
-static void UnInitializeGame(void)
-{
- UnInitWindowSystem();
- UnInitNewgrEngines();
-
- free(_config_file);
-}
-
-static void LoadIntroGame(void)
-{
- char filename[256];
-
- _game_mode = GM_MENU;
- CLRBITS(_display_opt, DO_TRANS_BUILDINGS); // don't make buildings transparent in intro
- _opt_ptr = &_opt_newgame;
-
- GfxLoadSprites();
- LoadStringWidthTable();
-
- // Setup main window
- ResetWindowSystem();
- SetupColorsAndInitialWindow();
-
- // Generate a world.
- sprintf(filename, "%sopntitle.dat", _path.data_dir);
- if (SaveOrLoad(filename, SL_LOAD) != SL_OK) {
-#if defined SECOND_DATA_DIR
- sprintf(filename, "%sopntitle.dat", _path.second_data_dir);
- if (SaveOrLoad(filename, SL_LOAD) != SL_OK)
-#endif
- GenerateWorld(1, 6, 6); // if failed loading, make empty world.
- }
-
- _pause = 0;
- _local_player = 0;
- MarkWholeScreenDirty();
-
- // Play main theme
- if (_music_driver->is_song_playing()) ResetMusic();
-}
-
-extern void DedicatedFork(void);
-extern void CheckExternalFiles(void);
-
-int ttd_main(int argc, char* argv[])
-{
- MyGetOptData mgo;
- int i;
- bool network = false;
- char *network_conn = NULL;
- char *language = NULL;
- const char *optformat;
- char musicdriver[16], sounddriver[16], videodriver[16];
- int resolution[2] = {0,0};
- uint startdate = -1;
- bool dedicated;
-
- musicdriver[0] = sounddriver[0] = videodriver[0] = 0;
-
- _game_mode = GM_MENU;
- _switch_mode = SM_MENU;
- _switch_mode_errorstr = INVALID_STRING_ID;
- _dedicated_forks = false;
- dedicated = false;
- _config_file = NULL;
-
- // The last param of the following function means this:
- // a letter means: it accepts that param (e.g.: -h)
- // a ':' behind it means: it need a param (e.g.: -m<driver>)
- // a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
- #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
- optformat = "m:s:v:hDfn::l:eit:d::r:g::G:p:c:";
- #else
- optformat = "m:s:v:hDn::l:eit:d::r:g::G:p:c:"; // no fork option
- #endif
-
- MyGetOptInit(&mgo, argc-1, argv+1, optformat);
- while ((i = MyGetOpt(&mgo)) != -1) {
- switch(i) {
- case 'm': ttd_strlcpy(musicdriver, mgo.opt, sizeof(musicdriver)); break;
- case 's': ttd_strlcpy(sounddriver, mgo.opt, sizeof(sounddriver)); break;
- case 'v': ttd_strlcpy(videodriver, mgo.opt, sizeof(videodriver)); break;
- case 'D': {
- sprintf(musicdriver,"null");
- sprintf(sounddriver,"null");
- sprintf(videodriver,"dedicated");
- dedicated = true;
- } break;
- case 'f': {
- _dedicated_forks = true;
- }; break;
- case 'n': {
- network = true;
- if (mgo.opt)
- // Optional, you can give an IP
- network_conn = mgo.opt;
- else
- network_conn = NULL;
- } break;
- case 'r': ParseResolution(resolution, mgo.opt); break;
- case 'l': {
- language = mgo.opt;
- } break;
- case 't': {
- startdate = atoi(mgo.opt);
- } break;
- case 'd': {
-#if defined(WIN32)
- CreateConsole();
-#endif
- if (mgo.opt)
- SetDebugString(mgo.opt);
- } break;
- case 'e': _switch_mode = SM_EDITOR; break;
- case 'i': _use_dos_palette = true; break;
- case 'g':
- if (mgo.opt) {
- strcpy(_file_to_saveload.name, mgo.opt);
- _switch_mode = SM_LOAD;
- } else
- _switch_mode = SM_NEWGAME;
- break;
- case 'G':
- _random_seeds[0][0] = atoi(mgo.opt);
- break;
- case 'p': {
- int i = atoi(mgo.opt);
- // Play as an other player in network games
- if (IS_INT_INSIDE(i, 1, MAX_PLAYERS)) _network_playas = i;
- break;
- }
- case 'c':
- _config_file = strdup(mgo.opt);
- break;
- case -2:
- case 'h':
- showhelp();
- return 0;
- }
- }
-
- DeterminePaths();
- CheckExternalFiles();
-
-#ifdef UNIX
- // We must fork here, or we'll end up without some resources we need (like sockets)
- if (_dedicated_forks)
- DedicatedFork();
-#endif
-
- LoadFromConfig();
- CheckConfig();
- LoadFromHighScore();
-
- // override config?
- if (musicdriver[0]) ttd_strlcpy(_ini_musicdriver, musicdriver, sizeof(_ini_musicdriver));
- if (sounddriver[0]) ttd_strlcpy(_ini_sounddriver, sounddriver, sizeof(_ini_sounddriver));
- if (videodriver[0]) ttd_strlcpy(_ini_videodriver, videodriver, sizeof(_ini_videodriver));
- if (resolution[0]) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; }
- if (startdate != (uint)-1) _patches.starting_date = startdate;
-
- if (_dedicated_forks && !dedicated)
- _dedicated_forks = false;
-
- // enumerate language files
- InitializeLanguagePacks();
-
- // initialize screenshot formats
- InitializeScreenshotFormats();
-
- // initialize airport state machines
- InitializeAirports();
-
- /* initialize all variables that are allocated dynamically */
- InitializeDynamicVariables();
-
- // Sample catalogue
- DEBUG(misc, 1) ("Loading sound effects...");
- _os_version = GetOSVersion();
- MxInitialize(11025);
- SoundInitialize("sample.cat");
-
- // This must be done early, since functions use the InvalidateWindow* calls
- InitWindowSystem();
-
- GfxLoadSprites();
- LoadStringWidthTable();
-
- DEBUG(misc, 1) ("Loading drivers...");
- LoadDriver(SOUND_DRIVER, _ini_sounddriver);
- LoadDriver(MUSIC_DRIVER, _ini_musicdriver);
- LoadDriver(VIDEO_DRIVER, _ini_videodriver); // load video last, to prevent an empty window while sound and music loads
- _savegame_sort_order = 1; // default sorting of savegames is by date, newest first
-
-#ifdef ENABLE_NETWORK
- // initialize network-core
- NetworkStartUp();
-#endif /* ENABLE_NETWORK */
-
- _opt_ptr = &_opt_newgame;
-
- /* XXX - ugly hack, if diff_level is 9, it means we got no setting from the config file */
- if (_opt_newgame.diff_level == 9)
- SetDifficultyLevel(0, &_opt_newgame);
-
- // initialize the ingame console
- IConsoleInit();
- InitializeGUI();
- IConsoleCmdExec("exec scripts/autoexec.scr 0");
-
- InitPlayerRandoms();
-
- GenerateWorld(1, 6, 6); // Make the viewport initialization happy
-
-#ifdef ENABLE_NETWORK
- if ((network) && (_network_available)) {
- if (network_conn != NULL) {
- const char *port = NULL;
- const char *player = NULL;
- uint16 rport;
-
- rport = NETWORK_DEFAULT_PORT;
-
- ParseConnectionString(&player, &port, network_conn);
-
- if (player != NULL) _network_playas = atoi(player);
- if (port != NULL) rport = atoi(port);
-
- LoadIntroGame();
- _switch_mode = SM_NONE;
- NetworkClientConnectGame(network_conn, rport);
- }
- }
-#endif /* ENABLE_NETWORK */
-
- while (_video_driver->main_loop() == ML_SWITCHDRIVER) {}
-
- JoinOTTDThread();
- IConsoleFree();
-
-#ifdef ENABLE_NETWORK
- if (_network_available) {
- // Shut down the network and close any open connections
- NetworkDisconnect();
- NetworkUDPClose();
- NetworkShutDown();
- }
-#endif /* ENABLE_NETWORK */
-
- _video_driver->stop();
- _music_driver->stop();
- _sound_driver->stop();
-
- SaveToConfig();
- SaveToHighScore();
-
- // uninitialize airport state machines
- UnInitializeAirports();
-
- /* uninitialize variables that are allocated dynamic */
- UnInitializeDynamicVariables();
-
- /* Close all and any open filehandles */
- FioCloseAll();
- UnInitializeGame();
-
- return 0;
-}
-
-static void ShowScreenshotResult(bool b)
-{
- if (b) {
- SetDParam(0, STR_SPEC_SCREENSHOT_NAME);
- ShowErrorMessage(INVALID_STRING_ID, STR_031B_SCREENSHOT_SUCCESSFULLY, 0, 0);
- } else {
- ShowErrorMessage(INVALID_STRING_ID, STR_031C_SCREENSHOT_FAILED, 0, 0);
- }
-
-}
-
-static void MakeNewGame(void)
-{
- _game_mode = GM_NORMAL;
-
- // Copy in game options
- _opt_ptr = &_opt;
- memcpy(_opt_ptr, &_opt_newgame, sizeof(GameOptions));
-
- GfxLoadSprites();
-
- // Reinitialize windows
- ResetWindowSystem();
- LoadStringWidthTable();
-
- SetupColorsAndInitialWindow();
-
- // Randomize world
- GenerateWorld(0, _patches.map_x, _patches.map_y);
-
- // In a dedicated server, the server does not play
- if (_network_dedicated) {
- _local_player = OWNER_SPECTATOR;
- } else {
- // Create a single player
- DoStartupNewPlayer(false);
-
- _local_player = 0;
- }
-
- MarkWholeScreenDirty();
-}
-
-static void MakeNewEditorWorld(void)
-{
- _game_mode = GM_EDITOR;
-
- // Copy in game options
- _opt_ptr = &_opt;
- memcpy(_opt_ptr, &_opt_newgame, sizeof(GameOptions));
-
- GfxLoadSprites();
-
- // Re-init the windowing system
- ResetWindowSystem();
-
- // Create toolbars
- SetupColorsAndInitialWindow();
-
- // Startup the game system
- GenerateWorld(1, _patches.map_x, _patches.map_y);
-
- _local_player = OWNER_NONE;
- MarkWholeScreenDirty();
-}
-
-void StartupPlayers(void);
-void StartupDisasters(void);
-
-/**
- * Start Scenario starts a new game based on a scenario.
- * Eg 'New Game' --> select a preset scenario
- * This starts a scenario based on your current difficulty settings
- */
-static void StartScenario(void)
-{
- _game_mode = GM_NORMAL;
-
- // invalid type
- if (_file_to_saveload.mode == SL_INVALID) {
- printf("Savegame is obsolete or invalid format: %s\n", _file_to_saveload.name);
- ShowErrorMessage(_error_message, STR_4009_GAME_LOAD_FAILED, 0, 0);
- _game_mode = GM_MENU;
- return;
- }
-
- GfxLoadSprites();
-
- // Reinitialize windows
- ResetWindowSystem();
- LoadStringWidthTable();
-
- SetupColorsAndInitialWindow();
-
- // Load game
- if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode) != SL_OK) {
- LoadIntroGame();
- ShowErrorMessage(_error_message, STR_4009_GAME_LOAD_FAILED, 0, 0);
- }
-
- _opt_ptr = &_opt;
- memcpy(&_opt_ptr->diff, &_opt_newgame.diff, sizeof(GameDifficulty));
- _opt.diff_level = _opt_newgame.diff_level;
-
- // Inititalize data
- StartupPlayers();
- StartupEngines();
- StartupDisasters();
-
- _local_player = 0;
-
- MarkWholeScreenDirty();
-}
-
-bool SafeSaveOrLoad(const char *filename, int mode, int newgm)
-{
- byte ogm = _game_mode;
- int r;
-
- _game_mode = newgm;
- r = SaveOrLoad(filename, mode);
- if (r == SL_REINIT) {
- if (ogm == GM_MENU)
- LoadIntroGame();
- else if (ogm == GM_EDITOR)
- MakeNewEditorWorld();
- else
- MakeNewGame();
- return false;
- } else if (r != SL_OK) {
- _game_mode = ogm;
- return false;
- } else
- return true;
-}
-
-void SwitchMode(int new_mode)
-{
- _in_state_game_loop = true;
-
-#ifdef ENABLE_NETWORK
- // If we are saving something, the network stays in his current state
- if (new_mode != SM_SAVE) {
- // If the network is active, make it not-active
- if (_networking) {
- if (_network_server && (new_mode == SM_LOAD || new_mode == SM_NEWGAME)) {
- NetworkReboot();
- NetworkUDPClose();
- } else {
- NetworkDisconnect();
- NetworkUDPClose();
- }
- }
-
- // If we are a server, we restart the server
- if (_is_network_server) {
- // But not if we are going to the menu
- if (new_mode != SM_MENU) {
- NetworkServerStart();
- } else {
- // This client no longer wants to be a network-server
- _is_network_server = false;
- }
- }
- }
-#endif /* ENABLE_NETWORK */
-
- switch (new_mode) {
- case SM_EDITOR: /* Switch to scenario editor */
- MakeNewEditorWorld();
- break;
-
- case SM_NEWGAME: /* New Game --> 'Random game' */
-#ifdef ENABLE_NETWORK
- if (_network_server)
- snprintf(_network_game_info.map_name, 40, "Random");
-#endif /* ENABLE_NETWORK */
- MakeNewGame();
- break;
-
- case SM_START_SCENARIO: /* New Game --> Choose one of the preset scenarios */
- StartScenario();
- break;
-
- case SM_LOAD: { /* Load game, Play Scenario */
- _opt_ptr = &_opt;
-
- _error_message = INVALID_STRING_ID;
- if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) {
- LoadIntroGame();
- ShowErrorMessage(_error_message, STR_4009_GAME_LOAD_FAILED, 0, 0);
- } else {
- _local_player = 0;
- DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
-#ifdef ENABLE_NETWORK
- if (_network_server)
- snprintf(_network_game_info.map_name, 40, "Loaded game");
-#endif /* ENABLE_NETWORK */
- }
- break;
- }
-
- case SM_LOAD_SCENARIO: { /* Load scenario from scenario editor */
- int i;
-
- if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR)) {
- _opt_ptr = &_opt;
-
- _local_player = OWNER_NONE;
- _generating_world = true;
- // delete all players.
- for (i = 0; i != MAX_PLAYERS; i++) {
- ChangeOwnershipOfPlayerItems(i, 0xff);
- _players[i].is_active = false;
- }
- _generating_world = false;
- // delete all stations owned by a player
- DeleteAllPlayerStations();
-
-#ifdef ENABLE_NETWORK
- if (_network_server)
- snprintf(_network_game_info.map_name, 40, "Loaded scenario");
-#endif /* ENABLE_NETWORK */
- } else
- ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
-
- break;
- }
-
-
- case SM_MENU: /* Switch to game intro menu */
- LoadIntroGame();
- break;
-
- case SM_SAVE: /* Save game */
- if (SaveOrLoad(_file_to_saveload.name, SL_SAVE) != SL_OK)
- ShowErrorMessage(INVALID_STRING_ID, STR_4007_GAME_SAVE_FAILED, 0, 0);
- else
- DeleteWindowById(WC_SAVELOAD, 0);
- break;
-
- case SM_GENRANDLAND: /* Generate random land within scenario editor */
- GenerateWorld(2, _patches.map_x, _patches.map_y);
- // XXX: set date
- _local_player = OWNER_NONE;
- MarkWholeScreenDirty();
- break;
- }
-
- if (_switch_mode_errorstr != INVALID_STRING_ID)
- ShowErrorMessage(INVALID_STRING_ID,_switch_mode_errorstr,0,0);
-
- _in_state_game_loop = false;
-}
-
-
-// State controlling game loop.
-// The state must not be changed from anywhere
-// but here.
-// That check is enforced in DoCommand.
-void StateGameLoop(void)
-{
- // dont execute the state loop during pause
- if (_pause) return;
-
- _in_state_game_loop = true;
- // _frame_counter is increased somewhere else when in network-mode
- // Sidenote: _frame_counter is ONLY used for _savedump in non-MP-games
- // Should that not be deleted? If so, the next 2 lines can also be deleted
- if (!_networking)
- _frame_counter++;
-
- if (_savedump_path[0] && (uint)_frame_counter >= _savedump_first && (uint)(_frame_counter -_savedump_first) % _savedump_freq == 0 ) {
- char buf[100];
- sprintf(buf, "%s%.5d.sav", _savedump_path, _frame_counter);
- SaveOrLoad(buf, SL_SAVE);
- if ((uint)_frame_counter >= _savedump_last) exit(1);
- }
-
- if (_game_mode == GM_EDITOR) {
- RunTileLoop();
- CallVehicleTicks();
- CallLandscapeTick();
- CallWindowTickEvent();
- NewsLoop();
- } else {
- // All these actions has to be done from OWNER_NONE
- // for multiplayer compatibility
- uint p = _current_player;
- _current_player = OWNER_NONE;
-
- AnimateAnimatedTiles();
- IncreaseDate();
- RunTileLoop();
- CallVehicleTicks();
- CallLandscapeTick();
-
- // To bad the AI does not work in multiplayer, because states are not saved
- // perfectly
- if (!disable_computer && !_networking)
- RunOtherPlayersLoop();
-
- CallWindowTickEvent();
- NewsLoop();
- _current_player = p;
- }
-
- _in_state_game_loop = false;
-}
-
-static void DoAutosave(void)
-{
- char buf[200];
-
- if (_patches.keep_all_autosave && _local_player != OWNER_SPECTATOR) {
- const Player *p = DEREF_PLAYER(_local_player);
- char *s;
- sprintf(buf, "%s%s", _path.autosave_dir, PATHSEP);
-
- SetDParam(0, p->name_1);
- SetDParam(1, p->name_2);
- SetDParam(2, _date);
- s = (char*)GetString(buf + strlen(_path.autosave_dir) + strlen(PATHSEP), STR_4004);
- strcpy(s, ".sav");
- } else { /* Save a maximum of 15 autosaves */
- int n = _autosave_ctr;
- _autosave_ctr = (_autosave_ctr + 1) & 15;
- sprintf(buf, "%s%sautosave%d.sav", _path.autosave_dir, PATHSEP, n);
- }
-
- DEBUG(misc, 2) ("Autosaving to %s", buf);
- if (SaveOrLoad(buf, SL_SAVE) != 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).scrollpos_x += x << w->viewport->zoom;
- WP(w,vp_d).scrollpos_y += y << w->viewport->zoom;
- }
-}
-
-static const int8 scrollamt[16][2] = {
- { 0, 0},
- {-2, 0}, // 1:left
- { 0,-2}, // 2:up
- {-2,-1}, // 3:left + up
- { 2, 0}, // 4:right
- { 0, 0}, // 5:left + right
- { 2,-1}, // 6:right + up
- { 0,-2}, // 7:left + right + up = up
- { 0 ,2}, // 8:down
- {-2 ,1}, // 9:down+left
- { 0, 0}, // 10:impossible
- {-2, 0}, // 11:left + up + down = left
- { 2, 1}, // 12:down+right
- { 0, 2}, // 13:left + right + down = down
- { 0,-2}, // 14:left + right + up = up
- { 0, 0}, // 15:impossible
-};
-
-static void HandleKeyScrolling(void)
-{
- if (_dirkeys && !_no_scroll) {
- int factor = _shift_pressed ? 50 : 10;
- ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
- }
-}
-
-void GameLoop(void)
-{
- int m;
-
- // autosave game?
- if (_do_autosave) {
- _do_autosave = false;
- DoAutosave();
- RedrawAutosave();
- }
-
- // handle scrolling of the main window
- if (_dirkeys) HandleKeyScrolling();
-
- // make a screenshot?
- if ((m=_make_screenshot) != 0) {
- _make_screenshot = 0;
- switch(m) {
- case 1: // make small screenshot
- UndrawMouseCursor();
- ShowScreenshotResult(MakeScreenshot());
- break;
- case 2: // make large screenshot
- ShowScreenshotResult(MakeWorldScreenshot(-(int)MapMaxX() * 32, 0, MapMaxX() * 64, MapSizeY() * 32, 0));
- break;
- }
- }
-
- // switch game mode?
- if ((m=_switch_mode) != SM_NONE) {
- _switch_mode = SM_NONE;
- SwitchMode(m);
- }
-
- IncreaseSpriteLRU();
- InteractiveRandom();
-
- if (_scroller_click_timeout > 3)
- _scroller_click_timeout -= 3;
- else
- _scroller_click_timeout = 0;
-
- _caret_timer += 3;
- _timer_counter+=8;
- CursorTick();
-
-#ifdef ENABLE_NETWORK
- // Check for UDP stuff
- NetworkUDPGameLoop();
-
- if (_networking) {
- // 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 && _display_opt&DO_FULL_ANIMATION)
- DoPaletteAnimations();
-
- if (!_pause || _cheats.build_in_pause.value)
- MoveAllTextEffects();
-
- InputLoop();
-
- MusicLoop();
-}
-
-void BeforeSaveGame(void)
-{
- Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
-
- if (w != NULL) {
- _saved_scrollpos_x = WP(w,vp_d).scrollpos_x;
- _saved_scrollpos_y = WP(w,vp_d).scrollpos_y;
- _saved_scrollpos_zoom = w->viewport->zoom;
- }
-}
-
-static void ConvertTownOwner(void)
-{
- uint tile;
-
- for (tile = 0; tile != MapSize(); tile++) {
- if (IsTileType(tile, MP_STREET)) {
- if ((_map5[tile] & 0xF0) == 0x10 && _map3_lo[tile] & 0x80)
- _map3_lo[tile] = OWNER_TOWN;
-
- if (_map_owner[tile] & 0x80)
- _map_owner[tile] = OWNER_TOWN;
- } else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
- if (_map_owner[tile] & 0x80)
- _map_owner[tile] = OWNER_TOWN;
- }
- }
-}
-
-// before savegame version 4, the name of the company determined if it existed
-static void CheckIsPlayerActive(void)
-{
- 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(void)
-{
- Town *t;
- FOR_ALL_TOWNS(t) if (t->xy != 0) {
- t->exclusivity=(byte)-1;
- }
-
- /* 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
- one player, but for all others, then give him exclusivity.
- */
-}
-
-const byte convert_currency[] = {
- 0, 1, 12, 8, 3,
- 10, 14, 19, 4, 5,
- 9, 11, 13, 6, 17,
- 16, 22, 21, 7, 15,
- 18, 2, 20, };
-
-// since savegame version 4.2 the currencies are arranged differently
-static void UpdateCurrencies(void)
-{
- _opt.currency = convert_currency[_opt.currency];
-}
-
-/* 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(void)
-{
- uint i;
-
- for (i = 0; i < MapMaxY(); ++i)
- SetTileType(i * MapSizeX() + MapMaxX(), MP_VOID);
- for (i = 0; i < MapSizeX(); ++i)
- SetTileType(MapSizeX() * MapMaxY() + i, MP_VOID);
-}
-
-// since savegame version 6.0 each sign has an "owner", signs without owner (from old games are set to 255)
-static void UpdateSignOwner(void)
-{
- SignStruct *ss;
- FOR_ALL_SIGNS(ss) {
- ss->owner = OWNER_NONE; // no owner
- }
-}
-
-extern void UpdateOldAircraft( void );
-extern void UpdateOilRig( void );
-
-bool AfterLoadGame(uint version)
-{
- Window *w;
- ViewPort *vp;
-
- // in version 2.1 of the savegame, town owner was unified.
- if (version <= 0x200) {
- ConvertTownOwner();
- }
-
- // from version 4.1 of the savegame, exclusive rights are stored at towns
- if (version <= 0x400) {
- UpdateExclusiveRights();
- }
-
- // from version 4.2 of the savegame, currencies are in a different order
- if (version <= 0x401) {
- UpdateCurrencies();
- }
-
- // from version 6.0 of the savegame, signs have an "owner"
- if (version <= 0x600) {
- UpdateSignOwner();
- }
-
- /* In old version there seems to be a problem that water is owned by
- OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current
- (0x402) version, so I just check when versions are older, and then
- walk through the whole map.. */
- if (version <= 0x402) {
- TileIndex tile = TILE_XY(0,0);
- uint w = MapSizeX();
- uint h = MapSizeY();
-
- BEGIN_TILE_LOOP(tile_cur, w, h, tile)
- if (IsTileType(tile_cur, MP_WATER) && _map_owner[tile_cur] >= MAX_PLAYERS)
- _map_owner[tile_cur] = OWNER_WATER;
- END_TILE_LOOP(tile_cur, w, h, tile)
- }
-
- // convert road side to my format.
- if (_opt.road_side) _opt.road_side = 1;
-
- // Load the sprites
- GfxLoadSprites();
-
- // Update current year
- SetDate(_date);
-
- // reinit the landscape variables (landscape might have changed)
- InitializeLandscapeVariables(true);
-
- // Update all vehicles
- AfterLoadVehicles();
-
- // Update all waypoints
- if (version < 0x0C00)
- FixOldWaypoints();
-
- UpdateAllWaypointSigns();
-
- // in version 2.2 of the savegame, we have new airports
- if (version <= 0x201) {
- UpdateOldAircraft();
- }
-
- UpdateAllStationVirtCoord();
-
- // Setup town coords
- AfterLoadTown();
- UpdateAllSignVirtCoords();
-
- // make sure there is a town in the game
- if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, (uint)-1))
- {
- _error_message = STR_NO_TOWN_IN_SCENARIO;
- return false;
- }
-
- // Initialize windows
- ResetWindowSystem();
- SetupColorsAndInitialWindow();
-
- w = FindWindowById(WC_MAIN_WINDOW, 0);
-
- WP(w,vp_d).scrollpos_x = _saved_scrollpos_x;
- WP(w,vp_d).scrollpos_y = _saved_scrollpos_y;
-
- vp = w->viewport;
- vp->zoom = _saved_scrollpos_zoom;
- vp->virtual_width = vp->width << vp->zoom;
- vp->virtual_height = vp->height << vp->zoom;
-
-
- // in version 4.0 of the savegame, is_active was introduced to determine
- // if a player does exist, rather then checking name_1
- if (version <= 0x400) {
- CheckIsPlayerActive();
- }
-
- // the void tiles on the southern border used to belong to a wrong class.
- if (version <= 0x402)
- UpdateVoidTiles();
-
- // If Load Scenario / New (Scenario) Game is used,
- // a player does not exist yet. So create one here.
- // 1 exeption: network-games. Those can have 0 players
- // But this exeption is not true for network_servers!
- if (!_players[0].is_active && (!_networking || (_networking && _network_server)))
- DoStartupNewPlayer(false);
-
- DoZoomInOutWindow(ZOOM_NONE, w); // update button status
- MarkWholeScreenDirty();
-
- //In 5.1, Oilrigs have been moved (again)
- if (version <= 0x500) {
- UpdateOilRig();
- }
-
- if (version <= 0x600) {
- BEGIN_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0) {
- if (IsTileType(tile, MP_HOUSE)) {
- _map3_hi[tile] = _map2[tile];
- //XXX magic
- SetTileType(tile, MP_VOID);
- _map2[tile] = ClosestTownFromTile(tile,(uint)-1)->index;
- SetTileType(tile, MP_HOUSE);
- } else if (IsTileType(tile, MP_STREET)) {
- //XXX magic
- SetTileType(tile, MP_VOID);
- _map3_hi[tile] |= (_map2[tile] << 4);
- if ( _map_owner[tile] == OWNER_TOWN)
- _map2[tile] = ClosestTownFromTile(tile,(uint)-1)->index;
- else
- _map2[tile] = 0;
- SetTileType(tile, MP_STREET);
- }
- } END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
- }
-
- if (version < 0x900) {
- Town *t;
- FOR_ALL_TOWNS(t) {
- UpdateTownMaxPass(t);
- }
- }
-
- return true;
-}