level_resource.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright (c) 2012-2017 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "array.h"
  6. #include "compile_options.h"
  7. #include "dynamic_string.h"
  8. #include "file.h"
  9. #include "filesystem.h"
  10. #include "json_object.h"
  11. #include "level_resource.h"
  12. #include "map.h"
  13. #include "memory.h"
  14. #include "sjson.h"
  15. #include "temp_allocator.h"
  16. #include "unit_compiler.h"
  17. namespace crown
  18. {
  19. namespace level_resource_internal
  20. {
  21. void compile(const char* path, CompileOptions& opts)
  22. {
  23. Buffer buf = opts.read(path);
  24. TempAllocator4096 ta;
  25. JsonObject object(ta);
  26. sjson::parse(buf, object);
  27. Array<LevelSound> sounds(default_allocator());
  28. {
  29. JsonObject sounds_json(ta);
  30. sjson::parse_object(object["sounds"], sounds_json);
  31. auto cur = json_object::begin(sounds_json);
  32. auto end = json_object::end(sounds_json);
  33. for (; cur != end; ++cur)
  34. {
  35. JsonObject sound(ta);
  36. sjson::parse_object(cur->pair.second, sound);
  37. DynamicString sound_name(ta);
  38. sjson::parse_string(sound["name"], sound_name);
  39. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("sound"
  40. , sound_name.c_str()
  41. , opts
  42. );
  43. LevelSound ls;
  44. ls.name = sjson::parse_resource_id(sound["name"]);
  45. ls.position = sjson::parse_vector3 (sound["position"]);
  46. ls.volume = sjson::parse_float (sound["volume"]);
  47. ls.range = sjson::parse_float (sound["range"]);
  48. ls.loop = sjson::parse_bool (sound["loop"]);
  49. array::push_back(sounds, ls);
  50. }
  51. }
  52. UnitCompiler uc(opts);
  53. uc.compile_multiple_units(object["units"]);
  54. Buffer unit_blob = uc.blob();
  55. // Write
  56. LevelResource lr;
  57. lr.version = RESOURCE_VERSION_LEVEL;
  58. lr.num_sounds = array::size(sounds);
  59. lr.units_offset = sizeof(LevelResource);
  60. lr.sounds_offset = lr.units_offset + array::size(unit_blob);
  61. opts.write(lr.version);
  62. opts.write(lr.units_offset);
  63. opts.write(lr.num_sounds);
  64. opts.write(lr.sounds_offset);
  65. opts.write(unit_blob);
  66. for (u32 i = 0; i < array::size(sounds); ++i)
  67. {
  68. opts.write(sounds[i].name);
  69. opts.write(sounds[i].position);
  70. opts.write(sounds[i].volume);
  71. opts.write(sounds[i].range);
  72. opts.write(sounds[i].loop);
  73. opts.write(sounds[i]._pad[0]);
  74. opts.write(sounds[i]._pad[1]);
  75. opts.write(sounds[i]._pad[2]);
  76. }
  77. }
  78. } // namespace level_resource_internal
  79. namespace level_resource
  80. {
  81. const UnitResource* unit_resource(const LevelResource* lr)
  82. {
  83. return (const UnitResource*)((char*)lr + lr->units_offset);
  84. }
  85. u32 num_sounds(const LevelResource* lr)
  86. {
  87. return lr->num_sounds;
  88. }
  89. const LevelSound* get_sound(const LevelResource* lr, u32 i)
  90. {
  91. CE_ASSERT(i < num_sounds(lr), "Index out of bounds");
  92. const LevelSound* begin = (LevelSound*)((char*)lr + lr->sounds_offset);
  93. return &begin[i];
  94. }
  95. } // namespace level_resource
  96. } // namespace crown