Advertisement
Guest User

Untitled

a guest
May 24th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 51.40 KB | None | 0 0
  1. //#include "GL/glew.h"
  2. #include "SDL/SDL.h"
  3. #include "SDL/SDL_ttf.h"
  4. #include "SDL/SDL_opengl.h"
  5. #include <math.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <stdbool.h>
  10. #include <time.h>
  11.  
  12.  
  13. // astyle -SUET81
  14. // LINUX.Makefile: "gcc main.c -Wall -g -o hex -lGL -lGLU -lSDL"
  15.  
  16. /* WIN.bat
  17. PATH = ..\..\b\MinGW\bin
  18. gcc.exe main.c -pg -o hex.exe -lmingw32 -lglew32 -lSDLmain \
  19.     -lSDL -lSDL_image -lSDL_ttf -lopengl32 -lglu32
  20. hex.exe
  21. */
  22.  
  23. //TODO LIST
  24. /*
  25. -реализовать диалоги.
  26. -подсвечивать путь, по которому пойдет юнит при наведении на клетку.
  27. -массив персонажей -> динамический список. а то сложно удалять. хз !!!
  28. -скелетная анимация
  29. -загрузка статических мешей(и покадровой анимации) в vertex arrays
  30. -освещение
  31. -нормальные тени
  32. -базовый гуй.
  33. -ландшафт. маска высоты.
  34. -УПОРЯДОЧИТЬ ЭТОТ БРЕД
  35. -искуственный интеллект. хоть какойнибудь.
  36. -возможность привязывать кнопки\лейблы к разным краям экрана
  37. */
  38.  
  39. #define ushort  unsigned short int
  40. #define uint    unsigned int
  41.  
  42. #define AFTERSCAN_PRINT 0
  43. #define RESIZE      1 //remove later
  44. #define resize_coefficient (0.10) //remove later
  45.  
  46. #define V_COUNT  500
  47. #define VT_COUNT 500
  48. #define VN_COUNT 500
  49. #define F_COUNT  500
  50.  
  51. #define attack_cost 2 //TODO. надо что б считалась была вбита в юнит.
  52. //возможно вытаскивалась из типа атаки, если у юнита несколько атак.
  53.  
  54.  
  55.  
  56. // STRUCTURES
  57.  
  58. typedef struct Q {
  59.     long int tail;
  60.     long int head;
  61.     ushort *qx;
  62.     ushort *qy;
  63.     long int qu_size;
  64. } Q;
  65.  
  66.  
  67.  
  68. typedef struct vector {
  69.     float x, y, z;
  70. } vector;
  71.  
  72.  
  73.  
  74. typedef struct texture_coords {
  75.     float u, v;
  76. } texture_coords;
  77.  
  78.  
  79.  
  80. typedef struct indexes {
  81.     int v1, v2, v3;
  82.     int vt1, vt2, vt3;
  83.     int vn1, vn2, vn3;
  84. } indexes;
  85.  
  86.  
  87. //TODO ПЕРЕДЕЛАТЬ НАХЕР К ОДНОМУ МАССИВУ!!!
  88. typedef struct model {
  89.     vector      vertexes[V_COUNT];
  90.     vector      normals[VN_COUNT];
  91.     texture_coords  text_coords[VT_COUNT];
  92.     indexes     faces[F_COUNT];
  93.    
  94.     int f_count; //количество фэйсов
  95. } model;
  96.  
  97.  
  98.  
  99. //хранит свойства юнитов. потом сделать.
  100. typedef struct u_prop { //unit properties
  101.     char *name;
  102.     int value;
  103. } u_prop;
  104.  
  105.  
  106.  
  107. typedef struct unit unit;
  108. struct unit {
  109.     u_prop  properties[10]; // свойства персонажа. TODO
  110.     int mx, my; // grid position
  111.     float   x, y; // real position
  112.     int health; //TODO
  113.     int cost_attack;
  114.     int attack_distance;
  115.     int player;
  116.     float   rot;
  117.     int frame;
  118.     //bool  can_atack;
  119.     //bool  can_move;
  120.     ushort  ap; //acton points
  121.     float   movement_speed; // скорость перемещения
  122.     float   rotation_speed; // скорость поворота
  123.  
  124.     unit* next;
  125. };
  126.  
  127.  
  128. typedef struct cell {
  129.     uint    init_cost;
  130.     uint    move_cost;
  131.     ushort  parent_x, parent_y; //используется в путенахождении
  132.     //TODO тут еще можно зафигначить всякие дополнительные параметры, типа
  133.     //"есть ли у юнита на этйо клетке поддержка"
  134.     // или туман войны
  135.    
  136.     //мысль. можно ввести уровни тумана войны. вполне можно =)
  137.     //character *ch;
  138.     unit*   unit;
  139. } cell;
  140.  
  141.  
  142.  
  143. typedef struct gui_button {
  144.     char *name; //логическое имя кнопки(напр. "идентификатор игрока")
  145.     int x, y; //position
  146.     int sx, sy; //size
  147.     int textSX, textSY; //ширина и высота текстуры. пиксили.
  148.     unsigned textureID; //индекс текстуры кнопки
  149.     char *text; //отображаемый текст кнопки
  150.     //colorFG
  151.     //colorBG
  152. } gui_button;
  153. //~STRUCTURES
  154.  
  155. /*  GLOBAL VARIABLES */
  156.  
  157. GLUquadricObj *GQO; //тестовый объект
  158.  
  159. #define MODE_SELECT 1
  160. #define MODE_MOVE   2
  161. #define MODE_FIGHT  3
  162. #define MODE_PAUSE  5
  163. int MODE = MODE_SELECT;
  164. int PREVIOUS_MODE;
  165.  
  166. typedef struct fight fight;
  167. struct fight{
  168.     unit* u1;
  169.     unit* u2;
  170. };
  171. fight FIGHT = {NULL, NULL};
  172.  
  173. int PLAYER = 1; //TODO игроков то может быть и больше двух. подумать. потом.
  174.  
  175. int cursorX, cursorY; //координаты курсора
  176. int aX = 99,  aY = 99; //active cell
  177. unit* SELECTED_UNIT = NULL;
  178.  
  179. typedef struct camera {
  180.     float   x, y;
  181.     float   horiz_angle;
  182.     float   vert_angle;
  183.     float   distanse;
  184.     bool    is_rotating;
  185. } camera;
  186. camera CAMERA = {0, 0, 0, 60, 6, false};
  187.  
  188. //инфа о сторонах шестигранника. TODO посчитать и захардкодить. )
  189. float HEX_EX;
  190. float HEX_IN;
  191. float HEX[6*3]; //хранит координаты вершин шестригранника
  192.  
  193.  
  194. //размеры поля TODO ошибка если не квадратное.
  195. //проверить на неквадратном и исправить ошибки
  196. #define MAP_SIZE_X (10)
  197. #define MAP_SIZE_Y (10)
  198.  
  199.  
  200. int PICKED_SMTH;
  201. bool isProgramLooping = true;
  202. SDL_Surface *surface;
  203. int video_flags; /* Flags to pass to SDL_SetVideoMode */
  204.  
  205. int SCR_WIDTH = 800;
  206. int SCR_HEIGHT = 600;
  207. int SCR_BPP = 32;
  208.  
  209. TTF_Font* font;
  210.  
  211. cell MAP[MAP_SIZE_X][MAP_SIZE_Y]; //собсственно это и есть карта =)
  212.  
  213.  
  214. model mdl[130]; //массив анимаций. пока что только одна модель.
  215. GLuint texture; //ID текстуры персонажа
  216.  
  217. GLuint sky_texture[6]; //ID текстур неба.
  218.  
  219. //нужен для нахождения пути. завернуто в структуру
  220. typedef struct move {
  221.     int mx1, my1, mx2, my2;
  222.     float   rx1, ry1, rx2, ry2;
  223.     float   speed;
  224.     float   step_x; //за кадр по оси Х
  225.     float   step_y; //за кадр по оси Y
  226.     int step_count; //сколко кадров осталось до конца движения
  227.     unit*   unit;
  228. } move;
  229. move MOVE;
  230.  
  231.  
  232. unit* UNITS; // список с юнитами
  233.  
  234. int BUTTONS_COUNT = 0; //число задействованных кнопок
  235. int SELECTED_BUTTON; //индекс выбранной кнопки
  236. gui_button BUTTONS[100]; //массив кнопок
  237.  
  238. Q q; // очередь. нужна для нахождения пути
  239.  
  240.  
  241. ushort back_path_x[100];
  242. ushort back_path_y[100];
  243. ushort back_path_current = 0;
  244.  
  245. //======================================================
  246.  
  247. /*
  248. void list_remove(node **p) // remove head
  249. {
  250.     if (p != NULL && *p != NULL)
  251.     {
  252.         node *n = *p;
  253.         *p = (*p)->next;
  254.         free(n);
  255.     }
  256. }
  257. */ //TODO при смерти юнита
  258.  
  259.  
  260. int
  261. get_distance(int x1, int y1, int x2, int y2)
  262. {
  263.     x1 += y1/2;
  264.     x2 += y2/2;
  265.    
  266.     int dx = x2 - x1;
  267.     int dy = y2 - y1;
  268.    
  269.     return((abs(dx) + abs(dy) + abs(dx-dy)) / 2);
  270. }
  271.  
  272.  
  273.  
  274. bool
  275. get_close_hex_pos(int x, int y, int id, int *dest_x, int *dest_y)
  276. {
  277.     int dx, dy;
  278.     switch (id) {
  279.         case 0:
  280.             dx = x+1;
  281.             dy = y;
  282.             break;
  283.         case 1:
  284.             dx = x-1;
  285.             dy = y;
  286.             break;
  287.         case 2:
  288.             dx = x+1;
  289.             dy = y;
  290.             break;
  291.         case 3:
  292.             dx = x;
  293.             dy = y+1;
  294.             break;
  295.         case 4:
  296.             if (y%2==0) {
  297.                 dx = x+1;
  298.                 dy = y-1;
  299.             } else {
  300.                 dx = x-1;
  301.                 dy = y-1;
  302.             }
  303.             break;
  304.         case 5:
  305.             if (y%2==0) {
  306.                 dx = x+1;
  307.                 dy = y+1;
  308.             } else {
  309.                 dx = x-1;
  310.                 dy = y+1;
  311.             }
  312.             break;
  313.     }
  314.    
  315.     if ((dx < MAP_SIZE_X) && (dy < MAP_SIZE_Y) && (dx >= 0 && dy >= 0)) {
  316.         *dest_x = dx;
  317.         *dest_y = dy;
  318.         return(true);
  319.     }
  320.    
  321.     return(false);
  322. }
  323.  
  324.  
  325.  
  326. // преобразовывает координаты сетки в реальные
  327. void
  328. map_to_real(int mx, int my, float *rx, float *ry)
  329. {
  330.     *rx = (2 * HEX_IN * mx);
  331.     if (my%2 != 0)
  332.         *rx -= HEX_IN;
  333.     *ry = 1.5 * HEX_EX * (float)my;
  334. }
  335.  
  336.  
  337.  
  338. void
  339. generate_hex()
  340. {
  341.     HEX_EX = 0.42;
  342.     //HEX_EX = 1;
  343.     HEX_IN = sqrt(HEX_EX*HEX_EX - (HEX_EX/2)*(HEX_EX/2));
  344.    
  345.     int i;
  346.     //for(i = 5; i >= 0; i--)
  347.     for (i=0; i<6; i++) {
  348.         HEX[i*3]   = HEX_EX * cos((M_PI_2) + 2*M_PI * i/6);  //x
  349.         HEX[i*3+1] = HEX_EX * sin((M_PI_2) + 2*M_PI * i/6);  //y
  350.         HEX[i*3+2] = 0; //пропустить Z элемент
  351.     }
  352. }
  353.  
  354.  
  355.  
  356. bool
  357. is_lines_cross(float x1, float y1, float x2, float y2,
  358.            float x3, float y3, float x4, float y4)
  359. {
  360.     float ua = ((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))
  361.            /((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1));
  362.     float ub = ((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3))
  363.            /((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1));
  364. //  printf("ua:%f, ub:%f\n", ua, ub);
  365.  
  366. //TODO как то странно он иногда подсвечивает граничные хексы
  367. //  if(0<ua && ua<1 && 0<ub && ub <1){     //НЕ учитывать общие вершины
  368.     if (0<=ua && ua<=1 && 0<=ub && ub <=1) { //   учитывать общие вершины
  369.         //printf("point is (%.2f, %.2f)\n", x1+ua*(x2-x1), y1+ua*(y2-y1));
  370.         return(true);
  371.     } else {
  372.         //puts("no point");
  373.         return(false);
  374.     }
  375. }
  376.  
  377.  
  378.  
  379. bool
  380. check_line_hex_intersects(
  381.     int bx, int by, // begin
  382.     int ex, int ey, // end
  383.     int cx, int cy  // check it
  384. )
  385. {
  386.     float rbx, rby; // begin
  387.     float rex, rey; // end
  388.     float rcx, rcy; // check it
  389.     bool intersects = false;
  390.    
  391.     int i;
  392.     for (i = 0; i < 3; i++) {
  393.         map_to_real(cx, cy, &rcx, &rcy);
  394.        
  395.         float x1 = rcx + HEX_EX * cos((M_PI_2) + 2*M_PI * i/6);
  396.         float y1 = rcy + HEX_EX * sin((M_PI_2) + 2*M_PI * i/6);
  397.         float x2 = rcx + HEX_EX * cos((M_PI_2) + 2*M_PI * (i+3)/6);
  398.         float y2 = rcy + HEX_EX * sin((M_PI_2) + 2*M_PI * (i+3)/6);
  399.        
  400.         map_to_real(bx, by, &rbx, &rby);
  401.         map_to_real(ex, ey, &rex, &rey);
  402.        
  403.         if (is_lines_cross(x1,y1,x2,y2,   rbx,rby,rex,rey)) {
  404.             intersects = true;
  405.         }
  406.     }
  407.    
  408.     return(intersects);
  409. }
  410.  
  411.  
  412.  
  413. void
  414. translate(ushort y, ushort x)
  415. {
  416.     float ry, rx;
  417.     map_to_real(x, y, &rx, &ry);
  418.    
  419.     glTranslatef(rx, ry, 0);
  420. }
  421.  
  422.  
  423. float
  424. get_rot_angle(int x1, int y1, int x2, int y2)
  425. {
  426.     float rx1, ry1, rx2, ry2;
  427.     map_to_real(x1, y1, &rx1, &ry1);
  428.     map_to_real(x2, y2, &rx2, &ry2);
  429.    
  430.     float distance = sqrt(pow(ry2-ry1, 2) + pow(rx2-rx1, 2));
  431.     float angle = (asin((rx2-rx1)/distance))/ M_PI * 180.0;
  432.    
  433.     if (ry2-ry1 > 0)
  434.         angle = -(180+angle);
  435.        
  436.     return(angle);
  437. }
  438.  
  439.  
  440.  
  441. //TODO встроить в movelogic
  442. void
  443. start_move(int x1, int y1, int x2, int y2)
  444. {
  445.     map_to_real(x1, y1, &MOVE.rx1, &MOVE.ry1);
  446.     map_to_real(x2, y2, &MOVE.rx2, &MOVE.ry2);
  447.    
  448.     float speed = SELECTED_UNIT->movement_speed;
  449.     float distance = sqrt(pow(MOVE.ry2-MOVE.ry1, 2) + pow(MOVE.rx2-MOVE.rx1, 2));
  450.    
  451.     MOVE.step_x = speed * ((MOVE.rx2-MOVE.rx1)/distance);
  452.     MOVE.step_y = speed * ((MOVE.ry2-MOVE.ry1)/distance);
  453.     MOVE.step_count = (int)(distance/speed);
  454.    
  455.     //MOVE.angle = (asin((MOVE.rx2-MOVE.rx1)/distance))/M_PI*180.0;
  456.     //if (MOVE.step_y > 0)
  457.     //  MOVE.angle = -(180+MOVE.angle);
  458. }
  459.  
  460.  
  461.  
  462. void
  463. push(Q *q, ushort x, ushort y, ushort px, ushort py, uint NEW)
  464. {
  465.     MAP[x][y].move_cost = NEW;
  466.     MAP[x][y].parent_x = px;
  467.     MAP[x][y].parent_y = py;
  468.    
  469.     if (q->tail == q->qu_size) {
  470.         q->tail = 0;
  471.     }
  472.     q->qx[q->tail] = x;
  473.     q->qy[q->tail] = y;
  474.     (q->tail)++;
  475. }
  476.  
  477.  
  478.  
  479. void
  480. try_push(Q *q, ushort x, ushort y, ushort px, ushort py)
  481. {
  482.     if ((x < MAP_SIZE_X) && (y < MAP_SIZE_Y)) { //(x >= 0 && y >= 0) but ushort
  483.         if (!MAP[x][y].unit) { //что бы не проходить через другх
  484.             uint NEW = MAP[px][py].move_cost + MAP[x][y].init_cost;
  485.             if ((MAP[x][y].move_cost > NEW)) //if(OLD > NEW)
  486.                 push(q, x, y, px, py, NEW);
  487.         }
  488.     }
  489. }
  490.  
  491.  
  492.  
  493. bool
  494. pop(Q *q, ushort *x, ushort *y)
  495. {
  496.     if (q->head == q->tail) {
  497.         return(false);  // Q is empty
  498.     }
  499.    
  500.     *x = q->qx[q->head];
  501.     *y = q->qy[q->head];
  502.     (q->head)++;
  503.     if (q->head == q->qu_size)
  504.         q->head = 0;
  505.        
  506.     return(true);
  507. }
  508.  
  509.  
  510.  
  511. bool
  512. init_q(Q *q, long int size)
  513. {
  514.     q->qx = (malloc(size * sizeof(ushort)));
  515.     q->qy = (malloc(size * sizeof(ushort)));
  516.    
  517.     if (q->qx == NULL || q->qy == NULL)
  518.         return(false);
  519.        
  520.     q->tail = 0;
  521.     q->head = 0;
  522.     q->qu_size = size;
  523.    
  524.     return(true);
  525. }
  526.  
  527.  
  528.  
  529. GLuint
  530. load_texture(/*int texnum, */char *name)
  531. {
  532.     SDL_Surface *tmp_surface;
  533. //  GLenum textureFormat;
  534.     GLuint textureID;
  535.    
  536.     //tmp_surface = IMG_Load(name);
  537.     tmp_surface = SDL_LoadBMP(name);
  538.    
  539. #if(0) //TODO: repair SDL_image loading
  540.     if (tmp_surface->format->BytesPerPixel == 4) {
  541.         if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  542.             textureFormat = GL_BGRA;
  543.         else
  544.             textureFormat = GL_RGBA;
  545.     } else {
  546.         if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  547.             textureFormat = GL_BGR;
  548.         else
  549.             textureFormat = GL_RGB;
  550.     }
  551. #endif
  552.    
  553.     /* Genarate texture */
  554.     glGenTextures(1, &textureID);
  555.     glBindTexture(GL_TEXTURE_2D, textureID);
  556.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  557.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  558.     glTexImage2D(GL_TEXTURE_2D, 0, tmp_surface->format->BytesPerPixel,
  559.              //tmp_surface->w, tmp_surface->h, 0, textureFormat, //TODO
  560.              tmp_surface->w, tmp_surface->h, 0, GL_BGR, // => SDL_LoadBMP
  561.              GL_UNSIGNED_BYTE, tmp_surface->pixels);
  562.                  
  563.     SDL_FreeSurface(tmp_surface);
  564.    
  565.     return(textureID);
  566. }
  567.  
  568.  
  569.  
  570. model
  571. read_obj_file(char* filename)
  572. {
  573.     model mdl;
  574.     char buffer[100];
  575.     FILE *obj_file = NULL;
  576.    
  577.     int v_count  = 0;
  578.     int vn_count  = 0;
  579.     int vt_count = 0;
  580.     int f_count = 0;
  581.    
  582.    
  583.     obj_file = fopen(filename, "r");
  584.     if (obj_file == NULL)
  585.         printf("can't find file: %s", filename);
  586.        
  587.     while (fgets(buffer, 100, obj_file)) {
  588.         /* puts(buffer); */
  589.         /* vertex coords */
  590.         if (buffer[0] == 'v' && buffer [1] == ' ') {
  591.             v_count++;
  592.             sscanf(buffer, "v %f %f %f",
  593.                    &mdl.vertexes[v_count].x,
  594.                    &mdl.vertexes[v_count].y,
  595.                    &mdl.vertexes[v_count].z);
  596. #if(RESIZE)
  597.             mdl.vertexes[v_count].x *= resize_coefficient;
  598.             mdl.vertexes[v_count].y *= resize_coefficient;
  599.             mdl.vertexes[v_count].z *= resize_coefficient;
  600. #endif
  601.         }
  602.        
  603.         /* vertex normals */
  604.         else if (buffer[0] == 'v' && buffer[1] == 'n') {
  605.             vn_count++;
  606.             sscanf(buffer, "vn %f %f %f",
  607.                    &mdl.normals[v_count].x,
  608.                    &mdl.normals[v_count].y,
  609.                    &mdl.normals[v_count].z);
  610.         }
  611.        
  612.         /* texture coords */
  613.         else if (buffer[0] == 'v' && buffer[1] == 't') {
  614.             vt_count++;
  615.             sscanf(buffer, "vt %f %f",
  616.                    &mdl.text_coords[vt_count].v,
  617.                    &mdl.text_coords[vt_count].u);
  618.         }
  619.        
  620.         /* faces */
  621.         else if (buffer[0] == 'f' && buffer [1] == ' ') {
  622.             int slash_count = 0;
  623.             f_count++;
  624.             int i;
  625.             for (i = 2; buffer[i] != ' '; i++)
  626.                 if (buffer[i] == '/')
  627.                     slash_count++;
  628.             /* printf("%i\n", slash_count); */
  629.            
  630.             if (slash_count == 1)
  631.                 sscanf(buffer, "f %i/%i %i/%i %i/%i",
  632.                        &mdl.faces[f_count].v1,  &mdl.faces[f_count].vt1,
  633.                        &mdl.faces[f_count].v2,  &mdl.faces[f_count].vt2,
  634.                        &mdl.faces[f_count].v3,  &mdl.faces[f_count].vt3
  635.                       );
  636.             else if (slash_count == 2)
  637.                 sscanf(buffer, "f %i/%i/%i %i/%i/%i %i/%i/%i",
  638.                        &mdl.faces[f_count].v1,  &mdl.faces[f_count].vt1, &mdl.faces[f_count].vn1,
  639.                        &mdl.faces[f_count].v2,  &mdl.faces[f_count].vt2, &mdl.faces[f_count].vn2,
  640.                        &mdl.faces[f_count].v3,  &mdl.faces[f_count].vt3, &mdl.faces[f_count].vn3);
  641.             else {
  642.                 puts("ERRRRORRRR!!!");
  643.                 exit(0);
  644.             }
  645.            
  646.         }
  647.     }
  648.    
  649.     fclose(obj_file);
  650.    
  651. #if(0) // AFTERSCAN_PRINT
  652.     printf("vertex count: %i\n", v_count);
  653.     printf("texture coords count: %i\n", vt_count);
  654.     printf("faces count: %i\n", f_count);
  655. #endif
  656.    
  657.     mdl.f_count = f_count; //remember for each model. later we'll use it for rendering
  658.    
  659.     return(mdl);
  660. }
  661.  
  662.  
  663.  
  664. void
  665. draw_model(/*int texnum, */model mdl)
  666. {
  667.     int ii = 0;
  668.    
  669.     //glBindTexture(GL_TEXTURE_2D, texture[texnum]);    /* Select Texture */
  670.     glBindTexture(GL_TEXTURE_2D, texture);
  671.     //glBindTexture(GL_TEXTURE_2D, sky_texture[3]);
  672.    
  673.     glBegin(GL_TRIANGLES);
  674.     {
  675.         for (ii = 0; ii <= mdl.f_count; ii++) {
  676.             /* TODO: remake whole structure. использовать вертексные массивы? */
  677.             glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt1 ].u,
  678.                      mdl.text_coords[ mdl.faces[ii].vt1 ].v);
  679.             glVertex3f(mdl.vertexes   [ mdl.faces[ii].v1  ].x,
  680.                    mdl.vertexes   [ mdl.faces[ii].v1  ].y,
  681.                    mdl.vertexes   [ mdl.faces[ii].v1  ].z);
  682.             //glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
  683.             //     mdl.normals   [ mdl.faces[ii].v1  ].y,
  684.             //     mdl.normals   [ mdl.faces[ii].v1  ].z);
  685.            
  686.             glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt2 ].u,
  687.                      mdl.text_coords[ mdl.faces[ii].vt2 ].v);
  688.             glVertex3f(mdl.vertexes   [ mdl.faces[ii].v2  ].x,
  689.                    mdl.vertexes   [ mdl.faces[ii].v2  ].y,
  690.                    mdl.vertexes   [ mdl.faces[ii].v2  ].z);
  691.             //glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
  692.             //     mdl.normals   [ mdl.faces[ii].v1  ].y,
  693.             //     mdl.normals   [ mdl.faces[ii].v1  ].z);
  694.            
  695.             glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt3 ].u,
  696.                      mdl.text_coords[ mdl.faces[ii].vt3 ].v);
  697.             glVertex3f(mdl.vertexes   [ mdl.faces[ii].v3  ].x,
  698.                    mdl.vertexes   [ mdl.faces[ii].v3  ].y,
  699.                    mdl.vertexes   [ mdl.faces[ii].v3  ].z);
  700.             //glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
  701.             //     mdl.normals   [ mdl.faces[ii].v1  ].y,
  702.             //     mdl.normals   [ mdl.faces[ii].v1  ].z);
  703.         }
  704.     }
  705.     glEnd();
  706. }
  707.  
  708.  
  709.  
  710. void
  711. reshape(int w, int h)
  712. {
  713.     glViewport(0, 0, w, h); // Reset The Current Viewport
  714.     glMatrixMode(GL_PROJECTION);
  715.    
  716.     glLoadIdentity();
  717.     //gluPerspective(45, (GLfloat)w/(GLfloat)h, 1, 100);
  718.     gluPerspective(45, (GLfloat)w/(GLfloat)h, 0.01, 100);
  719.    
  720.     glMatrixMode(GL_MODELVIEW);
  721.     glLoadIdentity();
  722.    
  723.     SCR_WIDTH = w;
  724.     SCR_HEIGHT = h;
  725. }
  726.  
  727.  
  728.  
  729. void
  730. draw_filled_hex()
  731. {
  732. #if(0)
  733.     int i;
  734.     for (i=0; i<6; i++) {
  735.         glBegin(GL_TRIANGLES);
  736.         {
  737.             glVertex2f(0, 0);
  738.             glVertex2f(0, HEX_EX);
  739.             glVertex2f(HEX_IN, HEX_EX/2);
  740.         }
  741.         glEnd();
  742.         glRotatef(60, 0, 0, 1);
  743.     }
  744. #else
  745.     glVertexPointer(3, GL_FLOAT, 0, HEX);
  746.     glDrawArrays(GL_POLYGON, 0, 6);
  747.     GLuint indexes[] = {0, 1, 2, 3, 4, 5};
  748.     glDrawElements(GL_LINE_LOOP, 6, GL_UNSIGNED_INT, indexes);
  749. #endif
  750. }
  751.  
  752.  
  753.  
  754.  
  755. void
  756. draw_wire_hex()
  757. {
  758. //  glLineStipple(1,0x00FF);
  759. //  glEnable(GL_LINE_STIPPLE);
  760.  
  761. #if(0)
  762.     glBegin(GL_LINE_STRIP);
  763.     {
  764.         glVertex3f(0,           HEX_EX, 0.01);
  765.         glVertex3f(-HEX_IN, +HEX_IN/2, 0.01);
  766.         glVertex3f(-HEX_IN, -HEX_IN/2, 0.01);
  767.         glVertex3f(0,          -HEX_EX, 0.01);
  768.         glVertex3f(HEX_IN, -HEX_IN/2, 0.01);
  769.         glVertex3f(HEX_IN,  HEX_IN/2, 0.01);
  770.         glVertex3f(0,           HEX_EX, 0.01);
  771.     }
  772.     glEnd();
  773. //  glDisable(GL_LINE_STIPPLE);
  774. #else
  775.     glVertexPointer(3, GL_FLOAT, 0, HEX);
  776.     glDrawArrays(GL_LINE_LOOP, 0, 6);
  777.     //GLuint indexes[] = {0, 1, 2, 3, 4, 5};
  778.     //glDrawElements(GL_LINE_LOOP, 6, GL_UNSIGNED_INT, indexes);
  779. #endif
  780. }
  781.  
  782.  
  783.  
  784. void
  785. draw_character(unit u)
  786. {
  787.     glPushMatrix();
  788.     glTranslatef(u.x, u.y, 0.01); //slightly above the floor
  789.    
  790.     //draw players identifier
  791.     if (u.player == 1) glColor3f(1.0, 0.5, 0.5);
  792.     if (u.player == 2) glColor3f(0.5, 0.5, 1.0);
  793.     gluDisk(GQO, HEX_IN*0.7, HEX_IN*0.9, 12, 2);
  794.    
  795.     //action points
  796.     glColor3f(0.3, 1, 0.3);
  797.     gluPartialDisk(GQO, HEX_IN*0.5, HEX_IN*0.7, u.ap, 2, 0, u.ap*60.0);
  798.    
  799.     //TODO где то тут должна рисоваться повернутая к камере фигнюшка с инфой над перцем
  800.     // + стоит находить для нее поправочный угол тут какнибудь =)
  801.     glPushMatrix();
  802.     {
  803.         glEnable(GL_BLEND);
  804.         glColor4f(0, 0, 1, 0.5);
  805.         glTranslatef(0, 0, 0.8);
  806.         glRotatef(CAMERA.horiz_angle+90, 0, 0, -1);
  807.         glRotatef(90, 0, 1, 0);
  808.         if(u.player == PLAYER)
  809.             gluPartialDisk(GQO, HEX_IN*0.1, HEX_IN*0.3, u.ap, 2, 0, u.ap*60.0);
  810.         glColor4f(0, 1, 0, 0.5);
  811.         gluPartialDisk(GQO, HEX_IN*0.3, HEX_IN*0.4, u.health, 2, 0, u.health*30);
  812.         glColor4f(1, 0, 0, 0.5);
  813.         gluPartialDisk(GQO, HEX_IN*0.3, HEX_IN*0.4, 12-u.health, 2, u.health*30, 360-u.health*30);
  814.         glDisable(GL_BLEND);
  815.     }
  816.     glPopMatrix();
  817.    
  818.     //glColor3f(1, 1, 1);
  819.     if (u.player == 1)
  820.         glColor3f(1.0, 0.8, 0.8);
  821.     else
  822.         glColor3f(0.8, 0.8, 1.0);
  823.  
  824. #if(0) //draw some test sphere
  825.     glTranslatef(0, 0, 0.2); //slightly above the floor
  826.     gluSphere(GQO, HEX_IN*0.3, 6, 6);
  827. #else //draw model     
  828.     glRotatef(90, 1, 0, 0); // because of blender exporter
  829.     glRotatef(u.rot, 0, 1, 0); //individual character rotation
  830.     glEnable(GL_TEXTURE_2D);
  831.     draw_model(mdl[u.frame]);
  832.     glDisable(GL_TEXTURE_2D);
  833. #if(1) //model's shadow
  834.     glScalef(1, 0.01, 1); //расплющить перца, что б был похож на тень
  835.     glColor4f(0, 0, 0, 0.5);
  836.     draw_model(mdl[u.frame]);
  837. #endif
  838. #endif
  839.     glPopMatrix();
  840. }
  841.  
  842.  
  843. void
  844. set_camera()
  845. {
  846.     glLoadIdentity();
  847.     glTranslatef(0, 0, -CAMERA.distanse); //отдаление
  848.     glRotatef(-CAMERA.vert_angle, 1, 0, 0);
  849.     glRotatef(CAMERA.horiz_angle, 0, 0, 1);
  850.     glTranslatef(CAMERA.x, CAMERA.y, 0);
  851. }
  852.  
  853.  
  854. #define PICK_BG  0 // code for backround
  855. #define PICK_HEX 1 //code for terrain hex
  856.  
  857. void
  858. draw_for_picking()
  859. {
  860.     glClearColor(0, 0, PICK_BG, 1);
  861.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  862.    
  863.     set_camera();
  864.    
  865.     glPushMatrix();
  866.     glEnableClientState(GL_VERTEX_ARRAY);
  867.    
  868.     int x, y;
  869.     for (y=0; y<MAP_SIZE_Y; y++) {
  870.         for (x=0; x<MAP_SIZE_X; x++) {
  871.             glColor3ub(x, y, PICK_HEX);
  872.             draw_filled_hex();
  873.             glTranslatef(2*HEX_IN, 0, 0);
  874.         }
  875.         if (y%2 == 0)
  876.             glTranslatef(-HEX_IN, 1.5*HEX_EX, 0);
  877.         else
  878.             glTranslatef(+HEX_IN, 1.5*HEX_EX, 0);
  879.         glTranslatef(-(2*HEX_IN *MAP_SIZE_X), 0, 0);
  880.     }
  881.    
  882.     glDisableClientState(GL_VERTEX_ARRAY);
  883.     glPopMatrix();
  884. }
  885.  
  886. #if(0)
  887. #define MAX_CHCOUNT 20
  888.  
  889. typedef struct Bone {
  890.     float a, l;
  891.     float rel[16];
  892.    
  893.     int childCount;
  894.     struct  Bone *child[MAX_CHCOUNT],
  895.                 *parent;
  896. } Bone;
  897.  
  898. typedef struct vertex {
  899.     float pos[3];
  900.     Bone *bone;
  901. } vertex;
  902.  
  903.  
  904.  
  905. Bone*
  906. boneAddChild(Bone *root, float a, float l)
  907. {
  908.     Bone *tmp_bone;
  909.     int i;
  910.    
  911.     if (!root) { /* If there is no root, create one */
  912.         if (!(root = (Bone *)malloc(sizeof(Bone))))
  913.             return(NULL);
  914.         root->parent = NULL;
  915.     } else if (root->childCount < MAX_CHCOUNT) { /* If there is space for another child */
  916.         /* Allocate the child */
  917.         if (!(tmp_bone = (Bone *)malloc(sizeof(Bone))))
  918.             return(NULL);
  919.            
  920.         tmp_bone->parent = root; /* Set it's parent */
  921.         /* Increment the childCounter and set the pointer */
  922.         root->child[root->childCount++] = tmp_bone;
  923.         root = tmp_bone; /* Change the root */
  924.     } else /* Can't add a child */
  925.         return(NULL);
  926.        
  927.     /* Set data */
  928.     root->a = a;
  929.     root->l = l;
  930.     root->childCount = 0;
  931.    
  932.     for (i = 0; i < MAX_CHCOUNT; i++)
  933.         root->child[i] = NULL;
  934.        
  935.     return(root); //return bone, that we just have added!
  936. }
  937.  
  938.  
  939.  
  940.  
  941. void
  942. boneDraw(Bone *root)
  943. {
  944.     glPushMatrix();
  945.    
  946.     glRotatef(root->a, 0, 0, 1);
  947.    
  948.     glGetFloatv(GL_MODELVIEW_MATRIX, root->rel);
  949.    
  950.     glBegin(GL_TRIANGLES);
  951.     //glBegin(GL_LINES);
  952.     {
  953.         glColor3f(1.0, 0.0, 0.0);
  954.         glVertex2f(0, -5);
  955.         glVertex2f(0, +5);
  956.         //glVertex2f(0, 0);
  957.         glColor3f(1.0, 1.0, 1.0);
  958.         glVertex2f(root->l, 0);
  959.     }
  960.     glEnd();
  961.    
  962.     /* Translate to reach the new starting position */
  963.     glTranslatef(root->l, 0.0, 0.0);
  964.    
  965.     int i;
  966.     /* Call function on bones children */
  967.     for (i = 0; i < root->childCount; i++)
  968.         boneDraw(root->child[i]);
  969.        
  970.     glPopMatrix();
  971. }
  972.  
  973.  
  974.  
  975. void
  976. rotate_vertex(float *m, float *pos)
  977. {
  978.     float v[3] = {pos[0], pos[1], pos[2]};
  979.    
  980.     pos[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8];
  981.     pos[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9];
  982.     pos[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10];
  983. }
  984. #endif //не надо мне пока костей. не до этого((
  985.  
  986. //TODO. просто хер знает что, честно((
  987. void
  988. draw_sky()
  989. {
  990.  
  991.  
  992.     glPushMatrix();
  993.     glScalef(50, 50, 50);
  994.     glColor3f(1, 1, 1);
  995.    
  996.     glEnable(GL_TEXTURE_2D);
  997.    
  998.    
  999.     // сторона 1
  1000.     glBindTexture(GL_TEXTURE_2D, sky_texture[1]);
  1001.     glBegin(GL_QUADS);
  1002.     //glColor3f(1, 0, 0);
  1003.     //glNormal3f(0.0f, -1.0f, 0.0f);
  1004.     glTexCoord2f(1, 1);
  1005.     glVertex3f(-1, -1, -1);
  1006.     glTexCoord2f(0, 1);
  1007.     glVertex3f(1, -1, -1);
  1008.     glTexCoord2f(0, 0);
  1009.     glVertex3f(1, -1,  1);
  1010.     glTexCoord2f(1, 0);
  1011.     glVertex3f(-1, -1,  1);
  1012.     glEnd();
  1013.    
  1014.     // сторона 2
  1015.     glBindTexture(GL_TEXTURE_2D, sky_texture[2]);
  1016.     glBegin(GL_QUADS);
  1017.     //glColor3f(0, 1, 0);
  1018.     //glNormal3f(0.0f, 1.0f, 0.0f);
  1019.     glTexCoord2f(0, 1);
  1020.     glVertex3f(-1,  1, -1);
  1021.     glTexCoord2f(0, 0);
  1022.     glVertex3f(-1,  1,  1);
  1023.     glTexCoord2f(1, 0);
  1024.     glVertex3f(1,  1,  1);
  1025.     glTexCoord2f(1, 1);
  1026.     glVertex3f(1,  1, -1);
  1027.     glEnd();
  1028.    
  1029.    
  1030.    
  1031.    
  1032.     // НИЖНЯЯ. ее вообще можно бы и удалить.
  1033.     //glBindTexture(GL_TEXTURE_2D, sky_texture[1]);
  1034.     //glBegin(GL_QUADS);
  1035.     //glColor3f(0, 0, 1);
  1036.     //glNormal3f(0.0f, 0.0f,-1.0f);
  1037.     glTexCoord2f(1, 0);
  1038.     glVertex3f(-1, -1, -1);
  1039.     glTexCoord2f(1, 1);
  1040.     glVertex3f(-1,  1, -1);
  1041.     glTexCoord2f(0, 1);
  1042.     glVertex3f(1,  1, -1);
  1043.     glTexCoord2f(0, 0);
  1044.     glVertex3f(1, -1, -1);
  1045.     glEnd();
  1046.    
  1047.    
  1048.     // сторона 3
  1049.     glBindTexture(GL_TEXTURE_2D, sky_texture[3]);
  1050.     glBegin(GL_QUADS);
  1051.     //glColor3f(1, 0, 1);
  1052.     //glNormal3f(1.0f, 0.0f, 0.0f);
  1053.     glTexCoord2f(0, 0);
  1054.     glVertex3f(1, -1, -1);
  1055.     glTexCoord2f(1, 0);
  1056.     glVertex3f(1,  1, -1);
  1057.     glTexCoord2f(1, 1);
  1058.     glVertex3f(1,  1,  1);
  1059.     glTexCoord2f(0, 1);
  1060.     glVertex3f(1, -1,  1);
  1061.     glEnd();
  1062.    
  1063.    
  1064.     // ВЕРХ
  1065.     //glBindTexture(GL_TEXTURE_2D, sky_texture[3]);
  1066.     //glBegin(GL_QUADS);
  1067.     //glColor3f(1, 1, 1);
  1068.     //glNormal3f(0.0f, 0.0f, 1.0f);
  1069.     glTexCoord2f(0, 0);
  1070.     glVertex3f(-1, -1,  1);
  1071.     glTexCoord2f(1, 0);
  1072.     glVertex3f(1, -1,  1);
  1073.     glTexCoord2f(1, 1);
  1074.     glVertex3f(1,  1,  1);
  1075.     glTexCoord2f(0, 1);
  1076.     glVertex3f(-1,  1,  1);
  1077.     glEnd();
  1078.    
  1079.    
  1080.     // сторона 4
  1081.     glBindTexture(GL_TEXTURE_2D, sky_texture[4]);
  1082.     glBegin(GL_QUADS);
  1083.     //glColor3f(1, 1, 0);
  1084.     //glNormal3f(-1.0f, 0.0f, 0.0f);
  1085.     glTexCoord2f(0, 1);
  1086.     glVertex3f(-1, -1, -1);
  1087.     glTexCoord2f(0, 0);
  1088.     glVertex3f(-1, -1,  1);
  1089.     glTexCoord2f(1, 0);
  1090.     glVertex3f(-1,  1,  1);
  1091.     glTexCoord2f(1, 1);
  1092.     glVertex3f(-1,  1, -1);
  1093.    
  1094.     glEnd();
  1095.     glPopMatrix();
  1096.    
  1097.     glDisable(GL_TEXTURE_2D);
  1098. }
  1099.  
  1100.  
  1101.  
  1102. void
  1103. draw_terrain()
  1104. {
  1105.     glPushMatrix();
  1106.    
  1107.     int x, y;
  1108.     for (y=0; y< MAP_SIZE_Y; y++) {
  1109.         for (x=0; x<MAP_SIZE_X; x++) {
  1110.             glPushMatrix();
  1111.             glTranslatef(0, 0, 0.01);
  1112.             if (SELECTED_UNIT) {
  1113.                 //это можно бы вынести отсюда и рисовать простым переносом.
  1114.                 if (SELECTED_UNIT->mx == x && SELECTED_UNIT->mx == y) {
  1115.                     glColor3f(0.8, 0.3, 0.3);
  1116.                     gluDisk(GQO, HEX_IN*0.9, HEX_IN*0.95, 12, 2);
  1117.                 }
  1118.                
  1119.                 //рисует кружок над клетой, если мы можем дойти туда
  1120.                 if (MAP[x][y].move_cost <= SELECTED_UNIT->ap) {
  1121.                     glColor3f(0.5, 0.5, 1.0);
  1122.                     gluDisk(GQO, HEX_IN*0.2, HEX_IN*0.4, 12, 2);
  1123.                 }
  1124.             }
  1125.             if (PICKED_SMTH && aX == x && aY == y) {
  1126.                 glColor3f(0.3, 0.8, 0.3);
  1127.                 gluDisk(GQO, HEX_IN*0.95, HEX_IN*1.1, 12, 2);
  1128.             }
  1129.             glPopMatrix();
  1130.            
  1131.             float coff = 1.0 - (float)(MAP[x][y].init_cost*20)/256;
  1132.             glColor3f(coff, coff, coff);
  1133.            
  1134.             if (SELECTED_UNIT && MODE == MODE_SELECT
  1135.                     && MAP[x][y].unit
  1136.                     && MAP[x][y].unit->player != PLAYER
  1137.                     //&& (get_distance(sX, sY, x, y) == 1 || get_distance(aX, aY, x, y) == 1))
  1138.                     //&& (get_distance(sX, sY, x, y) <= D || get_distance(aX, aY, x, y) <= D))
  1139.                     && (get_distance(SELECTED_UNIT->mx, SELECTED_UNIT->my, x, y) <= SELECTED_UNIT->attack_distance)) {
  1140.                 glColor3f(coff, 0, 0);
  1141.             }
  1142.            
  1143.             //гексы на пути будут подсвечены
  1144.             //можно делать проверку на то, что точка вообще в нужном районе для оптимизации
  1145.             if (SELECTED_UNIT && check_line_hex_intersects(SELECTED_UNIT->mx, SELECTED_UNIT->my,  aX,aY,  x,y))
  1146.                 glColor3f(0, coff, 0);
  1147.            
  1148.             glEnableClientState(GL_VERTEX_ARRAY);
  1149.             draw_filled_hex();
  1150. #if(1) //draw wire
  1151.             //glColor3f(0.5, 0.5, 0.5);
  1152.             if(PLAYER == 1)
  1153.                 glColor3f(1, 0, 0);
  1154.             else
  1155.                 glColor3f(0, 0, 1);
  1156.             draw_wire_hex();
  1157. #endif //draw wire
  1158.             glDisableClientState(GL_VERTEX_ARRAY);
  1159.             glTranslatef(2*HEX_IN, 0, 0);
  1160.         }
  1161.         if (y%2 == 0)
  1162.             glTranslatef(-HEX_IN, 1.5*HEX_EX, 0);
  1163.         else
  1164.             glTranslatef(+HEX_IN, 1.5*HEX_EX, 0);
  1165.         glTranslatef(-(2*HEX_IN *MAP_SIZE_X), 0, 0);
  1166.     }
  1167.    
  1168.     glPopMatrix();
  1169. }
  1170.  
  1171.  
  1172.  
  1173. void
  1174. draw_characters()
  1175. {
  1176.     unit* tmp = UNITS;
  1177.     while(tmp != NULL)
  1178.     {
  1179.         draw_character(*tmp);
  1180.         tmp = tmp->next;
  1181.     }
  1182. }
  1183.  
  1184.  
  1185.  
  1186. void
  1187. draw()
  1188. {
  1189.     glClearColor(0, 0, 0, 1);
  1190.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1191.    
  1192.     set_camera();
  1193.     draw_terrain();
  1194.     draw_characters();
  1195.     draw_sky();
  1196.    
  1197. #if(1)
  1198.     if (SELECTED_UNIT) {
  1199.         //рисует белую линию от выбранной ячейки до активной(куда тыкает мышка)
  1200.        
  1201.         glColor3f(1, 1, 1);
  1202.         glBegin(GL_LINES);
  1203.         {
  1204.             float rx, ry;
  1205.            
  1206.             map_to_real(aX, aY, &rx, &ry);
  1207.             glVertex3f(rx, ry, 0);
  1208.             map_to_real(SELECTED_UNIT->mx, SELECTED_UNIT->my, &rx, &ry);
  1209.             glVertex3f(rx, ry, 0);
  1210.         }
  1211.         glEnd();
  1212.     }
  1213. #endif
  1214.    
  1215. #if(0) //направление движения
  1216.     if (MODE == MODE_MOVE) {
  1217.         glColor3f(0, 1, 0);
  1218.         glBegin(GL_LINES);
  1219.         {
  1220.             float rx, ry;
  1221.            
  1222.             map_to_real(back_path_x[back_path_current], back_path_y[back_path_current], &rx, &ry);
  1223.             glVertex3f(rx, ry, 0);
  1224.             map_to_real(back_path_x[back_path_current-1], back_path_y[back_path_current-1], &rx, &ry);
  1225.             glVertex3f(rx, ry, 0);
  1226.         }
  1227.         glEnd();
  1228.     }
  1229. #endif
  1230.    
  1231. #if(1) // типа земля или чего то такое.
  1232.     glPushMatrix();
  1233.     glTranslatef(0, 0, -0.2);
  1234.     glScalef(100, 100, 100);
  1235.     glColor3f(1, 1, 1);
  1236.     glBegin(GL_QUADS);
  1237.     {
  1238.         glVertex2f(-1, -1);
  1239.         glVertex2f(+1, -1);
  1240.         glVertex2f(+1, +1);
  1241.         glVertex2f(-1, +1);
  1242.     }
  1243.     glEnd();
  1244.     glPopMatrix();
  1245. #endif
  1246. }
  1247.  
  1248.  
  1249.  
  1250. void
  1251. do_picking()
  1252. {
  1253.     GLint viewport[4];
  1254.     GLubyte pixel[3];
  1255.    
  1256.     glGetIntegerv(GL_VIEWPORT, viewport);
  1257.     glReadPixels(cursorX, viewport[3]-cursorY, 1, 1, GL_RGB,
  1258.              GL_UNSIGNED_BYTE, (void*)pixel);
  1259.                  
  1260.     //update active cell
  1261.     aX = pixel[0]; //TODO вот изза этого то и выбирается первая ячейка, вроде.
  1262.     aY = pixel[1];
  1263.     //printf("ax:%i, ay%i\n", aX, aY);
  1264.    
  1265.     // поворачивать выделенный юнит к активной ячейке
  1266.     //if (IS_SOMEONE_SELECTED) {
  1267.     //  UNITS[MAP[sX][sY].unit_id].rot = get_rot_angle(sX, sY, aX, aY);
  1268.     //  printf("angle = %f\n", get_rot_angle(sX, sY, aX, aY));
  1269.     // }
  1270.    
  1271.    
  1272.     PICKED_SMTH = (bool)pixel[2];
  1273.     //printf("%u\n", pixel[2]);
  1274.     if (pixel[2] > 1) { //если 3й элемент больше еденицы - мы тыркнулись в интерфейс
  1275.         //printf("some button\n");
  1276.         SELECTED_BUTTON = pixel[2]-2;
  1277.         printf("%s\n", BUTTONS[ pixel[2]-2 ].name);
  1278.     } else {
  1279.         SELECTED_BUTTON = -1;
  1280.     }
  1281. }
  1282.  
  1283.  
  1284.  
  1285. void
  1286. fill_map(Q *q, ushort by, ushort bx)
  1287. {
  1288.     ushort x, y;
  1289.     for (y=0; y<MAP_SIZE_Y; y++) {
  1290.         for (x=0; x<MAP_SIZE_X; x++) {
  1291.             // TODO: put there some information about other units
  1292.             MAP[x][y].move_cost = 30000;
  1293.         }
  1294.     }
  1295.    
  1296.     push(q, bx, by, bx, by, 0); //push start point
  1297.    
  1298.     while (pop(q, &x, &y)) { //TODO переписать исползуя новую функцию получения соседей.
  1299.         try_push(q, x+1, y  , x, y);
  1300.         try_push(q, x-1, y  , x, y);
  1301.         try_push(q, x  , y+1, x, y);
  1302.         try_push(q, x  , y-1, x, y);
  1303.         if (y%2==0) {
  1304.             try_push(q, x+1, y-1, x, y);
  1305.             try_push(q, x+1, y+1, x, y);
  1306.         } else {
  1307.             try_push(q, x-1, y-1, x, y);
  1308.             try_push(q, x-1, y+1, x, y);
  1309.         }
  1310.     }
  1311. }
  1312.  
  1313.  
  1314. //TODO: blablabla
  1315.  
  1316. void
  1317. get_path(ushort bx, ushort by, ushort ex, ushort ey)
  1318. {
  1319.     back_path_current = 0;
  1320.    
  1321.     ushort x = ex, y = ey, tmpx, tmpy;
  1322.     while ((x != bx) || (y != by)) {
  1323.         back_path_x[back_path_current] = x;
  1324.         back_path_y[back_path_current] = y;
  1325.         back_path_current++;
  1326.        
  1327.         tmpx = MAP[x][y].parent_x;
  1328.         tmpy = MAP[x][y].parent_y;
  1329.         x = tmpx;
  1330.         y = tmpy;
  1331.        
  1332.     }
  1333.     back_path_x[back_path_current] = x;
  1334.     back_path_y[back_path_current] = y;
  1335.     back_path_current++; //TODO я не уверен, что это должно быть в конце.
  1336. }
  1337.  
  1338.  
  1339.  
  1340. unsigned
  1341. generate_texture_from_str(char* Text, int *w, int *h)
  1342. {
  1343.     SDL_Color Color = {255, 255, 255, 0};
  1344.     SDL_Surface *txt = TTF_RenderUTF8_Blended(font, Text, Color);
  1345.     unsigned id = 0; // айди текстуры
  1346.    
  1347.     glGenTextures(1, &id); /*Generate an OpenGL 2D texture from the SDL_Surface*.*/
  1348.     glBindTexture(GL_TEXTURE_2D, id); //вот зза отстутсвтвия этой строки я столько мудохался
  1349.    
  1350.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, txt->w, txt->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, txt->pixels);
  1351.     *w = txt->w;
  1352.     *h = txt->h;
  1353.     SDL_FreeSurface(txt);
  1354.    
  1355.     return(id);
  1356. }
  1357.  
  1358.  
  1359.  
  1360. void
  1361. change_button_text (gui_button* b, char* text)
  1362. {
  1363.     glDeleteTextures(1, &(b->textureID));
  1364.     b->textureID = generate_texture_from_str(text, &(b->textSX), &(b->textSY));
  1365. }
  1366.  
  1367.  
  1368.  
  1369.  
  1370. void
  1371. end_player_turn()
  1372. {
  1373.     SELECTED_UNIT = false;
  1374.    
  1375.     if (PLAYER == 1) {
  1376.         PLAYER = 2;
  1377.         int i;
  1378.         for(i=0; i< BUTTONS_COUNT; i++){
  1379.             if(!strcmp(BUTTONS[i].name, "player identifier")){
  1380.                 change_button_text(&(BUTTONS[i]), "синий");
  1381.                 break;
  1382.             }
  1383.         }
  1384.     } else {
  1385.         PLAYER = 1;
  1386.         int i;
  1387.         for(i=0; i< BUTTONS_COUNT; i++){
  1388.             if(!strcmp(BUTTONS[i].name, "player identifier")){
  1389.                 change_button_text(&(BUTTONS[i]), "красный");
  1390.                 break;
  1391.             }
  1392.         }
  1393.     }
  1394.    
  1395.     unit* tmp = UNITS;
  1396.     while(tmp != NULL){
  1397.         if (tmp->player == PLAYER) {
  1398.             tmp->ap = 6;
  1399.         }
  1400.         tmp = tmp->next;
  1401.     }
  1402.  
  1403.     //CHECK WIN
  1404.     int p1=0, p2=0;
  1405.     unit* t = UNITS;
  1406.     while(t != NULL){
  1407.         if (t->player == 1) p1++;
  1408.         if (t->player == 2) p2++;
  1409.         t = t->next;
  1410.     }
  1411.     if(p1 == 0)
  1412.     {
  1413.         puts("PLAYER 2 WIN");
  1414.         exit(0);
  1415.     }
  1416.     if(p2 == 0)
  1417.     {
  1418.         puts("PLAYER 1 WIN");
  1419.         exit(0);
  1420.     }
  1421. }
  1422.  
  1423.  
  1424.  
  1425.  
  1426. void
  1427. handle_mouse_events(SDL_Event E)
  1428. {
  1429.     if (SELECTED_BUTTON != -1 && E.type == SDL_MOUSEBUTTONUP)
  1430.     {
  1431.         printf("%s\n", BUTTONS[ SELECTED_BUTTON ].name);
  1432.         return;
  1433.     }
  1434.    
  1435.     if (PICKED_SMTH && MODE == MODE_SELECT) {
  1436.         if (MAP[aX][aY].unit) { //если тут хто то есть
  1437.             //если это наш перец
  1438.             if (MAP[aX][aY].unit->player == PLAYER) {
  1439.                 //если опять кликнуть на уже выделенном юните
  1440.                 // - камера отцентрируется на нем
  1441.                 if (SELECTED_UNIT && MAP[aX][aY].unit == SELECTED_UNIT) {
  1442.                     map_to_real(aX, aY, &(CAMERA.x), &(CAMERA.y));
  1443.                     CAMERA.y = -CAMERA.y;
  1444.                     CAMERA.x = -CAMERA.x;
  1445.                 }else{
  1446.                     //select character
  1447.                     SELECTED_UNIT = MAP[aX][aY].unit;
  1448.                     fill_map(&q, aY, aX);
  1449.                 }
  1450.             } else if (SELECTED_UNIT
  1451.                     && SELECTED_UNIT->ap >= attack_cost
  1452.                     //&& get_distance(aX, aY, sX, sY) == 1) //ближний бой
  1453.                     //&& get_distance(aX, aY, sX, sY) <= 2) //дальний бой
  1454.                     && get_distance(aX, aY, SELECTED_UNIT->mx, SELECTED_UNIT->my)
  1455.                             <= SELECTED_UNIT->attack_distance)
  1456.             {
  1457.                 // try to kill KILL enemy unit!
  1458.                 //TODO ввести доп переменные в стрктуру ФАЙТ:
  1459.                 // смерть один, ответ, отступление, т.д.
  1460.                 //if (rand()%2) {
  1461.                 //  free(MAP[aX][aY].ch);
  1462.                 //  MAP[aX][aY].ch = NULL; //TODO подумать...
  1463.                 //  UNITS[MAP[aX][aY].unit_id].dead = true; //TODO подумать...
  1464.                 //  UNITS[MAP[aX][aY].unit_id].health -= 4;
  1465.                 //}
  1466.                 SELECTED_UNIT->ap -= attack_cost;
  1467.                 FIGHT.u1 = SELECTED_UNIT;
  1468.                 FIGHT.u2 = MAP[aX][aY].unit;
  1469.                 MODE = MODE_FIGHT;
  1470.             }
  1471.         } else { //если тут никого нет
  1472.             //но если все таки кто то выбран
  1473.             if (SELECTED_UNIT) {
  1474.                 // try move selected character
  1475.                 fill_map(&q, SELECTED_UNIT->my, SELECTED_UNIT->mx);
  1476.                 if (MAP[aX][aY].move_cost <= SELECTED_UNIT->ap) {
  1477.                     //if character has requested action points
  1478.                     SELECTED_UNIT->ap -= MAP[aX][aY].move_cost; //TODO убирать поэтапно
  1479.                     get_path(SELECTED_UNIT->mx, SELECTED_UNIT->my, aX, aY); //TODO изменить порядок
  1480.                     MODE = MODE_MOVE;
  1481.                     MOVE.step_count = 0;
  1482.                     MOVE.unit = SELECTED_UNIT;
  1483.                     MAP[SELECTED_UNIT->mx][SELECTED_UNIT->my].unit = NULL;
  1484.                 }
  1485.                
  1486.             }
  1487.         }
  1488.     }
  1489.    
  1490. }
  1491.  
  1492.  
  1493.  
  1494.  
  1495. void
  1496. hanlde_events(SDL_Event E)
  1497. {
  1498.  
  1499.     switch (E.type) {
  1500.         default:
  1501.             //puts("unknown event!");
  1502.             break;
  1503.            
  1504.         case SDL_QUIT:
  1505.             isProgramLooping = false;
  1506.             break;
  1507.            
  1508.         case SDL_VIDEORESIZE:
  1509.             reshape(E.resize.w, E.resize.h);
  1510.             break;
  1511.            
  1512.         case SDL_MOUSEMOTION:
  1513.             cursorX = E.motion.x;
  1514.             cursorY = E.motion.y;
  1515.            
  1516.             if (CAMERA.is_rotating) {
  1517.                 CAMERA.horiz_angle += E.motion.xrel;
  1518.                 CAMERA.vert_angle += E.motion.yrel;
  1519. #if(1) //ограничивает вращение камеры
  1520.                 if (CAMERA.vert_angle < 30 || CAMERA.vert_angle > 85)
  1521.                     CAMERA.vert_angle -= E.motion.yrel;
  1522.                 if (CAMERA.horiz_angle > 360 || CAMERA.horiz_angle < -360)
  1523.                     CAMERA.horiz_angle = 0;
  1524. #endif
  1525.             }
  1526.             break;
  1527.            
  1528.         case SDL_MOUSEBUTTONDOWN:
  1529.             if (E.button.button == SDL_BUTTON_RIGHT) {
  1530.                 CAMERA.is_rotating = true;
  1531.             }
  1532.             if (E.button.button == SDL_BUTTON_LEFT)
  1533.                 handle_mouse_events(E);
  1534.             break;
  1535.            
  1536.         case SDL_MOUSEBUTTONUP:
  1537.             if (E.button.button == SDL_BUTTON_RIGHT) {
  1538.                 CAMERA.is_rotating = false;
  1539.             } else {
  1540.                 if (E.button.button == SDL_BUTTON_WHEELUP   && CAMERA.distanse < 15)
  1541.                     CAMERA.distanse++;
  1542.                 if (E.button.button == SDL_BUTTON_WHEELDOWN && CAMERA.distanse > 4)
  1543.                     CAMERA.distanse--;
  1544.             }
  1545.             // если это не закоментить - то обработка вызыывается дважды за клик.
  1546.             //if (E.button.button == SDL_BUTTON_LEFT)
  1547.             //  handle_mouse_events(E);
  1548.            
  1549.             break;
  1550.            
  1551.            
  1552.         case SDL_KEYDOWN:
  1553.             switch (E.key.keysym.sym) {
  1554.                 default:
  1555.                     break;
  1556.                 case SDLK_q:
  1557.                 case SDLK_ESCAPE:
  1558.                     isProgramLooping = false;
  1559.                     break;
  1560.                 case SDLK_SPACE:
  1561.                     end_player_turn();
  1562.                     break;
  1563.                 case SDLK_UP:
  1564.                     CAMERA.y--;
  1565.                     break;
  1566.                 case SDLK_DOWN:
  1567.                     CAMERA.y++;
  1568.                     break;
  1569.                 case SDLK_LEFT:
  1570.                     if (E.key.keysym.mod & KMOD_LCTRL)
  1571.                         CAMERA.distanse++;
  1572.                     else
  1573.                         CAMERA.x++;
  1574.                     break;
  1575.                 case SDLK_RIGHT:
  1576.                     if (E.key.keysym.mod & KMOD_LCTRL)
  1577.                         CAMERA.distanse--;
  1578.                     else
  1579.                         CAMERA.x--;
  1580.                     break;
  1581.                 case SDLK_p:
  1582.                     if (MODE != MODE_PAUSE) {
  1583.                         PREVIOUS_MODE = MODE;
  1584.                         MODE = MODE_PAUSE;
  1585.                     } else {
  1586.                         MODE = PREVIOUS_MODE;
  1587.                     }
  1588.                     break;
  1589.             }
  1590.     }
  1591. }
  1592.  
  1593.  
  1594.  
  1595. void
  1596. init_sdl()
  1597. {
  1598.     SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
  1599.     atexit(SDL_Quit);
  1600.    
  1601.     /* the flags to pass to SDL_SetVideoMode */
  1602.     video_flags  = SDL_OPENGL;
  1603.     video_flags |= SDL_GL_DOUBLEBUFFER;
  1604.     video_flags |= SDL_RESIZABLE;
  1605.    
  1606.     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
  1607.     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
  1608.     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
  1609.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  1610.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  1611.     /* get a SDL surface */
  1612.     surface = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT,
  1613.                    SCR_BPP, video_flags);
  1614.     SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
  1615.    
  1616.     reshape(SCR_WIDTH, SCR_HEIGHT);
  1617. }
  1618.  
  1619.  
  1620.  
  1621. void
  1622. init_opengl()
  1623. {
  1624.     glEnable(GL_TEXTURE_2D);
  1625.     glShadeModel(GL_SMOOTH);
  1626.    
  1627.     glClearColor(0, 0, 0, 1);
  1628.     glClearDepth(1.0f);
  1629.     glEnable(GL_DEPTH_TEST);
  1630.    
  1631.     //glEnable(GL_LIGHTING);
  1632.     glEnable(GL_AUTO_NORMAL);
  1633.     glEnable(GL_COLOR_MATERIAL);
  1634.     glEnable(GL_LIGHT0);
  1635.     glEnable(GL_NORMALIZE);
  1636.     glEnable(GL_BLEND);
  1637.     //float POS[] = {0, 1, 0, 0};
  1638.     //glLightfv(GL_LIGHT0, GL_POSITION, POS);
  1639.    
  1640.     glDepthFunc(GL_LEQUAL);     /* The Type Of Depth Test To Do */
  1641.     /* Really Nice Perspective Calculations */
  1642.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  1643.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  1644.    
  1645.     //glEnable(GL_CULL_FACE);
  1646.     //glFrontFace(GL_CW);
  1647.     //glCullFace(GL_BACK);
  1648.    
  1649.     //glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  1650. }
  1651.  
  1652.  
  1653.  
  1654.  
  1655. bool
  1656. add_unit (/*TODO type, */ int x, int y, int player)
  1657. {
  1658.     unit* u = malloc(sizeof(unit));
  1659.     if (u == NULL)
  1660.         return(false);
  1661.         //exit(1);
  1662.  
  1663.     //добавит перца в список
  1664.     u->next = UNITS;
  1665.     UNITS = u; //теперь список будет начинаться с этого перца
  1666.    
  1667.     map_to_real(x, y, &(u->x), &(u->y)); //реальные координаты перца в этой клетке
  1668.     u->mx = x;
  1669.     u->my = y;
  1670.     u->player = player;
  1671.     u->rot = (rand()%6)*60+30; // потоврот персонажа. 30, 90, т.д.
  1672.     u->frame = (rand()%22)+99; //рандомный кадр из idle анимации
  1673.     u->ap = 6;
  1674.     u->cost_attack = 2;
  1675.     u->rotation_speed = 5;
  1676.     u->movement_speed = 0.031; // просто подобрал. хз =)
  1677.     u->health = 12;
  1678.     u->attack_distance = 3;
  1679.      
  1680.     //запомнить, что он находится в этой клетке
  1681.     MAP[x][y].unit = u;
  1682.    
  1683.     return(true);
  1684. }
  1685.  
  1686.  
  1687.  
  1688. void
  1689. init_map()
  1690. {
  1691.     int y, x;
  1692.     for (y=0; y<MAP_SIZE_Y; y++) {
  1693.         for (x=0; x<MAP_SIZE_X; x++) {
  1694.             //нет тут персонажа, т.к. индекс может быть >= 0
  1695.             MAP[x][y].unit = NULL;
  1696.             MAP[x][y].init_cost = (rand()%2)*3+1; // 1 или 4
  1697.             //такого значения не может быть(вроде), так что это значит,
  1698.             //что мы еще не трогали эиу клетку
  1699.             MAP[x][y].move_cost = 30000;
  1700.            
  1701.             if (rand()%10 > 8)
  1702.                 add_unit (x, y, rand()%2+1); //сторона определяется рандомом.
  1703.         }
  1704.     }
  1705. }
  1706.  
  1707.  
  1708.  
  1709. void
  1710. move_logic()
  1711. {
  1712.     if (MOVE.step_count > 0) { // we have not reached the destination
  1713.         MOVE.unit->x  += MOVE.step_x;
  1714.         MOVE.unit->y  += MOVE.step_y;
  1715.         MOVE.step_count--;
  1716.     } else {
  1717.         if (back_path_current > 1) { //если еще точки в маршруте
  1718.             // точки пути перечислены в обратном порядке
  1719.             float a = get_rot_angle(
  1720.                       back_path_x[back_path_current-1],
  1721.                       back_path_y[back_path_current-1],
  1722.                       back_path_x[back_path_current-2],
  1723.                       back_path_y[back_path_current-2]);
  1724.          
  1725.             //while(a<0) a+= 360; while(a>360) a-= 360;
  1726.             //while(UNITS[MOVE.unit_id].rot<0) UNITS[MOVE.unit_id].rot+= 360;
  1727.             //while(UNITS[MOVE.unit_id].rot>360) UNITS[MOVE.unit_id].rot-= 360;
  1728.            
  1729.             while (a - MOVE.unit->rot > 180) a -= 360;
  1730.             while (a - MOVE.unit->rot < -180)a += 360;
  1731.             float diff = a - MOVE.unit->rot;
  1732.            
  1733.             if (abs(diff) < 6) { //если мы достигли нужной точности. потом довернем
  1734.                 MOVE.unit->rot = a; //доворачивает перца на нужный угол
  1735.                 back_path_current--;
  1736.                 start_move(back_path_x[back_path_current],
  1737.                        back_path_y[back_path_current],
  1738.                        back_path_x[back_path_current-1],
  1739.                        back_path_y[back_path_current-1]);
  1740.                            
  1741.                 MAP[SELECTED_UNIT->mx][SELECTED_UNIT->my].unit = NULL;
  1742.                 SELECTED_UNIT->mx = back_path_x[back_path_current];
  1743.                 SELECTED_UNIT->my = back_path_y[back_path_current];
  1744.             } else { //rotate it
  1745.                 if (diff > 0)
  1746.                     MOVE.unit->rot += 5;
  1747.                 else
  1748.                     MOVE.unit->rot -= 5;
  1749.             }
  1750.         } else { // END
  1751.             MODE = MODE_SELECT;
  1752.             map_to_real(back_path_x[0], back_path_y[0], &(MOVE.unit->x), &(MOVE.unit->y));
  1753.             MOVE.unit->mx = back_path_x[0];
  1754.             MOVE.unit->my = back_path_y[0];
  1755.             MOVE.unit->frame = 98; //перейти к анимации ничегонеделания
  1756.             MAP[SELECTED_UNIT->mx][SELECTED_UNIT->my].unit = MOVE.unit;
  1757.             MOVE.unit = NULL; //никто больше не передвигается, так же?
  1758.             fill_map(&q, SELECTED_UNIT->my, SELECTED_UNIT->mx); //перезаполнить карту под новую позицию
  1759.         }
  1760.     }
  1761. }
  1762.  
  1763.  
  1764. //TODO
  1765. void
  1766. atack_logic()
  1767. {
  1768.     float a1 = get_rot_angle( FIGHT.u1->mx, FIGHT.u1->my,
  1769.             FIGHT.u2->mx, FIGHT.u2->my);
  1770.     float a2 = a1 - 180; //второго солдата надо повернуть наоборот
  1771.    
  1772.     while (a1 - FIGHT.u1->rot > 180) a1 -= 360;
  1773.     while (a1 - FIGHT.u1->rot < -180)a1 += 360;
  1774.     float diff1 = a1 - FIGHT.u1->rot;
  1775.    
  1776.     while (a2 - FIGHT.u2->rot > 180) a2 -= 360;
  1777.     while (a2 - FIGHT.u2->rot < -180)a2 += 360;
  1778.     float diff2 = a2 - FIGHT.u2->rot;
  1779.    
  1780.     if (abs(diff1) > 6) {
  1781.         if (diff1 > 0)
  1782.             FIGHT.u1->rot += 5;
  1783.         else
  1784.             FIGHT.u1->rot -= 5;
  1785.     }
  1786.     if (abs(diff2) > 6) {
  1787.         if (diff2 > 0)
  1788.             FIGHT.u2->rot += 5;
  1789.         else
  1790.             FIGHT.u2->rot -= 5;
  1791.     }
  1792.    
  1793.     if (abs(diff1) < 6 && abs(diff2) < 6) {
  1794.         if (FIGHT.u1->frame < 25 || FIGHT.u1->frame > 48)
  1795.             FIGHT.u1->frame = 25;
  1796.            
  1797.         if (FIGHT.u2->health > 4) { //выдержит он удар или нет
  1798.             //если выдержит - играть анимацию защиты.
  1799.             if (FIGHT.u2->frame < 48 || FIGHT.u2->frame > 72)
  1800.                 FIGHT.u2->frame = 48;
  1801.         } else {
  1802.             // если не выдержит - играть анимацию смерти
  1803.             if (FIGHT.u2->frame < 72 || FIGHT.u2->frame > 96)
  1804.                 FIGHT.u2->frame = 72;
  1805.         }
  1806.        
  1807.         // если был сыгран последний кадр. ТО...
  1808.         if (FIGHT.u1->frame == 48) {
  1809.             MODE = MODE_SELECT;
  1810.             FIGHT.u1->frame = 97; // вернуть к анимации ничегонеделания
  1811.            
  1812.             if(FIGHT.u2->health > 4){
  1813.                 FIGHT.u2->health -= 4;
  1814.                 FIGHT.u2->frame = 97;
  1815.             }else{
  1816.                 unit* tmp = UNITS;
  1817.                 if(tmp == FIGHT.u2) //если надо удалить первый элемент списка
  1818.                     UNITS = UNITS->next; //то меняем указатель на начало списка
  1819.                 else
  1820.                 {
  1821.                     while(tmp->next != FIGHT.u2)
  1822.                         tmp = tmp->next;
  1823.                     tmp->next = FIGHT.u2->next;
  1824.                 }
  1825.                 MAP[FIGHT.u2->mx][FIGHT.u2->my].unit = NULL;
  1826.                 free(FIGHT.u2);
  1827.             }
  1828.         }
  1829.     }
  1830. }
  1831.  
  1832.  
  1833.  
  1834.  
  1835. bool
  1836. add_button(int x, int y, int W, int H, char* name, char *text)
  1837. {
  1838.     unsigned textureID;
  1839.     int w, h;
  1840.     textureID = generate_texture_from_str(text, &w, &h);
  1841.    
  1842.     if (textureID == 0)
  1843.         exit(1);
  1844.        
  1845.     gui_button b = {name, x, y, W, H, w, h, textureID, text};
  1846.    
  1847.     BUTTONS[BUTTONS_COUNT] = b;
  1848.     BUTTONS_COUNT++;
  1849.    
  1850.     return(true);
  1851. }
  1852.  
  1853.  
  1854.  
  1855. void
  1856. draw_button_for_picking(gui_button b)
  1857. {
  1858.     glPushMatrix();
  1859.     {
  1860.         glTranslatef(b.x, b.y, 0);
  1861.         glBegin(GL_QUADS);
  1862.         {
  1863.             glVertex3d(0, 0, 0);
  1864.             glVertex3d(b.sx, 0, 0);
  1865.             glVertex3d(b.sx, b.sy, 0);
  1866.             glVertex3d(0, b.sy, 0);
  1867.         }
  1868.         glEnd();
  1869.     }
  1870.     glPopMatrix();
  1871. }
  1872.  
  1873.  
  1874.  
  1875. void
  1876. draw_button(gui_button b)
  1877. {
  1878.     glPushMatrix();
  1879.     {
  1880.         glTranslatef(b.x, b.y, 0);
  1881.        
  1882.         glColor4f(0.3, 0.3, 0.3, 0.8);
  1883.         glBegin(GL_QUADS);
  1884.         {
  1885.             glVertex3d(0, 0, 0);
  1886.             glVertex3d(b.sx, 0, 0);
  1887.             glVertex3d(b.sx, b.sy, 0);
  1888.             glVertex3d(0, b.sy, 0);
  1889.         }
  1890.         glEnd();
  1891.        
  1892.         glColor4f(1, 1, 1, 0.8);
  1893.         //glScalef(0.3, 0.3, 0.3);
  1894.        
  1895.         //RENDER TEXT
  1896.         {
  1897.             glEnable(GL_TEXTURE_2D);
  1898.             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1899.             glBindTexture(GL_TEXTURE_2D, b.textureID);
  1900.            
  1901.             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1902.             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1903.            
  1904.             glBegin(GL_QUADS);
  1905.             {
  1906.                 glTexCoord2d(0, 0);
  1907.                 glVertex2d(0, 0);
  1908.                 glTexCoord2d(1, 0);
  1909.                 glVertex2d(b.textSX, 0);
  1910.                 glTexCoord2d(1, 1);
  1911.                 glVertex2d(b.textSX, b.textSY);
  1912.                 glTexCoord2d(0, 1);
  1913.                 glVertex2d(0, b.textSY);
  1914.             }
  1915.             glEnd();
  1916.            
  1917.             glDisable(GL_TEXTURE_2D);
  1918.         }
  1919.     }
  1920.     glPopMatrix();
  1921. }
  1922.  
  1923.  
  1924.  
  1925. void
  1926. draw_interface()
  1927. {
  1928.     glDisable(GL_DEPTH_TEST);
  1929.     glEnable(GL_BLEND);
  1930.    
  1931.     glMatrixMode(GL_PROJECTION);
  1932.     glPushMatrix();
  1933.     glLoadIdentity();
  1934.     glOrtho(0, SCR_WIDTH, SCR_HEIGHT, 0, 0, 1);
  1935.    
  1936.     glMatrixMode(GL_MODELVIEW);
  1937.     glPushMatrix();
  1938.     {
  1939.         glLoadIdentity();
  1940.        
  1941.         int i;
  1942.         for (i = 0; i < BUTTONS_COUNT; i++)
  1943.             draw_button(BUTTONS[i]);
  1944.     }
  1945.     glPopMatrix();
  1946.    
  1947.     glMatrixMode(GL_PROJECTION);
  1948.     glPopMatrix();
  1949.    
  1950.     glMatrixMode(GL_MODELVIEW);
  1951.    
  1952.     glDisable(GL_BLEND);
  1953.     glEnable(GL_DEPTH_TEST);
  1954. }
  1955.  
  1956.  
  1957.  
  1958. void
  1959. draw_interface_for_picking()
  1960. {
  1961.     glDisable(GL_DEPTH_TEST);
  1962.    
  1963.     glMatrixMode(GL_PROJECTION);
  1964.     glPushMatrix();
  1965.     glLoadIdentity();
  1966.     glOrtho(0, SCR_WIDTH, SCR_HEIGHT, 0, 0, 1);
  1967.    
  1968.     glMatrixMode(GL_MODELVIEW);
  1969.     glPushMatrix();
  1970.     {
  1971.         glLoadIdentity();
  1972.        
  1973.         int i;
  1974.         for (i = 0; i <BUTTONS_COUNT; i++) {
  1975.             glColor3ub(0, 0, i+2);
  1976.             draw_button_for_picking(BUTTONS[i]);
  1977.         }
  1978.     }
  1979.     glPopMatrix();
  1980.    
  1981.     glMatrixMode(GL_PROJECTION);
  1982.     glPopMatrix();
  1983.    
  1984.     glMatrixMode(GL_MODELVIEW);
  1985.    
  1986.     glEnable(GL_DEPTH_TEST);
  1987. }
  1988.  
  1989.  
  1990.  
  1991. void
  1992. init_interface()
  1993. {
  1994.     if (TTF_Init() == -1) {
  1995.         printf("Unable to initialize SDL_ttf: %s \n", TTF_GetError());
  1996.         exit(1);
  1997.     }
  1998.     //font = TTF_OpenFont("font.ttf", 24);
  1999.     font = TTF_OpenFont("font.ttf", 18);
  2000.     if (font == NULL) {
  2001.         printf("Unable to initialize font: %s \n", TTF_GetError());
  2002.         exit(1);
  2003.     }
  2004.    
  2005.    
  2006.     add_button(0, 0, 80, 25, "player identifier", "красный");
  2007.     add_button(300, 300, 80, 25, "test button 1", "butt 1");
  2008.     add_button(350, 350, 80, 25, "test button 2", "butt 2");
  2009. }
  2010.  
  2011.  
  2012.  
  2013. void
  2014. init_textures()
  2015. {
  2016.     texture = load_texture("CUBE_WARRIOR.bmp");
  2017.    
  2018.     sky_texture[1] = load_texture("sky1.bmp");
  2019.     sky_texture[2] = load_texture("sky2.bmp");
  2020.     sky_texture[3] = load_texture("sky3.bmp");
  2021.     sky_texture[4] = load_texture("sky4.bmp");
  2022. }
  2023.  
  2024.  
  2025.  
  2026. void
  2027. init_models()
  2028. {
  2029.     int i;
  2030.     for (i = 0; i < 121; i++) {
  2031.         char obj_file_name[100];
  2032.         sprintf(obj_file_name, "test3/CUBE_WARRIOR_000%03i.obj", i+1);
  2033.         mdl[i] = read_obj_file(obj_file_name);
  2034.     }
  2035. }
  2036.  
  2037.  
  2038.  
  2039. void
  2040. camera_logic()
  2041. {
  2042.     float lastx = CAMERA.x; //запомним последние координаты.
  2043.     float lasty = CAMERA.y; //есл ивыходим за границы - откатимся на них.
  2044.    
  2045.     // насколько близко к краям экрана надо придвинутьr
  2046.     // мышу, что бы началось перемещение
  2047.     int border = 30;
  2048.    
  2049.     if (cursorY < border) { // наверху. двигаемся вперед
  2050.         CAMERA.x -= sinf(CAMERA.horiz_angle*M_PI/180.0f)*0.1;
  2051.         CAMERA.y -= cosf(CAMERA.horiz_angle*M_PI/180.0f)*0.1;
  2052.     } else if (cursorY > SCR_HEIGHT - border) { //курсор снизу. двигаемся назад.
  2053.         CAMERA.x += sinf(CAMERA.horiz_angle*M_PI/180.0f)*0.1;
  2054.         CAMERA.y += cosf(CAMERA.horiz_angle*M_PI/180.0f)*0.1;
  2055.     }
  2056.    
  2057.     if (cursorX < border) { //лево.
  2058.         CAMERA.x += sinf((CAMERA.horiz_angle+90.0)*M_PI/180.0)*0.1;
  2059.         CAMERA.y += cosf((CAMERA.horiz_angle+90.0)*M_PI/180.0)*0.1;
  2060.     } else if (cursorX > SCR_WIDTH - border) { //право.
  2061.         CAMERA.x -= sinf((CAMERA.horiz_angle+90.0)*M_PI/180.0)*0.1;
  2062.         CAMERA.y -= cosf((CAMERA.horiz_angle+90.0)*M_PI/180.0)*0.1;
  2063.     }
  2064.    
  2065.     //проверка границ + откаты на предыдущие позиции
  2066.     if (CAMERA.x > 0) CAMERA.x = lastx;
  2067.     if (CAMERA.y > 0) CAMERA.y = lasty;
  2068.     if (CAMERA.x < -2*HEX_IN*(MAP_SIZE_X-1)) CAMERA.x = lastx;
  2069.     if (CAMERA.y < -1.5*HEX_EX*(MAP_SIZE_Y-1)) CAMERA.y = lasty;
  2070. }
  2071.  
  2072.  
  2073.  
  2074. void
  2075. change_frames()
  2076. {
  2077.     unit* tmp = UNITS;
  2078.     while(tmp != NULL) {
  2079.         if (tmp != MOVE.unit) {
  2080.             //анимация ничегонеделания.
  2081.             if (tmp->frame++ == 120)
  2082.                 tmp->frame = 97;
  2083.         }
  2084.        
  2085.         if (tmp == MOVE.unit) {
  2086.             //анимация передвижения
  2087.             if (tmp->frame++ > 22)
  2088.                 tmp->frame = 1;
  2089.         }
  2090.         tmp = tmp->next;
  2091.     }
  2092. }
  2093.  
  2094.  
  2095.  
  2096. #undef main //write straight to the cosole
  2097.  
  2098. int
  2099. main(void)
  2100. {
  2101.     SDL_Event E;
  2102.     Uint32 next_time;
  2103.    
  2104.     srand(time(0));
  2105.    
  2106.     init_sdl();
  2107.     init_opengl();
  2108.     init_q(&q, 66000);
  2109.     init_models();
  2110.     init_textures();
  2111.     init_interface();
  2112.     generate_hex();
  2113.     init_map(); //generate map and units information
  2114.    
  2115.    
  2116.     //puts(glGetString(GL_VERSION));
  2117.    
  2118.     GQO = gluNewQuadric();
  2119.     MOVE.unit = NULL;
  2120.    
  2121.     //printf("%i\n", __LINE__);
  2122.    
  2123.     next_time = SDL_GetTicks() + 300;
  2124.     while (isProgramLooping) {
  2125.         //HANDLE EVENTS
  2126.         {
  2127.             while (SDL_PollEvent(&E))
  2128.                 hanlde_events(E);
  2129.         }
  2130.        
  2131.         //PICK
  2132.         {
  2133.             draw_for_picking();
  2134.             draw_interface_for_picking();
  2135.             do_picking();
  2136.         }
  2137.        
  2138.         //DRAW
  2139.         {
  2140.             draw();
  2141.             draw_interface();
  2142.             SDL_GL_SwapBuffers();
  2143.         }
  2144.        
  2145.         //LOGIC
  2146.         {
  2147.             if (MODE == MODE_MOVE)
  2148.                 move_logic();
  2149.             if (MODE == MODE_FIGHT)
  2150.                 atack_logic();
  2151.                
  2152.             camera_logic();
  2153.         }
  2154.        
  2155.         // TIME/FPS/animation changes...
  2156.         {
  2157.             //SDL_Delay(50);
  2158. #if(0)
  2159.             if (next_time > SDL_GetTicks())
  2160.                 SDL_Delay(next_time - SDL_GetTicks());
  2161.             else
  2162.                 next_time += 20; //SHIT
  2163.             next_time += 20;
  2164. #endif
  2165.             if (MODE != MODE_PAUSE) change_frames();
  2166.         }
  2167.     }
  2168.    
  2169.     return(0);
  2170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement