Files
scummvm-cursorfix/engines/ags/shared/game/room_struct.h
2026-02-02 04:50:13 +01:00

399 lines
12 KiB
C++

/* 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 <http://www.gnu.org/licenses/>.
*
*/
//
// 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<ccScript> 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<Bitmap> 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<RoomObjectInfo> 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<SpriteInfo> &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