aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/intern.h3
-rw-r--r--scumm/script.cpp13
-rw-r--r--scumm/script_v6.cpp16
-rw-r--r--scumm/script_v8.cpp23
-rw-r--r--scumm/scumm.h3
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();