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