229 行
5.5 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cstdlib>
  14. #include <cstdio>
  15. #include <cstring>
  16. #if defined _WIN32
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <windows.h>
  19. # undef WIN32_LEAN_AND_MEAN
  20. #endif
  21. #include "textureimage-private.h"
  22. namespace lol
  23. {
  24. /*
  25. * TileSet implementation class
  26. */
  27. class TileSetData
  28. {
  29. friend class TileSet;
  30. protected:
  31. /* Pixels, then texture coordinates */
  32. array<ibox2, box2> m_tiles;
  33. ivec2 m_tile_size;
  34. };
  35. /*
  36. * Public TileSet class
  37. */
  38. TileSet::TileSet(char const *path)
  39. : TextureImage(path),
  40. m_tileset_data(new TileSetData()),
  41. m_palette(nullptr)
  42. {
  43. array<ivec2, ivec2> tiles;
  44. if (m_data->m_image->RetrieveTiles(tiles))
  45. for (int i = 0; i < tiles.count(); i++)
  46. define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2));
  47. }
  48. TileSet::TileSet(char const *path, Image* image)
  49. : TextureImage(path, image),
  50. m_tileset_data(new TileSetData()),
  51. m_palette(nullptr)
  52. {
  53. array<ivec2, ivec2> tiles;
  54. if (m_data->m_image->RetrieveTiles(tiles))
  55. for (int i = 0; i < tiles.count(); i++)
  56. define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2));
  57. }
  58. TileSet::TileSet(char const *path, ivec2 size, ivec2 count)
  59. : TileSet(path)
  60. {
  61. /* If count is valid, fix size; otherwise, fix count. */
  62. if (count.x > 0 && count.y > 0)
  63. {
  64. size = m_data->m_image_size / count;
  65. }
  66. else
  67. {
  68. if (size.x <= 0 || size.y <= 0)
  69. size = ivec2(32, 32);
  70. count = max(ivec2(1, 1), m_data->m_image_size / size);
  71. }
  72. for (int j = 0; j < count.y; ++j)
  73. for (int i = 0; i < count.x; ++i)
  74. {
  75. define_tile(ibox2(size * ivec2(i, j),
  76. size * ivec2(i + 1, j + 1)));
  77. }
  78. }
  79. TileSet::TileSet(char const *path, Image* image, ivec2 size, ivec2 count)
  80. : TileSet(path, image)
  81. {
  82. /* If count is valid, fix size; otherwise, fix count. */
  83. if (count.x > 0 && count.y > 0)
  84. {
  85. size = m_data->m_image_size / count;
  86. }
  87. else
  88. {
  89. if (size.x <= 0 || size.y <= 0)
  90. size = ivec2(32, 32);
  91. count = max(ivec2(1, 1), m_data->m_image_size / size);
  92. }
  93. for (int j = 0; j < count.y; ++j)
  94. for (int i = 0; i < count.x; ++i)
  95. {
  96. define_tile(ibox2(size * ivec2(i, j),
  97. size * ivec2(i + 1, j + 1)));
  98. }
  99. }
  100. TileSet::~TileSet()
  101. {
  102. delete m_tileset_data;
  103. }
  104. void TileSet::Init(char const *path, Image* image)
  105. {
  106. super::Init(path, image);
  107. m_data->m_name = String("<tileset> ") + path;
  108. }
  109. //Inherited from Entity -------------------------------------------------------
  110. char const *TileSet::GetName()
  111. {
  112. return m_data->m_name.C();
  113. }
  114. //New methods -----------------------------------------------------------------
  115. int TileSet::define_tile(ibox2 rect)
  116. {
  117. m_tileset_data->m_tiles.push(rect,
  118. box2((vec2)rect.aa / (vec2)m_data->m_texture_size,
  119. (vec2)rect.bb / (vec2)m_data->m_texture_size));
  120. return m_tileset_data->m_tiles.count() - 1;
  121. }
  122. void TileSet::define_tile(ivec2 count)
  123. {
  124. ivec2 size = m_data->m_image_size / count;
  125. for (int j = 0; j < count.y; ++j)
  126. for (int i = 0; i < count.x; ++i)
  127. {
  128. define_tile(ibox2(size * ivec2(i, j),
  129. size * ivec2(i + 1, j + 1)));
  130. }
  131. }
  132. int TileSet::GetTileCount() const
  133. {
  134. return m_tileset_data->m_tiles.count();
  135. }
  136. ivec2 TileSet::GetTileSize(int tileid) const
  137. {
  138. return m_tileset_data->m_tiles[tileid].m1.extent();
  139. }
  140. ibox2 TileSet::GetTilePixel(int tileid) const
  141. {
  142. return m_tileset_data->m_tiles[tileid].m1;
  143. }
  144. box2 TileSet::GetTileTexel(int tileid) const
  145. {
  146. return m_tileset_data->m_tiles[tileid].m2;
  147. }
  148. //Palette ---------------------------------------------------------------------
  149. void TileSet::SetPalette(TileSet* palette)
  150. {
  151. m_palette = palette;
  152. }
  153. TileSet* TileSet::GetPalette()
  154. {
  155. return m_palette;
  156. }
  157. TileSet const* TileSet::GetPalette() const
  158. {
  159. return m_palette;
  160. }
  161. void TileSet::BlitTile(uint32_t id, mat4 model, vec3 *vertex, vec2 *texture)
  162. {
  163. ibox2 pixels = m_tileset_data->m_tiles[id].m1;
  164. box2 texels = m_tileset_data->m_tiles[id].m2;
  165. float dtx = texels.extent().x;
  166. float dty = texels.extent().y;
  167. float tx = texels.aa.x;
  168. float ty = texels.aa.y;
  169. vec3 pos = (model * vec4(0.f, 0.f, 0.f, 1.f)).xyz;
  170. vec3 extent_x = 0.5f * pixels.extent().x * (model * vec4::axis_x).xyz;
  171. vec3 extent_y = 0.5f * pixels.extent().y * (model * vec4::axis_y).xyz;
  172. if (!m_data->m_image && m_data->m_texture)
  173. {
  174. *vertex++ = pos + extent_x + extent_y;
  175. *vertex++ = pos - extent_x + extent_y;
  176. *vertex++ = pos + extent_x - extent_y;
  177. *vertex++ = pos + extent_x - extent_y;
  178. *vertex++ = pos - extent_x + extent_y;
  179. *vertex++ = pos - extent_x - extent_y;
  180. *texture++ = vec2(tx + dtx, ty);
  181. *texture++ = vec2(tx, ty);
  182. *texture++ = vec2(tx + dtx, ty + dty);
  183. *texture++ = vec2(tx + dtx, ty + dty);
  184. *texture++ = vec2(tx, ty);
  185. *texture++ = vec2(tx, ty + dty);
  186. }
  187. else
  188. {
  189. memset(vertex, 0, 6 * sizeof(vec3));
  190. memset(texture, 0, 6 * sizeof(vec2));
  191. }
  192. }
  193. } /* namespace lol */