game_core.cpp

Go to the documentation of this file.
00001 /* $Id$ */
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 "../map_func.h"
00019 #include "game.hpp"
00020 #include "game_scanner.hpp"
00021 #include "game_config.hpp"
00022 #include "game_instance.hpp"
00023 #include "game_info.hpp"
00024 
00025 /* static */ uint Game::frame_counter = 0;
00026 /* static */ GameInfo *Game::info = NULL;
00027 /* static */ GameInstance *Game::instance = NULL;
00028 /* static */ GameScannerInfo *Game::scanner_info = NULL;
00029 /* static */ GameScannerLibrary *Game::scanner_library = NULL;
00030 
00031 /* static */ const char *Game::GetMainScript()
00032 {
00033     return Game::info->GetMainScript();
00034 }
00035 
00036 /* static */ void Game::GameLoop()
00037 {
00038   if (_networking && !_network_server) return;
00039   if (Game::instance == NULL) return;
00040 
00041   Game::frame_counter++;
00042   
00043   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
00044   cur_company.Change(OWNER_DEITY);
00045   Game::instance->GameLoop();
00046   cur_company.Restore();
00047 
00048   /* Occasionally collect garbage */
00049   if ((Game::frame_counter & 255) == 0) {
00050     Game::instance->CollectGarbage();
00051   }
00052 }
00053 
00054 /* static */ void Game::Initialize()
00055 {
00056   if (Game::instance != NULL) Game::Uninitialize(true);
00057 
00058   Game::frame_counter = 0;
00059 
00060   if (Game::scanner_info == NULL) {
00061     TarScanner::DoScan(TarScanner::GAME);
00062     Game::scanner_info = new GameScannerInfo();
00063     Game::scanner_info->Initialize();
00064     Game::scanner_library = new GameScannerLibrary();
00065     Game::scanner_library->Initialize();
00066   }
00067 }
00068 
00069 /* static */ void Game::StartNew()
00070 {
00071   if (Game::instance != NULL) return;
00072 
00073   /* Clients shouldn't start GameScripts */
00074   if (_networking && !_network_server) return;
00075 
00076   GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
00077   GameInfo *info = config->GetInfo();
00078   if (info == NULL) return;
00079 
00080   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
00081   cur_company.Change(OWNER_DEITY);
00082 
00083   Game::info = info;
00084   Game::instance = new GameInstance();
00085   Game::instance->Initialize(info);
00086 
00087   cur_company.Restore();
00088 
00089   InvalidateWindowData(WC_AI_DEBUG, 0, -1);
00090 }
00091 
00092 /* static */ void Game::Uninitialize(bool keepConfig)
00093 {
00094   Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
00095 
00096   delete Game::instance;
00097   Game::instance = NULL;
00098   Game::info = NULL;
00099 
00100   cur_company.Restore();
00101 
00102   if (keepConfig) {
00103     Rescan();
00104   } else {
00105     delete Game::scanner_info;
00106     delete Game::scanner_library;
00107     Game::scanner_info = NULL;
00108     Game::scanner_library = NULL;
00109 
00110     if (_settings_game.game_config != NULL) {
00111       delete _settings_game.game_config;
00112       _settings_game.game_config = NULL;
00113     }
00114     if (_settings_newgame.game_config != NULL) {
00115       delete _settings_newgame.game_config;
00116       _settings_newgame.game_config = NULL;
00117     }
00118   }
00119 }
00120 
00121 /* static */ void Game::NewEvent(ScriptEvent *event)
00122 {
00123   /* AddRef() and Release() need to be called at least once, so do it here */
00124   event->AddRef();
00125 
00126   /* Clients should ignore events */
00127   if (_networking && !_network_server) {
00128     event->Release();
00129     return;
00130   }
00131 
00132   /* Check if Game instance is alive */
00133   if (Game::instance == NULL) {
00134     event->Release();
00135     return;
00136   }
00137 
00138   /* Queue the event */
00139   Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
00140   Game::instance->InsertEvent(event);
00141   cur_company.Restore();
00142 
00143   event->Release();
00144 }
00145 
00146 /* static */ void Game::ResetConfig()
00147 {
00148   /* Check for both newgame as current game if we can reload the GameInfo insde
00149    *  the GameConfig. If not, remove the Game from the list. */
00150   if (_settings_game.game_config != NULL && _settings_game.game_config->HasScript()) {
00151     if (!_settings_game.game_config->ResetInfo(true)) {
00152       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());
00153       _settings_game.game_config->Change(NULL);
00154       if (Game::instance != NULL) {
00155         delete Game::instance;
00156         Game::instance = NULL;
00157         Game::info = NULL;
00158       }
00159     } else if (Game::instance != NULL) {
00160       Game::info = _settings_game.game_config->GetInfo();
00161     }
00162   }
00163   if (_settings_newgame.game_config != NULL && _settings_newgame.game_config->HasScript()) {
00164     if (!_settings_newgame.game_config->ResetInfo(false)) {
00165       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());
00166       _settings_newgame.game_config->Change(NULL);
00167     }
00168   }
00169 }
00170 
00171 /* static */ void Game::Rescan()
00172 {
00173   TarScanner::DoScan(TarScanner::GAME);
00174 
00175   Game::scanner_info->RescanDir();
00176   Game::scanner_library->RescanDir();
00177   ResetConfig();
00178 
00179   InvalidateWindowData(WC_AI_LIST, 0, 1);
00180   SetWindowClassesDirty(WC_AI_DEBUG);
00181   InvalidateWindowClassesData(WC_AI_SETTINGS);
00182 }
00183 
00184 
00185 /* static */ void Game::Save()
00186 {
00187   if (Game::instance != NULL && (!_networking || _network_server)) {
00188     Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
00189     Game::instance->Save();
00190     cur_company.Restore();
00191   } else {
00192     GameInstance::SaveEmpty();
00193   }
00194 }
00195 
00196 /* static */ void Game::Load(int version)
00197 {
00198   if (Game::instance != NULL && (!_networking || _network_server)) {
00199     Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
00200     Game::instance->Load(version);
00201     cur_company.Restore();
00202   } else {
00203     /* Read, but ignore, the load data */
00204     GameInstance::LoadEmpty();
00205   }
00206 }
00207 
00208 /* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only)
00209 {
00210   return Game::scanner_info->GetConsoleList(p, last, newest_only);
00211 }
00212 
00213 /* static */ char *Game::GetConsoleLibraryList(char *p, const char *last)
00214 {
00215    return Game::scanner_library->GetConsoleList(p, last, true);
00216 }
00217 
00218 /* static */ const ScriptInfoList *Game::GetInfoList()
00219 {
00220   return Game::scanner_info->GetInfoList();
00221 }
00222 
00223 /* static */ const ScriptInfoList *Game::GetUniqueInfoList()
00224 {
00225   return Game::scanner_info->GetUniqueInfoList();
00226 }
00227 
00228 /* static */ GameInfo *Game::FindInfo(const char *name, int version, bool force_exact_match)
00229 {
00230   return Game::scanner_info->FindInfo(name, version, force_exact_match);
00231 }
00232 
00233 /* static */ GameLibrary *Game::FindLibrary(const char *library, int version)
00234 {
00235   return Game::scanner_library->FindLibrary(library, version);
00236 }
00237 
00238 #if defined(ENABLE_NETWORK)
00239 
00246 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
00247 {
00248   return Game::scanner_info->HasScript(ci, md5sum);
00249 }
00250 
00251 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
00252 {
00253   return Game::scanner_library->HasScript(ci, md5sum);
00254 }
00255 
00256 #endif /* defined(ENABLE_NETWORK) */
00257 
00258 /* static */ GameScannerInfo *Game::GetScannerInfo()
00259 {
00260   return Game::scanner_info;
00261 }
00262 /* static */ GameScannerLibrary *Game::GetScannerLibrary()
00263 {
00264   return Game::scanner_library;
00265 }