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