ScummVM API documentation
room_struct.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 //
23 // RoomStruct, a class describing initial room data.
24 //
25 // Because of the imperfect implementation there is inconsistency in how
26 // this data is interpreted at the runtime.
27 // Some of that data is never supposed to be changed at runtime. Another
28 // may be changed, but these changes are lost as soon as room is unloaded.
29 // The changes that must remain in memory are kept as separate classes:
30 // see RoomStatus, RoomObject etc.
31 //
32 // Partially this is because same class was used for both engine and editor,
33 // while runtime code was not available for the editor.
34 //
35 // This is also the reason why some classes here are named with the "Info"
36 // postfix. For example, RoomObjectInfo is the initial object data, and
37 // there is also RoomObject runtime-only class for mutable data.
38 //
39 // [ivan-mogilko] In my opinion, eventually there should be only one room class
40 // and one class per room entity, regardless of whether code is shared with
41 // the editor or not. But that would require extensive refactor/rewrite of
42 // the engine code, and savegame read/write code.
43 //
44 //=============================================================================
45 
46 #ifndef AGS_SHARED_GAME_ROOM_INFO_H
47 #define AGS_SHARED_GAME_ROOM_INFO_H
48 
49 #include "ags/lib/std/memory.h"
50 #include "ags/lib/allegro.h" // RGB
51 #include "ags/shared/ac/common_defines.h"
52 #include "ags/shared/game/interactions.h"
53 #include "ags/shared/util/geometry.h"
54 #include "ags/shared/util/string.h"
55 
56 namespace AGS3 {
57 
58 struct ccScript;
59 struct SpriteInfo;
60 typedef std::shared_ptr<ccScript> PScript;
61 
62 // TODO: move the following enums under AGS::Shared namespace
63 // later, when more engine source is put in AGS namespace and
64 // refactored.
65 
66 // Room's area mask type
67 enum RoomAreaMask {
68  kRoomAreaNone = 0,
69  kRoomAreaHotspot,
70  kRoomAreaWalkBehind,
71  kRoomAreaWalkable,
72  kRoomAreaRegion
73 };
74 
75 // Room's audio volume modifier
76 enum RoomVolumeMod {
77  kRoomVolumeQuietest = -3,
78  kRoomVolumeQuieter = -2,
79  kRoomVolumeQuiet = -1,
80  kRoomVolumeNormal = 0,
81  kRoomVolumeLoud = 1,
82  kRoomVolumeLouder = 2,
83  kRoomVolumeLoudest = 3,
84  // These two options are only settable at runtime by SetMusicVolume()
85  kRoomVolumeExtra1 = 4,
86  kRoomVolumeExtra2 = 5,
87 
88  kRoomVolumeMin = kRoomVolumeQuietest,
89  kRoomVolumeMax = kRoomVolumeExtra2,
90 };
91 
92 // Extended room boolean options
93 enum RoomFlags {
94  kRoomFlag_BkgFrameLocked = 0x01
95 };
96 
97 // Flag tells that walkable area does not have continious zoom
98 #define NOT_VECTOR_SCALED -10000
99 // Flags tells that room is not linked to particular game ID
100 #define NO_GAME_ID_IN_ROOM_FILE 16325
101 
102 #define MAX_ROOM_BGFRAMES 5 // max number of frames in animating bg scene
103 
104 #define MAX_ROOM_HOTSPOTS 50 // v2.62: 20 -> 30; v2.8: -> 50
105 #define MAX_ROOM_OBJECTS_v300 40 // for some legacy logic support
106 #define MAX_ROOM_OBJECTS 256 // v3.6.0: 40 -> 256 (now limited by room format)
107 #define MAX_ROOM_REGIONS 16
108 // TODO: this is remains of the older code, MAX_WALK_AREAS = real number - 1, where
109 // -1 is for the solid wall. When fixing this you need to be careful, because some
110 // walk-area indexes are 0-based and some 1-based (and some arrays have MAX_WALK_AREAS + 1 size)
111 #define MAX_WALK_AREAS 15
112 #define MAX_WALK_BEHINDS 16
113 
114 #define MAX_MESSAGES 100
115 
116 
117 namespace AGS {
118 namespace Shared {
119 
120 class Bitmap;
121 class Stream;
122 
123 typedef std::shared_ptr<Bitmap> PBitmap;
124 
125 // Various room options
126 struct RoomOptions {
127  // Index of the startup music in the room
128  int StartupMusic;
129  // If saving and loading game is disabled in the room
130  bool SaveLoadDisabled;
131  // If player character is turned off in the room
132  bool PlayerCharOff;
133  // Apply player character's normal view when entering this room
134  int PlayerView;
135  // Room's music volume modifier
136  RoomVolumeMod MusicVolume;
137  // A collection of boolean options
138  int Flags;
139 
140  RoomOptions();
141 };
142 
143 // Single room background frame
144 struct RoomBgFrame {
145  PBitmap Graphic;
146  // Palette is only valid in 8-bit games
147  RGB Palette[256];
148  // Tells if this frame should keep previous frame palette instead of using its own
149  bool IsPaletteShared;
150 
151  RoomBgFrame();
152 };
153 
154 // Describes room edges (coordinates of four edges)
155 struct RoomEdges {
156  int32_t Left;
157  int32_t Right;
158  int32_t Top;
159  int32_t Bottom;
160 
161  RoomEdges();
162  RoomEdges(int l, int r, int t, int b);
163 };
164 
165 // Room hotspot description
166 struct RoomHotspot {
167  String Name;
168  String ScriptName;
169  // Custom properties
170  StringIMap Properties;
171  // Old-style interactions
173  // Event script links
174  PInteractionScripts EventHandlers;
175 
176  // Player will automatically walk here when interacting with hotspot
177  Point WalkTo;
178 };
179 
180 // Room object description
182  int32_t Room;
183  int32_t X;
184  int32_t Y;
185  int32_t Sprite;
186  bool IsOn;
187  // Object's z-order in the room, or -1 (use Y)
188  int32_t Baseline;
189  int32_t Flags;
190  String Name;
191  String ScriptName;
192  // Custom properties
193  StringIMap Properties;
194  // Old-style interactions
196  // Event script links
197  PInteractionScripts EventHandlers;
198 
199  RoomObjectInfo();
200 };
201 
202 // Room region description
203 struct RoomRegion {
204  // Light level (-100 -> +100) or Tint luminance (0 - 255)
205  int32_t Light;
206  // Tint setting (R-B-G-S)
207  int32_t Tint;
208  // Custom properties
209  StringIMap Properties;
210  // Old-style interactions
212  // Event script links
213  PInteractionScripts EventHandlers;
214 
215  RoomRegion();
216 };
217 
218 // Walkable area description
219 struct WalkArea {
220  // Apply player character's normal view on this area
221  int32_t CharacterView;
222  // Character's scaling (-100 -> +100 %)
223  // General scaling, or scaling at the farthest point
224  int32_t ScalingFar;
225  // Scaling at the nearest point, or NOT_VECTOR_SCALED for uniform scaling
226  int32_t ScalingNear;
227  // Optional override for player character view
228  int32_t PlayerView;
229  // Top and bottom Y of the area
230  int32_t Top;
231  int32_t Bottom;
232 
233  WalkArea();
234 };
235 
236 // Walk-behind description
237 struct WalkBehind {
238  // Object's z-order in the room
239  int32_t Baseline;
240 
241  WalkBehind();
242 };
243 
244 // Room messages
245 
246 #define MSG_DISPLAYNEXT 0x01 // supercedes using alt-200 at end of message
247 #define MSG_TIMELIMIT 0x02
248 
249 struct MessageInfo {
250  int8 DisplayAs; // 0 - std display window, >=1 - as character's speech
251  int8 Flags; // combination of MSG_xxx flags
252 
253  MessageInfo();
254 };
255 
256 
257 // Room's legacy resolution type
258 enum RoomResolutionType {
259  kRoomRealRes = 0, // room should always be treated as-is
260  kRoomLoRes = 1, // created for low-resolution game
261  kRoomHiRes = 2 // created for high-resolution game
262 };
263 
264 
265 //
266 // Description of a single room.
267 // This class contains initial room data. Some of it may still be modified
268 // at the runtime, but then these changes get lost as soon as room is unloaded.
269 //
270 class RoomStruct {
271 public:
272  RoomStruct();
273  ~RoomStruct();
274 
275  // Gets if room should adjust its base size depending on game's resolution
276  inline bool IsRelativeRes() const {
277  return _resolution != kRoomRealRes;
278  }
279  // Gets if room belongs to high resolution
280  inline bool IsLegacyHiRes() const {
281  return _resolution == kRoomHiRes;
282  }
283  // Gets legacy resolution type
284  inline RoomResolutionType GetResolutionType() const {
285  return _resolution;
286  }
287 
288  // Releases room resources
289  void Free();
290  // Release room messages and scripts correspondingly. These two functions are needed
291  // at very specific occasion when only part of the room resources has to be freed.
292  void FreeMessages();
293  void FreeScripts();
294  // Init default room state
295  void InitDefaults();
296  // Set legacy resolution type
297  void SetResolution(RoomResolutionType type);
298 
299  // Gets bitmap of particular mask layer
300  Bitmap *GetMask(RoomAreaMask mask) const;
301  // Gets mask's scale relative to the room's background size
302  float GetMaskScale(RoomAreaMask mask) const;
303 
304  // TODO: see later whether it may be more convenient to move these to the Region class instead.
305  // Gets if the given region has light level set
306  bool HasRegionLightLevel(int id) const;
307  // Gets if the given region has a tint set
308  bool HasRegionTint(int id) const;
309  // Gets region's light level in -100 to 100 range value; returns 0 (default level) if region's tint is set
310  int GetRegionLightLevel(int id) const;
311  // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set
312  int GetRegionTintLuminance(int id) const;
313 
314  // TODO: all members are currently public because they are used everywhere; hide them later
315 public:
316  // Game's unique ID, corresponds to GameSetupStructBase::uniqueid.
317  // If this field has a valid value and does not match actual game's id,
318  // then engine will refuse to start this room.
319  // May be set to NO_GAME_ID_IN_ROOM_FILE to let it run within any game.
320  int32_t GameID;
321  // Loaded room file's data version. This value may be used to know when
322  // the room must have behavior specific to certain version of AGS.
323  int32_t DataVersion;
324 
325  // Room region masks resolution. Defines the relation between room and mask units.
326  // Mask point is calculated as roompt / MaskResolution. Must be >= 1.
327  int32_t MaskResolution;
328  // Size of the room, in logical coordinates (= pixels)
329  int32_t Width;
330  int32_t Height;
331  // Primary room palette (8-bit games)
332  RGB Palette[256];
333 
334  // Basic room options
335  RoomOptions Options;
336 
337  // Background frames
338  int32_t BackgroundBPP; // bytes per pixel
339  size_t BgFrameCount;
340  RoomBgFrame BgFrames[MAX_ROOM_BGFRAMES];
341  // Speed at which background frames are changing, 0 - no auto animation
342  int32_t BgAnimSpeed;
343  // Edges
344  RoomEdges Edges;
345  // Region masks
346  PBitmap HotspotMask;
347  PBitmap RegionMask;
348  PBitmap WalkAreaMask;
349  PBitmap WalkBehindMask;
350  // Room entities
351  size_t HotspotCount;
352  RoomHotspot Hotspots[MAX_ROOM_HOTSPOTS];
354  size_t RegionCount;
355  RoomRegion Regions[MAX_ROOM_REGIONS];
356  size_t WalkAreaCount;
357  WalkArea WalkAreas[MAX_WALK_AREAS + 1];
358  size_t WalkBehindCount;
359  WalkBehind WalkBehinds[MAX_WALK_BEHINDS];
360 
361  // Old numbered room messages (used with DisplayMessage, etc)
362  size_t MessageCount;
363  String Messages[MAX_MESSAGES];
364  MessageInfo MessageInfos[MAX_MESSAGES];
365 
366  // Custom properties
367  StringIMap Properties;
368  // Old-style interactions
369  InterVarVector LocalVariables;
371  // Event script links
372  PInteractionScripts EventHandlers;
373  // Compiled room script
374  PScript CompiledScript;
375  // Various extended options with string values, meta-data etc
376  StringMap StrOptions;
377 
378 private:
379  // Room's legacy resolution type, defines relation room and game's resolution
380  RoomResolutionType _resolution;
381 };
382 
383 
384 // Loads new room data into the given RoomStruct object
385 void load_room(const String &filename, RoomStruct *room, bool game_is_hires, const std::vector<SpriteInfo> &sprinfos);
386 // Checks if it's necessary and upscales low-res room backgrounds and masks for the high resolution game
387 // NOTE: it does not upscale object coordinates, because that is usually done when the room is loaded
388 void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires);
389 // Ensures that all existing room masks match room background size and
390 // MaskResolution property, resizes mask bitmaps if necessary.
391 void FixRoomMasks(RoomStruct *room);
392 // Adjusts bitmap size if necessary and returns either new or old bitmap.
393 PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height);
394 
395 } // namespace Shared
396 } // namespace AGS
397 } // namespace AGS3
398 
399 #endif
Definition: achievements_tables.h:27
Definition: room_struct.h:219
Definition: interactions.h:154
Definition: room_struct.h:249
Definition: allegro_bitmap.h:44
Definition: room_struct.h:181
Definition: vector.h:45
Definition: geometry.h:87
Definition: room_struct.h:203
Definition: room_struct.h:237
Definition: room_struct.h:144
Definition: room_struct.h:166
Definition: color.h:49
Definition: string.h:62
Definition: room_struct.h:270
Definition: room_struct.h:155
Definition: ptr.h:159
Definition: ags.h:40
Definition: room_struct.h:126
Definition: display_client.h:78