ScummVM API documentation
objects.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 ALCACHOFA_OBJECTS_H
23 #define ALCACHOFA_OBJECTS_H
24 
25 #include "alcachofa/shape.h"
26 #include "alcachofa/graphics.h"
27 
28 #include "common/serializer.h"
29 
30 namespace Alcachofa {
31 
32 class Room;
33 class Process;
34 struct Task;
35 
36 class ObjectBase {
37 public:
38  static constexpr const char *kClassName = "CObjetoBase";
39  ObjectBase(Room *room, const char *name);
40  ObjectBase(Room *room, Common::ReadStream &stream);
41  virtual ~ObjectBase() {}
42 
43  inline const Common::String &name() const { return _name; }
44  inline Room *&room() { return _room; }
45  inline Room *room() const { return _room; }
46  inline bool isEnabled() const { return _isEnabled; }
47 
48  virtual void toggle(bool isEnabled);
49  virtual void draw();
50  virtual void drawDebug();
51  virtual void update();
52  virtual void loadResources();
53  virtual void freeResources();
54  virtual void syncGame(Common::Serializer &serializer);
55  virtual Graphic *graphic();
56  virtual Shape *shape();
57  virtual const char *typeName() const;
58 
59 private:
60  Common::String _name;
61  bool _isEnabled = true;
62  Room *_room = nullptr;
63 };
64 
65 class PointObject : public ObjectBase {
66 public:
67  static constexpr const char *kClassName = "CObjetoPunto";
68  PointObject(Room *room, Common::ReadStream &stream);
69 
70  inline Common::Point &position() { return _pos; }
71  inline Common::Point position() const { return _pos; }
72  const char *typeName() const override;
73 
74 private:
75  Common::Point _pos;
76 };
77 
78 enum class GraphicObjectType : byte
79 {
80  Normal,
81  NormalPosterize, // the posterization is not actually applied in the original engine
82  Effect
83 };
84 
85 class GraphicObject : public ObjectBase {
86 public:
87  static constexpr const char *kClassName = "CObjetoGrafico";
88  GraphicObject(Room *room, Common::ReadStream &stream);
89  ~GraphicObject() override {}
90 
91  void draw() override;
92  void drawDebug() override;
93  void loadResources() override;
94  void freeResources() override;
95  void syncGame(Common::Serializer &serializer) override;
96  Graphic *graphic() override;
97  const char *typeName() const override;
98 
99  Task *animate(Process &process);
100 
101 protected:
102  GraphicObject(Room *room, const char *name);
103 
104  Graphic _graphic;
105  GraphicObjectType _type;
106  int32 _posterizeAlpha;
107 };
108 
109 class SpecialEffectObject final : public GraphicObject {
110 public:
111  static constexpr const char *kClassName = "CObjetoGraficoMuare";
113 
114  void draw() override;
115  const char *typeName() const override;
116 
117 private:
118  static constexpr const float kShiftSpeed = 1 / 256.0f;
119  Common::Point _topLeft, _bottomRight;
120  Math::Vector2d _texShift;
121 };
122 
123 class ShapeObject : public ObjectBase {
124 public:
125  ShapeObject(Room *room, Common::ReadStream &stream);
126  ~ShapeObject() override {}
127 
128  inline int8 order() const { return _order; }
129  inline bool isNewlySelected() const { return _isNewlySelected; }
130  inline bool wasSelected() const { return _wasSelected; }
131 
132  void update() override;
133  void syncGame(Common::Serializer &serializer) override;
134  Shape *shape() override;
135  virtual CursorType cursorType() const;
136  virtual void onHoverStart();
137  virtual void onHoverEnd();
138  virtual void onHoverUpdate();
139  virtual void onClick();
140  const char *typeName() const override;
141  void markSelected();
142 
143 protected:
144  void updateSelection();
145 
146  // original inconsistency: base class has member that is read by the sub classes
147  int8 _order = 0;
148 private:
149  Shape _shape;
150  CursorType _cursorType;
151  bool _isNewlySelected = false,
152  _wasSelected = false;
153 };
154 
155 class PhysicalObject : public ShapeObject {
156 public:
157  PhysicalObject(Room *room, Common::ReadStream &stream);
158  const char *typeName() const override;
159 };
160 
161 class MenuButton : public PhysicalObject {
162 public:
163  static constexpr const char *kClassName = "CBotonMenu";
164  MenuButton(Room *room, Common::ReadStream &stream);
165  ~MenuButton() override {}
166 
167  inline int32 actionId() const { return _actionId; }
168  inline bool &isInteractable() { return _isInteractable; }
169 
170  void draw() override;
171  void update() override;
172  void loadResources() override;
173  void freeResources() override;
174  void onHoverUpdate() override;
175  void onClick() override;
176  virtual void trigger();
177  const char *typeName() const override;
178 
179 private:
180  bool
181  _isInteractable = true,
182  _isClicked = false,
183  _triggerNextFrame = false;
184  int32 _actionId;
185  Graphic
186  _graphicNormal,
187  _graphicHovered,
188  _graphicClicked,
189  _graphicDisabled;
190  FakeLock _interactionLock;
191 };
192 
193 // some of the UI elements are only used for the multiplayer menus
194 // so are currently not needed
195 
196 class InternetMenuButton final : public MenuButton {
197 public:
198  static constexpr const char *kClassName = "CBotonMenuInternet";
200 
201  const char *typeName() const override;
202 };
203 
204 class OptionsMenuButton final : public MenuButton {
205 public:
206  static constexpr const char *kClassName = "CBotonMenuOpciones";
207  OptionsMenuButton(Room *room, Common::ReadStream &stream);
208 
209  void update() override;
210  void trigger() override;
211  const char *typeName() const override;
212 };
213 
214 class MainMenuButton final : public MenuButton {
215 public:
216  static constexpr const char *kClassName = "CBotonMenuPrincipal";
217  MainMenuButton(Room *room, Common::ReadStream &stream);
218 
219  void update() override;
220  void trigger() override;
221  const char *typeName() const override;
222 };
223 
224 class PushButton final : public PhysicalObject {
225 public:
226  static constexpr const char *kClassName = "CPushButton";
227  PushButton(Room *room, Common::ReadStream &stream);
228 
229  const char *typeName() const override;
230 
231 private:
232  bool _alwaysVisible;
233  Graphic _graphic1, _graphic2;
234  int32 _actionId;
235 };
236 
237 class EditBox final : public PhysicalObject {
238 public:
239  static constexpr const char *kClassName = "CEditBox";
240  EditBox(Room *room, Common::ReadStream &stream);
241 
242  const char *typeName() const override;
243 
244 private:
245  int32 i1;
246  Common::Point p1;
247  Common::String _labelId;
248  bool b1;
249  int32 i3, i4, i5,
250  _fontId;
251 };
252 
253 class CheckBox : public PhysicalObject {
254 public:
255  static constexpr const char *kClassName = "CCheckBox";
256  CheckBox(Room *room, Common::ReadStream &stream);
257  ~CheckBox() override {}
258 
259  inline bool &isChecked() { return _isChecked; }
260  inline int32 actionId() const { return _actionId; }
261 
262  void draw() override;
263  void update() override;
264  void loadResources() override;
265  void freeResources() override;
266  void onHoverUpdate() override;
267  void onClick() override;
268  virtual void trigger();
269  const char *typeName() const override;
270 
271 private:
272  bool
273  _isChecked = false,
274  _wasClicked = false;
275  Graphic
276  _graphicUnchecked,
277  _graphicChecked,
278  _graphicHovered,
279  _graphicClicked;
280  int32 _actionId = 0;
281  uint32 _clickTime = 0;
282 };
283 
284 class SlideButton final : public ObjectBase {
285 public:
286  static constexpr const char *kClassName = "CSlideButton";
287  SlideButton(Room *room, Common::ReadStream &stream);
288  ~SlideButton() override {}
289 
290  inline float &value() { return _value; }
291 
292  void draw() override;
293  void update() override;
294  void loadResources() override;
295  void freeResources() override;
296  const char *typeName() const override;
297 
298 private:
299  bool isMouseOver() const;
300 
301  float _value = 0;
302  int32 _valueId;
303  Common::Point _minPos, _maxPos;
304  Graphic
305  _graphicIdle,
306  _graphicHovered,
307  _graphicClicked;
308 };
309 
310 class CheckBoxAutoAdjustNoise final : public CheckBox {
311 public:
312  static constexpr const char *kClassName = "CCheckBoxAutoAjustarRuido";
314 
315  const char *typeName() const override;
316 };
317 
318 class IRCWindow final : public ObjectBase {
319 public:
320  static constexpr const char *kClassName = "CVentanaIRC";
321  IRCWindow(Room *room, Common::ReadStream &stream);
322 
323  const char *typeName() const override;
324 
325 private:
326  Common::Point _p1, _p2;
327 };
328 
329 class MessageBox final : public ObjectBase {
330 public:
331  static constexpr const char *kClassName = "CMessageBox";
332  MessageBox(Room *room, Common::ReadStream &stream);
333  ~MessageBox() override {}
334 
335  const char *typeName() const override;
336 
337 private:
338  Graphic
339  _graph1,
340  _graph2,
341  _graph3,
342  _graph4,
343  _graph5;
344 };
345 
346 class VoiceMeter final : public GraphicObject {
347 public:
348  static constexpr const char *kClassName = "CVuMeter";
349  VoiceMeter(Room *room, Common::ReadStream &stream);
350 
351  const char *typeName() const override;
352 };
353 
354 class Item : public GraphicObject { //-V690
355 public:
356  static constexpr const char *kClassName = "CObjetoInventario";
357  Item(Room *room, Common::ReadStream &stream);
358  Item(const Item &other);
359  // no copy-assign operator as it is non-sensical, the copy ctor is a special case for item-handling
360 
361  void draw() override;
362  const char *typeName() const override;
363  void trigger();
364 };
365 
367 public:
369  virtual ~ITriggerableObject() {}
370 
371  inline Direction interactionDirection() const { return _interactionDirection; }
372  inline Common::Point interactionPoint() const { return _interactionPoint; }
373 
374  virtual void trigger(const char *action) = 0;
375 
376 protected:
377  void onClick();
378 
379  Common::Point _interactionPoint;
380  Direction _interactionDirection = Direction::Right;
381 };
382 
384 public:
385  static constexpr const char *kClassName = "CObjetoTipico";
387  ~InteractableObject() override {}
388 
389  void drawDebug() override;
390  void onClick() override;
391  void trigger(const char *action) override;
392  void toggle(bool isEnabled) override;
393  const char *typeName() const override;
394 
395 private:
396  Common::String _relatedObject;
397 };
398 
399 class Door final : public InteractableObject {
400 public:
401  static constexpr const char *kClassName = "CPuerta";
402  Door(Room *room, Common::ReadStream &stream);
403 
404  inline const Common::String &targetRoom() const { return _targetRoom; }
405  inline const Common::String &targetObject() const { return _targetObject; }
406  inline Direction characterDirection() const { return _characterDirection; }
407 
408  CursorType cursorType() const override;
409  void onClick() override;
410  void trigger(const char *action) override;
411  const char *typeName() const override;
412 
413 private:
414  Common::String _targetRoom, _targetObject;
415  Direction _characterDirection;
416  uint32 _lastClickTime = 0;
417 };
418 
419 class Character : public ShapeObject, public ITriggerableObject {
420 public:
421  static constexpr const char *kClassName = "CPersonaje";
422  Character(Room *room, Common::ReadStream &stream);
423  ~Character() override {}
424 
425  void update() override;
426  void draw() override;
427  void drawDebug() override;
428  void loadResources() override;
429  void freeResources() override;
430  void syncGame(Common::Serializer &serializer) override;
431  Graphic *graphic() override;
432  void onClick() override;
433  void trigger(const char *action) override;
434  const char *typeName() const override;
435 
436  Task *sayText(Process &process, int32 dialogId);
437  void resetTalking();
438  void talkUsing(ObjectBase *talkObject);
439  Task *animate(Process &process, ObjectBase *animateObject);
440  Task *lerpLodBias(Process &process, float targetLodBias, int32 durationMs);
441  inline float &lodBias() { return _lodBias; }
442  inline bool &isSpeaking() { return _isSpeaking; }
443 
444 protected:
445  friend struct SayTextTask;
446  friend struct AnimateCharacterTask;
447  void syncObjectAsString(Common::Serializer &serializer, ObjectBase *&object);
448  void updateTalkingAnimation();
449 
450  Graphic _graphicNormal, _graphicTalking;
451 
452  bool _isTalking = false;
453  bool _isSpeaking = true;
454  int _curDialogId = -1;
455  float _lodBias = 0.0f;
456  ObjectBase
457  *_curAnimateObject = nullptr,
458  *_curTalkingObject = nullptr;
459 };
460 
461 class WalkingCharacter : public Character {
462 public:
463  static constexpr const char *kClassName = "CPersonajeAnda";
464  WalkingCharacter(Room *room, Common::ReadStream &stream);
465  ~WalkingCharacter() override {}
466 
467  inline bool isWalking() const { return _isWalking; }
468  inline Common::Point position() const { return _currentPos; }
469  inline float stepSizeFactor() const { return _stepSizeFactor; }
470 
471  void update() override;
472  void draw() override;
473  void drawDebug() override;
474  void loadResources() override;
475  void freeResources() override;
476  void syncGame(Common::Serializer &serializer) override;
477  virtual void walkTo(
478  Common::Point target,
479  Direction endDirection = Direction::Invalid,
480  ITriggerableObject *activateObject = nullptr,
481  const char *activateAction = nullptr);
482  void stopWalking(Direction direction = Direction::Invalid);
483  void setPosition(Common::Point target);
484  const char *typeName() const override;
485 
486  Task *waitForArrival(Process &process);
487 
488 protected:
489  virtual void onArrived();
490  void updateWalking();
491  void updateWalkingAnimation();
492 
493  inline Animation *currentAnimationOf(Common::ScopedPtr<Animation> *const animations) {
494  Animation *animation = animations[(int)_direction].get();
495  if (animation == nullptr)
496  animation = animations[0].get();
497  assert(animation != nullptr);
498  return animation;
499  }
500  inline Animation *walkingAnimation() { return currentAnimationOf(_walkingAnimations); }
501  inline Animation *talkingAnimation() { return currentAnimationOf(_talkingAnimations); }
502 
504  _walkingAnimations[kDirectionCount],
505  _talkingAnimations[kDirectionCount];
506 
507  int32
508  _lastWalkAnimFrame = -1,
509  _walkedDistance = 0,
510  _curPathPointI = -1;
511  float _stepSizeFactor = 0.0f;
513  _sourcePos,
514  _currentPos;
515  bool _isWalking = false;
516  Direction
517  _direction = Direction::Right,
518  _endWalkingDirection = Direction::Invalid;
519  Common::Stack<Common::Point> _pathPoints;
520 };
521 
523  int32 _dialogId = -1;
524  int32 _yPosition = 0;
525  int32 _returnValue = 0;
526 };
527 
528 class MainCharacter final : public WalkingCharacter {
529 public:
530  static constexpr const char *kClassName = "CPersonajePrincipal";
531  MainCharacter(Room *room, Common::ReadStream &stream);
532  ~MainCharacter() override;
533 
534  inline MainCharacterKind kind() const { return _kind; }
535  inline ObjectBase *&currentlyUsing() { return _currentlyUsingObject; }
536  inline ObjectBase *currentlyUsing() const { return _currentlyUsingObject; }
537  inline Color &color() { return _color; }
538  inline uint8 &alphaPremultiplier() { return _alphaPremultiplier; }
539  inline FakeSemaphore &semaphore() { return _semaphore; }
540  bool isBusy() const;
541 
542  void update() override;
543  void draw() override;
544  void syncGame(Common::Serializer &serializer) override;
545  const char *typeName() const override;
546  void walkTo(
547  Common::Point target,
548  Direction endDirection = Direction::Invalid,
549  ITriggerableObject *activateObject = nullptr,
550  const char *activateAction = nullptr) override;
551  void walkToMouse();
552  bool clearTargetIf(const ITriggerableObject *target);
553  void clearInventory();
554  bool hasItem(const Common::String &name) const;
555  void pickup(const Common::String &name, bool putInHand);
556  void drop(const Common::String &name);
557  void addDialogLine(int32 dialogId);
558  void setLastDialogReturnValue(int32 returnValue);
559  Task *dialogMenu(Process &process);
560  void resetUsingObjectAndDialogMenu();
561 
562 protected:
563  void onArrived() override;
564 
565 private:
566  friend class Inventory;
567  friend struct DialogMenuTask;
568  Item *getItemByName(const Common::String &name) const;
569  void drawInner();
570 
571  Common::Array<Item *> _items;
572  Common::Array<DialogMenuLine> _dialogLines;
573  ObjectBase *_currentlyUsingObject = nullptr;
574  MainCharacterKind _kind;
575  FakeSemaphore _semaphore;
576  ITriggerableObject *_activateObject = nullptr;
577  const char *_activateAction = nullptr;
578  Color _color = kWhite;
579  uint8 _alphaPremultiplier = 255;
580 };
581 
582 class Background final : public GraphicObject {
583 public:
584  Background(Room *room, const Common::String &animationFileName, int16 scale);
585  const char *typeName() const override;
586 };
587 
588 class FloorColor final : public ObjectBase {
589 public:
590  static constexpr const char *kClassName = "CSueloColor";
591  FloorColor(Room *room, Common::ReadStream &stream);
592  ~FloorColor() override {}
593 
594  void update() override;
595  void drawDebug() override;
596  Shape *shape() override;
597  const char *typeName() const override;
598 
599 private:
600  FloorColorShape _shape;
601 };
602 
603 }
604 
605 #endif // ALCACHOFA_OBJECTS_H
Definition: objects.h:461
Definition: objects.h:354
Definition: alcachofa.h:45
Definition: common.h:69
Definition: str.h:59
Definition: objects.h:522
Definition: scheduler.h:84
Definition: scheduler.h:164
Definition: objects.h:36
Definition: objects.h:123
Definition: array.h:52
Definition: graphics.h:257
Definition: objects.h:253
Definition: objects.h:109
Definition: objects.h:346
Definition: objects.h:329
Definition: graphics.h:184
Definition: objects.h:582
Definition: ptr.h:572
Definition: objects.h:214
Definition: serializer.h:79
Definition: shape.h:238
Definition: objects.h:161
Definition: objects.h:284
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: objects.h:310
Definition: objects.h:419
Definition: objects.h:196
Definition: objects.h:588
Definition: rooms.h:119
Definition: objects.h:366
Definition: rect.h:144
Definition: objects.h:318
Definition: objects.h:528
Definition: shape.h:118
Definition: objects.h:155
Definition: objects.h:399
Definition: objects.h:224
Definition: objects.h:65
Definition: stream.h:385
Definition: rooms.h:31
Definition: objects.h:85
Definition: objects.h:383
Definition: objects.h:204
This fake semaphore does not work in multi-threaded scenarios It is used as a safer option for a simp...
Definition: common.h:84
PointerType get() const
Definition: ptr.h:636
Definition: objects.h:237
Definition: common.h:98