aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/features.h
blob: 7a1c6f59aa7cb7f4ed368a645f4f84cd95130583 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/* 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef SCI_INCLUDE_FEATURES_H
#define SCI_INCLUDE_FEATURES_H

#include "sci/resource.h"
#include "sci/engine/seg_manager.h"

namespace Sci {

enum MoveCountType {
	kMoveCountUninitialized,
	kIgnoreMoveCount,
	kIncrementMoveCount
};

enum PseudoMouseAbilityType {
	kPseudoMouseAbilityUninitialized,
	kPseudoMouseAbilityFalse,
	kPseudoMouseAbilityTrue
};

enum MessageTypeSyncStrategy {
	kMessageTypeSyncStrategyNone,
	kMessageTypeSyncStrategyDefault
#ifdef ENABLE_SCI32
	,
	kMessageTypeSyncStrategyLSL6Hires,
	kMessageTypeSyncStrategyShivers
#endif
};

class GameFeatures {
public:
	GameFeatures(SegManager *segMan, Kernel *kernel);
	~GameFeatures() {}

	/**
	 * Autodetects the DoSound type
	 * @return DoSound type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE /
	 *                       SCI_VERSION_1_EARLY / SCI_VERSION_1_LATE
	 */
	SciVersion detectDoSoundType();

	/**
	 * Autodetects the SetCursor type
	 * @return SetCursor type, SCI_VERSION_0_EARLY / SCI_VERSION_1_1
	 */
	SciVersion detectSetCursorType();

	/**
	 * Autodetects the Lofs type
	 * @return Lofs type, SCI_VERSION_0_EARLY / SCI_VERSION_1_MIDDLE / SCI_VERSION_1_1 / SCI_VERSION_3
	 */
	SciVersion detectLofsType();

	/**
	 * Autodetects the graphics functions used
	 * @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
	 */
	SciVersion detectGfxFunctionsType();

	/**
	 * Autodetects the message function used
	 * @return Message function type, SCI_VERSION_1_LATE / SCI_VERSION_1_1
	 */
	SciVersion detectMessageFunctionType();

#ifdef ENABLE_SCI32
	/**
	 * Autodetects the kernel functions used in SCI2.1
	 * @return Graphics functions type, SCI_VERSION_2 / SCI_VERSION_2_1
	 */
	SciVersion detectSci21KernelType();

	inline bool usesModifiedAudioAttenuation() const {
		switch (g_sci->getGameId()) {
		// Assuming MGDX uses modified attenuation since SQ6 does and it was
		// released earlier, but not verified (Phar Lap Windows-only release)
		case GID_MOTHERGOOSEHIRES:
		case GID_PQ4:
		case GID_SQ6:
			return true;
		case GID_KQ7:
			// KQ7 1.51 (SCI2.1early) uses the non-standard attenuation, but
			// 2.00b (SCI2.1mid) does not
			return getSciVersion() == SCI_VERSION_2_1_EARLY;
		default:
			return false;
		}
	}

	inline bool gameScriptsControlMasterVolume() const {
		switch (g_sci->getGameId()) {
		case GID_LSL7:
		case GID_PHANTASMAGORIA2:
		case GID_TORIN:
			return true;
		default:
			return false;
		}
	}

	inline bool hasSci3Audio() const {
		return getSciVersion() == SCI_VERSION_3 || g_sci->getGameId() == GID_GK2;
	}

	inline bool hasTransparentPicturePlanes() const {
		const SciGameId &gid = g_sci->getGameId();

		// MGDX is assumed to not have transparent picture planes since it
		// was released before SQ6, but this has not been verified since it
		// cannot be disassembled at the moment (Phar Lap Windows-only release)
		return getSciVersion() >= SCI_VERSION_2_1_MIDDLE &&
			gid != GID_SQ6 &&
			gid != GID_MOTHERGOOSEHIRES;
	}

	inline bool hasMidPaletteCode() const {
		return getSciVersion() >= SCI_VERSION_2_1_MIDDLE || g_sci->getGameId() == GID_KQ7;
	}

	inline bool hasLatePaletteCode() const {
		return getSciVersion() > SCI_VERSION_2_1_MIDDLE ||
			g_sci->getGameId() == GID_GK2 ||
			g_sci->getGameId() == GID_PQSWAT ||
			// Guessing that Shivers has the late palette code because it has a
			// brightness slider
			g_sci->getGameId() == GID_SHIVERS ||
			g_sci->getGameId() == GID_TORIN;
	}

	inline bool VMDOpenStopsAudio() const {
		// Of the games that use VMDs:
		// Yes: Phant1, Shivers, Torin
		// No: SQ6
		// TODO: Optional extra flag to kPlayVMD which defaults to Yes: PQ:SWAT
		// TODO: SCI3, GK2 (GK2's VMD code is closer to SCI3 than SCI21)
		return getSciVersion() == SCI_VERSION_2_1_MIDDLE &&
			g_sci->getGameId() != GID_SQ6 &&
			g_sci->getGameId() != GID_GK2;
	}

	inline bool usesAlternateSelectors() const {
		return g_sci->getGameId() == GID_PHANTASMAGORIA2;
	}

	inline bool hasEmptyScaleDrawHack() const {
		// Yes: KQ7 (all), PQ4CD, QFG4CD, SQ6, Phant1
		// No: All SCI2, all SCI3, GK2, LSL6hires, PQ:SWAT, Torin
		// Unknown: Hoyle5, MGDX, Shivers
		const SciGameId &gid = g_sci->getGameId();
		return getSciVersion() > SCI_VERSION_2 &&
			getSciVersion() < SCI_VERSION_2_1_LATE &&
			gid != GID_LSL6HIRES &&
			gid != GID_GK2 &&
			gid != GID_PQSWAT &&
			gid != GID_TORIN;
	}
#endif

	/**
	 * If true, the current game supports simultaneous speech & subtitles.
	 */
	bool supportsSpeechWithSubtitles() const;

	/**
	 * If true, the game supports changing text speed.
	 */
	bool supportsTextSpeed() const {
		switch (g_sci->getGameId()) {
#ifdef ENABLE_SCI32
		case GID_GK1:
		case GID_SQ6:
			return true;
#endif
		default:
			break;
		}

		return false;
	}

	/**
	 * If true, audio volume sync between the game and ScummVM is done by
	 * monitoring and setting game global variables.
	 */
	bool audioVolumeSyncUsesGlobals() const;

	/**
	 * The strategy that should be used when synchronising the message type
	 * (text/speech/text+speech) between the game and ScummVM.
	 */
	MessageTypeSyncStrategy getMessageTypeSyncStrategy() const;

	/**
	 * Applies to all versions before 0.000.502
	 * Old SCI versions used to interpret the third DrawPic() parameter inversely,
	 * with the opposite default value (obviously).
	 * Also, they used 15 priority zones from 42 to 200 instead of 14 priority
	 * zones from 42 to 190.
	 */
	bool usesOldGfxFunctions() { return detectGfxFunctionsType() == SCI_VERSION_0_EARLY; }

	/**
	 * Autodetects the Bresenham routine used in the actor movement functions
	 * @return Move count type, kIncrementMoveCnt / kIgnoreMoveCnt
	 */
	MoveCountType detectMoveCountType();

	bool handleMoveCount() { return detectMoveCountType() == kIncrementMoveCount; }

	bool usesCdTrack() { return _usesCdTrack; }

	/**
	 * Checks if the alternative Windows GM MIDI soundtrack should be used. Such
	 * soundtracks are available for the Windows CD versions of EcoQuest, Jones,
	 * KQ5 and SQ4.
	 */
	bool useAltWinGMSound();

	/**
	 * Checks if the game only supports General MIDI for music playback.
	 */
	bool generalMidiOnly();

	/**
	 * Forces DOS soundtracks in Windows CD versions when the user hasn't
	 * selected a MIDI output device
	 */
	void forceDOSTracks() { _forceDOSTracks = true; }

	/**
	 * Autodetects, if Pseudo Mouse ability is enabled (different behavior in keyboard driver)
	 * @return kPseudoMouseAbilityTrue or kPseudoMouseAbilityFalse
	 */
	PseudoMouseAbilityType detectPseudoMouseAbility();

private:
	reg_t getDetectionAddr(const Common::String &objName, Selector slc, int methodNum = -1);

	bool autoDetectLofsType(Common::String gameSuperClassName, int methodNum);
	bool autoDetectGfxFunctionsType(int methodNum = -1);
	bool autoDetectSoundType();
	bool autoDetectMoveCountType();
#ifdef ENABLE_SCI32
	bool autoDetectSci21KernelType();
#endif

	SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType, _messageFunctionType;
#ifdef ENABLE_SCI32
	SciVersion _sci21KernelType;
#endif

	MoveCountType _moveCountType;
	bool _usesCdTrack;
	bool _forceDOSTracks;

	PseudoMouseAbilityType _pseudoMouseAbility;

	SegManager *_segMan;
	Kernel *_kernel;
};

} // End of namespace Sci

#endif // SCI_INCLUDE_ENGINE_H