2011-12-19 20:50:54 +00: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 20:55:56 +00:00
# include "../window_func.h"
2019-02-04 00:26:55 +00:00
# include "../framerate_type.h"
2011-12-19 20:50:54 +00:00
# include "game.hpp"
2011-12-19 20:55:56 +00:00
# include "game_scanner.hpp"
# include "game_config.hpp"
2011-12-19 20:50:54 +00:00
# include "game_instance.hpp"
2011-12-19 21:05:46 +00:00
# include "game_info.hpp"
2011-12-19 20:50:54 +00:00
2014-04-23 20:13:33 +00:00
# include "../safeguards.h"
2011-12-19 20:50:54 +00:00
/* static */ uint Game : : frame_counter = 0 ;
2019-04-10 21:07:06 +00: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 20:50:54 +00:00
/* static */ void Game : : GameLoop ( )
{
2019-02-04 00:26:55 +00:00
if ( _networking & & ! _network_server ) {
PerformanceMeasurer : : SetInactive ( PFE_GAMESCRIPT ) ;
return ;
}
2019-04-10 21:07:06 +00:00
if ( Game : : instance = = nullptr ) {
2019-02-04 00:26:55 +00:00
PerformanceMeasurer : : SetInactive ( PFE_GAMESCRIPT ) ;
return ;
}
PerformanceMeasurer framerate ( PFE_GAMESCRIPT ) ;
2011-12-19 20:50:54 +00:00
Game : : frame_counter + + ;
2019-04-22 08:10:04 +00:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 20:50:54 +00: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 21:07:06 +00:00
if ( Game : : instance ! = nullptr ) Game : : Uninitialize ( true ) ;
2011-12-19 20:50:54 +00:00
Game : : frame_counter = 0 ;
2011-12-19 20:55:56 +00:00
2019-04-10 21:07:06 +00:00
if ( Game : : scanner_info = = nullptr ) {
2011-12-19 20:55:56 +00:00
TarScanner : : DoScan ( TarScanner : : GAME ) ;
2011-12-19 20:56:59 +00:00
Game : : scanner_info = new GameScannerInfo ( ) ;
Game : : scanner_info - > Initialize ( ) ;
Game : : scanner_library = new GameScannerLibrary ( ) ;
Game : : scanner_library - > Initialize ( ) ;
2011-12-19 20:55:56 +00:00
}
2011-12-19 20:56:34 +00:00
}
2011-12-19 20:55:56 +00:00
2011-12-19 20:56:34 +00:00
/* static */ void Game : : StartNew ( )
{
2019-04-10 21:07:06 +00:00
if ( Game : : instance ! = nullptr ) return ;
2011-12-19 20:50:54 +00:00
2023-01-02 01:13:16 +00:00
/* Don't start GameScripts in intro */
if ( _game_mode = = GM_MENU ) return ;
2011-12-19 20:56:34 +00:00
/* Clients shouldn't start GameScripts */
if ( _networking & & ! _network_server ) return ;
2011-12-19 20:55:56 +00:00
2012-04-09 12:35:01 +00:00
GameConfig * config = GameConfig : : GetConfig ( GameConfig : : SSS_FORCE_GAME ) ;
2011-12-19 20:56:34 +00:00
GameInfo * info = config - > GetInfo ( ) ;
2019-04-10 21:07:06 +00:00
if ( info = = nullptr ) return ;
2011-12-19 20:50:54 +00:00
2013-07-12 18:54:27 +00:00
config - > AnchorUnchangeableSettings ( ) ;
2019-04-22 08:10:04 +00:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 20:56:34 +00:00
cur_company . Change ( OWNER_DEITY ) ;
2011-12-19 20:50:54 +00:00
2011-12-19 20:56:34 +00:00
Game : : info = info ;
Game : : instance = new GameInstance ( ) ;
Game : : instance - > Initialize ( info ) ;
2022-12-28 04:02:26 +00:00
Game : : instance - > LoadOnStack ( config - > GetToLoadData ( ) ) ;
config - > SetToLoadData ( nullptr ) ;
2011-12-19 20:55:56 +00:00
2011-12-19 20:56:34 +00:00
cur_company . Restore ( ) ;
2023-02-04 03:17:55 +00:00
InvalidateWindowData ( WC_SCRIPT_DEBUG , 0 , - 1 ) ;
2011-12-19 20:50:54 +00:00
}
2011-12-19 20:55:56 +00:00
/* static */ void Game : : Uninitialize ( bool keepConfig )
2011-12-19 20:50:54 +00:00
{
2019-04-22 08:10:04 +00:00
Backup < CompanyID > cur_company ( _current_company , FILE_LINE ) ;
2011-12-19 21:05:25 +00:00
2011-12-19 20:50:54 +00:00
delete Game : : instance ;
2019-04-10 21:07:06 +00:00
Game : : instance = nullptr ;
Game : : info = nullptr ;
2011-12-19 20:55:56 +00:00
2011-12-19 21:05:25 +00:00
cur_company . Restore ( ) ;
2011-12-19 20:55:56 +00:00
if ( keepConfig ) {
Rescan ( ) ;
} else {
2011-12-19 20:56:59 +00:00
delete Game : : scanner_info ;
delete Game : : scanner_library ;
2019-04-10 21:07:06 +00:00
Game : : scanner_info = nullptr ;
Game : : scanner_library = nullptr ;
2011-12-19 20:55:56 +00:00
2019-04-10 21:07:06 +00:00
if ( _settings_game . game_config ! = nullptr ) {
2011-12-19 20:55:56 +00:00
delete _settings_game . game_config ;
2019-04-10 21:07:06 +00:00
_settings_game . game_config = nullptr ;
2011-12-19 20:55:56 +00:00
}
2019-04-10 21:07:06 +00:00
if ( _settings_newgame . game_config ! = nullptr ) {
2011-12-19 20:55:56 +00:00
delete _settings_newgame . game_config ;
2019-04-10 21:07:06 +00:00
_settings_newgame . game_config = nullptr ;
2011-12-19 20:55:56 +00:00
}
}
}
2012-09-21 19:58:18 +00:00
/* static */ void Game : : Pause ( )
{
2019-04-10 21:07:06 +00:00
if ( Game : : instance ! = nullptr ) Game : : instance - > Pause ( ) ;
2012-09-21 19:58:18 +00:00
}
/* static */ void Game : : Unpause ( )
{
2019-04-10 21:07:06 +00:00
if ( Game : : instance ! = nullptr ) Game : : instance - > Unpause ( ) ;
2012-09-21 19:58:18 +00:00
}
/* static */ bool Game : : IsPaused ( )
{
2019-04-10 21:07:06 +00:00
return Game : : instance ! = nullptr ? Game : : instance - > IsPaused ( ) : false ;
2012-09-21 19:58:18 +00:00
}
2011-12-19 20:59:36 +00: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 21:07:06 +00:00
if ( Game : : instance = = nullptr ) {
2011-12-19 20:59:36 +00:00
event - > Release ( ) ;
return ;
}
/* Queue the event */
2019-04-22 08:10:04 +00:00
Backup < CompanyID > cur_company ( _current_company , OWNER_DEITY , FILE_LINE ) ;
2011-12-19 20:59:36 +00:00
Game : : instance - > InsertEvent ( event ) ;
cur_company . Restore ( ) ;
event - > Release ( ) ;
}
2011-12-19 20:55:56 +00:00
/* static */ void Game : : ResetConfig ( )
{
2013-01-08 22:46:42 +00:00
/* Check for both newgame as current game if we can reload the GameInfo inside
2011-12-19 20:55:56 +00:00
* the GameConfig . If not , remove the Game from the list . */
2019-04-10 21:07:06 +00:00
if ( _settings_game . game_config ! = nullptr & & _settings_game . game_config - > HasScript ( ) ) {
2011-12-19 20:55:56 +00:00
if ( ! _settings_game . game_config - > ResetInfo ( true ) ) {
2021-06-12 07:10:17 +00:00
Debug ( script , 0 , " After a reload, the GameScript by the name '{}' was no longer found, and removed from the list. " , _settings_game . game_config - > GetName ( ) ) ;
2019-04-10 21:07:06 +00:00
_settings_game . game_config - > Change ( nullptr ) ;
if ( Game : : instance ! = nullptr ) {
2011-12-19 20:55:56 +00:00
delete Game : : instance ;
2019-04-10 21:07:06 +00:00
Game : : instance = nullptr ;
Game : : info = nullptr ;
2011-12-19 20:55:56 +00:00
}
2019-04-10 21:07:06 +00:00
} else if ( Game : : instance ! = nullptr ) {
2011-12-19 20:55:56 +00:00
Game : : info = _settings_game . game_config - > GetInfo ( ) ;
}
}
2019-04-10 21:07:06 +00:00
if ( _settings_newgame . game_config ! = nullptr & & _settings_newgame . game_config - > HasScript ( ) ) {
2011-12-19 20:55:56 +00:00
if ( ! _settings_newgame . game_config - > ResetInfo ( false ) ) {
2021-06-12 07:10:17 +00:00
Debug ( script , 0 , " After a reload, the GameScript by the name '{}' was no longer found, and removed from the list. " , _settings_newgame . game_config - > GetName ( ) ) ;
2019-04-10 21:07:06 +00:00
_settings_newgame . game_config - > Change ( nullptr ) ;
2011-12-19 20:55:56 +00:00
}
}
}
/* static */ void Game : : Rescan ( )
{
TarScanner : : DoScan ( TarScanner : : GAME ) ;
2011-12-19 20:56:59 +00:00
Game : : scanner_info - > RescanDir ( ) ;
Game : : scanner_library - > RescanDir ( ) ;
2011-12-19 20:55:56 +00:00
ResetConfig ( ) ;
2023-02-04 03:17:55 +00:00
InvalidateWindowData ( WC_SCRIPT_LIST , 0 , 1 ) ;
SetWindowClassesDirty ( WC_SCRIPT_DEBUG ) ;
InvalidateWindowClassesData ( WC_SCRIPT_SETTINGS ) ;
2022-12-22 19:23:17 +00:00
InvalidateWindowClassesData ( WC_GAME_OPTIONS ) ;
2011-12-19 20:55:56 +00:00
}
2011-12-19 20:56:34 +00:00
/* static */ void Game : : Save ( )
{
2019-04-10 21:07:06 +00:00
if ( Game : : instance ! = nullptr & & ( ! _networking | | _network_server ) ) {
2019-04-22 08:10:04 +00:00
Backup < CompanyID > cur_company ( _current_company , OWNER_DEITY , FILE_LINE ) ;
2011-12-19 20:56:34 +00:00
Game : : instance - > Save ( ) ;
cur_company . Restore ( ) ;
} else {
GameInstance : : SaveEmpty ( ) ;
}
}
2022-10-10 11:19:58 +00:00
/* static */ std : : string Game : : GetConsoleList ( bool newest_only )
2011-12-19 20:55:56 +00:00
{
2022-10-10 11:19:58 +00:00
return Game : : scanner_info - > GetConsoleList ( newest_only ) ;
2011-12-19 20:56:59 +00:00
}
2022-10-10 11:19:58 +00:00
/* static */ std : : string Game : : GetConsoleLibraryList ( )
2011-12-19 20:56:59 +00:00
{
2022-10-10 11:19:58 +00:00
return Game : : scanner_library - > GetConsoleList ( true ) ;
2011-12-19 20:55:56 +00:00
}
/* static */ const ScriptInfoList * Game : : GetInfoList ( )
{
2011-12-19 20:56:59 +00:00
return Game : : scanner_info - > GetInfoList ( ) ;
2011-12-19 20:55:56 +00:00
}
/* static */ const ScriptInfoList * Game : : GetUniqueInfoList ( )
{
2011-12-19 20:56:59 +00:00
return Game : : scanner_info - > GetUniqueInfoList ( ) ;
2011-12-19 20:55:56 +00:00
}
/* static */ GameInfo * Game : : FindInfo ( const char * name , int version , bool force_exact_match )
{
2011-12-19 20:56:59 +00: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 20:50:54 +00:00
}
2011-12-19 20:56:59 +00: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 21:01:40 +00:00
/* static */ GameScannerInfo * Game : : GetScannerInfo ( )
{
return Game : : scanner_info ;
}
/* static */ GameScannerLibrary * Game : : GetScannerLibrary ( )
{
return Game : : scanner_library ;
}