Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

231 linhas
5.6 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) && !defined(_XBOX)
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <windows.h>
  19. # if defined USE_D3D9
  20. # define FAR
  21. # define NEAR
  22. # include <d3d9.h>
  23. # endif
  24. #endif
  25. #include "textureimage-private.h"
  26. namespace lol
  27. {
  28. /*
  29. * TileSet implementation class
  30. */
  31. class TileSetData
  32. {
  33. friend class TileSet;
  34. protected:
  35. /* Pixels, then texture coordinates */
  36. array<ibox2, box2> m_tiles;
  37. ivec2 m_tile_size;
  38. };
  39. /*
  40. * Public TileSet class
  41. */
  42. TileSet::TileSet(char const *path)
  43. : TextureImage(path),
  44. m_tileset_data(new TileSetData()),
  45. m_palette(nullptr)
  46. {
  47. array<ivec2, ivec2> tiles;
  48. if (m_data->m_image->RetrieveTiles(tiles))
  49. for (int i = 0; i < tiles.count(); i++)
  50. define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2));
  51. }
  52. TileSet::TileSet(char const *path, Image* image)
  53. : TextureImage(path, image),
  54. m_tileset_data(new TileSetData()),
  55. m_palette(nullptr)
  56. {
  57. array<ivec2, ivec2> tiles;
  58. if (m_data->m_image->RetrieveTiles(tiles))
  59. for (int i = 0; i < tiles.count(); i++)
  60. define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2));
  61. }
  62. TileSet::TileSet(char const *path, ivec2 size, ivec2 count)
  63. : TileSet(path)
  64. {
  65. /* If count is valid, fix size; otherwise, fix count. */
  66. if (count.x > 0 && count.y > 0)
  67. {
  68. size = m_data->m_image_size / count;
  69. }
  70. else
  71. {
  72. if (size.x <= 0 || size.y <= 0)
  73. size = ivec2(32, 32);
  74. count = max(ivec2(1, 1), m_data->m_image_size / size);
  75. }
  76. for (int j = 0; j < count.y; ++j)
  77. for (int i = 0; i < count.x; ++i)
  78. {
  79. define_tile(ibox2(size * ivec2(i, j),
  80. size * ivec2(i + 1, j + 1)));
  81. }
  82. }
  83. TileSet::TileSet(char const *path, Image* image, ivec2 size, ivec2 count)
  84. : TileSet(path, image)
  85. {
  86. /* If count is valid, fix size; otherwise, fix count. */
  87. if (count.x > 0 && count.y > 0)
  88. {
  89. size = m_data->m_image_size / count;
  90. }
  91. else
  92. {
  93. if (size.x <= 0 || size.y <= 0)
  94. size = ivec2(32, 32);
  95. count = max(ivec2(1, 1), m_data->m_image_size / size);
  96. }
  97. for (int j = 0; j < count.y; ++j)
  98. for (int i = 0; i < count.x; ++i)
  99. {
  100. define_tile(ibox2(size * ivec2(i, j),
  101. size * ivec2(i + 1, j + 1)));
  102. }
  103. }
  104. TileSet::~TileSet()
  105. {
  106. delete m_tileset_data;
  107. }
  108. void TileSet::Init(char const *path, Image* image)
  109. {
  110. super::Init(path, image);
  111. m_data->m_name = String("<tileset> ") + path;
  112. }
  113. //Inherited from Entity -------------------------------------------------------
  114. char const *TileSet::GetName()
  115. {
  116. return m_data->m_name.C();
  117. }
  118. //New methods -----------------------------------------------------------------
  119. int TileSet::define_tile(ibox2 rect)
  120. {
  121. m_tileset_data->m_tiles.push(rect,
  122. box2((vec2)rect.aa / (vec2)m_data->m_texture_size,
  123. (vec2)rect.bb / (vec2)m_data->m_texture_size));
  124. return m_tileset_data->m_tiles.count() - 1;
  125. }
  126. void TileSet::define_tile(ivec2 count)
  127. {
  128. ivec2 size = m_data->m_image_size / count;
  129. for (int j = 0; j < count.y; ++j)
  130. for (int i = 0; i < count.x; ++i)
  131. {
  132. define_tile(ibox2(size * ivec2(i, j),
  133. size * ivec2(i + 1, j + 1)));
  134. }
  135. }
  136. int TileSet::GetTileCount() const
  137. {
  138. return m_tileset_data->m_tiles.count();
  139. }
  140. ivec2 TileSet::GetTileSize(int tileid) const
  141. {
  142. return m_tileset_data->m_tiles[tileid].m1.extent();
  143. }
  144. //Palette ---------------------------------------------------------------------
  145. void TileSet::SetPalette(TileSet* palette)
  146. {
  147. m_palette = palette;
  148. }
  149. TileSet* TileSet::GetPalette()
  150. {
  151. return m_palette;
  152. }
  153. TileSet const* TileSet::GetPalette() const
  154. {
  155. return m_palette;
  156. }
  157. void TileSet::BlitTile(uint32_t id, mat4 model, vec3 *vertex, vec2 *texture)
  158. {
  159. ibox2 pixels = m_tileset_data->m_tiles[id].m1;
  160. box2 texels = m_tileset_data->m_tiles[id].m2;
  161. float dtx = texels.extent().x;
  162. float dty = texels.extent().y;
  163. float tx = texels.aa.x;
  164. float ty = texels.aa.y;
  165. #if 1
  166. /* HACK: tweak UV values */
  167. tx += (1.f / 128.f) * dtx;
  168. ty += (1.f / 128.f) * dty;
  169. dtx *= 126.f / 128.f;
  170. dty *= 126.f / 128.f;
  171. #endif
  172. vec3 pos = (model * vec4(0.f, 0.f, 0.f, 1.f)).xyz;
  173. vec3 extent_x = 0.5f * pixels.extent().x * (model * vec4::axis_x).xyz;
  174. vec3 extent_y = 0.5f * pixels.extent().y * (model * vec4::axis_y).xyz;
  175. if (!m_data->m_image && m_data->m_texture)
  176. {
  177. *vertex++ = pos + extent_x + extent_y;
  178. *vertex++ = pos - extent_x + extent_y;
  179. *vertex++ = pos + extent_x - extent_y;
  180. *vertex++ = pos + extent_x - extent_y;
  181. *vertex++ = pos - extent_x + extent_y;
  182. *vertex++ = pos - extent_x - extent_y;
  183. *texture++ = vec2(tx + dtx, ty);
  184. *texture++ = vec2(tx, ty);
  185. *texture++ = vec2(tx + dtx, ty + dty);
  186. *texture++ = vec2(tx + dtx, ty + dty);
  187. *texture++ = vec2(tx, ty);
  188. *texture++ = vec2(tx, ty + dty);
  189. }
  190. else
  191. {
  192. memset(vertex, 0, 6 * sizeof(vec3));
  193. memset(texture, 0, 6 * sizeof(vec2));
  194. }
  195. }
  196. } /* namespace lol */