2 /****************************************************************************
3 * Copyright (C) 2002 by Leo Khramov
4 * email: leo@xnc.dubna.su
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
)
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
)
48 WellDrawingEngine::init(inum_fields
,idx
,idy
,il
,ih
);
51 maingc
=XCreateGC(disp
,mainw
,0,0);
52 XSetBackground(disp
,maingc
,colors
[BackColor
]);
53 XSetForeground(disp
,maingc
,colors
[GridColor
]);
54 XSetGraphicsExposures(disp
,maingc
,False
);
58 fields
[i
]=XCreatePixmap(disp
,mainw
,l
,h
,DefaultDepth(disp
,scr
));
61 gcs
[i
]=XCreateGC(disp
,fields
[i
],0,0);
62 XSetBackground(disp
,gcs
[i
],colors
[FreezeColor
]);
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
);
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
);
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
)
132 int idx
=current_id
,w
,sign_x13
,sign_y13
,sign_x24
,sign_y24
;
134 unsigned long rcolor
=colors
[color
];
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;
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
);
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
);
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
);
206 //===========================================================================
207 /// global draw_grid()
208 /// draw grid - all wall and floor polygons
209 /// tags XWellDrawingEngine
210 void XWellDrawingEngine::draw_grid()
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
]);
238 XSetForeground(disp
,gc
,colors
[GridColor
]);
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
]);
249 XSetForeground(disp
,gc
,colors
[GridColor
]);
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
);
279 //===========================================================================
281 /// flush event in X queue
282 /// tags XWellDrawingEngine
283 void XWellDrawingEngine::sync()
288 //===========================================================================
289 /// global flush_dirty()
290 /// copy list of dirty rectangle areas to the screen
291 /// tags XWellDrawingEngine
292 void XWellDrawingEngine::flush_dirty()
300 plist
=dirty_list
.get_next();
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(),
307 drec
.get_dest_x(),drec
.get_dest_y());
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
;
325 ks
=XLookupKeysym(&ev
->xkey
, 0);
367 return OUTER_ROTATION
;
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
,
391 XSetForeground(disp
,maingc
,colors
[color_idx
]);
392 XDrawLine(disp
,mainw
,maingc
,x1
,y1
,x2
,y2
);
395 XSetForeground(disp
,*gcs
,colors
[color_idx
]);
396 XDrawLine(disp
,*fields
,*gcs
,x1
,y1
,x2
,y2
);
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
,
407 unsigned int ih
, int color_idx
,
413 XSetForeground(disp
,maingc
,colors
[color_idx
]);
414 XDrawRectangle(disp
,mainw
,maingc
,x1
,y1
,il
,ih
);
417 XSetForeground(disp
,*gcs
,colors
[color_idx
]);
418 XDrawRectangle(disp
,*fields
,*gcs
,x1
,y1
,il
,ih
);
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
,
429 unsigned int ih
, int color_idx
,
435 XSetForeground(disp
,maingc
,colors
[color_idx
]);
436 XFillRectangle(disp
,mainw
,maingc
,x1
,y1
,il
,ih
);
439 XSetForeground(disp
,*gcs
,colors
[color_idx
]);
440 XFillRectangle(disp
,*fields
,*gcs
,x1
,y1
,il
,ih
);
445 //===========================================================================
446 /// global pixmap_copy(Geo*)
447 /// copy part of image to the screen
448 /// tags XWellDrawingEngine
449 void XWellDrawingEngine::pixmap_copy(Geo
*pgeo
)
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
);