OpenTTD
game_core.cpp
Go to the documentation of this file.
1 /* $Id: game_core.cpp 26482 2014-04-23 20:13:33Z rubidium $ */
2 
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  */
9 
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 "game.hpp"
19 #include "game_scanner.hpp"
20 #include "game_config.hpp"
21 #include "game_instance.hpp"
22 #include "game_info.hpp"
23 
24 #include "../safeguards.h"
25 
26 /* static */ uint Game::frame_counter = 0;
27 /* static */ GameInfo *Game::info = NULL;
28 /* static */ GameInstance *Game::instance = NULL;
29 /* static */ GameScannerInfo *Game::scanner_info = NULL;
30 /* static */ GameScannerLibrary *Game::scanner_library = NULL;
31 
32 /* static */ void Game::GameLoop()
33 {
34  if (_networking && !_network_server) return;
35  if (Game::instance == NULL) return;
36 
38 
39  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
40  cur_company.Change(OWNER_DEITY);
41  Game::instance->GameLoop();
42  cur_company.Restore();
43 
44  /* Occasionally collect garbage */
45  if ((Game::frame_counter & 255) == 0) {
46  Game::instance->CollectGarbage();
47  }
48 }
49 
50 /* static */ void Game::Initialize()
51 {
52  if (Game::instance != NULL) Game::Uninitialize(true);
53 
55 
56  if (Game::scanner_info == NULL) {
58  Game::scanner_info = new GameScannerInfo();
59  Game::scanner_info->Initialize();
60  Game::scanner_library = new GameScannerLibrary();
61  Game::scanner_library->Initialize();
62  }
63 }
64 
65 /* static */ void Game::StartNew()
66 {
67  if (Game::instance != NULL) return;
68 
69  /* Clients shouldn't start GameScripts */
70  if (_networking && !_network_server) return;
71 
73  GameInfo *info = config->GetInfo();
74  if (info == NULL) return;
75 
77 
78  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
79  cur_company.Change(OWNER_DEITY);
80 
81  Game::info = info;
82  Game::instance = new GameInstance();
83  Game::instance->Initialize(info);
84 
85  cur_company.Restore();
86 
88 }
89 
90 /* static */ void Game::Uninitialize(bool keepConfig)
91 {
92  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
93 
94  delete Game::instance;
95  Game::instance = NULL;
96  Game::info = NULL;
97 
98  cur_company.Restore();
99 
100  if (keepConfig) {
101  Rescan();
102  } else {
103  delete Game::scanner_info;
104  delete Game::scanner_library;
105  Game::scanner_info = NULL;
106  Game::scanner_library = NULL;
107 
108  if (_settings_game.game_config != NULL) {
111  }
112  if (_settings_newgame.game_config != NULL) {
115  }
116  }
117 }
118 
119 /* static */ void Game::Pause()
120 {
121  if (Game::instance != NULL) Game::instance->Pause();
122 }
123 
124 /* static */ void Game::Unpause()
125 {
126  if (Game::instance != NULL) Game::instance->Unpause();
127 }
128 
129 /* static */ bool Game::IsPaused()
130 {
131  return Game::instance != NULL? Game::instance->IsPaused() : false;
132 }
133 
134 /* static */ void Game::NewEvent(ScriptEvent *event)
135 {
136  /* AddRef() and Release() need to be called at least once, so do it here */
137  event->AddRef();
138 
139  /* Clients should ignore events */
140  if (_networking && !_network_server) {
141  event->Release();
142  return;
143  }
144 
145  /* Check if Game instance is alive */
146  if (Game::instance == NULL) {
147  event->Release();
148  return;
149  }
150 
151  /* Queue the event */
152  Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
153  Game::instance->InsertEvent(event);
154  cur_company.Restore();
155 
156  event->Release();
157 }
158 
159 /* static */ void Game::ResetConfig()
160 {
161  /* Check for both newgame as current game if we can reload the GameInfo inside
162  * the GameConfig. If not, remove the Game from the list. */
164  if (!_settings_game.game_config->ResetInfo(true)) {
165  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());
167  if (Game::instance != NULL) {
168  delete Game::instance;
169  Game::instance = NULL;
170  Game::info = NULL;
171  }
172  } else if (Game::instance != NULL) {
173  Game::info = _settings_game.game_config->GetInfo();
174  }
175  }
177  if (!_settings_newgame.game_config->ResetInfo(false)) {
178  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());
180  }
181  }
182 }
183 
184 /* static */ void Game::Rescan()
185 {
187 
188  Game::scanner_info->RescanDir();
189  Game::scanner_library->RescanDir();
190  ResetConfig();
191 
195 }
196 
197 
198 /* static */ void Game::Save()
199 {
200  if (Game::instance != NULL && (!_networking || _network_server)) {
201  Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
202  Game::instance->Save();
203  cur_company.Restore();
204  } else {
206  }
207 }
208 
209 /* static */ void Game::Load(int version)
210 {
211  if (Game::instance != NULL && (!_networking || _network_server)) {
212  Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
213  Game::instance->Load(version);
214  cur_company.Restore();
215  } else {
216  /* Read, but ignore, the load data */
218  }
219 }
220 
221 /* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only)
222 {
223  return Game::scanner_info->GetConsoleList(p, last, newest_only);
224 }
225 
226 /* static */ char *Game::GetConsoleLibraryList(char *p, const char *last)
227 {
228  return Game::scanner_library->GetConsoleList(p, last, true);
229 }
230 
231 /* static */ const ScriptInfoList *Game::GetInfoList()
232 {
233  return Game::scanner_info->GetInfoList();
234 }
235 
237 {
238  return Game::scanner_info->GetUniqueInfoList();
239 }
240 
241 /* static */ GameInfo *Game::FindInfo(const char *name, int version, bool force_exact_match)
242 {
243  return Game::scanner_info->FindInfo(name, version, force_exact_match);
244 }
245 
246 /* static */ GameLibrary *Game::FindLibrary(const char *library, int version)
247 {
248  return Game::scanner_library->FindLibrary(library, version);
249 }
250 
251 #if defined(ENABLE_NETWORK)
252 
259 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
260 {
261  return Game::scanner_info->HasScript(ci, md5sum);
262 }
263 
264 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
265 {
266  return Game::scanner_library->HasScript(ci, md5sum);
267 }
268 
269 #endif /* defined(ENABLE_NETWORK) */
270 
272 {
273  return Game::scanner_info;
274 }
276 {
277  return Game::scanner_library;
278 }