original 1.0.1 release
[xwelltris.git] / src / x11 / xwelldrawing.cxx
blob30ecae4b26733f7e5f595770fb2833e402bf1596
1 // docm_prefix(///)
2 /****************************************************************************
3 * Copyright (C) 2002 by Leo Khramov
4 * email: leo@xnc.dubna.su
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 ****************************************************************************/
16 // $Id: xwelldrawing.cxx,v 1.1.1.1 2003/01/04 11:37:22 leo Exp $
18 /// module description
19 /// X11 implementation of WellDrawing class - drawing routines for the game.
20 /// Draw field on pixmap, then maps it to the screen. Uses dirty rectangles
21 /// algorithm for mapping areas to screen from pixmap
23 #include "xwelldrawing.h"
24 #include "xwellengine.h"
26 //===========================================================================
27 /// global XWellDrawingEngine()
28 /// constructor of the class - init's variables.
29 /// tags XWellDrawingEngine
30 XWellDrawingEngine::XWellDrawingEngine(XWellEngine* myengine)
32 xengine=myengine;
33 if(xengine==0)
34 xengine=static_cast<XWellEngine*>(default_well_engine);
35 mainw=xengine->get_main_window();
36 colors=xengine->get_colors();
37 scr=DefaultScreen(disp);
40 //===========================================================================
41 /// global init(int n_fields, int idx, int idy, unsigned il, unsigned ih)
42 /// init fields - creates x pixmaps and gcs
43 /// tags XWellDrawingEngine
44 void XWellDrawingEngine::init(int inum_fields, int idx, int idy,
45 unsigned int il, unsigned int ih)
47 int i;
48 WellDrawingEngine::init(inum_fields,idx,idy,il,ih);
49 fields=new Pixmap;
50 gcs=new GC;
51 maingc=XCreateGC(disp,mainw,0,0);
52 XSetBackground(disp,maingc,colors[BackColor]);
53 XSetForeground(disp,maingc,colors[GridColor]);
54 XSetGraphicsExposures(disp,maingc,False);
56 for(i=0;i<1;i++)
58 fields[i]=XCreatePixmap(disp,mainw,l,h,DefaultDepth(disp,scr));
59 if(fields[i]>0)
61 gcs[i]=XCreateGC(disp,fields[i],0,0);
62 XSetBackground(disp,gcs[i],colors[FreezeColor]);
63 clear_field(i);
68 //===========================================================================
69 /// global draw_square(int color_idx, int i, int j)
70 /// Draw square (floor polygon) on all fields with given color
71 /// tags XWellDrawingEngine
72 void XWellDrawingEngine::draw_square(int color, int i, int j)
74 int idx=current_id,sign_x13,sign_y13,sign_x24,sign_y24;
76 XSetForeground(disp,*gcs,colors[color]);
78 sign_x13= points[idx].base_points[i+1][j+1].x -
79 points[idx].base_points[i][j].x;
80 sign_x13= sign_x13 ? (sign_x13>0 ? 1 : -1) : 0;
82 sign_y13= points[idx].base_points[i+1][j+1].y -
83 points[idx].base_points[i][j].y;
84 sign_y13= sign_y13 ? (sign_y13>0 ? 1 : -1) : 0;
86 sign_x24= points[idx].base_points[i][j+1].x -
87 points[idx].base_points[i+1][j].x;
88 sign_x24= sign_x24 ? (sign_x24>0 ? 1 : -1) : 0;
90 sign_y24= points[idx].base_points[i][j+1].y -
91 points[idx].base_points[i+1][j].y;
92 sign_y24= sign_y24 ? (sign_y24>0 ? 1 : -1) : 0;
94 trapazoid_list[0].x = points[idx].base_points[i][j].x+sign_x13;
95 trapazoid_list[0].y = points[idx].base_points[i][j].y+sign_y13;
96 trapazoid_list[1].x = points[idx].base_points[i+1][j].x+sign_x24;
97 trapazoid_list[1].y = points[idx].base_points[i+1][j].y+sign_y24;
98 trapazoid_list[2].x = points[idx].base_points[i+1][j+1].x-sign_x13;
99 trapazoid_list[2].y = points[idx].base_points[i+1][j+1].y-sign_y13;
100 trapazoid_list[3].x = points[idx].base_points[i][j+1].x-sign_x24;
101 trapazoid_list[3].y = points[idx].base_points[i][j+1].y-sign_y24;
102 XFillPolygon (disp, *fields, *gcs, trapazoid_list, MAX_SIDES,
103 Convex, CoordModeOrigin);
104 //Now draw the grid
105 trapazoid_list[0].x = points[idx].base_points[i][j].x;
106 trapazoid_list[0].y = points[idx].base_points[i][j].y;
107 trapazoid_list[1].x = points[idx].base_points[i+1][j].x;
108 trapazoid_list[1].y = points[idx].base_points[i+1][j].y;
109 trapazoid_list[2].x = points[idx].base_points[i+1][j+1].x;
110 trapazoid_list[2].y = points[idx].base_points[i+1][j+1].y;
111 trapazoid_list[3].x = points[idx].base_points[i][j+1].x;
112 trapazoid_list[3].y = points[idx].base_points[i][j+1].y;
113 XSetForeground(disp,*gcs,colors[GridColor2]);
114 XDrawLines(disp, *fields, *gcs, trapazoid_list, MAX_SIDES, CoordModeOrigin);
116 new_dirty_rec(delta_x,delta_y);
117 dirty_add_xy(trapazoid_list[0].x,trapazoid_list[0].y);
118 dirty_add_xy(trapazoid_list[1].x,trapazoid_list[1].y);
119 dirty_add_xy(trapazoid_list[2].x,trapazoid_list[2].y);
120 dirty_add_xy(trapazoid_list[3].x,trapazoid_list[3].y);
121 finish_dirty_rec();
124 //===========================================================================
125 /// global draw_trapazoid(int color_idx, int i,int j)
126 /// draw trapazoid - wall polygon with given color
127 /// tags XWellDrawingEngine
128 void XWellDrawingEngine::draw_trapazoid(int color, int i, int j)
130 Window win;
131 GC gc;
132 int idx=current_id,w,sign_x13,sign_y13,sign_x24,sign_y24;
134 unsigned long rcolor=colors[color];
136 win=*fields;
137 gc=*gcs;
138 XSetForeground(disp,gc,rcolor);
140 sign_x13= points[idx].wall_points[i+1][j+1].x -
141 points[idx].wall_points[i][j].x;
142 sign_x13= sign_x13 ? (sign_x13>0 ? 1 : -1) : 0;
144 sign_y13= points[idx].wall_points[i+1][j+1].y -
145 points[idx].wall_points[i][j].y;
146 sign_y13= sign_y13 ? (sign_y13>0 ? 1 : -1) : 0;
148 sign_x24= points[idx].wall_points[i][j+1].x -
149 points[idx].wall_points[i+1][j].x;
150 sign_x24= sign_x24 ? (sign_x24>0 ? 1 : -1) : 0;
152 sign_y24= points[idx].wall_points[i][j+1].y -
153 points[idx].wall_points[i+1][j].y;
154 sign_y24= sign_y24 ? (sign_y24>0 ? 1 : -1) : 0;
157 w=i/MAX_WIDTH;
158 dbgprintf(("trapazoid [%2d][%2d] = [%d - %d],[%d - %d]\n",i,j,
159 points[idx].wall_points[i+1][j+1].x,
160 points[idx].wall_points[i][j].x,
161 points[idx].wall_points[i+1][j+1].y,
162 points[idx].wall_points[i][j].y));
164 dbgprintf(("trapazoid2[%2d][%2d] = [%d - %d],[%d - %d]\n",i,j,
165 points[idx].wall_points[i][j+1].x,
166 points[idx].wall_points[i+1][j].x,
167 points[idx].wall_points[i][j+1].y,
168 points[idx].wall_points[i+1][j].y));
169 dbgprintf(("trapazoid [%2d][%2d] = [%d][%d],[%d][%d]\n",i,j,
170 sign_x13,sign_y13,sign_x24,sign_y24));
174 trapazoid_list[0].x = points[idx].wall_points[i][j].x+sign_x13;
175 trapazoid_list[0].y = points[idx].wall_points[i][j].y+sign_y13;
176 trapazoid_list[1].x = points[idx].wall_points[i+1][j].x+sign_x24;
177 trapazoid_list[1].y = points[idx].wall_points[i+1][j].y+sign_y24;
178 trapazoid_list[2].x = points[idx].wall_points[i+1][j+1].x-sign_x13;
179 trapazoid_list[2].y = points[idx].wall_points[i+1][j+1].y-sign_y13;
180 trapazoid_list[3].x = points[idx].wall_points[i][j+1].x-sign_x24;
181 trapazoid_list[3].y = points[idx].wall_points[i][j+1].y-sign_y24;
182 XFillPolygon (disp, win, gc, trapazoid_list, MAX_SIDES,
183 Convex, CoordModeOrigin);
184 //Now draw the grid
185 trapazoid_list[0].x = points[idx].wall_points[i][j].x;
186 trapazoid_list[0].y = points[idx].wall_points[i][j].y;
187 trapazoid_list[1].x = points[idx].wall_points[i+1][j].x;
188 trapazoid_list[1].y = points[idx].wall_points[i+1][j].y;
189 trapazoid_list[2].x = points[idx].wall_points[i+1][j+1].x;
190 trapazoid_list[2].y = points[idx].wall_points[i+1][j+1].y;
191 trapazoid_list[3].x = points[idx].wall_points[i][j+1].x;
192 trapazoid_list[3].y = points[idx].wall_points[i][j+1].y;
193 XSetForeground(disp,gc,colors[GridColor]);
194 XDrawLines(disp, win, gc, trapazoid_list, MAX_SIDES, CoordModeOrigin);
195 if(idx==current_id)
197 new_dirty_rec(delta_x,delta_y);
198 dirty_add_xy(trapazoid_list[0].x,trapazoid_list[0].y);
199 dirty_add_xy(trapazoid_list[1].x,trapazoid_list[1].y);
200 dirty_add_xy(trapazoid_list[2].x,trapazoid_list[2].y);
201 dirty_add_xy(trapazoid_list[3].x,trapazoid_list[3].y);
202 finish_dirty_rec();
206 //===========================================================================
207 /// global draw_grid()
208 /// draw grid - all wall and floor polygons
209 /// tags XWellDrawingEngine
210 void XWellDrawingEngine::draw_grid()
212 int idx,i,j,k;
213 Window win;
214 GC gc;
215 idx=current_id;
217 gc=*gcs;
218 win=*fields;
219 XSetForeground(disp,gc,colors[GridColor]);
220 for(i=0;i<MAX_PERIMETER;i++)
221 for(j=0;j<MAX_DEPTH;j++)
223 XDrawLine(disp,win,gc,points[idx].wall_points[i][j].x,
224 points[idx].wall_points[i][j].y,
225 points[idx].wall_points[i][j+1].x,
226 points[idx].wall_points[i][j+1].y);
227 XDrawLine(disp,win,gc,points[idx].wall_points[i][j].x,
228 points[idx].wall_points[i][j].y,
229 points[idx].wall_points[i+1][j].x,
230 points[idx].wall_points[i+1][j].y);
232 for(i=0;i<MAX_WIDTH+1;i++)
233 for(j=0;j<MAX_WIDTH+1;j++)
235 if(j==0 || j==MAX_WIDTH)
236 XSetForeground(disp,gc,colors[GridColor2]);
237 else
238 XSetForeground(disp,gc,colors[GridColor]);
240 if(i<MAX_WIDTH)
241 XDrawLine(disp,win,gc,points[idx].base_points[i][j].x,
242 points[idx].base_points[i][j].y,
243 points[idx].base_points[i+1][j].x,
244 points[idx].base_points[i+1][j].y);
246 if(i==0 || i==MAX_WIDTH)
247 XSetForeground(disp,gc,colors[GridColor2]);
248 else
249 XSetForeground(disp,gc,colors[GridColor]);
251 if(j<MAX_WIDTH)
252 XDrawLine(disp,win,gc,points[idx].base_points[i][j].x,
253 points[idx].base_points[i][j].y,
254 points[idx].base_points[i][j+1].x,
255 points[idx].base_points[i][j+1].y);
259 //===========================================================================
260 /// global clear_field(int i)
261 /// clear field with given index with BackColor (black)
262 /// tags XWellDrawingEngine
263 void XWellDrawingEngine::clear_field(int)
265 XSetForeground(disp,*gcs,colors[BackColor]);
266 XFillRectangle(disp,*fields,*gcs,0,0,l,h);
269 //===========================================================================
270 /// global flush_all()
271 /// copy all the field with current_id to the screen
272 /// tags XWellDrawingEngine
273 void XWellDrawingEngine::flush_all()
275 XCopyArea(disp,*fields,mainw,maingc,0,0,l,h,delta_x,delta_y);
276 sync();
279 //===========================================================================
280 /// global sync()
281 /// flush event in X queue
282 /// tags XWellDrawingEngine
283 void XWellDrawingEngine::sync()
285 XFlush(disp);
288 //===========================================================================
289 /// global flush_dirty()
290 /// copy list of dirty rectangle areas to the screen
291 /// tags XWellDrawingEngine
292 void XWellDrawingEngine::flush_dirty()
294 DirtyList *plist;
296 Window win=*fields;
300 plist=dirty_list.get_next();
301 if(plist)
303 DirtyRect& drec=plist->get_object();
304 //Here we need to draw dirty rec on the screen -> will be in overloaded childs
305 XCopyArea(disp,win,mainw,maingc,drec.get_src_x(),drec.get_src_y(),
306 drec.l,drec.h,
307 drec.get_dest_x(),drec.get_dest_y());
309 plist->del_self();
310 delete plist;
312 } while(plist);
313 XFlush(disp);
316 //===========================================================================
317 /// global key_to_action(void* event)
318 /// convert keys to actions in the game
319 /// tags XWellDrawingEngine
320 Actions XWellDrawingEngine::key_to_action(void* event)
322 XEvent *ev=(XEvent*)event;
323 KeySym ks;
325 ks=XLookupKeysym(&ev->xkey, 0);
326 switch(ks)
328 case XK_KP_Left:
329 case XK_KP_4:
330 case XK_Left:
331 case XK_j:
332 case XK_J:
333 return RIGHT;
335 case XK_KP_Right:
336 case XK_KP_6:
337 case XK_Right:
338 case XK_l:
339 case XK_L:
340 return LEFT;
342 case XK_Up:
343 case XK_Down:
344 case XK_KP_Begin:
345 case XK_KP_5:
346 case XK_k:
347 case XK_K:
348 return ROTATE;
350 case XK_space:
351 case XK_KP_0:
352 case XK_KP_Insert:
353 return DROP;
355 case XK_Pause:
356 case XK_p:
357 case XK_P:
358 return PAUSE_GAME;
360 case XK_F10:
361 case XK_q:
362 case XK_Q:
363 case XK_Escape:
364 return END_GAME;
366 case XK_KP_Multiply:
367 return OUTER_ROTATION;
369 case XK_KP_Add:
370 return LEVEL_UP;
372 case XK_KP_Subtract:
373 return LEVEL_DOWN;
377 return NOTHING;
381 //===========================================================================
382 /// global draw_line(...)
383 /// draw line with given coords and color
384 /// tags XWellDrawingEngine
385 void XWellDrawingEngine::draw_line(int x1, int y1, int x2, int y2, int color_idx,
386 Canvas where)
388 switch(where)
390 case screen:
391 XSetForeground(disp,maingc,colors[color_idx]);
392 XDrawLine(disp,mainw,maingc,x1,y1,x2,y2);
393 break;
394 case pixmap:
395 XSetForeground(disp,*gcs,colors[color_idx]);
396 XDrawLine(disp,*fields,*gcs,x1,y1,x2,y2);
397 break;
401 //===========================================================================
402 /// global draw_rect(...)
403 /// draw rectangle with given coords and color
404 /// tags XWellDrawingEngine
405 void XWellDrawingEngine::draw_rect(int x1, int y1,
406 unsigned int il,
407 unsigned int ih, int color_idx,
408 Canvas where)
410 switch(where)
412 case screen:
413 XSetForeground(disp,maingc,colors[color_idx]);
414 XDrawRectangle(disp,mainw,maingc,x1,y1,il,ih);
415 break;
416 case pixmap:
417 XSetForeground(disp,*gcs,colors[color_idx]);
418 XDrawRectangle(disp,*fields,*gcs,x1,y1,il,ih);
419 break;
423 //===========================================================================
424 /// global fill_rect(...)
425 /// fill rectangle with given coords and color
426 /// tags XWellDrawingEngine
427 void XWellDrawingEngine::fill_rect(int x1, int y1,
428 unsigned int il,
429 unsigned int ih, int color_idx,
430 Canvas where)
432 switch(where)
434 case screen:
435 XSetForeground(disp,maingc,colors[color_idx]);
436 XFillRectangle(disp,mainw,maingc,x1,y1,il,ih);
437 break;
438 case pixmap:
439 XSetForeground(disp,*gcs,colors[color_idx]);
440 XFillRectangle(disp,*fields,*gcs,x1,y1,il,ih);
441 break;
445 //===========================================================================
446 /// global pixmap_copy(Geo*)
447 /// copy part of image to the screen
448 /// tags XWellDrawingEngine
449 void XWellDrawingEngine::pixmap_copy(Geo *pgeo)
451 if(pgeo->im==imNone)
452 return;
453 XCopyArea(disp,xengine->get_pixmap_of_image(pgeo->im),*fields,*gcs,
454 pgeo->fromx,pgeo->fromy,pgeo->l,pgeo->h,
455 pgeo->tox,pgeo->toy);