OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

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
37 Game::frame_counter++;
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
54 Game::frame_counter = 0;
55
56 if (Game::scanner_info == NULL) {
57 TarScanner::DoScan(TarScanner::GAME);
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
72 GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
73 GameInfo *info = config->GetInfo();
74 if (info == NULL) return;
75
76 config->AnchorUnchangeableSettings();
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
87 InvalidateWindowData(WC_AI_DEBUG, 0, -1);
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) {
109 delete _settings_game.game_config;
110 _settings_game.game_config = NULL;
111 }
112 if (_settings_newgame.game_config != NULL) {
113 delete _settings_newgame.game_config;
114 _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. */
163 if (_settings_game.game_config != NULL && _settings_game.game_config->HasScript()) {
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());
166 _settings_game.game_config->Change(NULL);
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 }
176 if (_settings_newgame.game_config != NULL && _settings_newgame.game_config->HasScript()) {
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());
179 _settings_newgame.game_config->Change(NULL);
180 }
181 }
182 }
183
184 /* static */ void Game::Rescan()
185 {
186 TarScanner::DoScan(TarScanner::GAME);
187
188 Game::scanner_info->RescanDir();
189 Game::scanner_library->RescanDir();
190 ResetConfig();
191
192 InvalidateWindowData(WC_AI_LIST, 0, 1);
193 SetWindowClassesDirty(WC_AI_DEBUG);
194 InvalidateWindowClassesData(WC_AI_SETTINGS);
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 {
205 GameInstance::SaveEmpty();
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 */
217 GameInstance::LoadEmpty();
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
236 /* static */ const ScriptInfoList *Game::GetUniqueInfoList()
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
271 /* static */ GameScannerInfo *Game::GetScannerInfo()
272 {
273 return Game::scanner_info;
274 }
275 /* static */ GameScannerLibrary *Game::GetScannerLibrary()
276 {
277 return Game::scanner_library;
278 }