level_resource.cpp 2.8 KB

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