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.
 
 
 
 
 

735 lines
22 KiB

  1. /*
  2. * ttyvaders Textmode shoot'em up
  3. * Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id: weapons.c,v 1.12 2002/12/23 09:28:37 sam Exp $
  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 <stdlib.h>
  23. #include "common.h"
  24. static void draw_bomb( int x, int y, int vx, int vy );
  25. static void draw_nuke( int x, int y, int frame );
  26. static void draw_beam( int x, int y, int frame );
  27. static void draw_circle( int x, int y, int r, char c );
  28. static void draw_fragbomb( int x, int y, int frame );
  29. void init_weapons( game *g, weapons *wp )
  30. {
  31. int i;
  32. for( i = 0; i < WEAPONS; i++ )
  33. {
  34. wp->type[i] = WEAPON_NONE;
  35. }
  36. }
  37. void draw_weapons( game *g, weapons *wp )
  38. {
  39. int i;
  40. for( i = 0; i < WEAPONS; i++ )
  41. {
  42. switch( wp->type[i] )
  43. {
  44. case WEAPON_LASER:
  45. gfx_color( WHITE );
  46. gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
  47. gfx_putchar( '|' );
  48. gfx_color( CYAN );
  49. gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
  50. gfx_putchar( '|' );
  51. break;
  52. case WEAPON_SEEKER:
  53. gfx_color( CYAN );
  54. gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
  55. gfx_putchar( '.' );
  56. gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
  57. gfx_putchar( 'o' );
  58. gfx_color( WHITE );
  59. gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
  60. gfx_putchar( '@' );
  61. break;
  62. case WEAPON_BOMB:
  63. gfx_color( GRAY );
  64. gfx_goto( (wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4 );
  65. gfx_putchar( '.' );
  66. gfx_goto( (wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4 );
  67. gfx_putchar( '.' );
  68. gfx_goto( (wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4 );
  69. gfx_putchar( '.' );
  70. gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
  71. gfx_putchar( '.' );
  72. gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
  73. gfx_putchar( '.' );
  74. draw_bomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i] );
  75. break;
  76. case WEAPON_FRAGBOMB:
  77. draw_fragbomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
  78. break;
  79. case WEAPON_BEAM:
  80. draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
  81. break;
  82. case WEAPON_NUKE:
  83. draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
  84. break;
  85. case WEAPON_LIGHTNING:
  86. case WEAPON_NONE:
  87. break;
  88. }
  89. }
  90. }
  91. void update_weapons( game *g, weapons *wp )
  92. {
  93. int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
  94. for( i = 0; i < WEAPONS; i++ )
  95. {
  96. switch( wp->type[i] )
  97. {
  98. case WEAPON_LASER:
  99. wp->x[i] += wp->vx[i];
  100. wp->y[i] += wp->vy[i];
  101. if( wp->y[i] < 0 )
  102. {
  103. wp->type[i] = WEAPON_NONE;
  104. }
  105. break;
  106. case WEAPON_BOMB:
  107. case WEAPON_SEEKER:
  108. /* Update tail */
  109. wp->x3[i] = wp->x2[i];
  110. wp->y3[i] = wp->y2[i];
  111. wp->x2[i] = wp->x[i];
  112. wp->y2[i] = wp->y[i];
  113. wp->x[i] += wp->vx[i];
  114. wp->y[i] += wp->vy[i];
  115. if( wp->y[i] < 0 )
  116. {
  117. wp->type[i] = WEAPON_NONE;
  118. break;
  119. }
  120. if( wp->n[i] < 0 )
  121. {
  122. /* Stop updating direction */
  123. break;
  124. }
  125. wp->n[i]--;
  126. /* Estimate our position next frames */
  127. xnew = wp->x[i] + wp->vx[i];
  128. ynew = wp->y[i] + wp->vy[i];
  129. xmin = xnew;
  130. ymin = - (g->h << 4);
  131. dist = (xnew - xmin) * (xnew - xmin)
  132. + 4 * (ynew - ymin) * (ynew - ymin);
  133. /* Find the nearest alien */
  134. for( j = 0; j < ALIENS; j++ )
  135. {
  136. if( g->al->type[j] != ALIEN_NONE )
  137. {
  138. int alx = g->al->x[j] << 4;
  139. int aly = g->al->y[j] << 4;
  140. int new = (xnew - alx) * (xnew - alx)
  141. + 4 * (ynew - aly) * (ynew - aly);
  142. if( new <= dist )
  143. {
  144. dist = new;
  145. xmin = alx;
  146. ymin = aly;
  147. }
  148. }
  149. }
  150. /* Find our new direction */
  151. dx = xmin - wp->x[i];
  152. dy = ymin - wp->y[i];
  153. /* Normalize direction */
  154. if( dx | dy )
  155. {
  156. int norm = r00t( dx * dx + 4 * dy * dy );
  157. dx = dx * 32 / norm;
  158. dy = dy * 32 / norm;
  159. }
  160. /* Find our new speed */
  161. dx = (dx + 3 * wp->vx[i]) / 4;
  162. dy = (dy + 3 * wp->vy[i]) / 4;
  163. /* Normalize speed */
  164. if( dx | dy )
  165. {
  166. int norm = r00t( dx * dx + 4 * dy * dy );
  167. wp->vx[i] = dx * 32 / norm;
  168. wp->vy[i] = dy * 32 / norm;
  169. }
  170. break;
  171. case WEAPON_FRAGBOMB:
  172. /* If n was set to -1, the fragbomb just exploded */
  173. if( wp->n[i] == -1 )
  174. {
  175. int coords[] =
  176. {
  177. 32, 0, -32, 0, 0, 16, 0, -16,
  178. 28, 8, -28, 8, 28, -8, -28, -8,
  179. 24, 12, -24, 12, 24, -12, -24, -12,
  180. 16, 14, -16, 14, 16, -14, -16, -14
  181. };
  182. for( j = 0 ; j < sizeof(coords) / sizeof(int) ; j += 2 )
  183. {
  184. add_weapon( g, g->wp, wp->x[i] + coords[j], wp->y[i] + coords[j+1] / 2, coords[j], coords[j+1], WEAPON_SEEKER );
  185. add_weapon( g, g->wp, wp->x[i] + coords[j] / 2, wp->y[i] + coords[j+1], coords[j], coords[j+1], WEAPON_SEEKER );
  186. }
  187. wp->type[i] = WEAPON_NONE;
  188. }
  189. wp->x[i] += wp->vx[i];
  190. wp->y[i] += wp->vy[i];
  191. wp->n[i]++;
  192. if( wp->y[i] < 0 )
  193. {
  194. wp->type[i] = WEAPON_NONE;
  195. }
  196. break;
  197. case WEAPON_BEAM:
  198. wp->x[i] = (g->p->x + 2) << 4;
  199. wp->y[i] = g->p->y << 4;
  200. wp->n[i]--;
  201. if( wp->n[i] < 0 )
  202. {
  203. wp->type[i] = WEAPON_NONE;
  204. }
  205. break;
  206. case WEAPON_NUKE:
  207. wp->n[i]--;
  208. if( wp->n[i] < 0 )
  209. {
  210. wp->type[i] = WEAPON_NONE;
  211. }
  212. break;
  213. case WEAPON_LIGHTNING:
  214. case WEAPON_NONE:
  215. break;
  216. }
  217. }
  218. }
  219. void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
  220. {
  221. int i;
  222. for( i = 0; i < WEAPONS; i++ )
  223. {
  224. if( wp->type[i] == WEAPON_NONE )
  225. {
  226. wp->x[i] = x;
  227. wp->y[i] = y;
  228. wp->vx[i] = vx;
  229. wp->vy[i] = vy;
  230. wp->type[i] = type;
  231. wp->n[i] = 0;
  232. switch( type )
  233. {
  234. case WEAPON_LASER:
  235. break;
  236. case WEAPON_FRAGBOMB:
  237. break;
  238. case WEAPON_SEEKER:
  239. case WEAPON_BOMB:
  240. wp->x2[i] = x;
  241. wp->y2[i] = y;
  242. wp->x3[i] = x;
  243. wp->y3[i] = y;
  244. wp->n[i] = 20;
  245. break;
  246. case WEAPON_BEAM:
  247. wp->n[i] = 25;
  248. break;
  249. case WEAPON_NUKE:
  250. wp->n[i] = 25;
  251. break;
  252. case WEAPON_NONE:
  253. break;
  254. }
  255. break;
  256. }
  257. }
  258. }
  259. static void draw_bomb( int x, int y, int vx, int vy )
  260. {
  261. vy *= 2;
  262. gfx_color( CYAN );
  263. if( vx > vy )
  264. {
  265. if( vx > -vy ) /* right quarter */
  266. {
  267. if( vy > vx/4 )
  268. {
  269. /* -1pi/6 */
  270. gfx_goto( x-4, y-1 );
  271. gfx_putstr( "/`-." );
  272. gfx_goto( x-4, y );
  273. gfx_putstr( "`-._\\" );
  274. gfx_color( WHITE );
  275. gfx_goto( x-1, y );
  276. gfx_putstr( "_\\" );
  277. gfx_goto( x, y+1 );
  278. gfx_putchar( '`' );
  279. }
  280. else if( vy < -vx/4 )
  281. {
  282. /* 1pi/6 */
  283. gfx_goto( x-4, y );
  284. gfx_putstr( ",-' " );
  285. gfx_goto( x-4, y+1 );
  286. gfx_putstr( "\\,-'" );
  287. gfx_color( WHITE );
  288. gfx_goto( x-1, y-1 );
  289. gfx_putstr( "_," );
  290. gfx_goto( x, y );
  291. gfx_putchar( '/' );
  292. }
  293. else
  294. {
  295. /* 0pi/6 */
  296. gfx_goto( x-4, y-1 );
  297. gfx_putstr( "____" );
  298. gfx_goto( x-5, y );
  299. gfx_putstr( "|____" );
  300. gfx_color( WHITE );
  301. gfx_goto( x, y );
  302. gfx_putchar( '>' );
  303. }
  304. }
  305. else /* top quarter */
  306. {
  307. if( vx > -vy/4 )
  308. {
  309. /* 2pi/6 */
  310. gfx_goto( x-2, y );
  311. gfx_putstr( "/ " );
  312. gfx_goto( x-3, y+1 );
  313. gfx_putstr( "/ /" );
  314. gfx_goto( x-3, y+2 );
  315. gfx_putstr( "`'" );
  316. gfx_color( WHITE );
  317. gfx_goto( x-1, y-1 );
  318. gfx_putstr( "_," );
  319. gfx_goto( x, y );
  320. gfx_putchar( '|' );
  321. }
  322. else if( vx < vy/4 )
  323. {
  324. /* 4pi/6 */
  325. gfx_goto( x+1, y );
  326. gfx_putstr( " \\" );
  327. gfx_goto( x+1, y+1 );
  328. gfx_putstr( "\\ \\" );
  329. gfx_goto( x+2, y+2 );
  330. gfx_putstr( "`'" );
  331. gfx_color( WHITE );
  332. gfx_goto( x, y-1 );
  333. gfx_putstr( "._" );
  334. gfx_goto( x, y );
  335. gfx_putchar( '|' );
  336. }
  337. else
  338. {
  339. /* 3pi/6 */
  340. gfx_goto( x-1, y+1 );
  341. gfx_putstr( "| |" );
  342. gfx_goto( x-1, y+2 );
  343. gfx_putstr( "|_|" );
  344. gfx_color( WHITE );
  345. gfx_goto( x-1, y );
  346. gfx_putstr( ",^." );
  347. }
  348. }
  349. }
  350. else
  351. {
  352. if( vx > -vy ) /* bottom quarter */
  353. {
  354. if( vx > vy/4 )
  355. {
  356. /* -2pi/6 */
  357. gfx_goto( x-2, y-2 );
  358. gfx_putstr( ",." );
  359. gfx_goto( x-2, y-1 );
  360. gfx_putstr( "\\ \\" );
  361. gfx_goto( x-1, y );
  362. gfx_putchar( '\\' );
  363. gfx_color( WHITE );
  364. gfx_goto( x, y );
  365. gfx_putstr( "_|" );
  366. }
  367. else if( vx < -vy/4 )
  368. {
  369. /* -4pi/6 */
  370. gfx_goto( x+1, y-2 );
  371. gfx_putstr( ",." );
  372. gfx_goto( x, y-1 );
  373. gfx_putstr( "/ /" );
  374. gfx_goto( x+1, y );
  375. gfx_putchar( '/' );
  376. gfx_color( WHITE );
  377. gfx_goto( x-1, y );
  378. gfx_putstr( "|_/" );
  379. }
  380. else
  381. {
  382. /* -3pi/6 */
  383. gfx_goto( x, y-3 );
  384. gfx_putchar( '_' );
  385. gfx_goto( x-1, y-2 );
  386. gfx_putstr( "| |" );
  387. gfx_goto( x-1, y-1 );
  388. gfx_putstr( "| |" );
  389. gfx_color( WHITE );
  390. gfx_goto( x-1, y );
  391. gfx_putstr( "`v'" );
  392. }
  393. }
  394. else /* left quarter */
  395. {
  396. if( vy > -vx/4 )
  397. {
  398. /* -5pi/6 */
  399. gfx_goto( x+1, y-1 );
  400. gfx_putstr( ",-'\\" );
  401. gfx_goto( x+2, y );
  402. gfx_putstr( ",-'" );
  403. gfx_goto( x, y+1 );
  404. gfx_putchar( '\'' );
  405. gfx_color( WHITE );
  406. gfx_goto( x, y );
  407. gfx_putstr( "/_" );
  408. }
  409. else if( vy < vx/4 )
  410. {
  411. /* 5pi/6 */
  412. gfx_goto( x+1, y );
  413. gfx_putstr( " `-." );
  414. gfx_goto( x+1, y+1 );
  415. gfx_putstr( "`-./" );
  416. gfx_color( WHITE );
  417. gfx_goto( x, y-1 );
  418. gfx_putstr( "._" );
  419. gfx_goto( x, y );
  420. gfx_putchar( '\\' );
  421. }
  422. else
  423. {
  424. /* 6pi/6 */
  425. gfx_goto( x+1, y-1 );
  426. gfx_putstr( "____" );
  427. gfx_goto( x+1, y );
  428. gfx_putstr( "____|" );
  429. gfx_color( WHITE );
  430. gfx_goto( x, y );
  431. gfx_putchar( '<' );
  432. }
  433. }
  434. }
  435. }
  436. static void draw_fragbomb( int x, int y, int frame )
  437. {
  438. gfx_color( WHITE );
  439. gfx_color( frame & 1 ? CYAN : WHITE );
  440. gfx_goto( x-2, y );
  441. gfx_putstr( "( )" );
  442. gfx_goto( x-1, y+1 );
  443. gfx_putstr( "`--'" );
  444. gfx_color( frame & 1 ? WHITE : CYAN );
  445. gfx_goto( x-1, y-1 );
  446. gfx_putstr( ",--." );
  447. gfx_goto( x, y );
  448. gfx_putstr( "'," );
  449. switch( frame % 4 )
  450. {
  451. case 0:
  452. gfx_color( CYAN );
  453. gfx_goto( x, y + 2 );
  454. gfx_putchar( 'O' );
  455. gfx_goto( x + 2, y + 2 );
  456. gfx_putchar( 'o' );
  457. gfx_goto( x + 1, y + 3 );
  458. gfx_putchar( 'o' );
  459. gfx_color( GRAY );
  460. gfx_goto( x - 1, y + 3 );
  461. gfx_putchar( '°' );
  462. gfx_goto( x + 2, y + 4 );
  463. gfx_putchar( '°' );
  464. gfx_goto( x, y + 4 );
  465. gfx_putchar( '.' );
  466. gfx_goto( x + 1, y + 5 );
  467. gfx_putchar( '.' );
  468. break;
  469. case 1:
  470. gfx_color( CYAN );
  471. //gfx_goto( x, y + 1 );
  472. //gfx_putchar( 'O' );
  473. gfx_goto( x + 1, y + 2 );
  474. gfx_putchar( 'O' );
  475. gfx_goto( x, y + 3 );
  476. gfx_putchar( 'o' );
  477. gfx_color( GRAY );
  478. gfx_goto( x + 2, y + 3 );
  479. gfx_putchar( '°' );
  480. gfx_goto( x + 1, y + 4 );
  481. gfx_putchar( '°' );
  482. gfx_goto( x - 1, y + 4 );
  483. gfx_putchar( '.' );
  484. gfx_goto( x + 2, y + 5 );
  485. gfx_putchar( '.' );
  486. break;
  487. case 2:
  488. gfx_color( CYAN );
  489. //gfx_goto( x - 1, y + 1 );
  490. //gfx_putchar( 'O' );
  491. gfx_goto( x + 2, y + 2 );
  492. gfx_putchar( 'O' );
  493. gfx_goto( x, y + 2 );
  494. gfx_putchar( 'o' );
  495. gfx_goto( x + 1, y + 3 );
  496. gfx_putchar( 'o' );
  497. gfx_color( GRAY );
  498. gfx_goto( x, y + 4 );
  499. gfx_putchar( '°' );
  500. gfx_goto( x + 2, y + 4 );
  501. gfx_putchar( '.' );
  502. gfx_goto( x + 1, y + 5 );
  503. gfx_putchar( '.' );
  504. break;
  505. case 3:
  506. gfx_color( CYAN );
  507. //gfx_goto( x + 2, y + 1 );
  508. //gfx_putchar( 'O' );
  509. gfx_goto( x + 1, y + 2 );
  510. gfx_putchar( 'O' );
  511. gfx_goto( x - 1, y + 2 );
  512. gfx_putchar( 'o' );
  513. gfx_goto( x + 2, y + 3 );
  514. gfx_putchar( 'o' );
  515. gfx_color( GRAY );
  516. gfx_goto( x, y + 3 );
  517. gfx_putchar( '°' );
  518. gfx_goto( x + 1, y + 4 );
  519. gfx_putchar( '°' );
  520. gfx_goto( x, y + 5 );
  521. gfx_putchar( '.' );
  522. break;
  523. }
  524. }
  525. static void draw_beam( int x, int y, int frame )
  526. {
  527. int r = (29 - frame) * (29 - frame) / 8;
  528. int i;
  529. switch( frame )
  530. {
  531. case 24:
  532. gfx_color( WHITE );
  533. gfx_goto( x, y-3 );
  534. gfx_putstr( "__" );
  535. gfx_goto( x-1, y-2 );
  536. gfx_putchar( '\'' );
  537. gfx_goto( x+2, y-2 );
  538. gfx_putchar( '`' );
  539. break;
  540. case 23:
  541. gfx_color( CYAN );
  542. gfx_goto( x, y-3 );
  543. gfx_putstr( "__" );
  544. gfx_color( WHITE );
  545. gfx_goto( x-2, y-2 );
  546. gfx_putstr( "-'" );
  547. gfx_goto( x+2, y-2 );
  548. gfx_putstr( "`-" );
  549. break;
  550. case 22:
  551. gfx_color( CYAN );
  552. gfx_goto( x, y-3 );
  553. gfx_putstr( "__" );
  554. gfx_goto( x-1, y-2 );
  555. gfx_putchar( '\'' );
  556. gfx_goto( x+2, y-2 );
  557. gfx_putchar( '`' );
  558. gfx_color( WHITE );
  559. gfx_goto( x-3, y-2 );
  560. gfx_putstr( ",-" );
  561. gfx_goto( x+3, y-2 );
  562. gfx_putstr( "-." );
  563. break;
  564. case 21:
  565. gfx_color( CYAN );
  566. gfx_goto( x-1, y-3 );
  567. gfx_putstr( "____" );
  568. gfx_goto( x-2, y-2 );
  569. gfx_putchar( '\'' );
  570. gfx_goto( x+3, y-2 );
  571. gfx_putchar( '`' );
  572. gfx_color( WHITE );
  573. gfx_goto( x-4, y-2 );
  574. gfx_putstr( ",-" );
  575. gfx_goto( x+4, y-2 );
  576. gfx_putstr( "-." );
  577. break;
  578. case 20:
  579. gfx_color( WHITE );
  580. gfx_goto( x, y-3 );
  581. gfx_putstr( "%%" );
  582. gfx_goto( x-4, y-2 );
  583. gfx_putchar( ',' );
  584. gfx_goto( x+5, y-2 );
  585. gfx_putchar( '.' );
  586. gfx_color( CYAN );
  587. gfx_goto( x-1, y-3 );
  588. gfx_putchar( ':' );
  589. gfx_goto( x+2, y-3 );
  590. gfx_putchar( ':' );
  591. gfx_goto( x-3, y-2 );
  592. gfx_putstr( "-'" );
  593. gfx_goto( x+3, y-2 );
  594. gfx_putstr( "`-" );
  595. break;
  596. case 19:
  597. gfx_color( WHITE );
  598. gfx_goto( x, y-4 );
  599. gfx_putstr( "%%" );
  600. gfx_goto( x, y-3 );
  601. gfx_putstr( "##" );
  602. gfx_color( CYAN );
  603. gfx_goto( x-1, y-4 );
  604. gfx_putchar( ':' );
  605. gfx_goto( x+2, y-4 );
  606. gfx_putchar( ':' );
  607. gfx_goto( x-1, y-3 );
  608. gfx_putchar( '%' );
  609. gfx_goto( x+2, y-3 );
  610. gfx_putchar( '%' );
  611. gfx_goto( x-4, y-2 );
  612. gfx_putstr( ",-'" );
  613. gfx_goto( x+3, y-2 );
  614. gfx_putstr( "`-." );
  615. gfx_color( BLUE );
  616. gfx_goto( x-2, y-3 );
  617. gfx_putchar( ':' );
  618. gfx_goto( x+3, y-3 );
  619. gfx_putchar( ':' );
  620. break;
  621. case 18:
  622. default:
  623. r = (18 - frame) * (18 - frame);
  624. gfx_color( WHITE );
  625. gfx_goto( x-1, y-5-r );
  626. gfx_putstr( ":%%:" );
  627. gfx_goto( x-1, y-4-r );
  628. gfx_putstr( "%##%" );
  629. gfx_color( CYAN );
  630. gfx_goto( x-2, y-4-r );
  631. gfx_putchar( ':' );
  632. gfx_goto( x+3, y-4-r );
  633. gfx_putchar( ':' );
  634. gfx_goto( x-2, y-2 );
  635. gfx_putchar( '\'' );
  636. gfx_goto( x+3, y-2 );
  637. gfx_putchar( '`' );
  638. gfx_color( BLUE );
  639. gfx_goto( x-3, y-2 );
  640. gfx_putchar( ':' );
  641. gfx_goto( x+4, y-2 );
  642. gfx_putchar( ':' );
  643. for( i = 0; i <= r; i++ )
  644. {
  645. gfx_color( WHITE );
  646. gfx_goto( x-1, y-3-i );
  647. gfx_putstr( (i+frame) % 5 ? "####" : "%%%%" );
  648. gfx_color( CYAN );
  649. gfx_goto( x-2, y-3-i );
  650. gfx_putchar( '%' );
  651. gfx_goto( x+3, y-3-i );
  652. gfx_putchar( '%' );
  653. gfx_color( BLUE );
  654. gfx_goto( x-3, y-3-i );
  655. gfx_putchar( ':' );
  656. gfx_goto( x+4, y-3-i );
  657. gfx_putchar( ':' );
  658. }
  659. break;
  660. }
  661. }
  662. static void draw_nuke( int x, int y, int frame )
  663. {
  664. int r = (29 - frame) * (29 - frame) / 8;
  665. /* Lots of duplicate pixels, but we don't care */
  666. gfx_color( BLUE );
  667. draw_circle( x, y, r++, ':' );
  668. gfx_color( CYAN );
  669. draw_circle( x, y, r++, '%' );
  670. gfx_color( WHITE );
  671. draw_circle( x, y, r++, '#' );
  672. draw_circle( x, y, r++, '#' );
  673. }
  674. static void draw_circle( int x, int y, int r, char c )
  675. {
  676. int test, dx, dy;
  677. /* Optimized Bresenham. Kick ass. */
  678. for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
  679. {
  680. gfx_putcharTO( x + dx, y + dy / 2, c );
  681. gfx_putcharTO( x - dx, y + dy / 2, c );
  682. gfx_putcharTO( x + dx, y - dy / 2, c );
  683. gfx_putcharTO( x - dx, y - dy / 2, c );
  684. gfx_putcharTO( x + dy, y + dx / 2, c );
  685. gfx_putcharTO( x - dy, y + dx / 2, c );
  686. gfx_putcharTO( x + dy, y - dx / 2, c );
  687. gfx_putcharTO( x - dy, y - dx / 2, c );
  688. test += test > 0 ? dx - dy-- : dx;
  689. }
  690. }