Guest User

asteroids clone

a guest
Aug 15th, 2010
520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.81 KB | None | 0 0
  1. /* See LICENSE file for copyright and license details. */
  2.  
  3. #include <math.h>
  4. #include <stdbool.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include <assert.h>
  8. #include <stdarg.h>
  9.  
  10. #include "SDL/SDL.h"
  11. #include "SDL/SDL_opengl.h"
  12. #include "SDL/SDL_mixer.h"
  13. #include "SDL/SDL_ttf.h"
  14. #include "ubiqx/ubi_dLinkList.h"
  15.  
  16. //#include "mcheck.h"
  17.  
  18.  
  19. /*
  20. (!)gprof asteroids -b | vim -
  21. (!)astyle asteroids.c -SUT8b
  22. (!)ctags asteroids.c
  23. (!)make && gdb -q asteroids.c -ex r -ex q
  24.  
  25. gcc
  26. -Wall -Wextra --pedantic //all warnings, etc
  27. asteroids.c -o asteroids
  28. -lGL -lSDL -lSDL_mixer -lSDL_ttf -lGLU
  29. -lm -lc //link math and c libs
  30. -lubiqx //abstract primitives lib(for OBJ_LIST)
  31. -std=c99
  32. -g //for gdb
  33. -pg //for gprof
  34.  
  35. ---TODO---
  36. *HIGH priority:
  37. -rules for getting EXP from destroyed targets (calculate target hit score)
  38. -split events() func
  39. -levels
  40. -rewrite kill_old_objects() func
  41. -mcheck
  42. -create player in safe pos
  43. -rewrite ext rendering
  44. -time + pause + missiles + particles
  45. *MEDIUM priority:
  46. -reloading progressbar
  47. -suckless.org-like makefile
  48. -replace astyle with gnu indent
  49. -licence
  50. -limit player speed, not just slowdown
  51. *LOW priority:
  52. -gettext lib support
  53. *later:
  54. -split OBJ_LIST to few lists for optimization of nested loops
  55. *already done:
  56. -for(OBJ_LIST) -> while(i)
  57. -'define TYPE_### #' -> 'enum(TYPE_###, ...)'
  58. -int x, int y -> vec2i pos
  59. -add targets & Dlazer
  60. -vsnprintf() for buttons text
  61. */
  62.  
  63. #define uint unsigned int
  64. #define lint long int
  65. #define ulint unsigned long int
  66. #define M_PI 3.14159265358979323846
  67.  
  68.  
  69. enum
  70. {
  71. TYPE_PLAYER,
  72. TYPE_ROCK,
  73. TYPE_MISSILE,
  74. TYPE_PARTICLE,
  75. TYPE_STAR,
  76. TYPE_TARGET,
  77. TYPE_EXPLOSION,
  78. TYPE_CIRCLE,
  79. };
  80.  
  81.  
  82.  
  83. //2d float vector(point)
  84.  
  85. typedef struct vec2f vec2f;
  86. struct vec2f
  87. {
  88. float x, y;
  89. };
  90.  
  91.  
  92.  
  93. //2d integer vector(point)
  94.  
  95. typedef struct vec2i vec2i;
  96. struct vec2i
  97. {
  98. int x, y;
  99. };
  100.  
  101.  
  102.  
  103. typedef struct obj obj;
  104. struct obj
  105. {
  106. ubi_dlNode node; //see 'ubi_dlList OBJ_LIST'
  107.  
  108. vec2f pos; //position
  109. vec2f vel; //velocity
  110. float a; //angle
  111. float va; //rotation speed
  112. float size; //
  113. Uint32 creation_time; //
  114. int type; //see #define TYPE_######
  115. bool del; //see delete_marked_objects()
  116. };
  117.  
  118.  
  119.  
  120. typedef struct gui_button gui_button;
  121. struct gui_button
  122. {
  123. ubi_dlNode node;
  124.  
  125. char* name; //button's idintifier
  126. char* text; //displayed info
  127. vec2i pos; //position
  128. vec2i size; //size
  129. vec2i tex_size; //texture's size
  130. uint tex_id; //texture's ID.
  131. };
  132.  
  133.  
  134. /* forward declarations */
  135. int rnd(int min, int max);
  136. float rndf(float min, float max);
  137. float deg2rad(float degrees);
  138. //float rad2deg(float radians);
  139. float get_dist(vec2f p1, vec2f p2);
  140. bool intersect_circle_line(vec2f c, float rad, vec2f p1, vec2f p2);
  141.  
  142. void init_sdl();
  143. void init_opengl();
  144. void init_sound();
  145. void init_interface();
  146. void init_all();
  147. void cleanup();
  148.  
  149. obj* add_player();
  150. obj* add_target();
  151. obj* add_rock();
  152. obj* add_star();
  153. obj* add_circle(vec2f pos);
  154. obj* add_explosion(vec2f pos, float power);
  155. obj* add_particle(vec2f pos);
  156. obj* add_missile();
  157.  
  158. void kill_player(obj *o);
  159. void kill_target(obj *o);
  160. void kill_rock(obj *o);
  161. void kill_star(obj *o);
  162. void kill_circle(obj *o);
  163. void kill_explosion(obj *o);
  164. void kill_particle(obj *o);
  165. void kill_missle(obj *o);
  166.  
  167. void draw_player(obj *o);
  168. void draw_target(obj *o);
  169. void draw_rock(obj *o);
  170. void draw_star(obj *o);
  171. void draw_circle(obj *o);
  172. void draw_explosion(obj *o);
  173. void draw_particle(obj *o);
  174. void draw_missle(obj *o);
  175.  
  176. void draw_gui();
  177. void draw_obj(obj *o);
  178. void draw_playe2targets_lines();
  179. void draw_death_rays();
  180.  
  181. void events();
  182. void logic();
  183. void draw();
  184.  
  185. bool can_player_shoot();
  186. void accelerate_player();
  187. void player_rocks_collisions();
  188.  
  189. void move_objects();
  190. void teleport_objects();
  191. void missles_rocks_collisions();
  192. void kill_old_objects();
  193. void change_targets_speed_and_direction();
  194. void do_objects_tails();
  195. void stretch_circles();
  196.  
  197. void delete_marked_objects();
  198.  
  199. void particle_explosion(vec2f pos, vec2f vel, int power);
  200.  
  201. int str2tex(char* text, vec2i *tex_size);
  202. void change_button_text(char* name, char* format, ...);
  203. bool add_button(int x, int y, int w, int h, char* name, char *text);
  204.  
  205.  
  206. /* global variables */
  207. ubi_dlList OBJ_LIST[1] = {{ NULL, NULL, 0 }};
  208. ubi_dlList GUI_LIST[1] = {{ NULL, NULL, 0 }};
  209.  
  210. obj* PLAYER = NULL;
  211. float PLAYER_ACCELERATION = 0;
  212. float PLAYER_SIZE = 6;
  213.  
  214. int PARTICLE_COUNT = 0;
  215. int MAX_PARTICLE_COUNT = 1000;
  216. Uint32 PARTICLE_LIVETIME = 800;
  217.  
  218. int ROCKS_COUNT = 0;
  219. int MAX_ROCK_COUNT = 9;
  220. int MIN_ROCK_SPLIT_SIZE = 6;
  221. float MIN_ROCK_SPEED = 1;
  222. float MAX_ROCK_SPEED = 3;
  223. float MIN_ROCK_SIZE = 20;
  224. float MAX_ROCK_SIZE = 30;
  225.  
  226. int MAX_TARGET_COUNT = 5;
  227. int TARGETS_COUNT = 0;
  228. float MIN_TARGET_SIZE = 6;
  229. float MAX_TARGET_SIZE = 9;
  230. float DLAZER_DIST = 350; //death lazer distance
  231.  
  232. Uint32 RELOAD_TIME = 1500;
  233. Uint32 LAST_SHOOT_TIME = 0;
  234. bool IS_PLAYER_SHOOTING = false;
  235.  
  236. Uint32 MISSILE_LIVETIME = 1500;
  237. float MISSILE_SPEED = 8;
  238. float MISSLE_SIZE = 2;
  239. float MAX_MISSLE_SPREAD = 3;
  240.  
  241. Uint32 CIRCLE_LIVETIME = 400;
  242.  
  243. Uint32 EXPLOSION_LIVETIME = 400;
  244.  
  245. Mix_Chunk* SND_BAM = NULL;
  246. Mix_Chunk* SND_MISSLE = NULL;
  247. Mix_Chunk* SND_MOVING = NULL;
  248. int motor_channel = -1;
  249.  
  250. bool IS_PROG_RUNNING = true;
  251. bool PAUSE = false;
  252. int FUEL = 0;
  253. int AMMO = 0;
  254. int EXP = 0;
  255. int LIVES = 3;
  256. int LEVEL = 1;
  257. float FPS = 60;
  258.  
  259. vec2i SCR = {500, 500};
  260. vec2i WORLD = {1000, 1000};
  261.  
  262. TTF_Font* FONT = NULL;
  263.  
  264. float LINE_WIDTH = 1.5;
  265.  
  266.  
  267.  
  268. int
  269. rnd(int min, int max)
  270. {
  271. assert(min <= max);
  272. return (rand()%(max-min+1)+min);
  273. }
  274.  
  275.  
  276.  
  277. float
  278. rndf(float min, float max)
  279. {
  280. assert(min <= max);
  281. return ((max-min)*((float)rand()/RAND_MAX))+min;
  282. }
  283.  
  284.  
  285.  
  286. float
  287. deg2rad(float degrees)
  288. {
  289. return(degrees*(M_PI/180.));
  290. }
  291.  
  292.  
  293.  
  294. #if(0)
  295. float
  296. rad2deg(float radians)
  297. {
  298. return(radians*(180./M_PI));
  299. }
  300. #endif
  301.  
  302.  
  303.  
  304. void
  305. init_sdl()
  306. {
  307. SDL_Init(SDL_INIT_EVERYTHING);
  308. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  309. SDL_SetVideoMode(SCR.x, SCR.y, 32, SDL_OPENGL);
  310. }
  311.  
  312.  
  313.  
  314. void
  315. init_opengl()
  316. {
  317. glViewport(0, 0, SCR.x, SCR.y);
  318.  
  319. glMatrixMode(GL_PROJECTION);
  320. glLoadIdentity();
  321. int w = WORLD.x/2, h = WORLD.y/2;
  322. gluOrtho2D(-w, w, -h, h);
  323.  
  324. glMatrixMode(GL_MODELVIEW);
  325. glLoadIdentity();
  326.  
  327. glClearColor(0, 0, 0, 1);
  328. glLineWidth(LINE_WIDTH);
  329.  
  330. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  331. glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  332. glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
  333. glEnable(GL_LINE_SMOOTH);
  334. glEnable(GL_POINT_SMOOTH);
  335. glEnable(GL_BLEND);
  336. }
  337.  
  338.  
  339.  
  340. obj*
  341. add_explosion(vec2f p, float power)
  342. {
  343. obj *t = calloc(sizeof(obj), 1);
  344.  
  345. t->pos.x = p.x;
  346. t->pos.y = p.y;
  347.  
  348. t->size = rndf(power*30, power*35);
  349. t->type = TYPE_EXPLOSION;
  350.  
  351. t->creation_time = SDL_GetTicks();
  352.  
  353. ubi_dlAddTail(OBJ_LIST, t);
  354.  
  355. return(t);
  356. }
  357.  
  358.  
  359.  
  360. obj*
  361. add_circle(vec2f p)
  362. {
  363. obj *t = calloc(sizeof(obj), 1);
  364.  
  365. t->pos.x = p.x;
  366. t->pos.y = p.y;
  367.  
  368. t->size = 5;
  369. t->type = TYPE_CIRCLE;
  370.  
  371. t->creation_time = SDL_GetTicks();
  372.  
  373. ubi_dlAddTail(OBJ_LIST, t);
  374.  
  375. return(t);
  376. }
  377.  
  378.  
  379.  
  380.  
  381.  
  382. obj*
  383. add_target()
  384. {
  385. obj *t = calloc(sizeof(obj), 1);
  386.  
  387. t->pos.x = rnd(-(WORLD.x/2), (WORLD.x/2));
  388. t->pos.y = rnd(-(WORLD.y/2), (WORLD.y/2));
  389.  
  390. t->size = rndf(MIN_TARGET_SIZE, MAX_TARGET_SIZE);
  391. t->type = TYPE_TARGET;
  392.  
  393. ubi_dlAddTail(OBJ_LIST, t);
  394.  
  395. TARGETS_COUNT++;
  396.  
  397. add_circle(t->pos);
  398.  
  399. return(t);
  400. }
  401.  
  402.  
  403.  
  404. obj*
  405. add_rock()
  406. {
  407. obj *r = calloc(sizeof(obj), 1);
  408.  
  409. r->pos.x = rnd(-(WORLD.x/2), (WORLD.x/2));
  410. r->pos.y = rnd(-(WORLD.y/2), (WORLD.y/2));
  411.  
  412. r->a = rnd(0, 360);
  413. float speed = rndf(MIN_ROCK_SPEED, MAX_ROCK_SPEED);
  414. r->vel.x = cosf(deg2rad(r->a))*speed;
  415. r->vel.y = sinf(deg2rad(r->a))*speed;
  416.  
  417. r->va = rnd(-10, 10);
  418. r->size = rnd(MIN_ROCK_SIZE, MAX_ROCK_SIZE);
  419. r->type = TYPE_ROCK;
  420.  
  421. ROCKS_COUNT++;
  422.  
  423. ubi_dlAddTail(OBJ_LIST, r);
  424.  
  425. return(r);
  426. }
  427.  
  428.  
  429.  
  430. obj*
  431. add_star()
  432. {
  433. obj *s = calloc(sizeof(obj), 1);
  434. s->pos.x = rnd(-WORLD.x/2, WORLD.x/2);
  435. s->pos.y = rnd(-WORLD.y/2, WORLD.y/2);
  436. s->size = rndf(0.5, 3);
  437. s->type = TYPE_STAR;
  438.  
  439. ubi_dlAddTail(OBJ_LIST, s);
  440.  
  441. return(s);
  442. }
  443.  
  444.  
  445.  
  446. obj*
  447. add_particle(vec2f pos)
  448. {
  449. obj *p = calloc(sizeof(obj), 1);
  450. p->pos.x = pos.x;
  451. p->pos.y = pos.y;
  452. p->a = rnd(0, 360);
  453. float speed = rndf(1, 5);
  454. p->vel.x = cosf(deg2rad(p->a))*speed;
  455. p->vel.y = sinf(deg2rad(p->a))*speed;
  456. p->size = rndf(0.2, 1.0);
  457. p->type = TYPE_PARTICLE;
  458.  
  459. ubi_dlAddTail(OBJ_LIST, p);
  460.  
  461. p->creation_time = SDL_GetTicks();
  462.  
  463. PARTICLE_COUNT++;
  464.  
  465. return(p);
  466. }
  467.  
  468.  
  469.  
  470. obj*
  471. add_missile()
  472. {
  473. obj *b = calloc(sizeof(obj), 1);
  474. float spread = MAX_MISSLE_SPREAD;
  475. float a = PLAYER->a + rnd(-spread,spread);
  476.  
  477. b->pos = PLAYER->pos;
  478. b->vel.x = PLAYER->vel.x + (cosf(deg2rad(a)) * MISSILE_SPEED);
  479. b->vel.y = PLAYER->vel.y + (sinf(deg2rad(a)) * MISSILE_SPEED);
  480. b->a = a;
  481. b->type = TYPE_MISSILE;
  482. b->size = MISSLE_SIZE;
  483.  
  484. ubi_dlAddTail(OBJ_LIST, b);
  485.  
  486. b->creation_time = SDL_GetTicks();
  487.  
  488. return(b);
  489. }
  490.  
  491.  
  492.  
  493. obj*
  494. add_player()
  495. {
  496. PLAYER = calloc(sizeof(obj), 1);
  497. PLAYER->size = PLAYER_SIZE;
  498. PLAYER->type = TYPE_PLAYER;
  499. PLAYER->pos.x = rndf(-WORLD.x/2, WORLD.x/2);
  500. PLAYER->pos.y = rndf(-WORLD.y/2, WORLD.y/2);
  501. PLAYER->a = rnd(0, 360);
  502. ubi_dlAddTail(OBJ_LIST, PLAYER);
  503.  
  504. LAST_SHOOT_TIME = SDL_GetTicks()-RELOAD_TIME;
  505.  
  506. FUEL = 1500;
  507. AMMO = 20;
  508. PLAYER_ACCELERATION = 0;
  509. IS_PLAYER_SHOOTING = false;
  510. LIVES --;
  511.  
  512. change_button_text("fuel", "fuel: %i", FUEL);
  513. change_button_text("ammo", "ammo: %i", AMMO);
  514. change_button_text("live", "lives: %i", LIVES);
  515.  
  516. add_circle(PLAYER->pos);
  517.  
  518. return(PLAYER);
  519. }
  520.  
  521.  
  522.  
  523. void
  524. kill_player(obj *o)
  525. {
  526. particle_explosion(PLAYER->pos, PLAYER->vel, 35);
  527. add_explosion(o->pos, 33);
  528. PLAYER = NULL;
  529. change_button_text("live", "lives: %i", LIVES);
  530. Mix_PlayChannel(-1, SND_BAM, 0);
  531. }
  532.  
  533.  
  534.  
  535. void
  536. kill_target(obj *o)
  537. {
  538. #if(1)//TODO
  539. EXP += 30;
  540. #else
  541. float x = (float)(o->creation_time - SDL_GetTicks())/1000;
  542. EXP += 30;
  543. #endif
  544. TARGETS_COUNT--;
  545. change_button_text("exp", "exp: %i", EXP);
  546.  
  547. //50, 200, 450, 800, 1250, 1800, 2450, 3200, 4050
  548. if ((EXP >= pow(LEVEL, 2)*50))
  549. {
  550. LEVEL++;
  551. change_button_text("level", "level: %i", LEVEL);
  552. //TODO change some parameters to make game harder
  553. }
  554.  
  555. add_explosion(o->pos, 15);
  556. particle_explosion(o->pos, o->vel, 60);
  557.  
  558. Mix_PlayChannel(-1, SND_BAM, 0);
  559. }
  560.  
  561.  
  562.  
  563. void
  564. kill_rock(obj *o)
  565. {
  566. ROCKS_COUNT--;
  567.  
  568. if (o->size > MIN_ROCK_SPLIT_SIZE)
  569. {
  570. int x = rnd(1, 3);
  571. while (x--)
  572. {
  573. obj *r = add_rock();
  574. r->pos.x = o->pos.x;
  575. r->pos.y = o->pos.y;
  576. r->size = o->size/rndf(1.3, 2);
  577. }
  578. }
  579.  
  580. particle_explosion(o->pos, o->vel, o->size*3);
  581.  
  582. add_explosion(o->pos, o->size/2);
  583. Mix_PlayChannel(-1, SND_BAM, 0);
  584. }
  585.  
  586.  
  587.  
  588. void
  589. kill_star(obj *o)
  590. {
  591. assert(o != NULL);
  592. }
  593.  
  594.  
  595.  
  596. void
  597. kill_circle(obj *o)
  598. {
  599. assert(o != NULL);
  600. }
  601.  
  602.  
  603.  
  604. void
  605. kill_explosion(obj *o)
  606. {
  607. assert(o != NULL);
  608. }
  609.  
  610.  
  611.  
  612. void
  613. kill_particle(obj *o)
  614. {
  615. assert(o != NULL);
  616. PARTICLE_COUNT--;
  617. }
  618.  
  619.  
  620.  
  621. void
  622. kill_missle(obj *o)
  623. {
  624. assert(o != NULL);
  625. }
  626.  
  627.  
  628.  
  629. void
  630. draw_player(obj *o)
  631. {
  632. assert(o != NULL);
  633.  
  634. glColor3f(1, 1, 1);
  635. glBegin(GL_LINES);
  636. {
  637. glVertex2d(-1, -1);
  638. glVertex2d(+1, 0);
  639. glVertex2d(-1, +1);
  640. glVertex2d(+1, 0);
  641. }
  642. glEnd();
  643. }
  644.  
  645.  
  646.  
  647. void
  648. draw_target(obj *o)
  649. {
  650. assert(o != NULL);
  651.  
  652. glColor3f(1, 0, 0);
  653. //glColor3f(1, 1, 1);
  654. glBegin(GL_LINE_STRIP);
  655. float a;
  656. for (a=0; a<=360; a+=120)
  657. {
  658. float x,y;
  659. x = sinf(deg2rad(a));
  660. y = cosf(deg2rad(a));
  661. glVertex2d(x, y);
  662. }
  663. glVertex2d(0, 0);
  664. glEnd();
  665. }
  666.  
  667.  
  668.  
  669. void
  670. draw_rock(obj *o)
  671. {
  672. assert(o != NULL);
  673.  
  674. glColor3f(1, 1, 1);
  675. glBegin(GL_LINE_STRIP);
  676. float i;
  677. for (i=0; i<=360; i+=60)
  678. {
  679. float x,y;
  680. x = sinf(deg2rad(i));
  681. y = cosf(deg2rad(i));
  682. glVertex2d(x, y);
  683. }
  684. //glVertex2d(0, 0);
  685. glEnd();
  686. }
  687.  
  688.  
  689.  
  690. void
  691. draw_star(obj *o)
  692. {
  693. assert(o != NULL);
  694.  
  695. glColor4f(1, 1, 1, rndf(0, 0.5));
  696. //glColor4f(rndf(0,1), rndf(0,1), rndf(0,1), rndf(0,1));
  697. glBegin(GL_LINES);
  698. glVertex2d(0, 0);
  699. glVertex2d(+0.5, 0);
  700. glEnd();
  701. }
  702.  
  703.  
  704.  
  705. void
  706. draw_circle(obj *o)
  707. {
  708. assert(o != NULL);
  709.  
  710. glBegin(GL_LINE_STRIP);
  711. float time = SDL_GetTicks() - o->creation_time;
  712. float t = 1. - time/CIRCLE_LIVETIME;
  713. glColor4f(1, 1, 1, t);
  714. //glColor4f(1, 1, 1, 0.3);
  715.  
  716. float i;
  717. for (i=0; i<=360; i+=10)
  718. {
  719. float x,y;
  720. x = sinf(deg2rad(i));
  721. y = cosf(deg2rad(i));
  722. glVertex2d(x, y);
  723. }
  724. glEnd();
  725. }
  726.  
  727.  
  728.  
  729. void
  730. draw_explosion(obj *o)
  731. {
  732. assert(o != NULL);
  733.  
  734. glBegin(GL_POLYGON);
  735. float time = SDL_GetTicks() - o->creation_time+150;
  736. float t = 1. - time/EXPLOSION_LIVETIME;
  737. glColor4f(1, 1, 1, t);
  738. glVertex2d(0, 0);
  739.  
  740. glColor4f(1, 1, 1, 0.02);
  741. float i;
  742. for (i=0; i<=360; i+=30)
  743. {
  744. float x,y;
  745. x = sinf(deg2rad(i));
  746. y = cosf(deg2rad(i));
  747. glVertex2d(x, y);
  748. }
  749. glEnd();
  750. }
  751.  
  752.  
  753.  
  754. void
  755. draw_particle(obj *o)
  756. {
  757. assert(o != NULL);
  758.  
  759. float time = SDL_GetTicks() - o->creation_time;
  760. float t = 1. - time/PARTICLE_LIVETIME;
  761. glColor4f(1, 1, 1, t);
  762. //glColor4f(rndf(0,1), rndf(0,1), rndf(0,1), rndf(0.5,1)*t);
  763.  
  764. glBegin(GL_LINES);
  765. glVertex2d(-1, 0);
  766. glVertex2d(+1, 0);
  767. glEnd();
  768. }
  769.  
  770.  
  771.  
  772. void
  773. draw_missle(obj *o)
  774. {
  775. assert(o != NULL);
  776.  
  777. glColor3f(1, 1, 1);
  778. glBegin(GL_LINES);
  779. glVertex2d(-1, 0);
  780. glVertex2d(+1, 0);
  781. glEnd();
  782. }
  783.  
  784.  
  785.  
  786. void
  787. draw_button(gui_button *b)
  788. {
  789. glPushMatrix();
  790.  
  791. glTranslatef(-WORLD.x/2+10, WORLD.y/2-30-10, 0);
  792. glTranslatef(b->pos.x, b->pos.y, 0);
  793.  
  794. glBindTexture(GL_TEXTURE_2D, b->tex_id);
  795.  
  796. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  797. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  798.  
  799. glBegin(GL_QUADS);
  800. {
  801. glTexCoord2d(0, 0);
  802. glVertex2d(0, b->tex_size.y);
  803. glTexCoord2d(1, 0);
  804. glVertex2d(b->tex_size.x, b->tex_size.y);
  805. glTexCoord2d(1, 1);
  806. glVertex2d(b->tex_size.x, 0);
  807. glTexCoord2d(0, 1);
  808. glVertex2d(0, 0);
  809. }
  810. glEnd();
  811.  
  812. glPopMatrix();
  813. }
  814.  
  815.  
  816.  
  817. void
  818. draw_gui()
  819. {
  820. glLoadIdentity();
  821. glColor4f(1, 1, 1, 0.4);
  822. glEnable(GL_TEXTURE_2D);
  823.  
  824. gui_button *i = (gui_button*)ubi_dlFirst(GUI_LIST);
  825. while (i)
  826. {
  827. draw_button(i);
  828. i = (gui_button*)ubi_dlNext(i);
  829. }
  830.  
  831. glDisable(GL_TEXTURE_2D);
  832. }
  833.  
  834.  
  835.  
  836. void
  837. draw_obj(obj *o)
  838. {
  839. glPushMatrix();
  840. glTranslatef(o->pos.x, o->pos.y, 0);
  841. glColor3f(1, 1, 1);
  842.  
  843. #if(0) //draw velocity vectors
  844. if (PAUSE && o->type != TYPE_PARTICLE)
  845. {
  846. glColor4f(1, 0, 0, 0.7);
  847. glBegin(GL_LINES);
  848. glVertex2d(0, 0);
  849. glVertex2d(o->vel.x*15, o->vel.y*15);
  850. glEnd();
  851. }
  852. #endif
  853.  
  854. glRotatef(o->a, 0, 0, 1);
  855. glScalef(o->size, o->size, 0);
  856.  
  857. if (o->type == TYPE_PLAYER) draw_player(o);
  858. if (o->type == TYPE_TARGET) draw_target(o);
  859. if (o->type == TYPE_EXPLOSION) draw_explosion(o);
  860. if (o->type == TYPE_CIRCLE) draw_circle(o);
  861. if (o->type == TYPE_ROCK) draw_rock(o);
  862. if (o->type == TYPE_MISSILE) draw_missle(o);
  863. if (o->type == TYPE_STAR) draw_star(o);
  864. if (o->type == TYPE_PARTICLE) draw_particle(o);
  865.  
  866. glPopMatrix();
  867. }
  868.  
  869.  
  870. void
  871. draw_playe2targets_lines()
  872. {
  873. glLineWidth(0.3);
  874. glColor4f(1, 1, 1, 0.4);
  875.  
  876. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  877. while (i)
  878. {
  879. if (PLAYER && i->type == TYPE_TARGET)
  880. {
  881. glBegin(GL_LINES);
  882. glVertex2d(PLAYER->pos.x, PLAYER->pos.y);
  883. glVertex2d(i->pos.x, i->pos.y);
  884. glEnd();
  885. }
  886.  
  887. i = (obj*)ubi_dlNext(i);
  888. }
  889. glLineWidth(LINE_WIDTH);
  890. }
  891.  
  892.  
  893.  
  894. void
  895. draw_death_rays()
  896. {
  897. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  898. while (i)
  899. {
  900. if (i->type == TYPE_TARGET)
  901. {
  902. obj *j = (obj*)ubi_dlFirst(OBJ_LIST);
  903. while (j)
  904. {
  905. if (j->type == TYPE_TARGET &&
  906. get_dist(i->pos, j->pos) < DLAZER_DIST)
  907. {
  908. glColor4f(1, 0, 0, rndf(0, 1));
  909. glLineWidth(rndf(0, 3));
  910. glBegin(GL_LINES);
  911. glVertex2f(i->pos.x, i->pos.y);
  912. glVertex2f(j->pos.x, j->pos.y);
  913. glEnd();
  914. glLineWidth(LINE_WIDTH);
  915. }
  916.  
  917. j = (obj*)ubi_dlNext(j);
  918. }
  919. }
  920.  
  921. i = (obj*)ubi_dlNext(i);
  922. }
  923. }
  924.  
  925.  
  926.  
  927. void
  928. draw()
  929. {
  930. glClear(GL_COLOR_BUFFER_BIT);
  931. glLoadIdentity();
  932.  
  933. draw_gui();
  934. draw_death_rays();
  935. draw_playe2targets_lines();
  936.  
  937. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  938. while (i)
  939. {
  940. draw_obj(i);
  941. i = (obj*)ubi_dlNext(i);
  942. }
  943.  
  944. SDL_GL_SwapBuffers();
  945. }
  946.  
  947.  
  948.  
  949. bool
  950. can_player_shoot()
  951. {
  952. Uint32 time = LAST_SHOOT_TIME+RELOAD_TIME;
  953. return(AMMO > 0 && SDL_GetTicks() > time);
  954. }
  955.  
  956.  
  957.  
  958. void
  959. events()
  960. {
  961. SDL_Event E;
  962. while (SDL_PollEvent(&E))
  963. {
  964. if (E.type == SDL_QUIT)
  965. {
  966. IS_PROG_RUNNING = false;
  967. }
  968.  
  969. //general keys(works if player is dead or alive)
  970. if (E.type == SDL_KEYUP)
  971. {
  972. switch (E.key.keysym.sym)
  973. {
  974. case SDLK_ESCAPE:
  975. case SDLK_q:
  976. IS_PROG_RUNNING = false;
  977. break;
  978. case SDLK_p:
  979. PAUSE = !PAUSE;
  980. break;
  981. case SDLK_o:
  982. if (MAX_PARTICLE_COUNT)
  983. {
  984. MAX_PARTICLE_COUNT = 0;
  985. }
  986. else
  987. {
  988. MAX_PARTICLE_COUNT = 1200;
  989. }
  990. break;
  991. case SDLK_0:
  992. FPS += 2;
  993. change_button_text("fps", "fps: %i", FPS);
  994. break;
  995. case SDLK_9:
  996. FPS -= 2;
  997. change_button_text("fps", "fps: %i", FPS);
  998. break;
  999. default:
  1000. break;
  1001. }
  1002. }
  1003.  
  1004. if (!PLAYER)
  1005. {
  1006. if (E.type == SDL_KEYUP)
  1007. {
  1008. switch (E.key.keysym.sym)
  1009. {
  1010. case SDLK_RETURN:
  1011. add_player();
  1012. if (LIVES == 0)
  1013. {
  1014. FUEL = 0;
  1015. AMMO = 0;
  1016. EXP = 0;
  1017. LIVES = 3;
  1018. LEVEL = 1;
  1019. change_button_text("fuel", "fuel: %i", FUEL);
  1020. change_button_text("ammo", "ammo: %i", AMMO);
  1021. change_button_text("exp", "exp: %i", EXP);
  1022. change_button_text("live", "lives: %i", LIVES);
  1023. change_button_text("level", "level: %i", LEVEL);
  1024. }
  1025. break;
  1026. default:
  1027. break;
  1028. }
  1029. }
  1030. }
  1031.  
  1032. if (PLAYER)
  1033. {
  1034. if (E.type == SDL_KEYDOWN)
  1035. {
  1036. switch (E.key.keysym.sym)
  1037. {
  1038. case SDLK_LEFT:
  1039. PLAYER->va += 3;
  1040. break;
  1041. case SDLK_RIGHT:
  1042. PLAYER->va -= 3;
  1043. break;
  1044. case SDLK_SPACE:
  1045. IS_PLAYER_SHOOTING = true;
  1046. break;
  1047. case SDLK_UP:
  1048. PLAYER_ACCELERATION += 0.08;
  1049. if (motor_channel < 0)
  1050. {
  1051. motor_channel = Mix_PlayChannel(-1, SND_MOVING, -1);
  1052. }
  1053. break;
  1054. default:
  1055. break;
  1056. }
  1057. }
  1058.  
  1059. if (E.type == SDL_KEYUP)
  1060. {
  1061. switch (E.key.keysym.sym)
  1062. {
  1063. case SDLK_RIGHT:
  1064. PLAYER->va += 3;
  1065. break;
  1066. case SDLK_LEFT:
  1067. PLAYER->va -= 3;
  1068. break;
  1069. case SDLK_DOWN:
  1070. break;
  1071. case SDLK_UP:
  1072. PLAYER_ACCELERATION = 0;
  1073. Mix_HaltChannel(motor_channel);
  1074. motor_channel = -1;
  1075. break;
  1076. case SDLK_SPACE:
  1077. IS_PLAYER_SHOOTING = false;
  1078. break;
  1079. case SDLK_RETURN:
  1080. FUEL += 500;
  1081. AMMO += 20;
  1082. default:
  1083. break;
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089.  
  1090.  
  1091.  
  1092. void
  1093. accelerate_player()
  1094. {
  1095. //float oldx = PLAYER->vx, oldy = PLAYER->vy;
  1096.  
  1097. if (FUEL > 0 && (PLAYER_ACCELERATION || PLAYER->va))
  1098. {
  1099. FUEL--;
  1100. change_button_text("fuel", "fuel: %i", FUEL);
  1101. }
  1102. else
  1103. {
  1104. PLAYER_ACCELERATION = 0;
  1105. PLAYER->va = 0;
  1106. }
  1107.  
  1108. float acc_coeff = abs(PLAYER->va)*0.015 + PLAYER_ACCELERATION;
  1109. PLAYER->vel.x += cosf(deg2rad(PLAYER->a)) * acc_coeff;
  1110. PLAYER->vel.y += sinf(deg2rad(PLAYER->a)) * acc_coeff;
  1111.  
  1112. #if(0) //limit PLAYER speed //TODO
  1113. float limit = 4;
  1114. if (sqrt(pow(PLAYER->vx,2) + pow(PLAYER->vy,2)) > limit)
  1115. {
  1116. PLAYER->vx = oldx;
  1117. PLAYER->vy = oldy;
  1118. }
  1119. #endif
  1120.  
  1121. #if(1) //slowdown
  1122. PLAYER->vel.x *= 0.995;
  1123. PLAYER->vel.y *= 0.995;
  1124. #endif
  1125.  
  1126. }
  1127.  
  1128.  
  1129.  
  1130. void
  1131. move_objects()
  1132. {
  1133. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1134. while (i)
  1135. {
  1136. i->a += i->va;
  1137. i->pos.x += i->vel.x;
  1138. i->pos.y += i->vel.y;
  1139.  
  1140. i = (obj*)ubi_dlNext(i);
  1141. }
  1142. }
  1143.  
  1144.  
  1145.  
  1146. void
  1147. teleport_objects()
  1148. {
  1149. float w2 = WORLD.x / 2.;
  1150. float h2 = WORLD.y / 2.;
  1151.  
  1152. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1153. while (i)
  1154. {
  1155. if (i->pos.x > +w2) i->pos.x = -w2;
  1156. if (i->pos.x < -w2) i->pos.x = +w2;
  1157. if (i->pos.y > +h2) i->pos.y = -h2;
  1158. if (i->pos.y < -h2) i->pos.y = +h2;
  1159.  
  1160. i = (obj*)ubi_dlNext(i);
  1161. }
  1162. }
  1163.  
  1164.  
  1165.  
  1166. float
  1167. get_dist(vec2f p1, vec2f p2)
  1168. {
  1169. float dx = p1.x - p2.x;
  1170. float dy = p1.y - p2.y;
  1171.  
  1172. float dist = sqrt(pow(dx, 2) + pow(dy, 2));
  1173.  
  1174. return(dist);
  1175. }
  1176.  
  1177.  
  1178.  
  1179. void
  1180. player_rocks_collisions()
  1181. {
  1182. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1183. while (i)
  1184. {
  1185. float size = i->size + PLAYER->size;
  1186. if ((i->type == TYPE_ROCK || i->type == TYPE_TARGET)
  1187. && get_dist(i->pos, PLAYER->pos) < size)
  1188. {
  1189. //i->del = true;
  1190. PLAYER->del = true;
  1191. return;
  1192. }
  1193.  
  1194. i = (obj*)ubi_dlNext(i);
  1195. }
  1196. }
  1197.  
  1198.  
  1199.  
  1200. void
  1201. missles_rocks_collisions()
  1202. {
  1203. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);;
  1204. while (i)
  1205. {
  1206. if (i->type == TYPE_MISSILE && !(i->del))
  1207. {
  1208. obj *j = (obj*)ubi_dlFirst(OBJ_LIST);;
  1209. while (j)
  1210. {
  1211. float size = j->size + i->size;
  1212.  
  1213. if ((j->type == TYPE_TARGET || j->type == TYPE_ROCK)
  1214. && !(j->del)
  1215. && get_dist(i->pos, j->pos) < size)
  1216. {
  1217. i->del = true;
  1218. j->del = true;
  1219. }
  1220.  
  1221. j = (obj*)ubi_dlNext(j);
  1222. }
  1223. }
  1224.  
  1225. i = (obj*)ubi_dlNext(i);
  1226. }
  1227. }
  1228.  
  1229.  
  1230.  
  1231. void
  1232. kill_old_objects() //TODO
  1233. {
  1234. Uint32 time = SDL_GetTicks();
  1235. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1236. while (i)
  1237. {
  1238. if (i->type == TYPE_MISSILE && time > (i->creation_time + MISSILE_LIVETIME))
  1239. i->del = true;
  1240. if (i->type == TYPE_PARTICLE && time > (i->creation_time + PARTICLE_LIVETIME))
  1241. i->del = true;
  1242. if (i->type == TYPE_EXPLOSION && time > (i->creation_time + EXPLOSION_LIVETIME))
  1243. i->del = true;
  1244.  
  1245. i = (obj*)ubi_dlNext(i);
  1246. }
  1247. }
  1248.  
  1249.  
  1250.  
  1251. void
  1252. particle_explosion(vec2f pos, vec2f vel, int power)
  1253. {
  1254. while (power--)
  1255. {
  1256. if (PARTICLE_COUNT < MAX_PARTICLE_COUNT)
  1257. {
  1258. obj *p = add_particle(pos);
  1259. p->vel.x += vel.x;
  1260. p->vel.y += vel.y;
  1261. }
  1262. }
  1263. }
  1264.  
  1265.  
  1266.  
  1267. void
  1268. player_shoot()
  1269. {
  1270. if (IS_PLAYER_SHOOTING && can_player_shoot())
  1271. {
  1272. add_missile();
  1273. Mix_PlayChannel(-1, SND_MISSLE, 0);
  1274. LAST_SHOOT_TIME = SDL_GetTicks();
  1275.  
  1276. AMMO--;
  1277. change_button_text("ammo", "ammo:%i", AMMO);
  1278.  
  1279. #if(0)
  1280. {
  1281. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);;
  1282.  
  1283. while (i)
  1284. {
  1285. if (i->type == TYPE_TARGET)
  1286. {
  1287. float a = rnd(0, 360);
  1288. float speed = rndf(1, 3);
  1289. i->vel.x = cosf(deg2rad(a))*speed;
  1290. i->vel.y = sinf(deg2rad(a))*speed;
  1291. i->va = rnd(-9, 9);
  1292. }
  1293. i = (obj*)ubi_dlNext(i);
  1294. }
  1295. }
  1296. #endif
  1297. }
  1298. }
  1299.  
  1300.  
  1301.  
  1302. // if obj->del == true then delete obj from OBJ_LIST and free it
  1303. // called by 'logic()'
  1304.  
  1305. void
  1306. delete_marked_objects()
  1307. {
  1308. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1309. while (i)
  1310. {
  1311. obj *next = (obj*)ubi_dlNext(i);
  1312. if (i->del)
  1313. {
  1314. if (i->type == TYPE_ROCK) kill_rock(i);
  1315. if (i->type == TYPE_PARTICLE) kill_particle(i);
  1316. if (i->type == TYPE_TARGET) kill_target(i);
  1317. if (i->type == TYPE_PLAYER) kill_player(i);
  1318.  
  1319. free(ubi_dlRemove(OBJ_LIST, (ubi_dlNodePtr)i));
  1320. }
  1321. i = next;
  1322. }
  1323. }
  1324.  
  1325.  
  1326.  
  1327. void
  1328. change_targets_speed_and_direction()
  1329. {
  1330. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);;
  1331.  
  1332. while (i)
  1333. {
  1334. if (i->type == TYPE_TARGET && !rnd(0, 250))
  1335. {
  1336. float a = rnd(0, 360);
  1337. float speed = rndf(1, 3); // diffuculty level
  1338. i->vel.x = cosf(deg2rad(a))*speed;
  1339. i->vel.y = sinf(deg2rad(a))*speed;
  1340. i->va = rnd(-9, 9);
  1341. }
  1342. i = (obj*)ubi_dlNext(i);
  1343. }
  1344. }
  1345.  
  1346.  
  1347.  
  1348.  
  1349. void
  1350. do_objects_tails()
  1351. {
  1352. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);;
  1353. while (i)
  1354. {
  1355. if (i->type == TYPE_MISSILE && rnd(0,1))
  1356. {
  1357. if (PARTICLE_COUNT < MAX_PARTICLE_COUNT)
  1358. {
  1359. obj *p = add_particle(i->pos);
  1360. float a = rnd(-5,5) + i->a + 180;
  1361. p->vel.x = cosf(deg2rad(a)) * rndf(2,4);
  1362. p->vel.y = sinf(deg2rad(a)) * rndf(2,4);
  1363. p->a = a;
  1364. }
  1365. }
  1366. i = (obj*)ubi_dlNext(i);
  1367. }
  1368.  
  1369. if (PLAYER && (PLAYER_ACCELERATION > 0.02 || PLAYER->va))
  1370. {
  1371. if (PARTICLE_COUNT < MAX_PARTICLE_COUNT)
  1372. {
  1373. obj *p = add_particle(PLAYER->pos);
  1374. float a = PLAYER->a + 180. + rnd(-15,15);
  1375. float speed = rndf(2,6);
  1376. p->vel.x = cosf(deg2rad(a))*speed;
  1377. p->vel.y = sinf(deg2rad(a))*speed;
  1378. p->a = a;
  1379. }
  1380. }
  1381. }
  1382.  
  1383.  
  1384.  
  1385.  
  1386. bool
  1387. intersect_circle_line(vec2f cpos, float crad, vec2f p1, vec2f p2)
  1388. {
  1389. float x1 = p1.x - cpos.x;
  1390. float y1 = p1.y - cpos.y;
  1391. float x2 = p2.x - cpos.x;
  1392. float y2 = p2.y - cpos.y;
  1393.  
  1394. float dx = x2-x1;
  1395. float dy = y2-y1;
  1396.  
  1397. float a = dx*dx + dy*dy;
  1398. float b = 2. * (x1*dx + y1*dy);
  1399. float c = x1*x1 + y1*y1 - crad*crad;
  1400.  
  1401. if (-b < 0) return (c < 0);
  1402. if (-b < (2.*a)) return (4.*a*c-b*b < 0);
  1403. return (a+b+c < 0);
  1404. }
  1405.  
  1406.  
  1407.  
  1408. void
  1409. stretch_circles()
  1410. {
  1411. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1412. while (i)
  1413. {
  1414. if (i->type == TYPE_CIRCLE)
  1415. {
  1416. i->size *= 1.28;
  1417. i->size += 0.3;
  1418. if (i->size > 800)
  1419. {
  1420. i->del = true;
  1421. }
  1422. }
  1423. i = (obj*)ubi_dlNext(i);
  1424. }
  1425. }
  1426.  
  1427.  
  1428. void
  1429. death_rays_logic()
  1430. {
  1431. obj *i = (obj*)ubi_dlFirst(OBJ_LIST);
  1432. while (i)
  1433. {
  1434. if (i->type == TYPE_TARGET)
  1435. {
  1436. obj *j = (obj*)ubi_dlFirst(OBJ_LIST);
  1437. while (j)
  1438. {
  1439. if (j->type == TYPE_TARGET
  1440. && get_dist(i->pos, j->pos) < DLAZER_DIST
  1441. && intersect_circle_line(PLAYER->pos, PLAYER->size, i->pos, j->pos))
  1442. {
  1443. PLAYER->del = true;
  1444. }
  1445.  
  1446. j = (obj*)ubi_dlNext(j);
  1447. }
  1448. }
  1449. i = (obj*)ubi_dlNext(i);
  1450. }
  1451. }
  1452.  
  1453.  
  1454.  
  1455. void
  1456. logic()
  1457. {
  1458. if (PAUSE) return;
  1459.  
  1460. if (PLAYER)
  1461. {
  1462. accelerate_player();
  1463. player_rocks_collisions();
  1464. death_rays_logic();
  1465. player_shoot();
  1466. }
  1467.  
  1468. change_targets_speed_and_direction();
  1469. move_objects();
  1470. teleport_objects();
  1471. do_objects_tails();
  1472. missles_rocks_collisions();
  1473. kill_old_objects();
  1474. stretch_circles();
  1475.  
  1476. if (ROCKS_COUNT < MAX_ROCK_COUNT && !rnd(0, 200))
  1477. {
  1478. add_rock();
  1479. }
  1480. if (TARGETS_COUNT < MAX_TARGET_COUNT && !rnd(0, 100))
  1481. {
  1482. add_target();
  1483. }
  1484.  
  1485. delete_marked_objects();
  1486. }
  1487.  
  1488.  
  1489.  
  1490. void
  1491. init_sound()
  1492. {
  1493. int rate = 44100;
  1494. Uint16 format = MIX_DEFAULT_FORMAT;
  1495. int channels = 1;
  1496. int buffers = 1024;
  1497.  
  1498. if (Mix_OpenAudio(rate, format, channels, buffers))
  1499. {
  1500. printf("Unable to open audio!\n");
  1501. exit(EXIT_FAILURE);
  1502. }
  1503.  
  1504. SND_MISSLE = Mix_LoadWAV("lounch_rocket.ogg");
  1505. SND_BAM = Mix_LoadWAV("bam.ogg");
  1506. SND_MOVING = Mix_LoadWAV("motor.ogg");
  1507. }
  1508.  
  1509.  
  1510.  
  1511. //generates opengl texture from 'char *text'
  1512. //returns texture ID (see glGenTextures)
  1513. //returns texture width and heigh
  1514.  
  1515. int
  1516. str2tex(char *text, vec2i *tex_size)
  1517. {
  1518. SDL_Color color = {255, 255, 255, 0};
  1519. SDL_Surface *txt = TTF_RenderUTF8_Blended(FONT, text, color);
  1520. uint id = 0;
  1521.  
  1522. glGenTextures(1, &id);
  1523. glBindTexture(GL_TEXTURE_2D, id);
  1524.  
  1525. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, txt->w, txt->h,
  1526. 0, GL_BGRA, GL_UNSIGNED_BYTE, txt->pixels);
  1527. tex_size->x = txt->w;
  1528. tex_size->y = txt->h;
  1529. SDL_FreeSurface(txt);
  1530.  
  1531. return((int)id);
  1532. }
  1533.  
  1534.  
  1535.  
  1536. void
  1537. change_button_text(char* name, char* format, ...)
  1538. {
  1539. gui_button *i = (gui_button*)ubi_dlFirst(GUI_LIST);
  1540. char str[80];
  1541. va_list ptr;
  1542.  
  1543. va_start(ptr, format);
  1544.  
  1545. while (i)
  1546. {
  1547. if (!strcmp(i->name, name))
  1548. {
  1549. glDeleteTextures(1, &(i->tex_id));
  1550. vsnprintf(str, 80, format, ptr);
  1551. i->tex_id = str2tex(str, &(i->tex_size));
  1552. va_end(ptr);
  1553. return;
  1554. }
  1555. i = (gui_button*)ubi_dlNext(i);
  1556. }
  1557. }
  1558.  
  1559.  
  1560.  
  1561. bool
  1562. add_button(int x, int y, int w, int h, char* name, char *text)
  1563. {
  1564. vec2i tex_size;
  1565. int tex_id = str2tex(text, &(tex_size));
  1566.  
  1567. gui_button *b = calloc(sizeof(gui_button), 1);
  1568.  
  1569. b->name = name;
  1570. //b->pos = pos;
  1571. //b->size = size;
  1572. b->pos.x = x;
  1573. b->pos.y = y;
  1574. b->size.x = w;
  1575. b->size.y = h;
  1576. b->tex_size = tex_size;
  1577. b->tex_id = tex_id;
  1578. b->text = text;
  1579.  
  1580. ubi_dlAddTail(GUI_LIST, b);
  1581.  
  1582. return(true);
  1583. }
  1584.  
  1585.  
  1586.  
  1587. void
  1588. free_lists()
  1589. {
  1590. while (ubi_dlCount(OBJ_LIST))
  1591. {
  1592. free(ubi_dlRemHead(OBJ_LIST));
  1593. }
  1594.  
  1595. while (ubi_dlCount(GUI_LIST))
  1596. {
  1597. free(ubi_dlRemHead(GUI_LIST));
  1598. }
  1599. }
  1600.  
  1601.  
  1602.  
  1603. void
  1604. init_interface()
  1605. {
  1606. if (TTF_Init())
  1607. {
  1608. printf("TTF_Init: %s\n", TTF_GetError());
  1609. exit(EXIT_FAILURE);
  1610. }
  1611.  
  1612. FONT = TTF_OpenFont("font.ttf", 22);
  1613. if (!FONT)
  1614. {
  1615. puts("can not open font!!!");
  1616. exit(EXIT_FAILURE);
  1617. }
  1618.  
  1619. add_button(0, 0, 200, 40, "fuel", "fuel: 0");
  1620. add_button(0, -30, 200, 40, "ammo", "ammo: 0");
  1621. add_button(0, -60, 200, 40, "exp", "exp: 0");
  1622. add_button(0, -90, 200, 40, "live", "lives: 0");
  1623. add_button(0, -120, 200, 40, "fps", "time: -");
  1624. add_button(0, -150, 200, 40, "level","level: 0");
  1625. change_button_text("live", "lives: %i", LIVES);
  1626. change_button_text("fps", "fps: %i", FPS);
  1627. }
  1628.  
  1629.  
  1630.  
  1631. void
  1632. add_stars()
  1633. {
  1634. int x = 80;
  1635. while (x--)
  1636. {
  1637. add_star();
  1638. }
  1639. }
  1640.  
  1641.  
  1642.  
  1643. void
  1644. process_args(int argc, char *argv[])
  1645. {
  1646. if (argc > 1 || !argv[0])
  1647. {
  1648. exit(EXIT_FAILURE);
  1649. }
  1650. }
  1651.  
  1652.  
  1653.  
  1654. void
  1655. init_all(int argc, char *argv[])
  1656. {
  1657. //mtrace();
  1658. process_args(argc, argv);
  1659. srand(time(NULL));
  1660.  
  1661. init_sdl();
  1662. init_opengl();
  1663. init_sound();
  1664. init_interface();
  1665.  
  1666. add_stars();
  1667. }
  1668.  
  1669.  
  1670.  
  1671. void
  1672. cleanup()
  1673. {
  1674. free_lists();
  1675. SDL_Quit();
  1676. Mix_FreeChunk(SND_MOVING);
  1677. Mix_FreeChunk(SND_BAM);
  1678. Mix_FreeChunk(SND_MISSLE);
  1679. Mix_CloseAudio();
  1680. //muntrace();
  1681. }
  1682.  
  1683.  
  1684.  
  1685. int
  1686. main(int argc, char *argv[])
  1687. {
  1688. Uint32 t;
  1689.  
  1690. init_all(argc, argv);
  1691.  
  1692. t = SDL_GetTicks() + 100;
  1693. while (IS_PROG_RUNNING)
  1694. {
  1695. events();
  1696. draw();
  1697. logic();
  1698.  
  1699. if (SDL_GetTicks() < t)
  1700. {
  1701. SDL_Delay(t - SDL_GetTicks());
  1702. }
  1703. t = SDL_GetTicks() + 1000./FPS;
  1704. }
  1705.  
  1706. cleanup();
  1707.  
  1708. return(EXIT_SUCCESS);
  1709. }
Advertisement
Add Comment
Please, Sign In to add comment