diff options
author | Darkvater <darkvater@openttd.org> | 2005-06-02 19:30:21 +0000 |
---|---|---|
committer | Darkvater <darkvater@openttd.org> | 2005-06-02 19:30:21 +0000 |
commit | b438b1248cc14d0a290c36ad486cc34bb6b6f81b (patch) | |
tree | 243253abb7dad04a2f8a7113f263dfec2836344e /ttd.c | |
parent | 62c96b52a0d3ff1bafd6a0ef84c2c807f725f2a6 (diff) | |
download | openttd-b438b1248cc14d0a290c36ad486cc34bb6b6f81b.tar.xz |
(svn r2397) - CodeChange: rename all "ttd" files to "openttd" files.
Diffstat (limited to 'ttd.c')
-rw-r--r-- | ttd.c | 1415 |
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; -} |