globals.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568
  1. /*************************************************************************/
  2. /* globals.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "globals.h"
  30. #include "os/dir_access.h"
  31. #include "os/file_access.h"
  32. #include "os/keyboard.h"
  33. #include "io/marshalls.h"
  34. #include "bind/core_bind.h"
  35. #include "os/os.h"
  36. #include "io/file_access_pack.h"
  37. #include "io/file_access_network.h"
  38. Globals *Globals::singleton=NULL;
  39. Globals *Globals::get_singleton() {
  40. return singleton;
  41. }
  42. String Globals::get_resource_path() const {
  43. return resource_path;
  44. };
  45. String Globals::localize_path(const String& p_path) const {
  46. if (resource_path=="")
  47. return p_path; //not initialied yet
  48. if (p_path.begins_with("res://") || p_path.begins_with("user://") ||
  49. (p_path.is_abs_path() && !p_path.begins_with(resource_path)))
  50. return p_path.simplify_path();
  51. DirAccess *dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  52. String path = p_path.replace("\\","/").simplify_path();
  53. if (dir->change_dir(path)==OK) {
  54. String cwd = dir->get_current_dir();
  55. cwd = cwd.replace("\\","/");
  56. memdelete(dir);
  57. if (!cwd.begins_with(resource_path)) {
  58. return p_path;
  59. };
  60. return cwd.replace_first(resource_path, "res:/");
  61. } else {
  62. memdelete(dir);
  63. int sep = path.find_last("/");
  64. if (sep == -1) {
  65. return "res://"+path;
  66. };
  67. String parent = path.substr(0, sep);
  68. String plocal = localize_path(parent);
  69. if (plocal == "") {
  70. return "";
  71. };
  72. return plocal + path.substr(sep, path.size() - sep);
  73. };
  74. }
  75. void Globals::set_persisting(const String& p_name, bool p_persist) {
  76. ERR_FAIL_COND(!props.has(p_name));
  77. props[p_name].persist=p_persist;
  78. }
  79. bool Globals::is_persisting(const String& p_name) const {
  80. ERR_FAIL_COND_V(!props.has(p_name),false);
  81. return props[p_name].persist;
  82. }
  83. String Globals::globalize_path(const String& p_path) const {
  84. if (p_path.begins_with("res://")) {
  85. if (resource_path != "") {
  86. return p_path.replace("res:/",resource_path);
  87. };
  88. return p_path.replace("res://", "");
  89. };
  90. return p_path;
  91. }
  92. bool Globals::_set(const StringName& p_name, const Variant& p_value) {
  93. _THREAD_SAFE_METHOD_
  94. if (p_value.get_type()==Variant::NIL)
  95. props.erase(p_name);
  96. else {
  97. if (props.has(p_name)) {
  98. if (!props[p_name].overrided)
  99. props[p_name].variant=p_value;
  100. if (props[p_name].order>=NO_ORDER_BASE && registering_order) {
  101. props[p_name].order=last_order++;
  102. }
  103. } else {
  104. props[p_name]=VariantContainer(p_value,last_order++ + (registering_order?0:NO_ORDER_BASE));
  105. }
  106. }
  107. if (!disable_platform_override) {
  108. String s=String(p_name);
  109. int sl = s.find("/");
  110. int p = s.find(".");
  111. if (p!=-1 && sl!=-1 && p < sl) {
  112. Vector<String> ps = s.substr(0,sl).split(".");
  113. String prop=s.substr(sl,s.length()-sl);
  114. for(int i=1;i<ps.size();i++) {
  115. if (ps[i]==OS::get_singleton()->get_name()) {
  116. String fullprop=ps[0]+prop;
  117. set(fullprop,p_value);
  118. props[fullprop].overrided=true;
  119. }
  120. }
  121. }
  122. }
  123. return true;
  124. }
  125. bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
  126. _THREAD_SAFE_METHOD_
  127. if (!props.has(p_name))
  128. return false;
  129. r_ret=props[p_name].variant;
  130. return true;
  131. }
  132. struct _VCSort {
  133. String name;
  134. Variant::Type type;
  135. int order;
  136. int flags;
  137. bool operator<(const _VCSort& p_vcs) const{ return order==p_vcs.order?name<p_vcs.name:order< p_vcs.order; }
  138. };
  139. void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
  140. _THREAD_SAFE_METHOD_
  141. Set<_VCSort> vclist;
  142. for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
  143. const VariantContainer *v=&E->get();
  144. if (v->hide_from_editor)
  145. continue;
  146. _VCSort vc;
  147. vc.name=E->key();
  148. vc.order=v->order;
  149. vc.type=v->variant.get_type();
  150. if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload"))
  151. vc.flags=PROPERTY_USAGE_CHECKABLE|PROPERTY_USAGE_STORAGE;
  152. else
  153. vc.flags=PROPERTY_USAGE_CHECKABLE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_STORAGE;
  154. if (v->persist) {
  155. vc.flags|=PROPERTY_USAGE_CHECKED;
  156. }
  157. vclist.insert(vc);
  158. }
  159. for(Set<_VCSort>::Element *E=vclist.front();E;E=E->next()) {
  160. if (custom_prop_info.has(E->get().name)) {
  161. PropertyInfo pi=custom_prop_info[E->get().name];
  162. pi.name=E->get().name;
  163. pi.usage=E->get().flags;
  164. p_list->push_back( pi );
  165. } else
  166. p_list->push_back( PropertyInfo(E->get().type, E->get().name,PROPERTY_HINT_NONE,"",E->get().flags) );
  167. }
  168. }
  169. bool Globals::_load_resource_pack(const String& p_pack) {
  170. if (PackedData::get_singleton()->is_disabled())
  171. return false;
  172. bool ok = PackedData::get_singleton()->add_pack(p_pack)==OK;
  173. if (!ok)
  174. return false;
  175. //if data.pck is found, all directory access will be from here
  176. DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
  177. using_datapack=true;
  178. return true;
  179. }
  180. Error Globals::setup(const String& p_path,const String & p_main_pack) {
  181. //an absolute mess of a function, must be cleaned up and reorganized somehow at some point
  182. //_load_settings(p_path+"/override.cfg");
  183. if (p_main_pack!="") {
  184. bool ok = _load_resource_pack(p_main_pack);
  185. ERR_FAIL_COND_V(!ok,ERR_CANT_OPEN);
  186. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  187. _load_settings("res://override.cfg");
  188. }
  189. return OK;
  190. }
  191. if (OS::get_singleton()->get_executable_path()!="") {
  192. if (_load_resource_pack(OS::get_singleton()->get_executable_path())) {
  193. if (p_path!="") {
  194. resource_path=p_path;
  195. } else {
  196. DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  197. resource_path=d->get_current_dir();
  198. memdelete(d);
  199. }
  200. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  201. _load_settings("res://override.cfg");
  202. }
  203. return OK;
  204. }
  205. }
  206. if (FileAccessNetworkClient::get_singleton()) {
  207. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  208. _load_settings("res://override.cfg");
  209. }
  210. return OK;
  211. }
  212. if (OS::get_singleton()->get_resource_dir()!="") {
  213. //OS will call Globals->get_resource_path which will be empty if not overriden!
  214. //if the OS would rather use somewhere else, then it will not be empty.
  215. resource_path=OS::get_singleton()->get_resource_dir().replace("\\","/");
  216. if (resource_path.length() && resource_path[ resource_path.length()-1]=='/')
  217. resource_path=resource_path.substr(0,resource_path.length()-1); // chop end
  218. print_line("has res dir: "+resource_path);
  219. if (!_load_resource_pack("res://data.pck"))
  220. _load_resource_pack("res://data.zip");
  221. // make sure this is load from the resource path
  222. print_line("exists engine cfg? "+itos(FileAccess::exists("/engine.cfg")));
  223. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  224. print_line("loaded engine.cfg");
  225. _load_settings("res://override.cfg");
  226. }
  227. return OK;
  228. }
  229. DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  230. if (!d) {
  231. resource_path = p_path;
  232. } else {
  233. d->change_dir(p_path);
  234. String candidate = d->get_current_dir();
  235. String current_dir = d->get_current_dir();
  236. String exec_name = OS::get_singleton()->get_executable_path().get_file().basename();
  237. bool found = false;
  238. bool first_time=true;
  239. while(true) {
  240. //try to load settings in ascending through dirs shape!
  241. //tries to open pack, but only first time
  242. if (first_time && (_load_resource_pack(current_dir+"/"+exec_name+".pck") || _load_resource_pack(current_dir+"/"+exec_name+".zip") )) {
  243. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  244. _load_settings("res://override.cfg");
  245. found=true;
  246. }
  247. break;
  248. } else if (first_time && (_load_resource_pack(current_dir+"/data.pck") || _load_resource_pack(current_dir+"/data.zip") )) {
  249. if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
  250. _load_settings("res://override.cfg");
  251. found=true;
  252. }
  253. break;
  254. } else if (_load_settings(current_dir+"/engine.cfg")==OK || _load_settings_binary(current_dir+"/engine.cfb")==OK) {
  255. _load_settings(current_dir+"/override.cfg");
  256. candidate=current_dir;
  257. found=true;
  258. break;
  259. }
  260. d->change_dir("..");
  261. if (d->get_current_dir()==current_dir)
  262. break; //not doing anything useful
  263. current_dir=d->get_current_dir();
  264. first_time=false;
  265. }
  266. resource_path=candidate;
  267. resource_path = resource_path.replace("\\","/"); // windows path to unix path just in case
  268. memdelete(d);
  269. if (!found)
  270. return ERR_FILE_NOT_FOUND;
  271. };
  272. if (resource_path.length() && resource_path[ resource_path.length()-1]=='/')
  273. resource_path=resource_path.substr(0,resource_path.length()-1); // chop end
  274. return OK;
  275. }
  276. bool Globals::has(String p_var) const {
  277. _THREAD_SAFE_METHOD_
  278. return props.has(p_var);
  279. }
  280. static Vector<String> _decode_params(const String& p_string) {
  281. int begin=p_string.find("(");
  282. ERR_FAIL_COND_V(begin==-1,Vector<String>());
  283. begin++;
  284. int end=p_string.find(")");
  285. ERR_FAIL_COND_V(end<begin,Vector<String>());
  286. return p_string.substr(begin,end-begin).split(",");
  287. }
  288. static String _get_chunk(const String& str,int &pos, int close_pos) {
  289. enum {
  290. MIN_COMMA,
  291. MIN_COLON,
  292. MIN_CLOSE,
  293. MIN_QUOTE,
  294. MIN_PARENTHESIS,
  295. MIN_CURLY_OPEN,
  296. MIN_OPEN
  297. };
  298. int min_pos=close_pos;
  299. int min_what=MIN_CLOSE;
  300. #define TEST_MIN(m_how,m_what) \
  301. {\
  302. int res = str.find(m_how,pos);\
  303. if (res!=-1 && res < min_pos) {\
  304. min_pos=res;\
  305. min_what=m_what;\
  306. }\
  307. }\
  308. TEST_MIN(",",MIN_COMMA);
  309. TEST_MIN("[",MIN_OPEN);
  310. TEST_MIN("{",MIN_CURLY_OPEN);
  311. TEST_MIN("(",MIN_PARENTHESIS);
  312. TEST_MIN("\"",MIN_QUOTE);
  313. int end=min_pos;
  314. switch(min_what) {
  315. case MIN_COMMA: {
  316. } break;
  317. case MIN_CLOSE: {
  318. //end because it's done
  319. } break;
  320. case MIN_QUOTE: {
  321. end=str.find("\"",min_pos+1)+1;
  322. ERR_FAIL_COND_V(end==-1,Variant());
  323. } break;
  324. case MIN_PARENTHESIS: {
  325. end=str.find(")",min_pos+1)+1;
  326. ERR_FAIL_COND_V(end==-1,Variant());
  327. } break;
  328. case MIN_OPEN: {
  329. int level=1;
  330. end++;
  331. while(end<close_pos) {
  332. if (str[end]=='[')
  333. level++;
  334. if (str[end]==']') {
  335. level--;
  336. if (level==0)
  337. break;
  338. }
  339. end++;
  340. }
  341. ERR_FAIL_COND_V(level!=0,Variant());
  342. end++;
  343. } break;
  344. case MIN_CURLY_OPEN: {
  345. int level=1;
  346. end++;
  347. while(end<close_pos) {
  348. if (str[end]=='{')
  349. level++;
  350. if (str[end]=='}') {
  351. level--;
  352. if (level==0)
  353. break;
  354. }
  355. end++;
  356. }
  357. ERR_FAIL_COND_V(level!=0,Variant());
  358. end++;
  359. } break;
  360. }
  361. String ret = str.substr(pos,end-pos);
  362. pos=end;
  363. while(pos<close_pos) {
  364. if (str[pos]!=',' && str[pos]!=' ' && str[pos]!=':')
  365. break;
  366. pos++;
  367. }
  368. return ret;
  369. }
  370. static Variant _decode_variant(const String& p_string) {
  371. String str = p_string.strip_edges();
  372. if (str.nocasecmp_to("true")==0)
  373. return Variant(true);
  374. if (str.nocasecmp_to("false")==0)
  375. return Variant(false);
  376. if (str.nocasecmp_to("nil")==0)
  377. return Variant();
  378. if (str.is_valid_float()) {
  379. if (str.find(".")==-1)
  380. return str.to_int();
  381. else
  382. return str.to_double();
  383. }
  384. if (str.begins_with("#")) { //string
  385. return Color::html(str);
  386. }
  387. if (str.begins_with("\"")) { //string
  388. int end = str.find_last("\"");
  389. ERR_FAIL_COND_V(end==0,Variant());
  390. return str.substr(1,end-1).xml_unescape();
  391. }
  392. if (str.begins_with("[")) { //array
  393. int close_pos = str.find_last("]");
  394. ERR_FAIL_COND_V(close_pos==-1,Variant());
  395. Array array;
  396. int pos=1;
  397. while(pos<close_pos) {
  398. String s = _get_chunk(str,pos,close_pos);
  399. array.push_back(_decode_variant(s));
  400. }
  401. return array;
  402. }
  403. if (str.begins_with("{")) { //array
  404. int close_pos = str.find_last("}");
  405. ERR_FAIL_COND_V(close_pos==-1,Variant());
  406. Dictionary d;
  407. int pos=1;
  408. while(pos<close_pos) {
  409. String key = _get_chunk(str,pos,close_pos);
  410. String data = _get_chunk(str,pos,close_pos);
  411. d[_decode_variant(key)]=_decode_variant(data);
  412. }
  413. return d;
  414. }
  415. if (str.begins_with("key")) {
  416. Vector<String> params = _decode_params(p_string);
  417. ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,Variant());
  418. int scode=0;
  419. if (params[0].is_numeric()) {
  420. scode=params[0].to_int();
  421. if (scode<10)
  422. scode+=KEY_0;
  423. } else
  424. scode=find_keycode(params[0]);
  425. InputEvent ie;
  426. ie.type=InputEvent::KEY;
  427. ie.key.scancode=scode;
  428. if (params.size()==2) {
  429. String mods=params[1];
  430. if (mods.findn("C")!=-1)
  431. ie.key.mod.control=true;
  432. if (mods.findn("A")!=-1)
  433. ie.key.mod.alt=true;
  434. if (mods.findn("S")!=-1)
  435. ie.key.mod.shift=true;
  436. if (mods.findn("M")!=-1)
  437. ie.key.mod.meta=true;
  438. }
  439. return ie;
  440. }
  441. if (str.begins_with("mbutton")) {
  442. Vector<String> params = _decode_params(p_string);
  443. ERR_FAIL_COND_V(params.size()!=2,Variant());
  444. InputEvent ie;
  445. ie.type=InputEvent::MOUSE_BUTTON;
  446. ie.device=params[0].to_int();
  447. ie.mouse_button.button_index=params[1].to_int();
  448. return ie;
  449. }
  450. if (str.begins_with("jbutton")) {
  451. Vector<String> params = _decode_params(p_string);
  452. ERR_FAIL_COND_V(params.size()!=2,Variant());
  453. InputEvent ie;
  454. ie.type=InputEvent::JOYSTICK_BUTTON;
  455. ie.device=params[0].to_int();
  456. ie.joy_button.button_index=params[1].to_int();
  457. return ie;
  458. }
  459. if (str.begins_with("jaxis")) {
  460. Vector<String> params = _decode_params(p_string);
  461. ERR_FAIL_COND_V(params.size()!=2,Variant());
  462. InputEvent ie;
  463. ie.type=InputEvent::JOYSTICK_MOTION;
  464. ie.device=params[0].to_int();
  465. int axis = params[1].to_int();;
  466. ie.joy_motion.axis=axis>>1;
  467. ie.joy_motion.axis_value=axis&1?1:-1;
  468. return ie;
  469. }
  470. if (str.begins_with("img")) {
  471. Vector<String> params = _decode_params(p_string);
  472. if (params.size()==0) {
  473. return Image();
  474. }
  475. ERR_FAIL_COND_V(params.size()!=5,Image());
  476. String format=params[0].strip_edges();
  477. Image::Format imgformat;
  478. /*
  479. if (format=="grayscale") {
  480. imgformat=Image::FORMAT_L8;
  481. } else if (format=="intensity") {
  482. imgformat=Image::FORMAT_INTENSITY;
  483. } else if (format=="grayscale_alpha") {
  484. imgformat=Image::FORMAT_LA8;
  485. } else if (format=="rgb") {
  486. imgformat=Image::FORMAT_RGB8;
  487. } else if (format=="rgba") {
  488. imgformat=Image::FORMAT_RGBA8;
  489. } else if (format=="indexed") {
  490. imgformat=Image::FORMAT_INDEXED;
  491. } else if (format=="indexed_alpha") {
  492. imgformat=Image::FORMAT_INDEXED_ALPHA;
  493. } else if (format=="bc1") {
  494. imgformat=Image::FORMAT_DXT1;
  495. } else if (format=="bc2") {
  496. imgformat=Image::FORMAT_DXT3;
  497. } else if (format=="bc3") {
  498. imgformat=Image::FORMAT_DXT5;
  499. } else if (format=="bc4") {
  500. imgformat=Image::FORMAT_ATI1;
  501. } else if (format=="bc5") {
  502. imgformat=Image::FORMAT_ATI2;
  503. } else if (format=="custom") {
  504. imgformat=Image::FORMAT_CUSTOM;
  505. } else {
  506. ERR_FAIL_V( Image() );
  507. }*/
  508. int mipmaps=params[1].to_int();
  509. int w=params[2].to_int();
  510. int h=params[3].to_int();
  511. if (w == 0 && h == 0) {
  512. //r_v = Image(w, h, imgformat);
  513. return Image();
  514. };
  515. String data=params[4];
  516. int datasize=data.length()/2;
  517. DVector<uint8_t> pixels;
  518. pixels.resize(datasize);
  519. DVector<uint8_t>::Write wb = pixels.write();
  520. const CharType *cptr=data.c_str();
  521. int idx=0;
  522. uint8_t byte;
  523. while( idx<datasize*2) {
  524. CharType c=*(cptr++);
  525. ERR_FAIL_COND_V(c=='<',ERR_FILE_CORRUPT);
  526. if ( (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f') ) {
  527. if (idx&1) {
  528. byte|=HEX2CHR(c);
  529. wb[idx>>1]=byte;
  530. } else {
  531. byte=HEX2CHR(c)<<4;
  532. }
  533. idx++;
  534. }
  535. }
  536. wb = DVector<uint8_t>::Write();
  537. return Image(w,h,mipmaps,imgformat,pixels);
  538. }
  539. if (str.find(",")!=-1) { //vector2 or vector3
  540. Vector<float> farr = str.split_floats(",",true);
  541. if (farr.size()==2) {
  542. return Point2(farr[0],farr[1]);
  543. }
  544. if (farr.size()==3) {
  545. return Vector3(farr[0],farr[1],farr[2]);
  546. }
  547. ERR_FAIL_V(Variant());
  548. }
  549. return Variant();
  550. }
  551. void Globals::set_registering_order(bool p_enable) {
  552. registering_order=p_enable;
  553. }
  554. Error Globals::_load_settings_binary(const String p_path) {
  555. Error err;
  556. FileAccess *f= FileAccess::open(p_path,FileAccess::READ,&err);
  557. if (err!=OK) {
  558. return err;
  559. }
  560. uint8_t hdr[4];
  561. f->get_buffer(hdr,4);
  562. if (hdr[0]!='E'|| hdr[1]!='C' || hdr[2]!='F' || hdr[3]!='G') {
  563. memdelete(f);
  564. ERR_EXPLAIN("Corrupted header in binary engine.cfb (not ECFG)");
  565. ERR_FAIL_V(ERR_FILE_CORRUPT;)
  566. }
  567. set_registering_order(false);
  568. uint32_t count=f->get_32();
  569. for(int i=0;i<count;i++) {
  570. uint32_t slen=f->get_32();
  571. CharString cs;
  572. cs.resize(slen+1);
  573. cs[slen]=0;
  574. f->get_buffer((uint8_t*)cs.ptr(),slen);
  575. String key;
  576. key.parse_utf8(cs.ptr());
  577. uint32_t vlen=f->get_32();
  578. Vector<uint8_t> d;
  579. d.resize(vlen);
  580. f->get_buffer(d.ptr(),vlen);
  581. Variant value;
  582. Error err = decode_variant(value,d.ptr(),d.size());
  583. ERR_EXPLAIN("Error decoding property: "+key);
  584. ERR_CONTINUE(err!=OK);
  585. set(key,value);
  586. set_persisting(key,true);
  587. }
  588. set_registering_order(true);
  589. return OK;
  590. }
  591. Error Globals::_load_settings(const String p_path) {
  592. Error err;
  593. FileAccess *f= FileAccess::open(p_path,FileAccess::READ,&err);
  594. if (err!=OK) {
  595. return err;
  596. }
  597. String line;
  598. String section;
  599. String subpath;
  600. set_registering_order(false);
  601. int line_count = 0;
  602. while(!f->eof_reached()) {
  603. String line = f->get_line().strip_edges();
  604. line_count++;
  605. if (line=="")
  606. continue;
  607. // find comments
  608. {
  609. int pos=0;
  610. while (true) {
  611. int ret = line.find(";",pos);
  612. if (ret==-1)
  613. break;
  614. int qc=0;
  615. for(int i=0;i<ret;i++) {
  616. if (line[i]=='"')
  617. qc++;
  618. }
  619. if ( !(qc&1) ) {
  620. //not inside string, real comment
  621. line=line.substr(0,ret);
  622. break;
  623. }
  624. pos=ret+1;
  625. }
  626. }
  627. if (line.begins_with("[")) {
  628. int end = line.find_last("]");
  629. ERR_CONTINUE(end!=line.length()-1);
  630. String section=line.substr(1,line.length()-2);
  631. if (section=="global" || section == "")
  632. subpath="";
  633. else
  634. subpath=section+"/";
  635. } else if (line.find("=")!=-1) {
  636. int eqpos = line.find("=");
  637. String var=line.substr(0,eqpos).strip_edges();
  638. String value=line.substr(eqpos+1,line.length()).strip_edges();
  639. Variant val = _decode_variant(value);
  640. set(subpath+var,val);
  641. set_persisting(subpath+var,true);
  642. //props[subpath+var]=VariantContainer(val,last_order++,true);
  643. } else {
  644. if (line.length() > 0) {
  645. ERR_PRINT(String("Syntax error on line "+itos(line_count)+" of file "+p_path).ascii().get_data());
  646. };
  647. };
  648. }
  649. memdelete(f);
  650. set_registering_order(true);
  651. return OK;
  652. }
  653. static String _encode_variant(const Variant& p_variant) {
  654. switch(p_variant.get_type()) {
  655. case Variant::BOOL: {
  656. bool val = p_variant;
  657. return (val?"true":"false");
  658. } break;
  659. case Variant::INT: {
  660. int val = p_variant;
  661. return itos(val);
  662. } break;
  663. case Variant::REAL: {
  664. float val = p_variant;
  665. return rtos(val)+(val==int(val)?".0":"");
  666. } break;
  667. case Variant::VECTOR2: {
  668. Vector2 val = p_variant;
  669. return String("Vector2(")+rtos(val.x)+String(", ")+rtos(val.y)+String(")");
  670. } break;
  671. case Variant::VECTOR3: {
  672. Vector3 val = p_variant;
  673. return String("Vector3(")+rtos(val.x)+ String(", ") +rtos(val.y)+ String(", ") +rtos(val.z)+String(")");
  674. } break;
  675. case Variant::STRING: {
  676. String val = p_variant;
  677. return "\""+val.xml_escape()+"\"";
  678. } break;
  679. case Variant::COLOR: {
  680. Color val = p_variant;
  681. return "#"+val.to_html();
  682. } break;
  683. case Variant::STRING_ARRAY:
  684. case Variant::INT_ARRAY:
  685. case Variant::REAL_ARRAY:
  686. case Variant::ARRAY: {
  687. Array arr = p_variant;
  688. String str="[";
  689. for(int i=0;i<arr.size();i++) {
  690. if (i>0)
  691. str+=", ";
  692. str+=_encode_variant(arr[i]);
  693. }
  694. str+="]";
  695. return str;
  696. } break;
  697. case Variant::DICTIONARY: {
  698. Dictionary d = p_variant;
  699. String str="{";
  700. List<Variant> keys;
  701. d.get_key_list(&keys);
  702. for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
  703. if (E!=keys.front())
  704. str+=", ";
  705. str+=_encode_variant(E->get());
  706. str+=":";
  707. str+=_encode_variant(d[E->get()]);
  708. }
  709. str+="}";
  710. return str;
  711. } break;
  712. case Variant::IMAGE: {
  713. String str="img(";
  714. Image img=p_variant;
  715. if (!img.empty()) {
  716. String format;
  717. /*
  718. switch(img.get_format()) {
  719. case Image::FORMAT_L8: format="grayscale"; break;
  720. case Image::FORMAT_INTENSITY: format="intensity"; break;
  721. case Image::FORMAT_LA8: format="grayscale_alpha"; break;
  722. case Image::FORMAT_RGB8: format="rgb"; break;
  723. case Image::FORMAT_RGBA8: format="rgba"; break;
  724. case Image::FORMAT_INDEXED : format="indexed"; break;
  725. case Image::FORMAT_INDEXED_ALPHA: format="indexed_alpha"; break;
  726. case Image::FORMAT_DXT1: format="bc1"; break;
  727. case Image::FORMAT_DXT3: format="bc2"; break;
  728. case Image::FORMAT_DXT5: format="bc3"; break;
  729. case Image::FORMAT_ATI1: format="bc4"; break;
  730. case Image::FORMAT_ATI2: format="bc5"; break;
  731. case Image::FORMAT_CUSTOM: format="custom custom_size="+itos(img.get_data().size())+""; break;
  732. default: {}
  733. }
  734. */
  735. str+=format+", ";
  736. str+=itos(img.has_mipmaps())+", ";
  737. str+=itos(img.get_width())+", ";
  738. str+=itos(img.get_height())+", ";
  739. DVector<uint8_t> data = img.get_data();
  740. int ds=data.size();
  741. DVector<uint8_t>::Read r = data.read();
  742. for(int i=0;i<ds;i++) {
  743. uint8_t byte = r[i];
  744. const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  745. char bstr[3]={ hex[byte>>4], hex[byte&0xF], 0};
  746. str+=bstr;
  747. }
  748. }
  749. str+=")";
  750. return str;
  751. } break;
  752. case Variant::INPUT_EVENT: {
  753. InputEvent ev = p_variant;
  754. switch(ev.type) {
  755. case InputEvent::KEY: {
  756. String mods;
  757. if (ev.key.mod.control)
  758. mods+="C";
  759. if (ev.key.mod.shift)
  760. mods+="S";
  761. if (ev.key.mod.alt)
  762. mods+="A";
  763. if (ev.key.mod.meta)
  764. mods+="M";
  765. if (mods!="")
  766. mods=", "+mods;
  767. return "key("+keycode_get_string(ev.key.scancode)+mods+")";
  768. } break;
  769. case InputEvent::MOUSE_BUTTON: {
  770. return "mbutton("+itos(ev.device)+", "+itos(ev.mouse_button.button_index)+")";
  771. } break;
  772. case InputEvent::JOYSTICK_BUTTON: {
  773. return "jbutton("+itos(ev.device)+", "+itos(ev.joy_button.button_index)+")";
  774. } break;
  775. case InputEvent::JOYSTICK_MOTION: {
  776. return "jaxis("+itos(ev.device)+", "+itos(ev.joy_motion.axis * 2 + (ev.joy_motion.axis_value<0?0:1))+")";
  777. } break;
  778. default: {
  779. return "nil";
  780. } break;
  781. }
  782. } break;
  783. default: {}
  784. }
  785. return "nil"; //don't know wha to do with this
  786. }
  787. int Globals::get_order(const String& p_name) const {
  788. ERR_FAIL_COND_V(!props.has(p_name),-1);
  789. return props[p_name].order;
  790. }
  791. void Globals::set_order(const String& p_name, int p_order){
  792. ERR_FAIL_COND(!props.has(p_name));
  793. props[p_name].order=p_order;
  794. }
  795. void Globals::clear(const String& p_name) {
  796. ERR_FAIL_COND(!props.has(p_name));
  797. props.erase(p_name);
  798. }
  799. Error Globals::save() {
  800. return save_custom(get_resource_path()+"/engine.cfg");
  801. }
  802. Error Globals::_save_settings_binary(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom) {
  803. Error err;
  804. FileAccess *file = FileAccess::open(p_file,FileAccess::WRITE,&err);
  805. if (err!=OK) {
  806. ERR_EXPLAIN("Coudln't save engine.cfb at "+p_file);
  807. ERR_FAIL_COND_V(err,err)
  808. }
  809. uint8_t hdr[4]={'E','C','F','G'};
  810. file->store_buffer(hdr,4);
  811. int count=0;
  812. for(Map<String,List<String> >::Element *E=props.front();E;E=E->next()) {
  813. for(List<String>::Element *F=E->get().front();F;F=F->next()) {
  814. count++;
  815. }
  816. }
  817. file->store_32(count); //store how many properties are saved
  818. for(Map<String,List<String> >::Element *E=props.front();E;E=E->next()) {
  819. for(List<String>::Element *F=E->get().front();F;F=F->next()) {
  820. String key = F->get();
  821. if (E->key()!="")
  822. key=E->key()+"/"+key;
  823. Variant value;
  824. if (p_custom.has(key))
  825. value=p_custom[key];
  826. else
  827. value = get(key);
  828. file->store_32(key.length());
  829. file->store_string(key);
  830. int len;
  831. Error err = encode_variant(value,NULL,len);
  832. if (err!=OK)
  833. memdelete(file);
  834. ERR_FAIL_COND_V( err != OK, ERR_INVALID_DATA );
  835. Vector<uint8_t> buff;
  836. buff.resize(len);
  837. err = encode_variant(value,&buff[0],len);
  838. if (err!=OK)
  839. memdelete(file);
  840. ERR_FAIL_COND_V( err != OK, ERR_INVALID_DATA );
  841. file->store_32(len);
  842. file->store_buffer(buff.ptr(),buff.size());
  843. }
  844. }
  845. file->close();
  846. memdelete(file);
  847. return OK;
  848. }
  849. Error Globals::_save_settings_text(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom) {
  850. Error err;
  851. FileAccess *file = FileAccess::open(p_file,FileAccess::WRITE,&err);
  852. if (err) {
  853. ERR_EXPLAIN("Coudln't save engine.cfg - "+p_file);
  854. ERR_FAIL_COND_V(err,err)
  855. }
  856. for(Map<String,List<String> >::Element *E=props.front();E;E=E->next()) {
  857. if (E!=props.front())
  858. file->store_string("\n");
  859. if (E->key()!="")
  860. file->store_string("["+E->key()+"]\n\n");
  861. for(List<String>::Element *F=E->get().front();F;F=F->next()) {
  862. String key = F->get();
  863. if (E->key()!="")
  864. key=E->key()+"/"+key;
  865. Variant value;
  866. if (p_custom.has(key))
  867. value=p_custom[key];
  868. else
  869. value = get(key);
  870. file->store_string(F->get()+"="+_encode_variant(value)+"\n");
  871. }
  872. }
  873. file->close();
  874. memdelete(file);
  875. return OK;
  876. }
  877. Error Globals::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
  878. return save_custom(p_file);
  879. };
  880. Error Globals::save_custom(const String& p_path,const CustomMap& p_custom,const Set<String>& p_ignore_masks) {
  881. ERR_FAIL_COND_V(p_path=="",ERR_INVALID_PARAMETER);
  882. Set<_VCSort> vclist;
  883. for(Map<StringName,VariantContainer>::Element *G=props.front();G;G=G->next()) {
  884. const VariantContainer *v=&G->get();
  885. if (v->hide_from_editor)
  886. continue;
  887. if (p_custom.has(G->key()))
  888. continue;
  889. bool discard=false;
  890. for(const Set<String>::Element *E=p_ignore_masks.front();E;E=E->next()) {
  891. if ( String(G->key()).match(E->get())) {
  892. discard=true;
  893. break;
  894. }
  895. }
  896. if (discard)
  897. continue;
  898. _VCSort vc;
  899. vc.name=G->key();//*k;
  900. vc.order=v->order;
  901. vc.type=v->variant.get_type();
  902. vc.flags=PROPERTY_USAGE_CHECKABLE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_STORAGE;
  903. if (!v->persist)
  904. continue;
  905. vclist.insert(vc);
  906. }
  907. for(const Map<String,Variant>::Element *E=p_custom.front();E;E=E->next()) {
  908. _VCSort vc;
  909. vc.name=E->key();
  910. vc.order=0xFFFFFFF;
  911. vc.type=E->get().get_type();
  912. vc.flags=PROPERTY_USAGE_STORAGE;
  913. vclist.insert(vc);
  914. }
  915. Map<String,List<String> > props;
  916. for(Set<_VCSort>::Element *E=vclist.front();E;E=E->next()) {
  917. String category = E->get().name;
  918. String name = E->get().name;
  919. int div = category.find("/");
  920. if (div<0)
  921. category="";
  922. else {
  923. category=category.substr(0,div);
  924. name=name.substr(div+1,name.size());
  925. }
  926. props[category].push_back(name);
  927. }
  928. if (p_path.ends_with(".cfg"))
  929. return _save_settings_text(p_path,props,p_custom);
  930. else if (p_path.ends_with(".cfb"))
  931. return _save_settings_binary(p_path,props,p_custom);
  932. else {
  933. ERR_EXPLAIN("Unknown config file format: "+p_path);
  934. ERR_FAIL_V( ERR_FILE_UNRECOGNIZED );
  935. }
  936. return OK;
  937. #if 0
  938. Error err = file->open(dst_file,FileAccess::WRITE);
  939. if (err) {
  940. memdelete(file);
  941. ERR_EXPLAIN("Coudln't save engine.cfg");
  942. ERR_FAIL_COND_V(err,err)
  943. }
  944. for(Map<String,List<String> >::Element *E=props.front();E;E=E->next()) {
  945. if (E!=props.front())
  946. file->store_string("\n");
  947. if (E->key()!="")
  948. file->store_string("["+E->key()+"]\n\n");
  949. for(List<String>::Element *F=E->get().front();F;F=F->next()) {
  950. String key = F->get();
  951. if (E->key()!="")
  952. key=E->key()+"/"+key;
  953. Variant value;
  954. if (p_custom.has(key))
  955. value=p_custom[key];
  956. else
  957. value = get(key);
  958. file->store_string(F->get()+"="+_encode_variant(value)+"\n");
  959. }
  960. }
  961. file->close();
  962. memdelete(file);
  963. return OK;
  964. #endif
  965. }
  966. Variant _GLOBAL_DEF( const String& p_var, const Variant& p_default) {
  967. if (Globals::get_singleton()->has(p_var))
  968. return Globals::get_singleton()->get(p_var);
  969. Globals::get_singleton()->set(p_var,p_default);
  970. return p_default;
  971. }
  972. void Globals::add_singleton(const Singleton &p_singleton) {
  973. singletons.push_back(p_singleton);
  974. singleton_ptrs[p_singleton.name]=p_singleton.ptr;
  975. }
  976. Object* Globals::get_singleton_object(const String& p_name) const {
  977. const Map<StringName,Object*>::Element *E=singleton_ptrs.find(p_name);
  978. if (!E)
  979. return NULL;
  980. else
  981. return E->get();
  982. };
  983. bool Globals::has_singleton(const String& p_name) const {
  984. return get_singleton_object(p_name) != NULL;
  985. };
  986. void Globals::get_singletons(List<Singleton> *p_singletons) {
  987. for(List<Singleton>::Element *E=singletons.front();E;E=E->next())
  988. p_singletons->push_back(E->get());
  989. }
  990. Vector<String> Globals::get_optimizer_presets() const {
  991. List<PropertyInfo> pi;
  992. Globals::get_singleton()->get_property_list(&pi);
  993. Vector<String> names;
  994. for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) {
  995. if (!E->get().name.begins_with("optimizer_presets/"))
  996. continue;
  997. names.push_back(E->get().name.get_slicec('/',1));
  998. }
  999. names.sort();
  1000. return names;
  1001. }
  1002. void Globals::_add_property_info_bind(const Dictionary& p_info) {
  1003. ERR_FAIL_COND(!p_info.has("name"));
  1004. ERR_FAIL_COND(!p_info.has("type"));
  1005. PropertyInfo pinfo;
  1006. pinfo.name = p_info["name"];
  1007. ERR_FAIL_COND(!props.has(pinfo.name));
  1008. pinfo.type = Variant::Type(p_info["type"].operator int());
  1009. ERR_FAIL_INDEX(pinfo.type, Variant::VARIANT_MAX);
  1010. if (p_info.has("hint"))
  1011. pinfo.hint = PropertyHint(p_info["hint"].operator int());
  1012. if (p_info.has("hint_string"))
  1013. pinfo.hint_string = p_info["hint_string"];
  1014. set_custom_property_info(pinfo.name, pinfo);
  1015. }
  1016. void Globals::set_custom_property_info(const String& p_prop,const PropertyInfo& p_info) {
  1017. ERR_FAIL_COND(!props.has(p_prop));
  1018. custom_prop_info[p_prop]=p_info;
  1019. custom_prop_info[p_prop].name=p_prop;
  1020. }
  1021. void Globals::set_disable_platform_override(bool p_disable) {
  1022. disable_platform_override=p_disable;
  1023. }
  1024. bool Globals::is_using_datapack() const {
  1025. return using_datapack;
  1026. }
  1027. void Globals::_bind_methods() {
  1028. ObjectTypeDB::bind_method(_MD("has","name"),&Globals::has);
  1029. ObjectTypeDB::bind_method(_MD("set_order","name","pos"),&Globals::set_order);
  1030. ObjectTypeDB::bind_method(_MD("get_order","name"),&Globals::get_order);
  1031. ObjectTypeDB::bind_method(_MD("set_persisting","name","enable"),&Globals::set_persisting);
  1032. ObjectTypeDB::bind_method(_MD("is_persisting","name"),&Globals::is_persisting);
  1033. ObjectTypeDB::bind_method(_MD("add_property_info", "hint"),&Globals::_add_property_info_bind);
  1034. ObjectTypeDB::bind_method(_MD("clear","name"),&Globals::clear);
  1035. ObjectTypeDB::bind_method(_MD("localize_path","path"),&Globals::localize_path);
  1036. ObjectTypeDB::bind_method(_MD("globalize_path","path"),&Globals::globalize_path);
  1037. ObjectTypeDB::bind_method(_MD("save"),&Globals::save);
  1038. ObjectTypeDB::bind_method(_MD("has_singleton","name"),&Globals::has_singleton);
  1039. ObjectTypeDB::bind_method(_MD("get_singleton","name"),&Globals::get_singleton_object);
  1040. ObjectTypeDB::bind_method(_MD("load_resource_pack","pack"),&Globals::_load_resource_pack);
  1041. ObjectTypeDB::bind_method(_MD("save_custom","file"),&Globals::_save_custom_bnd);
  1042. }
  1043. Globals::Globals() {
  1044. singleton=this;
  1045. last_order=0;
  1046. disable_platform_override=false;
  1047. registering_order=true;
  1048. Array va;
  1049. InputEvent key;
  1050. key.type=InputEvent::KEY;
  1051. InputEvent joyb;
  1052. joyb.type=InputEvent::JOYSTICK_BUTTON;
  1053. set("application/name","" );
  1054. set("application/main_scene","");
  1055. custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"tscn,scn,xscn,xml,res");
  1056. set("application/disable_stdout",false);
  1057. set("application/use_shared_user_dir",true);
  1058. key.key.scancode=KEY_RETURN;
  1059. va.push_back(key);
  1060. key.key.scancode=KEY_ENTER;
  1061. va.push_back(key);
  1062. key.key.scancode=KEY_SPACE;
  1063. va.push_back(key);
  1064. joyb.joy_button.button_index=JOY_BUTTON_0;
  1065. va.push_back(joyb);
  1066. set("input/ui_accept",va);
  1067. input_presets.push_back("input/ui_accept");
  1068. va=Array();
  1069. key.key.scancode=KEY_SPACE;
  1070. va.push_back(key);
  1071. joyb.joy_button.button_index=JOY_BUTTON_3;
  1072. va.push_back(joyb);
  1073. set("input/ui_select",va);
  1074. input_presets.push_back("input/ui_select");
  1075. va=Array();
  1076. key.key.scancode=KEY_ESCAPE;
  1077. va.push_back(key);
  1078. joyb.joy_button.button_index=JOY_BUTTON_1;
  1079. va.push_back(joyb);
  1080. set("input/ui_cancel",va);
  1081. input_presets.push_back("input/ui_cancel");
  1082. va=Array();
  1083. key.key.scancode=KEY_TAB;
  1084. va.push_back(key);
  1085. set("input/ui_focus_next",va);
  1086. input_presets.push_back("input/ui_focus_next");
  1087. va=Array();
  1088. key.key.scancode=KEY_TAB;
  1089. key.key.mod.shift=true;
  1090. va.push_back(key);
  1091. set("input/ui_focus_prev",va);
  1092. input_presets.push_back("input/ui_focus_prev");
  1093. key.key.mod.shift=false;
  1094. va=Array();
  1095. key.key.scancode=KEY_LEFT;
  1096. va.push_back(key);
  1097. joyb.joy_button.button_index=JOY_DPAD_LEFT;
  1098. va.push_back(joyb);
  1099. set("input/ui_left",va);
  1100. input_presets.push_back("input/ui_left");
  1101. va=Array();
  1102. key.key.scancode=KEY_RIGHT;
  1103. va.push_back(key);
  1104. joyb.joy_button.button_index=JOY_DPAD_RIGHT;
  1105. va.push_back(joyb);
  1106. set("input/ui_right",va);
  1107. input_presets.push_back("input/ui_right");
  1108. va=Array();
  1109. key.key.scancode=KEY_UP;
  1110. va.push_back(key);
  1111. joyb.joy_button.button_index=JOY_DPAD_UP;
  1112. va.push_back(joyb);
  1113. set("input/ui_up",va);
  1114. input_presets.push_back("input/ui_up");
  1115. va=Array();
  1116. key.key.scancode=KEY_DOWN;
  1117. va.push_back(key);
  1118. joyb.joy_button.button_index=JOY_DPAD_DOWN;
  1119. va.push_back(joyb);
  1120. set("input/ui_down",va);
  1121. input_presets.push_back("input/ui_down");
  1122. va=Array();
  1123. key.key.scancode=KEY_PAGEUP;
  1124. va.push_back(key);
  1125. set("input/ui_page_up",va);
  1126. input_presets.push_back("input/ui_page_up");
  1127. va=Array();
  1128. key.key.scancode=KEY_PAGEDOWN;
  1129. va.push_back(key);
  1130. set("input/ui_page_down",va);
  1131. input_presets.push_back("input/ui_page_down");
  1132. // set("display/orientation", "landscape");
  1133. custom_prop_info["display/orientation"]=PropertyInfo(Variant::STRING,"display/orientation",PROPERTY_HINT_ENUM,"landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
  1134. custom_prop_info["render/mipmap_policy"]=PropertyInfo(Variant::INT,"render/mipmap_policy",PROPERTY_HINT_ENUM,"Allow,Allow For Po2,Disallow");
  1135. custom_prop_info["render/thread_model"]=PropertyInfo(Variant::INT,"render/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
  1136. custom_prop_info["physics_2d/thread_model"]=PropertyInfo(Variant::INT,"physics_2d/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
  1137. set("debug/profiler_max_functions",16384);
  1138. using_datapack=false;
  1139. }
  1140. Globals::~Globals() {
  1141. singleton=NULL;
  1142. }