/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ // // RoomStruct, a class describing initial room data. // // Because of the imperfect implementation there is inconsistency in how // this data is interpreted at the runtime. // Some of that data is never supposed to be changed at runtime. Another // may be changed, but these changes are lost as soon as room is unloaded. // The changes that must remain in memory are kept as separate classes: // see RoomStatus, RoomObject etc. // // Partially this is because same class was used for both engine and editor, // while runtime code was not available for the editor. // // This is also the reason why some classes here are named with the "Info" // postfix. For example, RoomObjectInfo is the initial object data, and // there is also RoomObject runtime-only class for mutable data. // // [ivan-mogilko] In my opinion, eventually there should be only one room class // and one class per room entity, regardless of whether code is shared with // the editor or not. But that would require extensive refactor/rewrite of // the engine code, and savegame read/write code. // //============================================================================= #ifndef AGS_SHARED_GAME_ROOM_INFO_H #define AGS_SHARED_GAME_ROOM_INFO_H #include "common/std/memory.h" #include "ags/lib/allegro.h" // RGB #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/interactions.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/string.h" namespace AGS3 { struct ccScript; struct SpriteInfo; typedef std::shared_ptr PScript; // TODO: move the following enums under AGS::Shared namespace // later, when more engine source is put in AGS namespace and // refactored. // Room's area mask type enum RoomAreaMask { kRoomAreaNone = 0, kRoomAreaHotspot, kRoomAreaWalkBehind, kRoomAreaWalkable, kRoomAreaRegion }; // Room's audio volume modifier enum RoomVolumeMod { kRoomVolumeQuietest = -3, kRoomVolumeQuieter = -2, kRoomVolumeQuiet = -1, kRoomVolumeNormal = 0, kRoomVolumeLoud = 1, kRoomVolumeLouder = 2, kRoomVolumeLoudest = 3, // These two options are only settable at runtime by SetMusicVolume() kRoomVolumeExtra1 = 4, kRoomVolumeExtra2 = 5, kRoomVolumeMin = kRoomVolumeQuietest, kRoomVolumeMax = kRoomVolumeExtra2, }; // Extended room boolean options enum RoomFlags { kRoomFlag_BkgFrameLocked = 0x01 }; // Flag tells that walkable area does not have continious zoom #define NOT_VECTOR_SCALED -10000 // Flags tells that room is not linked to particular game ID #define NO_GAME_ID_IN_ROOM_FILE 16325 #define MAX_ROOM_BGFRAMES 5 // max number of frames in animating bg scene #define MAX_ROOM_HOTSPOTS 50 // v2.62: 20 -> 30; v2.8: -> 50 #define MAX_ROOM_OBJECTS_v300 40 // for some legacy logic support #define MAX_ROOM_OBJECTS 256 // v3.6.0: 40 -> 256 (now limited by room format) #define MAX_ROOM_REGIONS 16 #define MAX_WALK_AREAS 16 #define MAX_WALK_BEHINDS 16 #define MAX_MESSAGES 100 namespace AGS { namespace Shared { class Bitmap; class Stream; typedef std::shared_ptr PBitmap; // Various room options struct RoomOptions { // Index of the startup music in the room // this is a deprecated option, used before 3.2.* with old audio API. int StartupMusic; // If saving and loading game is disabled in the room; // this is a deprecated option that affects only built-in save/load dialogs bool SaveLoadDisabled; // If player character is turned off in the room bool PlayerCharOff; // Apply player character's normal view when entering this room int PlayerView; // Room's music volume modifier RoomVolumeMod MusicVolume; // A collection of RoomFlags int Flags; RoomOptions(); }; // Single room background frame struct RoomBgFrame { PBitmap Graphic; // Palette is only valid in 8-bit games RGB Palette[256]; // Tells if this frame should keep previous frame palette instead of using its own bool IsPaletteShared; RoomBgFrame(); }; // Describes room edges (coordinates of four edges) struct RoomEdges { int32_t Left; int32_t Right; int32_t Top; int32_t Bottom; RoomEdges(); RoomEdges(int l, int r, int t, int b); }; // Room hotspot description struct RoomHotspot { String Name; String ScriptName; // Custom properties StringIMap Properties; // Old-style interactions PInteraction Interaction; // Event script links PInteractionScripts EventHandlers; // Player will automatically walk here when interacting with hotspot Point WalkTo; }; // Room object description struct RoomObjectInfo { int32_t Room; int32_t X; int32_t Y; int32_t Sprite; bool IsOn; // Object's z-order in the room, or -1 (use Y) int32_t Baseline; int32_t Flags; String Name; String ScriptName; // Custom properties StringIMap Properties; // Old-style interactions PInteraction Interaction; // Event script links PInteractionScripts EventHandlers; RoomObjectInfo(); }; // Room region description struct RoomRegion { // Light level (-100 -> +100) or Tint luminance (0 - 255) int32_t Light; // Tint setting (R-B-G-S) int32_t Tint; // Custom properties StringIMap Properties; // Old-style interactions PInteraction Interaction; // Event script links PInteractionScripts EventHandlers; RoomRegion(); }; // Walkable area description struct WalkArea { // Apply player character's normal view on this area int32_t CharacterView; // Character's scaling (-100 -> +100 %) // General scaling, or scaling at the farthest point int32_t ScalingFar; // Scaling at the nearest point, or NOT_VECTOR_SCALED for uniform scaling int32_t ScalingNear; // Optional override for player character view int32_t PlayerView; // Top and bottom Y of the area int32_t Top; int32_t Bottom; WalkArea(); }; // Walk-behind description struct WalkBehind { // Object's z-order in the room int32_t Baseline; WalkBehind(); }; // Room messages #define MSG_DISPLAYNEXT 0x01 // supercedes using alt-200 at end of message #define MSG_TIMELIMIT 0x02 struct MessageInfo { int8 DisplayAs; // 0 - std display window, >=1 - as character's speech int8 Flags; // combination of MSG_xxx flags MessageInfo(); }; // Room's legacy resolution type enum RoomResolutionType { kRoomRealRes = 0, // room should always be treated as-is kRoomLoRes = 1, // created for low-resolution game kRoomHiRes = 2 // created for high-resolution game }; // // Description of a single room. // This class contains initial room data. Some of it may still be modified // at the runtime, but then these changes get lost as soon as room is unloaded. // class RoomStruct { public: RoomStruct(); ~RoomStruct(); // Gets if room should adjust its base size depending on game's resolution inline bool IsRelativeRes() const { return _resolution != kRoomRealRes; } // Gets if room belongs to high resolution inline bool IsLegacyHiRes() const { return _resolution == kRoomHiRes; } // Gets legacy resolution type inline RoomResolutionType GetResolutionType() const { return _resolution; } // Releases room resources void Free(); // Release room messages and scripts correspondingly. These two functions are needed // at very specific occasion when only part of the room resources has to be freed. void FreeMessages(); void FreeScripts(); // Init default room state void InitDefaults(); // Set legacy resolution type void SetResolution(RoomResolutionType type); // Gets bitmap of particular mask layer Bitmap *GetMask(RoomAreaMask mask) const; // Gets mask's scale relative to the room's background size float GetMaskScale(RoomAreaMask mask) const; // TODO: see later whether it may be more convenient to move these to the Region class instead. // Gets if the given region has light level set bool HasRegionLightLevel(int id) const; // Gets if the given region has a tint set bool HasRegionTint(int id) const; // Gets region's light level in -100 to 100 range value; returns 0 (default level) if region's tint is set int GetRegionLightLevel(int id) const; // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set int GetRegionTintLuminance(int id) const; // TODO: all members are currently public because they are used everywhere; hide them later public: // Game's unique ID, corresponds to GameSetupStructBase::uniqueid. // If this field has a valid value and does not match actual game's id, // then engine will refuse to start this room. // May be set to NO_GAME_ID_IN_ROOM_FILE to let it run within any game. int32_t GameID; // Loaded room file's data version. This value may be used to know when // the room must have behavior specific to certain version of AGS. int32_t DataVersion; // Room region masks resolution. Defines the relation between room and mask units. // Mask point is calculated as roompt / MaskResolution. Must be >= 1. int32_t MaskResolution; // Size of the room, in logical coordinates (= pixels) int32_t Width; int32_t Height; // Primary room palette (8-bit games) RGB Palette[256]; // Basic room options RoomOptions Options; // Background frames int32_t BackgroundBPP; // bytes per pixel size_t BgFrameCount; RoomBgFrame BgFrames[MAX_ROOM_BGFRAMES]; // Speed at which background frames are changing, 0 - no auto animation int32_t BgAnimSpeed; // Edges RoomEdges Edges; // Region masks PBitmap HotspotMask; PBitmap RegionMask; PBitmap WalkAreaMask; PBitmap WalkBehindMask; // Room entities size_t HotspotCount; RoomHotspot Hotspots[MAX_ROOM_HOTSPOTS]; std::vector Objects; size_t RegionCount; RoomRegion Regions[MAX_ROOM_REGIONS]; size_t WalkAreaCount; WalkArea WalkAreas[MAX_WALK_AREAS]; size_t WalkBehindCount; WalkBehind WalkBehinds[MAX_WALK_BEHINDS]; // Old numbered room messages (used with DisplayMessage, etc) size_t MessageCount; String Messages[MAX_MESSAGES]; MessageInfo MessageInfos[MAX_MESSAGES]; // Custom properties StringIMap Properties; // Old-style interactions InterVarVector LocalVariables; PInteraction Interaction; // Event script links PInteractionScripts EventHandlers; // Compiled room script PScript CompiledScript; // Various extended options with string values, meta-data etc StringMap StrOptions; private: // Room's legacy resolution type, defines relation room and game's resolution RoomResolutionType _resolution; }; // Loads new room data into the given RoomStruct object void load_room(const String &filename, RoomStruct *room, bool game_is_hires, const std::vector &sprinfos); // Checks if it's necessary and upscales low-res room backgrounds and masks for the high resolution game // NOTE: it does not upscale object coordinates, because that is usually done when the room is loaded void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires); // Ensures that all existing room masks match room background size and // MaskResolution property, resizes mask bitmaps if necessary. void FixRoomMasks(RoomStruct *room); // Adjusts bitmap size if necessary and returns either new or old bitmap. PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height); } // namespace Shared } // namespace AGS } // namespace AGS3 #endif