You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

180 rivejä
4.2 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #include <cmath>
  15. #ifdef WIN32
  16. # define WIN32_LEAN_AND_MEAN
  17. # include <windows.h>
  18. #endif
  19. #if defined __APPLE__ && defined __MACH__
  20. # include <OpenGL/gl.h>
  21. #else
  22. # define GL_GLEXT_PROTOTYPES
  23. # include <GL/gl.h>
  24. #endif
  25. #include <SDL.h>
  26. #include <SDL_image.h>
  27. #include "core.h"
  28. /*
  29. * TileSet implementation class
  30. */
  31. class TileSetData
  32. {
  33. friend class TileSet;
  34. private:
  35. char *name;
  36. int *tiles;
  37. int w, h, nw, nh, ntiles;
  38. float dilate, tx, ty;
  39. SDL_Surface *img;
  40. GLuint texture;
  41. };
  42. /*
  43. * Public TileSet class
  44. */
  45. TileSet::TileSet(char const *path, int w, int h, float dilate)
  46. : data(new TileSetData())
  47. {
  48. data->name = strdup(path);
  49. data->tiles = NULL;
  50. data->img = NULL;
  51. data->texture = 0;
  52. for (char const *name = path; *name; name++)
  53. if ((data->img = IMG_Load(name)))
  54. break;
  55. if (!data->img)
  56. {
  57. #if !FINAL_RELEASE
  58. fprintf(stderr, "ERROR: could not load %s\n", path);
  59. #endif
  60. SDL_Quit();
  61. exit(1);
  62. }
  63. if (w <= 0)
  64. w = 32;
  65. if (h <= 0)
  66. h = 32;
  67. data->w = w;
  68. data->h = h;
  69. data->dilate = dilate;
  70. /* FIXME: check for non-zero here */
  71. data->nw = data->img->w / w;
  72. data->nh = data->img->h / h;
  73. data->ntiles = data->nw * data->nh;
  74. data->tx = (float)w / PotUp(data->img->w);
  75. data->ty = (float)h / PotUp(data->img->h);
  76. drawgroup = DRAWGROUP_BEFORE;
  77. }
  78. TileSet::~TileSet()
  79. {
  80. free(data->tiles);
  81. free(data->name);
  82. delete data;
  83. }
  84. void TileSet::TickDraw(float deltams)
  85. {
  86. Entity::TickDraw(deltams);
  87. if (destroy)
  88. {
  89. if (data->img)
  90. SDL_FreeSurface(data->img);
  91. else
  92. glDeleteTextures(1, &data->texture);
  93. }
  94. else if (data->img)
  95. {
  96. GLuint format = data->img->format->Amask ? GL_RGBA : GL_RGB;
  97. int planes = data->img->format->Amask ? 4 : 3;
  98. int w = PotUp(data->img->w);
  99. int h = PotUp(data->img->h);
  100. uint8_t *pixels = (uint8_t *)data->img->pixels;
  101. if (w != data->img->w || h != data->img->h)
  102. {
  103. uint8_t *tmp = (uint8_t *)malloc(planes * w * h);
  104. for (int line = 0; line < data->img->h; line++)
  105. memcpy(tmp + planes * w * line,
  106. pixels + planes * data->img->w * line,
  107. planes * data->img->w);
  108. pixels = tmp;
  109. }
  110. glGenTextures(1, &data->texture);
  111. glBindTexture(GL_TEXTURE_2D, data->texture);
  112. glTexImage2D(GL_TEXTURE_2D, 0, planes, w, h, 0,
  113. format, GL_UNSIGNED_BYTE, pixels);
  114. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  115. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  116. if (pixels != data->img->pixels)
  117. free(pixels);
  118. SDL_FreeSurface(data->img);
  119. data->img = NULL;
  120. }
  121. }
  122. char const *TileSet::GetName()
  123. {
  124. return data->name;
  125. }
  126. void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o)
  127. {
  128. float tx = data->tx * ((id & 0xffff) % data->nw);
  129. float ty = data->ty * ((id & 0xffff) / data->nw);
  130. float dilate = data->dilate;
  131. int off = o ? data->h : 0;
  132. int dx = data->w;
  133. int dy = data->h * 38 / 32; /* Magic... fix this one day */
  134. int dy2 = data->h * 70 / 32;
  135. if (!data->img)
  136. {
  137. glBindTexture(GL_TEXTURE_2D, data->texture);
  138. glBegin(GL_QUADS);
  139. glTexCoord2f(tx, ty);
  140. glVertex3f(x, dilate * (y - dy - off), dilate * (z + off));
  141. glTexCoord2f(tx + data->tx, ty);
  142. glVertex3f(x + dx, dilate * (y - dy - off), dilate * (z + off));
  143. glTexCoord2f(tx + data->tx, ty + data->ty);
  144. glVertex3f(x + dx, dilate * (y - dy2), dilate * z);
  145. glTexCoord2f(tx, ty + data->ty);
  146. glVertex3f(x, dilate * (y - dy2), dilate * z);
  147. glEnd();
  148. }
  149. }