ScummVM API documentation
anim_manager.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NUVIE_CORE_ANIM_MANAGER_H
23 #define NUVIE_CORE_ANIM_MANAGER_H
24 
25 #include "ultima/nuvie/core/nuvie_defs.h"
26 #include "ultima/nuvie/gui/widgets/map_window.h"
27 #include "ultima/nuvie/core/timed_event.h"
28 #include "ultima/nuvie/misc/call_back.h"
29 #include "ultima/nuvie/misc/map_entity.h"
30 #include "ultima/nuvie/misc/u6_line_walker.h"
31 
32 namespace Ultima {
33 namespace Nuvie {
34 
35 using Std::list;
36 using Std::string;
37 using Std::vector;
38 
39 class Actor;
40 class CallBack;
41 class AnimManager;
42 class NuvieAnim;
43 class Screen;
44 class Font;
45 
46 #define MESG_TIMED CB_TIMED
47 
48 typedef Std::list<NuvieAnim *>::iterator AnimIterator;
49 
50 /* Each viewable area has it's own AnimManager. (but I can only think of
51  * animations in the MapWindow using this, so that could very well change)
52  */
53 class AnimManager {
54  MapWindow *map_window;
55  Screen *viewsurf;
56  Common::Rect viewport; // clip anims to location
57  Std::list<NuvieAnim *> anim_list; // in paint order
58  uint32 next_id;
59 
60  uint8 tile_pitch;
61 
62  sint16 mapwindow_x_offset;
63  sint16 mapwindow_y_offset;
64 
65  AnimIterator get_anim_iterator(uint32 anim_id);
66 
67 public:
68  AnimManager(sint16 x, sint16 y, Screen *screen = nullptr, Common::Rect *clipto = nullptr);
69  ~AnimManager() {
70  destroy_all();
71  }
72 
73  void update();
74  void display(bool top_anims = false);
75 
76  Screen *get_surface() {
77  return viewsurf;
78  }
79  void set_surface(Screen *screen) {
80  viewsurf = screen;
81  }
82  void set_area(Common::Rect clipto) {
83  viewport = clipto;
84  }
85  void set_tile_pitch(uint8 p) {
86  tile_pitch = p;
87  }
88  uint8 get_tile_pitch() const {
89  return tile_pitch;
90  }
91 
92 //new_anim(new ExplosiveAnim(speed));
93  sint32 new_anim(NuvieAnim *new_anim);
94  void destroy_all();
95  bool destroy_anim(uint32 anim_id);
96  bool destroy_anim(NuvieAnim *anim_pt);
97 
98  NuvieAnim *get_anim(uint32 anim_id);
99 
100  void drawTile(const Tile *tile, uint16 x, uint16 y);
101  void drawTileAtWorldCoords(const Tile *tile, uint16 wx, uint16 wy, uint16 add_x = 0, uint16 add_y = 0);
102  void drawText(Font *font, const char *text, uint16 x, uint16 y);
103 };
104 
105 
106 /* Contains methods to support management, continuous display, and movement of
107  * animation across viewport.
108  */
109 /* FIXME: The return of update() is not very useful. If an anim isn't
110  * redrawn then it just disappears on next MapWindow::Display(). If you don't
111  * want it to appear just delete it.*/
112 class NuvieAnim: public CallBack {
113 protected:
114  friend class AnimManager;
115  AnimManager *anim_manager; // set by anim_manager when adding to list
116 
117  uint32 id_n; // unique
118 
119  sint32 vel_x, vel_y; // movement across viewport (pixels/second; min=10)
120  uint32 px, py; // location on surface
121  uint32 last_move_time; // last time when update_position() moved (ticks)
122 
123  bool safe_to_delete; // can animmgr delete me?
124  bool updated; // call display
125  bool running;
126  bool paused;
127  bool top_anim; //animate on top of mapwindow.
128 
129  // return false if animation doesn't need redraw
130  virtual bool update() {
131  return true;
132  }
133  virtual void display() = 0;
134 
135  void update_position();
136 
137 public:
138  NuvieAnim();
139  ~NuvieAnim() override;
140 
141  void pause() {
142  paused = true;
143  }
144  void unpause() {
145  paused = false;
146  }
147  bool is_paused() const {
148  return paused;
149  }
150 
151  virtual MapCoord get_location() {
152  return MapCoord(px, py, 0);
153  }
154  uint32 get_id() const {
155  return id_n;
156  }
157 
158  void set_safe_to_delete(bool val) {
159  safe_to_delete = val;
160  }
161  void set_velocity(sint32 sx, sint32 sy) {
162  vel_x = sx;
163  vel_y = sy;
164  }
165  void set_velocity_for_speed(sint16 xdir, sint16 ydir, uint32 spd);
166 
167  virtual void stop() {
168  updated = running = false;
169  }
170  virtual void start() { }
171  uint16 message(uint16 msg, void *msg_data = nullptr, void *my_data = nullptr) {
172  if (callback_target) return (CallBack::message(msg, msg_data, my_data));
173  else return 0;
174  }
175 
176  virtual void move(uint32 x, uint32 y, uint32 add_x = 0, uint32 add_y = 0) {
177  px = x;
178  py = y;
179  }
180  virtual void shift(sint32 sx, sint32 sy) {
181  px += sx;
182  py += sy;
183  }
184 
185 // void set_flags();
186 // ANIM_ONTOP
187 // ANIM_ONBOTTOM
188 };
189 
190 
191 /* Tile placement & data for TileAnim
192  */
193 typedef struct {
194  sint16 pos_x, pos_y; // map position relative to Anim tx,ty
195  uint16 px, py; // pixel offset from pos_x,pos_y
196  Tile *tile;
198 
199 
200 /* Animation using game tiles
201  */
202 class TileAnim : public NuvieAnim {
203 protected:
204  MapWindow *_mapWindow;
205  uint32 _tx, _ty, // location on surface: in increments of "tile_pitch"
206  _px, _py; // location on surface: pixel offset from tx,ty
207 
209 
210  void display() override;
211 
212 public:
213  TileAnim();
214  ~TileAnim() override;
215 
216  MapCoord get_location() override {
217  return MapCoord(_tx, _ty, 0);
218  }
219  void get_offset(uint32 &x_add, uint32 &y_add) const {
220  x_add = _px;
221  y_add = _py;
222  }
223  sint32 get_tile_id(PositionedTile *find_tile);
224 
225  void move(uint32 x, uint32 y, uint32 add_x = 0, uint32 add_y = 0) override {
226  _tx = x;
227  _ty = y;
228  _px = add_x;
229  _py = add_y;
230  }
231  void shift(sint32 sx, sint32 sy) override;
232  void shift_tile(uint32 ptile_num, sint32 sx, sint32 sy);
233  void move_tile(PositionedTile *ptile, uint32 x, uint32 y);
234 
235 
236  PositionedTile *add_tile(Tile *tile, sint16 x, sint16 y, uint16 add_x = 0, uint16 add_y = 0);
237  void remove_tile(uint32 i = 0);
238  void remove_tile(PositionedTile *p_tile);
239 };
240 
241 
242 /* TileAnim using a timed event.
243  */
244 class TimedAnim: public TileAnim {
245 protected:
246  TimedCallback *timer;
247 public:
248  TimedAnim() {
249  timer = nullptr;
250  }
251  ~TimedAnim() override {
252  stop_timer();
253  }
254  void start_timer(uint32 delay) {
255  if (!timer) timer = new TimedCallback(this, nullptr, delay, true);
256  }
257  void stop_timer() {
258  if (timer) {
259  timer->clear_target();
260  timer = nullptr;
261  }
262  }
263 
264  void stop() override {
265  stop_timer();
266  NuvieAnim::stop();
267  }
268 };
269 
270 
271 // OR these together to tell a TossAnim what to intercept
272 #define TOSS_TO_BLOCKING 0x01
273 #define TOSS_TO_ACTOR 0x02
274 #define TOSS_TO_OBJECT 0x04
275 
276 /* A TileAnim that can intercept objects in the world. Start selected tile at
277  * source, and move across viewport to target. The tile is rotated by the
278  * degrees argument passed to the constructor.
279  */
280 class TossAnim : public TileAnim {
281 protected:
282  ActorManager *actor_manager;
283  ObjManager *obj_manager;
284  Map *map;
285 
286  MapCoord *src, *target;
287  uint32 start_px, start_py, target_px, target_py;
288  uint8 mapwindow_level; // level of map being viewed
289  uint16 speed; // movement speed in pixels per second (X and Y speed can't be set independently)
290 
291  Tile *toss_tile;
292  uint8 blocking; // stop_flags
293  uint8 tile_center; // tile_pitch / 2
294  float tanS; // Ydiff/Xdiff, between src and target (for movement velocity)
295  sint16 old_relpos; // when moving diagonally, last relative position on minor axis
296  float x_left, y_left; // when unable to move in a call, fractional movement values are collected here
297  uint16 x_dist, y_dist; // distances from start->target on X-axis & Y-axis
298 
299  bool update() override;
300  MapCoord get_location() override;
301 
302  void display() override;
303 
304 public:
305  TossAnim(const Tile *tile, const MapCoord &start, const MapCoord &stop, uint16 pixels_per_sec, uint8 stop_flags = 0);
306  TossAnim(Obj *obj, uint16 degrees, const MapCoord &start, const MapCoord &stop, uint16 pixels_per_sec, uint8 stop_flags = 0);
307  ~TossAnim() override;
308 
309  void init(const Tile *tile, uint16 degrees, const MapCoord &start, const MapCoord &stop, uint16 pixels_per_sec, uint8 stop_flags);
310  void start() override;
311  void stop() override;
312  uint32 update_position(uint32 max_move = 0);
313  inline void accumulate_moves(float moves, sint32 &x_move, sint32 &y_move, sint8 xdir, sint8 ydir);
314 
315  // Virtual functions are called when the tile hits something.
316  virtual void hit_target();
317  virtual void hit_object(Obj *obj);
318  virtual void hit_actor(Actor *actor);
319  virtual void hit_blocking(const MapCoord &obj_loc);
320 };
321 
322 // This is for off-center tiles. The tile will be moved down by the
323 // shift amount if moving right, and up if moving left. (and rotated)
325  uint16 tile_num;
326  sint8 shift; // plus or minus vertical position
327 };
328 extern const struct tossanim_tile_shifts_s tossanim_tile_shifts[];
329 
330 /* a line of fire */
331 typedef struct {
332  PositionedTile *tile; // last associated sprite
333  MapCoord direction; // where the explosion sprites are going
334  uint32 travelled; // distance this fire line has travelled
336 
337 /* SuperBomberman! Toss fireballs in multiple directions from source out.
338  */
339 class ExplosiveAnim : public TimedAnim {
340  MapCoord center;
341  uint32 radius; // num. of spaces from center
342  vector<ExplosiveAnimSegment> flame; // lines of fire from the center
343  uint16 exploding_tile_num; // fireball effect tile_num
344  vector<MapEntity> hit_items; // things the explosion has hit
345 
346 public:
347  ExplosiveAnim(const MapCoord &start, uint32 size);
348  ~ExplosiveAnim() override;
349  void start() override;
350  uint16 callback(uint16 msg, CallBack *caller, void *data) override;
351  bool update() override;
352  bool already_hit(const MapEntity &ent);
353  void hit_object(Obj *obj);
354  void hit_actor(Actor *actor);
355  void get_shifted_location(uint16 &x, uint16 &y, uint16 &px, uint16 &py,
356  uint32 sx, uint32 sy);
357 };
358 
359 typedef struct {
360  MapCoord target;
361  U6LineWalker *lineWalker;
362  PositionedTile *p_tile;
363  uint8 update_idx;
364  uint16 rotation;
365  uint16 rotation_amount;
366  float current_deg;
367  bool isRunning;
369 
370 class ProjectileAnim : public TileAnim {
371  MapCoord src;
373  uint16 tile_num; // fireball effect tile_num
374  uint8 src_tile_y_offset; //amount to offset src_tile when rotating. Used by arrows and bolts
375  vector<MapEntity> hit_items; // things the projectile has hit
376  uint16 stopped_count;
377  uint8 speed; //number of pixels to move in a single update.
378 
379  bool leaveTrailFlag;
380 public:
381  ProjectileAnim(uint16 tileNum, MapCoord *start, vector<MapCoord> target, uint8 animSpeed, bool leaveTrailFlag = false, uint16 initialTileRotation = 0, uint16 rotationAmount = 0, uint8 src_y_offset = 0);
382  ~ProjectileAnim() override;
383  void start() override;
384 
385  bool update() override;
386 
387 protected:
388  void hit_entity(MapEntity entity);
389  bool already_hit(const MapEntity &ent);
390 
391 };
392 
393 class WingAnim : public TileAnim {
394  MapCoord target;
395  sint32 x, y, finish_x;
396  sint16 x_inc;
397  Tile *wing_top[2];
398  Tile *wing_bottom[2];
399 
400  PositionedTile *p_tile_top;
401  PositionedTile *p_tile_bottom;
402 
403 public:
404  WingAnim(const MapCoord &target);
405  ~WingAnim() override;
406  void start() override;
407  bool update() override;
408 
409 };
410 
411 typedef struct {
412  uint16 x, y;
413  PositionedTile *p_tile;
414  uint8 length_left;
415 } Hailstone;
416 
417 #define HAILSTORM_ANIM_MAX_STONES 6
418 class HailstormAnim : public TileAnim {
419  MapCoord target;
420 
421  Tile *hailstone_tile;
422 
423  Hailstone hailstones[HAILSTORM_ANIM_MAX_STONES];
424  uint8 num_hailstones_left;
425  uint8 num_active;
426 
427 public:
428  HailstormAnim(const MapCoord &t);
429  ~HailstormAnim() override;
430  void start() override;
431  bool update() override;
432 
433 protected:
434  sint8 find_free_hailstone();
435 
436 };
437 
438 /* Display hit effect over an actor or location for a certain duration.
439  */
440 class HitAnim : public TimedAnim {
441  Actor *hit_actor;
442 
443  bool update() override;
444 
445 public:
446  HitAnim(const MapCoord &loc);
447  HitAnim(Actor *actor);
448 
449  uint16 callback(uint16 msg, CallBack *caller, void *msg_data) override;
450  void start() override {
451  start_timer(300);
452  }
453 };
454 
455 class TextAnim : public TimedAnim {
456  Std::string text;
457  Font *font;
458  uint32 duration;
459 
460 public:
461  TextAnim(Std::string text, MapCoord loc, uint32 dur);
462  ~TextAnim() override;
463  uint16 callback(uint16 msg, CallBack *caller, void *msg_data) override;
464  void start() override {
465  start_timer(duration);
466  }
467 
468  void display() override;
469 };
470 
471 class TileFadeAnim : public TileAnim {
472  uint16 pixel_count;
473  Tile *anim_tile;
474  Tile *to_tile;
475  bool should_delete_to_tile;
476  uint16 pixels_per_update; //the number of pixels to change in each update.
477  unsigned char mask[256];
478 
479 public:
480  TileFadeAnim();
481  TileFadeAnim(const MapCoord &loc, Tile *from, Tile *to, uint16 speed);
482  TileFadeAnim(const MapCoord &loc, Tile *from, uint8 color_from, uint8 color_to, bool reverse, uint16 speed);
483  ~TileFadeAnim() override;
484 
485  bool update() override;
486 protected:
487  void init(uint16 speed);
488 };
489 
490 } // End of namespace Nuvie
491 } // End of namespace Ultima
492 
493 #endif
Definition: vector.h:39
Definition: map_window.h:73
Definition: actor.h:178
Definition: anim_manager.h:244
Definition: obj.h:84
Definition: anim_manager.h:455
Definition: list.h:39
Definition: rect.h:144
Definition: map.h:147
Definition: atari-screen.h:60
Definition: actor_manager.h:42
Definition: timed_event.h:209
Definition: anim_manager.h:393
Definition: screen.h:41
Definition: anim_manager.h:359
Definition: detection.h:27
Definition: u6_line_walker.h:30
Definition: anim_manager.h:471
Definition: map_entity.h:45
Definition: anim_manager.h:280
Definition: call_back.h:50
Definition: string.h:30
Definition: anim_manager.h:440
Definition: anim_manager.h:331
Definition: anim_manager.h:202
Definition: map.h:84
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: anim_manager.h:418
Definition: containers.h:200
Definition: obj_manager.h:75
Definition: anim_manager.h:411
Definition: anim_manager.h:339
Definition: anim_manager.h:112
Definition: list_intern.h:51
Definition: anim_manager.h:370
Definition: tile_manager.h:113
Definition: anim_manager.h:193
Definition: anim_manager.h:53
Definition: anim_manager.h:324
Definition: font.h:42