level_resource.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2012-2023 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "core/containers/array.inl"
  6. #include "core/filesystem/file.h"
  7. #include "core/filesystem/filesystem.h"
  8. #include "core/json/json_object.inl"
  9. #include "core/json/sjson.h"
  10. #include "core/memory/globals.h"
  11. #include "core/memory/temp_allocator.inl"
  12. #include "core/strings/dynamic_string.inl"
  13. #include "core/strings/string_id.inl"
  14. #include "resource/compile_options.inl"
  15. #include "resource/level_resource.h"
  16. #include "resource/unit_compiler.h"
  17. namespace crown
  18. {
  19. namespace level_resource
  20. {
  21. const StringId32 *unit_names(const LevelResource *lr)
  22. {
  23. return (const StringId32 *)((char *)lr + lr->unit_names_offset);
  24. }
  25. const UnitResource *unit_resource(const LevelResource *lr)
  26. {
  27. return (const UnitResource *)((char *)lr + lr->units_offset);
  28. }
  29. u32 num_sounds(const LevelResource *lr)
  30. {
  31. return lr->num_sounds;
  32. }
  33. const LevelSound *get_sound(const LevelResource *lr, u32 i)
  34. {
  35. CE_ASSERT(i < num_sounds(lr), "Index out of bounds");
  36. const LevelSound *begin = (LevelSound *)((char *)lr + lr->sounds_offset);
  37. return &begin[i];
  38. }
  39. } // namespace level_resource
  40. #if CROWN_CAN_COMPILE
  41. namespace level_resource_internal
  42. {
  43. s32 compile(CompileOptions &opts)
  44. {
  45. Buffer buf = opts.read();
  46. TempAllocator4096 ta;
  47. JsonObject obj(ta);
  48. sjson::parse(obj, buf);
  49. Array<LevelSound> sounds(default_allocator());
  50. {
  51. JsonArray sounds_json(ta);
  52. sjson::parse_array(sounds_json, obj["sounds"]);
  53. for (u32 i = 0; i < array::size(sounds_json); ++i) {
  54. JsonObject sound(ta);
  55. sjson::parse_object(sound, sounds_json[i]);
  56. DynamicString sound_name(ta);
  57. sjson::parse_string(sound_name, sound["name"]);
  58. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("sound"
  59. , sound_name.c_str()
  60. , opts
  61. );
  62. opts.add_requirement("sound", sound_name.c_str());
  63. LevelSound ls;
  64. ls.name = sjson::parse_resource_name(sound["name"]);
  65. ls.position = sjson::parse_vector3 (sound["position"]);
  66. ls.volume = sjson::parse_float (sound["volume"]);
  67. ls.range = sjson::parse_float (sound["range"]);
  68. ls.loop = sjson::parse_bool (sound["loop"]);
  69. array::push_back(sounds, ls);
  70. }
  71. }
  72. UnitCompiler uc(opts);
  73. s32 err = 0;
  74. err = uc.compile_units_array(obj["units"], UINT32_MAX);
  75. DATA_COMPILER_ENSURE(err == 0, opts);
  76. Buffer unit_blob = uc.blob();
  77. // Write
  78. LevelResource lr;
  79. lr.version = RESOURCE_HEADER(RESOURCE_VERSION_LEVEL);
  80. lr.num_units = uc._num_units;
  81. lr.num_sounds = array::size(sounds);
  82. lr.sounds_offset = sizeof(lr);
  83. lr.unit_names_offset = lr.sounds_offset + sizeof(LevelSound) * lr.num_sounds;
  84. lr.units_offset = lr.unit_names_offset + sizeof(StringId32) * lr.num_units;
  85. lr.units_offset = (u32)(uintptr_t)memory::align_top((void *)(uintptr_t)lr.units_offset, 16);
  86. opts.write(lr.version);
  87. opts.write(lr.num_units);
  88. opts.write(lr.unit_names_offset);
  89. opts.write(lr.units_offset);
  90. opts.write(lr.num_sounds);
  91. opts.write(lr.sounds_offset);
  92. // Write level sounds
  93. for (u32 i = 0; i < array::size(sounds); ++i) {
  94. opts.write(sounds[i].name);
  95. opts.write(sounds[i].position);
  96. opts.write(sounds[i].volume);
  97. opts.write(sounds[i].range);
  98. opts.write(sounds[i].loop);
  99. }
  100. // Write unit names
  101. for (u32 i = 0; i < array::size(uc._unit_names); ++i)
  102. opts.write(uc._unit_names[i]._id);
  103. // Write units
  104. opts.align(16);
  105. opts.write(unit_blob);
  106. return 0;
  107. }
  108. } // namespace level_resource_internal
  109. #endif // if CROWN_CAN_COMPILE
  110. } // namespace crown