00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "functions.h"
00008 #include "landscape.h"
00009 #include "company_func.h"
00010 #include "variables.h"
00011 #include "thread.h"
00012 #include "command_func.h"
00013 #include "genworld.h"
00014 #include "gfxinit.h"
00015 #include "window_func.h"
00016 #include "network/network.h"
00017 #include "heightmap.h"
00018 #include "viewport_func.h"
00019 #include "gfx_func.h"
00020 #include "date_func.h"
00021 #include "core/random_func.hpp"
00022 #include "engine_func.h"
00023 #include "newgrf_storage.h"
00024 #include "water.h"
00025 #include "blitter/factory.hpp"
00026 #include "tilehighlight_func.h"
00027 #include "saveload/saveload.h"
00028 #include "void_map.h"
00029 #include "settings_type.h"
00030 #include "town.h"
00031
00032 #include "table/sprites.h"
00033
00034 void GenerateClearTile();
00035 void GenerateIndustries();
00036 void GenerateUnmovables();
00037 void GenerateTrees();
00038
00039 void StartupEconomy();
00040 void StartupCompanies();
00041 void StartupDisasters();
00042
00043 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
00044
00045
00046
00047
00048
00049 gw_info _gw;
00050
00052 ThreadMutex *_genworld_mapgen_mutex = ThreadMutex::New();
00054 ThreadMutex *_genworld_paint_mutex = ThreadMutex::New();
00055
00059 bool IsGenerateWorldThreaded()
00060 {
00061 return _gw.threaded && !_gw.quit_thread;
00062 }
00063
00068 static void CleanupGeneration()
00069 {
00070 _generating_world = false;
00071
00072 if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
00073
00074 if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
00075 _gw.active = false;
00076 _gw.proc = NULL;
00077 _gw.abortp = NULL;
00078 _gw.threaded = false;
00079
00080 DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
00081 MarkWholeScreenDirty();
00082 _genworld_mapgen_mutex->EndCritical();
00083 }
00084
00088 static void _GenerateWorld(void *arg)
00089 {
00090 try {
00091 _generating_world = true;
00092 _genworld_mapgen_mutex->BeginCritical();
00093 if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
00094
00095 if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00096 _random.SetSeed(_settings_game.game_creation.generation_seed);
00097 SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
00098 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
00099
00100 IncreaseGeneratingWorldProgress(GWP_MAP_INIT);
00101
00102 StartupEconomy();
00103
00104
00105 if (_gw.mode == GW_EMPTY) {
00106 SetGeneratingWorldProgress(GWP_UNMOVABLE, 1);
00107
00108
00109 if (_settings_game.construction.freeform_edges) {
00110 for (uint row = 0; row < MapSizeY(); row++) MakeVoid(TileXY(0, row));
00111 for (uint col = 0; col < MapSizeX(); col++) MakeVoid(TileXY(col, 0));
00112 }
00113
00114
00115 if (_game_mode != GM_MENU) FlatEmptyWorld(_settings_game.game_creation.se_flat_world_height);
00116
00117 ConvertGroundTilesIntoWaterTiles();
00118 IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
00119 } else {
00120 GenerateLandscape(_gw.mode);
00121 GenerateClearTile();
00122
00123
00124 if (_game_mode != GM_EDITOR) {
00125 if (!GenerateTowns(_settings_game.economy.town_layout)) {
00126 HandleGeneratingWorldAbortion();
00127 return;
00128 }
00129 GenerateIndustries();
00130 GenerateUnmovables();
00131 GenerateTrees();
00132 }
00133 }
00134
00135 ClearStorageChanges(true);
00136
00137
00138 SetGeneratingWorldProgress(GWP_GAME_INIT, 3);
00139 StartupCompanies();
00140 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00141 StartupEngines();
00142 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00143 StartupDisasters();
00144 _generating_world = false;
00145
00146
00147 if (_gw.mode != GW_EMPTY) {
00148 uint i;
00149
00150 SetGeneratingWorldProgress(GWP_RUNTILELOOP, 0x500);
00151 for (i = 0; i < 0x500; i++) {
00152 RunTileLoop();
00153 IncreaseGeneratingWorldProgress(GWP_RUNTILELOOP);
00154 }
00155 }
00156
00157 ResetObjectToPlace();
00158 _local_company = _gw.lc;
00159
00160 SetGeneratingWorldProgress(GWP_GAME_START, 1);
00161
00162 if (_gw.proc != NULL) _gw.proc();
00163 IncreaseGeneratingWorldProgress(GWP_GAME_START);
00164
00165 CleanupGeneration();
00166
00167 if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
00168 DEBUG(desync, 1, "new_map: %i\n", _settings_game.game_creation.generation_seed);
00169
00170 if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, CMD_PAUSE);
00171 if (_debug_desync_level > 0) {
00172 char name[MAX_PATH];
00173 snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
00174 SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
00175 }
00176 } catch (...) {
00177 _generating_world = false;
00178 _genworld_mapgen_mutex->EndCritical();
00179 throw;
00180 }
00181 }
00182
00187 void GenerateWorldSetCallback(gw_done_proc *proc)
00188 {
00189 _gw.proc = proc;
00190 }
00191
00196 void GenerateWorldSetAbortCallback(gw_abort_proc *proc)
00197 {
00198 _gw.abortp = proc;
00199 }
00200
00205 void WaitTillGeneratedWorld()
00206 {
00207 if (_gw.thread == NULL) return;
00208
00209 _genworld_mapgen_mutex->EndCritical();
00210 _genworld_paint_mutex->EndCritical();
00211 _gw.quit_thread = true;
00212 _gw.thread->Join();
00213 delete _gw.thread;
00214 _gw.thread = NULL;
00215 _gw.threaded = false;
00216 _genworld_mapgen_mutex->BeginCritical();
00217 _genworld_paint_mutex->BeginCritical();
00218 }
00219
00223 void AbortGeneratingWorld()
00224 {
00225 _gw.abort = true;
00226 }
00227
00231 bool IsGeneratingWorldAborted()
00232 {
00233 return _gw.abort;
00234 }
00235
00239 void HandleGeneratingWorldAbortion()
00240 {
00241
00242 _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
00243
00244 if (_gw.abortp != NULL) _gw.abortp();
00245
00246 CleanupGeneration();
00247
00248 if (_gw.thread != NULL) _gw.thread->Exit();
00249
00250 extern void SwitchToMode(SwitchMode new_mode);
00251 SwitchToMode(_switch_mode);
00252 }
00253
00260 void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y, bool reset_settings)
00261 {
00262 if (_gw.active) return;
00263 _gw.mode = mode;
00264 _gw.size_x = size_x;
00265 _gw.size_y = size_y;
00266 _gw.active = true;
00267 _gw.abort = false;
00268 _gw.abortp = NULL;
00269 _gw.lc = _local_company;
00270 _gw.quit_thread = false;
00271 _gw.threaded = true;
00272
00273
00274 SetLocalCompany(COMPANY_SPECTATOR);
00275
00276 _current_company = OWNER_NONE;
00277
00278
00279 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00280
00281 InitializeGame(_gw.size_x, _gw.size_y, false, reset_settings);
00282 PrepareGenerateWorldProgress();
00283
00284
00285 GfxLoadSprites();
00286 LoadStringWidthTable();
00287
00288
00289 InitializeLandscapeVariables(false);
00290
00291
00292 ResetWindowSystem();
00293
00294
00295 SetupColoursAndInitialWindow();
00296 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
00297
00298 if (_gw.thread != NULL) {
00299 _gw.thread->Join();
00300 delete _gw.thread;
00301 _gw.thread = NULL;
00302 }
00303
00304 if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0 ||
00305 !ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread)) {
00306 DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
00307 _gw.threaded = false;
00308 _genworld_mapgen_mutex->EndCritical();
00309 _GenerateWorld(NULL);
00310 _genworld_mapgen_mutex->BeginCritical();
00311 return;
00312 }
00313
00314
00315 DeleteAllNonVitalWindows();
00316
00317 HideVitalWindows();
00318
00319
00320 ShowGenerateWorldProgress();
00321
00322
00323 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
00324 ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
00325 }
00326 }