mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 20:59:00 +00:00
SCI: Cleanup of the save/load dialog patching code and the lofs type detection code
This commit is contained in:
parent
d90c7a8314
commit
4d33923436
@ -285,20 +285,16 @@ SciVersion GameFeatures::detectLofsType() {
|
||||
}
|
||||
|
||||
// Find a function of the "Game" object (which is the game super class) which invokes lofsa/lofss
|
||||
reg_t gameSuperClass = g_sci->getGameSuperClassAddress();
|
||||
const Object *gameObject = _segMan->getObject(g_sci->getGameObject());
|
||||
const Object *gameSuperObject = _segMan->getObject(gameObject->getSuperClassSelector());
|
||||
bool found = false;
|
||||
if (!gameSuperClass.isNull()) {
|
||||
Common::String gameSuperClassName = _segMan->getObjectName(gameSuperClass);
|
||||
const Object *gameSuperObject = _segMan->getObject(gameSuperClass);
|
||||
if (gameSuperObject) {
|
||||
Common::String gameSuperClassName = _segMan->getObjectName(gameObject->getSuperClassSelector());
|
||||
|
||||
if (gameSuperObject) {
|
||||
for (uint m = 0; m < gameSuperObject->getMethodCount(); m++) {
|
||||
found = autoDetectLofsType(gameSuperClassName, m);
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
warning("detectLofsType(): Could not get superclass object");
|
||||
for (uint m = 0; m < gameSuperObject->getMethodCount(); m++) {
|
||||
found = autoDetectLofsType(gameSuperClassName, m);
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
warning("detectLofsType(): Could not find superclass of game object");
|
||||
|
@ -213,7 +213,6 @@ Common::Error SciEngine::run() {
|
||||
// Add the after market GM patches for the specified game, if they exist
|
||||
_resMan->addNewGMPatch(_gameId);
|
||||
_gameObjectAddress = _resMan->findGameObject();
|
||||
_gameSuperClassAddress = NULL_REG;
|
||||
|
||||
SegManager *segMan = new SegManager(_resMan);
|
||||
|
||||
@ -250,7 +249,6 @@ Common::Error SciEngine::run() {
|
||||
warning("Could not get game object, aborting...");
|
||||
return Common::kUnknownError;
|
||||
}
|
||||
_gameSuperClassAddress = gameObject->getSuperClassSelector();
|
||||
|
||||
script_adjust_opcode_formats();
|
||||
|
||||
@ -441,19 +439,24 @@ static byte patchGameRestoreSaveSci2[] = {
|
||||
0x48, // ret
|
||||
};
|
||||
|
||||
static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) {
|
||||
Script *script = segMan->getScript(methodAddress.segment);
|
||||
byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.offset));
|
||||
if (getSciVersion() <= SCI_VERSION_1_1)
|
||||
memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
|
||||
else if (getSciVersion() == SCI_VERSION_2)
|
||||
memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2));
|
||||
// TODO: SCI21/SCI3
|
||||
patchPtr[8] = id;
|
||||
}
|
||||
|
||||
void SciEngine::patchGameSaveRestore() {
|
||||
SegManager *segMan = _gamestate->_segMan;
|
||||
const Object *gameObject = segMan->getObject(_gameObjectAddress);
|
||||
const uint16 gameMethodCount = gameObject->getMethodCount();
|
||||
const Object *gameSuperObject = segMan->getObject(_gameSuperClassAddress);
|
||||
const Object *gameSuperObject = segMan->getObject(gameObject->getSuperClassSelector());
|
||||
if (!gameSuperObject)
|
||||
gameSuperObject = gameObject; // happens in KQ5CD, when loading saved games before r54510
|
||||
const uint16 gameSuperMethodCount = gameSuperObject->getMethodCount();
|
||||
reg_t methodAddress;
|
||||
const uint16 kernelCount = _kernel->getKernelNamesSize();
|
||||
const byte *scriptRestorePtr = NULL;
|
||||
byte kernelIdRestore = 0;
|
||||
const byte *scriptSavePtr = NULL;
|
||||
byte kernelIdSave = 0;
|
||||
|
||||
// This feature is currently not supported in SCI21 or SCI3
|
||||
@ -473,7 +476,8 @@ void SciEngine::patchGameSaveRestore() {
|
||||
if (ConfMan.getBool("sci_originalsaveload"))
|
||||
return;
|
||||
|
||||
for (uint16 kernelNr = 0; kernelNr < kernelCount; kernelNr++) {
|
||||
uint16 kernelNamesSize = _kernel->getKernelNamesSize();
|
||||
for (uint16 kernelNr = 0; kernelNr < kernelNamesSize; kernelNr++) {
|
||||
Common::String kernelName = _kernel->getKernelName(kernelNr);
|
||||
if (kernelName == "RestoreGame")
|
||||
kernelIdRestore = kernelNr;
|
||||
@ -481,61 +485,30 @@ void SciEngine::patchGameSaveRestore() {
|
||||
kernelIdSave = kernelNr;
|
||||
}
|
||||
|
||||
// Search for gameobject-superclass ::restore
|
||||
for (uint16 methodNr = 0; methodNr < gameSuperMethodCount; methodNr++) {
|
||||
// Search for gameobject superclass ::restore
|
||||
uint16 gameSuperObjectMethodCount = gameSuperObject->getMethodCount();
|
||||
for (uint16 methodNr = 0; methodNr < gameSuperObjectMethodCount; methodNr++) {
|
||||
uint16 selectorId = gameSuperObject->getFuncSelector(methodNr);
|
||||
Common::String methodName = _kernel->getSelectorName(selectorId);
|
||||
if (methodName == "restore") {
|
||||
methodAddress = gameSuperObject->getFunction(methodNr);
|
||||
Script *script = segMan->getScript(methodAddress.segment);
|
||||
scriptRestorePtr = script->getBuf(methodAddress.offset);
|
||||
}
|
||||
if (methodName == "save") {
|
||||
methodAddress = gameSuperObject->getFunction(methodNr);
|
||||
Script *script = segMan->getScript(methodAddress.segment);
|
||||
scriptSavePtr = script->getBuf(methodAddress.offset);
|
||||
if (methodName == "restore")
|
||||
patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdRestore);
|
||||
else if (methodName == "save") {
|
||||
if (_gameId != GID_FAIRYTALES) // Fairy Tales saves automatically without a dialog
|
||||
patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave);
|
||||
}
|
||||
}
|
||||
|
||||
// Search for gameobject ::save, if there is one patch that one instead
|
||||
for (uint16 methodNr = 0; methodNr < gameMethodCount; methodNr++) {
|
||||
// Search for gameobject ::save, if there is one patch that one too
|
||||
uint16 gameObjectMethodCount = gameObject->getMethodCount();
|
||||
for (uint16 methodNr = 0; methodNr < gameObjectMethodCount; methodNr++) {
|
||||
uint16 selectorId = gameObject->getFuncSelector(methodNr);
|
||||
Common::String methodName = _kernel->getSelectorName(selectorId);
|
||||
if (methodName == "save") {
|
||||
methodAddress = gameObject->getFunction(methodNr);
|
||||
Script *script = segMan->getScript(methodAddress.segment);
|
||||
scriptSavePtr = script->getBuf(methodAddress.offset);
|
||||
if (_gameId != GID_FAIRYTALES) // Fairy Tales saves automatically without a dialog
|
||||
patchGameSaveRestoreCode(segMan, gameObject->getFunction(methodNr), kernelIdSave);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_gameId) {
|
||||
case GID_FAIRYTALES: // fairy tales automatically saves w/o dialog
|
||||
scriptSavePtr = NULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (scriptRestorePtr) {
|
||||
// Now patch in our code
|
||||
byte *patchPtr = const_cast<byte *>(scriptRestorePtr);
|
||||
if (getSciVersion() <= SCI_VERSION_1_1)
|
||||
memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
|
||||
else if (getSciVersion() == SCI_VERSION_2)
|
||||
memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2));
|
||||
// TODO: SCI21/SCI3
|
||||
patchPtr[8] = kernelIdRestore;
|
||||
}
|
||||
if (scriptSavePtr) {
|
||||
// Now patch in our code
|
||||
byte *patchPtr = const_cast<byte *>(scriptSavePtr);
|
||||
if (getSciVersion() <= SCI_VERSION_1_1)
|
||||
memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
|
||||
else if (getSciVersion() == SCI_VERSION_2)
|
||||
memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2));
|
||||
// TODO: SCI21/SCI3
|
||||
patchPtr[8] = kernelIdSave;
|
||||
}
|
||||
}
|
||||
|
||||
bool SciEngine::initGame() {
|
||||
|
@ -246,7 +246,6 @@ public:
|
||||
inline Vocabulary *getVocabulary() const { return _vocabulary; }
|
||||
inline EventManager *getEventManager() const { return _eventMan; }
|
||||
inline reg_t getGameObject() const { return _gameObjectAddress; }
|
||||
inline reg_t getGameSuperClassAddress() const { return _gameSuperClassAddress; }
|
||||
|
||||
Common::RandomSource &getRNG() { return _rng; }
|
||||
|
||||
@ -375,7 +374,6 @@ private:
|
||||
int16 _vocabularyLanguage;
|
||||
EventManager *_eventMan;
|
||||
reg_t _gameObjectAddress; /**< Pointer to the game object */
|
||||
reg_t _gameSuperClassAddress; // Address of the super class of the game object
|
||||
Console *_console;
|
||||
Common::RandomSource _rng;
|
||||
Common::MacResManager _macExecutable;
|
||||
|
Loading…
x
Reference in New Issue
Block a user