1 |
|
/* |
2 |
|
* Copyright (C) 2002,2003 Daniel Heck |
3 |
|
* |
4 |
|
* This program is free software; you can redistribute it and/or |
5 |
|
* modify it under the terms of the GNU General Public License |
6 |
|
* as published by the Free Software Foundation; either version 2 |
7 |
|
* of the License, or (at your option) any later version. |
8 |
|
* |
9 |
|
* This program is distributed in the hope that it will be useful, |
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
|
* GNU General Public License for more details. |
13 |
|
* |
14 |
|
* You should have received a copy of the GNU General Public License along |
15 |
|
* with this program; if not, write to the Free Software Foundation, Inc., |
16 |
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
17 |
|
* |
18 |
|
* $Id$ |
19 |
|
*/ |
20 |
|
#ifndef D_ENGINE_HH |
21 |
|
#define D_ENGINE_HH |
22 |
|
|
23 |
|
#include "px/tools.hh" |
24 |
|
#include "px/geom.hh" |
25 |
|
#include "px/array2.hh" |
26 |
|
#include "px/alist.hh" |
27 |
|
#include "px/pxfwd.hh" |
28 |
|
#include <list> |
29 |
|
|
30 |
namespace display |
namespace display |
31 |
{ |
{ |
32 |
|
using px::V2; |
33 |
|
using px::V3; |
34 |
typedef px::Rect ScreenArea; |
typedef px::Rect ScreenArea; |
35 |
typedef px::Rect WorldArea; |
typedef px::Rect WorldArea; |
36 |
|
|
41 |
static const int NUM_LAYERS = 3; |
static const int NUM_LAYERS = 3; |
42 |
|
|
43 |
Field() { |
Field() { |
44 |
fill_n(layers, NUM_LAYERS, (Model*)0); |
layers[0] = layers[1] = layers[2] = 0; |
45 |
} |
} |
46 |
~Field() { delete_sequence(layers, layers+NUM_LAYERS); } |
~Field() { px::delete_sequence(layers, layers+NUM_LAYERS); } |
47 |
|
|
48 |
Model* layers[NUM_LAYERS]; |
Model* layers[NUM_LAYERS]; |
49 |
}; |
}; |
50 |
|
|
51 |
typedef Array2<Field> FieldArray; |
typedef px::Array2<Field> FieldArray; |
52 |
typedef list<Model*> ModelList; |
typedef std::list<Model*> ModelList; |
53 |
|
|
54 |
|
|
55 |
struct Field2 { |
struct Field2 { |
97 |
** Coordinate conversion |
** Coordinate conversion |
98 |
*/ |
*/ |
99 |
|
|
100 |
void world_to_screen (const V3 & pos, int *x, int *y); |
void world_to_screen (const px::V3 & pos, int *x, int *y); |
101 |
void world_to_screen (const V2 & pos, int *x, int *y); |
void world_to_screen (const px::V2 & pos, int *x, int *y); |
102 |
WorldArea screen_to_world (const ScreenArea &a); |
WorldArea screen_to_world (const ScreenArea &a); |
103 |
ScreenArea world_to_screen (const WorldArea &a); |
ScreenArea world_to_screen (const WorldArea &a); |
104 |
|
|
123 |
|
|
124 |
private: |
private: |
125 |
|
|
126 |
void draw_field (GC &gc, int x, int y); |
void draw_field (px::GC &gc, int x, int y); |
127 |
|
|
128 |
|
|
129 |
/* |
/* |
165 |
** DisplayLayer interface. |
** DisplayLayer interface. |
166 |
*/ |
*/ |
167 |
virtual void draw (px::GC &gc, const WorldArea &a, int x, int y) = 0; |
virtual void draw (px::GC &gc, const WorldArea &a, int x, int y) = 0; |
168 |
virtual void notify_expose (px::Rect &area) {} |
// virtual void notify_expose (px::Rect &area) {} |
169 |
virtual void tick (double dtime) {} |
virtual void tick (double dtime) {} |
170 |
virtual void new_world (int w, int h) {} |
virtual void new_world (int w, int h) {} |
171 |
|
|
185 |
|
|
186 |
// DisplayLayer interface |
// DisplayLayer interface |
187 |
void tick (double dtime); |
void tick (double dtime); |
188 |
|
void new_world (int, int); |
189 |
|
|
190 |
// Member functions |
// Member functions |
191 |
void activate (Model *m); |
void activate (Model *m); |
192 |
void deactivate (Model *m); |
void deactivate (Model *m); |
193 |
|
void maybe_redraw_model(Model *m); |
194 |
|
|
195 |
virtual bool is_sprite_layer() const = 0; |
virtual bool is_sprite_layer() const = 0; |
196 |
private: |
private: |
197 |
|
|
198 |
|
|
199 |
// Variables |
// Variables |
200 |
ModelList m_active_models; |
ModelList m_active_models; |
201 |
}; |
}; |
222 |
// ModelLayer interface |
// ModelLayer interface |
223 |
virtual bool is_sprite_layer() const { return false; } |
virtual bool is_sprite_layer() const { return false; } |
224 |
|
|
|
|
|
225 |
// Variables. |
// Variables. |
226 |
typedef Array2<Model*> ModelArray; |
typedef px::Array2<Model*> ModelArray; |
227 |
ModelArray m_models; |
ModelArray m_models; |
228 |
}; |
}; |
229 |
|
|
231 |
// Sprite layer |
// Sprite layer |
232 |
//---------------------------------------- |
//---------------------------------------- |
233 |
|
|
234 |
class Sprite : public Nocopy { |
class Sprite : public px::Nocopy { |
235 |
public: |
public: |
236 |
Model *model; |
Model *model; |
237 |
V3 pos; |
V3 pos; |
238 |
SpriteLayer layer; |
SpriteLayer layer; |
239 |
bool visible; |
bool visible; |
240 |
|
|
241 |
Sprite(const V3 & p, SpriteLayer l, Model *m) |
Sprite (const V3 & p, SpriteLayer l, Model *m) |
242 |
: model(m), pos(p), layer(l) |
: model(m), pos(p), layer(l) |
243 |
{} |
{} |
244 |
~Sprite() { delete model; } |
~Sprite() { delete model; } |
245 |
}; |
}; |
246 |
|
|
247 |
typedef vector<Sprite*> SpriteList; |
typedef std::vector<Sprite*> SpriteList; |
248 |
|
|
249 |
class DL_Sprites : public ModelLayer { |
class DL_Sprites : public ModelLayer { |
250 |
public: |
public: |
264 |
void replace_sprite (SpriteId id, Model *m); |
void replace_sprite (SpriteId id, Model *m); |
265 |
|
|
266 |
void redraw_sprite_region (SpriteId id); |
void redraw_sprite_region (SpriteId id); |
267 |
void draw_sprites (bool shades, GC &gc); |
void draw_sprites (bool shades, px::GC &gc); |
268 |
|
|
269 |
SpriteList sprites; |
SpriteList sprites; |
270 |
|
|
272 |
|
|
273 |
private: |
private: |
274 |
// ModelLayer interface |
// ModelLayer interface |
275 |
bool is_sprite_layer() const { return false; } |
bool is_sprite_layer() const { return true; } |
276 |
|
|
277 |
|
|
278 |
// Variables. |
// Variables. |
280 |
unsigned maxsprites; // Maximum number of sprites |
unsigned maxsprites; // Maximum number of sprites |
281 |
}; |
}; |
282 |
|
|
283 |
|
class SpriteHandle { |
284 |
|
DL_Sprites *layer; |
285 |
|
unsigned id; |
286 |
|
public: |
287 |
|
SpriteHandle (DL_Sprites *l, unsigned spriteid) |
288 |
|
: layer(l), id(spriteid) |
289 |
|
{} |
290 |
|
|
291 |
|
void kill() { layer->kill_sprite (id); } |
292 |
|
|
293 |
|
void move (const px::V2 &newpos) |
294 |
|
{ |
295 |
|
layer->move_sprite (id, V3(newpos[0], newpos[1], 0)); |
296 |
|
} |
297 |
|
void replace_model (Model *m) |
298 |
|
{ |
299 |
|
layer->replace_sprite (id, m); |
300 |
|
} |
301 |
|
}; |
302 |
|
|
303 |
//---------------------------------------- |
//---------------------------------------- |
304 |
// Shadow layer |
// Shadow layer |
305 |
//---------------------------------------- |
//---------------------------------------- |
309 |
virtual ~ShadowLayer() {} |
virtual ~ShadowLayer() {} |
310 |
virtual void new_world(int w, int h) {} |
virtual void new_world(int w, int h) {} |
311 |
virtual void update (int x, int y) = 0; |
virtual void update (int x, int y) = 0; |
312 |
virtual void draw(GC &gc, int xpos, int ypos, int x, int y) = 0; |
virtual void draw (px::GC &gc, int xpos, int ypos, int x, int y) = 0; |
313 |
}; |
}; |
314 |
|
|
315 |
|
|
321 |
|
|
322 |
void new_world(int w, int h); |
void new_world(int w, int h); |
323 |
void update (int x, int y); |
void update (int x, int y); |
324 |
void draw(GC &gc, int xpos, int ypos, int x, int y); |
void draw (px::GC &gc, int xpos, int ypos, int x, int y); |
325 |
|
|
326 |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
327 |
private: |
private: |
331 |
void shadow_blit (px::Surface *scr, int x, int y, |
void shadow_blit (px::Surface *scr, int x, int y, |
332 |
px::Surface *shadows, px::Rect r); |
px::Surface *shadows, px::Rect r); |
333 |
|
|
334 |
Surface *new_surface(); |
px::Surface *new_surface(); |
335 |
void dispose_surface(Surface *s); |
void dispose_surface(px::Surface *s); |
336 |
Surface *get_cache(int x, int y); |
px::Surface *get_cache(int x, int y); |
337 |
bool draw_stone_shade(GC &gc, int x, int y, Field &f); |
bool draw_stone_shade(px::GC &gc, int x, int y, Field &f); |
338 |
|
|
339 |
|
Model *get_shadow_model (Model *stone_models[4]); |
340 |
|
|
341 |
/* |
/* |
342 |
** Variables |
** Variables |
344 |
DL_Grid *m_grid; // stone models |
DL_Grid *m_grid; // stone models |
345 |
DL_Sprites *m_sprites; // sprite models |
DL_Sprites *m_sprites; // sprite models |
346 |
|
|
347 |
Surface *shadow_surface; |
px::Surface *shadow_surface; |
348 |
Uint32 shadow_ckey; // Color key |
Uint32 shadow_ckey; // Color key |
349 |
Array2<Surface *> m_gridcache; |
px::Array2<px::Surface *> m_gridcache; |
350 |
Array2<bool> has_shadow; |
px::Array2<bool> has_shadow; |
351 |
vector<Surface *> m_surface_avail; |
std::vector<px::Surface *> m_surface_avail; |
352 |
Surface *buffer; |
px::Surface *buffer; |
353 |
}; |
}; |
354 |
|
|
355 |
//---------------------------------------- |
//---------------------------------------- |
390 |
}; |
}; |
391 |
|
|
392 |
|
|
393 |
typedef AssocList<unsigned, Line> LineMap; |
typedef px::AssocList<unsigned, Line> LineMap; |
394 |
|
|
395 |
class DL_Lines : public DisplayLayer { |
class DL_Lines : public DisplayLayer { |
396 |
public: |
public: |
400 |
|
|
401 |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
402 |
|
|
403 |
void draw_lines (GC &gc); |
void draw_lines (px::GC &gc); |
404 |
|
|
405 |
|
|
406 |
RubberHandle add_line (const V2 &p1, const V2 &p2); |
RubberHandle add_line (const V2 &p1, const V2 &p2); |
423 |
|
|
424 |
class CommonDisplay { |
class CommonDisplay { |
425 |
public: |
public: |
426 |
|
CommonDisplay (const ScreenArea &a); |
427 |
|
~CommonDisplay(); |
428 |
|
|
429 |
Model *set_model (const GridLoc &l, Model *m); |
Model *set_model (const GridLoc &l, Model *m); |
430 |
Model *get_model (const GridLoc &l); |
Model *get_model (const GridLoc &l); |
431 |
Model *yield_model (const GridLoc &l); |
Model *yield_model (const GridLoc &l); |
432 |
|
|
433 |
|
void set_floor (int x, int y, Model *m); |
434 |
|
|
435 |
|
DisplayEngine *get_engine() const { return m_engine; } |
436 |
|
|
437 |
|
SpriteHandle add_effect (const V3& pos, Model *m); |
438 |
|
|
439 |
|
void new_world (int w, int h); |
440 |
|
void redraw(); |
441 |
|
|
442 |
protected: |
protected: |
443 |
DL_Grid *floor_layer; |
DL_Grid *floor_layer; |
444 |
DL_Grid *item_layer; |
DL_Grid *item_layer; |
445 |
DL_Grid *stone_layer; |
DL_Grid *stone_layer; |
446 |
|
|
447 |
DL_Sprites *effects_layer; |
DL_Sprites *effects_layer; |
448 |
|
|
449 |
|
private: |
450 |
|
|
451 |
|
DisplayEngine *m_engine; |
452 |
}; |
}; |
453 |
|
|
454 |
|
|
460 |
virtual ~Follower() {} |
virtual ~Follower() {} |
461 |
virtual void tick(double dtime, const px::V2 &point) = 0; |
virtual void tick(double dtime, const px::V2 &point) = 0; |
462 |
virtual void center(const px::V2 &point) = 0; |
virtual void center(const px::V2 &point) = 0; |
463 |
|
|
464 |
|
void set_engine(DisplayEngine *e) { m_engine = e; } |
465 |
|
DisplayEngine *get_engine() const { return m_engine; } |
466 |
|
private: |
467 |
|
DisplayEngine *m_engine; |
468 |
}; |
}; |
469 |
|
|
470 |
class Follower_Screen : public Follower { |
class Follower_Screen : public Follower { |
488 |
|
|
489 |
class GameDisplay : public CommonDisplay { |
class GameDisplay : public CommonDisplay { |
490 |
public: |
public: |
491 |
GameDisplay(); |
GameDisplay(const ScreenArea &a); |
492 |
~GameDisplay(); |
~GameDisplay(); |
493 |
|
|
494 |
StatusBar * get_status_bar() const; |
StatusBar * get_status_bar() const; |
496 |
void tick(double dtime); |
void tick(double dtime); |
497 |
void new_world (int w, int h); |
void new_world (int w, int h); |
498 |
|
|
|
void add_effect (const V3& pos, Model *m) { |
|
|
effects_layer->add_sprite(new Sprite (pos, SPRITE_EFFECT, m)); |
|
|
} |
|
|
|
|
499 |
/* |
/* |
500 |
** Scrolling |
** Scrolling |
501 |
*/ |
*/ |
508 |
*/ |
*/ |
509 |
void redraw (px::Screen *scr); |
void redraw (px::Screen *scr); |
510 |
void redraw_all (px::Screen *scr); |
void redraw_all (px::Screen *scr); |
511 |
void draw_all (GC &gc); |
void draw_all (px::GC &gc); |
512 |
private: |
private: |
513 |
void set_follower (Follower *f); |
void set_follower (Follower *f); |
514 |
|
|
526 |
ScreenArea inventoryarea; |
ScreenArea inventoryarea; |
527 |
}; |
}; |
528 |
|
|
529 |
//---------------------------------------- |
class ModelHandle { |
|
// Editor display engine |
|
|
//---------------------------------------- |
|
|
class EditorDisplay { |
|
530 |
public: |
public: |
531 |
EditorDisplay(); |
ModelHandle (); |
|
~EditorDisplay(); |
|
|
|
|
|
void tick(double dtime); |
|
|
private: |
|
|
|
|
532 |
}; |
}; |
533 |
} |
} |
534 |
|
|
535 |
|
#endif |