SCI: Fix restarting SCI engine with different SCI version

This commit is contained in:
Willem Jan Palenstijn 2011-11-29 18:34:25 +01:00
parent dabea2b515
commit 0192d2f2de
8 changed files with 49 additions and 41 deletions

View file

@ -913,31 +913,33 @@ Common::String Kernel::lookupText(reg_t address, int index) {
// TODO: script_adjust_opcode_formats should probably be part of the // TODO: script_adjust_opcode_formats should probably be part of the
// constructor (?) of a VirtualMachine or a ScriptManager class. // constructor (?) of a VirtualMachine or a ScriptManager class.
//
// FIXME: This function breaks return to launcher because its effects persist
void script_adjust_opcode_formats() { 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) { if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) {
g_opcode_formats[op_lofsa][0] = Script_Offset; g_sci->_opcode_formats[op_lofsa][0] = Script_Offset;
g_opcode_formats[op_lofss][0] = Script_Offset; g_sci->_opcode_formats[op_lofss][0] = Script_Offset;
} }
#ifdef ENABLE_SCI32 #ifdef ENABLE_SCI32
// In SCI32, some arguments are now words instead of bytes // In SCI32, some arguments are now words instead of bytes
if (getSciVersion() >= SCI_VERSION_2) { if (getSciVersion() >= SCI_VERSION_2) {
g_opcode_formats[op_calle][2] = Script_Word; g_sci->_opcode_formats[op_calle][2] = Script_Word;
g_opcode_formats[op_callk][1] = Script_Word; g_sci->_opcode_formats[op_callk][1] = Script_Word;
g_opcode_formats[op_super][1] = Script_Word; g_sci->_opcode_formats[op_super][1] = Script_Word;
g_opcode_formats[op_send][0] = Script_Word; g_sci->_opcode_formats[op_send][0] = Script_Word;
g_opcode_formats[op_self][0] = Script_Word; g_sci->_opcode_formats[op_self][0] = Script_Word;
g_opcode_formats[op_call][1] = Script_Word; g_sci->_opcode_formats[op_call][1] = Script_Word;
g_opcode_formats[op_callb][1] = Script_Word; g_sci->_opcode_formats[op_callb][1] = Script_Word;
} }
if (getSciVersion() >= SCI_VERSION_3) { if (getSciVersion() >= SCI_VERSION_3) {
// TODO: There are also opcodes in // TODO: There are also opcodes in
// here to get the superclass, and possibly the species too. // here to get the superclass, and possibly the species too.
g_opcode_formats[0x4d/2][0] = Script_None; g_sci->_opcode_formats[0x4d/2][0] = Script_None;
g_opcode_formats[0x4e/2][0] = Script_None; g_sci->_opcode_formats[0x4e/2][0] = Script_None;
} }
#endif #endif
} }

View file

@ -24,7 +24,7 @@
#define SCI_ENGINE_KERNEL_TABLES_H #define SCI_ENGINE_KERNEL_TABLES_H
#include "sci/engine/workarounds.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 { namespace Sci {
@ -1110,7 +1110,9 @@ static const char *const sci21_default_knames[] = {
#endif #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*/ /*00*/
{Script_None}, {Script_None}, {Script_None}, {Script_None}, {Script_None}, {Script_None}, {Script_None}, {Script_None},
/*04*/ /*04*/

View file

@ -122,8 +122,8 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
#endif #endif
i = 0; i = 0;
while (g_opcode_formats[opcode][i]) { while (g_sci->_opcode_formats[opcode][i]) {
switch (g_opcode_formats[opcode][i++]) { switch (g_sci->_opcode_formats[opcode][i++]) {
case Script_Invalid: case Script_Invalid:
warning("-Invalid operation-"); warning("-Invalid operation-");
break; break;

View file

@ -462,10 +462,10 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])
memset(opparams, 0, 4*sizeof(int16)); 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); //debugN("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opcode, temp);
assert(i < 3); assert(i < 3);
switch (g_opcode_formats[opcode][i]) { switch (g_sci->_opcode_formats[opcode][i]) {
case Script_Byte: case Script_Byte:
opparams[i] = src[offset++]; opparams[i] = src[offset++];

View file

@ -139,26 +139,6 @@ enum {
GC_INTERVAL = 0x8000 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 { enum sci_opcodes {
op_bnot = 0x00, // 000 op_bnot = 0x00, // 000
op_add = 0x01, // 001 op_add = 0x01, // 001
@ -290,8 +270,6 @@ enum sci_opcodes {
op_minusspi = 0x7f // 127 op_minusspi = 0x7f // 127
}; };
extern opcode_format g_opcode_formats[128][4];
void script_adjust_opcode_formats(); void script_adjust_opcode_formats();
/** /**

View file

@ -172,6 +172,26 @@ enum {
NULL_SELECTOR = -1 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 } // End of namespace Sci

View file

@ -91,6 +91,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
_vocabularyLanguage = 1; // we load english vocabulary on startup _vocabularyLanguage = 1; // we load english vocabulary on startup
_eventMan = 0; _eventMan = 0;
_console = 0; _console = 0;
_opcode_formats = 0;
// Set up the engine specific debug levels // Set up the engine specific debug levels
DebugMan.addDebugChannel(kDebugLevelError, "Error", "Script error debugging"); DebugMan.addDebugChannel(kDebugLevelError, "Error", "Script error debugging");
@ -179,6 +180,9 @@ SciEngine::~SciEngine() {
delete _eventMan; delete _eventMan;
delete _gamestate->_segMan; delete _gamestate->_segMan;
delete _gamestate; delete _gamestate;
delete[] _opcode_formats;
delete _resMan; // should be deleted last delete _resMan; // should be deleted last
g_sci = 0; g_sci = 0;
} }

View file

@ -330,6 +330,8 @@ public:
SoundCommandParser *_soundCmd; SoundCommandParser *_soundCmd;
GameFeatures *_features; GameFeatures *_features;
opcode_format (*_opcode_formats)[4];
DebugState _debugState; DebugState _debugState;
Common::MacResManager *getMacExecutable() { return &_macExecutable; } Common::MacResManager *getMacExecutable() { return &_macExecutable; }