2011-12-19 21:50:54 +01:00
/*
* This file is part of OpenTTD .
* 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.
* 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 .
* 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/>.
*/
/** @file game_core.cpp Implementation of Game. */
# include "../stdafx.h"
# include "../core/backup_type.hpp"
# include "../company_base.h"
# include "../company_func.h"
# include "../network/network.h"
2011-12-19 21:55:56 +01:00
# include "../window_func.h"
2019-02-04 01:26:55 +01:00
# include "../framerate_type.h"
2011-12-19 21:50:54 +01:00
# include "game.hpp"
2011-12-19 21:55:56 +01:00
# include "game_scanner.hpp"
# include "game_config.hpp"
2011-12-19 21:50:54 +01:00
# include "game_instance.hpp"
2011-12-19 22:05:46 +01:00
# include "game_info.hpp"
2011-12-19 21:50:54 +01:00
2014-04-23 22:13:33 +02:00
# include "../safeguards.h"
2011-12-19 21:50:54 +01:00
/* static */ uint Game : : frame_counter = 0 ;
2019-04-10 23:07:06 +02:00
/* static */ GameInfo * Game : : info = nullptr ;
/* static */ GameInstance * Game : : instance = nullptr ;
/* static */ GameScannerInfo * Game : : scanner_info = nullptr ;
/* static */ GameScannerLibrary * Game : : scanner_library = nullptr ;
2011-12-19 21:50:54 +01:00
/* static */ void Game : : GameLoop ( )
{
2019-02-04 01:26:55 +01:00
if ( _networking & & ! _network_server ) {
PerformanceMeasurer : : SetInactive ( PFE_GAMESCRIPT ) ;
return ;
}
2019-04-10 23:07:06 +02:00
if ( Game : : instance = = nullptr ) {
2019-02-04 01:26:55 +01:00
PerformanceMeasurer : : SetInactive ( PFE_GAMESCRIPT ) ;
return ;
}
PerformanceMeasurer framerate ( PFE_GAMESCRIPT ) ;
2011-12-19 21:50:54 +01:00
Game : : frame_counter + + ;
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 21:50:54 +01:00
cur_company . Change ( OWNER_DEITY ) ;
Game : : instance - > GameLoop ( ) ;
cur_company . Restore ( ) ;
/* Occasionally collect garbage */
if ( ( Game : : frame_counter & 255 ) = = 0 ) {
Game : : instance - > CollectGarbage ( ) ;
}
}
/* static */ void Game : : Initialize ( )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr ) Game : : Uninitialize ( true ) ;
2011-12-19 21:50:54 +01:00
Game : : frame_counter = 0 ;
2011-12-19 21:55:56 +01:00
2019-04-10 23:07:06 +02:00
if ( Game : : scanner_info = = nullptr ) {
2011-12-19 21:55:56 +01:00
TarScanner : : DoScan ( TarScanner : : GAME ) ;
2011-12-19 21:56:59 +01:00
Game : : scanner_info = new GameScannerInfo ( ) ;
Game : : scanner_info - > Initialize ( ) ;
Game : : scanner_library = new GameScannerLibrary ( ) ;
Game : : scanner_library - > Initialize ( ) ;
2011-12-19 21:55:56 +01:00
}
2011-12-19 21:56:34 +01:00
}
2011-12-19 21:55:56 +01:00
2011-12-19 21:56:34 +01:00
/* static */ void Game : : StartNew ( )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr ) return ;
2011-12-19 21:50:54 +01:00
2011-12-19 21:56:34 +01:00
/* Clients shouldn't start GameScripts */
if ( _networking & & ! _network_server ) return ;
2011-12-19 21:55:56 +01:00
2012-04-09 14:35:01 +02:00
GameConfig * config = GameConfig : : GetConfig ( GameConfig : : SSS_FORCE_GAME ) ;
2011-12-19 21:56:34 +01:00
GameInfo * info = config - > GetInfo ( ) ;
2019-04-10 23:07:06 +02:00
if ( info = = nullptr ) return ;
2011-12-19 21:50:54 +01:00
2013-07-12 20:54:27 +02:00
config - > AnchorUnchangeableSettings ( ) ;
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 21:56:34 +01:00
cur_company . Change ( OWNER_DEITY ) ;
2011-12-19 21:50:54 +01:00
2011-12-19 21:56:34 +01:00
Game : : info = info ;
Game : : instance = new GameInstance ( ) ;
Game : : instance - > Initialize ( info ) ;
2011-12-19 21:55:56 +01:00
2011-12-19 21:56:34 +01:00
cur_company . Restore ( ) ;
InvalidateWindowData ( WC_AI_DEBUG , 0 , - 1 ) ;
2011-12-19 21:50:54 +01:00
}
2011-12-19 21:55:56 +01:00
/* static */ void Game : : Uninitialize ( bool keepConfig )
2011-12-19 21:50:54 +01:00
{
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 22:05:25 +01:00
2011-12-19 21:50:54 +01:00
delete Game : : instance ;
2019-04-10 23:07:06 +02:00
Game : : instance = nullptr ;
Game : : info = nullptr ;
2011-12-19 21:55:56 +01:00
2011-12-19 22:05:25 +01:00
cur_company . Restore ( ) ;
2011-12-19 21:55:56 +01:00
if ( keepConfig ) {
Rescan ( ) ;
} else {
2011-12-19 21:56:59 +01:00
delete Game : : scanner_info ;
delete Game : : scanner_library ;
2019-04-10 23:07:06 +02:00
Game : : scanner_info = nullptr ;
Game : : scanner_library = nullptr ;
2011-12-19 21:55:56 +01:00
2019-04-10 23:07:06 +02:00
if ( _settings_game . game_config ! = nullptr ) {
2011-12-19 21:55:56 +01:00
delete _settings_game . game_config ;
2019-04-10 23:07:06 +02:00
_settings_game . game_config = nullptr ;
2011-12-19 21:55:56 +01:00
}
2019-04-10 23:07:06 +02:00
if ( _settings_newgame . game_config ! = nullptr ) {
2011-12-19 21:55:56 +01:00
delete _settings_newgame . game_config ;
2019-04-10 23:07:06 +02:00
_settings_newgame . game_config = nullptr ;
2011-12-19 21:55:56 +01:00
}
}
}
2012-09-21 21:58:18 +02:00
/* static */ void Game : : Pause ( )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr ) Game : : instance - > Pause ( ) ;
2012-09-21 21:58:18 +02:00
}
/* static */ void Game : : Unpause ( )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr ) Game : : instance - > Unpause ( ) ;
2012-09-21 21:58:18 +02:00
}
/* static */ bool Game : : IsPaused ( )
{
2019-04-10 23:07:06 +02:00
return Game : : instance ! = nullptr ? Game : : instance - > IsPaused ( ) : false ;
2012-09-21 21:58:18 +02:00
}
2011-12-19 21:59:36 +01:00
/* static */ void Game : : NewEvent ( ScriptEvent * event )
{
/* AddRef() and Release() need to be called at least once, so do it here */
event - > AddRef ( ) ;
/* Clients should ignore events */
if ( _networking & & ! _network_server ) {
event - > Release ( ) ;
return ;
}
/* Check if Game instance is alive */
2019-04-10 23:07:06 +02:00
if ( Game : : instance = = nullptr ) {
2011-12-19 21:59:36 +01:00
event - > Release ( ) ;
return ;
}
/* Queue the event */
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , OWNER_DEITY , FILE_LINE ) ;
2011-12-19 21:59:36 +01:00
Game : : instance - > InsertEvent ( event ) ;
cur_company . Restore ( ) ;
event - > Release ( ) ;
}
2011-12-19 21:55:56 +01:00
/* static */ void Game : : ResetConfig ( )
{
2013-01-08 23:46:42 +01:00
/* Check for both newgame as current game if we can reload the GameInfo inside
2011-12-19 21:55:56 +01:00
* the GameConfig . If not , remove the Game from the list . */
2019-04-10 23:07:06 +02:00
if ( _settings_game . game_config ! = nullptr & & _settings_game . game_config - > HasScript ( ) ) {
2011-12-19 21:55:56 +01:00
if ( ! _settings_game . game_config - > ResetInfo ( true ) ) {
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 ( ) ) ;
2019-04-10 23:07:06 +02:00
_settings_game . game_config - > Change ( nullptr ) ;
if ( Game : : instance ! = nullptr ) {
2011-12-19 21:55:56 +01:00
delete Game : : instance ;
2019-04-10 23:07:06 +02:00
Game : : instance = nullptr ;
Game : : info = nullptr ;
2011-12-19 21:55:56 +01:00
}
2019-04-10 23:07:06 +02:00
} else if ( Game : : instance ! = nullptr ) {
2011-12-19 21:55:56 +01:00
Game : : info = _settings_game . game_config - > GetInfo ( ) ;
}
}
2019-04-10 23:07:06 +02:00
if ( _settings_newgame . game_config ! = nullptr & & _settings_newgame . game_config - > HasScript ( ) ) {
2011-12-19 21:55:56 +01:00
if ( ! _settings_newgame . game_config - > ResetInfo ( false ) ) {
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 ( ) ) ;
2019-04-10 23:07:06 +02:00
_settings_newgame . game_config - > Change ( nullptr ) ;
2011-12-19 21:55:56 +01:00
}
}
}
/* static */ void Game : : Rescan ( )
{
TarScanner : : DoScan ( TarScanner : : GAME ) ;
2011-12-19 21:56:59 +01:00
Game : : scanner_info - > RescanDir ( ) ;
Game : : scanner_library - > RescanDir ( ) ;
2011-12-19 21:55:56 +01:00
ResetConfig ( ) ;
InvalidateWindowData ( WC_AI_LIST , 0 , 1 ) ;
SetWindowClassesDirty ( WC_AI_DEBUG ) ;
2012-01-02 21:39:50 +01:00
InvalidateWindowClassesData ( WC_AI_SETTINGS ) ;
2011-12-19 21:55:56 +01:00
}
2011-12-19 21:56:34 +01:00
/* static */ void Game : : Save ( )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr & & ( ! _networking | | _network_server ) ) {
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , OWNER_DEITY , FILE_LINE ) ;
2011-12-19 21:56:34 +01:00
Game : : instance - > Save ( ) ;
cur_company . Restore ( ) ;
} else {
GameInstance : : SaveEmpty ( ) ;
}
}
/* static */ void Game : : Load ( int version )
{
2019-04-10 23:07:06 +02:00
if ( Game : : instance ! = nullptr & & ( ! _networking | | _network_server ) ) {
2019-04-22 10:10:04 +02:00
Backup < CompanyID > cur_company ( _current_company , OWNER_DEITY , FILE_LINE ) ;
2011-12-19 21:56:34 +01:00
Game : : instance - > Load ( version ) ;
cur_company . Restore ( ) ;
} else {
/* Read, but ignore, the load data */
GameInstance : : LoadEmpty ( ) ;
}
}
2011-12-19 21:55:56 +01:00
/* static */ char * Game : : GetConsoleList ( char * p , const char * last , bool newest_only )
{
2011-12-19 21:56:59 +01:00
return Game : : scanner_info - > GetConsoleList ( p , last , newest_only ) ;
}
/* static */ char * Game : : GetConsoleLibraryList ( char * p , const char * last )
{
return Game : : scanner_library - > GetConsoleList ( p , last , true ) ;
2011-12-19 21:55:56 +01:00
}
/* static */ const ScriptInfoList * Game : : GetInfoList ( )
{
2011-12-19 21:56:59 +01:00
return Game : : scanner_info - > GetInfoList ( ) ;
2011-12-19 21:55:56 +01:00
}
/* static */ const ScriptInfoList * Game : : GetUniqueInfoList ( )
{
2011-12-19 21:56:59 +01:00
return Game : : scanner_info - > GetUniqueInfoList ( ) ;
2011-12-19 21:55:56 +01:00
}
/* static */ GameInfo * Game : : FindInfo ( const char * name , int version , bool force_exact_match )
{
2011-12-19 21:56:59 +01:00
return Game : : scanner_info - > FindInfo ( name , version , force_exact_match ) ;
}
/* static */ GameLibrary * Game : : FindLibrary ( const char * library , int version )
{
return Game : : scanner_library - > FindLibrary ( library , version ) ;
2011-12-19 21:50:54 +01:00
}
2011-12-19 21:56:59 +01:00
/**
* Check whether we have an Game ( library ) with the exact characteristics as ci .
* @ param ci the characteristics to search on ( shortname and md5sum )
* @ param md5sum whether to check the MD5 checksum
* @ return true iff we have an Game ( library ) matching .
*/
/* static */ bool Game : : HasGame ( const ContentInfo * ci , bool md5sum )
{
return Game : : scanner_info - > HasScript ( ci , md5sum ) ;
}
/* static */ bool Game : : HasGameLibrary ( const ContentInfo * ci , bool md5sum )
{
return Game : : scanner_library - > HasScript ( ci , md5sum ) ;
}
2012-08-20 23:01:40 +02:00
/* static */ GameScannerInfo * Game : : GetScannerInfo ( )
{
return Game : : scanner_info ;
}
/* static */ GameScannerLibrary * Game : : GetScannerLibrary ( )
{
return Game : : scanner_library ;
}