ScummVM API documentation
game_setup_struct_base.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 //=============================================================================
24 //
25 // GameSetupStructBase is a base class for main game data.
26 //
27 //=============================================================================
28 
29 #ifndef AGS_SHARED_AC_GAME_SETUP_STRUCT_BASE_H
30 #define AGS_SHARED_AC_GAME_SETUP_STRUCT_BASE_H
31 
32 #include "ags/lib/allegro.h" // RGB
33 #include "common/std/array.h"
34 #include "common/std/memory.h"
35 #include "common/std/vector.h"
36 #include "ags/shared/ac/game_version.h"
37 #include "ags/shared/ac/game_struct_defines.h"
38 #include "ags/shared/ac/words_dictionary.h"
39 #include "ags/shared/util/string.h"
40 #include "ags/globals.h"
41 
42 namespace AGS3 {
43 
44 // Forward declaration
45 namespace AGS {
46 namespace Shared {
47 class Stream;
48 } // namespace Shared
49 } // namespace AGS
50 
51 using namespace AGS; // FIXME later
52 
53 struct CharacterInfo;
54 struct ccScript;
55 
56 
58  static const int LEGACY_GAME_NAME_LENGTH = 50;
59  static const int MAX_OPTIONS = 100;
60  static const int NUM_INTS_RESERVED = 16;
61 
62  Shared::String gamename;
63  int32_t options[MAX_OPTIONS];
64  uint8_t paluses[256];
65  RGB defpal[256];
66  int numviews;
67  int numcharacters;
68  int playercharacter;
69  int totalscore;
70  int numinvitems;
71  int numdialog;
72  int numdlgmessage; // [DEPRECATED]
73  int numfonts;
74  int color_depth; // in bytes per pixel (ie. 1 or 2)
75  int target_win;
76  int dialog_bullet; // 0 for none, otherwise slot num of bullet point
77  int hotdot; // inv cursor hotspot dot color
78  int hotdotouter;
79  int uniqueid; // random key identifying the game
80  int numgui;
81  int numcursors;
82  int default_lipsync_frame; // used for unknown chars
83  int invhotdotsprite;
84  int32_t reserved[NUM_INTS_RESERVED];
85  String messages[MAXGLOBALMES];
88  std::vector<CharacterInfo2> chars2; // extended character fields
89 
93 
94  GameSetupStructBase &operator=(GameSetupStructBase &&gss) = default;
95 
96  void Free();
97  void SetDefaultResolution(GameResolutionType type);
98  void SetDefaultResolution(Size game_res);
99  void SetGameResolution(GameResolutionType type);
100  void SetGameResolution(Size game_res);
101 
102  // Tells whether the serialized game data contains certain components
103  struct SerializeInfo {
104  bool HasCCScript = false;
105  bool HasWordsDict = false;
106  std::array<int32_t> HasMessages;
107  // File offset at which game data extensions begin
108  uint32_t ExtensionOffset = 0u;
109 
110  SerializeInfo() {
111  HasMessages.resize(MAXGLOBALMES);
112  }
113  };
114 
115  void ReadFromFile(Shared::Stream *in, GameDataVersion game_ver, SerializeInfo &info);
116  void WriteToFile(Shared::Stream *out, const SerializeInfo &info) const;
117 
118  //
119  // ** On game resolution.
120  //
121  // Game resolution is a size of a native game screen in pixels.
122  // This is the "game resolution" that developer sets up in AGS Editor.
123  // It is in the same units in which sprite and font sizes are defined.
124  //
125  // Graphic renderer may scale and stretch game's frame as requested by
126  // player or system, which will not affect native coordinates in any way.
127  //
128  // ** Legacy upscale mode.
129  //
130  // In the past engine had a separation between logical and native screen
131  // coordinates and supported running games "upscaled". E.g. 320x200 games
132  // could be run as 640x400. This was not done by simply stretching final
133  // game's drawn frame to the larger window, but by multiplying all data
134  // containing coordinates and graphics either on load or real-time.
135  // Games of 640x400 and above were scripted and set up in coordinate units
136  // that were always x2 times smaller than the one developer chose.
137  // For example, choosing a 640x400 resolution would make game draw itself
138  // as 640x400, but all the game logic (object properties, script commands)
139  // would work in 320x200 (this also let run 640x400 downscaled to 320x200).
140  // Ignoring the obvious complications, the known benefit from such approach
141  // was that developers could supply separate sets of fonts and sprites for
142  // low-res and high-res modes.
143  // The 3rd generation of AGS still allows to achieve same effect by using
144  // backwards-compatible option (although it is not recommended except when
145  // importing and continuing old projects).
146  //
147  // In order to support this legacy behavior we have a set of functions for
148  // coordinate conversion. They are required to move from "data" resolution
149  // to "final game" resolution and back.
150  //
151  // Some of the script commands, as well as some internal engine data use
152  // coordinates in "game resolution" instead (this should be documented).
153  // In such case there's another conversion which translates these from
154  // default to actual resolution; e.g. when 320x200 game is run as 640x400
155  // they should be multiplied by 2.
156  //
157  // ** TODO.
158  //
159  // Truth be told, all this is still implemented incorrectly, because no one
160  // found time to rewrite the thing. The correct way would perhaps be:
161  // 1) treat old games as x2 lower resolution than they say.
162  // 2) support drawing particular sprites and texts in x2 higher resolution
163  // (assuming display resolution allows). The latter is potentially enabled
164  // by "sprite batches" system in the engine and will benefit new games too.
165 
166  inline GameResolutionType GetResolutionType() const {
167  return _resolutionType;
168  }
169 
170  // Get actual game's resolution
171  const Size &GetGameRes() const {
172  return _gameResolution;
173  }
174  // Get default resolution the game was created for;
175  // this is usually equal to GetGameRes except for legacy modes.
176  const Size &GetDefaultRes() const {
177  return _defGameResolution;
178  }
179  // Get data & script resolution;
180  // this is usually equal to GetGameRes except for legacy modes.
181  const Size &GetDataRes() const {
182  return _dataResolution;
183  }
184  // Get game data-->final game resolution coordinate multiplier
185  inline int GetDataUpscaleMult() const {
186  return _dataUpscaleMult;
187  }
188  // Get multiplier for various default UI sizes, meant to keep UI looks
189  // more or less readable in any game resolution.
190  // TODO: find a better solution for UI sizes, perhaps make variables.
191  inline int GetRelativeUIMult() const {
192  return _relativeUIMult;
193  }
194  // Get game default res-->final game resolution coordinate multiplier;
195  // used to convert coordinates from original game res to actual one
196  inline int GetScreenUpscaleMult() const {
197  return _screenUpscaleMult;
198  }
199  // Tells if game allows assets defined in relative resolution;
200  // that is - have to be converted to this game resolution type
201  inline bool AllowRelativeRes() const {
202  return options[OPT_RELATIVEASSETRES] != 0;
203  }
204  // Legacy definition of high and low game resolution.
205  // Used to determine certain hardcoded coordinate conversion logic, but
206  // does not make much sense today when the resolution is arbitrary.
207  inline bool IsLegacyHiRes() const {
208  if (_resolutionType == kGameResolution_Custom)
209  return (_gameResolution.Width * _gameResolution.Height) > (320 * 240);
210  return ::AGS3::IsLegacyHiRes(_resolutionType);
211  }
212  // Tells if data has coordinates in default game resolution
213  inline bool IsDataInNativeCoordinates() const {
214  return options[OPT_NATIVECOORDINATES] != 0;
215  }
216 
217  // Tells if game runs in native letterbox mode (legacy option)
218  inline bool IsLegacyLetterbox() const {
219  return options[OPT_LETTERBOX] != 0;
220  }
221  // Get letterboxed frame size
222  const Size &GetLetterboxSize() const {
223  return _letterboxSize;
224  }
225 
226  // Room region/hotspot masks are traditionally 1:1 of the room's size in
227  // low-resolution games and 1:2 of the room size in high-resolution games.
228  // This also means that mask relation to data resolution is 1:1 if the
229  // game uses low-res coordinates in script and 1:2 if high-res.
230 
231  // Test if the game is built around old audio system
232  inline bool IsLegacyAudioSystem() const {
233  return _G(loaded_game_file_version) < kGameVersion_320;
234  }
235 
236  // Returns the expected filename of a digital audio package
237  inline AGS::Shared::String GetAudioVOXName() const {
238  return IsLegacyAudioSystem() ? "music.vox" : "audio.vox";
239  }
240 
241  // Returns a list of game options that are forbidden to change at runtime
242  inline static Common::Array<int> GetRestrictedOptions() {
243  return Common::Array<int> {{
244  OPT_DEBUGMODE, OPT_LETTERBOX, OPT_HIRES_FONTS, OPT_SPLITRESOURCES,
245  OPT_STRICTSCRIPTING, OPT_LEFTTORIGHTEVAL, OPT_COMPRESSSPRITES, OPT_STRICTSTRINGS,
246  OPT_NATIVECOORDINATES, OPT_SAFEFILEPATHS, OPT_DIALOGOPTIONSAPI, OPT_BASESCRIPTAPI,
247  OPT_SCRIPTCOMPATLEV, OPT_RELATIVEASSETRES, OPT_GAMETEXTENCODING, OPT_KEYHANDLEAPI,
248  OPT_CUSTOMENGINETAG
249  }};
250  }
251 
252 private:
253  void SetDefaultResolution(GameResolutionType type, Size game_res);
254  void SetNativeResolution(GameResolutionType type, Size game_res);
255  void OnResolutionSet();
256 
257  // Game's native resolution ID, used to init following values.
258  GameResolutionType _resolutionType;
259 
260  // Determines game's default screen resolution. Use for the reference
261  // when comparing with actual screen resolution, which may be modified
262  // by certain overriding game modes.
263  Size _defGameResolution;
264  // Determines game's actual resolution.
265  Size _gameResolution;
266  // Determines resolution in which loaded data and script define coordinates
267  // and sizes (with very little exception).
268  Size _dataResolution;
269  // Letterboxed frame size. Used when old game is run in native letterbox
270  // mode. In all other situations is equal to game's resolution.
271  Size _letterboxSize;
272 
273  // Game logic to game resolution coordinate factor
274  int _dataUpscaleMult;
275  // Multiplier for various UI drawin sizes, meant to keep UI elements readable
276  int _relativeUIMult;
277  // Game default resolution to actual game resolution factor
278  int _screenUpscaleMult;
279 };
280 
281 } // namespace AGS3
282 
283 #endif
Definition: achievements_tables.h:27
Definition: vector.h:39
Definition: ptr.h:572
Definition: game_setup_struct_base.h:57
Definition: color.h:49
Definition: string.h:62
void resize(size_type newSize)
Definition: array.h:411
Definition: geometry.h:148
Definition: stream.h:52
Definition: ags.h:40
Definition: game_setup_struct_base.h:103