# 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) */