1 |
namespace |
namespace display |
2 |
{ |
{ |
3 |
typedef px::Rect ScreenArea; |
typedef px::Rect ScreenArea; |
4 |
typedef px::Rect WorldArea; |
typedef px::Rect WorldArea; |
5 |
|
|
6 |
class DisplayLayer; |
class DisplayLayer; |
7 |
|
class StatusBarImpl; |
8 |
|
|
9 |
|
struct Field { |
10 |
|
static const int NUM_LAYERS = 3; |
11 |
|
|
12 |
|
Field() { |
13 |
|
fill_n(layers, NUM_LAYERS, (Model*)0); |
14 |
|
} |
15 |
|
~Field() { delete_sequence(layers, layers+NUM_LAYERS); } |
16 |
|
|
17 |
|
Model* layers[NUM_LAYERS]; |
18 |
|
}; |
19 |
|
|
20 |
|
typedef Array2<Field> FieldArray; |
21 |
|
typedef list<Model*> ModelList; |
22 |
|
|
23 |
|
|
24 |
struct Field2 { |
struct Field2 { |
25 |
Field2() { updatep=redrawp=false; } |
Field2() { updatep=redrawp=false; } |
29 |
}; |
}; |
30 |
typedef px::Array2<Field2> Field2Array; |
typedef px::Array2<Field2> Field2Array; |
31 |
|
|
32 |
|
//---------------------------------------- |
33 |
|
// Display engine |
34 |
|
//---------------------------------------- |
35 |
|
|
36 |
class DisplayEngine { |
class DisplayEngine { |
37 |
public: |
public: |
38 |
DisplayEngine (px::Screen *scr); |
DisplayEngine (px::Screen *scr); |
69 |
void world_to_screen (const V3 & pos, int *x, int *y); |
void world_to_screen (const V3 & pos, int *x, int *y); |
70 |
void world_to_screen (const V2 & pos, int *x, int *y); |
void world_to_screen (const V2 & pos, int *x, int *y); |
71 |
WorldArea screen_to_world (const ScreenArea &a); |
WorldArea screen_to_world (const ScreenArea &a); |
72 |
|
ScreenArea world_to_screen (const WorldArea &a); |
73 |
|
|
74 |
V2 to_screen (const V2 &pos); |
V2 to_screen (const V2 &pos); |
75 |
V2 to_world (const V2 &pos); |
V2 to_world (const V2 &pos); |
91 |
Field2 &get_field (int x, int y) { return m_fields(x,y); } |
Field2 &get_field (int x, int y) { return m_fields(x,y); } |
92 |
|
|
93 |
private: |
private: |
94 |
|
|
95 |
|
void draw_field (GC &gc, int x, int y); |
96 |
|
|
97 |
|
|
98 |
/* |
/* |
99 |
** Variables |
** Variables |
100 |
*/ |
*/ |
133 |
/* |
/* |
134 |
** DisplayLayer interface. |
** DisplayLayer interface. |
135 |
*/ |
*/ |
136 |
virtual void draw (px::GC &gc, px::Rect &area, int x, int y) = 0; |
virtual void draw (px::GC &gc, const WorldArea &a, int x, int y) = 0; |
137 |
virtual void notify_expose (px::Rect &area) {} |
virtual void notify_expose (px::Rect &area) {} |
138 |
virtual void tick (double dtime) {} |
virtual void tick (double dtime) {} |
139 |
virtual void new_world (int w, int h) {} |
virtual void new_world (int w, int h) {} |
146 |
}; |
}; |
147 |
|
|
148 |
//---------------------------------------- |
//---------------------------------------- |
149 |
|
// Base class for all layers that contains Models |
150 |
|
//---------------------------------------- |
151 |
|
class ModelLayer : public DisplayLayer { |
152 |
|
public: |
153 |
|
ModelLayer() {} |
154 |
|
|
155 |
|
// DisplayLayer interface |
156 |
|
void tick (double dtime); |
157 |
|
|
158 |
|
// Member functions |
159 |
|
void activate (Model *m); |
160 |
|
void deactivate (Model *m); |
161 |
|
|
162 |
|
virtual bool is_sprite_layer() const = 0; |
163 |
|
private: |
164 |
|
// Variables |
165 |
|
ModelList m_active_models; |
166 |
|
}; |
167 |
|
|
168 |
|
//---------------------------------------- |
169 |
// Layer for grid-aligned models |
// Layer for grid-aligned models |
170 |
//---------------------------------------- |
//---------------------------------------- |
171 |
|
|
172 |
class DL_GridModels : public DisplayLayer { |
class DL_Grid : public ModelLayer { |
173 |
public: |
public: |
174 |
DL_GridModels(); |
DL_Grid(); |
175 |
|
|
176 |
|
void set_model (int x, int y, Model *m); |
177 |
|
Model *get_model (int x, int y); |
178 |
|
Model *yield_model (int x, int y); |
179 |
|
|
|
virtual void draw (px::GC &gc, px::Rect &area, int x, int y) { |
|
|
} |
|
180 |
private: |
private: |
181 |
|
// DisplayLayer interface. |
182 |
|
void new_world (int w, int h); |
183 |
|
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
184 |
|
|
185 |
|
void mark_update (int x, int y); |
186 |
|
|
187 |
|
// ModelLayer interface |
188 |
|
virtual bool is_sprite_layer() const { return false; } |
189 |
|
|
190 |
|
|
191 |
// Variables. |
// Variables. |
192 |
|
typedef Array2<Model*> ModelArray; |
193 |
|
ModelArray m_models; |
194 |
}; |
}; |
195 |
|
|
196 |
//---------------------------------------- |
//---------------------------------------- |
212 |
|
|
213 |
typedef vector<Sprite*> SpriteList; |
typedef vector<Sprite*> SpriteList; |
214 |
|
|
215 |
class DL_Sprites : public DisplayLayer { |
class DL_Sprites : public ModelLayer { |
216 |
public: |
public: |
217 |
DL_Sprites(); |
DL_Sprites(); |
218 |
~DL_Sprites(); |
~DL_Sprites(); |
219 |
|
|
220 |
void draw (px::GC &gc, px::Rect &area, int x, int y) { |
// DisplayLayer interface |
221 |
} |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
|
|
|
222 |
void new_world (int, int); |
void new_world (int, int); |
223 |
|
|
224 |
|
/* |
225 |
|
** Member functions |
226 |
|
*/ |
227 |
SpriteId add_sprite (Sprite *sprite); |
SpriteId add_sprite (Sprite *sprite); |
228 |
void kill_sprite (SpriteId id); |
void kill_sprite (SpriteId id); |
229 |
void move_sprite (SpriteId, const px::V3& newpos); |
void move_sprite (SpriteId, const px::V3& newpos); |
230 |
void replace_sprite (SpriteId id, Model *m); |
void replace_sprite (SpriteId id, Model *m); |
231 |
|
|
|
|
|
232 |
void redraw_sprite_region (SpriteId id); |
void redraw_sprite_region (SpriteId id); |
233 |
void draw_sprites (bool shades, GC &gc); |
void draw_sprites (bool shades, GC &gc); |
234 |
|
|
237 |
void set_maxsprites (unsigned m) { maxsprites = m; } |
void set_maxsprites (unsigned m) { maxsprites = m; } |
238 |
|
|
239 |
private: |
private: |
240 |
|
// ModelLayer interface |
241 |
|
bool is_sprite_layer() const { return false; } |
242 |
|
|
243 |
|
|
244 |
// Variables. |
// Variables. |
245 |
unsigned numsprites; // Current number of sprites |
unsigned numsprites; // Current number of sprites |
246 |
unsigned maxsprites; // Maximum number of sprites |
unsigned maxsprites; // Maximum number of sprites |
262 |
|
|
263 |
class DL_Shadows : public DisplayLayer { |
class DL_Shadows : public DisplayLayer { |
264 |
public: |
public: |
265 |
DL_Shadows(); |
DL_Shadows(DL_Grid *grid, DL_Sprites *sprites); |
266 |
|
~DL_Shadows(); |
267 |
|
|
268 |
virtual void draw (px::GC &gc, px::Rect &area, int x, int y) { |
void new_world(int w, int h); |
269 |
} |
void update (int x, int y); |
270 |
|
void draw(GC &gc, int xpos, int ypos, int x, int y); |
271 |
|
|
272 |
|
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
273 |
private: |
private: |
274 |
// Variables. |
/* |
275 |
DL_GridModels m_grid; // stone shadows |
** Private functions |
276 |
DL_Sprites m_sprites; // sprite shadows |
*/ |
277 |
|
void shadow_blit (px::Surface *scr, int x, int y, |
278 |
|
px::Surface *shadows, px::Rect r); |
279 |
|
|
280 |
|
Surface *new_surface(); |
281 |
|
void dispose_surface(Surface *s); |
282 |
|
Surface *get_cache(int x, int y); |
283 |
|
bool draw_stone_shade(GC &gc, int x, int y, Field &f); |
284 |
|
|
285 |
|
/* |
286 |
|
** Variables |
287 |
|
*/ |
288 |
|
DL_Grid *m_grid; // stone models |
289 |
|
DL_Sprites *m_sprites; // sprite models |
290 |
|
|
291 |
|
Surface *shadow_surface; |
292 |
|
Uint32 shadow_ckey; // Color key |
293 |
|
Array2<Surface *> m_gridcache; |
294 |
|
Array2<bool> has_shadow; |
295 |
|
vector<Surface *> m_surface_avail; |
296 |
|
Surface *buffer; |
297 |
|
}; |
298 |
|
|
299 |
|
//---------------------------------------- |
300 |
|
// Stone layer |
301 |
|
//---------------------------------------- |
302 |
|
|
303 |
|
class DL_Stones : public DL_Grid { |
304 |
|
public: |
305 |
|
DL_Stones (DL_Shadows *shadowlayer); |
306 |
|
|
307 |
|
void set_model (int x, int y, Model *m); |
308 |
|
Model *yield_model (int x, int y); |
309 |
|
}; |
310 |
|
|
311 |
|
|
312 |
|
//---------------------------------------- |
313 |
|
// Actor layer |
314 |
|
// |
315 |
|
// This layer is quite similar to a sprite layer, the only difference |
316 |
|
// being that actors can have a shadow that must be taken care of. |
317 |
|
//---------------------------------------- |
318 |
|
|
319 |
|
class DL_Actors : public DL_Sprites { |
320 |
|
public: |
321 |
|
DL_Actors (DL_Shadows *shadowlayer); |
322 |
|
|
323 |
}; |
}; |
324 |
|
|
325 |
//---------------------------------------- |
//---------------------------------------- |
342 |
{ |
{ |
343 |
} |
} |
344 |
|
|
345 |
virtual void draw (px::GC &gc, px::Rect &area, int x, int y) |
void draw (px::GC &gc, const WorldArea &a, int x, int y); |
|
{ |
|
|
} |
|
346 |
|
|
347 |
void draw_lines (GC &gc); |
void draw_lines (GC &gc); |
348 |
|
|
360 |
unsigned m_id; |
unsigned m_id; |
361 |
LineMap m_rubbers; |
LineMap m_rubbers; |
362 |
}; |
}; |
363 |
|
|
364 |
|
//---------------------------------------- |
365 |
|
// Parts of the display engine that are common to the game and the editor |
366 |
|
//---------------------------------------- |
367 |
|
|
368 |
|
class CommonDisplay { |
369 |
|
public: |
370 |
|
|
371 |
|
Model *set_model (const GridLoc &l, Model *m); |
372 |
|
Model *get_model (const GridLoc &l); |
373 |
|
Model *yield_model (const GridLoc &l); |
374 |
|
|
375 |
|
protected: |
376 |
|
DL_Grid *floor_layer; |
377 |
|
DL_Grid *item_layer; |
378 |
|
DL_Grid *stone_layer; |
379 |
|
|
380 |
|
DL_Sprites *effects_layer; |
381 |
|
}; |
382 |
|
|
383 |
|
|
384 |
|
//---------------------------------------- |
385 |
|
// Game Display Engine |
386 |
|
//---------------------------------------- |
387 |
|
class Follower { |
388 |
|
public: |
389 |
|
virtual ~Follower() {} |
390 |
|
virtual void tick(double dtime, const px::V2 &point) = 0; |
391 |
|
virtual void center(const px::V2 &point) = 0; |
392 |
|
}; |
393 |
|
|
394 |
|
class Follower_Screen : public Follower { |
395 |
|
public: |
396 |
|
void tick(double dtime, const px::V2 &point); |
397 |
|
void center(const px::V2 &point); |
398 |
|
}; |
399 |
|
|
400 |
|
class Follower_Scrolling : public Follower { |
401 |
|
public: |
402 |
|
Follower_Scrolling(); |
403 |
|
void tick(double dtime, const px::V2 &point); |
404 |
|
void center(const px::V2 &point); |
405 |
|
private: |
406 |
|
bool currently_scrolling; |
407 |
|
V2 curpos, destpos; |
408 |
|
V2 dir; |
409 |
|
double scrollspeed; |
410 |
|
double resttime; |
411 |
|
}; |
412 |
|
|
413 |
|
class GameDisplay : public CommonDisplay { |
414 |
|
public: |
415 |
|
GameDisplay(); |
416 |
|
~GameDisplay(); |
417 |
|
|
418 |
|
StatusBar * get_status_bar() const; |
419 |
|
|
420 |
|
void tick(double dtime); |
421 |
|
void new_world (int w, int h); |
422 |
|
|
423 |
|
void add_effect (const V3& pos, Model *m) { |
424 |
|
effects_layer->add_sprite(new Sprite (pos, SPRITE_EFFECT, m)); |
425 |
|
} |
426 |
|
|
427 |
|
/* |
428 |
|
** Scrolling |
429 |
|
*/ |
430 |
|
FollowMode set_follow_mode (FollowMode m); |
431 |
|
void follow_center(); |
432 |
|
void set_follow_sprite(SpriteId id); |
433 |
|
|
434 |
|
/* |
435 |
|
** Screen updates |
436 |
|
*/ |
437 |
|
void redraw (px::Screen *scr); |
438 |
|
void redraw_all (px::Screen *scr); |
439 |
|
void draw_all (GC &gc); |
440 |
|
private: |
441 |
|
void set_follower (Follower *f); |
442 |
|
|
443 |
|
/* |
444 |
|
** Variables |
445 |
|
*/ |
446 |
|
Uint32 last_frame_time; |
447 |
|
bool redraw_everything; |
448 |
|
StatusBarImpl *status_bar; |
449 |
|
|
450 |
|
SpriteId follow_sprite; |
451 |
|
FollowMode follow_mode; |
452 |
|
Follower *follower; |
453 |
|
|
454 |
|
ScreenArea inventoryarea; |
455 |
|
}; |
456 |
|
|
457 |
|
//---------------------------------------- |
458 |
|
// Editor display engine |
459 |
|
//---------------------------------------- |
460 |
|
class EditorDisplay { |
461 |
|
public: |
462 |
|
EditorDisplay(); |
463 |
|
~EditorDisplay(); |
464 |
|
|
465 |
|
void tick(double dtime); |
466 |
|
private: |
467 |
|
|
468 |
|
}; |
469 |
} |
} |