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: sdlwelldrawing.cxx,v 1.4 2003/02/21 11:40:33 leo Exp $
18 /// module description
19 /// SDL 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 "sdlwelldrawing.h"
24 #include "sdlwellengine.h"
25 #include "sdl_gfxprimitives.h"
27 //===========================================================================
28 /// global SDLWellDrawingEngine()
29 /// constructor of the class - init's variables.
30 /// tags SDLWellDrawingEngine
31 SDLWellDrawingEngine::SDLWellDrawingEngine(SDLWellEngine
* myengine
)
35 engine
=static_cast<SDLWellEngine
*>(default_well_engine
);
36 mainw
=engine
->get_main_window();
37 colors
=engine
->get_colors();
38 RGBA
=engine
->get_RGBA();
41 //===========================================================================
42 /// global init(int n_fields, int idx, int idy, unsigned il, unsigned ih)
43 /// init fields - creates x pixmaps and gcs
44 /// tags SDLWellDrawingEngine
45 void SDLWellDrawingEngine::init(int inum_fields
, int idx
, int idy
,
46 unsigned int il
, unsigned int ih
)
52 WellDrawingEngine::init(inum_fields
,idx
,idy
,il
,ih
);
53 fields
=new SDL_Surface
*;
55 fg_color
=colors
[GridColor
];
59 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
60 surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, l
, h
, 32,
66 surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, l
, h
, 32,
73 fields
[i
]=SDL_DisplayFormat(surface
);
74 SDL_FreeSurface(surface
);
78 bg_color
=colors
[BackColor
];
79 fg_color
=colors
[GridColor
];
82 //===========================================================================
83 /// global draw_square(int color_idx, int i, int j)
84 /// Draw square (floor polygon) on all fields with given color
85 /// tags SDLWellDrawingEngine
86 void SDLWellDrawingEngine::draw_square(int color
, int i
, int j
)
88 int idx
=current_id
,sign_x13
,sign_y13
,sign_x24
,sign_y24
;
90 Uint8
*rcolor
=&RGBA
[color
*4];
92 sign_x13
= points
[idx
].base_points
[i
+1][j
+1].x
-
93 points
[idx
].base_points
[i
][j
].x
;
94 sign_x13
= sign_x13
? (sign_x13
>0 ? 1 : -1) : 0;
96 sign_y13
= points
[idx
].base_points
[i
+1][j
+1].y
-
97 points
[idx
].base_points
[i
][j
].y
;
98 sign_y13
= sign_y13
? (sign_y13
>0 ? 1 : -1) : 0;
100 sign_x24
= points
[idx
].base_points
[i
][j
+1].x
-
101 points
[idx
].base_points
[i
+1][j
].x
;
102 sign_x24
= sign_x24
? (sign_x24
>0 ? 1 : -1) : 0;
104 sign_y24
= points
[idx
].base_points
[i
][j
+1].y
-
105 points
[idx
].base_points
[i
+1][j
].y
;
106 sign_y24
= sign_y24
? (sign_y24
>0 ? 1 : -1) : 0;
108 trap_x
[0] = points
[idx
].base_points
[i
][j
].x
+sign_x13
;
109 trap_y
[0] = points
[idx
].base_points
[i
][j
].y
+sign_y13
;
110 trap_x
[1] = points
[idx
].base_points
[i
+1][j
].x
+sign_x24
;
111 trap_y
[1] = points
[idx
].base_points
[i
+1][j
].y
+sign_y24
;
112 trap_x
[2] = points
[idx
].base_points
[i
+1][j
+1].x
-sign_x13
;
113 trap_y
[2] = points
[idx
].base_points
[i
+1][j
+1].y
-sign_y13
;
114 trap_x
[3] = points
[idx
].base_points
[i
][j
+1].x
-sign_x24
;
115 trap_y
[3] = points
[idx
].base_points
[i
][j
+1].y
-sign_y24
;
117 filledPolygonRGBA(*fields
, trap_x
, trap_y
, MAX_SIDES
,
125 trap_x
[0] = points
[idx
].base_points
[i
][j
].x
;
126 trap_y
[0] = points
[idx
].base_points
[i
][j
].y
;
127 trap_x
[1] = points
[idx
].base_points
[i
+1][j
].x
;
128 trap_y
[1] = points
[idx
].base_points
[i
+1][j
].y
;
129 trap_x
[2] = points
[idx
].base_points
[i
+1][j
+1].x
;
130 trap_y
[2] = points
[idx
].base_points
[i
+1][j
+1].y
;
131 trap_x
[3] = points
[idx
].base_points
[i
][j
+1].x
;
132 trap_y
[3] = points
[idx
].base_points
[i
][j
+1].y
;
134 polygonRGBA(*fields
, trap_x
, trap_y
, MAX_SIDES
,
136 RGBA
[GridColor2
*4+1],
137 RGBA
[GridColor2
*4+2],
141 new_dirty_rec(delta_x
,delta_y
);
142 dirty_add_xy(trap_x
[0],trap_y
[0]);
143 dirty_add_xy(trap_x
[1],trap_y
[1]);
144 dirty_add_xy(trap_x
[2],trap_y
[2]);
145 dirty_add_xy(trap_x
[3],trap_y
[3]);
149 //===========================================================================
150 /// global draw_trapazoid(int color_idx, int i,int j)
151 /// draw trapazoid - wall polygon with given color
152 /// tags SDLWellDrawingEngine
153 void SDLWellDrawingEngine::draw_trapazoid(int color
, int i
, int j
)
155 SDL_Surface
*win
=*fields
;
156 int idx
=current_id
,sign_x13
,sign_y13
,sign_x24
,sign_y24
;
158 Uint8
*rcolor
=&RGBA
[color
*4];
161 sign_x13
= points
[idx
].wall_points
[i
+1][j
+1].x
-
162 points
[idx
].wall_points
[i
][j
].x
;
163 sign_x13
= sign_x13
? (sign_x13
>0 ? 1 : -1) : 0;
165 sign_y13
= points
[idx
].wall_points
[i
+1][j
+1].y
-
166 points
[idx
].wall_points
[i
][j
].y
;
167 sign_y13
= sign_y13
? (sign_y13
>0 ? 1 : -1) : 0;
169 sign_x24
= points
[idx
].wall_points
[i
][j
+1].x
-
170 points
[idx
].wall_points
[i
+1][j
].x
;
171 sign_x24
= sign_x24
? (sign_x24
>0 ? 1 : -1) : 0;
173 sign_y24
= points
[idx
].wall_points
[i
][j
+1].y
-
174 points
[idx
].wall_points
[i
+1][j
].y
;
175 sign_y24
= sign_y24
? (sign_y24
>0 ? 1 : -1) : 0;
179 dbgprintf(("trapazoid [%2d][%2d] = [%d - %d],[%d - %d]\n",i,j,
180 points[idx].wall_points[i+1][j+1].x,
181 points[idx].wall_points[i][j].x,
182 points[idx].wall_points[i+1][j+1].y,
183 points[idx].wall_points[i][j].y));
185 dbgprintf(("trapazoid2[%2d][%2d] = [%d - %d],[%d - %d]\n",i,j,
186 points[idx].wall_points[i][j+1].x,
187 points[idx].wall_points[i+1][j].x,
188 points[idx].wall_points[i][j+1].y,
189 points[idx].wall_points[i+1][j].y));
190 dbgprintf(("trapazoid [%2d][%2d] = [%d][%d],[%d][%d]\n",i,j,
191 sign_x13,sign_y13,sign_x24,sign_y24));
195 trap_x
[0] = points
[idx
].wall_points
[i
][j
].x
+sign_x13
;
196 trap_y
[0] = points
[idx
].wall_points
[i
][j
].y
+sign_y13
;
197 trap_x
[1] = points
[idx
].wall_points
[i
+1][j
].x
+sign_x24
;
198 trap_y
[1] = points
[idx
].wall_points
[i
+1][j
].y
+sign_y24
;
199 trap_x
[2] = points
[idx
].wall_points
[i
+1][j
+1].x
-sign_x13
;
200 trap_y
[2] = points
[idx
].wall_points
[i
+1][j
+1].y
-sign_y13
;
201 trap_x
[3] = points
[idx
].wall_points
[i
][j
+1].x
-sign_x24
;
202 trap_y
[3] = points
[idx
].wall_points
[i
][j
+1].y
-sign_y24
;
203 filledPolygonRGBA(win
, trap_x
, trap_y
, MAX_SIDES
,
210 trap_x
[0] = points
[idx
].wall_points
[i
][j
].x
;
211 trap_y
[0] = points
[idx
].wall_points
[i
][j
].y
;
212 trap_x
[1] = points
[idx
].wall_points
[i
+1][j
].x
;
213 trap_y
[1] = points
[idx
].wall_points
[i
+1][j
].y
;
214 trap_x
[2] = points
[idx
].wall_points
[i
+1][j
+1].x
;
215 trap_y
[2] = points
[idx
].wall_points
[i
+1][j
+1].y
;
216 trap_x
[3] = points
[idx
].wall_points
[i
][j
+1].x
;
217 trap_y
[3] = points
[idx
].wall_points
[i
][j
+1].y
;
218 polygonRGBA(win
, trap_x
, trap_y
, MAX_SIDES
,
227 new_dirty_rec(delta_x
,delta_y
);
228 dirty_add_xy(trap_x
[0],trap_y
[0]);
229 dirty_add_xy(trap_x
[1],trap_y
[1]);
230 dirty_add_xy(trap_x
[2],trap_y
[2]);
231 dirty_add_xy(trap_x
[3],trap_y
[3]);
236 //===========================================================================
237 /// global draw_grid()
238 /// draw grid - all wall and floor polygons
239 /// tags SDLWellDrawingEngine
240 void SDLWellDrawingEngine::draw_grid()
248 for(i
=0;i
<MAX_PERIMETER
;i
++)
249 for(j
=0;j
<MAX_DEPTH
;j
++)
251 lineRGBA(win
,points
[idx
].wall_points
[i
][j
].x
,
252 points
[idx
].wall_points
[i
][j
].y
,
253 points
[idx
].wall_points
[i
][j
+1].x
,
254 points
[idx
].wall_points
[i
][j
+1].y
,
260 lineRGBA(win
,points
[idx
].wall_points
[i
][j
].x
,
261 points
[idx
].wall_points
[i
][j
].y
,
262 points
[idx
].wall_points
[i
+1][j
].x
,
263 points
[idx
].wall_points
[i
+1][j
].y
,
270 for(i
=0;i
<MAX_WIDTH
+1;i
++)
271 for(j
=0;j
<MAX_WIDTH
+1;j
++)
273 if(j
==0 || j
==MAX_WIDTH
)
274 fg_color
=GridColor2
*4;
276 fg_color
=GridColor
*4;
279 lineRGBA(win
,points
[idx
].base_points
[i
][j
].x
,
280 points
[idx
].base_points
[i
][j
].y
,
281 points
[idx
].base_points
[i
+1][j
].x
,
282 points
[idx
].base_points
[i
+1][j
].y
,
289 if(i
==0 || i
==MAX_WIDTH
)
290 fg_color
=GridColor2
*4;
292 fg_color
=GridColor
*4;
295 lineRGBA(win
,points
[idx
].base_points
[i
][j
].x
,
296 points
[idx
].base_points
[i
][j
].y
,
297 points
[idx
].base_points
[i
][j
+1].x
,
298 points
[idx
].base_points
[i
][j
+1].y
,
305 flush_field(*fields
, 0, 0, l
, h
);
308 //===========================================================================
309 /// global clear_field(int i)
310 /// clear field with given index with BackColor (black)
311 /// tags SDLWellDrawingEngine
312 void SDLWellDrawingEngine::clear_field(int)
314 boxRGBA(*fields
, 0, 0, l
, h
,
320 flush_field(*fields
, 0, 0, l
, h
);
323 //===========================================================================
324 /// global flush_all()
325 /// copy all the field with current_id to the screen
326 /// tags SDLWellDrawingEngine
327 void SDLWellDrawingEngine::flush_all()
338 SDL_BlitSurface(*fields
, &src
, mainw
, &dest
);
339 /* Update the changed portion of the screen */
340 SDL_UpdateRects(mainw
, 1, &dest
);
343 //===========================================================================
344 /// global flush_field()
345 /// copy all the field with current_id to the screen
346 /// tags SDLWellDrawingEngine
347 void SDLWellDrawingEngine::flush_field(SDL_Surface
* win
,
356 /* Update the changed portion of the screen */
357 SDL_UpdateRects(win
, 1, &dest
);
360 //===========================================================================
361 /// global flush_field()
362 /// copy all the field with current_id to the screen
363 /// tags SDLWellDrawingEngine
364 void SDLWellDrawingEngine::field_sync()
366 flush_field(*fields
, 0, 0, l
, h
);
368 //===========================================================================
370 /// flush event in SDL queue
371 /// tags SDLWellDrawingEngine
372 void SDLWellDrawingEngine::sync()
375 // flush_field(*fields, 0, 0, l, h);
378 //===========================================================================
379 /// global flush_dirty()
380 /// copy list of dirty rectangle areas to the screen
381 /// tags SDLWellDrawingEngine
382 void SDLWellDrawingEngine::flush_dirty()
387 if(!get_max_dirties())
390 from
=new SDL_Rect
[get_max_dirties()];
391 to
=new SDL_Rect
[get_max_dirties()];
397 plist
=dirty_list
.get_next();
400 DirtyRect
& drec
=plist
->get_object();
401 //Here we need to draw dirty rec on the screen -> will be in overloaded childs
402 from
[idx
].x
=drec
.get_src_x();
403 from
[idx
].y
=drec
.get_src_y();
404 from
[idx
].w
=to
[idx
].w
=drec
.l
;
405 from
[idx
].h
=to
[idx
].h
=drec
.h
;
406 to
[idx
].x
=drec
.get_dest_x();
407 to
[idx
].y
=drec
.get_dest_y();
409 SDL_BlitSurface(*fields
, &from
[idx
], mainw
, &to
[idx
]);
416 SDL_UpdateRects(mainw
, idx
, to
);
422 //===========================================================================
423 /// global key_to_action(void* event)
424 /// convert keys to actions in the game
425 /// tags SDLWellDrawingEngine
426 Actions
SDLWellDrawingEngine::key_to_action(void* event
)
428 SDL_Event
*ev
=(SDL_Event
*)event
;
429 switch(ev
->key
.keysym
.sym
)
461 case SDLK_KP_MULTIPLY
:
462 return OUTER_ROTATION
;
475 //===========================================================================
476 /// global draw_line(...)
477 /// draw line with given coords and color
478 /// tags SDLWellDrawingEngine
479 void SDLWellDrawingEngine::draw_line(int x1
, int y1
, int x2
, int y2
, int color_idx
,
482 Uint8
*color
=&RGBA
[color_idx
*4];
486 lineRGBA(mainw
,x1
,y1
,x2
,y2
,
494 lineRGBA(*fields
,x1
,y1
,x2
,y2
,
504 //===========================================================================
505 /// global draw_rect(...)
506 /// draw rectangle with given coords and color
507 /// tags SDLWellDrawingEngine
508 void SDLWellDrawingEngine::draw_rect(int x1
, int y1
,
510 unsigned int ih
, int color_idx
,
513 Uint8
*color
=&RGBA
[color_idx
*4];
517 rectangleRGBA(mainw
,x1
,y1
,x1
+il
-1,y1
+ih
-1,
523 flush_field(mainw
, x1
,y1
, il
, ih
);
526 rectangleRGBA(*fields
,x1
,y1
,x1
+il
-1,y1
+ih
-1,
532 flush_field(*fields
, x1
,y1
, il
, ih
);
537 //===========================================================================
538 /// global fill_rect(...)
539 /// fill rectangle with given coords and color
540 /// tags SDLWellDrawingEngine
541 void SDLWellDrawingEngine::fill_rect(int x1
, int y1
,
543 unsigned int ih
, int color_idx
,
546 Uint8
*color
=&RGBA
[color_idx
*4];
550 boxRGBA(mainw
,x1
,y1
,x1
+il
-1,y1
+ih
-1,
556 flush_field(mainw
, x1
,y1
, il
, ih
);
559 boxRGBA(*fields
,x1
,y1
,x1
+il
-1,y1
+ih
-1,
565 flush_field(*fields
, x1
,y1
, il
, ih
);
570 //===========================================================================
571 /// global pixmap_copy(Geo*)
572 /// copy part of image to the screen
573 /// tags SDLWellDrawingEngine
574 void SDLWellDrawingEngine::pixmap_copy(Geo
*pgeo
)
582 src
.w
=dest
.w
=pgeo
->l
;
583 src
.h
=dest
.h
=pgeo
->h
;
587 SDL_BlitSurface(engine
->get_pixmap_of_image(pgeo
->im
),
588 &src
, *fields
, &dest
);
589 SDL_UpdateRects(*fields
, 1, &dest
);