ScummVM API documentation
gameobjects.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 MACS2_GAMEOBJECTS_H
23 #define MACS2_GAMEOBJECTS_H
24 
25 #include "common/array.h"
26 #include "common/rect.h"
27 #include "common/singleton.h"
28 
29 namespace Common {
30 class MemoryReadStream;
31 class MemoryReadStreamEndian;
32 class SeekableReadStream;
33 } // namespace Common
34 
35 namespace Macs2 {
36 
37 class Scene {
38 public:
39  Common::MemoryReadStream *_script;
40 };
41 
42 // Data for scenes can be accessed:
43 // Script data: Load from objects data [0752]: ID * 0xC, offset at [di-6] and [di-8h]
44 class Scenes : public Common::Singleton<Scenes> {
45 public:
46  Common::Array<Scene> _scenes;
47 
48  // Global [077Ch]
49  int _currentSceneIndex;
50 
51  // Global [077Eh]
52  // TODO: Check what the initial value of this is
53  int _lastSceneIndex;
54 
55  // Global [0776h]
56  int _currentActorIndex;
57 
58  // TODO: Handle properly as a field of the scene
59  class Common::MemoryReadStream *_currentSceneScript;
60 
61  class Common::MemoryReadStream *_currentSceneStrings;
62  Common::Array<uint32> _currentSceneSpecialAnimOffsets;
63 
64  class Common::MemoryReadStream *readSceneScript(uint16 sceneIndex, Common::SeekableReadStream *fileStream);
65  Common::Array<uint32> readSpecialAnimsOffsets(uint16 sceneIndex, Common::SeekableReadStream *fileStream);
66  class Common::MemoryReadStream *readSceneStrings(uint16 sceneIndex, Common::SeekableReadStream *fileStream);
67  Common::Array<uint8> readSpecialAnimBlob(uint16 index, Common::SeekableReadStream *fileStream);
68 };
69 
71 public:
72  Common::MemoryReadStreamEndian *_readStream;
73 
75  ~AnimationReader();
76 
77  uint16 readNumAnimations();
78 
79  void seekToAnimation(uint16 index);
80 
81  // Expects us to be pointed at the header of an animation frame,
82  // will seek to the start of the next header
83  void skipCurrentAnimationFrame();
84 };
85 
86 enum ObjectOrientation : uint16 {
87  OrientationNone = 0,
88  OrientationNorth = 1,
89  OrientationNorthEast = 2,
90  OrientationEast = 3,
91  OrientationSouthEast = 4,
92  OrientationSouth = 5,
93  OrientationSouthWest = 6,
94  OrientationWest = 7,
95  OrientationNorthWest = 8,
96  OrientationStandingNorth = 9,
97  OrientationStandingNorthEast = 10,
98  OrientationStandingEast = 11,
99  OrientationStandingSouthEast = 12,
100  OrientationStandingSouth = 13,
101  OrientationStandingSouthWest = 14,
102  OrientationStandingWest = 15,
103  OrientationStandingNorthWest = 16,
104  OrientationPickup = 17
105 };
106 
107 class GameObject {
108 public:
109  // Index of the object, starting at 1
110  uint16 _index = 0;
111  uint32 _dataOffset = 0;
112 
113  Common::Array<uint8> _overloadAnimation;
114  uint16 _overloadAnimationSourceKey = 0;
115  bool _overloadAnimationMirrored = false;
116  bool _useOverloadAnimation = false;
117  // Runtime field +0x22D: when the character's orientation matches this value,
118  // the renderer uses animation slot 0x15 (overload) instead of the normal slot.
119  // Initialized to 0x7FFF (never match). Set by opcode 0x27 (V1).
120  uint16 _overloadAnimTriggerDirection = 0x7FFF;
121  // V2: five trigger words at runtime+0x50e.
122  // 0x7FFF = inactive. When orientation matches entry i, play specialAnimSlotToAnimSlot(i+1).
123  uint16 _specialAnimTriggers[5] = {0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF};
124 
125  // These are the values read by the code around l0037_082D:
126  Common::Point _position;
127  uint16 _sceneIndex = 0;
128  // The direction is chosen based on the angle between current and target position:
129  // Each direction has a validity flag at runtime offset +0x43 + (dir-1)*0x20
130  // that indicates whether the object has animation data for that direction.
131  ObjectOrientation _orientation = OrientationNone;
132  // Per-object percentage multiplier for ground-elevation vertical offset.
133  // Walkability map values < 0xC8 represent ground height at each pixel;
134  // this factor scales how much that height displaces the object upward
135  // when drawn. 0 = no vertical offset. 100 = full elevation offset.
136  uint16 _verticalOffsetScale = 0;
137  // Dialect v2 setObjectAdjust: runtime object adjust pair.
138  uint16 _objectAdjust1 = 0;
139  uint16 _objectAdjust2 = 0;
140  // Runtime +0x217: frame index during pickup animation at which the item is grabbed
141  uint16 _pickupFrameStart = 0;
142  // Runtime +0x219: frame index at which pickup animation completes
143  uint16 _pickupFrameEnd = 0;
144  // Runtime +0x22F: when set, snap character position to exact target on walk arrival
145  bool _snapToTarget = false;
146  // Runtime +0x185 (bHasShading): per-object flag loaded from file. When set, character sprites
147  // are drawn through the shading table using the shadow map intensity.
148  bool _hasShading = false;
149  // Runtime +0x186: per-object flag loaded from file. When set, character sprites
150  // are scaled based on Y position (perspective depth scaling).
151  bool _hasScaling = false;
152  // V2: half-res anim data drawn at 2x
153  bool _hasDoubleResAnim = false;
154  // Runtime field +0x231: "frozen/attached" flag. Set by scriptSetObjectBounds (opcode 0x35).
155  // When set, the object cannot be walked (opcode 0x11 returns error 0x1F)
156  // and walkAlongPath skips movement for this object.
157  // Cleared when objectA == objectB in scriptSetObjectBounds.
158  bool _hasBoundsAttachment = false;
159  uint16 _boundsAttachmentObjectID = 0; // +0x232
160  uint16 _boundsAttachmentValue1 = 0; // +0x234
161  uint16 _boundsAttachmentValue2 = 0; // +0x236
162  uint16 _boundsAttachmentValue3 = 0; // +0x238
163 
164  // Runtime[+0x20D..+0x213] dirty rect; [+0x225..+0x22B] last sprite draw bounds.
165  int16 _dirtyLeft = 0;
166  int16 _dirtyTop = 0;
167  int16 _dirtyRight = 0;
168  int16 _dirtyBottom = 0;
169  int16 _lastDrawX = 0;
170  int16 _lastDrawY = 0;
171  uint16 _lastDrawWidth = 0;
172  uint16 _lastDrawHeight = 0;
173 
174  void resetDrawBounds() {
175  _lastDrawX = 0;
176  _lastDrawY = 0;
177  _lastDrawWidth = 0;
178  _lastDrawHeight = 0;
179  _dirtyLeft = 0;
180  _dirtyTop = 0;
181  _dirtyRight = 0;
182  _dirtyBottom = 0;
183  }
184 
185  // Each object can have up to 15h blocks of data that are loaded, which can
186  // include the animations, the dialogue images, the inventory icons etc.
188  Common::Array<uint16> _blobSourceKeys; // Per-slot wSourceKey2 from resource file (slot+0x02, editor metadata)
189  Common::Array<bool> _blobMirrorFlags;
190  Common::Array<uint16> _blobWalkSpeeds; // Per-slot wAnimSpeed (slot+0x0C, walk speed 2-8 px/frame, used by walkAlongPath)
191 
192  // The object-specific script
193  Common::Array<uint8> _script;
194 
195  // Amiga: plaintext string entries for this object (script offsets are relative to this).
196  // Empty on DOS; DOS strings are read from RESOURCE.MCS via the scene/object tables.
197  Common::Array<uint8> _stringData;
198 
199  // Per-object resource offset table (runtime +0x18D, 128 bytes = 32 dword file offsets).
200  // Loaded from file during loadObjectData. Used by scriptLoadObjectAnim/scriptLoadSpecialAnim
201  // to look up animation resource file addresses for this object.
202  uint32 _resourceOffsets[32] = {0};
203 
204  // Stashed walk/motion runtime when no Character exists (binary heap runtime
205  // survives scene change / off-scene script opcodes). Restored on Character create.
207  bool valid = false;
208  bool stepDirectionSet = false;
209  Common::Point targetPosition;
210  Common::Point pathFinalDestination;
211  int16 stepDeltaX = 0;
212  int16 stepDeltaY = 0;
213  int16 stepError = 0;
214  int16 currentPathIndex = 0;
216  uint16 motionTargetVerticalOffset = 0;
217  uint16 motionVerticalOffsetDelta = 0;
218  uint16 motionDistanceUnits = 0;
219  uint16 motionProgress = 0;
220  };
221  StoredWalkRuntime _storedWalkRuntime;
222 
223  Common::MemoryReadStream *getScriptStream();
224 
225  // Binary pAnimSlots[1..maxAnimSlots] at runtime+slot*0x10. Overload slot may be in
226  // _blobs[overload-1] (loadObjectData) or _overloadAnimation (script load / savegame).
227  Common::Array<uint8> *getAnimSlotBlob(uint16 slot);
228  const Common::Array<uint8> *getAnimSlotBlob(uint16 slot) const;
229 
230  // Binary bSlotLoaded (runtime+orient*0x10+0x33): blob present or walk-speed high byte set.
231  bool isAnimSlotLoaded(uint16 orient) const;
232 };
233 
234 class GameObjects : public Common::Singleton<GameObjects> {
235 public:
237 
239  static bool isNpcIndex(uint16 objectIndex);
240 
241  static GameObject *getProtagonistObject();
242 
243  static GameObject *getObjectByIndex(uint16 index);
244 
245  static class Common::MemoryReadStream *readGameObjectStrings(uint16 index, Common::SeekableReadStream *fileStream);
246 };
247 
248 } // namespace Macs2
249 
250 #endif // MACS2_GAMEOBJECTS_H
Definition: gameobjects.h:107
Definition: array.h:52
Definition: gameobjects.h:70
Definition: gameobjects.h:37
Definition: stream.h:745
Definition: memstream.h:103
Definition: gameobjects.h:206
Definition: gameobjects.h:44
Definition: algorithm.h:29
Definition: rect.h:144
Definition: memstream.h:43
Definition: actionbar.h:31
Definition: gameobjects.h:234
Definition: singleton.h:42