texture.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include "image.hpp"
  2. #include "video.hpp"
  3. #include "macs.hpp"
  4. #include "event.hpp"
  5. #include <math.h>
  6. #define SHB 7
  7. class vect
  8. {
  9. public :
  10. long screenx, screeny, screendx, screendy,
  11. imagex, imagey, imagedx, imagedy;
  12. short steps;
  13. void init(short imagex1, short imagey1, short imagex2, short imagey2,
  14. short screenx1, short screeny1, short screenx2, short screeny2);
  15. short step();
  16. } ;
  17. inline short vect::step()
  18. {
  19. long oy;
  20. do
  21. {
  22. oy=screeny>>SHB;
  23. screenx+=screendx;
  24. screeny+=screendy;
  25. imagex+=imagedx;
  26. imagey+=imagedy;
  27. steps--;
  28. } while (steps && (screeny>>SHB)==oy);
  29. return steps>=0;
  30. }
  31. void vect::init(short imagex1, short imagey1, short imagex2, short imagey2,
  32. short screenx1, short screeny1, short screenx2, short screeny2)
  33. {
  34. steps=abs(screeny1-screeny2)+1;
  35. screenx=(long)screenx1<<SHB;
  36. screeny=(long)screeny1<<SHB;
  37. if (screenx2>=screenx1)
  38. screendx=((long)(screenx2-screenx1+1)<<(SHB*2))/((long)(steps<<SHB));
  39. else screendx=((long)(screenx2-screenx1-1)<<(SHB*2))/((long)(steps<<SHB));
  40. if (screeny2>=screeny1)
  41. screendy=((long)(screeny2-screeny1+1)<<(SHB*2))/((long)(steps<<SHB));
  42. else
  43. screendy=((long)(screeny2-screeny1-1)<<(SHB*2))/((long)(steps<<SHB));
  44. imagex =(long)imagex1<<SHB;
  45. imagey =(long)imagey1<<SHB;
  46. if (imagex2>=imagex1)
  47. imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
  48. else
  49. imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
  50. if (imagey2>=imagey1)
  51. imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
  52. else
  53. imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
  54. }
  55. void texture_map(image *screen, image *tx, short *points)
  56. {
  57. vect right[2],left[2];
  58. unsigned char *sl;
  59. short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
  60. short cx1,cy1,cx2,cy2;
  61. long ix,iy,idx,idy,steps,scx;
  62. screen->get_clip(cx1,cy1,cx2,cy2);
  63. x1=0;
  64. x2=0;
  65. for (i=1;i<4;i++)
  66. if (points[i*2]<points[x1*2])
  67. x1=i;
  68. else if (points[i*2]>points[x2*2])
  69. x2=i;
  70. min=0;
  71. max=0;
  72. for (i=1;i<4;i++)
  73. if (points[i*2+1]<points[min*2+1])
  74. min=i;
  75. else if (points[i*2+1]>points[max*2+1])
  76. max=i;
  77. if (min==0)
  78. {
  79. right[0].init(0,0,tx->width()-1,0, points[0],points[1],points[2],points[3]);
  80. right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
  81. left[0].init(0,0,0,tx->height()-1, points[0],points[1],points[6],points[7]);
  82. left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
  83. }
  84. else if (min==1)
  85. {
  86. right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
  87. right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  88. left[0].init(tx->width()-1,0,0,0, points[2],points[3],points[0],points[1]);
  89. left[1].init(0,0,0,tx->height()-1, points[0],points[1],points[6],points[7]);
  90. } else if (min==2)
  91. {
  92. right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  93. right[1].init(0,tx->height()-1,0,0, points[6],points[7],points[0],points[1]);
  94. left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  95. left[1].init(tx->width()-1,0,0,0, points[2],points[3],points[0],points[1]);
  96. } else
  97. {
  98. right[0].init(0,tx->height()-1,0,0, points[6],points[7],points[0],points[1]);
  99. right[1].init(0,0,tx->width()-1,0, points[0],points[1],points[2],points[3]);
  100. left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  101. left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  102. }
  103. do
  104. {
  105. screeny=right[r].screeny>>SHB;
  106. if (screeny>=cy1 && screeny<=cy2)
  107. {
  108. sl=screen->scan_line(screeny);
  109. ix=left[l].imagex;
  110. iy=left[l].imagey;
  111. if (left[l].screenx<right[r].screenx)
  112. { sa=1; steps=right[r].screenx-left[l].screenx; }
  113. else { sa=-1; steps=left[l].screenx-right[r].screenx; }
  114. steps+=1<<SHB;
  115. if (right[r].imagex>ix)
  116. idx=((right[r].imagex-ix)<<SHB)/steps;
  117. else idx=((right[r].imagex-ix)<<SHB)/steps;
  118. if (right[r].imagey>iy)
  119. idy=((right[r].imagey-iy)<<SHB)/steps;
  120. else idy=((right[r].imagey-iy)<<SHB)/steps;
  121. scx=left[l].screenx>>SHB;
  122. steps=steps>>SHB;
  123. if (left[l].screenx<right[r].screenx)
  124. sa=1; else sa=-1;
  125. while (steps--)
  126. {
  127. if (scx>=cx1 && scx<=cx2)
  128. sl[scx]=tx->scan_line(iy>>SHB)[ix>>SHB];
  129. ix+=idx; iy+=idy;
  130. scx+=sa;
  131. }
  132. }
  133. do
  134. { y=right[r].screeny>>SHB;
  135. if (!right[r].step())
  136. r++;
  137. } while (r!=2 && y==right[r].screeny>>SHB);
  138. do
  139. { y=left[l].screeny>>SHB;
  140. if (!left[l].step())
  141. l++;
  142. } while (l!=2 && y==left[l].screeny>>SHB);
  143. } while (r!=2 && l!=2);
  144. }
  145. // slower, but allows transparency textures
  146. void clear_texture_map(image *screen, image *tx, short *points)
  147. {
  148. vect right[3],left[3];
  149. unsigned char *sl;
  150. short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
  151. short cx1,cy1,cx2,cy2;
  152. long ix,iy,idx,idy,steps,scx;
  153. screen->get_clip(cx1,cy1,cx2,cy2);
  154. x1=0;
  155. x2=0;
  156. for (i=1;i<4;i++)
  157. if (points[i*2]<points[x1*2])
  158. x1=i;
  159. else if (points[i*2]>points[x2*2])
  160. x2=i;
  161. min=0;
  162. max=0;
  163. for (i=1;i<4;i++)
  164. if (points[i*2+1]<points[min*2+1])
  165. min=i;
  166. else if (points[i*2+1]>points[max*2+1])
  167. max=i;
  168. if (min==0)
  169. {
  170. right[0].init(0,0,tx->width()-1,0, points[0],points[1],points[2],points[3]);
  171. right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
  172. right[2].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  173. left[0].init(0,0,0,tx->height()-1, points[0],points[1],points[6],points[7]);
  174. left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
  175. left[2].init(tx->width()-1,tx->height()-1,tx->width()-1,0, points[4],points[5],points[2],points[3]);
  176. }
  177. else if (min==1)
  178. {
  179. right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
  180. right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  181. right[2].init(0,tx->height()-1,0,0, points[6],points[7],points[0],points[1]);
  182. left[0].init(tx->width()-1,0,0,0, points[2],points[3],points[0],points[1]);
  183. left[1].init(0,0,0,tx->height()-1, points[0],points[1],points[6],points[7]);
  184. left[2].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  185. } else if (min==2)
  186. {
  187. right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
  188. right[1].init(0,tx->height()-1,0,0, points[6],points[7],points[0],points[1]);
  189. right[2].init(0,0,tx->width()-1,0, points[0],points[1],points[2],points[3]);
  190. left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  191. left[1].init(tx->width()-1,0,0,0, points[2],points[3],points[0],points[1]);
  192. left[2].init(0,0,0,tx->height()-1, points[0],points[1],points[6],points[7]);
  193. } else
  194. {
  195. right[0].init(0,tx->height()-1,0,0, points[6],points[7],points[0],points[1]);
  196. right[1].init(0,0,tx->width()-1,0, points[0],points[1],points[2],points[3]);
  197. right[2].init(tx->width()-1,0,tx->width()-1,tx->height(), points[2],points[3],points[4],points[5]);
  198. left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
  199. left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
  200. left[2].init(tx->width()-1,0,0,0, points[2],points[3],points[0],points[1]);
  201. }
  202. do
  203. {
  204. screeny=right[r].screeny>>SHB;
  205. if (screeny>=cy1 && screeny<=cy2)
  206. {
  207. sl=screen->scan_line(screeny);
  208. ix=left[l].imagex;
  209. iy=left[l].imagey;
  210. if (left[l].screenx<right[r].screenx)
  211. { sa=1; steps=right[r].screenx-left[l].screenx; }
  212. else { sa=-1; steps=left[l].screenx-right[r].screenx; }
  213. steps+=1<<SHB;
  214. if (right[r].imagex>ix)
  215. idx=((right[r].imagex-ix)<<SHB)/steps;
  216. else idx=((right[r].imagex-ix)<<SHB)/steps;
  217. if (right[r].imagey>iy)
  218. idy=((right[r].imagey-iy)<<SHB)/steps;
  219. else idy=((right[r].imagey-iy)<<SHB)/steps;
  220. scx=left[l].screenx>>SHB;
  221. steps=steps>>SHB;
  222. if (left[l].screenx<right[r].screenx)
  223. sa=1; else sa=-1;
  224. while (steps--)
  225. {
  226. if (scx>=cx1 && scx<=cx2)
  227. {
  228. unsigned char c=tx->scan_line(iy>>SHB)[ix>>SHB];
  229. if (c!=current_background)
  230. sl[scx]=c;
  231. }
  232. ix+=idx; iy+=idy;
  233. scx+=sa;
  234. }
  235. }
  236. do
  237. { y=right[r].screeny>>SHB;
  238. if (!right[r].step())
  239. r++;
  240. } while (r!=2 && y==(right[r].screeny>>SHB));
  241. do
  242. { y=left[l].screeny>>SHB;
  243. if (!left[l].step())
  244. l++;
  245. } while (l!=2 && y==(left[l].screeny>>SHB));
  246. } while ((r!=2 || l==0) && (l!=2 || r==0));
  247. }