resource_format_binary.cpp 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928
  1. /*************************************************************************/
  2. /* resource_format_binary.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 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 "resource_format_binary.h"
  31. #include "core/image.h"
  32. #include "core/io/file_access_compressed.h"
  33. #include "core/io/marshalls.h"
  34. #include "core/os/dir_access.h"
  35. #include "core/project_settings.h"
  36. #include "core/version.h"
  37. //#define print_bl(m_what) print_line(m_what)
  38. #define print_bl(m_what) (void)(m_what)
  39. enum {
  40. //numbering must be different from variant, in case new variant types are added (variant must be always contiguous for jumptable optimization)
  41. VARIANT_NIL = 1,
  42. VARIANT_BOOL = 2,
  43. VARIANT_INT = 3,
  44. VARIANT_REAL = 4,
  45. VARIANT_STRING = 5,
  46. VARIANT_VECTOR2 = 10,
  47. VARIANT_RECT2 = 11,
  48. VARIANT_VECTOR3 = 12,
  49. VARIANT_PLANE = 13,
  50. VARIANT_QUAT = 14,
  51. VARIANT_AABB = 15,
  52. VARIANT_MATRIX3 = 16,
  53. VARIANT_TRANSFORM = 17,
  54. VARIANT_MATRIX32 = 18,
  55. VARIANT_COLOR = 20,
  56. VARIANT_NODE_PATH = 22,
  57. VARIANT_RID = 23,
  58. VARIANT_OBJECT = 24,
  59. VARIANT_INPUT_EVENT = 25,
  60. VARIANT_DICTIONARY = 26,
  61. VARIANT_ARRAY = 30,
  62. VARIANT_RAW_ARRAY = 31,
  63. VARIANT_INT_ARRAY = 32,
  64. VARIANT_REAL_ARRAY = 33,
  65. VARIANT_STRING_ARRAY = 34,
  66. VARIANT_VECTOR3_ARRAY = 35,
  67. VARIANT_COLOR_ARRAY = 36,
  68. VARIANT_VECTOR2_ARRAY = 37,
  69. VARIANT_INT64 = 40,
  70. VARIANT_DOUBLE = 41,
  71. #ifndef DISABLE_DEPRECATED
  72. VARIANT_IMAGE = 21, // - no longer variant type
  73. IMAGE_ENCODING_EMPTY = 0,
  74. IMAGE_ENCODING_RAW = 1,
  75. IMAGE_ENCODING_LOSSLESS = 2,
  76. IMAGE_ENCODING_LOSSY = 3,
  77. #endif
  78. OBJECT_EMPTY = 0,
  79. OBJECT_EXTERNAL_RESOURCE = 1,
  80. OBJECT_INTERNAL_RESOURCE = 2,
  81. OBJECT_EXTERNAL_RESOURCE_INDEX = 3,
  82. //version 2: added 64 bits support for float and int
  83. FORMAT_VERSION = 2,
  84. FORMAT_VERSION_CAN_RENAME_DEPS = 1
  85. };
  86. void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) {
  87. uint32_t extra = 4 - (p_len % 4);
  88. if (extra < 4) {
  89. for (uint32_t i = 0; i < extra; i++)
  90. f->get_8(); //pad to 32
  91. }
  92. }
  93. StringName ResourceInteractiveLoaderBinary::_get_string() {
  94. uint32_t id = f->get_32();
  95. if (id & 0x80000000) {
  96. int len = id & 0x7FFFFFFF;
  97. if (len > str_buf.size()) {
  98. str_buf.resize(len);
  99. }
  100. if (len == 0)
  101. return StringName();
  102. f->get_buffer((uint8_t *)&str_buf[0], len);
  103. String s;
  104. s.parse_utf8(&str_buf[0]);
  105. return s;
  106. }
  107. return string_map[id];
  108. }
  109. Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
  110. uint32_t type = f->get_32();
  111. print_bl("find property of type: " + itos(type));
  112. switch (type) {
  113. case VARIANT_NIL: {
  114. r_v = Variant();
  115. } break;
  116. case VARIANT_BOOL: {
  117. r_v = bool(f->get_32());
  118. } break;
  119. case VARIANT_INT: {
  120. r_v = int(f->get_32());
  121. } break;
  122. case VARIANT_INT64: {
  123. r_v = int64_t(f->get_64());
  124. } break;
  125. case VARIANT_REAL: {
  126. r_v = f->get_real();
  127. } break;
  128. case VARIANT_DOUBLE: {
  129. r_v = f->get_double();
  130. } break;
  131. case VARIANT_STRING: {
  132. r_v = get_unicode_string();
  133. } break;
  134. case VARIANT_VECTOR2: {
  135. Vector2 v;
  136. v.x = f->get_real();
  137. v.y = f->get_real();
  138. r_v = v;
  139. } break;
  140. case VARIANT_RECT2: {
  141. Rect2 v;
  142. v.position.x = f->get_real();
  143. v.position.y = f->get_real();
  144. v.size.x = f->get_real();
  145. v.size.y = f->get_real();
  146. r_v = v;
  147. } break;
  148. case VARIANT_VECTOR3: {
  149. Vector3 v;
  150. v.x = f->get_real();
  151. v.y = f->get_real();
  152. v.z = f->get_real();
  153. r_v = v;
  154. } break;
  155. case VARIANT_PLANE: {
  156. Plane v;
  157. v.normal.x = f->get_real();
  158. v.normal.y = f->get_real();
  159. v.normal.z = f->get_real();
  160. v.d = f->get_real();
  161. r_v = v;
  162. } break;
  163. case VARIANT_QUAT: {
  164. Quat v;
  165. v.x = f->get_real();
  166. v.y = f->get_real();
  167. v.z = f->get_real();
  168. v.w = f->get_real();
  169. r_v = v;
  170. } break;
  171. case VARIANT_AABB: {
  172. AABB v;
  173. v.position.x = f->get_real();
  174. v.position.y = f->get_real();
  175. v.position.z = f->get_real();
  176. v.size.x = f->get_real();
  177. v.size.y = f->get_real();
  178. v.size.z = f->get_real();
  179. r_v = v;
  180. } break;
  181. case VARIANT_MATRIX32: {
  182. Transform2D v;
  183. v.elements[0].x = f->get_real();
  184. v.elements[0].y = f->get_real();
  185. v.elements[1].x = f->get_real();
  186. v.elements[1].y = f->get_real();
  187. v.elements[2].x = f->get_real();
  188. v.elements[2].y = f->get_real();
  189. r_v = v;
  190. } break;
  191. case VARIANT_MATRIX3: {
  192. Basis v;
  193. v.elements[0].x = f->get_real();
  194. v.elements[0].y = f->get_real();
  195. v.elements[0].z = f->get_real();
  196. v.elements[1].x = f->get_real();
  197. v.elements[1].y = f->get_real();
  198. v.elements[1].z = f->get_real();
  199. v.elements[2].x = f->get_real();
  200. v.elements[2].y = f->get_real();
  201. v.elements[2].z = f->get_real();
  202. r_v = v;
  203. } break;
  204. case VARIANT_TRANSFORM: {
  205. Transform v;
  206. v.basis.elements[0].x = f->get_real();
  207. v.basis.elements[0].y = f->get_real();
  208. v.basis.elements[0].z = f->get_real();
  209. v.basis.elements[1].x = f->get_real();
  210. v.basis.elements[1].y = f->get_real();
  211. v.basis.elements[1].z = f->get_real();
  212. v.basis.elements[2].x = f->get_real();
  213. v.basis.elements[2].y = f->get_real();
  214. v.basis.elements[2].z = f->get_real();
  215. v.origin.x = f->get_real();
  216. v.origin.y = f->get_real();
  217. v.origin.z = f->get_real();
  218. r_v = v;
  219. } break;
  220. case VARIANT_COLOR: {
  221. Color v;
  222. v.r = f->get_real();
  223. v.g = f->get_real();
  224. v.b = f->get_real();
  225. v.a = f->get_real();
  226. r_v = v;
  227. } break;
  228. case VARIANT_NODE_PATH: {
  229. Vector<StringName> names;
  230. Vector<StringName> subnames;
  231. bool absolute;
  232. int name_count = f->get_16();
  233. uint32_t subname_count = f->get_16();
  234. absolute = subname_count & 0x8000;
  235. subname_count &= 0x7FFF;
  236. for (int i = 0; i < name_count; i++)
  237. names.push_back(_get_string());
  238. for (uint32_t i = 0; i < subname_count; i++)
  239. subnames.push_back(_get_string());
  240. NodePath np = NodePath(names, subnames, absolute);
  241. r_v = np;
  242. } break;
  243. case VARIANT_RID: {
  244. r_v = f->get_32();
  245. } break;
  246. case VARIANT_OBJECT: {
  247. uint32_t type = f->get_32();
  248. switch (type) {
  249. case OBJECT_EMPTY: {
  250. //do none
  251. } break;
  252. case OBJECT_INTERNAL_RESOURCE: {
  253. uint32_t index = f->get_32();
  254. String path = res_path + "::" + itos(index);
  255. RES res = ResourceLoader::load(path);
  256. if (res.is_null()) {
  257. WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
  258. }
  259. r_v = res;
  260. } break;
  261. case OBJECT_EXTERNAL_RESOURCE: {
  262. //old file format, still around for compatibility
  263. String type = get_unicode_string();
  264. String path = get_unicode_string();
  265. if (path.find("://") == -1 && path.is_rel_path()) {
  266. // path is relative to file being loaded, so convert to a resource path
  267. path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
  268. }
  269. if (remaps.find(path)) {
  270. path = remaps[path];
  271. }
  272. RES res = ResourceLoader::load(path, type);
  273. if (res.is_null()) {
  274. WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
  275. }
  276. r_v = res;
  277. } break;
  278. case OBJECT_EXTERNAL_RESOURCE_INDEX: {
  279. //new file format, just refers to an index in the external list
  280. int erindex = f->get_32();
  281. if (erindex < 0 || erindex >= external_resources.size()) {
  282. WARN_PRINT("Broken external resource! (index out of size");
  283. r_v = Variant();
  284. } else {
  285. String type = external_resources[erindex].type;
  286. String path = external_resources[erindex].path;
  287. if (path.find("://") == -1 && path.is_rel_path()) {
  288. // path is relative to file being loaded, so convert to a resource path
  289. path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
  290. }
  291. RES res = ResourceLoader::load(path, type);
  292. if (res.is_null()) {
  293. WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
  294. }
  295. r_v = res;
  296. }
  297. } break;
  298. default: {
  299. ERR_FAIL_V(ERR_FILE_CORRUPT);
  300. } break;
  301. }
  302. } break;
  303. case VARIANT_DICTIONARY: {
  304. uint32_t len = f->get_32();
  305. Dictionary d; //last bit means shared
  306. len &= 0x7FFFFFFF;
  307. for (uint32_t i = 0; i < len; i++) {
  308. Variant key;
  309. Error err = parse_variant(key);
  310. ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
  311. Variant value;
  312. err = parse_variant(value);
  313. ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
  314. d[key] = value;
  315. }
  316. r_v = d;
  317. } break;
  318. case VARIANT_ARRAY: {
  319. uint32_t len = f->get_32();
  320. Array a; //last bit means shared
  321. len &= 0x7FFFFFFF;
  322. a.resize(len);
  323. for (uint32_t i = 0; i < len; i++) {
  324. Variant val;
  325. Error err = parse_variant(val);
  326. ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
  327. a[i] = val;
  328. }
  329. r_v = a;
  330. } break;
  331. case VARIANT_RAW_ARRAY: {
  332. uint32_t len = f->get_32();
  333. PoolVector<uint8_t> array;
  334. array.resize(len);
  335. PoolVector<uint8_t>::Write w = array.write();
  336. f->get_buffer(w.ptr(), len);
  337. _advance_padding(len);
  338. w = PoolVector<uint8_t>::Write();
  339. r_v = array;
  340. } break;
  341. case VARIANT_INT_ARRAY: {
  342. uint32_t len = f->get_32();
  343. PoolVector<int> array;
  344. array.resize(len);
  345. PoolVector<int>::Write w = array.write();
  346. f->get_buffer((uint8_t *)w.ptr(), len * 4);
  347. #ifdef BIG_ENDIAN_ENABLED
  348. {
  349. uint32_t *ptr = (uint32_t *)w.ptr();
  350. for (int i = 0; i < len; i++) {
  351. ptr[i] = BSWAP32(ptr[i]);
  352. }
  353. }
  354. #endif
  355. w = PoolVector<int>::Write();
  356. r_v = array;
  357. } break;
  358. case VARIANT_REAL_ARRAY: {
  359. uint32_t len = f->get_32();
  360. PoolVector<real_t> array;
  361. array.resize(len);
  362. PoolVector<real_t>::Write w = array.write();
  363. f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t));
  364. #ifdef BIG_ENDIAN_ENABLED
  365. {
  366. uint32_t *ptr = (uint32_t *)w.ptr();
  367. for (int i = 0; i < len; i++) {
  368. ptr[i] = BSWAP32(ptr[i]);
  369. }
  370. }
  371. #endif
  372. w = PoolVector<real_t>::Write();
  373. r_v = array;
  374. } break;
  375. case VARIANT_STRING_ARRAY: {
  376. uint32_t len = f->get_32();
  377. PoolVector<String> array;
  378. array.resize(len);
  379. PoolVector<String>::Write w = array.write();
  380. for (uint32_t i = 0; i < len; i++)
  381. w[i] = get_unicode_string();
  382. w = PoolVector<String>::Write();
  383. r_v = array;
  384. } break;
  385. case VARIANT_VECTOR2_ARRAY: {
  386. uint32_t len = f->get_32();
  387. PoolVector<Vector2> array;
  388. array.resize(len);
  389. PoolVector<Vector2>::Write w = array.write();
  390. if (sizeof(Vector2) == 8) {
  391. f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 2);
  392. #ifdef BIG_ENDIAN_ENABLED
  393. {
  394. uint32_t *ptr = (uint32_t *)w.ptr();
  395. for (int i = 0; i < len * 2; i++) {
  396. ptr[i] = BSWAP32(ptr[i]);
  397. }
  398. }
  399. #endif
  400. } else {
  401. ERR_EXPLAIN("Vector2 size is NOT 8!");
  402. ERR_FAIL_V(ERR_UNAVAILABLE);
  403. }
  404. w = PoolVector<Vector2>::Write();
  405. r_v = array;
  406. } break;
  407. case VARIANT_VECTOR3_ARRAY: {
  408. uint32_t len = f->get_32();
  409. PoolVector<Vector3> array;
  410. array.resize(len);
  411. PoolVector<Vector3>::Write w = array.write();
  412. if (sizeof(Vector3) == 12) {
  413. f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 3);
  414. #ifdef BIG_ENDIAN_ENABLED
  415. {
  416. uint32_t *ptr = (uint32_t *)w.ptr();
  417. for (int i = 0; i < len * 3; i++) {
  418. ptr[i] = BSWAP32(ptr[i]);
  419. }
  420. }
  421. #endif
  422. } else {
  423. ERR_EXPLAIN("Vector3 size is NOT 12!");
  424. ERR_FAIL_V(ERR_UNAVAILABLE);
  425. }
  426. w = PoolVector<Vector3>::Write();
  427. r_v = array;
  428. } break;
  429. case VARIANT_COLOR_ARRAY: {
  430. uint32_t len = f->get_32();
  431. PoolVector<Color> array;
  432. array.resize(len);
  433. PoolVector<Color>::Write w = array.write();
  434. if (sizeof(Color) == 16) {
  435. f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 4);
  436. #ifdef BIG_ENDIAN_ENABLED
  437. {
  438. uint32_t *ptr = (uint32_t *)w.ptr();
  439. for (int i = 0; i < len * 4; i++) {
  440. ptr[i] = BSWAP32(ptr[i]);
  441. }
  442. }
  443. #endif
  444. } else {
  445. ERR_EXPLAIN("Color size is NOT 16!");
  446. ERR_FAIL_V(ERR_UNAVAILABLE);
  447. }
  448. w = PoolVector<Color>::Write();
  449. r_v = array;
  450. } break;
  451. #ifndef DISABLE_DEPRECATED
  452. case VARIANT_IMAGE: {
  453. uint32_t encoding = f->get_32();
  454. if (encoding == IMAGE_ENCODING_EMPTY) {
  455. r_v = Ref<Image>();
  456. break;
  457. } else if (encoding == IMAGE_ENCODING_RAW) {
  458. uint32_t width = f->get_32();
  459. uint32_t height = f->get_32();
  460. uint32_t mipmaps = f->get_32();
  461. uint32_t format = f->get_32();
  462. const uint32_t format_version_shift = 24;
  463. const uint32_t format_version_mask = format_version_shift - 1;
  464. uint32_t format_version = format >> format_version_shift;
  465. const uint32_t current_version = 0;
  466. if (format_version > current_version) {
  467. ERR_PRINT("Format version for encoded binary image is too new");
  468. return ERR_PARSE_ERROR;
  469. }
  470. Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top
  471. uint32_t datalen = f->get_32();
  472. PoolVector<uint8_t> imgdata;
  473. imgdata.resize(datalen);
  474. PoolVector<uint8_t>::Write w = imgdata.write();
  475. f->get_buffer(w.ptr(), datalen);
  476. _advance_padding(datalen);
  477. w = PoolVector<uint8_t>::Write();
  478. Ref<Image> image;
  479. image.instance();
  480. image->create(width, height, mipmaps, fmt, imgdata);
  481. r_v = image;
  482. } else {
  483. //compressed
  484. PoolVector<uint8_t> data;
  485. data.resize(f->get_32());
  486. PoolVector<uint8_t>::Write w = data.write();
  487. f->get_buffer(w.ptr(), data.size());
  488. w = PoolVector<uint8_t>::Write();
  489. Ref<Image> image;
  490. if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {
  491. image = Image::lossy_unpacker(data);
  492. } else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {
  493. image = Image::lossless_unpacker(data);
  494. }
  495. _advance_padding(data.size());
  496. r_v = image;
  497. }
  498. } break;
  499. #endif
  500. default: {
  501. ERR_FAIL_V(ERR_FILE_CORRUPT);
  502. } break;
  503. }
  504. return OK; //never reach anyway
  505. }
  506. void ResourceInteractiveLoaderBinary::set_local_path(const String &p_local_path) {
  507. res_path = p_local_path;
  508. }
  509. Ref<Resource> ResourceInteractiveLoaderBinary::get_resource() {
  510. return resource;
  511. }
  512. Error ResourceInteractiveLoaderBinary::poll() {
  513. if (error != OK)
  514. return error;
  515. int s = stage;
  516. if (s < external_resources.size()) {
  517. String path = external_resources[s].path;
  518. if (remaps.has(path)) {
  519. path = remaps[path];
  520. }
  521. RES res = ResourceLoader::load(path, external_resources[s].type);
  522. if (res.is_null()) {
  523. if (!ResourceLoader::get_abort_on_missing_resources()) {
  524. ResourceLoader::notify_dependency_error(local_path, path, external_resources[s].type);
  525. } else {
  526. error = ERR_FILE_MISSING_DEPENDENCIES;
  527. ERR_EXPLAIN("Can't load dependency: " + path);
  528. ERR_FAIL_V(error);
  529. }
  530. } else {
  531. resource_cache.push_back(res);
  532. }
  533. stage++;
  534. return error;
  535. }
  536. s -= external_resources.size();
  537. if (s >= internal_resources.size()) {
  538. error = ERR_BUG;
  539. ERR_FAIL_COND_V(s >= internal_resources.size(), error);
  540. }
  541. bool main = s == (internal_resources.size() - 1);
  542. //maybe it is loaded already
  543. String path;
  544. int subindex = 0;
  545. if (!main) {
  546. path = internal_resources[s].path;
  547. if (path.begins_with("local://")) {
  548. path = path.replace_first("local://", "");
  549. subindex = path.to_int();
  550. path = res_path + "::" + path;
  551. }
  552. if (ResourceCache::has(path)) {
  553. //already loaded, don't do anything
  554. stage++;
  555. error = OK;
  556. return error;
  557. }
  558. } else {
  559. if (!ResourceCache::has(res_path))
  560. path = res_path;
  561. }
  562. uint64_t offset = internal_resources[s].offset;
  563. f->seek(offset);
  564. String t = get_unicode_string();
  565. Object *obj = ClassDB::instance(t);
  566. if (!obj) {
  567. error = ERR_FILE_CORRUPT;
  568. ERR_EXPLAIN(local_path + ":Resource of unrecognized type in file: " + t);
  569. }
  570. ERR_FAIL_COND_V(!obj, ERR_FILE_CORRUPT);
  571. Resource *r = Object::cast_to<Resource>(obj);
  572. if (!r) {
  573. error = ERR_FILE_CORRUPT;
  574. memdelete(obj); //bye
  575. ERR_EXPLAIN(local_path + ":Resource type in resource field not a resource, type is: " + obj->get_class());
  576. ERR_FAIL_COND_V(!r, ERR_FILE_CORRUPT);
  577. }
  578. RES res = RES(r);
  579. r->set_path(path);
  580. r->set_subindex(subindex);
  581. int pc = f->get_32();
  582. //set properties
  583. for (int i = 0; i < pc; i++) {
  584. StringName name = _get_string();
  585. if (name == StringName()) {
  586. error = ERR_FILE_CORRUPT;
  587. ERR_FAIL_V(ERR_FILE_CORRUPT);
  588. }
  589. Variant value;
  590. error = parse_variant(value);
  591. if (error)
  592. return error;
  593. res->set(name, value);
  594. }
  595. #ifdef TOOLS_ENABLED
  596. res->set_edited(false);
  597. #endif
  598. stage++;
  599. resource_cache.push_back(res);
  600. if (main) {
  601. f->close();
  602. resource = res;
  603. resource->set_as_translation_remapped(translation_remapped);
  604. error = ERR_FILE_EOF;
  605. } else {
  606. error = OK;
  607. }
  608. return OK;
  609. }
  610. int ResourceInteractiveLoaderBinary::get_stage() const {
  611. return stage;
  612. }
  613. int ResourceInteractiveLoaderBinary::get_stage_count() const {
  614. return external_resources.size() + internal_resources.size();
  615. }
  616. void ResourceInteractiveLoaderBinary::set_translation_remapped(bool p_remapped) {
  617. translation_remapped = p_remapped;
  618. }
  619. static void save_ustring(FileAccess *f, const String &p_string) {
  620. CharString utf8 = p_string.utf8();
  621. f->store_32(utf8.length() + 1);
  622. f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
  623. }
  624. static String get_ustring(FileAccess *f) {
  625. int len = f->get_32();
  626. Vector<char> str_buf;
  627. str_buf.resize(len);
  628. f->get_buffer((uint8_t *)&str_buf[0], len);
  629. String s;
  630. s.parse_utf8(&str_buf[0]);
  631. return s;
  632. }
  633. String ResourceInteractiveLoaderBinary::get_unicode_string() {
  634. int len = f->get_32();
  635. if (len > str_buf.size()) {
  636. str_buf.resize(len);
  637. }
  638. if (len == 0)
  639. return String();
  640. f->get_buffer((uint8_t *)&str_buf[0], len);
  641. String s;
  642. s.parse_utf8(&str_buf[0]);
  643. return s;
  644. }
  645. void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
  646. open(p_f);
  647. if (error)
  648. return;
  649. for (int i = 0; i < external_resources.size(); i++) {
  650. String dep = external_resources[i].path;
  651. if (p_add_types && external_resources[i].type != String()) {
  652. dep += "::" + external_resources[i].type;
  653. }
  654. p_dependencies->push_back(dep);
  655. }
  656. }
  657. void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
  658. error = OK;
  659. f = p_f;
  660. uint8_t header[4];
  661. f->get_buffer(header, 4);
  662. if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
  663. //compressed
  664. FileAccessCompressed *fac = memnew(FileAccessCompressed);
  665. fac->open_after_magic(f);
  666. f = fac;
  667. } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
  668. //not normal
  669. error = ERR_FILE_UNRECOGNIZED;
  670. ERR_EXPLAIN("Unrecognized binary resource file: " + local_path);
  671. ERR_FAIL();
  672. }
  673. bool big_endian = f->get_32();
  674. bool use_real64 = f->get_32();
  675. f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
  676. uint32_t ver_major = f->get_32();
  677. uint32_t ver_minor = f->get_32();
  678. uint32_t ver_format = f->get_32();
  679. print_bl("big endian: " + itos(big_endian));
  680. #ifdef BIG_ENDIAN_ENABLED
  681. print_bl("endian swap: " + itos(!big_endian));
  682. #else
  683. print_bl("endian swap: " + itos(big_endian));
  684. #endif
  685. print_bl("real64: " + itos(use_real64));
  686. print_bl("major: " + itos(ver_major));
  687. print_bl("minor: " + itos(ver_minor));
  688. print_bl("format: " + itos(ver_format));
  689. if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
  690. f->close();
  691. ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
  692. ERR_FAIL();
  693. }
  694. type = get_unicode_string();
  695. print_bl("type: " + type);
  696. importmd_ofs = f->get_64();
  697. for (int i = 0; i < 14; i++)
  698. f->get_32(); //skip a few reserved fields
  699. uint32_t string_table_size = f->get_32();
  700. string_map.resize(string_table_size);
  701. for (uint32_t i = 0; i < string_table_size; i++) {
  702. StringName s = get_unicode_string();
  703. string_map[i] = s;
  704. }
  705. print_bl("strings: " + itos(string_table_size));
  706. uint32_t ext_resources_size = f->get_32();
  707. for (uint32_t i = 0; i < ext_resources_size; i++) {
  708. ExtResource er;
  709. er.type = get_unicode_string();
  710. er.path = get_unicode_string();
  711. external_resources.push_back(er);
  712. }
  713. print_bl("ext resources: " + itos(ext_resources_size));
  714. uint32_t int_resources_size = f->get_32();
  715. for (uint32_t i = 0; i < int_resources_size; i++) {
  716. IntResource ir;
  717. ir.path = get_unicode_string();
  718. ir.offset = f->get_64();
  719. internal_resources.push_back(ir);
  720. }
  721. print_bl("int resources: " + itos(int_resources_size));
  722. if (f->eof_reached()) {
  723. error = ERR_FILE_CORRUPT;
  724. ERR_EXPLAIN("Premature End Of File: " + local_path);
  725. ERR_FAIL();
  726. }
  727. }
  728. String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
  729. error = OK;
  730. f = p_f;
  731. uint8_t header[4];
  732. f->get_buffer(header, 4);
  733. if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
  734. //compressed
  735. FileAccessCompressed *fac = memnew(FileAccessCompressed);
  736. fac->open_after_magic(f);
  737. f = fac;
  738. } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
  739. //not normal
  740. error = ERR_FILE_UNRECOGNIZED;
  741. return "";
  742. }
  743. bool big_endian = f->get_32();
  744. f->get_32(); // use_real64
  745. f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
  746. uint32_t ver_major = f->get_32();
  747. f->get_32(); // ver_minor
  748. uint32_t ver_format = f->get_32();
  749. if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
  750. f->close();
  751. return "";
  752. }
  753. String type = get_unicode_string();
  754. return type;
  755. }
  756. ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() {
  757. f = NULL;
  758. stage = 0;
  759. error = OK;
  760. translation_remapped = false;
  761. }
  762. ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
  763. if (f)
  764. memdelete(f);
  765. }
  766. Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
  767. if (r_error)
  768. *r_error = ERR_FILE_CANT_OPEN;
  769. Error err;
  770. FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
  771. if (err != OK) {
  772. ERR_FAIL_COND_V(err != OK, Ref<ResourceInteractiveLoader>());
  773. }
  774. Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
  775. String path = p_original_path != "" ? p_original_path : p_path;
  776. ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
  777. ria->res_path = ria->local_path;
  778. //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
  779. ria->open(f);
  780. return ria;
  781. }
  782. void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
  783. if (p_type == "") {
  784. get_recognized_extensions(p_extensions);
  785. return;
  786. }
  787. List<String> extensions;
  788. ClassDB::get_extensions_for_type(p_type, &extensions);
  789. extensions.sort();
  790. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  791. String ext = E->get().to_lower();
  792. p_extensions->push_back(ext);
  793. }
  794. }
  795. void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_extensions) const {
  796. List<String> extensions;
  797. ClassDB::get_resource_base_extensions(&extensions);
  798. extensions.sort();
  799. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  800. String ext = E->get().to_lower();
  801. p_extensions->push_back(ext);
  802. }
  803. }
  804. bool ResourceFormatLoaderBinary::handles_type(const String &p_type) const {
  805. return true; //handles all
  806. }
  807. void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
  808. FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
  809. ERR_FAIL_COND(!f);
  810. Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
  811. ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
  812. ria->res_path = ria->local_path;
  813. //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
  814. ria->get_dependencies(f, p_dependencies, p_add_types);
  815. }
  816. Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
  817. //Error error=OK;
  818. FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
  819. ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
  820. FileAccess *fw = NULL; //=FileAccess::open(p_path+".depren");
  821. String local_path = p_path.get_base_dir();
  822. uint8_t header[4];
  823. f->get_buffer(header, 4);
  824. if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
  825. //compressed
  826. FileAccessCompressed *fac = memnew(FileAccessCompressed);
  827. fac->open_after_magic(f);
  828. f = fac;
  829. FileAccessCompressed *facw = memnew(FileAccessCompressed);
  830. facw->configure("RSCC");
  831. Error err = facw->_open(p_path + ".depren", FileAccess::WRITE);
  832. if (err) {
  833. memdelete(fac);
  834. memdelete(facw);
  835. ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT);
  836. }
  837. fw = facw;
  838. } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
  839. //not normal
  840. //error=ERR_FILE_UNRECOGNIZED;
  841. memdelete(f);
  842. ERR_EXPLAIN("Unrecognized binary resource file: " + local_path);
  843. ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
  844. } else {
  845. fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE);
  846. if (!fw) {
  847. memdelete(f);
  848. }
  849. ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE);
  850. uint8_t magic[4] = { 'R', 'S', 'R', 'C' };
  851. fw->store_buffer(magic, 4);
  852. }
  853. bool big_endian = f->get_32();
  854. bool use_real64 = f->get_32();
  855. f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
  856. #ifdef BIG_ENDIAN_ENABLED
  857. fw->store_32(!big_endian);
  858. #else
  859. fw->store_32(big_endian);
  860. #endif
  861. fw->set_endian_swap(big_endian != 0);
  862. fw->store_32(use_real64); //use real64
  863. uint32_t ver_major = f->get_32();
  864. uint32_t ver_minor = f->get_32();
  865. uint32_t ver_format = f->get_32();
  866. if (ver_format < FORMAT_VERSION_CAN_RENAME_DEPS) {
  867. memdelete(f);
  868. memdelete(fw);
  869. DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  870. da->remove(p_path + ".depren");
  871. memdelete(da);
  872. //fuck it, use the old approach;
  873. WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: " + p_path).utf8().get_data());
  874. Error err;
  875. f = FileAccess::open(p_path, FileAccess::READ, &err);
  876. if (err != OK) {
  877. ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN);
  878. }
  879. Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
  880. ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
  881. ria->res_path = ria->local_path;
  882. ria->remaps = p_map;
  883. //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
  884. ria->open(f);
  885. err = ria->poll();
  886. while (err == OK) {
  887. err = ria->poll();
  888. }
  889. ERR_FAIL_COND_V(err != ERR_FILE_EOF, ERR_FILE_CORRUPT);
  890. RES res = ria->get_resource();
  891. ERR_FAIL_COND_V(!res.is_valid(), ERR_FILE_CORRUPT);
  892. return ResourceFormatSaverBinary::singleton->save(p_path, res);
  893. }
  894. if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
  895. memdelete(f);
  896. memdelete(fw);
  897. ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
  898. ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
  899. }
  900. fw->store_32(VERSION_MAJOR); //current version
  901. fw->store_32(VERSION_MINOR);
  902. fw->store_32(FORMAT_VERSION);
  903. save_ustring(fw, get_ustring(f)); //type
  904. size_t md_ofs = f->get_position();
  905. size_t importmd_ofs = f->get_64();
  906. fw->store_64(0); //metadata offset
  907. for (int i = 0; i < 14; i++) {
  908. fw->store_32(0);
  909. f->get_32();
  910. }
  911. //string table
  912. uint32_t string_table_size = f->get_32();
  913. fw->store_32(string_table_size);
  914. for (uint32_t i = 0; i < string_table_size; i++) {
  915. String s = get_ustring(f);
  916. save_ustring(fw, s);
  917. }
  918. //external resources
  919. uint32_t ext_resources_size = f->get_32();
  920. fw->store_32(ext_resources_size);
  921. for (uint32_t i = 0; i < ext_resources_size; i++) {
  922. String type = get_ustring(f);
  923. String path = get_ustring(f);
  924. bool relative = false;
  925. if (!path.begins_with("res://")) {
  926. path = local_path.plus_file(path).simplify_path();
  927. relative = true;
  928. }
  929. if (p_map.has(path)) {
  930. String np = p_map[path];
  931. path = np;
  932. }
  933. if (relative) {
  934. //restore relative
  935. path = local_path.path_to_file(path);
  936. }
  937. save_ustring(fw, type);
  938. save_ustring(fw, path);
  939. }
  940. int64_t size_diff = (int64_t)fw->get_position() - (int64_t)f->get_position();
  941. //internal resources
  942. uint32_t int_resources_size = f->get_32();
  943. fw->store_32(int_resources_size);
  944. for (uint32_t i = 0; i < int_resources_size; i++) {
  945. String path = get_ustring(f);
  946. uint64_t offset = f->get_64();
  947. save_ustring(fw, path);
  948. fw->store_64(offset + size_diff);
  949. }
  950. //rest of file
  951. uint8_t b = f->get_8();
  952. while (!f->eof_reached()) {
  953. fw->store_8(b);
  954. b = f->get_8();
  955. }
  956. bool all_ok = fw->get_error() == OK;
  957. fw->seek(md_ofs);
  958. fw->store_64(importmd_ofs + size_diff);
  959. memdelete(f);
  960. memdelete(fw);
  961. if (!all_ok) {
  962. return ERR_CANT_CREATE;
  963. }
  964. DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
  965. da->remove(p_path);
  966. da->rename(p_path + ".depren", p_path);
  967. memdelete(da);
  968. return OK;
  969. }
  970. String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const {
  971. FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
  972. if (!f) {
  973. return ""; //could not rwead
  974. }
  975. Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
  976. ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
  977. ria->res_path = ria->local_path;
  978. //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
  979. String r = ria->recognize(f);
  980. return r;
  981. }
  982. ///////////////////////////////////////////////////////////
  983. ///////////////////////////////////////////////////////////
  984. ///////////////////////////////////////////////////////////
  985. void ResourceFormatSaverBinaryInstance::_pad_buffer(int p_bytes) {
  986. int extra = 4 - (p_bytes % 4);
  987. if (extra < 4) {
  988. for (int i = 0; i < extra; i++)
  989. f->store_8(0); //pad to 32
  990. }
  991. }
  992. void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, const PropertyInfo &p_hint) {
  993. switch (p_property.get_type()) {
  994. case Variant::NIL: {
  995. f->store_32(VARIANT_NIL);
  996. // don't store anything
  997. } break;
  998. case Variant::BOOL: {
  999. f->store_32(VARIANT_BOOL);
  1000. bool val = p_property;
  1001. f->store_32(val);
  1002. } break;
  1003. case Variant::INT: {
  1004. int64_t val = p_property;
  1005. if (val > 0x7FFFFFFF || val < -0x80000000) {
  1006. f->store_32(VARIANT_INT64);
  1007. f->store_64(val);
  1008. } else {
  1009. f->store_32(VARIANT_INT);
  1010. int val = p_property;
  1011. f->store_32(int32_t(val));
  1012. }
  1013. } break;
  1014. case Variant::REAL: {
  1015. double d = p_property;
  1016. float fl = d;
  1017. if (double(fl) != d) {
  1018. f->store_32(VARIANT_DOUBLE);
  1019. f->store_double(d);
  1020. } else {
  1021. f->store_32(VARIANT_REAL);
  1022. f->store_real(fl);
  1023. }
  1024. } break;
  1025. case Variant::STRING: {
  1026. f->store_32(VARIANT_STRING);
  1027. String val = p_property;
  1028. save_unicode_string(val);
  1029. } break;
  1030. case Variant::VECTOR2: {
  1031. f->store_32(VARIANT_VECTOR2);
  1032. Vector2 val = p_property;
  1033. f->store_real(val.x);
  1034. f->store_real(val.y);
  1035. } break;
  1036. case Variant::RECT2: {
  1037. f->store_32(VARIANT_RECT2);
  1038. Rect2 val = p_property;
  1039. f->store_real(val.position.x);
  1040. f->store_real(val.position.y);
  1041. f->store_real(val.size.x);
  1042. f->store_real(val.size.y);
  1043. } break;
  1044. case Variant::VECTOR3: {
  1045. f->store_32(VARIANT_VECTOR3);
  1046. Vector3 val = p_property;
  1047. f->store_real(val.x);
  1048. f->store_real(val.y);
  1049. f->store_real(val.z);
  1050. } break;
  1051. case Variant::PLANE: {
  1052. f->store_32(VARIANT_PLANE);
  1053. Plane val = p_property;
  1054. f->store_real(val.normal.x);
  1055. f->store_real(val.normal.y);
  1056. f->store_real(val.normal.z);
  1057. f->store_real(val.d);
  1058. } break;
  1059. case Variant::QUAT: {
  1060. f->store_32(VARIANT_QUAT);
  1061. Quat val = p_property;
  1062. f->store_real(val.x);
  1063. f->store_real(val.y);
  1064. f->store_real(val.z);
  1065. f->store_real(val.w);
  1066. } break;
  1067. case Variant::AABB: {
  1068. f->store_32(VARIANT_AABB);
  1069. AABB val = p_property;
  1070. f->store_real(val.position.x);
  1071. f->store_real(val.position.y);
  1072. f->store_real(val.position.z);
  1073. f->store_real(val.size.x);
  1074. f->store_real(val.size.y);
  1075. f->store_real(val.size.z);
  1076. } break;
  1077. case Variant::TRANSFORM2D: {
  1078. f->store_32(VARIANT_MATRIX32);
  1079. Transform2D val = p_property;
  1080. f->store_real(val.elements[0].x);
  1081. f->store_real(val.elements[0].y);
  1082. f->store_real(val.elements[1].x);
  1083. f->store_real(val.elements[1].y);
  1084. f->store_real(val.elements[2].x);
  1085. f->store_real(val.elements[2].y);
  1086. } break;
  1087. case Variant::BASIS: {
  1088. f->store_32(VARIANT_MATRIX3);
  1089. Basis val = p_property;
  1090. f->store_real(val.elements[0].x);
  1091. f->store_real(val.elements[0].y);
  1092. f->store_real(val.elements[0].z);
  1093. f->store_real(val.elements[1].x);
  1094. f->store_real(val.elements[1].y);
  1095. f->store_real(val.elements[1].z);
  1096. f->store_real(val.elements[2].x);
  1097. f->store_real(val.elements[2].y);
  1098. f->store_real(val.elements[2].z);
  1099. } break;
  1100. case Variant::TRANSFORM: {
  1101. f->store_32(VARIANT_TRANSFORM);
  1102. Transform val = p_property;
  1103. f->store_real(val.basis.elements[0].x);
  1104. f->store_real(val.basis.elements[0].y);
  1105. f->store_real(val.basis.elements[0].z);
  1106. f->store_real(val.basis.elements[1].x);
  1107. f->store_real(val.basis.elements[1].y);
  1108. f->store_real(val.basis.elements[1].z);
  1109. f->store_real(val.basis.elements[2].x);
  1110. f->store_real(val.basis.elements[2].y);
  1111. f->store_real(val.basis.elements[2].z);
  1112. f->store_real(val.origin.x);
  1113. f->store_real(val.origin.y);
  1114. f->store_real(val.origin.z);
  1115. } break;
  1116. case Variant::COLOR: {
  1117. f->store_32(VARIANT_COLOR);
  1118. Color val = p_property;
  1119. f->store_real(val.r);
  1120. f->store_real(val.g);
  1121. f->store_real(val.b);
  1122. f->store_real(val.a);
  1123. } break;
  1124. case Variant::NODE_PATH: {
  1125. f->store_32(VARIANT_NODE_PATH);
  1126. NodePath np = p_property;
  1127. f->store_16(np.get_name_count());
  1128. uint16_t snc = np.get_subname_count();
  1129. if (np.is_absolute())
  1130. snc |= 0x8000;
  1131. f->store_16(snc);
  1132. for (int i = 0; i < np.get_name_count(); i++)
  1133. f->store_32(get_string_index(np.get_name(i)));
  1134. for (int i = 0; i < np.get_subname_count(); i++)
  1135. f->store_32(get_string_index(np.get_subname(i)));
  1136. } break;
  1137. case Variant::_RID: {
  1138. f->store_32(VARIANT_RID);
  1139. WARN_PRINT("Can't save RIDs");
  1140. RID val = p_property;
  1141. f->store_32(val.get_id());
  1142. } break;
  1143. case Variant::OBJECT: {
  1144. f->store_32(VARIANT_OBJECT);
  1145. RES res = p_property;
  1146. if (res.is_null()) {
  1147. f->store_32(OBJECT_EMPTY);
  1148. return; // don't save it
  1149. }
  1150. if (res->get_path().length() && res->get_path().find("::") == -1) {
  1151. f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
  1152. f->store_32(external_resources[res]);
  1153. } else {
  1154. if (!resource_set.has(res)) {
  1155. f->store_32(OBJECT_EMPTY);
  1156. ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
  1157. ERR_FAIL();
  1158. }
  1159. f->store_32(OBJECT_INTERNAL_RESOURCE);
  1160. f->store_32(res->get_subindex());
  1161. //internal resource
  1162. }
  1163. } break;
  1164. case Variant::DICTIONARY: {
  1165. f->store_32(VARIANT_DICTIONARY);
  1166. Dictionary d = p_property;
  1167. f->store_32(uint32_t(d.size()));
  1168. List<Variant> keys;
  1169. d.get_key_list(&keys);
  1170. for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
  1171. /*
  1172. if (!_check_type(dict[E->get()]))
  1173. continue;
  1174. */
  1175. write_variant(E->get());
  1176. write_variant(d[E->get()]);
  1177. }
  1178. } break;
  1179. case Variant::ARRAY: {
  1180. f->store_32(VARIANT_ARRAY);
  1181. Array a = p_property;
  1182. f->store_32(uint32_t(a.size()));
  1183. for (int i = 0; i < a.size(); i++) {
  1184. write_variant(a[i]);
  1185. }
  1186. } break;
  1187. case Variant::POOL_BYTE_ARRAY: {
  1188. f->store_32(VARIANT_RAW_ARRAY);
  1189. PoolVector<uint8_t> arr = p_property;
  1190. int len = arr.size();
  1191. f->store_32(len);
  1192. PoolVector<uint8_t>::Read r = arr.read();
  1193. f->store_buffer(r.ptr(), len);
  1194. _pad_buffer(len);
  1195. } break;
  1196. case Variant::POOL_INT_ARRAY: {
  1197. f->store_32(VARIANT_INT_ARRAY);
  1198. PoolVector<int> arr = p_property;
  1199. int len = arr.size();
  1200. f->store_32(len);
  1201. PoolVector<int>::Read r = arr.read();
  1202. for (int i = 0; i < len; i++)
  1203. f->store_32(r[i]);
  1204. } break;
  1205. case Variant::POOL_REAL_ARRAY: {
  1206. f->store_32(VARIANT_REAL_ARRAY);
  1207. PoolVector<real_t> arr = p_property;
  1208. int len = arr.size();
  1209. f->store_32(len);
  1210. PoolVector<real_t>::Read r = arr.read();
  1211. for (int i = 0; i < len; i++) {
  1212. f->store_real(r[i]);
  1213. }
  1214. } break;
  1215. case Variant::POOL_STRING_ARRAY: {
  1216. f->store_32(VARIANT_STRING_ARRAY);
  1217. PoolVector<String> arr = p_property;
  1218. int len = arr.size();
  1219. f->store_32(len);
  1220. PoolVector<String>::Read r = arr.read();
  1221. for (int i = 0; i < len; i++) {
  1222. save_unicode_string(r[i]);
  1223. }
  1224. } break;
  1225. case Variant::POOL_VECTOR3_ARRAY: {
  1226. f->store_32(VARIANT_VECTOR3_ARRAY);
  1227. PoolVector<Vector3> arr = p_property;
  1228. int len = arr.size();
  1229. f->store_32(len);
  1230. PoolVector<Vector3>::Read r = arr.read();
  1231. for (int i = 0; i < len; i++) {
  1232. f->store_real(r[i].x);
  1233. f->store_real(r[i].y);
  1234. f->store_real(r[i].z);
  1235. }
  1236. } break;
  1237. case Variant::POOL_VECTOR2_ARRAY: {
  1238. f->store_32(VARIANT_VECTOR2_ARRAY);
  1239. PoolVector<Vector2> arr = p_property;
  1240. int len = arr.size();
  1241. f->store_32(len);
  1242. PoolVector<Vector2>::Read r = arr.read();
  1243. for (int i = 0; i < len; i++) {
  1244. f->store_real(r[i].x);
  1245. f->store_real(r[i].y);
  1246. }
  1247. } break;
  1248. case Variant::POOL_COLOR_ARRAY: {
  1249. f->store_32(VARIANT_COLOR_ARRAY);
  1250. PoolVector<Color> arr = p_property;
  1251. int len = arr.size();
  1252. f->store_32(len);
  1253. PoolVector<Color>::Read r = arr.read();
  1254. for (int i = 0; i < len; i++) {
  1255. f->store_real(r[i].r);
  1256. f->store_real(r[i].g);
  1257. f->store_real(r[i].b);
  1258. f->store_real(r[i].a);
  1259. }
  1260. } break;
  1261. default: {
  1262. ERR_EXPLAIN("Invalid variant");
  1263. ERR_FAIL();
  1264. }
  1265. }
  1266. }
  1267. void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant, bool p_main) {
  1268. switch (p_variant.get_type()) {
  1269. case Variant::OBJECT: {
  1270. RES res = p_variant.operator RefPtr();
  1271. if (res.is_null() || external_resources.has(res))
  1272. return;
  1273. if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
  1274. int idx = external_resources.size();
  1275. external_resources[res] = idx;
  1276. return;
  1277. }
  1278. if (resource_set.has(res))
  1279. return;
  1280. List<PropertyInfo> property_list;
  1281. res->get_property_list(&property_list);
  1282. for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
  1283. if (E->get().usage & PROPERTY_USAGE_STORAGE) {
  1284. _find_resources(res->get(E->get().name));
  1285. }
  1286. }
  1287. resource_set.insert(res);
  1288. saved_resources.push_back(res);
  1289. } break;
  1290. case Variant::ARRAY: {
  1291. Array varray = p_variant;
  1292. int len = varray.size();
  1293. for (int i = 0; i < len; i++) {
  1294. Variant v = varray.get(i);
  1295. _find_resources(v);
  1296. }
  1297. } break;
  1298. case Variant::DICTIONARY: {
  1299. Dictionary d = p_variant;
  1300. List<Variant> keys;
  1301. d.get_key_list(&keys);
  1302. for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
  1303. _find_resources(E->get());
  1304. Variant v = d[E->get()];
  1305. _find_resources(v);
  1306. }
  1307. } break;
  1308. case Variant::NODE_PATH: {
  1309. //take the chance and save node path strings
  1310. NodePath np = p_variant;
  1311. for (int i = 0; i < np.get_name_count(); i++)
  1312. get_string_index(np.get_name(i));
  1313. for (int i = 0; i < np.get_subname_count(); i++)
  1314. get_string_index(np.get_subname(i));
  1315. } break;
  1316. default: {}
  1317. }
  1318. }
  1319. void ResourceFormatSaverBinaryInstance::save_unicode_string(const String &p_string) {
  1320. CharString utf8 = p_string.utf8();
  1321. f->store_32(utf8.length() + 1);
  1322. f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
  1323. }
  1324. int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) {
  1325. StringName s = p_string;
  1326. if (string_map.has(s))
  1327. return string_map[s];
  1328. string_map[s] = strings.size();
  1329. strings.push_back(s);
  1330. return strings.size() - 1;
  1331. }
  1332. Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
  1333. Error err;
  1334. if (p_flags & ResourceSaver::FLAG_COMPRESS) {
  1335. FileAccessCompressed *fac = memnew(FileAccessCompressed);
  1336. fac->configure("RSCC");
  1337. f = fac;
  1338. err = fac->_open(p_path, FileAccess::WRITE);
  1339. if (err)
  1340. memdelete(f);
  1341. } else {
  1342. f = FileAccess::open(p_path, FileAccess::WRITE, &err);
  1343. }
  1344. ERR_FAIL_COND_V(err, err);
  1345. relative_paths = p_flags & ResourceSaver::FLAG_RELATIVE_PATHS;
  1346. skip_editor = p_flags & ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
  1347. bundle_resources = p_flags & ResourceSaver::FLAG_BUNDLE_RESOURCES;
  1348. big_endian = p_flags & ResourceSaver::FLAG_SAVE_BIG_ENDIAN;
  1349. takeover_paths = p_flags & ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
  1350. if (!p_path.begins_with("res://"))
  1351. takeover_paths = false;
  1352. local_path = p_path.get_base_dir();
  1353. _find_resources(p_resource, true);
  1354. if (!(p_flags & ResourceSaver::FLAG_COMPRESS)) {
  1355. //save header compressed
  1356. static const uint8_t header[4] = { 'R', 'S', 'R', 'C' };
  1357. f->store_buffer(header, 4);
  1358. }
  1359. if (big_endian) {
  1360. f->store_32(1);
  1361. f->set_endian_swap(true);
  1362. } else
  1363. f->store_32(0);
  1364. f->store_32(0); //64 bits file, false for now
  1365. f->store_32(VERSION_MAJOR);
  1366. f->store_32(VERSION_MINOR);
  1367. f->store_32(FORMAT_VERSION);
  1368. if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
  1369. f->close();
  1370. return ERR_CANT_CREATE;
  1371. }
  1372. save_unicode_string(p_resource->get_class());
  1373. f->store_64(0); //offset to import metadata
  1374. for (int i = 0; i < 14; i++)
  1375. f->store_32(0); // reserved
  1376. List<ResourceData> resources;
  1377. {
  1378. for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
  1379. ResourceData &rd = resources.push_back(ResourceData())->get();
  1380. rd.type = E->get()->get_class();
  1381. List<PropertyInfo> property_list;
  1382. E->get()->get_property_list(&property_list);
  1383. for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) {
  1384. if (skip_editor && F->get().name.begins_with("__editor"))
  1385. continue;
  1386. if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
  1387. Property p;
  1388. p.name_idx = get_string_index(F->get().name);
  1389. p.value = E->get()->get(F->get().name);
  1390. if (((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && p.value.is_zero()) || ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && p.value.is_one()))
  1391. continue;
  1392. p.pi = F->get();
  1393. rd.properties.push_back(p);
  1394. }
  1395. }
  1396. }
  1397. }
  1398. f->store_32(strings.size()); //string table size
  1399. for (int i = 0; i < strings.size(); i++) {
  1400. save_unicode_string(strings[i]);
  1401. }
  1402. // save external resource table
  1403. f->store_32(external_resources.size()); //amount of external resources
  1404. Vector<RES> save_order;
  1405. save_order.resize(external_resources.size());
  1406. for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
  1407. save_order[E->get()] = E->key();
  1408. }
  1409. for (int i = 0; i < save_order.size(); i++) {
  1410. save_unicode_string(save_order[i]->get_save_class());
  1411. String path = save_order[i]->get_path();
  1412. path = relative_paths ? local_path.path_to_file(path) : path;
  1413. save_unicode_string(path);
  1414. }
  1415. // save internal resource table
  1416. f->store_32(saved_resources.size()); //amount of internal resources
  1417. Vector<uint64_t> ofs_pos;
  1418. Set<int> used_indices;
  1419. for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
  1420. RES r = E->get();
  1421. if (r->get_path() == "" || r->get_path().find("::") != -1) {
  1422. if (r->get_subindex() != 0) {
  1423. if (used_indices.has(r->get_subindex())) {
  1424. r->set_subindex(0); //repeated
  1425. } else {
  1426. used_indices.insert(r->get_subindex());
  1427. }
  1428. }
  1429. }
  1430. }
  1431. for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
  1432. RES r = E->get();
  1433. if (r->get_path() == "" || r->get_path().find("::") != -1) {
  1434. if (r->get_subindex() == 0) {
  1435. int new_subindex = 1;
  1436. if (used_indices.size()) {
  1437. new_subindex = used_indices.back()->get() + 1;
  1438. }
  1439. r->set_subindex(new_subindex);
  1440. used_indices.insert(new_subindex);
  1441. }
  1442. save_unicode_string("local://" + itos(r->get_subindex()));
  1443. if (takeover_paths) {
  1444. r->set_path(p_path + "::" + itos(r->get_subindex()), true);
  1445. }
  1446. #ifdef TOOLS_ENABLED
  1447. r->set_edited(false);
  1448. #endif
  1449. } else {
  1450. save_unicode_string(r->get_path()); //actual external
  1451. }
  1452. ofs_pos.push_back(f->get_position());
  1453. f->store_64(0); //offset in 64 bits
  1454. }
  1455. Vector<uint64_t> ofs_table;
  1456. //now actually save the resources
  1457. for (List<ResourceData>::Element *E = resources.front(); E; E = E->next()) {
  1458. ResourceData &rd = E->get();
  1459. ofs_table.push_back(f->get_position());
  1460. save_unicode_string(rd.type);
  1461. f->store_32(rd.properties.size());
  1462. for (List<Property>::Element *F = rd.properties.front(); F; F = F->next()) {
  1463. Property &p = F->get();
  1464. f->store_32(p.name_idx);
  1465. write_variant(p.value, F->get().pi);
  1466. }
  1467. }
  1468. for (int i = 0; i < ofs_table.size(); i++) {
  1469. f->seek(ofs_pos[i]);
  1470. f->store_64(ofs_table[i]);
  1471. }
  1472. f->seek_end();
  1473. f->store_buffer((const uint8_t *)"RSRC", 4); //magic at end
  1474. if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
  1475. f->close();
  1476. return ERR_CANT_CREATE;
  1477. }
  1478. f->close();
  1479. return OK;
  1480. }
  1481. Error ResourceFormatSaverBinary::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
  1482. String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
  1483. ResourceFormatSaverBinaryInstance saver;
  1484. return saver.save(local_path, p_resource, p_flags);
  1485. }
  1486. bool ResourceFormatSaverBinary::recognize(const RES &p_resource) const {
  1487. return true; //all recognized
  1488. }
  1489. void ResourceFormatSaverBinary::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
  1490. String base = p_resource->get_base_extension().to_lower();
  1491. p_extensions->push_back(base);
  1492. if (base != "res")
  1493. p_extensions->push_back("res");
  1494. }
  1495. ResourceFormatSaverBinary *ResourceFormatSaverBinary::singleton = NULL;
  1496. ResourceFormatSaverBinary::ResourceFormatSaverBinary() {
  1497. singleton = this;
  1498. }