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
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef AGS_SHARED_AC_GAME_SETUP_STRUCT_BASE_H
24 #define AGS_SHARED_AC_GAME_SETUP_STRUCT_BASE_H
25 
26 #include "ags/lib/allegro.h" // RGB
27 #include "ags/shared/ac/game_version.h"
28 #include "ags/shared/ac/game_struct_defines.h"
29 #include "ags/shared/util/string.h"
30 #include "ags/globals.h"
31 
32 namespace AGS3 {
33 
34 // Forward declaration
35 namespace AGS {
36 namespace Shared {
37 class Stream;
38 } // namespace Shared
39 } // namespace AGS
40 
41 using namespace AGS; // FIXME later
42 
43 struct WordsDictionary;
44 struct CharacterInfo;
45 struct ccScript;
46 
47 
48 struct GameSetupStructBase {
49 	static const int  GAME_NAME_LENGTH = 50;
50 	static const int  MAX_OPTIONS = 100;
51 	static const int  NUM_INTS_RESERVED = 17;
52 
53 	char              gamename[GAME_NAME_LENGTH];
54 	int32_t           options[MAX_OPTIONS];
55 	unsigned char     paluses[256];
56 	RGB               defpal[256];
57 	int               numviews;
58 	int               numcharacters;
59 	int               playercharacter;
60 	int               totalscore;
61 	short             numinvitems;
62 	int               numdialog, numdlgmessage;
63 	int               numfonts;
64 	int               color_depth;          // in bytes per pixel (ie. 1 or 2)
65 	int               target_win;
66 	int               dialog_bullet;        // 0 for none, otherwise slot num of bullet point
67 	unsigned short    hotdot, hotdotouter;  // inv cursor hotspot dot color
68 	int               uniqueid;    // random key identifying the game
69 	int               numgui;
70 	int               numcursors;
71 	int               default_lipsync_frame; // used for unknown chars
72 	int               invhotdotsprite;
73 	int32_t           reserved[NUM_INTS_RESERVED];
74 	char *messages[MAXGLOBALMES];
75 	WordsDictionary *dict;
76 	char *globalscript;
77 	CharacterInfo *chars;
78 	ccScript *compiled_script;
79 
80 	int32_t *load_messages;
81 	bool load_dictionary;
82 	bool load_compiled_script;
83 	// [IKM] 2013-03-30
84 	// NOTE: it looks like nor 'globalscript', not 'compiled_script' are used
85 	// to store actual script data anytime; 'ccScript* _GP(gamescript)' global
86 	// pointer is used for that instead.
87 
88 	GameSetupStructBase();
89 	~GameSetupStructBase();
90 	void Free();
91 	void SetDefaultResolution(GameResolutionType type);
92 	void SetDefaultResolution(Size game_res);
93 	void SetGameResolution(GameResolutionType type);
94 	void SetGameResolution(Size game_res);
95 	void ReadFromFile(Shared::Stream *in);
96 	void WriteToFile(Shared::Stream *out);
97 
98 
99 	//
100 	// ** On game resolution.
101 	//
102 	// Game resolution is a size of a native game screen in pixels.
103 	// This is the "game resolution" that developer sets up in AGS Editor.
104 	// It is in the same units in which sprite and font sizes are defined.
105 	//
106 	// Graphic renderer may scale and stretch game's frame as requested by
107 	// player or system, which will not affect native coordinates in any way.
108 	//
109 	// ** Legacy upscale mode.
110 	//
111 	// In the past engine had a separation between logical and native screen
112 	// coordinates and supported running games "upscaled". E.g. 320x200 games
113 	// could be run as 640x400. This was not done by simply stretching final
114 	// game's drawn frame to the larger window, but by multiplying all data
115 	// containing coordinates and graphics either on load or real-time.
116 	// Games of 640x400 and above were scripted and set up in coordinate units
117 	// that were always x2 times smaller than the one developer chose.
118 	// For example, choosing a 640x400 resolution would make game draw itself
119 	// as 640x400, but all the game logic (object properties, script commands)
120 	// would work in 320x200 (this also let run 640x400 downscaled to 320x200).
121 	// Ignoring the obvious complications, the known benefit from such approach
122 	// was that developers could supply separate sets of fonts and sprites for
123 	// low-res and high-res modes.
124 	// The 3rd generation of AGS still allows to achieve same effect by using
125 	// backwards-compatible option (although it is not recommended except when
126 	// importing and continuing old projects).
127 	//
128 	// In order to support this legacy behavior we have a set of functions for
129 	// coordinate conversion. They are required to move from "data" resolution
130 	// to "final game" resolution and back.
131 	//
132 	// Some of the script commands, as well as some internal engine data use
133 	// coordinates in "game resolution" instead (this should be documented).
134 	// In such case there's another conversion which translates these from
135 	// default to actual resolution; e.g. when 320x200 game is run as 640x400
136 	// they should be multiplied by 2.
137 	//
138 	// ** TODO.
139 	//
140 	// Truth be told, all this is still implemented incorrectly, because no one
141 	// found time to rewrite the thing. The correct way would perhaps be:
142 	// 1) treat old games as x2 lower resolution than they say.
143 	// 2) support drawing particular sprites and texts in x2 higher resolution
144 	// (assuming display resolution allows). The latter is potentially enabled
145 	// by "sprite batches" system in the engine and will benefit new games too.
146 
GetResolutionTypeGameSetupStructBase147 	inline GameResolutionType GetResolutionType() const {
148 		return _resolutionType;
149 	}
150 
151 	// Get actual game's resolution
GetGameResGameSetupStructBase152 	const Size &GetGameRes() const {
153 		return _gameResolution;
154 	}
155 	// Get default resolution the game was created for;
156 	// this is usually equal to GetGameRes except for legacy modes.
GetDefaultResGameSetupStructBase157 	const Size &GetDefaultRes() const {
158 		return _defGameResolution;
159 	}
160 	// Get data & script resolution;
161 	// this is usually equal to GetGameRes except for legacy modes.
GetDataResGameSetupStructBase162 	const Size &GetDataRes() const {
163 		return _dataResolution;
164 	}
165 	// Get game data-->final game resolution coordinate multiplier
GetDataUpscaleMultGameSetupStructBase166 	inline int GetDataUpscaleMult() const {
167 		return _dataUpscaleMult;
168 	}
169 	// Get multiplier for various default UI sizes, meant to keep UI looks
170 	// more or less readable in any game resolution.
171 	// TODO: find a better solution for UI sizes, perhaps make variables.
GetRelativeUIMultGameSetupStructBase172 	inline int GetRelativeUIMult() const {
173 		return _relativeUIMult;
174 	}
175 	// Get game default res-->final game resolution coordinate multiplier;
176 	// used to convert coordinates from original game res to actual one
GetScreenUpscaleMultGameSetupStructBase177 	inline int GetScreenUpscaleMult() const {
178 		return _screenUpscaleMult;
179 	}
180 	// Tells if game allows assets defined in relative resolution;
181 	// that is - have to be converted to this game resolution type
AllowRelativeResGameSetupStructBase182 	inline bool AllowRelativeRes() const {
183 		return options[OPT_RELATIVEASSETRES] != 0;
184 	}
185 	// Legacy definition of high and low game resolution.
186 	// Used to determine certain hardcoded coordinate conversion logic, but
187 	// does not make much sense today when the resolution is arbitrary.
IsLegacyHiResGameSetupStructBase188 	inline bool IsLegacyHiRes() const {
189 		if (_resolutionType == kGameResolution_Custom)
190 			return (_gameResolution.Width * _gameResolution.Height) > (320 * 240);
191 		return ::AGS3::IsLegacyHiRes(_resolutionType);
192 	}
193 	// Tells if data has coordinates in default game resolution
IsDataInNativeCoordinatesGameSetupStructBase194 	inline bool IsDataInNativeCoordinates() const {
195 		return options[OPT_NATIVECOORDINATES] != 0;
196 	}
197 
198 	// Tells if game runs in native letterbox mode (legacy option)
IsLegacyLetterboxGameSetupStructBase199 	inline bool IsLegacyLetterbox() const {
200 		return options[OPT_LETTERBOX] != 0;
201 	}
202 	// Get letterboxed frame size
GetLetterboxSizeGameSetupStructBase203 	const Size &GetLetterboxSize() const {
204 		return _letterboxSize;
205 	}
206 
207 	// Room region/hotspot masks are traditionally 1:1 of the room's size in
208 	// low-resolution games and 1:2 of the room size in high-resolution games.
209 	// This also means that mask relation to data resolution is 1:1 if the
210 	// game uses low-res coordinates in script and 1:2 if high-res.
211 
212 	// Test if the game is built around old audio system
IsLegacyAudioSystemGameSetupStructBase213 	inline bool IsLegacyAudioSystem() const {
214 		return _G(loaded_game_file_version) < kGameVersion_320;
215 	}
216 
217 	// Returns the expected filename of a digital audio package
GetAudioVOXNameGameSetupStructBase218 	inline AGS::Shared::String GetAudioVOXName() const {
219 		return IsLegacyAudioSystem() ? "music.vox" : "audio.vox";
220 	}
221 
222 private:
223 	void SetDefaultResolution(GameResolutionType type, Size game_res);
224 	void SetNativeResolution(GameResolutionType type, Size game_res);
225 	void OnResolutionSet();
226 
227 	// Game's native resolution ID, used to init following values.
228 	GameResolutionType _resolutionType;
229 
230 	// Determines game's default screen resolution. Use for the reference
231 	// when comparing with actual screen resolution, which may be modified
232 	// by certain overriding game modes.
233 	Size _defGameResolution;
234 	// Determines game's actual resolution.
235 	Size _gameResolution;
236 	// Determines resolution in which loaded data and script define coordinates
237 	// and sizes (with very little exception).
238 	Size _dataResolution;
239 	// Letterboxed frame size. Used when old game is run in native letterbox
240 	// mode. In all other situations is equal to game's resolution.
241 	Size _letterboxSize;
242 
243 	// Game logic to game resolution coordinate factor
244 	int _dataUpscaleMult;
245 	// Multiplier for various UI drawin sizes, meant to keep UI elements readable
246 	int _relativeUIMult;
247 	// Game default resolution to actual game resolution factor
248 	int _screenUpscaleMult;
249 };
250 
251 } // namespace AGS3
252 
253 #endif
254