Codechange: Use null pointer literal instead of the NULL macro
[openttd-github.git] / src / game / game_core.cpp
blob181e8b6bbc2de06902b93be6286505e74ace32c1
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file game_core.cpp Implementation of Game. */
12 #include "../stdafx.h"
13 #include "../core/backup_type.hpp"
14 #include "../company_base.h"
15 #include "../company_func.h"
16 #include "../network/network.h"
17 #include "../window_func.h"
18 #include "../framerate_type.h"
19 #include "game.hpp"
20 #include "game_scanner.hpp"
21 #include "game_config.hpp"
22 #include "game_instance.hpp"
23 #include "game_info.hpp"
25 #include "../safeguards.h"
27 /* static */ uint Game::frame_counter = 0;
28 /* static */ GameInfo *Game::info = nullptr;
29 /* static */ GameInstance *Game::instance = nullptr;
30 /* static */ GameScannerInfo *Game::scanner_info = nullptr;
31 /* static */ GameScannerLibrary *Game::scanner_library = nullptr;
33 /* static */ void Game::GameLoop()
35 if (_networking && !_network_server) {
36 PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT);
37 return;
39 if (Game::instance == nullptr) {
40 PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT);
41 return;
44 PerformanceMeasurer framerate(PFE_GAMESCRIPT);
46 Game::frame_counter++;
48 Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
49 cur_company.Change(OWNER_DEITY);
50 Game::instance->GameLoop();
51 cur_company.Restore();
53 /* Occasionally collect garbage */
54 if ((Game::frame_counter & 255) == 0) {
55 Game::instance->CollectGarbage();
59 /* static */ void Game::Initialize()
61 if (Game::instance != nullptr) Game::Uninitialize(true);
63 Game::frame_counter = 0;
65 if (Game::scanner_info == nullptr) {
66 TarScanner::DoScan(TarScanner::GAME);
67 Game::scanner_info = new GameScannerInfo();
68 Game::scanner_info->Initialize();
69 Game::scanner_library = new GameScannerLibrary();
70 Game::scanner_library->Initialize();
74 /* static */ void Game::StartNew()
76 if (Game::instance != nullptr) return;
78 /* Clients shouldn't start GameScripts */
79 if (_networking && !_network_server) return;
81 GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
82 GameInfo *info = config->GetInfo();
83 if (info == nullptr) return;
85 config->AnchorUnchangeableSettings();
87 Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
88 cur_company.Change(OWNER_DEITY);
90 Game::info = info;
91 Game::instance = new GameInstance();
92 Game::instance->Initialize(info);
94 cur_company.Restore();
96 InvalidateWindowData(WC_AI_DEBUG, 0, -1);
99 /* static */ void Game::Uninitialize(bool keepConfig)
101 Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
103 delete Game::instance;
104 Game::instance = nullptr;
105 Game::info = nullptr;
107 cur_company.Restore();
109 if (keepConfig) {
110 Rescan();
111 } else {
112 delete Game::scanner_info;
113 delete Game::scanner_library;
114 Game::scanner_info = nullptr;
115 Game::scanner_library = nullptr;
117 if (_settings_game.game_config != nullptr) {
118 delete _settings_game.game_config;
119 _settings_game.game_config = nullptr;
121 if (_settings_newgame.game_config != nullptr) {
122 delete _settings_newgame.game_config;
123 _settings_newgame.game_config = nullptr;
128 /* static */ void Game::Pause()
130 if (Game::instance != nullptr) Game::instance->Pause();
133 /* static */ void Game::Unpause()
135 if (Game::instance != nullptr) Game::instance->Unpause();
138 /* static */ bool Game::IsPaused()
140 return Game::instance != nullptr? Game::instance->IsPaused() : false;
143 /* static */ void Game::NewEvent(ScriptEvent *event)
145 /* AddRef() and Release() need to be called at least once, so do it here */
146 event->AddRef();
148 /* Clients should ignore events */
149 if (_networking && !_network_server) {
150 event->Release();
151 return;
154 /* Check if Game instance is alive */
155 if (Game::instance == nullptr) {
156 event->Release();
157 return;
160 /* Queue the event */
161 Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
162 Game::instance->InsertEvent(event);
163 cur_company.Restore();
165 event->Release();
168 /* static */ void Game::ResetConfig()
170 /* Check for both newgame as current game if we can reload the GameInfo inside
171 * the GameConfig. If not, remove the Game from the list. */
172 if (_settings_game.game_config != nullptr && _settings_game.game_config->HasScript()) {
173 if (!_settings_game.game_config->ResetInfo(true)) {
174 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());
175 _settings_game.game_config->Change(nullptr);
176 if (Game::instance != nullptr) {
177 delete Game::instance;
178 Game::instance = nullptr;
179 Game::info = nullptr;
181 } else if (Game::instance != nullptr) {
182 Game::info = _settings_game.game_config->GetInfo();
185 if (_settings_newgame.game_config != nullptr && _settings_newgame.game_config->HasScript()) {
186 if (!_settings_newgame.game_config->ResetInfo(false)) {
187 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());
188 _settings_newgame.game_config->Change(nullptr);
193 /* static */ void Game::Rescan()
195 TarScanner::DoScan(TarScanner::GAME);
197 Game::scanner_info->RescanDir();
198 Game::scanner_library->RescanDir();
199 ResetConfig();
201 InvalidateWindowData(WC_AI_LIST, 0, 1);
202 SetWindowClassesDirty(WC_AI_DEBUG);
203 InvalidateWindowClassesData(WC_AI_SETTINGS);
207 /* static */ void Game::Save()
209 if (Game::instance != nullptr && (!_networking || _network_server)) {
210 Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
211 Game::instance->Save();
212 cur_company.Restore();
213 } else {
214 GameInstance::SaveEmpty();
218 /* static */ void Game::Load(int version)
220 if (Game::instance != nullptr && (!_networking || _network_server)) {
221 Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
222 Game::instance->Load(version);
223 cur_company.Restore();
224 } else {
225 /* Read, but ignore, the load data */
226 GameInstance::LoadEmpty();
230 /* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only)
232 return Game::scanner_info->GetConsoleList(p, last, newest_only);
235 /* static */ char *Game::GetConsoleLibraryList(char *p, const char *last)
237 return Game::scanner_library->GetConsoleList(p, last, true);
240 /* static */ const ScriptInfoList *Game::GetInfoList()
242 return Game::scanner_info->GetInfoList();
245 /* static */ const ScriptInfoList *Game::GetUniqueInfoList()
247 return Game::scanner_info->GetUniqueInfoList();
250 /* static */ GameInfo *Game::FindInfo(const char *name, int version, bool force_exact_match)
252 return Game::scanner_info->FindInfo(name, version, force_exact_match);
255 /* static */ GameLibrary *Game::FindLibrary(const char *library, int version)
257 return Game::scanner_library->FindLibrary(library, version);
261 * Check whether we have an Game (library) with the exact characteristics as ci.
262 * @param ci the characteristics to search on (shortname and md5sum)
263 * @param md5sum whether to check the MD5 checksum
264 * @return true iff we have an Game (library) matching.
266 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
268 return Game::scanner_info->HasScript(ci, md5sum);
271 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
273 return Game::scanner_library->HasScript(ci, md5sum);
276 /* static */ GameScannerInfo *Game::GetScannerInfo()
278 return Game::scanner_info;
280 /* static */ GameScannerLibrary *Game::GetScannerLibrary()
282 return Game::scanner_library;