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.
 
 
 
 
 
 

235 lines
5.0 KiB

  1. /*
  2. * ttyvaders Textmode shoot'em up
  3. * Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include "config.h"
  23. #include <stdlib.h>
  24. #include "common.h"
  25. /* Init tunnel */
  26. tunnel * create_tunnel(game *g, int w, int h)
  27. {
  28. int i;
  29. tunnel *t = malloc(sizeof(tunnel));
  30. t->left = malloc(h*sizeof(int));
  31. t->right = malloc(h*sizeof(int));
  32. t->w = w;
  33. t->h = h;
  34. if(t->w >= g->w)
  35. {
  36. for(i = 0; i < g->h; i++)
  37. {
  38. t->left[i] = -10;
  39. t->right[i] = g->w + 10;
  40. }
  41. }
  42. else
  43. {
  44. t->left[0] = (g->w - w) / 2;
  45. t->right[0] = (g->w + w) / 2;
  46. /* Yeah, sub-efficient, but less code to do :-) */
  47. for(i = 0; i < g->h; i++)
  48. {
  49. update_tunnel(g, t);
  50. }
  51. }
  52. return t;
  53. }
  54. void free_tunnel(tunnel *t)
  55. {
  56. free(t->left);
  57. free(t->right);
  58. free(t);
  59. }
  60. void draw_tunnel(game *g, tunnel *t)
  61. {
  62. int i, j;
  63. char c;
  64. ee_color(EE_GREEN);
  65. /* Left border */
  66. for(i = 0; i < g->h ; i++)
  67. {
  68. if(t->left[i] <= -10)
  69. {
  70. continue;
  71. }
  72. if(i + 1 == g->h || t->left[i] > t->left[i+1])
  73. {
  74. c = (i == 0 || t->left[i] > t->left[i-1]) ? '>' : '/';
  75. }
  76. else
  77. {
  78. c = (i == 0 || t->left[i] > t->left[i-1]) ? '\\' : '<';
  79. }
  80. ee_goto(t->left[i] + 1, i);
  81. ee_putchar(c);
  82. if(i + 1 < g->h)
  83. {
  84. for(j = 1; j < t->left[i+1] - t->left[i]; j++)
  85. {
  86. ee_goto(t->left[i] + j + 1, i);
  87. ee_putchar('_');
  88. }
  89. }
  90. }
  91. /* Right border */
  92. for(i = 0; i < g->h ; i++)
  93. {
  94. if(t->right[i] >= g->w + 10)
  95. {
  96. continue;
  97. }
  98. if(i + 1 == g->h || t->right[i] > t->right[i+1])
  99. {
  100. c = (i == 0 || t->right[i] > t->right[i-1]) ? '>' : '/';
  101. }
  102. else
  103. {
  104. c = (i == 0 || t->right[i] > t->right[i-1]) ? '\\' : '<';
  105. }
  106. if(i + 1 < g->h)
  107. {
  108. for(j = 1; j < t->right[i] - t->right[i+1]; j++)
  109. {
  110. ee_goto(t->right[i+1] + j - 1, i);
  111. ee_putchar('_');
  112. }
  113. }
  114. ee_goto(t->right[i] - 1, i);
  115. ee_putchar(c);
  116. }
  117. ee_color(EE_RED);
  118. /* Left concrete */
  119. for(i = 0; i < g->h ; i++)
  120. {
  121. for(j = 0 ; j <= t->left[i]; j++)
  122. {
  123. ee_goto(j, i);
  124. ee_putchar('#');
  125. }
  126. }
  127. /* Right concrete */
  128. for(i = 0; i < g->h ; i++)
  129. {
  130. for(j = t->right[i] ; j < g->w ; j++)
  131. {
  132. ee_goto(j, i);
  133. ee_putchar('#');
  134. }
  135. }
  136. }
  137. void update_tunnel(game *g, tunnel *t)
  138. {
  139. static int const delta[] = { -3, -2, -1, 1, 2, 3 };
  140. int i,j,k;
  141. /* Slide tunnel one block vertically */
  142. for(i = t->h - 1; i--;)
  143. {
  144. t->left[i+1] = t->left[i];
  145. t->right[i+1] = t->right[i];
  146. }
  147. /* Generate new values */
  148. i = delta[ee_rand(0,5)];
  149. j = delta[ee_rand(0,5)];
  150. /* Check in which direction we need to alter tunnel */
  151. if(t->right[1] - t->left[1] < t->w)
  152. {
  153. /* Not wide enough, make sure i <= j */
  154. if(i > j)
  155. {
  156. k = j; j = i; i = k;
  157. }
  158. }
  159. else if(t->right[1] - t->left[1] - 2 > t->w)
  160. {
  161. /* Too wide, make sure i >= j */
  162. if(i < j)
  163. {
  164. k = j; j = i; i = k;
  165. }
  166. }
  167. else
  168. {
  169. /* No need to mess with i and j: width is OK */
  170. }
  171. /* If width doesn't exceed game size, update coords */
  172. if(t->w <= g->w || t->right[1] - t->left[1] < t->w)
  173. {
  174. t->left[0] = t->left[1] + i;
  175. t->right[0] = t->right[1] + j;
  176. }
  177. else
  178. {
  179. t->left[0] = -10;
  180. t->right[0] = g->w + 10;
  181. }
  182. if(t->w > g->w)
  183. {
  184. if(t->left[0] < 0 && t->right[0] < g->w - 2)
  185. {
  186. t->left[0] = t->left[1] + 1;
  187. }
  188. if(t->left[0] > 1 && t->right[0] > g->w - 1)
  189. {
  190. t->right[0] = t->right[1] - 1;
  191. }
  192. }
  193. else
  194. {
  195. if(t->left[0] < 0)
  196. {
  197. t->left[0] = t->left[1] + 1;
  198. }
  199. if(t->right[0] > g->w - 1)
  200. {
  201. t->right[0] = t->right[1] - 1;
  202. }
  203. }
  204. }