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 } // namespace Common
33 
34 namespace Macs2 {
35 
36 class Scene {
37 public:
38  Common::MemoryReadStream *_script;
39 };
40 
41 // Data for scenes can be accessed:
42 // Script data: Load from objects data [0752]: ID * 0xC, offset at [di-6] and [di-8h]
43 class Scenes : public Common::Singleton<Scenes> {
44 public:
45  Common::Array<Scene> _scenes;
46 
47  // Global [077Ch]
48  int _currentSceneIndex;
49 
50  // Global [077Eh]
51  // TODO: Check what the initial value of this is
52  int _lastSceneIndex;
53 
54  // Global [0776h]
55  int _currentActorIndex;
56 
57  // TODO: Handle properly as a field of the scene
58  class Common::MemoryReadStream *_currentSceneScript;
59 
60  class Common::MemoryReadStream *_currentSceneStrings;
61  Common::Array<uint32> _currentSceneSpecialAnimOffsets;
62 
63  class Common::MemoryReadStream *readSceneScript(uint16 sceneIndex, Common::MemoryReadStream *fileStream);
64  Common::Array<uint32> readSpecialAnimsOffsets(uint16 sceneIndex, Common::MemoryReadStream *fileStream);
65  class Common::MemoryReadStream *readSceneStrings(uint16 sceneIndex, Common::MemoryReadStream *fileStream);
66  Common::Array<uint8> readSpecialAnimBlob(uint16 index, Common::MemoryReadStream *fileStream);
67 };
68 
70 public:
71  Common::MemoryReadStreamEndian *_readStream;
72 
73  // TODO: Can the init list also go into the cpp file?
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 class GameObject {
87 public:
88  // Index of the object, starting at 1
89  uint16 _index = 0;
90  uint32 _dataOffset = 0;
91 
92  Common::Array<uint8> _overloadAnimation;
93  uint16 _overloadAnimationSourceKey = 0;
94  bool _overloadAnimationMirrored = false;
95  bool _useOverloadAnimation = false;
96  // Runtime field +0x22D: when the character's orientation matches this value,
97  // the renderer uses animation slot 0x15 (overload) instead of the normal slot.
98  // Initialized to 0x7FFF (never match). Set by opcode 0x27.
99  uint16 _overloadAnimTriggerDirection = 0x7FFF;
100 
101  // These are the values read by the code around l0037_082D:
102  Common::Point _position;
103  uint16 _sceneIndex = 0;
104  // 8-directional movement system from walkAlongPath (1008:1b8f).
105  // Direction codes 1-8 are walking directions, 9-16 are standing (idle) variants.
106  // The direction is chosen based on the angle between current and target position:
107  // 1 = North (up) - deltaY dominates, target above
108  // 2 = NorthEast - diagonal (deltaX/4 < deltaY < deltaX*2)
109  // 3 = East (right) - deltaX dominates, target to the right
110  // 4 = SouthEast - diagonal
111  // 5 = South (down) - deltaY dominates, target below
112  // 6 = SouthWest - diagonal
113  // 7 = West (left) - deltaX dominates, target to the left
114  // 8 = NorthWest - diagonal
115  // 9-16 = Standing idle variants (walking direction + 8)
116  // 17 (0x11) = Pickup animation
117  // Each direction has a validity flag at runtime offset +0x43 + (dir-1)*0x20
118  // that indicates whether the object has animation data for that direction.
119  uint16 _orientation = 0;
120  // Per-object percentage multiplier for ground-elevation vertical offset.
121  // Walkability map values < 0xC8 represent ground height at each pixel;
122  // this factor scales how much that height displaces the object upward
123  // when drawn. 0 = no vertical offset. 100 = full elevation offset.
124  uint16 _verticalOffsetScale = 0;
125  // Runtime +0x217: frame index during pickup animation at which the item is grabbed
126  uint16 _pickupFrameStart = 0;
127  // Runtime +0x219: frame index at which pickup animation completes
128  uint16 _pickupFrameEnd = 0;
129  // Runtime +0x22F: when set, snap character position to exact target on walk arrival
130  bool _snapToTarget = false;
131  // Runtime +0x185 (bHasShading): per-object flag loaded from file. When set, character sprites
132  // are drawn through the shading table using the shadow map intensity.
133  bool _hasShading = false;
134  // Runtime +0x186: per-object flag loaded from file. When set, character sprites
135  // are scaled based on Y position (perspective depth scaling).
136  bool _hasScaling = false;
137  // Runtime field +0x231: "frozen/attached" flag. Set by scriptSetObjectBounds (opcode 0x35).
138  // When set, the object cannot be walked (opcode 0x11 returns error 0x1F)
139  // and walkAlongPath skips movement for this object.
140  // Cleared when objectA == objectB in scriptSetObjectBounds.
141  bool _hasBoundsAttachment = false;
142  uint16 _boundsAttachmentObjectID = 0; // +0x232
143  uint16 _boundsAttachmentValue1 = 0; // +0x234
144  uint16 _boundsAttachmentValue2 = 0; // +0x236
145  uint16 _boundsAttachmentValue3 = 0; // +0x238
146 
147  // Runtime[+0x20D..+0x213] dirty rect; [+0x225..+0x22B] last sprite draw bounds.
148  int16 _dirtyLeft = 0;
149  int16 _dirtyTop = 0;
150  int16 _dirtyRight = 0;
151  int16 _dirtyBottom = 0;
152  int16 _lastDrawX = 0;
153  int16 _lastDrawY = 0;
154  uint16 _lastDrawWidth = 0;
155  uint16 _lastDrawHeight = 0;
156 
157  void resetDrawBounds() {
158  _lastDrawX = 0;
159  _lastDrawY = 0;
160  _lastDrawWidth = 0;
161  _lastDrawHeight = 0;
162  _dirtyLeft = 0;
163  _dirtyTop = 0;
164  _dirtyRight = 0;
165  _dirtyBottom = 0;
166  }
167 
168  // Each object can have up to 15h blocks of data that are loaded, which can
169  // include the animations, the dialogue images, the inventory icons etc.
171  Common::Array<uint16> _blobSourceKeys; // Per-slot wSourceKey2 from resource file (slot+0x02, editor metadata)
172  Common::Array<bool> _blobMirrorFlags;
173  Common::Array<uint16> _blobWalkSpeeds; // Per-slot wAnimSpeed (slot+0x0C, walk speed 2-8 px/frame, used by walkAlongPath)
174 
175  // The object-specific script
176  Common::Array<uint8> _script;
177 
178  // Per-object resource offset table (runtime +0x18D, 128 bytes = 32 dword file offsets).
179  // Loaded from file during loadObjectData. Used by scriptLoadObjectAnim/scriptLoadSpecialAnim
180  // to look up animation resource file addresses for this object.
181  uint32 _resourceOffsets[32] = {0};
182 
183  // Stashed walk/motion runtime when no Character exists (binary heap runtime
184  // survives scene change / off-scene script opcodes). Restored on Character create.
186  bool valid = false;
187  Common::Point targetPosition;
188  Common::Point pathFinalDestination;
189  int16 stepDeltaX = 0;
190  int16 stepDeltaY = 0;
191  int16 stepError = 0;
192  bool stepDirectionSet = false;
193  int16 currentPathIndex = 0;
195  uint16 motionTargetVerticalOffset = 0;
196  uint16 motionVerticalOffsetDelta = 0;
197  uint16 motionDistanceUnits = 0;
198  uint16 motionProgress = 0;
199  };
200  StoredWalkRuntime _storedWalkRuntime;
201 
202  Common::MemoryReadStream *getScriptStream();
203 
204  // Binary pAnimSlots[1..0x15] at runtime+slot*0x10. Slot 0x15 may be in _blobs[20]
205  // (loadObjectData) or overloadAnimation (script load / savegame).
206  Common::Array<uint8> *getAnimSlotBlob(uint16 slot);
207  const Common::Array<uint8> *getAnimSlotBlob(uint16 slot) const;
208 
209  // Binary bSlotLoaded (runtime+orient*0x10+0x33): blob present or walk-speed high byte set.
210  bool isAnimSlotLoaded(uint16 orient) const;
211 };
212 
213 class GameObjects : public Common::Singleton<GameObjects> {
214 public:
215  // Maximum of 200h objects
216  // How to address them in the original code:
217  // mov di,[bp+6h]
218  // shl di, 2h;
219  // les di, [di + 77Ch]
221 
222  Common::Array<Common::String> _objectNames;
223 
224  void init();
225 
227  static bool isNpcIndex(uint16 objectIndex);
228 
229  static GameObject *getProtagonistObject();
230 
231  static GameObject *getObjectByIndex(uint16 index);
232 
233  static class Common::MemoryReadStream *readGameObjectStrings(uint16 index, Common::MemoryReadStream *fileStream);
234 };
235 
236 } // namespace Macs2
237 
238 #endif // MACS2_GAMEOBJECTS_H
Definition: gameobjects.h:86
Definition: array.h:52
Definition: gameobjects.h:69
Definition: gameobjects.h:36
Definition: memstream.h:103
Definition: gameobjects.h:185
Definition: gameobjects.h:43
Definition: algorithm.h:29
Definition: rect.h:144
Definition: memstream.h:43
Definition: debugtools.h:25
Definition: gameobjects.h:213
Definition: singleton.h:42