Rewrite detectSetCursorType() so that it works for KQ5 Mac in addition to KQ5 DOS CD.

svn-id: r47948
This commit is contained in:
Matthew Hoops 2010-02-07 02:53:07 +00:00
parent d7a7fcd3a4
commit ecd8e6f7d1
2 changed files with 26 additions and 57 deletions

View file

@ -71,17 +71,6 @@ bool GameFeatures::autoDetectFeature(FeatureDetection featureDetection, int meth
objAddr = _segMan->findObjectByName(objName); objAddr = _segMan->findObjectByName(objName);
slc = _kernel->_selectorCache.play; slc = _kernel->_selectorCache.play;
break; break;
case kDetectSetCursorType:
objName = "Game";
objAddr = _segMan->findObjectByName(objName);
// KQ5CD overrides the default setCursor selector of the Game object,
// so we need to handle this separately
// KQ5 PC floppy is early SCI1, Amiga middle SCI1, and CD late SCI1
assert(!_gameId.empty());
if (_gameId == "kq5" && getSciVersion() == SCI_VERSION_1_LATE)
objAddr = _gameObj;
slc = _kernel->_selectorCache.setCursor;
break;
case kDetectLofsType: case kDetectLofsType:
objName = "Game"; objName = "Game";
objAddr = _segMan->findObjectByName(objName); objAddr = _segMan->findObjectByName(objName);
@ -260,15 +249,6 @@ bool GameFeatures::autoDetectFeature(FeatureDetection featureDetection, int meth
return true; return true;
} }
break; break;
case kDetectSetCursorType:
// Games with colored mouse cursors call kIsObject before kSetCursor
if (kFuncNum == 6) { // kIsObject (SCI0-SCI11)
foundTarget = true;
} else if (kFuncNum == 40) { // kSetCursor (SCI0-SCI11)
_setCursorType = foundTarget ? SCI_VERSION_1_1 : SCI_VERSION_0_EARLY;
return true;
}
break;
#ifdef ENABLE_SCI32 #ifdef ENABLE_SCI32
case kDetectSci21KernelTable: case kDetectSci21KernelTable:
if (kFuncNum == 0x40) { if (kFuncNum == 0x40) {
@ -302,15 +282,6 @@ bool GameFeatures::autoDetectFeature(FeatureDetection featureDetection, int meth
} }
} while (offset > 0); } while (offset > 0);
// Some games, like KQ5CD, never actually call SetCursor inside Game::setCursor
// but call isObject. Cover this case here, if we're actually reading the selector
// itself, and not iterating through the Game object (i.e. when the selector
// dictionary is missing)
if (featureDetection == kDetectSetCursorType && methodNum == -1 && foundTarget) {
_setCursorType = SCI_VERSION_1_1;
return true;
}
return false; // not found return false; // not found
} }
@ -347,40 +318,39 @@ SciVersion GameFeatures::detectDoSoundType() {
SciVersion GameFeatures::detectSetCursorType() { SciVersion GameFeatures::detectSetCursorType() {
if (_setCursorType == SCI_VERSION_NONE) { if (_setCursorType == SCI_VERSION_NONE) {
if (getSciVersion() <= SCI_VERSION_01) { if (getSciVersion() <= SCI_VERSION_1_MIDDLE) {
// SCI0/SCI01 games never use cursor views // SCI1 middle and older games never use cursor views
_setCursorType = SCI_VERSION_0_EARLY;
} else if (getSciVersion() >= SCI_VERSION_1_EARLY && getSciVersion() <= SCI_VERSION_1_MIDDLE) {
// SCI1 early/SCI1 middle games never use cursor views
_setCursorType = SCI_VERSION_0_EARLY; _setCursorType = SCI_VERSION_0_EARLY;
} else if (getSciVersion() >= SCI_VERSION_1_1) { } else if (getSciVersion() >= SCI_VERSION_1_1) {
// SCI1.1 games always use cursor views // SCI1.1 games always use cursor views
_setCursorType = SCI_VERSION_1_1; _setCursorType = SCI_VERSION_1_1;
} else { // SCI1 late game, detect cursor semantics } else { // SCI1 late game, detect cursor semantics
bool found = false; // If the Cursor object exists, we're using the SCI0 early kSetCursor semantics.
if (_segMan->findObjectByName("Cursor") == NULL_REG) {
if (_kernel->_selectorCache.setCursor == -1) { _setCursorType = SCI_VERSION_0_EARLY;
// Find which function of the Game object calls setCursor debugC(1, kDebugLevelGraphics, "Detected SetCursor type: %s", getSciVersionDesc(_setCursorType).c_str());
return _setCursorType;
Object *obj = _segMan->getObject(_gameObj);
for (uint m = 0; m < obj->getMethodCount(); m++) {
found = autoDetectFeature(kDetectSetCursorType, m);
if (found)
break;
}
} else {
found = autoDetectFeature(kDetectSetCursorType);
} }
if (!found) { // Check for the existence of the handCursor object (first found). This is based on KQ5.
// Quite normal in several demos which don't have a cursor reg_t objAddr = _segMan->findObjectByName("handCursor", 0);
warning("SetCursor detection failed, taking an educated guess");
if (getSciVersion() >= SCI_VERSION_1_1) // If that doesn't exist, we assume it uses SCI1.1 kSetCursor semantics
_setCursorType = SCI_VERSION_1_1; if (objAddr == NULL_REG) {
else _setCursorType = SCI_VERSION_1_1;
_setCursorType = SCI_VERSION_0_EARLY; debugC(1, kDebugLevelGraphics, "Detected SetCursor type: %s", getSciVersionDesc(_setCursorType).c_str());
return _setCursorType;
} }
// Now we check what the number variable holds in the handCursor object.
uint16 number = GET_SEL32V(_segMan, objAddr, SELECTOR(number));
// If the number is 0, it uses views and therefore the SCI1.1 kSetCursor semantics,
// otherwise it uses the SCI0 early kSetCursor semantics.
if (number == 0)
_setCursorType = SCI_VERSION_1_1;
else
_setCursorType = SCI_VERSION_0_EARLY;
} }
debugC(1, kDebugLevelGraphics, "Detected SetCursor type: %s", getSciVersionDesc(_setCursorType).c_str()); debugC(1, kDebugLevelGraphics, "Detected SetCursor type: %s", getSciVersionDesc(_setCursorType).c_str());

View file

@ -35,9 +35,8 @@ enum FeatureDetection {
kDetectGfxFunctions = 0, kDetectGfxFunctions = 0,
kDetectMoveCountType = 1, kDetectMoveCountType = 1,
kDetectSoundType = 2, kDetectSoundType = 2,
kDetectSetCursorType = 3, kDetectLofsType = 3,
kDetectLofsType = 4, kDetectSci21KernelTable = 4
kDetectSci21KernelTable = 5
}; };
class GameFeatures { class GameFeatures {