diff options
| -rw-r--r-- | scumm/intern.h | 3 | ||||
| -rw-r--r-- | scumm/script.cpp | 13 | ||||
| -rw-r--r-- | scumm/script_v6.cpp | 16 | ||||
| -rw-r--r-- | scumm/script_v8.cpp | 23 | ||||
| -rw-r--r-- | scumm/scumm.h | 3 |
5 files changed, 48 insertions, 10 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index 68e5992def..60d311e791 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -396,6 +396,9 @@ protected: virtual void executeOpcode(int i); virtual const char *getOpcodeDesc(int i); + virtual uint fetchScriptWord(); + virtual int fetchScriptWordSigned(); + /* Version 8 script opcodes */ void o8_unknown(); void o8_invalid(); diff --git a/scumm/script.cpp b/scumm/script.cpp index ff957955c0..182e0ce5f4 100644 --- a/scumm/script.cpp +++ b/scumm/script.cpp @@ -297,7 +297,7 @@ byte Scumm::fetchScriptByte() return *_scriptPointer++; } -int Scumm::fetchScriptWord() +uint Scumm::fetchScriptWord() { int a; if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) { @@ -310,6 +310,11 @@ int Scumm::fetchScriptWord() return a; } +int Scumm::fetchScriptWordSigned() +{ + return (int16)fetchScriptWord(); +} + #ifndef BYPASS_COPY_PROT #define BYPASS_COPY_PROT #endif @@ -1010,7 +1015,11 @@ int Scumm::defineArray(int array, int type, int dim2, int dim1) writeVar(array, id); - size = (type == 5) ? 16 : 8; + if (_features & GF_AFTER_V8) { + size = 32; // FIXME - this is just a guess + } else { + size = (type == 5) ? 16 : 8; + } size *= dim2 + 1; size *= dim1 + 1; size >>= 3; diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index c5210839b8..af7b9fc77b 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -422,6 +422,9 @@ int Scumm::readArray(int array, int idx, int base) if (ah->type == 4) { return ah->data[base]; + } else if (_features & GF_AFTER_V8) { + // FIXME - this is just a guess, might be wrong + return (int32)READ_LE_UINT32(ah->data + base * 4); } else { return (int16)READ_LE_UINT16(ah->data + base * 2); } @@ -438,6 +441,9 @@ void Scumm::writeArray(int array, int idx, int base, int value) if (ah->type == 4) { ah->data[base] = value; + } else if (_features & GF_AFTER_V8) { + // FIXME - this is just a guess, might be wrong + ((uint32 *)ah->data)[base] = TO_LE_32(value); } else { ((uint16 *)ah->data)[base] = TO_LE_16(value); } @@ -470,7 +476,7 @@ void Scumm_v6::o6_pushByte() void Scumm_v6::o6_pushWord() { - push((int16)fetchScriptWord()); + push(fetchScriptWordSigned()); } void Scumm_v6::o6_pushByteVar() @@ -722,7 +728,7 @@ void Scumm_v6::o6_jumpFalse() void Scumm_v6::o6_jump() { - _scriptPointer += (int16)fetchScriptWord(); + _scriptPointer += fetchScriptWordSigned(); } void Scumm_v6::o6_startScriptEx() @@ -2047,7 +2053,7 @@ void Scumm_v6::o6_wait() { switch (fetchScriptByte()) { case 168:{ - int offs = (int16)fetchScriptWord(); + int offs = fetchScriptWordSigned(); if (derefActorSafe(pop(), "o6_wait")->moving) { _scriptPointer += offs; o6_breakHere(); @@ -2092,7 +2098,7 @@ void Scumm_v6::o6_wait() case 226:{ /* wait until actor drawn */ int actnum = pop(); Actor *a = derefActorSafe(actnum, "o6_wait:226"); - int offs = (int16)fetchScriptWord(); + int offs = fetchScriptWordSigned(); if (a && a->isInCurrentRoom() && a->needRedraw) { _scriptPointer += offs; o6_breakHere(); @@ -2102,7 +2108,7 @@ void Scumm_v6::o6_wait() case 232:{ /* wait until actor stops turning */ int actnum = pop(); Actor *a = derefActorSafe(actnum, "o6_wait:232"); - int offs = (int16)fetchScriptWord(); + int offs = fetchScriptWordSigned(); if (a && a->isInCurrentRoom() && a->moving & MF_TURN) { _scriptPointer += offs; o6_breakHere(); diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index d5bb9120fa..6e88455807 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -161,8 +161,8 @@ void Scumm_v8::setupOpcodes() OPCODE(o8_unknown), OPCODE(o8_unknown), /* 64 */ - OPCODE(o6_jumpFalse), - OPCODE(o6_jumpTrue), + OPCODE(o6_jumpFalse), // Not sure about which of these two is which (false==if or true==if ?!?)... + OPCODE(o6_jumpTrue), // ... since "if" could mean 'jump "if"' or 'execute following code "if", otherwise jump'. OPCODE(o6_jump), OPCODE(o6_breakHere), /* 68 */ @@ -371,6 +371,25 @@ const char *Scumm_v8::getOpcodeDesc(int i) return _opcodesV8[i].desc; } +// In V8, the word size is 4 byte, not 2 bytes as in V6/V7 games +uint Scumm_v8::fetchScriptWord() +{ + int a; + if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) { + uint32 oldoffs = _scriptPointer - _scriptOrgPointer; + getScriptBaseAddress(); + _scriptPointer = _scriptOrgPointer + oldoffs; + } + a = READ_LE_UINT32(_scriptPointer); + _scriptPointer += 4; + return a; +} + +int Scumm_v8::fetchScriptWordSigned() +{ + return (int32)fetchScriptWord(); +} + void Scumm_v8::o8_unknown() { warning("Unknown opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer); diff --git a/scumm/scumm.h b/scumm/scumm.h index d9e8f93136..8015a7b030 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -476,7 +476,8 @@ public: void getScriptBaseAddress(); void getScriptEntryPoint(); byte fetchScriptByte(); - int fetchScriptWord(); + virtual uint fetchScriptWord(); + virtual int fetchScriptWordSigned(); void ignoreScriptWord() { fetchScriptWord(); } void ignoreScriptByte() { fetchScriptByte(); } void getResultPos(); |
