# game_core.cpp

Go to the documentation of this file.

    00001 /* $Id: game_core.cpp 25592 2013-07-12 18:54:27Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "../stdafx.h"
    00013 #include "../core/backup_type.hpp"
    00014 #include "../company_base.h"
    00015 #include "../company_func.h"
    00016 #include "../network/network.h"
    00017 #include "../window_func.h"
    00018 #include "game.hpp"
    00019 #include "game_scanner.hpp"
    00020 #include "game_config.hpp"
    00021 #include "game_instance.hpp"
    00022 #include "game_info.hpp"
    00023
    00024 /* static */ uint Game::frame_counter = 0;
    00025 /* static */ GameInfo *Game::info = NULL;
    00026 /* static */ GameInstance *Game::instance = NULL;
    00027 /* static */ GameScannerInfo *Game::scanner_info = NULL;
    00028 /* static */ GameScannerLibrary *Game::scanner_library = NULL;
    00029
    00030 /* static */ void Game::GameLoop()
    00031 {
    00032   if (_networking && !_network_server) return;
    00033   if (Game::instance == NULL) return;
    00034
    00035   Game::frame_counter++;
    00036
    00037   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
    00038   cur_company.Change(OWNER_DEITY);
    00039   Game::instance->GameLoop();
    00040   cur_company.Restore();
    00041
    00042   /* Occasionally collect garbage */
    00043   if ((Game::frame_counter & 255) == 0) {
    00044     Game::instance->CollectGarbage();
    00045   }
    00046 }
    00047
    00048 /* static */ void Game::Initialize()
    00049 {
    00050   if (Game::instance != NULL) Game::Uninitialize(true);
    00051
    00052   Game::frame_counter = 0;
    00053
    00054   if (Game::scanner_info == NULL) {
    00055     TarScanner::DoScan(TarScanner::GAME);
    00056     Game::scanner_info = new GameScannerInfo();
    00057     Game::scanner_info->Initialize();
    00058     Game::scanner_library = new GameScannerLibrary();
    00059     Game::scanner_library->Initialize();
    00060   }
    00061 }
    00062
    00063 /* static */ void Game::StartNew()
    00064 {
    00065   if (Game::instance != NULL) return;
    00066
    00067   /* Clients shouldn't start GameScripts */
    00068   if (_networking && !_network_server) return;
    00069
    00070   GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
    00071   GameInfo *info = config->GetInfo();
    00072   if (info == NULL) return;
    00073
    00074   config->AnchorUnchangeableSettings();
    00075
    00076   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
    00077   cur_company.Change(OWNER_DEITY);
    00078
    00079   Game::info = info;
    00080   Game::instance = new GameInstance();
    00081   Game::instance->Initialize(info);
    00082
    00083   cur_company.Restore();
    00084
    00085   InvalidateWindowData(WC_AI_DEBUG, 0, -1);
    00086 }
    00087
    00088 /* static */ void Game::Uninitialize(bool keepConfig)
    00089 {
    00090   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
    00091
    00092   delete Game::instance;
    00093   Game::instance = NULL;
    00094   Game::info = NULL;
    00095
    00096   cur_company.Restore();
    00097
    00098   if (keepConfig) {
    00099     Rescan();
    00100   } else {
    00101     delete Game::scanner_info;
    00102     delete Game::scanner_library;
    00103     Game::scanner_info = NULL;
    00104     Game::scanner_library = NULL;
    00105
    00106     if (_settings_game.game_config != NULL) {
    00107       delete _settings_game.game_config;
    00108       _settings_game.game_config = NULL;
    00109     }
    00110     if (_settings_newgame.game_config != NULL) {
    00111       delete _settings_newgame.game_config;
    00112       _settings_newgame.game_config = NULL;
    00113     }
    00114   }
    00115 }
    00116
    00117 /* static */ void Game::Pause()
    00118 {
    00119   if (Game::instance != NULL) Game::instance->Pause();
    00120 }
    00121
    00122 /* static */ void Game::Unpause()
    00123 {
    00124   if (Game::instance != NULL) Game::instance->Unpause();
    00125 }
    00126
    00127 /* static */ bool Game::IsPaused()
    00128 {
    00129   return Game::instance != NULL? Game::instance->IsPaused() : false;
    00130 }
    00131
    00132 /* static */ void Game::NewEvent(ScriptEvent *event)
    00133 {
    00134   /* AddRef() and Release() need to be called at least once, so do it here */
    00135   event->AddRef();
    00136
    00137   /* Clients should ignore events */
    00138   if (_networking && !_network_server) {
    00139     event->Release();
    00140     return;
    00141   }
    00142
    00143   /* Check if Game instance is alive */
    00144   if (Game::instance == NULL) {
    00145     event->Release();
    00146     return;
    00147   }
    00148
    00149   /* Queue the event */
    00150   Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
    00151   Game::instance->InsertEvent(event);
    00152   cur_company.Restore();
    00153
    00154   event->Release();
    00155 }
    00156
    00157 /* static */ void Game::ResetConfig()
    00158 {
    00159   /* Check for both newgame as current game if we can reload the GameInfo inside
    00160    *  the GameConfig. If not, remove the Game from the list. */
    00161   if (_settings_game.game_config != NULL && _settings_game.game_config->HasScript()) {
    00162     if (!_settings_game.game_config->ResetInfo(true)) {
    00163       DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
    00164       _settings_game.game_config->Change(NULL);
    00165       if (Game::instance != NULL) {
    00166         delete Game::instance;
    00167         Game::instance = NULL;
    00168         Game::info = NULL;
    00169       }
    00170     } else if (Game::instance != NULL) {
    00171       Game::info = _settings_game.game_config->GetInfo();
    00172     }
    00173   }
    00174   if (_settings_newgame.game_config != NULL && _settings_newgame.game_config->HasScript()) {
    00175     if (!_settings_newgame.game_config->ResetInfo(false)) {
    00176       DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
    00177       _settings_newgame.game_config->Change(NULL);
    00178     }
    00179   }
    00180 }
    00181
    00182 /* static */ void Game::Rescan()
    00183 {
    00184   TarScanner::DoScan(TarScanner::GAME);
    00185
    00186   Game::scanner_info->RescanDir();
    00187   Game::scanner_library->RescanDir();
    00188   ResetConfig();
    00189
    00190   InvalidateWindowData(WC_AI_LIST, 0, 1);
    00191   SetWindowClassesDirty(WC_AI_DEBUG);
    00192   InvalidateWindowClassesData(WC_AI_SETTINGS);
    00193 }
    00194
    00195
    00196 /* static */ void Game::Save()
    00197 {
    00198   if (Game::instance != NULL && (!_networking || _network_server)) {
    00199     Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
    00200     Game::instance->Save();
    00201     cur_company.Restore();
    00202   } else {
    00203     GameInstance::SaveEmpty();
    00204   }
    00205 }
    00206
    00207 /* static */ void Game::Load(int version)
    00208 {
    00209   if (Game::instance != NULL && (!_networking || _network_server)) {
    00210     Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
    00211     Game::instance->Load(version);
    00212     cur_company.Restore();
    00213   } else {
    00214     /* Read, but ignore, the load data */
    00215     GameInstance::LoadEmpty();
    00216   }
    00217 }
    00218
    00219 /* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only)
    00220 {
    00221   return Game::scanner_info->GetConsoleList(p, last, newest_only);
    00222 }
    00223
    00224 /* static */ char *Game::GetConsoleLibraryList(char *p, const char *last)
    00225 {
    00226    return Game::scanner_library->GetConsoleList(p, last, true);
    00227 }
    00228
    00229 /* static */ const ScriptInfoList *Game::GetInfoList()
    00230 {
    00231   return Game::scanner_info->GetInfoList();
    00232 }
    00233
    00234 /* static */ const ScriptInfoList *Game::GetUniqueInfoList()
    00235 {
    00236   return Game::scanner_info->GetUniqueInfoList();
    00237 }
    00238
    00239 /* static */ GameInfo *Game::FindInfo(const char *name, int version, bool force_exact_match)
    00240 {
    00241   return Game::scanner_info->FindInfo(name, version, force_exact_match);
    00242 }
    00243
    00244 /* static */ GameLibrary *Game::FindLibrary(const char *library, int version)
    00245 {
    00246   return Game::scanner_library->FindLibrary(library, version);
    00247 }
    00248
    00249 #if defined(ENABLE_NETWORK)
    00250
    00257 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
    00258 {
    00259   return Game::scanner_info->HasScript(ci, md5sum);
    00260 }
    00261
    00262 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
    00263 {
    00264   return Game::scanner_library->HasScript(ci, md5sum);
    00265 }
    00266
    00267 #endif /* defined(ENABLE_NETWORK) */
    00268
    00269 /* static */ GameScannerInfo *Game::GetScannerInfo()
    00270 {
    00271   return Game::scanner_info;
    00272 }
    00273 /* static */ GameScannerLibrary *Game::GetScannerLibrary()
    00274 {
    00275   return Game::scanner_library;
    00276 }