aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorMartin Kiewitz2016-08-13 14:58:07 +0200
committerMartin Kiewitz2016-08-13 14:58:07 +0200
commitc270b30a7937186fecd016b9a74421d633dd90c0 (patch)
tree9315baae08580c5f51b3bf07d503049680a33837 /engines/sci/engine
parent409772ea1f1986ff37656ae57a0e2b2eaf8c1b4d (diff)
downloadscummvm-rg350-c270b30a7937186fecd016b9a74421d633dd90c0.tar.gz
scummvm-rg350-c270b30a7937186fecd016b9a74421d633dd90c0.tar.bz2
scummvm-rg350-c270b30a7937186fecd016b9a74421d633dd90c0.zip
SCI: Fix pseudo mouse in various SCI1 games like e.g. Larry5
Pseudo mouse was functionality in SCI1+ games, that allowed the user to control the mouse via keyboard cursor keys. This new class only worked, when a tiny difference inside the keyboard driver happened on kMapKeyToDir calls. We previously tried to enable this behavior depending on cursor type, but this didn't work correctly (Larry 5 for example was not detected as such, but had PseudoMouse support).
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/features.cpp47
-rw-r--r--engines/sci/engine/features.h14
-rw-r--r--engines/sci/engine/kevent.cpp9
3 files changed, 66 insertions, 4 deletions
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index a993506f7a..e37a1651ef 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -45,6 +45,7 @@ GameFeatures::GameFeatures(SegManager *segMan, Kernel *kernel) : _segMan(segMan)
if (!ConfMan.getBool("use_cdaudio"))
_usesCdTrack = false;
_forceDOSTracks = false;
+ _pseudoMouseAbility = kPseudoMouseAbilityUninitialized;
}
reg_t GameFeatures::getDetectionAddr(const Common::String &objName, Selector slc, int methodNum) {
@@ -605,4 +606,50 @@ bool GameFeatures::useAltWinGMSound() {
}
}
+// PseudoMouse was added during SCI1
+// PseudoMouseAbility is about a tiny difference in the keyboard driver, which sets the event type to either
+// 40h (old behaviour) or 44h (the keyboard driver actually added 40h to the existing value).
+// See engine/kevent.cpp, kMapKeyToDir - also script 933
+
+// SCI1EGA:
+// Quest for Glory 2 still used the old way.
+//
+// SCI1EARLY:
+// King's Quest 5 0.000.062 uses the old way.
+// Leisure Suit Larry 1 demo uses the new way, but no PseudoMouse class.
+// Fairy Tales uses the new way.
+// X-Mas 1990 uses the old way, no PseudoMouse class.
+// Space Quest 4 floppy (1.1) uses the new way.
+// Mixed Up Mother Goose uses the old way, no PseudoMouse class.
+//
+// SCI1MIDDLE:
+// Leisure Suit Larry 5 demo uses the new way.
+// Conquests of the Longbow demo uses the new way.
+// Leisure Suit Larry 1 (2.0) uses the new way.
+// Astro Chicken II uses the new way.
+PseudoMouseAbilityType GameFeatures::detectPseudoMouseAbility() {
+ if (_pseudoMouseAbility == kPseudoMouseAbilityUninitialized) {
+ if (getSciVersion() < SCI_VERSION_1_EARLY) {
+ // SCI1 EGA or earlier -> pseudo mouse ability is always disabled
+ _pseudoMouseAbility = kPseudoMouseAbilityFalse;
+
+ } else if (getSciVersion() == SCI_VERSION_1_EARLY) {
+ // For SCI1 early some games had it enabled, some others didn't.
+ // We try to find an object called "PseudoMouse". If it's found, we enable the ability otherwise we don't.
+ reg_t pseudoMouseAddr = _segMan->findObjectByName("PseudoMouse", 0);
+
+ if (pseudoMouseAddr != NULL_REG) {
+ _pseudoMouseAbility = kPseudoMouseAbilityTrue;
+ } else {
+ _pseudoMouseAbility = kPseudoMouseAbilityFalse;
+ }
+
+ } else {
+ // SCI1 middle or later -> pseudo mouse ability is always enabled
+ _pseudoMouseAbility = kPseudoMouseAbilityTrue;
+ }
+ }
+ return _pseudoMouseAbility;
+}
+
} // End of namespace Sci
diff --git a/engines/sci/engine/features.h b/engines/sci/engine/features.h
index 1c410267e6..b2d40f400f 100644
--- a/engines/sci/engine/features.h
+++ b/engines/sci/engine/features.h
@@ -34,6 +34,12 @@ enum MoveCountType {
kIncrementMoveCount
};
+enum PseudoMouseAbilityType {
+ kPseudoMouseAbilityUninitialized,
+ kPseudoMouseAbilityFalse,
+ kPseudoMouseAbilityTrue
+};
+
class GameFeatures {
public:
GameFeatures(SegManager *segMan, Kernel *kernel);
@@ -110,6 +116,12 @@ public:
*/
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);
@@ -130,6 +142,8 @@ private:
bool _usesCdTrack;
bool _forceDOSTracks;
+ PseudoMouseAbilityType _pseudoMouseAbility;
+
SegManager *_segMan;
Kernel *_kernel;
};
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 534d9ce713..d7a716a504 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -258,11 +258,12 @@ reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv) {
if (readSelectorValue(segMan, obj, SELECTOR(type)) == SCI_EVENT_KEYBOARD) { // Keyboard
uint16 message = readSelectorValue(segMan, obj, SELECTOR(message));
uint16 eventType = SCI_EVENT_DIRECTION;
- // Check if the game is using cursor views. These games allowed control
- // of the mouse cursor via the keyboard controls (the so called
- // "PseudoMouse" functionality in script 933).
- if (g_sci->_features->detectSetCursorType() == SCI_VERSION_1_1)
+ // It seems with SCI1 Sierra started to add the SCI_EVENT_DIRECTION bit instead of setting it directly.
+ // It was done inside the keyboard driver and is required for the PseudoMouse functionality and class
+ // to work (script 933).
+ if (g_sci->_features->detectPseudoMouseAbility() == kPseudoMouseAbilityTrue) {
eventType |= SCI_EVENT_KEYBOARD;
+ }
for (int i = 0; i < 9; i++) {
if (keyToDirMap[i].key == message) {