Detect whether to use the modified SCI2 or SCI2.1 kernel table based on the kDoSound call used in Sound::play(), which fixes at least my version of KQ7 - probably others. The kernel table initialization now occurs after the script signatures are adjusted as we need it adjusted before checking through Sound::play for the kDoSound call.
svn-id: r47645
This commit is contained in:
parent
8ecd76e415
commit
d883b6215f
7 changed files with 78 additions and 27 deletions
|
@ -379,12 +379,9 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
{NULL, NULL, NULL} // Terminator
|
{NULL, NULL, NULL} // Terminator
|
||||||
};
|
};
|
||||||
|
|
||||||
Kernel::Kernel(ResourceManager *resMan, Common::String gameId) : _resMan(resMan) {
|
Kernel::Kernel(ResourceManager *resMan) : _resMan(resMan) {
|
||||||
loadSelectorNames();
|
loadSelectorNames();
|
||||||
mapSelectors(); // Map a few special selectors for later use
|
mapSelectors(); // Map a few special selectors for later use
|
||||||
|
|
||||||
loadKernelNames(gameId);
|
|
||||||
mapFunctions(); // Map the kernel functions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::~Kernel() {
|
Kernel::~Kernel() {
|
||||||
|
@ -777,17 +774,19 @@ void Kernel::setDefaultKernelNames(Common::String gameId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Kernel::loadKernelNames(Common::String gameId) {
|
bool Kernel::loadKernelNames(Common::String gameId, EngineState *s) {
|
||||||
_kernelNames.clear();
|
_kernelNames.clear();
|
||||||
|
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
if (getSciVersion() >= SCI_VERSION_2_1)
|
if (getSciVersion() >= SCI_VERSION_2_1)
|
||||||
setKernelNamesSci21(gameId);
|
setKernelNamesSci21(s);
|
||||||
else if (getSciVersion() == SCI_VERSION_2)
|
else if (getSciVersion() == SCI_VERSION_2)
|
||||||
setKernelNamesSci2();
|
setKernelNamesSci2();
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
setDefaultKernelNames(gameId);
|
setDefaultKernelNames(gameId);
|
||||||
|
|
||||||
|
mapFunctions();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Initializes the SCI kernel
|
* Initializes the SCI kernel
|
||||||
*/
|
*/
|
||||||
Kernel(ResourceManager *resMan, Common::String gameId);
|
Kernel(ResourceManager *resMan);
|
||||||
~Kernel();
|
~Kernel();
|
||||||
|
|
||||||
uint getSelectorNamesSize() const;
|
uint getSelectorNamesSize() const;
|
||||||
|
@ -121,6 +121,17 @@ public:
|
||||||
uint getKernelNamesSize() const;
|
uint getKernelNamesSize() const;
|
||||||
const Common::String &getKernelName(uint number) const;
|
const Common::String &getKernelName(uint number) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the kernel function names.
|
||||||
|
*
|
||||||
|
* This function reads the kernel function name table from resource_map,
|
||||||
|
* and fills the _kernelNames array with them.
|
||||||
|
* The resulting list has the same format regardless of the format of the
|
||||||
|
* name table of the resource (the format changed between version 0 and 1).
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool loadKernelNames(Common::String gameId, EngineState *s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the selector ID of a selector by its name
|
* Determines the selector ID of a selector by its name
|
||||||
* @param selectorName Name of the selector to look up
|
* @param selectorName Name of the selector to look up
|
||||||
|
@ -138,17 +149,6 @@ public:
|
||||||
KernelFuncsContainer _kernelFuncs; /**< Table of kernel functions */
|
KernelFuncsContainer _kernelFuncs; /**< Table of kernel functions */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* Loads the kernel function names.
|
|
||||||
*
|
|
||||||
* This function reads the kernel function name table from resource_map,
|
|
||||||
* and fills the _kernelNames array with them.
|
|
||||||
* The resulting list has the same format regardless of the format of the
|
|
||||||
* name table of the resource (the format changed between version 0 and 1).
|
|
||||||
* @return true on success, false on failure
|
|
||||||
*/
|
|
||||||
bool loadKernelNames(Common::String gameId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default kernel function names, based on the SCI version used
|
* Sets the default kernel function names, based on the SCI version used
|
||||||
*/
|
*/
|
||||||
|
@ -163,7 +163,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Sets the default kernel function names to the SCI2.1 kernel functions
|
* Sets the default kernel function names to the SCI2.1 kernel functions
|
||||||
*/
|
*/
|
||||||
void setKernelNamesSci21(Common::String gameId);
|
void setKernelNamesSci21(EngineState *s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -372,11 +372,15 @@ void Kernel::setKernelNamesSci2() {
|
||||||
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesSci2);
|
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesSci2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::setKernelNamesSci21(Common::String gameId) {
|
void Kernel::setKernelNamesSci21(EngineState *s) {
|
||||||
// The Gabriel Knight 2 demo uses a different kernel function set. It's pretty much a cross between
|
// Some SCI games use a modified SCI2 kernel table instead of the SCI2.1/SCI3 kernel table.
|
||||||
// the SCI2 and SCI2.1 set. Strangely, the GK2 executable still has the 2.100.002 version string,
|
// The GK2 demo does this as well as at least one version of KQ7. We detect which version
|
||||||
// even though it wouldn't be compatible with the other 2.100.002 games...
|
// to use based on where kDoSound is called from Sound::play().
|
||||||
if (gameId == "gk2" && ((SciEngine *)g_engine)->isDemo()) {
|
|
||||||
|
// This is interesting because they all have the same interpreter version (2.100.002), yet
|
||||||
|
// they would not be compatible with other games of the same interpreter.
|
||||||
|
|
||||||
|
if (s->detectSci21KernelType() == SCI_VERSION_2) {
|
||||||
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesGk2Demo);
|
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesGk2Demo);
|
||||||
// OnMe is IsOnMe here, but they should be compatible
|
// OnMe is IsOnMe here, but they should be compatible
|
||||||
_kernelNames[0x23] = "Robot"; // Graph in SCI2
|
_kernelNames[0x23] = "Robot"; // Graph in SCI2
|
||||||
|
|
|
@ -78,6 +78,10 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc,
|
||||||
_lofsType = SCI_VERSION_NONE;
|
_lofsType = SCI_VERSION_NONE;
|
||||||
_gfxFunctionsType = SCI_VERSION_NONE;
|
_gfxFunctionsType = SCI_VERSION_NONE;
|
||||||
_moveCountType = kMoveCountUninitialized;
|
_moveCountType = kMoveCountUninitialized;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
_sci21KernelType = SCI_VERSION_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
_usesCdTrack = Common::File::exists("cdaudio.map");
|
_usesCdTrack = Common::File::exists("cdaudio.map");
|
||||||
|
|
||||||
|
@ -246,6 +250,13 @@ bool EngineState::autoDetectFeature(FeatureDetection featureDetection, int metho
|
||||||
objName = "Game";
|
objName = "Game";
|
||||||
objAddr = _segMan->findObjectByName(objName);
|
objAddr = _segMan->findObjectByName(objName);
|
||||||
break;
|
break;
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
case kDetectSci21KernelTable:
|
||||||
|
objName = "Sound";
|
||||||
|
objAddr = _segMan->findObjectByName(objName);
|
||||||
|
slc = _kernel->_selectorCache.play;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
warning("autoDetectFeature: invalid featureDetection value %x", featureDetection);
|
warning("autoDetectFeature: invalid featureDetection value %x", featureDetection);
|
||||||
return false;
|
return false;
|
||||||
|
@ -422,6 +433,17 @@ bool EngineState::autoDetectFeature(FeatureDetection featureDetection, int metho
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
case kDetectSci21KernelTable:
|
||||||
|
if (kFuncNum == 0x40) {
|
||||||
|
_sci21KernelType = SCI_VERSION_2;
|
||||||
|
return true;
|
||||||
|
} else if (kFuncNum == 0x75) {
|
||||||
|
_sci21KernelType = SCI_VERSION_2_1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -629,6 +651,18 @@ SciVersion EngineState::detectGfxFunctionsType() {
|
||||||
return _gfxFunctionsType;
|
return _gfxFunctionsType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
SciVersion EngineState::detectSci21KernelType() {
|
||||||
|
if (_sci21KernelType == SCI_VERSION_NONE)
|
||||||
|
if (!autoDetectFeature(kDetectSci21KernelTable))
|
||||||
|
error("Could not detect the SCI2.1 kernel table type");
|
||||||
|
|
||||||
|
debugC(1, kDebugLevelVM, "Detected SCI2.1 kernel type: %s", getSciVersionDesc(_sci21KernelType).c_str());
|
||||||
|
|
||||||
|
return _sci21KernelType;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MoveCountType EngineState::detectMoveCountType() {
|
MoveCountType EngineState::detectMoveCountType() {
|
||||||
if (_moveCountType == kMoveCountUninitialized) {
|
if (_moveCountType == kMoveCountUninitialized) {
|
||||||
// SCI0/SCI01 games always increment move count
|
// SCI0/SCI01 games always increment move count
|
||||||
|
|
|
@ -110,7 +110,8 @@ enum FeatureDetection {
|
||||||
kDetectMoveCountType = 1,
|
kDetectMoveCountType = 1,
|
||||||
kDetectSoundType = 2,
|
kDetectSoundType = 2,
|
||||||
kDetectSetCursorType = 3,
|
kDetectSetCursorType = 3,
|
||||||
kDetectLofsType = 4
|
kDetectLofsType = 4,
|
||||||
|
kDetectSci21KernelTable = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileHandle {
|
class FileHandle {
|
||||||
|
@ -227,6 +228,14 @@ public:
|
||||||
* @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
|
* @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
|
||||||
*/
|
*/
|
||||||
SciVersion detectGfxFunctionsType();
|
SciVersion detectGfxFunctionsType();
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
/**
|
||||||
|
* Autodetects the kernel functions used in SCI2.1
|
||||||
|
* @return Graphics functions type, SCI_VERSION_2 / SCI_VERSION_2_1
|
||||||
|
*/
|
||||||
|
SciVersion detectSci21KernelType();
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies to all versions before 0.000.502
|
* Applies to all versions before 0.000.502
|
||||||
|
@ -270,6 +279,10 @@ private:
|
||||||
bool autoDetectFeature(FeatureDetection featureDetection, int methodNum = -1);
|
bool autoDetectFeature(FeatureDetection featureDetection, int methodNum = -1);
|
||||||
|
|
||||||
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
SciVersion _sci21KernelType;
|
||||||
|
#endif
|
||||||
|
|
||||||
MoveCountType _moveCountType;
|
MoveCountType _moveCountType;
|
||||||
kLanguage charToLanguage(const char c) const;
|
kLanguage charToLanguage(const char c) const;
|
||||||
bool _usesCdTrack;
|
bool _usesCdTrack;
|
||||||
|
|
|
@ -198,7 +198,7 @@ struct SelectorCache {
|
||||||
Selector setCursor; ///< For cursor semantics autodetection
|
Selector setCursor; ///< For cursor semantics autodetection
|
||||||
|
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
Selector data; // Used by Array()
|
Selector data; // Used by Array()/String()
|
||||||
Selector picture; // Used to hold the picture ID for SCI32 pictures
|
Selector picture; // Used to hold the picture ID for SCI32 pictures
|
||||||
|
|
||||||
Selector plane;
|
Selector plane;
|
||||||
|
|
|
@ -140,7 +140,7 @@ Common::Error SciEngine::run() {
|
||||||
// Create debugger console. It requires GFX to be initialized
|
// Create debugger console. It requires GFX to be initialized
|
||||||
_console = new Console(this);
|
_console = new Console(this);
|
||||||
|
|
||||||
_kernel = new Kernel(_resMan, getGameID());
|
_kernel = new Kernel(_resMan);
|
||||||
// Only SCI0 and SCI01 games used a parser
|
// Only SCI0 and SCI01 games used a parser
|
||||||
_vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL;
|
_vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL;
|
||||||
_audio = new AudioPlayer(_resMan);
|
_audio = new AudioPlayer(_resMan);
|
||||||
|
@ -163,6 +163,7 @@ Common::Error SciEngine::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
script_adjust_opcode_formats(_gamestate);
|
script_adjust_opcode_formats(_gamestate);
|
||||||
|
_kernel->loadKernelNames(getGameID(), _gamestate);
|
||||||
|
|
||||||
// Set the savegame dir (actually, we set it to a fake value,
|
// Set the savegame dir (actually, we set it to a fake value,
|
||||||
// since we cannot let the game control where saves are stored)
|
// since we cannot let the game control where saves are stored)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue