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
31namespace Alcachofa {
32
33class Room;
34class Process;
35struct Task;
36
38public:
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
60private:
61 Common::String _name;
62 bool _isEnabled = true;
63 Room *_room = nullptr;
64};
65
66class PointObject : public ObjectBase {
67public:
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
75private:
76 Common::Point _pos;
77};
78
79enum class GraphicObjectType : byte
80{
81 Normal,
82 NormalPosterize, // the posterization is not actually applied in the original engine
83 Effect
84};
85
86class GraphicObject : public ObjectBase {
87public:
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
102protected:
103 GraphicObject(Room *room, const char *name);
104
105 Graphic _graphic;
106 GraphicObjectType _type = GraphicObjectType::Normal;
107 int32 _posterizeAlpha = 100;
108};
109
110class SpecialEffectObject final : public GraphicObject {
111public:
112 static constexpr const char *kClassName = "CObjetoGraficoMuare";
114
115 void draw() override;
116 const char *typeName() const override;
117
118private:
119 static constexpr const float kShiftSpeed = 1 / 256.0f;
120 Common::Point _topLeft, _bottomRight;
121 Math::Vector2d _texShift;
122};
123
124class ShapeObject : public ObjectBase {
125public:
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
144protected:
145 void updateSelection();
146
147 // original inconsistency: base class has member that is read by the sub classes
148 int8 _order = 0;
149private:
150 Shape _shape;
151 CursorType _cursorType = CursorType::Point;
152 bool _isNewlySelected = false,
153 _wasSelected = false;
154};
155
157public:
158 static constexpr const char *kClassName = "CObjetoFisico";
160 const char *typeName() const override;
161};
162
163class ButtonV1 : public PhysicalObject {
164public:
165 static constexpr const char *kClassName = "CBoton";
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
175private:
176 MenuV1 &menu();
177
178 MainMenuAction _action = {};
179 Common::String _graphicName;
180 ObjectBase *_graphicObject = nullptr;
181 bool _isHovered = false;
182};
183
185public:
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
202private:
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
219class InternetMenuButton final : public MenuButton {
220public:
221 static constexpr const char *kClassName = "CBotonMenuInternet";
223
224 const char *typeName() const override;
225};
226
228public:
229 static constexpr const char *kClassName = "CBotonMenuOpciones";
231
232 void update() override;
233 void trigger() override;
234 const char *typeName() const override;
235};
236
238public:
240
241 void update() override;
242 void trigger() override;
243};
244
246public:
247 static constexpr const char *kClassName = "CBotonMenuPrincipal";
249
250 void update() override;
251 void trigger() override;
252 const char *typeName() const override;
253protected:
254 virtual MainMenuAction action() const;
255};
256
257class MainMenuButtonV2 final : public MainMenuButton {
258public:
260
261protected:
262 MainMenuAction action() const override;
263};
264
265// this is a variant of a CheckBox only used in V2
267public:
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
282private:
283 bool _isChecked = false;
284 Graphic _graphicHovered, _graphicChecked;
285 int32 _actionId = -1;
286 uint32 _clickTime = 0;
287};
288
289class EditBox : public PhysicalObject {
290public:
291 static constexpr const char *kClassName = "CEditBox";
293
294 const char *typeName() const override;
295
296protected:
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
305class EditBoxV2 final : public EditBox {
306public:
308};
309
310class EditBoxV3 final : public EditBox {
311public:
313};
314
315class CheckBox : public PhysicalObject {
316public:
317 static constexpr const char *kClassName = "CCheckBox";
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
333private:
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
346class SlideButton : public ObjectBase {
347public:
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
359protected:
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
371class SlideButtonV2 final : public SlideButton {
372public:
374};
375
376class SlideButtonV3 final : public SlideButton {
377public:
379};
380
381class CheckBoxAutoAdjustNoise final : public CheckBox {
382public:
383 static constexpr const char *kClassName = "CCheckBoxAutoAjustarRuido";
385
386 const char *typeName() const override;
387};
388
389class IRCWindow final : public ObjectBase {
390public:
391 static constexpr const char *kClassName = "CVentanaIRC";
393
394 const char *typeName() const override;
395
396private:
397 Common::Point _p1, _p2;
398};
399
400class MessageBox final : public ObjectBase {
401public:
402 static constexpr const char *kClassName = "CMessageBox";
404 ~MessageBox() override {}
405
406 const char *typeName() const override;
407
408private:
409 Graphic
410 _graph1,
411 _graph2,
412 _graph3,
413 _graph4,
414 _graph5;
415};
416
417class VoiceMeter final : public GraphicObject {
418public:
419 static constexpr const char *kClassName = "CVuMeter";
421
422 const char *typeName() const override;
423};
424
425class Item : public GraphicObject { //-V690
426public:
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
438public:
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
447protected:
448 ITriggerableObject() = default;
449 void read(Common::SeekableReadStream &stream);
450 void onClick();
451
452 Common::Point _interactionPoint;
453 Direction _interactionDirection = Direction::Right;
454};
455
457public:
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
468private:
469 Common::String _relatedObject;
470};
471
472class Door final : public InteractableObject {
473public:
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
486private:
487 Common::String _targetRoom, _targetObject;
488 Direction _characterDirection;
489 uint32 _lastClickTime = 0;
490};
491
493public:
494 static constexpr const char *kClassName = "CPersonaje";
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, const char *dialogSound);
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
517protected:
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;
530 *_curAnimateObject = nullptr,
531 *_curTalkingObject = nullptr;
532};
533
535public:
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
561protected:
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;
593};
594
596 int32 _dialogId = -1;
597 int32 _yPosition = 0;
598 int32 _returnValue = 0;
599};
600
601class MainCharacter final : public WalkingCharacter {
602public:
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
635protected:
636 void onArrived() override;
637
638private:
639 friend class Inventory;
640 friend struct DialogMenuTask;
641 Item *getItemByName(const Common::String &name) const;
642 void drawInner();
643
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
655class Background final : public GraphicObject {
656public:
657 Background(Room *room, const Common::String &animationFileName, int16 scale);
658 const char *typeName() const override;
659};
660
661class FloorColor final : public ObjectBase {
662public:
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
672private:
673 FloorColorShape _shape;
674};
675
676}
677
678#endif // ALCACHOFA_OBJECTS_H
Definition: graphics.h:220
Definition: objects.h:655
Definition: objects.h:163
Definition: objects.h:492
bool _isTalking
as in "in the process of saying a line"
Definition: objects.h:525
bool _isSpeaking
as in "actively moving their mouth to produce sounds", used in updateTalkingAnimation
Definition: objects.h:526
Definition: objects.h:381
Definition: objects.h:315
Definition: objects.h:472
Definition: objects.h:289
Definition: objects.h:305
Definition: objects.h:310
Definition: objects.h:661
Definition: shape.h:238
Definition: graphics.h:297
Definition: objects.h:86
Definition: objects.h:389
Definition: objects.h:437
Definition: objects.h:456
Definition: objects.h:219
Definition: rooms.h:139
Definition: objects.h:425
Definition: objects.h:601
Definition: objects.h:245
Definition: objects.h:257
Definition: objects.h:184
Definition: menu.h:146
Definition: objects.h:400
Definition: objects.h:37
Definition: objects.h:227
Definition: objects.h:237
Definition: objects.h:156
Definition: objects.h:66
Definition: scheduler.h:164
Definition: objects.h:266
Definition: rooms.h:31
Definition: shape.h:118
Definition: objects.h:124
Definition: objects.h:346
Definition: objects.h:371
Definition: objects.h:376
Definition: objects.h:110
Definition: objects.h:417
Definition: objects.h:534
Definition: array.h:52
Definition: ptr.h:572
PointerType get() const
Definition: ptr.h:637
Definition: stream.h:745
Definition: serializer.h:80
Definition: str.h:59
Definition: common.h:78
Definition: objects.h:595
Definition: common.h:107
This fake semaphore does not work in multi-threaded scenarios It is used as a safer option for a simp...
Definition: common.h:93
Definition: scheduler.h:84
Definition: rect.h:144