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