completely changed event_queue logic
[h2d.git] / draw.c
blob9795f1ae6b3d9cd3cc59d1e258ba3a0f9bb84254
3 // просто рисует пиксель
4 void pxl32(int x, int y, Uint32 pixel) {
5 if( x<0 || y<0 || x >= screen->w || y >= screen->h )
6 return;
7 Uint32 * pixels = (Uint32 *)screen->pixels;
8 pixels[ (y * screen->w) + x ] = pixel;
12 // рисует "большой"(size) пиксель
13 void bigpxl(Uint32 colr, int size, int x, int y){
14 SDL_Rect rect = {x, y, size, size};
15 SDL_FillRect(screen, &rect, colr);
20 #define bzpxl(x,y,clr) \
21 if(!steep) pxl32(x,y,clr); else pxl32(y,x,clr);
22 #define swap(a,b) { int tmp; tmp=a; a=b; b=tmp; }
24 void bzline (scrd a, scrd b, Uint32 clr){
25 bool steep = abs(b.y-a.y) > abs(b.x-a.x);
26 if(steep) { swap(a.x,a.y); swap(b.x,b.y); }
27 if(a.x>b.x) { swap(a.x,b.x); swap(a.y,b.y); }
28 int deltax = b.x-a.x;
29 int deltay = abs(b.y-a.y);
30 int error = deltax >> 1;
31 int y = a.y, ystep = (a.y<b.y) ? 1 : -1;
32 for (int x = a.x; x <= b.x; x++) {
33 bzpxl(x,y,clr);
34 error -= deltay;
35 if(error<0){ y+=ystep; error+=deltax; }
41 void blit(SDL_Surface *src, int x, int y) {
42 SDL_Rect rect = {x, y, 0, 0};
43 SDL_BlitSurface(src, NULL, screen, &rect);
48 void mblit(SDL_Surface *src, mcrd crd) {
49 blit(src, crd.x, crd.y);
54 void draw_map() {
55 FOR_EACH_TILE{
56 mblit(terrsrf[ mp(mc)->type ], map2scr(mc));
57 if(mp(mc)->fog<=0) mblit(hl3, map2scr(mc));
63 // TODO rename: mconnect? m2mline?
64 // draw line between 2 tiles
65 void mline(mcrd a, mcrd b){
66 scrd sa = map2scr(a), sb = map2scr(b);
67 sa.x+=36; sa.y+=54; sb.x+=36; sb.y+=54;
68 //unit * u = cw->selunit ? cw->selunit : cw->move_unit;
69 //if(!u)
70 //return;
71 //if(mp(a)->cost <= u->mvp)
72 //bzline(sa, sb, BLUE);
73 //else
74 bzline(sa, sb, RED);
79 // draw current path
80 void draw_path() {
81 if(cw->path->count>0){
82 mnode * tile = (mnode*)l_first(cw->path);
83 while(l_next(tile)){
84 if(l_next(tile)){
85 mcrd a = tile->crd;
86 mcrd b = ((mnode*)l_next(tile))->crd;
87 mline(a,b);
89 tile = (mnode*)l_next(tile);
96 // draw path to some point
97 void draw_path_2_mcrd(mcrd a){
98 if(mp(a)->cost==30000) return;
99 mcrd tmp = a;
100 while( ! mcrdeq(tmp,cw->selunit->mcrd) ){
101 mline(tmp, mp(tmp)->parent);
102 tmp = mp(tmp)->parent;
108 void draw_bg(Uint32 clr){ SDL_FillRect(screen,NULL,clr); }
112 void text(char * str, scrd crd, bool iscentred){
113 SDL_Color col = {0xFF, 0xFF, 0xFF, 0xFF};
114 SDL_Surface * s = TTF_RenderText_Blended(font, str, col);
116 SDL_Rect rect;
117 if(iscentred)
118 rect = (SDL_Rect){crd.x-s->w/2, crd.y-s->h/2, 0,0};
119 else
120 rect = (SDL_Rect){crd.x, crd.y, 0,0};
122 SDL_BlitSurface(s, NULL, screen, &rect);
123 SDL_FreeSurface(s);
128 SDL_Surface * type2srf(unit_type * t){
129 if(t==&utypes[0]) return(sldr_wd);
130 else if(t==&utypes[1]) return(sldr_wh);
131 else if(t==&utypes[2]) return(sldr_wa);
132 else exit(1);
137 void draw_unit(unit *u){
138 scrd s = map2scr(u->mcrd);
139 if(u->player==0) mblit(hl5, s);
140 if(u->player==1) mblit(hl6, s);
141 mblit(type2srf(u->type), s);
143 if(1){
144 char str[100];
145 sprintf(str, "%i", u->health);
146 text(str, (scrd){s.x+10, s.y+60}, false);
152 void draw_units(){
153 FOR_EACH_UNIT{
154 if(cw->mode==MODE_ATTACK
155 && cw->e[1]==EVENT_MELEE
156 && cw->e[2]==u->id)
157 continue;
159 if(cw->mode==MODE_MOVE
160 && cw->e[1]==EVENT_MOVE
161 && cw->e[2]==u->id)
162 continue;
164 if( u->player!=player
165 && (mp(u->mcrd)->fog==0 || is_invis(u)) )
166 continue;
168 draw_unit(u);
174 void draw_moving_unit(){
175 unit * u = id2unit(cw->e[2]);
176 mcrd a = u->mcrd;
177 mcrd b = neib(u->mcrd, cw->e[cw->mi+1]);
178 scrd crd = mbetween(a, b, cw->index);
179 mblit(type2srf(u->type), crd);
184 void draw_attacking_unit(){
185 mcrd a = id2unit(cw->e[2])->mcrd;
186 mcrd b = neib(a, cw->e[3]);
187 int i = (cw->index<STEPS/2) ? (cw->index) : (STEPS-cw->index);
188 scrd crd = mbetween(a, b, i);
189 mblit(type2srf(id2unit(cw->e[2])->type), crd);
193 void draw_possible_tiles(){
194 FOR_EACH_TILE{
195 mcrd p = mp(mc)->parent;
196 if(!(p.x==0 && p.y==0)
197 && mp(mc)->cost <= cw->selunit->mvp) {
198 mblit(hl1, map2scr(mc));
199 mline(mc, p);
206 void maptext(){
207 FOR_EACH_TILE{
208 if(mp(mc)->cost!=30000 && mp(mc)->cost!=0){
209 scrd s = map2scr(mc);
210 s.x+=36; s.y+=54;
211 char str[100];
212 sprintf(str, "%i", mp(mc)->cost);
213 text(str, s, true);
220 void draw_shoot_attack(){
221 unit * u1 = id2unit(cw->e[2]);
222 unit * u2 = id2unit(cw->e[3]);
223 scrd a = u1->scrd;
224 scrd b = u2->scrd;
225 int steps = sdist(a,b)/6;
226 float dx = (float)(b.x-a.x)/steps;
227 float dy = (float)(b.y-a.y)/steps;
229 a.x += dx * cw->index;
230 a.y += dy * cw->index;
232 // вертикальная поправка
233 //int dh = 36 * sinf((float)cw->index/steps*3.14);
234 int dh = 26 * sinf((float)cw->index/steps*3.14);
235 blit(arrow, a.x, a.y-dh);
237 // рисует "хвост" стрелы. через задницу!
238 for(int i=1; i<cw->index; i++){
239 // вертикальная поправка
240 int d0 = 36 * sinf((float)(i )/steps*3.14);
241 int d1 = 36 * sinf((float)(i-1)/steps*3.14);
243 scrd n0 = u1->scrd;
244 scrd n1 = u1->scrd;
245 n0.x += 36+ dx*(i ); n0.y += 36+ dy*(i )-d0;
246 n1.x += 36+ dx*(i-1); n1.y += 36+ dy*(i-1)-d1;
248 bzline(n0, n1, RED);
254 void draw(){
255 draw_bg(BLACK);
257 // TODO нужно вызывать не отсюда. смотри NOTES
258 updatefog(player);
260 draw_map();
261 if(cw->mode==MODE_SELECT && cw->selunit)
262 draw_possible_tiles();
263 mblit(sel, map2scr(cw->selhex));
264 if(cw->selunit) mblit(sel, map2scr(cw->selunit->mcrd));
265 draw_units();
266 if(cw->mode==MODE_MOVE){ draw_moving_unit(); /*draw_path();*/ }
267 if(cw->mode==MODE_ATTACK){
268 if(cw->e[1]==EVENT_MELEE) draw_attacking_unit();
269 if(cw->e[1]==EVENT_RANGE) draw_shoot_attack();
271 //maptext();
272 text( (player==0)?"[pl:0]":"[pl:1]", (scrd){0,0}, false);
274 SDL_Flip(screen);