main.cpp 111 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091
  1. /*************************************************************************/
  2. /* main.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "main.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/core_string_names.h"
  33. #include "core/crypto/crypto.h"
  34. #include "core/debugger/engine_debugger.h"
  35. #include "core/extension/extension_api_dump.h"
  36. #include "core/extension/native_extension_manager.h"
  37. #include "core/input/input.h"
  38. #include "core/input/input_map.h"
  39. #include "core/io/dir_access.h"
  40. #include "core/io/file_access_network.h"
  41. #include "core/io/file_access_pack.h"
  42. #include "core/io/file_access_zip.h"
  43. #include "core/io/image_loader.h"
  44. #include "core/io/ip.h"
  45. #include "core/io/resource_loader.h"
  46. #include "core/object/message_queue.h"
  47. #include "core/os/os.h"
  48. #include "core/os/time.h"
  49. #include "core/register_core_types.h"
  50. #include "core/string/translation.h"
  51. #include "core/version.h"
  52. #include "drivers/register_driver_types.h"
  53. #include "main/app_icon.gen.h"
  54. #include "main/main_timer_sync.h"
  55. #include "main/performance.h"
  56. #include "main/splash.gen.h"
  57. #include "modules/register_module_types.h"
  58. #include "platform/register_platform_apis.h"
  59. #include "scene/main/scene_tree.h"
  60. #include "scene/main/window.h"
  61. #include "scene/register_scene_types.h"
  62. #include "scene/resources/packed_scene.h"
  63. #include "servers/audio_server.h"
  64. #include "servers/camera_server.h"
  65. #include "servers/display_server.h"
  66. #include "servers/movie_writer/movie_writer.h"
  67. #include "servers/movie_writer/movie_writer_mjpeg.h"
  68. #include "servers/navigation_server_2d.h"
  69. #include "servers/navigation_server_3d.h"
  70. #include "servers/physics_server_2d.h"
  71. #include "servers/physics_server_3d.h"
  72. #include "servers/register_server_types.h"
  73. #include "servers/rendering/rendering_server_default.h"
  74. #include "servers/text/text_server_dummy.h"
  75. #include "servers/text_server.h"
  76. #include "servers/xr_server.h"
  77. #ifdef TESTS_ENABLED
  78. #include "tests/test_main.h"
  79. #endif
  80. #ifdef TOOLS_ENABLED
  81. #include "editor/doc_data_class_path.gen.h"
  82. #include "editor/doc_tools.h"
  83. #include "editor/editor_node.h"
  84. #include "editor/editor_paths.h"
  85. #include "editor/editor_settings.h"
  86. #include "editor/editor_translation.h"
  87. #include "editor/progress_dialog.h"
  88. #include "editor/project_converter_3_to_4.h"
  89. #include "editor/project_manager.h"
  90. #ifndef NO_EDITOR_SPLASH
  91. #include "main/splash_editor.gen.h"
  92. #endif
  93. #endif
  94. #include "modules/modules_enabled.gen.h" // For mono.
  95. /* Static members */
  96. // Singletons
  97. // Initialized in setup()
  98. static Engine *engine = nullptr;
  99. static ProjectSettings *globals = nullptr;
  100. static Input *input = nullptr;
  101. static InputMap *input_map = nullptr;
  102. static TranslationServer *translation_server = nullptr;
  103. static Performance *performance = nullptr;
  104. static PackedData *packed_data = nullptr;
  105. static Time *time_singleton = nullptr;
  106. #ifdef MINIZIP_ENABLED
  107. static ZipArchive *zip_packed_data = nullptr;
  108. #endif
  109. static FileAccessNetworkClient *file_access_network_client = nullptr;
  110. static MessageQueue *message_queue = nullptr;
  111. // Initialized in setup2()
  112. static AudioServer *audio_server = nullptr;
  113. static DisplayServer *display_server = nullptr;
  114. static RenderingServer *rendering_server = nullptr;
  115. static CameraServer *camera_server = nullptr;
  116. static XRServer *xr_server = nullptr;
  117. static TextServerManager *tsman = nullptr;
  118. static PhysicsServer3D *physics_server_3d = nullptr;
  119. static PhysicsServer2D *physics_server_2d = nullptr;
  120. static NavigationServer3D *navigation_server_3d = nullptr;
  121. static NavigationServer2D *navigation_server_2d = nullptr;
  122. // We error out if setup2() doesn't turn this true
  123. static bool _start_success = false;
  124. // Drivers
  125. String tablet_driver = "";
  126. String text_driver = "";
  127. String rendering_driver = "";
  128. static int text_driver_idx = -1;
  129. static int display_driver_idx = -1;
  130. static int audio_driver_idx = -1;
  131. // Engine config/tools
  132. static bool editor = false;
  133. static bool project_manager = false;
  134. static bool cmdline_tool = false;
  135. static String locale;
  136. static bool show_help = false;
  137. static bool auto_quit = false;
  138. static OS::ProcessID allow_focus_steal_pid = 0;
  139. #ifdef TOOLS_ENABLED
  140. static bool auto_build_solutions = false;
  141. static String debug_server_uri;
  142. #endif
  143. // Display
  144. static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED;
  145. static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE;
  146. static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED;
  147. static uint32_t window_flags = 0;
  148. static Size2i window_size = Size2i(1024, 600);
  149. static int init_screen = -1;
  150. static bool init_fullscreen = false;
  151. static bool init_maximized = false;
  152. static bool init_windowed = false;
  153. static bool init_always_on_top = false;
  154. static bool init_use_custom_pos = false;
  155. static Vector2 init_custom_pos;
  156. // Debug
  157. static bool use_debug_profiler = false;
  158. #ifdef DEBUG_ENABLED
  159. static bool debug_collisions = false;
  160. static bool debug_paths = false;
  161. static bool debug_navigation = false;
  162. #endif
  163. static int frame_delay = 0;
  164. static bool disable_render_loop = false;
  165. static int fixed_fps = -1;
  166. static String write_movie_path;
  167. static MovieWriter *movie_writer = nullptr;
  168. static bool disable_vsync = false;
  169. static bool print_fps = false;
  170. #ifdef TOOLS_ENABLED
  171. static bool dump_extension_api = false;
  172. #endif
  173. bool profile_gpu = false;
  174. /* Helper methods */
  175. bool Main::is_cmdline_tool() {
  176. return cmdline_tool;
  177. }
  178. static String unescape_cmdline(const String &p_str) {
  179. return p_str.replace("%20", " ");
  180. }
  181. static String get_full_version_string() {
  182. String hash = String(VERSION_HASH);
  183. if (!hash.is_empty()) {
  184. hash = "." + hash.left(9);
  185. }
  186. return String(VERSION_FULL_BUILD) + hash;
  187. }
  188. // FIXME: Could maybe be moved to PhysicsServer3DManager and PhysicsServer2DManager directly
  189. // to have less code in main.cpp.
  190. void initialize_physics() {
  191. /// 3D Physics Server
  192. physics_server_3d = PhysicsServer3DManager::new_server(
  193. ProjectSettings::get_singleton()->get(PhysicsServer3DManager::setting_property_name));
  194. if (!physics_server_3d) {
  195. // Physics server not found, Use the default physics
  196. physics_server_3d = PhysicsServer3DManager::new_default_server();
  197. }
  198. ERR_FAIL_COND(!physics_server_3d);
  199. physics_server_3d->init();
  200. /// 2D Physics server
  201. physics_server_2d = PhysicsServer2DManager::new_server(
  202. ProjectSettings::get_singleton()->get(PhysicsServer2DManager::setting_property_name));
  203. if (!physics_server_2d) {
  204. // Physics server not found, Use the default physics
  205. physics_server_2d = PhysicsServer2DManager::new_default_server();
  206. }
  207. ERR_FAIL_COND(!physics_server_2d);
  208. physics_server_2d->init();
  209. }
  210. void finalize_physics() {
  211. physics_server_3d->finish();
  212. memdelete(physics_server_3d);
  213. physics_server_2d->finish();
  214. memdelete(physics_server_2d);
  215. }
  216. void finalize_display() {
  217. rendering_server->finish();
  218. memdelete(rendering_server);
  219. memdelete(display_server);
  220. }
  221. void initialize_navigation_server() {
  222. ERR_FAIL_COND(navigation_server_3d != nullptr);
  223. navigation_server_3d = NavigationServer3DManager::new_default_server();
  224. navigation_server_2d = memnew(NavigationServer2D);
  225. }
  226. void finalize_navigation_server() {
  227. memdelete(navigation_server_3d);
  228. navigation_server_3d = nullptr;
  229. memdelete(navigation_server_2d);
  230. navigation_server_2d = nullptr;
  231. }
  232. //#define DEBUG_INIT
  233. #ifdef DEBUG_INIT
  234. #define MAIN_PRINT(m_txt) print_line(m_txt)
  235. #else
  236. #define MAIN_PRINT(m_txt)
  237. #endif
  238. void Main::print_help(const char *p_binary) {
  239. print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
  240. OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n");
  241. OS::get_singleton()->print("(c) 2007-2022 Juan Linietsky, Ariel Manzur.\n");
  242. OS::get_singleton()->print("(c) 2014-2022 Godot Engine contributors.\n");
  243. OS::get_singleton()->print("\n");
  244. OS::get_singleton()->print("Usage: %s [options] [path to scene or 'project.godot' file]\n", p_binary);
  245. OS::get_singleton()->print("\n");
  246. OS::get_singleton()->print("General options:\n");
  247. OS::get_singleton()->print(" -h, --help Display this help message.\n");
  248. OS::get_singleton()->print(" --version Display the version string.\n");
  249. OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n");
  250. OS::get_singleton()->print(" -q, --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n");
  251. OS::get_singleton()->print("\n");
  252. OS::get_singleton()->print("Run options:\n");
  253. #ifdef TOOLS_ENABLED
  254. OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n");
  255. OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n");
  256. OS::get_singleton()->print(" --debug-server <uri> Start the editor debug server (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007)\n");
  257. #endif
  258. OS::get_singleton()->print(" --quit Quit after the first iteration.\n");
  259. OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n");
  260. OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n");
  261. OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n");
  262. OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n");
  263. OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n");
  264. OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n");
  265. OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n");
  266. OS::get_singleton()->print(" --audio-driver <driver> Audio driver [");
  267. for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
  268. if (i > 0) {
  269. OS::get_singleton()->print(", ");
  270. }
  271. OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name());
  272. }
  273. OS::get_singleton()->print("].\n");
  274. OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver) [");
  275. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  276. if (i > 0) {
  277. OS::get_singleton()->print(", ");
  278. }
  279. OS::get_singleton()->print("'%s' (", DisplayServer::get_create_function_name(i));
  280. Vector<String> rd = DisplayServer::get_create_function_rendering_drivers(i);
  281. for (int j = 0; j < rd.size(); j++) {
  282. if (j > 0) {
  283. OS::get_singleton()->print(", ");
  284. }
  285. OS::get_singleton()->print("'%s'", rd[j].utf8().get_data());
  286. }
  287. OS::get_singleton()->print(")");
  288. }
  289. OS::get_singleton()->print("].\n");
  290. OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n");
  291. OS::get_singleton()->print(" --gpu-index <device_index> Use a specific GPU (run with --verbose to get available device list).\n");
  292. OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n");
  293. OS::get_singleton()->print(" --tablet-driver <driver> Pen tablet input driver.\n");
  294. OS::get_singleton()->print(" --headless Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.\n");
  295. OS::get_singleton()->print(" --write-movie <file> Run the engine in a way that a movie is written (by default .avi MJPEG). Fixed FPS is forced when enabled, but can be used to change movie FPS. Disabling vsync can speed up movie writing but makes interaction more difficult.\n");
  296. OS::get_singleton()->print(" --disable-vsync Force disabling of vsync. Run the engine in a way that a movie is written (by default .avi MJPEG). Fixed FPS is forced when enabled, but can be used to change movie FPS.\n");
  297. OS::get_singleton()->print("\n");
  298. OS::get_singleton()->print("Display options:\n");
  299. OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n");
  300. OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n");
  301. OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n");
  302. OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n");
  303. OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n");
  304. OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
  305. OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
  306. OS::get_singleton()->print("\n");
  307. OS::get_singleton()->print("Debug options:\n");
  308. OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n");
  309. OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
  310. OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
  311. OS::get_singleton()->print(" --gpu-profile Show a GPU profile of the tasks that took the most time during frame rendering.\n");
  312. OS::get_singleton()->print(" --gpu-validation Enable graphics API validation layers for debugging.\n");
  313. #if DEBUG_ENABLED
  314. OS::get_singleton()->print(" --gpu-abort Abort on graphics API usage errors (usually validation layer errors). May help see the problem if your system freezes.\n");
  315. #endif
  316. OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
  317. #if defined(DEBUG_ENABLED)
  318. OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
  319. OS::get_singleton()->print(" --debug-paths Show path lines when running the scene.\n");
  320. OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
  321. OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
  322. #endif
  323. OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
  324. OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
  325. OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
  326. OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n");
  327. OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
  328. OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n");
  329. OS::get_singleton()->print("\n");
  330. OS::get_singleton()->print("Standalone tools:\n");
  331. OS::get_singleton()->print(" -s, --script <script> Run a script.\n");
  332. OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n");
  333. #ifdef TOOLS_ENABLED
  334. OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n");
  335. OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n");
  336. OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
  337. OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n");
  338. OS::get_singleton()->print(" --convert-3to4 Converts project from Godot 3.x to Godot 4.x.\n");
  339. OS::get_singleton()->print(" --validate-conversion-3to4 Shows what elements will be renamed when converting project from Godot 3.x to Godot 4.x.\n");
  340. OS::get_singleton()->print(" --doctool [<path>] Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.\n");
  341. OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
  342. OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n");
  343. OS::get_singleton()->print(" --dump-extension-api Generate JSON dump of the Godot API for GDExtension bindings named 'extension_api.json' in the current folder.\n");
  344. #ifdef TESTS_ENABLED
  345. OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n");
  346. #endif
  347. #endif
  348. OS::get_singleton()->print("\n");
  349. }
  350. #ifdef TESTS_ENABLED
  351. // The order is the same as in `Main::setup()`, only core and some editor types
  352. // are initialized here. This also combines `Main::setup2()` initialization.
  353. Error Main::test_setup() {
  354. OS::get_singleton()->initialize();
  355. engine = memnew(Engine);
  356. register_core_types();
  357. register_core_driver_types();
  358. packed_data = memnew(PackedData);
  359. globals = memnew(ProjectSettings);
  360. GLOBAL_DEF("debug/settings/crash_handler/message",
  361. String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
  362. GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2);
  363. translation_server = memnew(TranslationServer);
  364. tsman = memnew(TextServerManager);
  365. if (tsman) {
  366. Ref<TextServerDummy> ts;
  367. ts.instantiate();
  368. tsman->add_interface(ts);
  369. }
  370. // From `Main::setup2()`.
  371. initialize_modules(MODULE_INITIALIZATION_LEVEL_CORE);
  372. register_core_extensions();
  373. register_core_singletons();
  374. /** INITIALIZE SERVERS **/
  375. register_server_types();
  376. initialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS);
  377. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS);
  378. translation_server->setup(); //register translations, load them, etc.
  379. if (!locale.is_empty()) {
  380. translation_server->set_locale(locale);
  381. }
  382. translation_server->load_translations();
  383. ResourceLoader::load_translation_remaps(); //load remaps for resources
  384. ResourceLoader::load_path_remaps();
  385. register_scene_types();
  386. register_driver_types();
  387. initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
  388. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
  389. #ifdef TOOLS_ENABLED
  390. ClassDB::set_current_api(ClassDB::API_EDITOR);
  391. EditorNode::register_editor_types();
  392. initialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR);
  393. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_EDITOR);
  394. ClassDB::set_current_api(ClassDB::API_CORE);
  395. #endif
  396. register_platform_apis();
  397. // Theme needs modules to be initialized so that sub-resources can be loaded.
  398. initialize_theme();
  399. ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE);
  400. /* Use one with the most features available. */
  401. int max_features = 0;
  402. for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
  403. uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features();
  404. int feature_number = 0;
  405. while (features) {
  406. feature_number += features & 1;
  407. features >>= 1;
  408. }
  409. if (feature_number >= max_features) {
  410. max_features = feature_number;
  411. text_driver_idx = i;
  412. }
  413. }
  414. if (text_driver_idx >= 0) {
  415. TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx));
  416. } else {
  417. ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface.");
  418. }
  419. ClassDB::set_current_api(ClassDB::API_NONE);
  420. _start_success = true;
  421. return OK;
  422. }
  423. // The order is the same as in `Main::cleanup()`.
  424. void Main::test_cleanup() {
  425. ERR_FAIL_COND(!_start_success);
  426. EngineDebugger::deinitialize();
  427. ResourceLoader::remove_custom_loaders();
  428. ResourceSaver::remove_custom_savers();
  429. #ifdef TOOLS_ENABLED
  430. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_EDITOR);
  431. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR);
  432. EditorNode::unregister_editor_types();
  433. #endif
  434. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
  435. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
  436. unregister_platform_apis();
  437. unregister_driver_types();
  438. unregister_scene_types();
  439. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS);
  440. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS);
  441. unregister_server_types();
  442. OS::get_singleton()->finalize();
  443. if (translation_server) {
  444. memdelete(translation_server);
  445. }
  446. if (tsman) {
  447. memdelete(tsman);
  448. }
  449. if (globals) {
  450. memdelete(globals);
  451. }
  452. if (packed_data) {
  453. memdelete(packed_data);
  454. }
  455. if (engine) {
  456. memdelete(engine);
  457. }
  458. unregister_core_driver_types();
  459. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_CORE);
  460. unregister_core_extensions();
  461. unregister_core_types();
  462. OS::get_singleton()->finalize_core();
  463. }
  464. #endif
  465. int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
  466. #ifdef TESTS_ENABLED
  467. for (int x = 0; x < argc; x++) {
  468. if ((strncmp(argv[x], "--test", 6) == 0) && (strlen(argv[x]) == 6)) {
  469. tests_need_run = true;
  470. // TODO: need to come up with different test contexts.
  471. // Not every test requires high-level functionality like `ClassDB`.
  472. test_setup();
  473. int status = test_main(argc, argv);
  474. test_cleanup();
  475. return status;
  476. }
  477. }
  478. #endif
  479. tests_need_run = false;
  480. return 0;
  481. }
  482. /* Engine initialization
  483. *
  484. * Consists of several methods that are called by each platform's specific main(argc, argv).
  485. * To fully understand engine init, one should therefore start from the platform's main and
  486. * see how it calls into the Main class' methods.
  487. *
  488. * The initialization is typically done in 3 steps (with the setup2 step triggered either
  489. * automatically by setup, or manually in the platform's main).
  490. *
  491. * - setup(execpath, argc, argv, p_second_phase) is the main entry point for all platforms,
  492. * responsible for the initialization of all low level singletons and core types, and parsing
  493. * command line arguments to configure things accordingly.
  494. * If p_second_phase is true, it will chain into setup2() (default behaviour). This is
  495. * disabled on some platforms (Android, iOS, UWP) which trigger the second step in their
  496. * own time.
  497. *
  498. * - setup2(p_main_tid_override) registers high level servers and singletons, displays the
  499. * boot splash, then registers higher level types (scene, editor, etc.).
  500. *
  501. * - start() is the last step and that's where command line tools can run, or the main loop
  502. * can be created eventually and the project settings put into action. That's also where
  503. * the editor node is created, if relevant.
  504. * start() does it own argument parsing for a subset of the command line arguments described
  505. * in help, it's a bit messy and should be globalized with the setup() parsing somehow.
  506. */
  507. Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
  508. OS::get_singleton()->initialize();
  509. engine = memnew(Engine);
  510. MAIN_PRINT("Main: Initialize CORE");
  511. register_core_types();
  512. register_core_driver_types();
  513. MAIN_PRINT("Main: Initialize Globals");
  514. input_map = memnew(InputMap);
  515. time_singleton = memnew(Time);
  516. globals = memnew(ProjectSettings);
  517. register_core_settings(); //here globals are present
  518. translation_server = memnew(TranslationServer);
  519. performance = memnew(Performance);
  520. GDREGISTER_CLASS(Performance);
  521. engine->add_singleton(Engine::Singleton("Performance", performance));
  522. // Only flush stdout in debug builds by default, as spamming `print()` will
  523. // decrease performance if this is enabled.
  524. GLOBAL_DEF_RST("application/run/flush_stdout_on_print", false);
  525. GLOBAL_DEF_RST("application/run/flush_stdout_on_print.debug", true);
  526. GLOBAL_DEF("debug/settings/crash_handler/message",
  527. String("Please include this when reporting the bug to the project developer."));
  528. GLOBAL_DEF("debug/settings/crash_handler/message.editor",
  529. String("Please include this when reporting the bug on: https://github.com/godotengine/godot/issues"));
  530. MAIN_PRINT("Main: Parse CMDLine");
  531. /* argument parsing and main creation */
  532. List<String> args;
  533. List<String> main_args;
  534. List<String> platform_args = OS::get_singleton()->get_cmdline_platform_args();
  535. // Add command line arguments.
  536. for (int i = 0; i < argc; i++) {
  537. args.push_back(String::utf8(argv[i]));
  538. }
  539. // Add arguments received from macOS LaunchService (URL schemas, file associations).
  540. for (const String &arg : platform_args) {
  541. args.push_back(arg);
  542. }
  543. List<String>::Element *I = args.front();
  544. while (I) {
  545. I->get() = unescape_cmdline(I->get().strip_edges());
  546. I = I->next();
  547. }
  548. String display_driver = "";
  549. String audio_driver = "";
  550. String project_path = ".";
  551. bool upwards = false;
  552. String debug_uri = "";
  553. bool skip_breakpoints = false;
  554. String main_pack;
  555. bool quiet_stdout = false;
  556. int rtm = -1;
  557. String remotefs;
  558. String remotefs_pass;
  559. Vector<String> breakpoints;
  560. bool use_custom_res = true;
  561. bool force_res = false;
  562. #ifdef TOOLS_ENABLED
  563. bool found_project = false;
  564. #endif
  565. String default_renderer = "";
  566. String renderer_hints = "";
  567. packed_data = PackedData::get_singleton();
  568. if (!packed_data) {
  569. packed_data = memnew(PackedData);
  570. }
  571. #ifdef MINIZIP_ENABLED
  572. //XXX: always get_singleton() == 0x0
  573. zip_packed_data = ZipArchive::get_singleton();
  574. //TODO: remove this temporary fix
  575. if (!zip_packed_data) {
  576. zip_packed_data = memnew(ZipArchive);
  577. }
  578. packed_data->add_pack_source(zip_packed_data);
  579. #endif
  580. // Default exit code, can be modified for certain errors.
  581. Error exit_code = ERR_INVALID_PARAMETER;
  582. I = args.front();
  583. while (I) {
  584. #ifdef MACOS_ENABLED
  585. // Ignore the process serial number argument passed by macOS Gatekeeper.
  586. // Otherwise, Godot would try to open a non-existent project on the first start and abort.
  587. if (I->get().begins_with("-psn_")) {
  588. I = I->next();
  589. continue;
  590. }
  591. #endif
  592. List<String>::Element *N = I->next();
  593. if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help
  594. show_help = true;
  595. exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
  596. goto error;
  597. } else if (I->get() == "--version") {
  598. print_line(get_full_version_string());
  599. exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
  600. goto error;
  601. } else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output
  602. OS::get_singleton()->_verbose_stdout = true;
  603. } else if (I->get() == "-q" || I->get() == "--quiet") { // quieter output
  604. quiet_stdout = true;
  605. } else if (I->get() == "--audio-driver") { // audio driver
  606. if (I->next()) {
  607. audio_driver = I->next()->get();
  608. bool found = false;
  609. for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
  610. if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
  611. found = true;
  612. }
  613. }
  614. if (!found) {
  615. OS::get_singleton()->print("Unknown audio driver '%s', aborting.\nValid options are ",
  616. audio_driver.utf8().get_data());
  617. for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
  618. if (i == AudioDriverManager::get_driver_count() - 1) {
  619. OS::get_singleton()->print(" and ");
  620. } else if (i != 0) {
  621. OS::get_singleton()->print(", ");
  622. }
  623. OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name());
  624. }
  625. OS::get_singleton()->print(".\n");
  626. goto error;
  627. }
  628. N = I->next()->next();
  629. } else {
  630. OS::get_singleton()->print("Missing audio driver argument, aborting.\n");
  631. goto error;
  632. }
  633. } else if (I->get() == "--text-driver") {
  634. if (I->next()) {
  635. text_driver = I->next()->get();
  636. N = I->next()->next();
  637. } else {
  638. OS::get_singleton()->print("Missing text driver argument, aborting.\n");
  639. goto error;
  640. }
  641. } else if (I->get() == "--display-driver") { // force video driver
  642. if (I->next()) {
  643. display_driver = I->next()->get();
  644. bool found = false;
  645. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  646. if (display_driver == DisplayServer::get_create_function_name(i)) {
  647. found = true;
  648. }
  649. }
  650. if (!found) {
  651. OS::get_singleton()->print("Unknown display driver '%s', aborting.\nValid options are ",
  652. display_driver.utf8().get_data());
  653. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  654. if (i == DisplayServer::get_create_function_count() - 1) {
  655. OS::get_singleton()->print(" and ");
  656. } else if (i != 0) {
  657. OS::get_singleton()->print(", ");
  658. }
  659. OS::get_singleton()->print("'%s'", DisplayServer::get_create_function_name(i));
  660. }
  661. OS::get_singleton()->print(".\n");
  662. goto error;
  663. }
  664. N = I->next()->next();
  665. } else {
  666. OS::get_singleton()->print("Missing display driver argument, aborting.\n");
  667. goto error;
  668. }
  669. } else if (I->get() == "--rendering-driver") {
  670. if (I->next()) {
  671. rendering_driver = I->next()->get();
  672. // as the rendering drivers available may depend on the display driver selected,
  673. // we can't do an exhaustive check here, but we can look through all the options in
  674. // all the display drivers for a match
  675. bool found = false;
  676. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  677. Vector<String> r_drivers = DisplayServer::get_create_function_rendering_drivers(i);
  678. for (int d = 0; d < r_drivers.size(); d++) {
  679. if (rendering_driver == r_drivers[d]) {
  680. found = true;
  681. break;
  682. }
  683. }
  684. }
  685. if (!found) {
  686. OS::get_singleton()->print("Unknown rendering driver '%s', aborting.\nValid options are ",
  687. rendering_driver.utf8().get_data());
  688. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  689. Vector<String> r_drivers = DisplayServer::get_create_function_rendering_drivers(i);
  690. for (int d = 0; d < r_drivers.size(); d++) {
  691. OS::get_singleton()->print("'%s', ", r_drivers[d].utf8().get_data());
  692. }
  693. }
  694. OS::get_singleton()->print(".\n");
  695. goto error;
  696. }
  697. N = I->next()->next();
  698. } else {
  699. OS::get_singleton()->print("Missing rendering driver argument, aborting.\n");
  700. goto error;
  701. }
  702. } else if (I->get() == "-f" || I->get() == "--fullscreen") { // force fullscreen
  703. init_fullscreen = true;
  704. } else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window
  705. init_maximized = true;
  706. window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
  707. } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window
  708. init_windowed = true;
  709. } else if (I->get() == "--gpu-index") {
  710. if (I->next()) {
  711. Engine::singleton->gpu_idx = I->next()->get().to_int();
  712. N = I->next()->next();
  713. } else {
  714. OS::get_singleton()->print("Missing GPU index argument, aborting.\n");
  715. goto error;
  716. }
  717. } else if (I->get() == "--gpu-validation") {
  718. Engine::singleton->use_validation_layers = true;
  719. #ifdef DEBUG_ENABLED
  720. } else if (I->get() == "--gpu-abort") {
  721. Engine::singleton->abort_on_gpu_errors = true;
  722. #endif
  723. } else if (I->get() == "--tablet-driver") {
  724. if (I->next()) {
  725. tablet_driver = I->next()->get();
  726. N = I->next()->next();
  727. } else {
  728. OS::get_singleton()->print("Missing tablet driver argument, aborting.\n");
  729. goto error;
  730. }
  731. } else if (I->get() == "--single-window") { // force single window
  732. OS::get_singleton()->_single_window = true;
  733. } else if (I->get() == "-t" || I->get() == "--always-on-top") { // force always-on-top window
  734. init_always_on_top = true;
  735. } else if (I->get() == "--resolution") { // force resolution
  736. if (I->next()) {
  737. String vm = I->next()->get();
  738. if (!vm.contains("x")) { // invalid parameter format
  739. OS::get_singleton()->print("Invalid resolution '%s', it should be e.g. '1280x720'.\n",
  740. vm.utf8().get_data());
  741. goto error;
  742. }
  743. int w = vm.get_slice("x", 0).to_int();
  744. int h = vm.get_slice("x", 1).to_int();
  745. if (w <= 0 || h <= 0) {
  746. OS::get_singleton()->print("Invalid resolution '%s', width and height must be above 0.\n",
  747. vm.utf8().get_data());
  748. goto error;
  749. }
  750. window_size.width = w;
  751. window_size.height = h;
  752. force_res = true;
  753. N = I->next()->next();
  754. } else {
  755. OS::get_singleton()->print("Missing resolution argument, aborting.\n");
  756. goto error;
  757. }
  758. } else if (I->get() == "--position") { // set window position
  759. if (I->next()) {
  760. String vm = I->next()->get();
  761. if (!vm.contains(",")) { // invalid parameter format
  762. OS::get_singleton()->print("Invalid position '%s', it should be e.g. '80,128'.\n",
  763. vm.utf8().get_data());
  764. goto error;
  765. }
  766. int x = vm.get_slice(",", 0).to_int();
  767. int y = vm.get_slice(",", 1).to_int();
  768. init_custom_pos = Point2(x, y);
  769. init_use_custom_pos = true;
  770. N = I->next()->next();
  771. } else {
  772. OS::get_singleton()->print("Missing position argument, aborting.\n");
  773. goto error;
  774. }
  775. } else if (I->get() == "--headless") { // enable headless mode (no audio, no rendering).
  776. audio_driver = "Dummy";
  777. display_driver = "headless";
  778. } else if (I->get() == "--profiling") { // enable profiling
  779. use_debug_profiler = true;
  780. } else if (I->get() == "-l" || I->get() == "--language") { // language
  781. if (I->next()) {
  782. locale = I->next()->get();
  783. N = I->next()->next();
  784. } else {
  785. OS::get_singleton()->print("Missing language argument, aborting.\n");
  786. goto error;
  787. }
  788. } else if (I->get() == "--remote-fs") { // remote filesystem
  789. if (I->next()) {
  790. remotefs = I->next()->get();
  791. N = I->next()->next();
  792. } else {
  793. OS::get_singleton()->print("Missing remote filesystem address, aborting.\n");
  794. goto error;
  795. }
  796. } else if (I->get() == "--remote-fs-password") { // remote filesystem password
  797. if (I->next()) {
  798. remotefs_pass = I->next()->get();
  799. N = I->next()->next();
  800. } else {
  801. OS::get_singleton()->print("Missing remote filesystem password, aborting.\n");
  802. goto error;
  803. }
  804. } else if (I->get() == "--render-thread") { // render thread mode
  805. if (I->next()) {
  806. if (I->next()->get() == "safe") {
  807. rtm = OS::RENDER_THREAD_SAFE;
  808. } else if (I->next()->get() == "unsafe") {
  809. rtm = OS::RENDER_THREAD_UNSAFE;
  810. } else if (I->next()->get() == "separate") {
  811. rtm = OS::RENDER_SEPARATE_THREAD;
  812. }
  813. N = I->next()->next();
  814. } else {
  815. OS::get_singleton()->print("Missing render thread mode argument, aborting.\n");
  816. goto error;
  817. }
  818. #ifdef TOOLS_ENABLED
  819. } else if (I->get() == "-e" || I->get() == "--editor") { // starts editor
  820. editor = true;
  821. } else if (I->get() == "-p" || I->get() == "--project-manager") { // starts project manager
  822. project_manager = true;
  823. } else if (I->get() == "--debug-server") {
  824. if (I->next()) {
  825. debug_server_uri = I->next()->get();
  826. if (!debug_server_uri.contains("://")) { // wrong address
  827. OS::get_singleton()->print("Invalid debug server uri. It should be of the form <protocol>://<bind_address>:<port>.\n");
  828. goto error;
  829. }
  830. N = I->next()->next();
  831. } else {
  832. OS::get_singleton()->print("Missing remote debug server uri, aborting.\n");
  833. goto error;
  834. }
  835. } else if (I->get() == "--build-solutions") { // Build the scripting solution such C#
  836. auto_build_solutions = true;
  837. editor = true;
  838. cmdline_tool = true;
  839. } else if (I->get() == "--dump-extension-api") {
  840. // Register as an editor instance to use low-end fallback if relevant.
  841. editor = true;
  842. cmdline_tool = true;
  843. dump_extension_api = true;
  844. print_line("Dumping Extension API");
  845. // Hack. Not needed but otherwise we end up detecting that this should
  846. // run the project instead of a cmdline tool.
  847. // Needs full refactoring to fix properly.
  848. main_args.push_back(I->get());
  849. } else if (I->get() == "--export" || I->get() == "--export-debug" ||
  850. I->get() == "--export-pack") { // Export project
  851. // Actually handling is done in start().
  852. editor = true;
  853. cmdline_tool = true;
  854. main_args.push_back(I->get());
  855. } else if (I->get() == "--convert-3to4") {
  856. // Actually handling is done in start().
  857. cmdline_tool = true;
  858. main_args.push_back(I->get());
  859. } else if (I->get() == "--validate-conversion-3to4") {
  860. // Actually handling is done in start().
  861. cmdline_tool = true;
  862. main_args.push_back(I->get());
  863. } else if (I->get() == "--doctool") {
  864. // Actually handling is done in start().
  865. cmdline_tool = true;
  866. // `--doctool` implies `--headless` to avoid spawning an unnecessary window
  867. // and speed up class reference generation.
  868. audio_driver = "Dummy";
  869. display_driver = "headless";
  870. main_args.push_back(I->get());
  871. #endif
  872. } else if (I->get() == "--path") { // set path of project to start or edit
  873. if (I->next()) {
  874. String p = I->next()->get();
  875. if (OS::get_singleton()->set_cwd(p) != OK) {
  876. OS::get_singleton()->print("Invalid project path specified: \"%s\", aborting.\n", p.utf8().get_data());
  877. goto error;
  878. }
  879. N = I->next()->next();
  880. } else {
  881. OS::get_singleton()->print("Missing relative or absolute path, aborting.\n");
  882. goto error;
  883. }
  884. } else if (I->get() == "-u" || I->get() == "--upwards") { // scan folders upwards
  885. upwards = true;
  886. } else if (I->get() == "--quit") { // Auto quit at the end of the first main loop iteration
  887. auto_quit = true;
  888. } else if (I->get().ends_with("project.godot")) {
  889. String path;
  890. String file = I->get();
  891. int sep = MAX(file.rfind("/"), file.rfind("\\"));
  892. if (sep == -1) {
  893. path = ".";
  894. } else {
  895. path = file.substr(0, sep);
  896. }
  897. if (OS::get_singleton()->set_cwd(path) == OK) {
  898. // path already specified, don't override
  899. } else {
  900. project_path = path;
  901. }
  902. #ifdef TOOLS_ENABLED
  903. editor = true;
  904. #endif
  905. } else if (I->get() == "-b" || I->get() == "--breakpoints") { // add breakpoints
  906. if (I->next()) {
  907. String bplist = I->next()->get();
  908. breakpoints = bplist.split(",");
  909. N = I->next()->next();
  910. } else {
  911. OS::get_singleton()->print("Missing list of breakpoints, aborting.\n");
  912. goto error;
  913. }
  914. } else if (I->get() == "--frame-delay") { // force frame delay
  915. if (I->next()) {
  916. frame_delay = I->next()->get().to_int();
  917. N = I->next()->next();
  918. } else {
  919. OS::get_singleton()->print("Missing frame delay argument, aborting.\n");
  920. goto error;
  921. }
  922. } else if (I->get() == "--time-scale") { // force time scale
  923. if (I->next()) {
  924. Engine::get_singleton()->set_time_scale(I->next()->get().to_float());
  925. N = I->next()->next();
  926. } else {
  927. OS::get_singleton()->print("Missing time scale argument, aborting.\n");
  928. goto error;
  929. }
  930. } else if (I->get() == "--main-pack") {
  931. if (I->next()) {
  932. main_pack = I->next()->get();
  933. N = I->next()->next();
  934. } else {
  935. OS::get_singleton()->print("Missing path to main pack file, aborting.\n");
  936. goto error;
  937. };
  938. } else if (I->get() == "-d" || I->get() == "--debug") {
  939. debug_uri = "local://";
  940. OS::get_singleton()->_debug_stdout = true;
  941. #if defined(DEBUG_ENABLED)
  942. } else if (I->get() == "--debug-collisions") {
  943. debug_collisions = true;
  944. } else if (I->get() == "--debug-paths") {
  945. debug_paths = true;
  946. } else if (I->get() == "--debug-navigation") {
  947. debug_navigation = true;
  948. } else if (I->get() == "--debug-stringnames") {
  949. StringName::set_debug_stringnames(true);
  950. #endif
  951. } else if (I->get() == "--remote-debug") {
  952. if (I->next()) {
  953. debug_uri = I->next()->get();
  954. if (!debug_uri.contains("://")) { // wrong address
  955. OS::get_singleton()->print(
  956. "Invalid debug host address, it should be of the form <protocol>://<host/IP>:<port>.\n");
  957. goto error;
  958. }
  959. N = I->next()->next();
  960. } else {
  961. OS::get_singleton()->print("Missing remote debug host address, aborting.\n");
  962. goto error;
  963. }
  964. } else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user
  965. if (I->next()) {
  966. allow_focus_steal_pid = I->next()->get().to_int();
  967. N = I->next()->next();
  968. } else {
  969. OS::get_singleton()->print("Missing editor PID argument, aborting.\n");
  970. goto error;
  971. }
  972. } else if (I->get() == "--disable-render-loop") {
  973. disable_render_loop = true;
  974. } else if (I->get() == "--fixed-fps") {
  975. if (I->next()) {
  976. fixed_fps = I->next()->get().to_int();
  977. N = I->next()->next();
  978. } else {
  979. OS::get_singleton()->print("Missing fixed-fps argument, aborting.\n");
  980. goto error;
  981. }
  982. } else if (I->get() == "--write-movie") {
  983. if (I->next()) {
  984. write_movie_path = I->next()->get();
  985. N = I->next()->next();
  986. if (fixed_fps == -1) {
  987. fixed_fps = 60;
  988. }
  989. OS::get_singleton()->_writing_movie = true;
  990. } else {
  991. OS::get_singleton()->print("Missing write-movie argument, aborting.\n");
  992. goto error;
  993. }
  994. } else if (I->get() == "--disable-vsync") {
  995. disable_vsync = true;
  996. } else if (I->get() == "--print-fps") {
  997. print_fps = true;
  998. } else if (I->get() == "--profile-gpu") {
  999. profile_gpu = true;
  1000. } else if (I->get() == "--disable-crash-handler") {
  1001. OS::get_singleton()->disable_crash_handler();
  1002. } else if (I->get() == "--skip-breakpoints") {
  1003. skip_breakpoints = true;
  1004. } else {
  1005. main_args.push_back(I->get());
  1006. }
  1007. I = N;
  1008. }
  1009. #ifdef TOOLS_ENABLED
  1010. if (editor && project_manager) {
  1011. OS::get_singleton()->print(
  1012. "Error: Command line arguments implied opening both editor and project manager, which is not possible. Aborting.\n");
  1013. goto error;
  1014. }
  1015. #endif
  1016. // Network file system needs to be configured before globals, since globals are based on the
  1017. // 'project.godot' file which will only be available through the network if this is enabled
  1018. FileAccessNetwork::configure();
  1019. if (!remotefs.is_empty()) {
  1020. file_access_network_client = memnew(FileAccessNetworkClient);
  1021. int port;
  1022. if (remotefs.contains(":")) {
  1023. port = remotefs.get_slicec(':', 1).to_int();
  1024. remotefs = remotefs.get_slicec(':', 0);
  1025. } else {
  1026. port = 6010;
  1027. }
  1028. Error err = file_access_network_client->connect(remotefs, port, remotefs_pass);
  1029. if (err) {
  1030. OS::get_singleton()->printerr("Could not connect to remotefs: %s:%i.\n", remotefs.utf8().get_data(), port);
  1031. goto error;
  1032. }
  1033. FileAccess::make_default<FileAccessNetwork>(FileAccess::ACCESS_RESOURCES);
  1034. }
  1035. if (globals->setup(project_path, main_pack, upwards, editor) == OK) {
  1036. #ifdef TOOLS_ENABLED
  1037. found_project = true;
  1038. #endif
  1039. } else {
  1040. #ifdef TOOLS_ENABLED
  1041. editor = false;
  1042. #else
  1043. const String error_msg = "Error: Couldn't load project data at path \"" + project_path + "\". Is the .pck file missing?\nIf you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n";
  1044. OS::get_singleton()->print("%s", error_msg.utf8().get_data());
  1045. OS::get_singleton()->alert(error_msg);
  1046. goto error;
  1047. #endif
  1048. }
  1049. // Initialize user data dir.
  1050. OS::get_singleton()->ensure_user_data_dir();
  1051. initialize_modules(MODULE_INITIALIZATION_LEVEL_CORE);
  1052. register_core_extensions(); // core extensions must be registered after globals setup and before display
  1053. ResourceUID::get_singleton()->load_from_cache(); // load UUIDs from cache.
  1054. GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60);
  1055. ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc",
  1056. PropertyInfo(Variant::INT,
  1057. "memory/limits/multithreaded_server/rid_pool_prealloc",
  1058. PROPERTY_HINT_RANGE,
  1059. "0,500,1")); // No negative and limit to 500 due to crashes
  1060. GLOBAL_DEF("network/limits/debugger/max_chars_per_second", 32768);
  1061. ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger/max_chars_per_second",
  1062. PropertyInfo(Variant::INT,
  1063. "network/limits/debugger/max_chars_per_second",
  1064. PROPERTY_HINT_RANGE,
  1065. "0, 4096, 1, or_greater"));
  1066. GLOBAL_DEF("network/limits/debugger/max_queued_messages", 2048);
  1067. ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger/max_queued_messages",
  1068. PropertyInfo(Variant::INT,
  1069. "network/limits/debugger/max_queued_messages",
  1070. PROPERTY_HINT_RANGE,
  1071. "0, 8192, 1, or_greater"));
  1072. GLOBAL_DEF("network/limits/debugger/max_errors_per_second", 400);
  1073. ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger/max_errors_per_second",
  1074. PropertyInfo(Variant::INT,
  1075. "network/limits/debugger/max_errors_per_second",
  1076. PROPERTY_HINT_RANGE,
  1077. "0, 200, 1, or_greater"));
  1078. GLOBAL_DEF("network/limits/debugger/max_warnings_per_second", 400);
  1079. ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger/max_warnings_per_second",
  1080. PropertyInfo(Variant::INT,
  1081. "network/limits/debugger/max_warnings_per_second",
  1082. PROPERTY_HINT_RANGE,
  1083. "0, 200, 1, or_greater"));
  1084. EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints);
  1085. #ifdef TOOLS_ENABLED
  1086. if (editor) {
  1087. packed_data->set_disabled(true);
  1088. globals->set_disable_feature_overrides(true);
  1089. Engine::get_singleton()->set_editor_hint(true);
  1090. main_args.push_back("--editor");
  1091. if (!init_windowed) {
  1092. init_maximized = true;
  1093. window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED;
  1094. }
  1095. }
  1096. if (!project_manager && !editor) {
  1097. // If we didn't find a project, we fall back to the project manager.
  1098. project_manager = !found_project && !cmdline_tool;
  1099. }
  1100. if (project_manager) {
  1101. Engine::get_singleton()->set_project_manager_hint(true);
  1102. }
  1103. #endif
  1104. GLOBAL_DEF("debug/file_logging/enable_file_logging", false);
  1105. // Only file logging by default on desktop platforms as logs can't be
  1106. // accessed easily on mobile/Web platforms (if at all).
  1107. // This also prevents logs from being created for the editor instance, as feature tags
  1108. // are disabled while in the editor (even if they should logically apply).
  1109. GLOBAL_DEF("debug/file_logging/enable_file_logging.pc", true);
  1110. GLOBAL_DEF("debug/file_logging/log_path", "user://logs/godot.log");
  1111. GLOBAL_DEF("debug/file_logging/max_log_files", 5);
  1112. ProjectSettings::get_singleton()->set_custom_property_info("debug/file_logging/max_log_files",
  1113. PropertyInfo(Variant::INT,
  1114. "debug/file_logging/max_log_files",
  1115. PROPERTY_HINT_RANGE,
  1116. "0,20,1,or_greater")); //no negative numbers
  1117. if (!project_manager && !editor && FileAccess::get_create_func(FileAccess::ACCESS_USERDATA) &&
  1118. GLOBAL_GET("debug/file_logging/enable_file_logging")) {
  1119. // Don't create logs for the project manager as they would be written to
  1120. // the current working directory, which is inconvenient.
  1121. String base_path = GLOBAL_GET("debug/file_logging/log_path");
  1122. int max_files = GLOBAL_GET("debug/file_logging/max_log_files");
  1123. OS::get_singleton()->add_logger(memnew(RotatedFileLogger(base_path, max_files)));
  1124. }
  1125. if (main_args.size() == 0 && String(GLOBAL_GET("application/run/main_scene")) == "") {
  1126. #ifdef TOOLS_ENABLED
  1127. if (!editor && !project_manager) {
  1128. #endif
  1129. const String error_msg = "Error: Can't run project: no main scene defined in the project.\n";
  1130. OS::get_singleton()->print("%s", error_msg.utf8().get_data());
  1131. OS::get_singleton()->alert(error_msg);
  1132. goto error;
  1133. #ifdef TOOLS_ENABLED
  1134. }
  1135. #endif
  1136. }
  1137. if (editor || project_manager) {
  1138. Engine::get_singleton()->set_editor_hint(true);
  1139. use_custom_res = false;
  1140. input_map->load_default(); //keys for editor
  1141. } else {
  1142. input_map->load_from_project_settings(); //keys for game
  1143. }
  1144. if (bool(ProjectSettings::get_singleton()->get("application/run/disable_stdout"))) {
  1145. quiet_stdout = true;
  1146. }
  1147. if (bool(ProjectSettings::get_singleton()->get("application/run/disable_stderr"))) {
  1148. _print_error_enabled = false;
  1149. };
  1150. if (quiet_stdout) {
  1151. _print_line_enabled = false;
  1152. }
  1153. Logger::set_flush_stdout_on_print(ProjectSettings::get_singleton()->get("application/run/flush_stdout_on_print"));
  1154. OS::get_singleton()->set_cmdline(execpath, main_args);
  1155. // possibly be worth changing the default from vulkan to something lower spec,
  1156. // for the project manager, depending on how smooth the fallback is.
  1157. // this list is hard coded, which makes it more difficult to add new backends.
  1158. // can potentially be changed to more of a plugin system at a later date.
  1159. // Start with Vulkan, which will be the default if enabled.
  1160. #ifdef VULKAN_ENABLED
  1161. renderer_hints = "vulkan";
  1162. #endif
  1163. // And OpenGL3 next, or first if Vulkan is disabled.
  1164. #ifdef GLES3_ENABLED
  1165. if (!renderer_hints.is_empty()) {
  1166. renderer_hints += ",";
  1167. }
  1168. renderer_hints += "opengl3";
  1169. #endif
  1170. if (renderer_hints.is_empty()) {
  1171. ERR_PRINT("No rendering driver available.");
  1172. }
  1173. default_renderer = renderer_hints.get_slice(",", 0);
  1174. GLOBAL_DEF_RST("rendering/driver/driver_name", default_renderer);
  1175. ProjectSettings::get_singleton()->set_custom_property_info("rendering/driver/driver_name",
  1176. PropertyInfo(Variant::STRING,
  1177. "rendering/driver/driver_name",
  1178. PROPERTY_HINT_ENUM, renderer_hints));
  1179. // if not set on the command line
  1180. if (rendering_driver.is_empty()) {
  1181. rendering_driver = GLOBAL_GET("rendering/driver/driver_name");
  1182. }
  1183. // note this is the desired rendering driver, it doesn't mean we will get it.
  1184. // TODO - make sure this is updated in the case of fallbacks, so that the user interface
  1185. // shows the correct driver string.
  1186. OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
  1187. // always convert to lower case for consistency in the code
  1188. rendering_driver = rendering_driver.to_lower();
  1189. if (use_custom_res) {
  1190. if (!force_res) {
  1191. window_size.width = GLOBAL_GET("display/window/size/viewport_width");
  1192. window_size.height = GLOBAL_GET("display/window/size/viewport_height");
  1193. if (globals->has_setting("display/window/size/window_width_override") &&
  1194. globals->has_setting("display/window/size/window_height_override")) {
  1195. int desired_width = globals->get("display/window/size/window_width_override");
  1196. if (desired_width > 0) {
  1197. window_size.width = desired_width;
  1198. }
  1199. int desired_height = globals->get("display/window/size/window_height_override");
  1200. if (desired_height > 0) {
  1201. window_size.height = desired_height;
  1202. }
  1203. }
  1204. }
  1205. if (!bool(GLOBAL_GET("display/window/size/resizable"))) {
  1206. window_flags |= DisplayServer::WINDOW_FLAG_RESIZE_DISABLED_BIT;
  1207. }
  1208. if (bool(GLOBAL_GET("display/window/size/borderless"))) {
  1209. window_flags |= DisplayServer::WINDOW_FLAG_BORDERLESS_BIT;
  1210. }
  1211. if (bool(GLOBAL_GET("display/window/size/fullscreen"))) {
  1212. window_mode = DisplayServer::WINDOW_MODE_FULLSCREEN;
  1213. }
  1214. if (bool(GLOBAL_GET("display/window/size/always_on_top"))) {
  1215. window_flags |= DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP_BIT;
  1216. }
  1217. }
  1218. GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
  1219. GLOBAL_DEF("internationalization/locale/include_text_server_data", false);
  1220. OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true);
  1221. // FIXME: Restore support.
  1222. #if 0
  1223. //OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
  1224. video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
  1225. #endif
  1226. if (editor || project_manager) {
  1227. // The editor and project manager always detect and use hiDPI if needed
  1228. OS::get_singleton()->_allow_hidpi = true;
  1229. OS::get_singleton()->_allow_layered = false;
  1230. }
  1231. OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
  1232. if (rtm == -1) {
  1233. rtm = GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE);
  1234. }
  1235. if (rtm >= 0 && rtm < 3) {
  1236. #ifdef NO_THREADS
  1237. rtm = OS::RENDER_THREAD_UNSAFE; // No threads available on this platform.
  1238. #else
  1239. if (editor) {
  1240. rtm = OS::RENDER_THREAD_SAFE;
  1241. }
  1242. #endif
  1243. OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm);
  1244. }
  1245. /* Determine audio and video drivers */
  1246. // Display driver, e.g. X11, Wayland.
  1247. // Make sure that headless is the last one, which it is assumed to be by design.
  1248. DEV_ASSERT(String("headless") == DisplayServer::get_create_function_name(DisplayServer::get_create_function_count() - 1));
  1249. for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
  1250. String name = DisplayServer::get_create_function_name(i);
  1251. if (display_driver == name) {
  1252. display_driver_idx = i;
  1253. break;
  1254. }
  1255. }
  1256. if (display_driver_idx < 0) {
  1257. // If the requested driver wasn't found, pick the first entry.
  1258. // If all else failed it would be the headless server.
  1259. display_driver_idx = 0;
  1260. }
  1261. // Store this in a globally accessible place, so we can retrieve the rendering drivers
  1262. // list from the display driver for the editor UI.
  1263. OS::get_singleton()->set_display_driver_id(display_driver_idx);
  1264. GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name());
  1265. if (audio_driver.is_empty()) { // Specified in project.godot.
  1266. audio_driver = GLOBAL_GET("audio/driver/driver");
  1267. }
  1268. // Make sure that dummy is the last one, which it is assumed to be by design.
  1269. DEV_ASSERT(String("Dummy") == AudioDriverManager::get_driver(AudioDriverManager::get_driver_count() - 1)->get_name());
  1270. for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
  1271. if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
  1272. audio_driver_idx = i;
  1273. break;
  1274. }
  1275. }
  1276. if (audio_driver_idx < 0) {
  1277. // If the requested driver wasn't found, pick the first entry.
  1278. // If all else failed it would be the dummy driver (no sound).
  1279. audio_driver_idx = 0;
  1280. }
  1281. if (write_movie_path != String()) {
  1282. // Always use dummy driver for audio driver (which is last), also in no threaded mode.
  1283. audio_driver_idx = AudioDriverManager::get_driver_count() - 1;
  1284. AudioDriverDummy::get_dummy_singleton()->set_use_threads(false);
  1285. }
  1286. {
  1287. window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE)));
  1288. }
  1289. {
  1290. window_vsync_mode = DisplayServer::VSyncMode(int(GLOBAL_DEF("display/window/vsync/vsync_mode", DisplayServer::VSyncMode::VSYNC_ENABLED)));
  1291. if (disable_vsync) {
  1292. window_vsync_mode = DisplayServer::VSyncMode::VSYNC_DISABLED;
  1293. }
  1294. }
  1295. Engine::get_singleton()->set_physics_ticks_per_second(GLOBAL_DEF_BASIC("physics/common/physics_ticks_per_second", 60));
  1296. ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_ticks_per_second",
  1297. PropertyInfo(Variant::INT, "physics/common/physics_ticks_per_second",
  1298. PROPERTY_HINT_RANGE, "1,1000,1"));
  1299. Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5));
  1300. Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0));
  1301. ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps",
  1302. PropertyInfo(Variant::INT,
  1303. "debug/settings/fps/force_fps",
  1304. PROPERTY_HINT_RANGE, "0,1000,1"));
  1305. GLOBAL_DEF("debug/settings/stdout/print_fps", false);
  1306. GLOBAL_DEF("debug/settings/stdout/print_gpu_profile", false);
  1307. GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
  1308. if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden.
  1309. OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout");
  1310. }
  1311. if (frame_delay == 0) {
  1312. frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0);
  1313. ProjectSettings::get_singleton()->set_custom_property_info("application/run/frame_delay_msec",
  1314. PropertyInfo(Variant::INT,
  1315. "application/run/frame_delay_msec",
  1316. PROPERTY_HINT_RANGE,
  1317. "0,100,1,or_greater")); // No negative numbers
  1318. }
  1319. OS::get_singleton()->set_low_processor_usage_mode(GLOBAL_DEF("application/run/low_processor_mode", false));
  1320. OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(
  1321. GLOBAL_DEF("application/run/low_processor_mode_sleep_usec", 6900)); // Roughly 144 FPS
  1322. ProjectSettings::get_singleton()->set_custom_property_info("application/run/low_processor_mode_sleep_usec",
  1323. PropertyInfo(Variant::INT,
  1324. "application/run/low_processor_mode_sleep_usec",
  1325. PROPERTY_HINT_RANGE,
  1326. "0,33200,1,or_greater")); // No negative numbers
  1327. GLOBAL_DEF("display/window/ios/hide_home_indicator", true);
  1328. GLOBAL_DEF("input_devices/pointing/ios/touch_delay", 0.15);
  1329. ProjectSettings::get_singleton()->set_custom_property_info("input_devices/pointing/ios/touch_delay",
  1330. PropertyInfo(Variant::FLOAT,
  1331. "input_devices/pointing/ios/touch_delay",
  1332. PROPERTY_HINT_RANGE, "0,1,0.001"));
  1333. // XR project settings.
  1334. GLOBAL_DEF_RST_BASIC("xr/openxr/enabled", false);
  1335. GLOBAL_DEF_BASIC("xr/openxr/default_action_map", "res://openxr_action_map.tres");
  1336. ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/default_action_map", PropertyInfo(Variant::STRING, "xr/openxr/default_action_map", PROPERTY_HINT_FILE, "*.tres"));
  1337. GLOBAL_DEF_BASIC("xr/openxr/form_factor", "0");
  1338. ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/form_factor", PropertyInfo(Variant::INT, "xr/openxr/form_factor", PROPERTY_HINT_ENUM, "Head Mounted,Handheld"));
  1339. GLOBAL_DEF_BASIC("xr/openxr/view_configuration", "1");
  1340. ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/view_configuration", PropertyInfo(Variant::INT, "xr/openxr/view_configuration", PROPERTY_HINT_ENUM, "Mono,Stereo")); // "Mono,Stereo,Quad,Observer"
  1341. GLOBAL_DEF_BASIC("xr/openxr/reference_space", "1");
  1342. ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/reference_space", PropertyInfo(Variant::INT, "xr/openxr/reference_space", PROPERTY_HINT_ENUM, "Local,Stage"));
  1343. #ifdef TOOLS_ENABLED
  1344. // Disabled for now, using XR inside of the editor we'll be working on during the coming months.
  1345. // editor settings (it seems we're too early in the process when setting up rendering, to access editor settings...)
  1346. // EDITOR_DEF_RST("xr/openxr/in_editor", false);
  1347. // GLOBAL_DEF("xr/openxr/in_editor", false);
  1348. #endif
  1349. Engine::get_singleton()->set_frame_delay(frame_delay);
  1350. message_queue = memnew(MessageQueue);
  1351. if (p_second_phase) {
  1352. return setup2();
  1353. }
  1354. return OK;
  1355. error:
  1356. text_driver = "";
  1357. display_driver = "";
  1358. audio_driver = "";
  1359. tablet_driver = "";
  1360. write_movie_path = "";
  1361. project_path = "";
  1362. args.clear();
  1363. main_args.clear();
  1364. if (show_help) {
  1365. print_help(execpath);
  1366. }
  1367. EngineDebugger::deinitialize();
  1368. if (performance) {
  1369. memdelete(performance);
  1370. }
  1371. if (input_map) {
  1372. memdelete(input_map);
  1373. }
  1374. if (time_singleton) {
  1375. memdelete(time_singleton);
  1376. }
  1377. if (translation_server) {
  1378. memdelete(translation_server);
  1379. }
  1380. if (globals) {
  1381. memdelete(globals);
  1382. }
  1383. if (engine) {
  1384. memdelete(engine);
  1385. }
  1386. if (packed_data) {
  1387. memdelete(packed_data);
  1388. }
  1389. if (file_access_network_client) {
  1390. memdelete(file_access_network_client);
  1391. }
  1392. unregister_core_driver_types();
  1393. unregister_core_extensions();
  1394. unregister_core_types();
  1395. OS::get_singleton()->_cmdline.clear();
  1396. if (message_queue) {
  1397. memdelete(message_queue);
  1398. }
  1399. OS::get_singleton()->finalize_core();
  1400. locale = String();
  1401. return exit_code;
  1402. }
  1403. Error Main::setup2(Thread::ID p_main_tid_override) {
  1404. tsman = memnew(TextServerManager);
  1405. if (tsman) {
  1406. Ref<TextServerDummy> ts;
  1407. ts.instantiate();
  1408. tsman->add_interface(ts);
  1409. }
  1410. register_server_types();
  1411. initialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS);
  1412. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS);
  1413. // Print engine name and version
  1414. print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
  1415. #if !defined(NO_THREADS)
  1416. if (p_main_tid_override) {
  1417. Thread::main_thread_id = p_main_tid_override;
  1418. }
  1419. #endif
  1420. #ifdef TOOLS_ENABLED
  1421. if (editor || project_manager || cmdline_tool) {
  1422. EditorPaths::create();
  1423. }
  1424. #endif
  1425. /* Initialize Input */
  1426. input = memnew(Input);
  1427. /* Initialize Display Server */
  1428. {
  1429. String display_driver = DisplayServer::get_create_function_name(display_driver_idx);
  1430. // rendering_driver now held in static global String in main and initialized in setup()
  1431. Error err;
  1432. display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
  1433. if (err != OK || display_server == nullptr) {
  1434. // We can't use this display server, try other ones as fallback.
  1435. // Skip headless (always last registered) because that's not what users
  1436. // would expect if they didn't request it explicitly.
  1437. for (int i = 0; i < DisplayServer::get_create_function_count() - 1; i++) {
  1438. if (i == display_driver_idx) {
  1439. continue; // Don't try the same twice.
  1440. }
  1441. display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err);
  1442. if (err == OK && display_server != nullptr) {
  1443. break;
  1444. }
  1445. }
  1446. }
  1447. if (err != OK || display_server == nullptr) {
  1448. ERR_PRINT("Unable to create DisplayServer, all display drivers failed.");
  1449. return err;
  1450. }
  1451. }
  1452. if (display_server->has_feature(DisplayServer::FEATURE_ORIENTATION)) {
  1453. display_server->screen_set_orientation(window_orientation);
  1454. }
  1455. if (GLOBAL_GET("debug/settings/stdout/print_fps") || print_fps) {
  1456. // Print requested V-Sync mode at startup to diagnose the printed FPS not going above the monitor refresh rate.
  1457. switch (window_vsync_mode) {
  1458. case DisplayServer::VSyncMode::VSYNC_DISABLED:
  1459. print_line("Requested V-Sync mode: Disabled");
  1460. break;
  1461. case DisplayServer::VSyncMode::VSYNC_ENABLED:
  1462. print_line("Requested V-Sync mode: Enabled - FPS will likely be capped to the monitor refresh rate.");
  1463. break;
  1464. case DisplayServer::VSyncMode::VSYNC_ADAPTIVE:
  1465. print_line("Requested V-Sync mode: Adaptive");
  1466. break;
  1467. case DisplayServer::VSyncMode::VSYNC_MAILBOX:
  1468. print_line("Requested V-Sync mode: Mailbox");
  1469. break;
  1470. }
  1471. }
  1472. /* Initialize Pen Tablet Driver */
  1473. {
  1474. GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver", "");
  1475. GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver.windows", "");
  1476. ProjectSettings::get_singleton()->set_custom_property_info("input_devices/pen_tablet/driver.windows", PropertyInfo(Variant::STRING, "input_devices/pen_tablet/driver.windows", PROPERTY_HINT_ENUM, "wintab,winink"));
  1477. }
  1478. if (tablet_driver.is_empty()) { // specified in project.godot
  1479. tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver");
  1480. if (tablet_driver.is_empty()) {
  1481. tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0);
  1482. }
  1483. }
  1484. for (int i = 0; i < DisplayServer::get_singleton()->tablet_get_driver_count(); i++) {
  1485. if (tablet_driver == DisplayServer::get_singleton()->tablet_get_driver_name(i)) {
  1486. DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(i));
  1487. break;
  1488. }
  1489. }
  1490. if (DisplayServer::get_singleton()->tablet_get_current_driver().is_empty()) {
  1491. DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0));
  1492. }
  1493. print_verbose("Using \"" + tablet_driver + "\" pen tablet driver...");
  1494. /* Initialize Rendering Server */
  1495. rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD));
  1496. rendering_server->init();
  1497. //rendering_server->call_set_use_vsync(OS::get_singleton()->_use_vsync);
  1498. rendering_server->set_render_loop_enabled(!disable_render_loop);
  1499. if (profile_gpu || (!editor && bool(GLOBAL_GET("debug/settings/stdout/print_gpu_profile")))) {
  1500. rendering_server->set_print_gpu_profile(true);
  1501. }
  1502. if (write_movie_path != String()) {
  1503. movie_writer = MovieWriter::find_writer_for_file(write_movie_path);
  1504. if (movie_writer == nullptr) {
  1505. ERR_PRINT("Can't find movie writer for file type, aborting: " + write_movie_path);
  1506. write_movie_path = String();
  1507. }
  1508. }
  1509. #ifdef UNIX_ENABLED
  1510. // Print warning after initializing the renderer but before initializing audio.
  1511. if (OS::get_singleton()->get_environment("USER") == "root" && !OS::get_singleton()->has_environment("GODOT_SILENCE_ROOT_WARNING")) {
  1512. WARN_PRINT("Started the engine as `root`/superuser. This is a security risk, and subsystems like audio may not work correctly.\nSet the environment variable `GODOT_SILENCE_ROOT_WARNING` to 1 to silence this warning.");
  1513. }
  1514. #endif
  1515. OS::get_singleton()->initialize_joypads();
  1516. /* Initialize Audio Driver */
  1517. AudioDriverManager::initialize(audio_driver_idx);
  1518. print_line(" "); //add a blank line for readability
  1519. if (init_use_custom_pos) {
  1520. display_server->window_set_position(init_custom_pos);
  1521. }
  1522. // right moment to create and initialize the audio server
  1523. audio_server = memnew(AudioServer);
  1524. audio_server->init();
  1525. // also init our xr_server from here
  1526. xr_server = memnew(XRServer);
  1527. register_core_singletons();
  1528. MAIN_PRINT("Main: Setup Logo");
  1529. #if defined(JAVASCRIPT_ENABLED) || defined(ANDROID_ENABLED)
  1530. bool show_logo = false;
  1531. #else
  1532. bool show_logo = true;
  1533. #endif
  1534. if (init_screen != -1) {
  1535. DisplayServer::get_singleton()->window_set_current_screen(init_screen);
  1536. }
  1537. if (init_windowed) {
  1538. //do none..
  1539. } else if (init_maximized) {
  1540. DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_MAXIMIZED);
  1541. } else if (init_fullscreen) {
  1542. DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_FULLSCREEN);
  1543. }
  1544. if (init_always_on_top) {
  1545. DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true);
  1546. }
  1547. if (allow_focus_steal_pid) {
  1548. DisplayServer::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid);
  1549. }
  1550. MAIN_PRINT("Main: Load Boot Image");
  1551. Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
  1552. RenderingServer::get_singleton()->set_default_clear_color(clear);
  1553. if (show_logo) { //boot logo!
  1554. const bool boot_logo_image = GLOBAL_DEF_BASIC("application/boot_splash/show_image", true);
  1555. const String boot_logo_path = String(GLOBAL_DEF_BASIC("application/boot_splash/image", String())).strip_edges();
  1556. const bool boot_logo_scale = GLOBAL_DEF_BASIC("application/boot_splash/fullsize", true);
  1557. const bool boot_logo_filter = GLOBAL_DEF_BASIC("application/boot_splash/use_filter", true);
  1558. ProjectSettings::get_singleton()->set_custom_property_info("application/boot_splash/image",
  1559. PropertyInfo(Variant::STRING,
  1560. "application/boot_splash/image",
  1561. PROPERTY_HINT_FILE, "*.png"));
  1562. Ref<Image> boot_logo;
  1563. if (boot_logo_image) {
  1564. if (!boot_logo_path.is_empty()) {
  1565. boot_logo.instantiate();
  1566. Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo);
  1567. if (load_err) {
  1568. ERR_PRINT("Non-existing or invalid boot splash at '" + boot_logo_path + "'. Loading default splash.");
  1569. }
  1570. }
  1571. } else {
  1572. // Create a 1×1 transparent image. This will effectively hide the splash image.
  1573. boot_logo.instantiate();
  1574. boot_logo->create(1, 1, false, Image::FORMAT_RGBA8);
  1575. boot_logo->set_pixel(0, 0, Color(0, 0, 0, 0));
  1576. }
  1577. #if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH)
  1578. const Color boot_bg_color =
  1579. GLOBAL_DEF_BASIC("application/boot_splash/bg_color",
  1580. (editor || project_manager) ? boot_splash_editor_bg_color : boot_splash_bg_color);
  1581. #else
  1582. const Color boot_bg_color = GLOBAL_DEF_BASIC("application/boot_splash/bg_color", boot_splash_bg_color);
  1583. #endif
  1584. if (boot_logo.is_valid()) {
  1585. RenderingServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale,
  1586. boot_logo_filter);
  1587. } else {
  1588. #ifndef NO_DEFAULT_BOOT_LOGO
  1589. MAIN_PRINT("Main: Create bootsplash");
  1590. #if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH)
  1591. Ref<Image> splash = (editor || project_manager) ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png));
  1592. #else
  1593. Ref<Image> splash = memnew(Image(boot_splash_png));
  1594. #endif
  1595. MAIN_PRINT("Main: ClearColor");
  1596. RenderingServer::get_singleton()->set_default_clear_color(boot_bg_color);
  1597. MAIN_PRINT("Main: Image");
  1598. RenderingServer::get_singleton()->set_boot_image(splash, boot_bg_color, false);
  1599. #endif
  1600. }
  1601. #ifdef TOOLS_ENABLED
  1602. if (OS::get_singleton()->get_bundle_icon_path().is_empty()) {
  1603. Ref<Image> icon = memnew(Image(app_icon_png));
  1604. DisplayServer::get_singleton()->set_icon(icon);
  1605. }
  1606. #endif
  1607. }
  1608. MAIN_PRINT("Main: DCC");
  1609. RenderingServer::get_singleton()->set_default_clear_color(
  1610. GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)));
  1611. GLOBAL_DEF("application/config/icon", String());
  1612. ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon",
  1613. PropertyInfo(Variant::STRING, "application/config/icon",
  1614. PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"));
  1615. GLOBAL_DEF("application/config/macos_native_icon", String());
  1616. ProjectSettings::get_singleton()->set_custom_property_info("application/config/macos_native_icon",
  1617. PropertyInfo(Variant::STRING,
  1618. "application/config/macos_native_icon",
  1619. PROPERTY_HINT_FILE, "*.icns"));
  1620. GLOBAL_DEF("application/config/windows_native_icon", String());
  1621. ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon",
  1622. PropertyInfo(Variant::STRING,
  1623. "application/config/windows_native_icon",
  1624. PROPERTY_HINT_FILE, "*.ico"));
  1625. Input *id = Input::get_singleton();
  1626. if (id) {
  1627. agile_input_event_flushing = GLOBAL_DEF("input_devices/buffering/agile_event_flushing", false);
  1628. if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) &&
  1629. !(editor || project_manager)) {
  1630. bool found_touchscreen = false;
  1631. for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
  1632. if (DisplayServer::get_singleton()->screen_is_touchscreen(i)) {
  1633. found_touchscreen = true;
  1634. }
  1635. }
  1636. if (!found_touchscreen) {
  1637. //only if no touchscreen ui hint, set emulation
  1638. id->set_emulate_touch_from_mouse(true);
  1639. }
  1640. }
  1641. id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true)));
  1642. }
  1643. MAIN_PRINT("Main: Load Translations and Remaps");
  1644. translation_server->setup(); //register translations, load them, etc.
  1645. if (!locale.is_empty()) {
  1646. translation_server->set_locale(locale);
  1647. }
  1648. translation_server->load_translations();
  1649. ResourceLoader::load_translation_remaps(); //load remaps for resources
  1650. ResourceLoader::load_path_remaps();
  1651. MAIN_PRINT("Main: Load TextServer");
  1652. /* Enum text drivers */
  1653. GLOBAL_DEF("internationalization/rendering/text_driver", "");
  1654. String text_driver_options;
  1655. for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
  1656. if (i > 0) {
  1657. text_driver_options += ",";
  1658. }
  1659. text_driver_options += TextServerManager::get_singleton()->get_interface(i)->get_name();
  1660. }
  1661. ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
  1662. /* Determine text driver */
  1663. if (text_driver.is_empty()) {
  1664. text_driver = GLOBAL_GET("internationalization/rendering/text_driver");
  1665. }
  1666. if (!text_driver.is_empty()) {
  1667. /* Load user selected text server. */
  1668. for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
  1669. if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) {
  1670. text_driver_idx = i;
  1671. break;
  1672. }
  1673. }
  1674. }
  1675. if (text_driver_idx < 0) {
  1676. /* If not selected, use one with the most features available. */
  1677. int max_features = 0;
  1678. for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
  1679. uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features();
  1680. int feature_number = 0;
  1681. while (features) {
  1682. feature_number += features & 1;
  1683. features >>= 1;
  1684. }
  1685. if (feature_number >= max_features) {
  1686. max_features = feature_number;
  1687. text_driver_idx = i;
  1688. }
  1689. }
  1690. }
  1691. if (text_driver_idx >= 0) {
  1692. TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx));
  1693. } else {
  1694. ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface.");
  1695. }
  1696. MAIN_PRINT("Main: Load Scene Types");
  1697. register_scene_types();
  1698. register_driver_types();
  1699. initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
  1700. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
  1701. #ifdef TOOLS_ENABLED
  1702. ClassDB::set_current_api(ClassDB::API_EDITOR);
  1703. EditorNode::register_editor_types();
  1704. initialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR);
  1705. NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_EDITOR);
  1706. ClassDB::set_current_api(ClassDB::API_CORE);
  1707. #endif
  1708. MAIN_PRINT("Main: Load Modules");
  1709. register_platform_apis();
  1710. // Theme needs modules to be initialized so that sub-resources can be loaded.
  1711. initialize_theme();
  1712. GLOBAL_DEF_BASIC("display/mouse_cursor/custom_image", String());
  1713. GLOBAL_DEF_BASIC("display/mouse_cursor/custom_image_hotspot", Vector2());
  1714. GLOBAL_DEF_BASIC("display/mouse_cursor/tooltip_position_offset", Point2(10, 10));
  1715. ProjectSettings::get_singleton()->set_custom_property_info("display/mouse_cursor/custom_image",
  1716. PropertyInfo(Variant::STRING,
  1717. "display/mouse_cursor/custom_image",
  1718. PROPERTY_HINT_FILE, "*.png,*.webp"));
  1719. if (String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")) != String()) {
  1720. Ref<Texture2D> cursor = ResourceLoader::load(
  1721. ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"));
  1722. if (cursor.is_valid()) {
  1723. Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
  1724. Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot);
  1725. }
  1726. }
  1727. camera_server = CameraServer::create();
  1728. MAIN_PRINT("Main: Load Physics");
  1729. initialize_physics();
  1730. initialize_navigation_server();
  1731. register_server_singletons();
  1732. // This loads global classes, so it must happen before custom loaders and savers are registered
  1733. ScriptServer::init_languages();
  1734. audio_server->load_default_bus_layout();
  1735. if (use_debug_profiler && EngineDebugger::is_active()) {
  1736. // Start the "scripts" profiler, used in local debugging.
  1737. // We could add more, and make the CLI arg require a comma-separated list of profilers.
  1738. EngineDebugger::get_singleton()->profiler_enable("scripts", true);
  1739. }
  1740. if (!project_manager) {
  1741. // If not running the project manager, and now that the engine is
  1742. // able to load resources, load the global shader variables.
  1743. // If running on editor, don't load the textures because the editor
  1744. // may want to import them first. Editor will reload those later.
  1745. rendering_server->global_variables_load_settings(!editor);
  1746. }
  1747. _start_success = true;
  1748. ClassDB::set_current_api(ClassDB::API_NONE); //no more APIs are registered at this point
  1749. print_verbose("CORE API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_CORE)));
  1750. print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
  1751. MAIN_PRINT("Main: Done");
  1752. return OK;
  1753. }
  1754. String Main::get_rendering_driver_name() {
  1755. return rendering_driver;
  1756. }
  1757. // everything the main loop needs to know about frame timings
  1758. static MainTimerSync main_timer_sync;
  1759. bool Main::start() {
  1760. ERR_FAIL_COND_V(!_start_success, false);
  1761. bool hasicon = false;
  1762. String positional_arg;
  1763. String game_path;
  1764. String script;
  1765. bool check_only = false;
  1766. #ifdef TOOLS_ENABLED
  1767. String doc_tool_path;
  1768. bool doc_base = true;
  1769. String _export_preset;
  1770. bool export_debug = false;
  1771. bool export_pack_only = false;
  1772. bool converting_project = false;
  1773. bool validating_converting_project = false;
  1774. #endif
  1775. main_timer_sync.init(OS::get_singleton()->get_ticks_usec());
  1776. List<String> args = OS::get_singleton()->get_cmdline_args();
  1777. for (int i = 0; i < args.size(); i++) {
  1778. // First check parameters that do not have an argument to the right.
  1779. // Doctest Unit Testing Handler
  1780. // Designed to override and pass arguments to the unit test handler.
  1781. if (args[i] == "--check-only") {
  1782. check_only = true;
  1783. #ifdef TOOLS_ENABLED
  1784. } else if (args[i] == "--no-docbase") {
  1785. doc_base = false;
  1786. } else if (args[i] == "--convert-3to4") {
  1787. converting_project = true;
  1788. } else if (args[i] == "--validate-conversion-3to4") {
  1789. validating_converting_project = true;
  1790. } else if (args[i] == "-e" || args[i] == "--editor") {
  1791. editor = true;
  1792. } else if (args[i] == "-p" || args[i] == "--project-manager") {
  1793. project_manager = true;
  1794. #endif
  1795. } else if (args[i].length() && args[i][0] != '-' && positional_arg.is_empty()) {
  1796. positional_arg = args[i];
  1797. if (args[i].ends_with(".scn") ||
  1798. args[i].ends_with(".tscn") ||
  1799. args[i].ends_with(".escn") ||
  1800. args[i].ends_with(".res") ||
  1801. args[i].ends_with(".tres")) {
  1802. // Only consider the positional argument to be a scene path if it ends with
  1803. // a file extension associated with Godot scenes. This makes it possible
  1804. // for projects to parse command-line arguments for custom CLI arguments
  1805. // or other file extensions without trouble. This can be used to implement
  1806. // "drag-and-drop onto executable" logic, which can prove helpful
  1807. // for non-game applications.
  1808. game_path = args[i];
  1809. }
  1810. }
  1811. // Then parameters that have an argument to the right.
  1812. else if (i < (args.size() - 1)) {
  1813. bool parsed_pair = true;
  1814. if (args[i] == "-s" || args[i] == "--script") {
  1815. script = args[i + 1];
  1816. #ifdef TOOLS_ENABLED
  1817. } else if (args[i] == "--doctool") {
  1818. doc_tool_path = args[i + 1];
  1819. if (doc_tool_path.begins_with("-")) {
  1820. // Assuming other command line arg, so default to cwd.
  1821. doc_tool_path = ".";
  1822. parsed_pair = false;
  1823. }
  1824. } else if (args[i] == "--export") {
  1825. editor = true; //needs editor
  1826. _export_preset = args[i + 1];
  1827. } else if (args[i] == "--export-debug") {
  1828. editor = true; //needs editor
  1829. _export_preset = args[i + 1];
  1830. export_debug = true;
  1831. } else if (args[i] == "--export-pack") {
  1832. editor = true;
  1833. _export_preset = args[i + 1];
  1834. export_pack_only = true;
  1835. #endif
  1836. } else {
  1837. // The parameter does not match anything known, don't skip the next argument
  1838. parsed_pair = false;
  1839. }
  1840. if (parsed_pair) {
  1841. i++;
  1842. }
  1843. }
  1844. #ifdef TOOLS_ENABLED
  1845. // Handle case where no path is given to --doctool.
  1846. else if (args[i] == "--doctool") {
  1847. doc_tool_path = ".";
  1848. }
  1849. #endif
  1850. }
  1851. uint64_t minimum_time_msec = GLOBAL_DEF("application/boot_splash/minimum_display_time", 0);
  1852. ProjectSettings::get_singleton()->set_custom_property_info("application/boot_splash/minimum_display_time",
  1853. PropertyInfo(Variant::INT,
  1854. "application/boot_splash/minimum_display_time",
  1855. PROPERTY_HINT_RANGE,
  1856. "0,100,1,or_greater,suffix:ms")); // No negative numbers.
  1857. #ifdef TOOLS_ENABLED
  1858. if (!doc_tool_path.is_empty()) {
  1859. // Needed to instance editor-only classes for their default values
  1860. Engine::get_singleton()->set_editor_hint(true);
  1861. // Translate the class reference only when `-l LOCALE` parameter is given.
  1862. if (!locale.is_empty() && locale != "en") {
  1863. load_doc_translations(locale);
  1864. }
  1865. {
  1866. Ref<DirAccess> da = DirAccess::open(doc_tool_path);
  1867. ERR_FAIL_COND_V_MSG(da.is_null(), false, "Argument supplied to --doctool must be a valid directory path.");
  1868. }
  1869. #ifndef MODULE_MONO_ENABLED
  1870. // Hack to define Mono-specific project settings even on non-Mono builds,
  1871. // so that we don't lose their descriptions and default values in DocData.
  1872. // Default values should be synced with mono_gd/gd_mono.cpp.
  1873. GLOBAL_DEF("mono/debugger_agent/port", 23685);
  1874. GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false);
  1875. GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
  1876. GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd");
  1877. GLOBAL_DEF("mono/profiler/enabled", false);
  1878. GLOBAL_DEF("mono/runtime/unhandled_exception_policy", 0);
  1879. #endif
  1880. Error err;
  1881. DocTools doc;
  1882. doc.generate(doc_base);
  1883. DocTools docsrc;
  1884. HashMap<String, String> doc_data_classes;
  1885. HashSet<String> checked_paths;
  1886. print_line("Loading docs...");
  1887. for (int i = 0; i < _doc_data_class_path_count; i++) {
  1888. // Custom modules are always located by absolute path.
  1889. String path = _doc_data_class_paths[i].path;
  1890. if (path.is_relative_path()) {
  1891. path = doc_tool_path.plus_file(path);
  1892. }
  1893. String name = _doc_data_class_paths[i].name;
  1894. doc_data_classes[name] = path;
  1895. if (!checked_paths.has(path)) {
  1896. checked_paths.insert(path);
  1897. // Create the module documentation directory if it doesn't exist
  1898. Ref<DirAccess> da = DirAccess::create_for_path(path);
  1899. err = da->make_dir_recursive(path);
  1900. ERR_FAIL_COND_V_MSG(err != OK, false, "Error: Can't create directory: " + path + ": " + itos(err));
  1901. print_line("Loading docs from: " + path);
  1902. err = docsrc.load_classes(path);
  1903. ERR_FAIL_COND_V_MSG(err != OK, false, "Error loading docs from: " + path + ": " + itos(err));
  1904. }
  1905. }
  1906. String index_path = doc_tool_path.plus_file("doc/classes");
  1907. // Create the main documentation directory if it doesn't exist
  1908. Ref<DirAccess> da = DirAccess::create_for_path(index_path);
  1909. err = da->make_dir_recursive(index_path);
  1910. ERR_FAIL_COND_V_MSG(err != OK, false, "Error: Can't create index directory: " + index_path + ": " + itos(err));
  1911. print_line("Loading classes from: " + index_path);
  1912. err = docsrc.load_classes(index_path);
  1913. ERR_FAIL_COND_V_MSG(err != OK, false, "Error loading classes from: " + index_path + ": " + itos(err));
  1914. checked_paths.insert(index_path);
  1915. print_line("Merging docs...");
  1916. doc.merge_from(docsrc);
  1917. for (const String &E : checked_paths) {
  1918. print_line("Erasing old docs at: " + E);
  1919. err = DocTools::erase_classes(E);
  1920. ERR_FAIL_COND_V_MSG(err != OK, false, "Error erasing old docs at: " + E + ": " + itos(err));
  1921. }
  1922. print_line("Generating new docs...");
  1923. err = doc.save_classes(index_path, doc_data_classes);
  1924. ERR_FAIL_COND_V_MSG(err != OK, false, "Error saving new docs:" + itos(err));
  1925. OS::get_singleton()->set_exit_code(EXIT_SUCCESS);
  1926. return false;
  1927. }
  1928. if (dump_extension_api) {
  1929. NativeExtensionAPIDump::generate_extension_json_file("extension_api.json");
  1930. return false;
  1931. }
  1932. if (converting_project) {
  1933. int exit_code = ProjectConverter3To4().convert();
  1934. OS::get_singleton()->set_exit_code(exit_code);
  1935. return false;
  1936. }
  1937. if (validating_converting_project) {
  1938. int exit_code = ProjectConverter3To4().validate_conversion();
  1939. OS::get_singleton()->set_exit_code(exit_code);
  1940. return false;
  1941. }
  1942. #endif
  1943. if (script.is_empty() && game_path.is_empty() && String(GLOBAL_GET("application/run/main_scene")) != "") {
  1944. game_path = GLOBAL_GET("application/run/main_scene");
  1945. }
  1946. #ifdef TOOLS_ENABLED
  1947. if (!editor && !project_manager && !cmdline_tool && script.is_empty() && game_path.is_empty()) {
  1948. // If we end up here, it means we didn't manage to detect what we want to run.
  1949. // Let's throw an error gently. The code leading to this is pretty brittle so
  1950. // this might end up triggered by valid usage, in which case we'll have to
  1951. // fine-tune further.
  1952. OS::get_singleton()->alert("Couldn't detect whether to run the editor, the project manager or a specific project. Aborting.");
  1953. ERR_FAIL_V_MSG(false, "Couldn't detect whether to run the editor, the project manager or a specific project. Aborting.");
  1954. }
  1955. #endif
  1956. MainLoop *main_loop = nullptr;
  1957. if (editor) {
  1958. main_loop = memnew(SceneTree);
  1959. }
  1960. String main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "SceneTree");
  1961. if (!script.is_empty()) {
  1962. Ref<Script> script_res = ResourceLoader::load(script);
  1963. ERR_FAIL_COND_V_MSG(script_res.is_null(), false, "Can't load script: " + script);
  1964. if (check_only) {
  1965. if (!script_res->is_valid()) {
  1966. OS::get_singleton()->set_exit_code(EXIT_FAILURE);
  1967. } else {
  1968. OS::get_singleton()->set_exit_code(EXIT_SUCCESS);
  1969. }
  1970. return false;
  1971. }
  1972. if (script_res->can_instantiate()) {
  1973. StringName instance_type = script_res->get_instance_base_type();
  1974. Object *obj = ClassDB::instantiate(instance_type);
  1975. MainLoop *script_loop = Object::cast_to<MainLoop>(obj);
  1976. if (!script_loop) {
  1977. if (obj) {
  1978. memdelete(obj);
  1979. }
  1980. OS::get_singleton()->alert(vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
  1981. ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
  1982. }
  1983. script_loop->set_initialize_script(script_res);
  1984. main_loop = script_loop;
  1985. } else {
  1986. return false;
  1987. }
  1988. } else { // Not based on script path.
  1989. if (!editor && !ClassDB::class_exists(main_loop_type) && ScriptServer::is_global_class(main_loop_type)) {
  1990. String script_path = ScriptServer::get_global_class_path(main_loop_type);
  1991. Ref<Script> script_res = ResourceLoader::load(script_path);
  1992. StringName script_base = ScriptServer::get_global_class_native_base(main_loop_type);
  1993. Object *obj = ClassDB::instantiate(script_base);
  1994. MainLoop *script_loop = Object::cast_to<MainLoop>(obj);
  1995. if (!script_loop) {
  1996. if (obj) {
  1997. memdelete(obj);
  1998. }
  1999. OS::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base);
  2000. ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type));
  2001. }
  2002. script_loop->set_initialize_script(script_res);
  2003. main_loop = script_loop;
  2004. }
  2005. }
  2006. if (!main_loop && main_loop_type.is_empty()) {
  2007. main_loop_type = "SceneTree";
  2008. }
  2009. if (!main_loop) {
  2010. if (!ClassDB::class_exists(main_loop_type)) {
  2011. OS::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
  2012. return false;
  2013. } else {
  2014. Object *ml = ClassDB::instantiate(main_loop_type);
  2015. ERR_FAIL_COND_V_MSG(!ml, false, "Can't instance MainLoop type.");
  2016. main_loop = Object::cast_to<MainLoop>(ml);
  2017. if (!main_loop) {
  2018. memdelete(ml);
  2019. ERR_FAIL_V_MSG(false, "Invalid MainLoop type.");
  2020. }
  2021. }
  2022. }
  2023. SceneTree *sml = Object::cast_to<SceneTree>(main_loop);
  2024. if (sml) {
  2025. #ifdef DEBUG_ENABLED
  2026. if (debug_collisions) {
  2027. sml->set_debug_collisions_hint(true);
  2028. }
  2029. if (debug_paths) {
  2030. sml->set_debug_paths_hint(true);
  2031. }
  2032. if (debug_navigation) {
  2033. sml->set_debug_navigation_hint(true);
  2034. }
  2035. #endif
  2036. bool embed_subwindows = GLOBAL_DEF("display/window/subwindows/embed_subwindows", true);
  2037. if (OS::get_singleton()->is_single_window() || (!project_manager && !editor && embed_subwindows) || !DisplayServer::get_singleton()->has_feature(DisplayServer::Feature::FEATURE_SUBWINDOWS)) {
  2038. sml->get_root()->set_embedding_subwindows(true);
  2039. }
  2040. ResourceLoader::add_custom_loaders();
  2041. ResourceSaver::add_custom_savers();
  2042. if (!project_manager && !editor) { // game
  2043. if (!game_path.is_empty() || !script.is_empty()) {
  2044. //autoload
  2045. HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
  2046. //first pass, add the constants so they exist before any script is loaded
  2047. for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
  2048. const ProjectSettings::AutoloadInfo &info = E.value;
  2049. if (info.is_singleton) {
  2050. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  2051. ScriptServer::get_language(i)->add_global_constant(info.name, Variant());
  2052. }
  2053. }
  2054. }
  2055. //second pass, load into global constants
  2056. List<Node *> to_add;
  2057. for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
  2058. const ProjectSettings::AutoloadInfo &info = E.value;
  2059. Ref<Resource> res = ResourceLoader::load(info.path);
  2060. ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path);
  2061. Node *n = nullptr;
  2062. Ref<PackedScene> scn = res;
  2063. Ref<Script> script_res = res;
  2064. if (scn.is_valid()) {
  2065. n = scn->instantiate();
  2066. } else if (script_res.is_valid()) {
  2067. StringName ibt = script_res->get_instance_base_type();
  2068. bool valid_type = ClassDB::is_parent_class(ibt, "Node");
  2069. ERR_CONTINUE_MSG(!valid_type, "Script does not inherit from Node: " + info.path);
  2070. Object *obj = ClassDB::instantiate(ibt);
  2071. ERR_CONTINUE_MSG(!obj, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + ".");
  2072. n = Object::cast_to<Node>(obj);
  2073. n->set_script(script_res);
  2074. }
  2075. ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path);
  2076. n->set_name(info.name);
  2077. //defer so references are all valid on _ready()
  2078. to_add.push_back(n);
  2079. if (info.is_singleton) {
  2080. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  2081. ScriptServer::get_language(i)->add_global_constant(info.name, n);
  2082. }
  2083. }
  2084. }
  2085. for (Node *E : to_add) {
  2086. sml->get_root()->add_child(E);
  2087. }
  2088. }
  2089. }
  2090. #ifdef TOOLS_ENABLED
  2091. EditorNode *editor_node = nullptr;
  2092. if (editor) {
  2093. editor_node = memnew(EditorNode);
  2094. sml->get_root()->add_child(editor_node);
  2095. if (!_export_preset.is_empty()) {
  2096. editor_node->export_preset(_export_preset, positional_arg, export_debug, export_pack_only);
  2097. game_path = ""; // Do not load anything.
  2098. }
  2099. }
  2100. #endif
  2101. if (!editor && !project_manager) {
  2102. //standard helpers that can be changed from main config
  2103. String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled");
  2104. String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep");
  2105. Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/viewport_width", 0),
  2106. GLOBAL_DEF_BASIC("display/window/size/viewport_height", 0));
  2107. real_t stretch_scale = GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0);
  2108. Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED;
  2109. if (stretch_mode == "canvas_items") {
  2110. cs_sm = Window::CONTENT_SCALE_MODE_CANVAS_ITEMS;
  2111. } else if (stretch_mode == "viewport") {
  2112. cs_sm = Window::CONTENT_SCALE_MODE_VIEWPORT;
  2113. }
  2114. Window::ContentScaleAspect cs_aspect = Window::CONTENT_SCALE_ASPECT_IGNORE;
  2115. if (stretch_aspect == "keep") {
  2116. cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP;
  2117. } else if (stretch_aspect == "keep_width") {
  2118. cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_WIDTH;
  2119. } else if (stretch_aspect == "keep_height") {
  2120. cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_HEIGHT;
  2121. } else if (stretch_aspect == "expand") {
  2122. cs_aspect = Window::CONTENT_SCALE_ASPECT_EXPAND;
  2123. }
  2124. sml->get_root()->set_content_scale_mode(cs_sm);
  2125. sml->get_root()->set_content_scale_aspect(cs_aspect);
  2126. sml->get_root()->set_content_scale_size(stretch_size);
  2127. sml->get_root()->set_content_scale_factor(stretch_scale);
  2128. sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
  2129. sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
  2130. String appname = ProjectSettings::get_singleton()->get("application/config/name");
  2131. appname = TranslationServer::get_singleton()->translate(appname);
  2132. #ifdef DEBUG_ENABLED
  2133. // Append a suffix to the window title to denote that the project is running
  2134. // from a debug build (including the editor). Since this results in lower performance,
  2135. // this should be clearly presented to the user.
  2136. DisplayServer::get_singleton()->window_set_title(vformat("%s (DEBUG)", appname));
  2137. #else
  2138. DisplayServer::get_singleton()->window_set_title(appname);
  2139. #endif
  2140. // Define a very small minimum window size to prevent bugs such as GH-37242.
  2141. // It can still be overridden by the user in a script.
  2142. DisplayServer::get_singleton()->window_set_min_size(Size2i(64, 64));
  2143. bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
  2144. sml->get_root()->set_snap_controls_to_pixels(snap_controls);
  2145. bool font_oversampling = GLOBAL_DEF("gui/fonts/dynamic_fonts/use_oversampling", true);
  2146. sml->get_root()->set_use_font_oversampling(font_oversampling);
  2147. int texture_filter = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_filter", 1);
  2148. int texture_repeat = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_repeat", 0);
  2149. sml->get_root()->set_default_canvas_item_texture_filter(
  2150. Viewport::DefaultCanvasItemTextureFilter(texture_filter));
  2151. sml->get_root()->set_default_canvas_item_texture_repeat(
  2152. Viewport::DefaultCanvasItemTextureRepeat(texture_repeat));
  2153. } else {
  2154. GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled");
  2155. ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode",
  2156. PropertyInfo(Variant::STRING,
  2157. "display/window/stretch/mode",
  2158. PROPERTY_HINT_ENUM,
  2159. "disabled,canvas_items,viewport"));
  2160. GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep");
  2161. ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect",
  2162. PropertyInfo(Variant::STRING,
  2163. "display/window/stretch/aspect",
  2164. PROPERTY_HINT_ENUM,
  2165. "ignore,keep,keep_width,keep_height,expand"));
  2166. GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0);
  2167. ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/scale",
  2168. PropertyInfo(Variant::FLOAT,
  2169. "display/window/stretch/scale",
  2170. PROPERTY_HINT_RANGE,
  2171. "1.0,8.0,0.1"));
  2172. sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
  2173. sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
  2174. GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true);
  2175. GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true);
  2176. GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_filter", 1);
  2177. ProjectSettings::get_singleton()->set_custom_property_info(
  2178. "rendering/textures/canvas_textures/default_texture_filter",
  2179. PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM,
  2180. "Nearest,Linear,Linear Mipmap,Nearest Mipmap"));
  2181. GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0);
  2182. ProjectSettings::get_singleton()->set_custom_property_info(
  2183. "rendering/textures/canvas_textures/default_texture_repeat",
  2184. PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM,
  2185. "Disable,Enable,Mirror"));
  2186. }
  2187. #ifdef TOOLS_ENABLED
  2188. if (editor) {
  2189. bool editor_embed_subwindows = EditorSettings::get_singleton()->get_setting(
  2190. "interface/editor/single_window_mode");
  2191. if (editor_embed_subwindows) {
  2192. sml->get_root()->set_embedding_subwindows(true);
  2193. }
  2194. }
  2195. #endif
  2196. String local_game_path;
  2197. if (!game_path.is_empty() && !project_manager) {
  2198. local_game_path = game_path.replace("\\", "/");
  2199. if (!local_game_path.begins_with("res://")) {
  2200. bool absolute =
  2201. (local_game_path.size() > 1) && (local_game_path[0] == '/' || local_game_path[1] == ':');
  2202. if (!absolute) {
  2203. if (ProjectSettings::get_singleton()->is_using_datapack()) {
  2204. local_game_path = "res://" + local_game_path;
  2205. } else {
  2206. int sep = local_game_path.rfind("/");
  2207. if (sep == -1) {
  2208. Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  2209. local_game_path = da->get_current_dir().plus_file(local_game_path);
  2210. } else {
  2211. Ref<DirAccess> da = DirAccess::open(local_game_path.substr(0, sep));
  2212. if (da.is_valid()) {
  2213. local_game_path = da->get_current_dir().plus_file(
  2214. local_game_path.substr(sep + 1, local_game_path.length()));
  2215. }
  2216. }
  2217. }
  2218. }
  2219. }
  2220. local_game_path = ProjectSettings::get_singleton()->localize_path(local_game_path);
  2221. #ifdef TOOLS_ENABLED
  2222. if (editor) {
  2223. if (game_path != String(GLOBAL_GET("application/run/main_scene")) || !editor_node->has_scenes_in_session()) {
  2224. Error serr = editor_node->load_scene(local_game_path);
  2225. if (serr != OK) {
  2226. ERR_PRINT("Failed to load scene");
  2227. }
  2228. }
  2229. DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_EDITOR);
  2230. if (!debug_server_uri.is_empty()) {
  2231. EditorDebuggerNode::get_singleton()->start(debug_server_uri);
  2232. }
  2233. }
  2234. #endif
  2235. if (!editor) {
  2236. DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_ENGINE);
  2237. }
  2238. }
  2239. if (!project_manager && !editor) { // game
  2240. // Load SSL Certificates from Project Settings (or builtin).
  2241. Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificate_bundle_override", ""));
  2242. if (!game_path.is_empty()) {
  2243. Node *scene = nullptr;
  2244. Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
  2245. if (scenedata.is_valid()) {
  2246. scene = scenedata->instantiate();
  2247. }
  2248. ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path);
  2249. sml->add_current_scene(scene);
  2250. #ifdef MACOS_ENABLED
  2251. String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()");
  2252. if (!mac_iconpath.is_empty()) {
  2253. DisplayServer::get_singleton()->set_native_icon(mac_iconpath);
  2254. hasicon = true;
  2255. }
  2256. #endif
  2257. #ifdef WINDOWS_ENABLED
  2258. String win_iconpath = GLOBAL_DEF("application/config/windows_native_icon", "Variant()");
  2259. if (!win_iconpath.is_empty()) {
  2260. DisplayServer::get_singleton()->set_native_icon(win_iconpath);
  2261. hasicon = true;
  2262. }
  2263. #endif
  2264. String iconpath = GLOBAL_DEF("application/config/icon", "Variant()");
  2265. if ((!iconpath.is_empty()) && (!hasicon)) {
  2266. Ref<Image> icon;
  2267. icon.instantiate();
  2268. if (ImageLoader::load_image(iconpath, icon) == OK) {
  2269. DisplayServer::get_singleton()->set_icon(icon);
  2270. hasicon = true;
  2271. }
  2272. }
  2273. }
  2274. }
  2275. #ifdef TOOLS_ENABLED
  2276. if (project_manager) {
  2277. Engine::get_singleton()->set_editor_hint(true);
  2278. ProjectManager *pmanager = memnew(ProjectManager);
  2279. ProgressDialog *progress_dialog = memnew(ProgressDialog);
  2280. pmanager->add_child(progress_dialog);
  2281. sml->get_root()->add_child(pmanager);
  2282. DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_PROJECTMAN);
  2283. }
  2284. if (project_manager || editor) {
  2285. // Load SSL Certificates from Editor Settings (or builtin)
  2286. Crypto::load_default_certificates(
  2287. EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String());
  2288. }
  2289. #endif
  2290. }
  2291. if (!hasicon && OS::get_singleton()->get_bundle_icon_path().is_empty()) {
  2292. Ref<Image> icon = memnew(Image(app_icon_png));
  2293. DisplayServer::get_singleton()->set_icon(icon);
  2294. }
  2295. OS::get_singleton()->set_main_loop(main_loop);
  2296. if (movie_writer) {
  2297. movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, write_movie_path);
  2298. }
  2299. if (minimum_time_msec) {
  2300. uint64_t minimum_time = 1000 * minimum_time_msec;
  2301. uint64_t elapsed_time = OS::get_singleton()->get_ticks_usec();
  2302. if (elapsed_time < minimum_time) {
  2303. OS::get_singleton()->delay_usec(minimum_time - elapsed_time);
  2304. }
  2305. }
  2306. return true;
  2307. }
  2308. /* Main iteration
  2309. *
  2310. * This is the iteration of the engine's game loop, advancing the state of physics,
  2311. * rendering and audio.
  2312. * It's called directly by the platform's OS::run method, where the loop is created
  2313. * and monitored.
  2314. *
  2315. * The OS implementation can impact its draw step with the Main::force_redraw() method.
  2316. */
  2317. uint64_t Main::last_ticks = 0;
  2318. uint32_t Main::frames = 0;
  2319. uint32_t Main::hide_print_fps_attempts = 3;
  2320. uint32_t Main::frame = 0;
  2321. bool Main::force_redraw_requested = false;
  2322. int Main::iterating = 0;
  2323. bool Main::agile_input_event_flushing = false;
  2324. bool Main::is_iterating() {
  2325. return iterating > 0;
  2326. }
  2327. // For performance metrics.
  2328. static uint64_t physics_process_max = 0;
  2329. static uint64_t process_max = 0;
  2330. bool Main::iteration() {
  2331. //for now do not error on this
  2332. //ERR_FAIL_COND_V(iterating, false);
  2333. iterating++;
  2334. const uint64_t ticks = OS::get_singleton()->get_ticks_usec();
  2335. Engine::get_singleton()->_frame_ticks = ticks;
  2336. main_timer_sync.set_cpu_ticks_usec(ticks);
  2337. main_timer_sync.set_fixed_fps(fixed_fps);
  2338. const uint64_t ticks_elapsed = ticks - last_ticks;
  2339. const int physics_ticks_per_second = Engine::get_singleton()->get_physics_ticks_per_second();
  2340. const double physics_step = 1.0 / physics_ticks_per_second;
  2341. const double time_scale = Engine::get_singleton()->get_time_scale();
  2342. MainFrameTime advance = main_timer_sync.advance(physics_step, physics_ticks_per_second);
  2343. double process_step = advance.process_step;
  2344. double scaled_step = process_step * time_scale;
  2345. Engine::get_singleton()->_process_step = process_step;
  2346. Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction;
  2347. uint64_t physics_process_ticks = 0;
  2348. uint64_t process_ticks = 0;
  2349. frame += ticks_elapsed;
  2350. last_ticks = ticks;
  2351. static const int max_physics_steps = 8;
  2352. if (fixed_fps == -1 && advance.physics_steps > max_physics_steps) {
  2353. process_step -= (advance.physics_steps - max_physics_steps) * physics_step;
  2354. advance.physics_steps = max_physics_steps;
  2355. }
  2356. bool exit = false;
  2357. // process all our active interfaces
  2358. XRServer::get_singleton()->_process();
  2359. for (int iters = 0; iters < advance.physics_steps; ++iters) {
  2360. if (Input::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) {
  2361. Input::get_singleton()->flush_buffered_events();
  2362. }
  2363. Engine::get_singleton()->_in_physics = true;
  2364. uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();
  2365. PhysicsServer3D::get_singleton()->sync();
  2366. PhysicsServer3D::get_singleton()->flush_queries();
  2367. PhysicsServer2D::get_singleton()->sync();
  2368. PhysicsServer2D::get_singleton()->flush_queries();
  2369. if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
  2370. exit = true;
  2371. break;
  2372. }
  2373. NavigationServer3D::get_singleton_mut()->process(physics_step * time_scale);
  2374. message_queue->flush();
  2375. PhysicsServer3D::get_singleton()->end_sync();
  2376. PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
  2377. PhysicsServer2D::get_singleton()->end_sync();
  2378. PhysicsServer2D::get_singleton()->step(physics_step * time_scale);
  2379. message_queue->flush();
  2380. physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference
  2381. physics_process_max = MAX(OS::get_singleton()->get_ticks_usec() - physics_begin, physics_process_max);
  2382. Engine::get_singleton()->_physics_frames++;
  2383. Engine::get_singleton()->_in_physics = false;
  2384. }
  2385. if (Input::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) {
  2386. Input::get_singleton()->flush_buffered_events();
  2387. }
  2388. uint64_t process_begin = OS::get_singleton()->get_ticks_usec();
  2389. if (OS::get_singleton()->get_main_loop()->process(process_step * time_scale)) {
  2390. exit = true;
  2391. }
  2392. message_queue->flush();
  2393. RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
  2394. if (DisplayServer::get_singleton()->can_any_window_draw() &&
  2395. RenderingServer::get_singleton()->is_render_loop_enabled()) {
  2396. if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
  2397. if (RenderingServer::get_singleton()->has_changed()) {
  2398. RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands
  2399. Engine::get_singleton()->frames_drawn++;
  2400. }
  2401. } else {
  2402. RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands
  2403. Engine::get_singleton()->frames_drawn++;
  2404. force_redraw_requested = false;
  2405. }
  2406. }
  2407. process_ticks = OS::get_singleton()->get_ticks_usec() - process_begin;
  2408. process_max = MAX(process_ticks, process_max);
  2409. uint64_t frame_time = OS::get_singleton()->get_ticks_usec() - ticks;
  2410. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  2411. ScriptServer::get_language(i)->frame();
  2412. }
  2413. AudioServer::get_singleton()->update();
  2414. if (EngineDebugger::is_active()) {
  2415. EngineDebugger::get_singleton()->iteration(frame_time, process_ticks, physics_process_ticks, physics_step);
  2416. }
  2417. frames++;
  2418. Engine::get_singleton()->_process_frames++;
  2419. if (frame > 1000000) {
  2420. // Wait a few seconds before printing FPS, as FPS reporting just after the engine has started is inaccurate.
  2421. if (hide_print_fps_attempts == 0) {
  2422. if (editor || project_manager) {
  2423. if (print_fps) {
  2424. print_line(vformat("Editor FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
  2425. }
  2426. } else if (print_fps || GLOBAL_GET("debug/settings/stdout/print_fps")) {
  2427. print_line(vformat("Project FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
  2428. }
  2429. } else {
  2430. hide_print_fps_attempts--;
  2431. }
  2432. Engine::get_singleton()->_fps = frames;
  2433. performance->set_process_time(USEC_TO_SEC(process_max));
  2434. performance->set_physics_process_time(USEC_TO_SEC(physics_process_max));
  2435. process_max = 0;
  2436. physics_process_max = 0;
  2437. frame %= 1000000;
  2438. frames = 0;
  2439. }
  2440. iterating--;
  2441. // Needed for OSs using input buffering regardless accumulation (like Android)
  2442. if (Input::get_singleton()->is_using_input_buffering() && !agile_input_event_flushing) {
  2443. Input::get_singleton()->flush_buffered_events();
  2444. }
  2445. if (movie_writer) {
  2446. RID main_vp_rid = RenderingServer::get_singleton()->viewport_find_from_screen_attachment(DisplayServer::MAIN_WINDOW_ID);
  2447. RID main_vp_texture = RenderingServer::get_singleton()->viewport_get_texture(main_vp_rid);
  2448. Ref<Image> vp_tex = RenderingServer::get_singleton()->texture_2d_get(main_vp_texture);
  2449. movie_writer->add_frame(vp_tex);
  2450. }
  2451. if (fixed_fps != -1) {
  2452. return exit;
  2453. }
  2454. OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
  2455. #ifdef TOOLS_ENABLED
  2456. if (auto_build_solutions) {
  2457. auto_build_solutions = false;
  2458. // Only relevant when running the editor.
  2459. if (!editor) {
  2460. ERR_FAIL_V_MSG(true,
  2461. "Command line option --build-solutions was passed, but no project is being edited. Aborting.");
  2462. }
  2463. if (!EditorNode::get_singleton()->call_build()) {
  2464. ERR_FAIL_V_MSG(true,
  2465. "Command line option --build-solutions was passed, but the build callback failed. Aborting.");
  2466. }
  2467. }
  2468. #endif
  2469. return exit || auto_quit;
  2470. }
  2471. void Main::force_redraw() {
  2472. force_redraw_requested = true;
  2473. }
  2474. /* Engine deinitialization
  2475. *
  2476. * Responsible for freeing all the memory allocated by previous setup steps,
  2477. * so that the engine closes cleanly without leaking memory or crashing.
  2478. * The order matters as some of those steps are linked with each other.
  2479. */
  2480. void Main::cleanup(bool p_force) {
  2481. if (!p_force) {
  2482. ERR_FAIL_COND(!_start_success);
  2483. }
  2484. if (movie_writer) {
  2485. movie_writer->end();
  2486. }
  2487. ResourceLoader::remove_custom_loaders();
  2488. ResourceSaver::remove_custom_savers();
  2489. // Flush before uninitializing the scene, but delete the MessageQueue as late as possible.
  2490. message_queue->flush();
  2491. OS::get_singleton()->delete_main_loop();
  2492. OS::get_singleton()->_cmdline.clear();
  2493. OS::get_singleton()->_execpath = "";
  2494. OS::get_singleton()->_local_clipboard = "";
  2495. ResourceLoader::clear_translation_remaps();
  2496. ResourceLoader::clear_path_remaps();
  2497. ScriptServer::finish_languages();
  2498. // Sync pending commands that may have been queued from a different thread during ScriptServer finalization
  2499. RenderingServer::get_singleton()->sync();
  2500. //clear global shader variables before scene and other graphics stuff are deinitialized.
  2501. rendering_server->global_variables_clear();
  2502. if (xr_server) {
  2503. // Now that we're unregistering properly in plugins we need to keep access to xr_server for a little longer
  2504. // We do however unset our primary interface
  2505. xr_server->set_primary_interface(Ref<XRInterface>());
  2506. }
  2507. #ifdef TOOLS_ENABLED
  2508. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_EDITOR);
  2509. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR);
  2510. EditorNode::unregister_editor_types();
  2511. #endif
  2512. ImageLoader::cleanup();
  2513. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
  2514. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE);
  2515. unregister_platform_apis();
  2516. unregister_driver_types();
  2517. unregister_scene_types();
  2518. NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS);
  2519. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS);
  2520. unregister_server_types();
  2521. EngineDebugger::deinitialize();
  2522. if (xr_server) {
  2523. memdelete(xr_server);
  2524. }
  2525. if (audio_server) {
  2526. audio_server->finish();
  2527. memdelete(audio_server);
  2528. }
  2529. if (camera_server) {
  2530. memdelete(camera_server);
  2531. }
  2532. OS::get_singleton()->finalize();
  2533. finalize_physics();
  2534. finalize_navigation_server();
  2535. finalize_display();
  2536. if (input) {
  2537. memdelete(input);
  2538. }
  2539. if (packed_data) {
  2540. memdelete(packed_data);
  2541. }
  2542. if (file_access_network_client) {
  2543. memdelete(file_access_network_client);
  2544. }
  2545. if (performance) {
  2546. memdelete(performance);
  2547. }
  2548. if (input_map) {
  2549. memdelete(input_map);
  2550. }
  2551. if (time_singleton) {
  2552. memdelete(time_singleton);
  2553. }
  2554. if (translation_server) {
  2555. memdelete(translation_server);
  2556. }
  2557. if (tsman) {
  2558. memdelete(tsman);
  2559. }
  2560. if (globals) {
  2561. memdelete(globals);
  2562. }
  2563. if (engine) {
  2564. memdelete(engine);
  2565. }
  2566. if (OS::get_singleton()->is_restart_on_exit_set()) {
  2567. //attempt to restart with arguments
  2568. List<String> args = OS::get_singleton()->get_restart_on_exit_arguments();
  2569. OS::get_singleton()->create_instance(args);
  2570. OS::get_singleton()->set_restart_on_exit(false, List<String>()); //clear list (uses memory)
  2571. }
  2572. // Now should be safe to delete MessageQueue (famous last words).
  2573. message_queue->flush();
  2574. memdelete(message_queue);
  2575. unregister_core_driver_types();
  2576. unregister_core_extensions();
  2577. uninitialize_modules(MODULE_INITIALIZATION_LEVEL_CORE);
  2578. unregister_core_types();
  2579. OS::get_singleton()->finalize_core();
  2580. }