From 0192d2f2de5838ac380b4ec3c6f0a72a93a4bc2b Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 29 Nov 2011 18:34:25 +0100 Subject: SCI: Fix restarting SCI engine with different SCI version --- engines/sci/engine/kernel.cpp | 28 +++++++++++++++------------- engines/sci/engine/kernel_tables.h | 6 ++++-- engines/sci/engine/scriptdebug.cpp | 4 ++-- engines/sci/engine/vm.cpp | 4 ++-- engines/sci/engine/vm.h | 22 ---------------------- engines/sci/engine/vm_types.h | 20 ++++++++++++++++++++ engines/sci/sci.cpp | 4 ++++ engines/sci/sci.h | 2 ++ 8 files changed, 49 insertions(+), 41 deletions(-) diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 9203bf24d3..c99bc4fe47 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -913,31 +913,33 @@ Common::String Kernel::lookupText(reg_t address, int index) { // TODO: script_adjust_opcode_formats should probably be part of the // constructor (?) of a VirtualMachine or a ScriptManager class. -// -// FIXME: This function breaks return to launcher because its effects persist void script_adjust_opcode_formats() { + + g_sci->_opcode_formats = new opcode_format[128][4]; + memcpy(g_sci->_opcode_formats, g_base_opcode_formats, 128*4*sizeof(opcode_format)); + if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) { - g_opcode_formats[op_lofsa][0] = Script_Offset; - g_opcode_formats[op_lofss][0] = Script_Offset; + g_sci->_opcode_formats[op_lofsa][0] = Script_Offset; + g_sci->_opcode_formats[op_lofss][0] = Script_Offset; } #ifdef ENABLE_SCI32 // In SCI32, some arguments are now words instead of bytes if (getSciVersion() >= SCI_VERSION_2) { - g_opcode_formats[op_calle][2] = Script_Word; - g_opcode_formats[op_callk][1] = Script_Word; - g_opcode_formats[op_super][1] = Script_Word; - g_opcode_formats[op_send][0] = Script_Word; - g_opcode_formats[op_self][0] = Script_Word; - g_opcode_formats[op_call][1] = Script_Word; - g_opcode_formats[op_callb][1] = Script_Word; + g_sci->_opcode_formats[op_calle][2] = Script_Word; + g_sci->_opcode_formats[op_callk][1] = Script_Word; + g_sci->_opcode_formats[op_super][1] = Script_Word; + g_sci->_opcode_formats[op_send][0] = Script_Word; + g_sci->_opcode_formats[op_self][0] = Script_Word; + g_sci->_opcode_formats[op_call][1] = Script_Word; + g_sci->_opcode_formats[op_callb][1] = Script_Word; } if (getSciVersion() >= SCI_VERSION_3) { // TODO: There are also opcodes in // here to get the superclass, and possibly the species too. - g_opcode_formats[0x4d/2][0] = Script_None; - g_opcode_formats[0x4e/2][0] = Script_None; + g_sci->_opcode_formats[0x4d/2][0] = Script_None; + g_sci->_opcode_formats[0x4e/2][0] = Script_None; } #endif } diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index d8d9f6bd82..fe0c9fc2ef 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -24,7 +24,7 @@ #define SCI_ENGINE_KERNEL_TABLES_H #include "sci/engine/workarounds.h" -#include "sci/engine/vm.h" // for opcode_formats +#include "sci/engine/vm_types.h" // for opcode_formats namespace Sci { @@ -1110,7 +1110,9 @@ static const char *const sci21_default_knames[] = { #endif -opcode_format g_opcode_formats[128][4] = { +// Base set of opcode formats. They're copied and adjusted slightly in +// script_adjust_opcode_format depending on SCI version. +static const opcode_format g_base_opcode_formats[128][4] = { /*00*/ {Script_None}, {Script_None}, {Script_None}, {Script_None}, /*04*/ diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 3faa13183c..554a6b6a2c 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -122,8 +122,8 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode #endif i = 0; - while (g_opcode_formats[opcode][i]) { - switch (g_opcode_formats[opcode][i++]) { + while (g_sci->_opcode_formats[opcode][i]) { + switch (g_sci->_opcode_formats[opcode][i++]) { case Script_Invalid: warning("-Invalid operation-"); break; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 226a73b139..cbe4736ba2 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -462,10 +462,10 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]) memset(opparams, 0, 4*sizeof(int16)); - for (int i = 0; g_opcode_formats[opcode][i]; ++i) { + for (int i = 0; g_sci->_opcode_formats[opcode][i]; ++i) { //debugN("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opcode, temp); assert(i < 3); - switch (g_opcode_formats[opcode][i]) { + switch (g_sci->_opcode_formats[opcode][i]) { case Script_Byte: opparams[i] = src[offset++]; diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 36eadfa1c2..334d224baf 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -139,26 +139,6 @@ enum { GC_INTERVAL = 0x8000 }; -// Opcode formats -enum opcode_format { - Script_Invalid = -1, - Script_None = 0, - Script_Byte, - Script_SByte, - Script_Word, - Script_SWord, - Script_Variable, - Script_SVariable, - Script_SRelative, - Script_Property, - Script_Global, - Script_Local, - Script_Temp, - Script_Param, - Script_Offset, - Script_End -}; - enum sci_opcodes { op_bnot = 0x00, // 000 op_add = 0x01, // 001 @@ -290,8 +270,6 @@ enum sci_opcodes { op_minusspi = 0x7f // 127 }; -extern opcode_format g_opcode_formats[128][4]; - void script_adjust_opcode_formats(); /** diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h index dc87cf758a..7b155a4532 100644 --- a/engines/sci/engine/vm_types.h +++ b/engines/sci/engine/vm_types.h @@ -172,6 +172,26 @@ enum { NULL_SELECTOR = -1 }; +// Opcode formats +enum opcode_format { + Script_Invalid = -1, + Script_None = 0, + Script_Byte, + Script_SByte, + Script_Word, + Script_SWord, + Script_Variable, + Script_SVariable, + Script_SRelative, + Script_Property, + Script_Global, + Script_Local, + Script_Temp, + Script_Param, + Script_Offset, + Script_End +}; + } // End of namespace Sci diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 6eeed66e4f..00731fc1cf 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -91,6 +91,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam _vocabularyLanguage = 1; // we load english vocabulary on startup _eventMan = 0; _console = 0; + _opcode_formats = 0; // Set up the engine specific debug levels DebugMan.addDebugChannel(kDebugLevelError, "Error", "Script error debugging"); @@ -179,6 +180,9 @@ SciEngine::~SciEngine() { delete _eventMan; delete _gamestate->_segMan; delete _gamestate; + + delete[] _opcode_formats; + delete _resMan; // should be deleted last g_sci = 0; } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 9bead768a6..9f18219cb7 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -330,6 +330,8 @@ public: SoundCommandParser *_soundCmd; GameFeatures *_features; + opcode_format (*_opcode_formats)[4]; + DebugState _debugState; Common::MacResManager *getMacExecutable() { return &_macExecutable; } -- cgit v1.2.3