VGearsBackgroundFileSerializer.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <OgreException.h>
  16. #include <OgreLogManager.h>
  17. #include <OgreStringConverter.h>
  18. #include "data/VGearsBackgroundFileSerializer.h"
  19. #include "data/VGearsPaletteFileSerializer.h"
  20. namespace VGears{
  21. const String BackgroundFileSerializer::SECTION_NAME_PALETTE("PALETTE");
  22. const String BackgroundFileSerializer::SECTION_NAME_BACK("BACK");
  23. const String BackgroundFileSerializer::SECTION_NAME_TEXTURE("TEXTURE");
  24. const String BackgroundFileSerializer::TAG_FILE_END("END");
  25. const Ogre::Real BackgroundFileSerializer::SRC_BIG_SCALE(10000000.0);
  26. BackgroundFileSerializer::BackgroundFileSerializer() :
  27. Serializer(), layer_index_(BackgroundFile::LAYER_COUNT)
  28. {}
  29. BackgroundFileSerializer::~BackgroundFileSerializer(){}
  30. void BackgroundFileSerializer::ImportBackgroundFile(
  31. Ogre::DataStreamPtr &stream, BackgroundFile *dest
  32. ){
  33. ReadFileHeader(stream);
  34. Read1ByteBool(stream, dest->GetLayers()[0].enabled);
  35. ReadPallete(stream, dest);
  36. stream->skip(2 * 2); // 2 * uint16 unused;
  37. ReadBackground(stream, dest);
  38. ReadTexture(stream, dest);
  39. ReadEnd(stream);
  40. }
  41. void BackgroundFileSerializer::ReadFileHeader(Ogre::DataStreamPtr &stream){
  42. uint16 data[2];
  43. readShorts(stream, data, 2);
  44. header_.unused = data[0];
  45. header_.sort_sprites_by_palette = data[1];
  46. }
  47. void
  48. BackgroundFileSerializer::ReadSectionHeader(Ogre::DataStreamPtr &stream
  49. ,const String &section_name)
  50. {
  51. String actual(readString(stream, section_name.size()));
  52. if (actual != section_name)
  53. {
  54. Ogre::LogManager::getSingleton().stream()
  55. << "Warming: Section didn't start with"
  56. << " expected String '" << section_name << "'"
  57. << " actual was '" << actual << "'";
  58. }
  59. }
  60. void BackgroundFileSerializer::ReadEnd(Ogre::DataStreamPtr &stream){
  61. ReadEndString(stream, TAG_FILE_END);
  62. }
  63. void BackgroundFileSerializer::ReadPallete(
  64. Ogre::DataStreamPtr &stream, BackgroundFile *dest){
  65. ReadSectionHeader(stream, SECTION_NAME_PALETTE);
  66. stream->read(
  67. dest->GetPalette().data(), BackgroundFile::PALETTE_ENTRY_COUNT
  68. );
  69. }
  70. void BackgroundFileSerializer::ReadBackground(
  71. Ogre::DataStreamPtr &stream, BackgroundFile *dest
  72. ){
  73. ReadSectionHeader(stream, SECTION_NAME_BACK);
  74. auto& layers(dest->GetLayers());
  75. for (size_t i(0); i < BackgroundFile::LAYER_COUNT; ++ i){
  76. if (i != 0) Read1ByteBool(stream, layers[i].enabled);
  77. ReadLayer(stream, &layers[i], i);
  78. }
  79. }
  80. void BackgroundFileSerializer::ReadLayer(
  81. Ogre::DataStreamPtr &stream, Layer *dest, size_t layer_index
  82. ){
  83. if (!dest->enabled) return;
  84. uint16 tmp[4], sprite_count;
  85. readShorts(stream, tmp, 4);
  86. dest->width = tmp[0];
  87. dest->height = tmp[1];
  88. sprite_count = tmp[2];
  89. dest->unknown_06 = tmp[3];
  90. switch(layer_index)
  91. {
  92. case 1:
  93. readShorts(stream, dest->unknown_08, 3);
  94. case 2:
  95. case 3:
  96. readShorts(stream, dest->unknown_0E, 4);
  97. }
  98. stream->skip(2 * 2); // 2 * uint16 unused.
  99. layer_index_ = layer_index;
  100. ReadVector(stream, dest->sprites, sprite_count);
  101. RemoveBuggySprites(dest->sprites);
  102. }
  103. void BackgroundFileSerializer::RemoveBuggySprites(SpriteList &sprites){
  104. auto it = sprites.begin();
  105. while (it != sprites.end()){
  106. const SpriteData &sprite = (*it);
  107. if (
  108. std::abs(sprite.dst.x) > SPRITE_DST_MAX
  109. || std::abs(sprite.dst.y) > SPRITE_DST_MAX
  110. ){
  111. it = sprites.erase(it);
  112. }
  113. else ++ it;
  114. }
  115. }
  116. void BackgroundFileSerializer::readObject(
  117. Ogre::DataStreamPtr &stream, SpriteData &dest
  118. ){
  119. readObject(stream, dest.dst);
  120. readShorts(stream, dest.unknown_04, 2);
  121. readObject(stream, dest.src);
  122. readObject(stream, dest.src2);
  123. ReadShort(stream, dest.width);
  124. ReadShort(stream, dest.height);
  125. uint16 size;
  126. // width and height are sometimes incorrect in the file
  127. if (layer_index_ < 2) size = 16;
  128. else if (layer_index_ < BackgroundFile::LAYER_COUNT) size = 32;
  129. else{
  130. OGRE_EXCEPT(
  131. Ogre::Exception::ERR_INVALIDPARAMS,
  132. "layer_index_ not set correctly",
  133. "BackgroundFileSerializer::readObject"
  134. );
  135. }
  136. dest.width = dest.height = size;
  137. ReadShort(stream, dest.palette_page);
  138. ReadShort(stream, dest.depth);
  139. // Force depth values
  140. switch (layer_index_){
  141. case 0:
  142. dest.depth = 4095;
  143. break;
  144. case 2:
  145. dest.depth = 4096;
  146. break;
  147. case 3:
  148. dest.depth = 0;
  149. break;
  150. }
  151. uint8 animation[2];
  152. stream->read(animation, sizeof(animation));
  153. dest.animation_id = animation[0];
  154. dest.animation_frame = animation[1];
  155. uint8 has_blending[2];
  156. stream->read(has_blending, sizeof(has_blending));
  157. dest.has_blending[0] = has_blending[0] > 0;
  158. dest.has_blending[1] = has_blending[1] > 0;
  159. ReadShort(stream, dest.blending);
  160. ReadShort(stream, dest.data_page);
  161. ReadShort(stream, dest.data_page2);
  162. // When data_page2 != 0, it must be used instead of data_page (not for
  163. // the first layer).
  164. if (layer_index_ > 0 && dest.data_page2){
  165. dest.src = dest.src2;
  166. dest.data_page = dest.data_page2;
  167. }
  168. ReadShort(stream, dest.colour_depth);
  169. readObject(stream, dest.src_big);
  170. dest.src_big /= SRC_BIG_SCALE;
  171. stream->skip(2 * 2); // 2 * uint16 unused
  172. }
  173. void BackgroundFileSerializer::ReadTexture(
  174. Ogre::DataStreamPtr &stream, BackgroundFile *dest
  175. ){
  176. ReadSectionHeader(stream, SECTION_NAME_TEXTURE);
  177. for (auto& page : dest->GetPages()) readObject(stream, page);
  178. }
  179. void BackgroundFileSerializer::readObject(
  180. Ogre::DataStreamPtr& stream, Color& dest
  181. ){
  182. uint16 colour;
  183. ReadShort(stream, colour);
  184. dest.r = static_cast<float>((colour & BIT_MASK_RED) >> 11);
  185. dest.g = static_cast<float>((colour & BIT_MASK_GREEN) >> 6);
  186. dest.b = static_cast<float>(colour & BIT_MASK_BLUE);
  187. dest /= BIT_SIZE;
  188. dest.a = 1.0f;
  189. if (colour == 0) dest.a = 0.0f;
  190. }
  191. void BackgroundFileSerializer::readObject(
  192. Ogre::DataStreamPtr &stream, Page &dest
  193. ){
  194. Read2ByteBool(stream, dest.enabled);
  195. if (!dest.enabled) return;
  196. ReadShort(stream, dest.unknown_02);
  197. ReadShort(stream, dest.value_size);
  198. if (dest.value_size != 1 && dest.value_size != 2){
  199. OGRE_EXCEPT(
  200. Ogre::Exception::ERR_INVALIDPARAMS,
  201. "Page value_size other then 1 and 2 is not supported",
  202. "BackgroundFileSerializer::readObject"
  203. );
  204. }
  205. size_t color_count(BackgroundFile::PAGE_DATA_SIZE);
  206. dest.colors.clear();
  207. dest.data.clear();
  208. if (dest.value_size == 2){
  209. dest.colors.reserve(color_count);
  210. for (size_t i(color_count); i --;){
  211. Color colourDest;
  212. readObject(stream, colourDest);
  213. dest.colors.push_back(colourDest);
  214. }
  215. }
  216. else{
  217. dest.data.resize(color_count);
  218. stream->read(&dest.data[0], color_count);
  219. }
  220. }
  221. }