mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-12 12:40:58 +00:00
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
@ -379,12 +379,9 @@ SciKernelFunction kfunct_mappers[] = {
|
||||
{NULL, NULL, NULL} // Terminator
|
||||
};
|
||||
|
||||
Kernel::Kernel(ResourceManager *resMan, Common::String gameId) : _resMan(resMan) {
|
||||
Kernel::Kernel(ResourceManager *resMan) : _resMan(resMan) {
|
||||
loadSelectorNames();
|
||||
mapSelectors(); // Map a few special selectors for later use
|
||||
|
||||
loadKernelNames(gameId);
|
||||
mapFunctions(); // Map the kernel functions
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2_1)
|
||||
setKernelNamesSci21(gameId);
|
||||
setKernelNamesSci21(s);
|
||||
else if (getSciVersion() == SCI_VERSION_2)
|
||||
setKernelNamesSci2();
|
||||
else
|
||||
#endif
|
||||
setDefaultKernelNames(gameId);
|
||||
|
||||
mapFunctions();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
/**
|
||||
* Initializes the SCI kernel
|
||||
*/
|
||||
Kernel(ResourceManager *resMan, Common::String gameId);
|
||||
Kernel(ResourceManager *resMan);
|
||||
~Kernel();
|
||||
|
||||
uint getSelectorNamesSize() const;
|
||||
@ -121,6 +121,17 @@ public:
|
||||
uint getKernelNamesSize() 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
|
||||
* @param selectorName Name of the selector to look up
|
||||
@ -138,17 +149,6 @@ public:
|
||||
KernelFuncsContainer _kernelFuncs; /**< Table of kernel functions */
|
||||
|
||||
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
|
||||
*/
|
||||
@ -163,7 +163,7 @@ private:
|
||||
/**
|
||||
* Sets the default kernel function names to the SCI2.1 kernel functions
|
||||
*/
|
||||
void setKernelNamesSci21(Common::String gameId);
|
||||
void setKernelNamesSci21(EngineState *s);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -372,11 +372,15 @@ void Kernel::setKernelNamesSci2() {
|
||||
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesSci2);
|
||||
}
|
||||
|
||||
void Kernel::setKernelNamesSci21(Common::String gameId) {
|
||||
// The Gabriel Knight 2 demo uses a different kernel function set. It's pretty much a cross between
|
||||
// the SCI2 and SCI2.1 set. Strangely, the GK2 executable still has the 2.100.002 version string,
|
||||
// even though it wouldn't be compatible with the other 2.100.002 games...
|
||||
if (gameId == "gk2" && ((SciEngine *)g_engine)->isDemo()) {
|
||||
void Kernel::setKernelNamesSci21(EngineState *s) {
|
||||
// Some SCI games use a modified SCI2 kernel table instead of the SCI2.1/SCI3 kernel table.
|
||||
// The GK2 demo does this as well as at least one version of KQ7. We detect which version
|
||||
// to use based on where kDoSound is called from Sound::play().
|
||||
|
||||
// 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);
|
||||
// OnMe is IsOnMe here, but they should be compatible
|
||||
_kernelNames[0x23] = "Robot"; // Graph in SCI2
|
||||
|
@ -78,6 +78,10 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc,
|
||||
_lofsType = SCI_VERSION_NONE;
|
||||
_gfxFunctionsType = SCI_VERSION_NONE;
|
||||
_moveCountType = kMoveCountUninitialized;
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
_sci21KernelType = SCI_VERSION_NONE;
|
||||
#endif
|
||||
|
||||
_usesCdTrack = Common::File::exists("cdaudio.map");
|
||||
|
||||
@ -246,6 +250,13 @@ bool EngineState::autoDetectFeature(FeatureDetection featureDetection, int metho
|
||||
objName = "Game";
|
||||
objAddr = _segMan->findObjectByName(objName);
|
||||
break;
|
||||
#ifdef ENABLE_SCI32
|
||||
case kDetectSci21KernelTable:
|
||||
objName = "Sound";
|
||||
objAddr = _segMan->findObjectByName(objName);
|
||||
slc = _kernel->_selectorCache.play;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
warning("autoDetectFeature: invalid featureDetection value %x", featureDetection);
|
||||
return false;
|
||||
@ -422,6 +433,17 @@ bool EngineState::autoDetectFeature(FeatureDetection featureDetection, int metho
|
||||
return true;
|
||||
}
|
||||
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:
|
||||
break;
|
||||
}
|
||||
@ -629,6 +651,18 @@ SciVersion EngineState::detectGfxFunctionsType() {
|
||||
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() {
|
||||
if (_moveCountType == kMoveCountUninitialized) {
|
||||
// SCI0/SCI01 games always increment move count
|
||||
|
@ -110,7 +110,8 @@ enum FeatureDetection {
|
||||
kDetectMoveCountType = 1,
|
||||
kDetectSoundType = 2,
|
||||
kDetectSetCursorType = 3,
|
||||
kDetectLofsType = 4
|
||||
kDetectLofsType = 4,
|
||||
kDetectSci21KernelTable = 5
|
||||
};
|
||||
|
||||
class FileHandle {
|
||||
@ -227,6 +228,14 @@ public:
|
||||
* @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
|
||||
*/
|
||||
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
|
||||
@ -270,6 +279,10 @@ private:
|
||||
bool autoDetectFeature(FeatureDetection featureDetection, int methodNum = -1);
|
||||
|
||||
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
||||
#ifdef ENABLE_SCI32
|
||||
SciVersion _sci21KernelType;
|
||||
#endif
|
||||
|
||||
MoveCountType _moveCountType;
|
||||
kLanguage charToLanguage(const char c) const;
|
||||
bool _usesCdTrack;
|
||||
|
@ -198,7 +198,7 @@ struct SelectorCache {
|
||||
Selector setCursor; ///< For cursor semantics autodetection
|
||||
|
||||
#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 plane;
|
||||
|
@ -140,7 +140,7 @@ Common::Error SciEngine::run() {
|
||||
// Create debugger console. It requires GFX to be initialized
|
||||
_console = new Console(this);
|
||||
|
||||
_kernel = new Kernel(_resMan, getGameID());
|
||||
_kernel = new Kernel(_resMan);
|
||||
// Only SCI0 and SCI01 games used a parser
|
||||
_vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL;
|
||||
_audio = new AudioPlayer(_resMan);
|
||||
@ -163,6 +163,7 @@ Common::Error SciEngine::run() {
|
||||
}
|
||||
|
||||
script_adjust_opcode_formats(_gamestate);
|
||||
_kernel->loadKernelNames(getGameID(), _gamestate);
|
||||
|
||||
// Set the savegame dir (actually, we set it to a fake value,
|
||||
// since we cannot let the game control where saves are stored)
|
||||
|
Loading…
x
Reference in New Issue
Block a user