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 
227 class OptionsMenuButton final : public MenuButton {
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 
237 class MainMenuButton final : public MenuButton {
238 public:
239  static constexpr const char *kClassName = "CBotonMenuPrincipal";
241 
242  void update() override;
243  void trigger() override;
244  const char *typeName() const override;
245 };
246 
247 class PushButton final : public PhysicalObject {
248 public:
249  static constexpr const char *kClassName = "CPushButton";
251 
252  const char *typeName() const override;
253 
254 private:
255  bool _alwaysVisible;
256  Graphic _graphic1, _graphic2;
257  int32 _actionId;
258 };
259 
260 class EditBox : public PhysicalObject {
261 public:
262  static constexpr const char *kClassName = "CEditBox";
263  EditBox(Room *room, Common::SeekableReadStream &stream);
264 
265  const char *typeName() const override;
266 
267 protected:
268  int32 i1 = 0;
269  Common::Point p1;
270  Common::String _labelId;
271  bool b1 = false;
272  int32 i3 = 0, i4 = 0, i5 = 0,
273  _fontId = 0;
274 };
275 
276 class EditBoxV2 final : public EditBox {
277 public:
278  EditBoxV2(Room *room, Common::SeekableReadStream &stream);
279 };
280 
281 class EditBoxV3 final : public EditBox {
282 public:
283  EditBoxV3(Room *room, Common::SeekableReadStream &stream);
284 };
285 
286 class CheckBox : public PhysicalObject {
287 public:
288  static constexpr const char *kClassName = "CCheckBox";
289  CheckBox(Room *room, Common::SeekableReadStream &stream);
290  ~CheckBox() override {}
291 
292  inline bool &isChecked() { return _isChecked; }
293  inline int32 actionId() const { return _actionId; }
294 
295  void draw() override;
296  void update() override;
297  void loadResources() override;
298  void freeResources() override;
299  void onHoverUpdate() override;
300  void onClick() override;
301  virtual void trigger();
302  const char *typeName() const override;
303 
304 private:
305  bool
306  _isChecked = false,
307  _wasClicked = false;
308  Graphic
309  _graphicUnchecked,
310  _graphicChecked,
311  _graphicHovered,
312  _graphicClicked;
313  int32 _actionId = 0;
314  uint32 _clickTime = 0;
315 };
316 
317 class SlideButton : public ObjectBase {
318 public:
319  static constexpr const char *kClassName = "CSlideButton";
321 
322  inline float &value() { return _value; }
323 
324  void draw() override;
325  void update() override;
326  void loadResources() override;
327  void freeResources() override;
328  const char *typeName() const override;
329 
330 protected:
331  bool isMouseOver() const;
332 
333  float _value = 0;
334  int32 _valueId = -1;
335  Common::Point _minPos, _maxPos;
336  Graphic
337  _graphicIdle,
338  _graphicHovered,
339  _graphicClicked;
340 };
341 
342 class SlideButtonV2 final : public SlideButton {
343 public:
345 };
346 
347 class SlideButtonV3 final : public SlideButton {
348 public:
350 };
351 
352 class CheckBoxAutoAdjustNoise final : public CheckBox {
353 public:
354  static constexpr const char *kClassName = "CCheckBoxAutoAjustarRuido";
356 
357  const char *typeName() const override;
358 };
359 
360 class IRCWindow final : public ObjectBase {
361 public:
362  static constexpr const char *kClassName = "CVentanaIRC";
363  IRCWindow(Room *room, Common::SeekableReadStream &stream);
364 
365  const char *typeName() const override;
366 
367 private:
368  Common::Point _p1, _p2;
369 };
370 
371 class MessageBox final : public ObjectBase {
372 public:
373  static constexpr const char *kClassName = "CMessageBox";
375  ~MessageBox() override {}
376 
377  const char *typeName() const override;
378 
379 private:
380  Graphic
381  _graph1,
382  _graph2,
383  _graph3,
384  _graph4,
385  _graph5;
386 };
387 
388 class VoiceMeter final : public GraphicObject {
389 public:
390  static constexpr const char *kClassName = "CVuMeter";
392 
393  const char *typeName() const override;
394 };
395 
396 class Item : public GraphicObject { //-V690
397 public:
398  static constexpr const char *kClassName = "CObjetoInventario";
399  Item(Room *room, Common::SeekableReadStream &stream);
400  Item(const Item &other);
401  // no copy-assign operator as it is non-sensical, the copy ctor is a special case for item-handling
402 
403  void draw() override;
404  const char *typeName() const override;
405  void trigger();
406 };
407 
409 public:
411  virtual ~ITriggerableObject() {}
412 
413  inline Direction interactionDirection() const { return _interactionDirection; }
414  inline Common::Point interactionPoint() const { return _interactionPoint; }
415 
416  virtual void trigger(const char *action) = 0;
417 
418 protected:
419  ITriggerableObject() = default;
420  void read(Common::SeekableReadStream &stream);
421  void onClick();
422 
423  Common::Point _interactionPoint;
424  Direction _interactionDirection = Direction::Right;
425 };
426 
428 public:
429  static constexpr const char *kClassName = "CObjetoTipico";
431  ~InteractableObject() override {}
432 
433  void drawDebug() override;
434  void onClick() override;
435  void trigger(const char *action) override;
436  void toggle(bool isEnabled) override;
437  const char *typeName() const override;
438 
439 private:
440  Common::String _relatedObject;
441 };
442 
443 class Door final : public InteractableObject {
444 public:
445  static constexpr const char *kClassName = "CPuerta";
446  Door(Room *room, Common::SeekableReadStream &stream);
447 
448  inline const Common::String &targetRoom() const { return _targetRoom; }
449  inline const Common::String &targetObject() const { return _targetObject; }
450  inline Direction characterDirection() const { return _characterDirection; }
451 
452  CursorType cursorType() const override;
453  void onClick() override;
454  void trigger(const char *action) override;
455  const char *typeName() const override;
456 
457 private:
458  Common::String _targetRoom, _targetObject;
459  Direction _characterDirection;
460  uint32 _lastClickTime = 0;
461 };
462 
463 class Character : public ShapeObject, public ITriggerableObject {
464 public:
465  static constexpr const char *kClassName = "CPersonaje";
466  Character(Room *room, Common::SeekableReadStream &stream);
467  ~Character() override {}
468 
469  void update() override;
470  void draw() override;
471  void drawDebug() override;
472  void loadResources() override;
473  void freeResources() override;
474  void syncGame(Common::Serializer &serializer) override;
475  Graphic *graphic() override;
476  void onClick() override;
477  void trigger(const char *action) override;
478  const char *typeName() const override;
479 
480  Task *sayText(Process &process, int32 dialogId);
481  void resetTalking();
482  void talkUsing(ObjectBase *talkObject);
483  Task *animate(Process &process, ObjectBase *animateObject);
484  Task *lerpLodBias(Process &process, float targetLodBias, int32 durationMs);
485  inline float &lodBias() { return _lodBias; }
486  inline bool &isSpeaking() { return _isSpeaking; }
487 
488 protected:
489  friend struct SayTextTask;
490  friend struct AnimateCharacterTask;
491  void syncObjectAsString(Common::Serializer &serializer, ObjectBase *&object);
492  void updateTalkingAnimation();
493 
494  Graphic _graphicNormal, _graphicTalking;
495 
496  bool _isTalking = false;
497  bool _isSpeaking = true;
498  int _curDialogId = -1;
499  float _lodBias = 0.0f;
500  ObjectBase
501  *_curAnimateObject = nullptr,
502  *_curTalkingObject = nullptr;
503 };
504 
505 class WalkingCharacter : public Character {
506 public:
507  static constexpr const char *kClassName = "CPersonajeAnda";
509  ~WalkingCharacter() override {}
510 
511  inline bool isWalking() const { return _isWalking; }
512  inline Common::Point position() const { return _currentPos; }
513  inline float stepSizeFactor() const { return _stepSizeFactor; }
514 
515  void update() override;
516  void draw() override;
517  void drawDebug() override;
518  void loadResources() override;
519  void freeResources() override;
520  void syncGame(Common::Serializer &serializer) override;
521  virtual void walkTo(
522  Common::Point target,
523  Direction endDirection = Direction::Invalid,
524  ITriggerableObject *activateObject = nullptr,
525  const char *activateAction = nullptr);
526  void stopWalking(Direction direction = Direction::Invalid);
527  void setPosition(Common::Point target);
528  const char *typeName() const override;
529 
530  Task *waitForArrival(Process &process);
531 
532 protected:
533  virtual void onArrived();
534  void updateWalking();
535  void updateWalkingAnimation();
536 
537  inline Animation *currentAnimationOf(Common::ScopedPtr<Animation> *const animations) {
538  Animation *animation = animations[(int)_direction].get();
539  if (animation == nullptr)
540  animation = animations[0].get();
541  assert(animation != nullptr);
542  return animation;
543  }
544  inline Animation *walkingAnimation() { return currentAnimationOf(_walkingAnimations); }
545  inline Animation *talkingAnimation() { return currentAnimationOf(_talkingAnimations); }
546 
548  _walkingAnimations[kDirectionCount],
549  _talkingAnimations[kDirectionCount];
550 
551  int32
552  _lastWalkAnimFrame = -1,
553  _walkedDistance = 0,
554  _curPathPointI = -1;
555  float _stepSizeFactor = 0.0f;
557  _sourcePos,
558  _currentPos;
559  bool _isWalking = false;
560  Direction
561  _direction = Direction::Right,
562  _endWalkingDirection = Direction::Invalid;
563  Common::Stack<Common::Point> _pathPoints;
564 };
565 
567  int32 _dialogId = -1;
568  int32 _yPosition = 0;
569  int32 _returnValue = 0;
570 };
571 
572 class MainCharacter final : public WalkingCharacter {
573 public:
574  static constexpr const char *kClassName = "CPersonajePrincipal";
576  ~MainCharacter() override;
577 
578  inline MainCharacterKind kind() const { return _kind; }
579  inline ObjectBase *&currentlyUsing() { return _currentlyUsingObject; }
580  inline ObjectBase *currentlyUsing() const { return _currentlyUsingObject; }
581  inline Color &color() { return _color; }
582  inline uint8 &alphaPremultiplier() { return _alphaPremultiplier; }
583  inline FakeSemaphore &semaphore() { return _semaphore; }
584  bool isBusy() const;
585 
586  void update() override;
587  void draw() override;
588  void syncGame(Common::Serializer &serializer) override;
589  const char *typeName() const override;
590  void walkTo(
591  Common::Point target,
592  Direction endDirection = Direction::Invalid,
593  ITriggerableObject *activateObject = nullptr,
594  const char *activateAction = nullptr) override;
595  void walkToMouse();
596  bool clearTargetIf(const ITriggerableObject *target);
597  void clearInventory();
598  bool hasItem(const Common::String &name) const;
599  void pickup(const Common::String &name, bool putInHand);
600  void drop(const Common::String &name);
601  void addDialogLine(int32 dialogId);
602  void setLastDialogReturnValue(int32 returnValue);
603  Task *dialogMenu(Process &process);
604  void resetUsingObjectAndDialogMenu();
605 
606 protected:
607  void onArrived() override;
608 
609 private:
610  friend class Inventory;
611  friend struct DialogMenuTask;
612  Item *getItemByName(const Common::String &name) const;
613  void drawInner();
614 
615  Common::Array<Item *> _items;
616  Common::Array<DialogMenuLine> _dialogLines;
617  ObjectBase *_currentlyUsingObject = nullptr;
618  MainCharacterKind _kind;
619  FakeSemaphore _semaphore;
620  ITriggerableObject *_activateObject = nullptr;
621  const char *_activateAction = nullptr;
622  Color _color = kWhite;
623  uint8 _alphaPremultiplier = 255;
624 };
625 
626 class Background final : public GraphicObject {
627 public:
628  Background(Room *room, const Common::String &animationFileName, int16 scale);
629  const char *typeName() const override;
630 };
631 
632 class FloorColor final : public ObjectBase {
633 public:
634  static constexpr const char *kClassName = "CSueloColor";
636  ~FloorColor() override {}
637 
638  void update() override;
639  void drawDebug() override;
640  Shape *shape() override;
641  const char *typeName() const override;
642 
643 private:
644  FloorColorShape _shape;
645 };
646 
647 }
648 
649 #endif // ALCACHOFA_OBJECTS_H
Definition: objects.h:505
Definition: objects.h:396
Definition: alcachofa.h:45
Definition: common.h:78
Definition: str.h:59
Definition: objects.h:566
Definition: scheduler.h:84
Definition: scheduler.h:164
Definition: objects.h:347
Definition: objects.h:37
Definition: objects.h:124
Definition: array.h:52
Definition: graphics.h:297
Definition: objects.h:286
Definition: objects.h:110
Definition: objects.h:388
Definition: menu.h:120
Definition: stream.h:745
Definition: objects.h:371
Definition: graphics.h:220
Definition: objects.h:626
Definition: ptr.h:572
Definition: objects.h:237
Definition: serializer.h:79
Definition: shape.h:238
Definition: objects.h:184
Definition: objects.h:317
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: objects.h:352
Definition: objects.h:463
Definition: objects.h:219
Definition: objects.h:281
Definition: objects.h:163
Definition: objects.h:632
Definition: rooms.h:134
Definition: objects.h:276
Definition: objects.h:408
Definition: rect.h:144
Definition: objects.h:360
Definition: objects.h:572
Definition: objects.h:342
Definition: shape.h:118
Definition: objects.h:156
Definition: objects.h:443
Definition: objects.h:247
Definition: objects.h:66
Definition: rooms.h:31
Definition: objects.h:86
Definition: objects.h:427
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:260
Definition: common.h:107