aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2002-12-22 21:58:16 +0000
committerMax Horn2002-12-22 21:58:16 +0000
commitdf3c41fa24f98423ccb9fc23f2fc50f81c782a31 (patch)
treed9fa81b485d8376b8b1478f0bcfc1906b60e304d /scumm
parent3ce3a5be5bbfd6f438584e5c09e08d26eadb9396 (diff)
downloadscummvm-rg350-df3c41fa24f98423ccb9fc23f2fc50f81c782a31.tar.gz
scummvm-rg350-df3c41fa24f98423ccb9fc23f2fc50f81c782a31.tar.bz2
scummvm-rg350-df3c41fa24f98423ccb9fc23f2fc50f81c782a31.zip
added some preliminary V8 work. Nope, it is not useful at all, and it doesn't mean we will have CMI support in this millenium, so don't hold your breath
svn-id: r6060
Diffstat (limited to 'scumm')
-rw-r--r--scumm/intern.h430
-rw-r--r--scumm/module.mk1
-rw-r--r--scumm/resource.cpp73
-rw-r--r--scumm/resource_v2.cpp5
-rw-r--r--scumm/resource_v3.cpp9
-rw-r--r--scumm/resource_v4.cpp5
-rw-r--r--scumm/saveload.cpp3
-rw-r--r--scumm/script_v5.cpp3
-rw-r--r--scumm/script_v6.cpp5
-rw-r--r--scumm/script_v8.cpp1040
-rw-r--r--scumm/scumm.h352
-rw-r--r--scumm/scummvm.cpp3
-rw-r--r--scumm/vars.cpp1
13 files changed, 1550 insertions, 380 deletions
diff --git a/scumm/intern.h b/scumm/intern.h
new file mode 100644
index 0000000000..f59d7ac8bf
--- /dev/null
+++ b/scumm/intern.h
@@ -0,0 +1,430 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001/2002 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef INTERN_H
+#define INTERN_H
+
+#include "scumm.h"
+
+
+class Scumm_v5 : public Scumm
+{
+protected:
+ typedef void (Scumm_v5::*OpcodeProcV5)();
+ struct OpcodeEntryV5 {
+ OpcodeProcV5 proc;
+ const char *desc;
+ };
+
+ const OpcodeEntryV5 *_opcodesV5;
+
+public:
+ Scumm_v5(GameDetector *detector, OSystem *syst) : Scumm(detector, syst) {}
+
+protected:
+ virtual void setupOpcodes();
+ virtual void executeOpcode(int i);
+ virtual const char *getOpcodeDesc(int i);
+
+ void decodeParseString();
+ int getWordVararg(int16 *ptr);
+ int getVarOrDirectWord(byte mask);
+ int getVarOrDirectByte(byte mask);
+
+ /* Version 5 script opcodes */
+ void o5_actorFollowCamera();
+ void o5_actorFromPos();
+ void o5_actorSet();
+ void o5_add();
+ void o5_and();
+ void o5_animateActor();
+ void o5_badOpcode();
+ void o5_breakHere();
+ void o5_chainScript();
+ void o5_cursorCommand();
+ void o5_cutscene();
+ void o5_debug();
+ void o5_decrement();
+ void o5_delay();
+ void o5_delayVariable();
+ void o5_divide();
+ void o5_doSentence();
+ void o5_drawBox();
+ void o5_drawObject();
+ void o5_dummy();
+ void o5_endCutscene();
+ void o5_equalZero();
+ void o5_expression();
+ void o5_faceActor();
+ void o5_findInventory();
+ void o5_findObject();
+ void o5_freezeScripts();
+ void o5_getActorCostume();
+ void o5_getActorElevation();
+ void o5_getActorFacing();
+ void o5_getActorMoving();
+ void o5_getActorRoom();
+ void o5_getActorScale();
+ void o5_getActorWalkBox();
+ void o5_getActorWidth();
+ void o5_getActorX();
+ void o5_getActorY();
+ void o5_getAnimCounter();
+ void o5_getClosestObjActor();
+ void o5_getDist();
+ void o5_getInventoryCount();
+ void o5_getObjectOwner();
+ void o5_getObjectState();
+ void o5_getRandomNr();
+ void o5_isScriptRunning();
+ void o5_getVerbEntrypoint();
+ void o5_ifClassOfIs();
+ void o5_increment();
+ void o5_isActorInBox();
+ void o5_isEqual();
+ void o5_isGreater();
+ void o5_isGreaterEqual();
+ void o5_isLess();
+ void o5_isNotEqual();
+ void o5_ifState();
+ void o5_ifNotState();
+ void o5_isSoundRunning();
+ void o5_jumpRelative();
+ void o5_lessOrEqual();
+ void o5_lights();
+ void o5_loadRoom();
+ void o5_loadRoomWithEgo();
+ void o5_matrixOps();
+ void o5_move();
+ void o5_multiply();
+ void o5_notEqualZero();
+ void o5_or();
+ void o5_overRide();
+ void o5_panCameraTo();
+ void o5_pickupObject();
+ void o5_print();
+ void o5_printEgo();
+ void o5_pseudoRoom();
+ void o5_putActor();
+ void o5_putActorAtObject();
+ void o5_putActorInRoom();
+ void o5_quitPauseRestart();
+ void o5_resourceRoutines();
+ void o5_roomOps();
+ void o5_saveRestoreVerbs();
+ void o5_setCameraAt();
+ void o5_setClass();
+ void o5_setObjectName();
+ void o5_setOwnerOf();
+ void o5_setState();
+ void o5_setVarRange();
+ void o5_soundKludge();
+ void o5_startMusic();
+ void o5_startObject();
+ void o5_startScript();
+ void o5_startSound();
+ void o5_stopMusic();
+ void o5_stopObjectCode();
+ void o5_stopObjectScript();
+ void o5_stopScript();
+ void o5_stopSound();
+ void o5_stringOps();
+ void o5_subtract();
+ void o5_verbOps();
+ void o5_wait();
+ void o5_walkActorTo();
+ void o5_walkActorToActor();
+ void o5_walkActorToObject();
+ void o5_oldRoomEffect();
+ void o5_pickupObjectOld();
+};
+
+// FIXME - subclassing V2 from Scumm_v5 is a hack: V2 should have its own opcode table
+class Scumm_v2 : public Scumm_v5
+{
+public:
+ Scumm_v2(GameDetector *detector, OSystem *syst) : Scumm_v5(detector, syst) {}
+
+ virtual void readIndexFile();
+};
+
+// FIXME - maybe we should move the opcodes from v5 to v3, and change the inheritance
+// accordingly - that would be more logical I guess. However, if you do so, take care
+// of preserving the right readIndexFile / loadCharset !!!
+class Scumm_v3 : public Scumm_v5
+{
+public:
+ Scumm_v3(GameDetector *detector, OSystem *syst) : Scumm_v5(detector, syst) {}
+
+ void readIndexFile();
+ virtual void loadCharset(int no);
+};
+
+class Scumm_v4 : public Scumm_v3
+{
+public:
+ Scumm_v4(GameDetector *detector, OSystem *syst) : Scumm_v3(detector, syst) {}
+
+ void loadCharset(int no);
+};
+
+class Scumm_v6 : public Scumm
+{
+protected:
+ typedef void (Scumm_v6::*OpcodeProcV6)();
+ struct OpcodeEntryV6 {
+ OpcodeProcV6 proc;
+ const char *desc;
+ };
+
+ const OpcodeEntryV6 *_opcodesV6;
+
+public:
+ Scumm_v6(GameDetector *detector, OSystem *syst) : Scumm(detector, syst) {}
+
+protected:
+ virtual void setupOpcodes();
+
+ virtual void executeOpcode(int i);
+ virtual const char *getOpcodeDesc(int i);
+
+ int popRoomAndObj(int *room);
+
+ void decodeParseString2(int a, int b);
+ int getStackList(int16 *args, uint maxnum);
+
+ /* Version 6 script opcodes */
+ void o6_setBlastObjectWindow();
+ void o6_pushByte();
+ void o6_pushWord();
+ void o6_pushByteVar();
+ void o6_pushWordVar();
+ void o6_invalid();
+ void o6_byteArrayRead();
+ void o6_wordArrayRead();
+ void o6_byteArrayIndexedRead();
+ void o6_wordArrayIndexedRead();
+ void o6_dup();
+ void o6_not();
+ void o6_eq();
+ void o6_neq();
+ void o6_gt();
+ void o6_lt();
+ void o6_le();
+ void o6_ge();
+ void o6_add();
+ void o6_sub();
+ void o6_mul();
+ void o6_div();
+ void o6_land();
+ void o6_lor();
+ void o6_kill();
+ void o6_writeByteVar();
+ void o6_writeWordVar();
+ void o6_byteArrayWrite();
+ void o6_wordArrayWrite();
+ void o6_byteArrayIndexedWrite();
+ void o6_wordArrayIndexedWrite();
+ void o6_byteVarInc();
+ void o6_wordVarInc();
+ void o6_byteArrayInc();
+ void o6_wordArrayInc();
+ void o6_byteVarDec();
+ void o6_wordVarDec();
+ void o6_byteArrayDec();
+ void o6_wordArrayDec();
+ void o6_jumpTrue();
+ void o6_jumpFalse();
+ void o6_jump();
+ void o6_startScriptEx();
+ void o6_startScript();
+ void o6_startObject();
+ void o6_setObjectState();
+ void o6_setObjectXY();
+ void o6_stopObjectCode();
+ void o6_endCutscene();
+ void o6_cutScene();
+ void o6_stopMusic();
+ void o6_freezeUnfreeze();
+ void o6_cursorCommand();
+ void o6_breakHere();
+ void o6_ifClassOfIs();
+ void o6_setClass();
+ void o6_getState();
+ void o6_setState();
+ void o6_setOwner();
+ void o6_getOwner();
+ void o6_startSound();
+ void o6_stopSound();
+ void o6_startMusic();
+ void o6_stopObjectScript();
+ void o6_panCameraTo();
+ void o6_actorFollowCamera();
+ void o6_setCameraAt();
+ void o6_loadRoom();
+ void o6_stopScript();
+ void o6_walkActorToObj();
+ void o6_walkActorTo();
+ void o6_putActorInRoom();
+ void o6_putActorAtObject();
+ void o6_faceActor();
+ void o6_animateActor();
+ void o6_doSentence();
+ void o6_pickupObject();
+ void o6_loadRoomWithEgo();
+ void o6_getRandomNumber();
+ void o6_getRandomNumberRange();
+ void o6_getActorMoving();
+ void o6_isScriptRunning();
+ void o6_getActorRoom();
+ void o6_getObjectX();
+ void o6_getObjectY();
+ void o6_getObjectOldDir();
+ void o6_getObjectNewDir();
+ void o6_getActorWalkBox();
+ void o6_getActorCostume();
+ void o6_findInventory();
+ void o6_getInventoryCount();
+ void o6_getVerbFromXY();
+ void o6_beginOverride();
+ void o6_endOverride();
+ void o6_setObjectName();
+ void o6_isSoundRunning();
+ void o6_setBoxFlags();
+ void o6_createBoxMatrix();
+ void o6_resourceRoutines();
+ void o6_roomOps();
+ void o6_actorSet();
+ void o6_verbOps();
+ void o6_getActorFromXY();
+ void o6_findObject();
+ void o6_pseudoRoom();
+ void o6_getActorElevation();
+ void o6_getVerbEntrypoint();
+ void o6_arrayOps();
+ void o6_saveRestoreVerbs();
+ void o6_drawBox();
+ void o6_getActorWidth();
+ void o6_wait();
+ void o6_getActorScaleX();
+ void o6_getActorAnimCounter1();
+ void o6_soundKludge();
+ void o6_isAnyOf();
+ void o6_quitPauseRestart();
+ void o6_isActorInBox();
+ void o6_delay();
+ void o6_delayLonger();
+ void o6_delayVeryLong();
+ void o6_stopSentence();
+ void o6_print_0();
+ void o6_print_1();
+ void o6_print_2();
+ void o6_print_3();
+ void o6_printActor();
+ void o6_printEgo();
+ void o6_talkActor();
+ void o6_talkEgo();
+ void o6_dim();
+ void o6_dummy();
+ void o6_runVerbCodeQuick();
+ void o6_runScriptQuick();
+ void o6_dim2();
+ void o6_abs();
+ void o6_distObjectObject();
+ void o6_distObjectPt();
+ void o6_distPtPt();
+ void o6_miscOps();
+ void o6_delayFrames();
+ void o6_pickOneOf();
+ void o6_pickOneOfDefault();
+ void o6_jumpToScript();
+ void o6_isRoomScriptRunning();
+ void o6_kernelFunction();
+ void o6_getAnimateVariable();
+ void o6_drawBlastObject();
+ void o6_getActorPriority();
+ void o6_unknownCD();
+ void o6_bor();
+ void o6_band();
+};
+
+class Scumm_v7 : public Scumm_v6
+{
+public:
+ Scumm_v7(GameDetector *detector, OSystem *syst) : Scumm_v6(detector, syst) {}
+
+protected:
+ virtual void setupScummVars();
+};
+
+class Scumm_v8 : public Scumm
+{
+protected:
+ typedef void (Scumm_v8::*OpcodeProcV8)();
+ struct OpcodeEntryV8 {
+ OpcodeProcV8 proc;
+ const char *desc;
+ };
+
+ const OpcodeEntryV8 *_opcodesV8;
+
+public:
+ Scumm_v8(GameDetector *detector, OSystem *syst) : Scumm(detector, syst) {}
+
+protected:
+ virtual void setupOpcodes();
+
+ virtual void executeOpcode(int i);
+ virtual const char *getOpcodeDesc(int i);
+
+ /* Version 8 script opcodes */
+ void o8_unknown();
+ void o8_invalid();
+
+ void o8_pushNumber();
+ void o8_pushVariable();
+ void o8_dup();
+ void o8_pop();
+ void o8_not();
+ void o8_eq();
+ void o8_neq();
+ void o8_gt();
+ void o8_lt();
+ void o8_le();
+ void o8_ge();
+ void o8_add();
+ void o8_sub();
+ void o8_mul();
+ void o8_div();
+ void o8_land();
+ void o8_lor();
+ void o8_band();
+ void o8_bor();
+ void o8_mod();
+ void o8_jump();
+ void o8_breakHere();
+ void o8_startScript();
+ void o8_startObject();
+};
+
+
+#endif
diff --git a/scumm/module.mk b/scumm/module.mk
index e1771b49f6..5f4a3b6410 100644
--- a/scumm/module.mk
+++ b/scumm/module.mk
@@ -20,6 +20,7 @@ SCUMM_OBJS = \
scumm/script.o \
scumm/script_v5.o \
scumm/script_v6.o \
+ scumm/script_v8.o \
scumm/scummvm.o \
scumm/sound.o \
scumm/string.o \
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index 5551d00f0f..e37b9a94d7 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -31,7 +31,6 @@
uint16 newTag2Old(uint32 oldTag);
-
/* Open a room */
void Scumm::openRoom(int room)
{
@@ -39,6 +38,7 @@ void Scumm::openRoom(int room)
char buf[256];
debug(9, "openRoom(%d)", room);
+ assert(room >= 0);
/* Don't load the same room again */
if (_lastLoadedRoom == room)
@@ -125,7 +125,17 @@ void Scumm::openRoom(int room)
} while (1);
deleteRoomOffsets();
- _fileOffset = 0; /* start of file */
+ _fileOffset = 0; // start of file
+}
+
+void Scumm::closeRoom()
+{
+ if (_lastLoadedRoom != -1) {
+ _lastLoadedRoom = -1;
+ _encbyte = 0;
+ deleteRoomOffsets();
+ _fileHandle.close();
+ }
}
/* Delete the currently loaded room offsets */
@@ -202,7 +212,7 @@ void Scumm::readIndexFile()
debug(9, "readIndexFile()");
- openRoom(-1);
+ closeRoom();
openRoom(0);
if (!(_features & GF_AFTER_V6)) {
@@ -330,12 +340,17 @@ void Scumm::readIndexFile()
break;
case MKID('AARY'):
+ debug(3, "Going to call readArrayFromIndexFile (pos = 0x%08x)", _fileHandle.pos());
readArrayFromIndexFile();
+ debug(3, "After readArrayFromIndexFile (pos = 0x%08x)", _fileHandle.pos());
break;
default:
- error("Bad ID %c%c%c%c found in directory!", blocktype & 0xFF,
- blocktype >> 8, blocktype >> 16, blocktype >> 24);
+ error("Bad ID %c%c%c%c found in directory!",
+ (byte)blocktype,
+ (byte)(blocktype >> 8),
+ (byte)(blocktype >> 16),
+ (byte)(blocktype >> 24));
return;
}
}
@@ -343,22 +358,42 @@ void Scumm::readIndexFile()
// if (numblock!=9)
// error("Not enough blocks read from directory");
- openRoom(-1);
+ closeRoom();
}
void Scumm::readArrayFromIndexFile()
{
int num;
- int a, b, c;
-
- while ((num = _fileHandle.readUint16LE()) != 0) {
- a = _fileHandle.readUint16LE();
- b = _fileHandle.readUint16LE();
- c = _fileHandle.readUint16LE();
- if (c == 1)
- defineArray(num, 1, a, b);
- else
- defineArray(num, 5, a, b);
+ int a, b, c, d;
+
+ if (_features & GF_AFTER_V8) {
+ // FIXME - I am not quite sure how to interpret the AARY format of COMI.
+ // Each entry seems to be 12 bytes, while in V7 games it is only 8 bytes.
+ // 2 of the additional bytes seem to be used for num. But what about the
+ // other 2?. Either one of the three fields grew, too (but which). Or there
+ // is a new field, but then what does it mean? Endy or ludde probably know more :-)
+ while ((num = _fileHandle.readUint32LE()) != 0) {
+ a = _fileHandle.readUint16LE();
+ b = _fileHandle.readUint16LE();
+ c = _fileHandle.readUint16LE();
+ d = _fileHandle.readUint16LE();
+
+ printf("Reading array (0x%08x,%d,%d,%d,%d) - (pos = 0x%08x)\n", num, a, b, c, d, _fileHandle.pos());
+ if (c == 1)
+ defineArray(num, 1, a, b);
+ else
+ defineArray(num, 5, a, b);
+ }
+ } else {
+ while ((num = _fileHandle.readUint16LE()) != 0) {
+ a = _fileHandle.readUint16LE();
+ b = _fileHandle.readUint16LE();
+ c = _fileHandle.readUint16LE();
+ if (c == 1)
+ defineArray(num, 1, a, b);
+ else
+ defineArray(num, 5, a, b);
+ }
}
}
@@ -388,7 +423,7 @@ void Scumm::readResTypeList(int id, uint32 tag, const char *name)
}
if (_features & GF_OLD_BUNDLE) {
- if (id == rtRoom){
+ if (id == rtRoom) {
for (i = 0; i < num; i++)
res.roomno[id][i] = i;
_fileHandle.seek(num, SEEK_CUR);
@@ -1514,6 +1549,10 @@ void Scumm::readMAXS()
_fileHandle.readUint32LE();
_numArray = _fileHandle.readUint32LE();
+ // FIXME - uhm... COMI seems to have an ARRY with 143 entries, but
+ // indeed _numArray gets set to 50 ?!?
+ _numArray = 150;
+
_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
_numGlobalScripts = 2000;
diff --git a/scumm/resource_v2.cpp b/scumm/resource_v2.cpp
index c78921f923..b992b3d7ea 100644
--- a/scumm/resource_v2.cpp
+++ b/scumm/resource_v2.cpp
@@ -21,6 +21,7 @@
#include "stdafx.h"
#include "scumm.h"
+#include "intern.h"
#include "resource.h"
@@ -29,7 +30,7 @@ void Scumm_v2::readIndexFile()
int magic = 0;
debug(9, "readIndexFile()");
- openRoom(-1);
+ closeRoom();
openRoom(0);
magic = _fileHandle.readUint16LE();
@@ -81,5 +82,5 @@ void Scumm_v2::readIndexFile()
readResTypeList(rtScript, MKID('SCRP'), "script");
readResTypeList(rtSound, MKID('SOUN'), "sound");
- openRoom(-1);
+ closeRoom();
}
diff --git a/scumm/resource_v3.cpp b/scumm/resource_v3.cpp
index 45b31bf6e5..e9b0a25d31 100644
--- a/scumm/resource_v3.cpp
+++ b/scumm/resource_v3.cpp
@@ -22,6 +22,7 @@
#include "stdafx.h"
#include "scumm.h"
+#include "intern.h"
#include "resource.h"
@@ -34,7 +35,7 @@ void Scumm_v3::readIndexFile()
debug(9, "readIndexFile()");
- openRoom(-1);
+ closeRoom();
openRoom(0);
while (!_fileHandle.eof()) {
@@ -147,7 +148,7 @@ void Scumm_v3::readIndexFile()
}
}
- openRoom(-1);
+ closeRoom();
}
void Scumm_v3::loadCharset(int no)
@@ -156,12 +157,12 @@ void Scumm_v3::loadCharset(int no)
memset(_charsetData, 0, sizeof(_charsetData));
checkRange(4, 0, no, "Loading illegal charset %d");
- openRoom(-1);
+ closeRoom();
openRoom(98 + no);
size = _fileHandle.readUint16LE();
_fileHandle.read(createResource(6, no, size), size);
- openRoom(-1);
+ closeRoom();
}
diff --git a/scumm/resource_v4.cpp b/scumm/resource_v4.cpp
index fc8ea5fb9b..e8731bae18 100644
--- a/scumm/resource_v4.cpp
+++ b/scumm/resource_v4.cpp
@@ -22,6 +22,7 @@
#include "stdafx.h"
#include "scumm.h"
+#include "intern.h"
void Scumm_v4::loadCharset(int no)
{
@@ -29,12 +30,12 @@ void Scumm_v4::loadCharset(int no)
memset(_charsetData, 0, sizeof(_charsetData));
checkRange(4, 0, no, "Loading illegal charset %d");
- openRoom(-1);
+ closeRoom();
openRoom(900 + no);
size = _fileHandle.readUint32LE() + 11;
_fileHandle.read(createResource(6, no, size), size);
- openRoom(-1);
+ closeRoom();
}
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
index 78be8b140b..817a833c2c 100644
--- a/scumm/saveload.cpp
+++ b/scumm/saveload.cpp
@@ -111,7 +111,8 @@ bool Scumm::loadState(int slot, bool compat, SaveFileManager *mgr)
_sound->stopCD();
_sound->pauseSounds(true);
- CHECK_HEAP openRoom(-1);
+ CHECK_HEAP
+ closeRoom();
memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory);
/* Nuke all resources */
diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp
index 9d9bfa0776..d385bab2dc 100644
--- a/scumm/script_v5.cpp
+++ b/scumm/script_v5.cpp
@@ -23,8 +23,9 @@
#include "stdafx.h"
#include "scumm.h"
#include "actor.h"
+#include "intern.h"
+#include "sound.h"
#include "verbs.h"
-#include "scumm/sound.h"
#define OPCODE(x) { &Scumm_v5::x, #x }
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index d6708374a8..3a375f7f7d 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -24,13 +24,14 @@
#include "stdafx.h"
#include "scumm.h"
#include "actor.h"
+#include "imuse.h"
+#include "intern.h"
+#include "sound.h"
#include "verbs.h"
#include "smush/player.h"
#include "smush/scumm_renderer.h"
#include "sound/mididrv.h"
-#include "scumm/sound.h"
-#include "scumm/imuse.h"
#include "dialogs.h" // FIXME: This is just for the FT-INSANE warning.
// Remove when INSANE is implemented
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
new file mode 100644
index 0000000000..49209c7957
--- /dev/null
+++ b/scumm/script_v8.cpp
@@ -0,0 +1,1040 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "scumm.h"
+#include "intern.h"
+
+/*
+ * NO, we do NOT support CMI yet :-) This file is mostly a placeholder and a place
+ * to grow real support in. For now, only a few opcodes are implemented, and they
+ * might even be wrong... so don't hold your breath.
+ */
+
+#define OPCODE(x) { &Scumm_v8::x, #x }
+
+void Scumm_v8::setupOpcodes()
+{
+ static const OpcodeEntryV8 opcodes[256] = {
+ /* 00 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_pushNumber),
+ OPCODE(o8_pushVariable),
+ OPCODE(o8_unknown),
+ /* 04 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_dup),
+ OPCODE(o8_pop),
+ OPCODE(o8_not),
+ /* 08 */
+ OPCODE(o8_eq),
+ OPCODE(o8_neq),
+ OPCODE(o8_gt),
+ OPCODE(o8_lt),
+ /* 0C */
+ OPCODE(o8_le),
+ OPCODE(o8_ge),
+ OPCODE(o8_add),
+ OPCODE(o8_sub),
+ /* 10 */
+ OPCODE(o8_mul),
+ OPCODE(o8_div),
+ OPCODE(o8_land),
+ OPCODE(o8_lor),
+ /* 14 */
+ OPCODE(o8_band),
+ OPCODE(o8_bor),
+ OPCODE(o8_mod),
+ OPCODE(o8_unknown),
+ /* 18 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 1C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 20 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 24 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 28 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 2C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 30 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 34 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 38 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 3C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 40 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 44 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 48 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 4C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 50 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 54 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 58 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 5C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 60 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 64 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_jump),
+ OPCODE(o8_breakHere),
+ /* 68 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 6C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 70 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 74 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 78 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 7C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 80 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 84 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 88 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 8C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 90 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 94 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 98 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* 9C */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* A0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* A4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* A8 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* AC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* B0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* B4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* B8 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* BC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* C0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* C4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* C8 */
+ OPCODE(o8_startScript),
+ OPCODE(o8_startObject),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* CC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* D0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* D4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* D8 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* DC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* E0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* E4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* E8 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* EC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* F0 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* F4 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* F8 */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ /* FC */
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ OPCODE(o8_unknown),
+ };
+
+ _opcodesV8 = opcodes;
+}
+
+void Scumm_v8::executeOpcode(int i)
+{
+ OpcodeProcV8 op = _opcodesV8[i].proc;
+ (this->*op) ();
+}
+
+const char *Scumm_v8::getOpcodeDesc(int i)
+{
+ return _opcodesV8[i].desc;
+}
+
+void Scumm_v8::o8_unknown()
+{
+ warning("Unknown opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer);
+}
+
+void Scumm_v8::o8_invalid()
+{
+ error("Invalid opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer);
+}
+
+void Scumm_v8::o8_dup()
+{
+ int a = pop();
+ push(a);
+ push(a);
+}
+
+void Scumm_v8::o8_pop()
+{
+ pop();
+}
+
+void Scumm_v8::o8_not()
+{
+ push(pop() == 0);
+}
+
+void Scumm_v8::o8_eq()
+{
+ push(pop() == pop());
+}
+
+void Scumm_v8::o8_neq()
+{
+ push(pop() != pop());
+}
+
+void Scumm_v8::o8_gt()
+{
+ int a = pop();
+ push(pop() > a);
+}
+
+void Scumm_v8::o8_lt()
+{
+ int a = pop();
+ push(pop() < a);
+}
+
+void Scumm_v8::o8_le()
+{
+ int a = pop();
+ push(pop() <= a);
+}
+
+void Scumm_v8::o8_ge()
+{
+ int a = pop();
+ push(pop() >= a);
+}
+
+void Scumm_v8::o8_add()
+{
+ int a = pop();
+ push(pop() + a);
+}
+
+void Scumm_v8::o8_sub()
+{
+ int a = pop();
+ push(pop() - a);
+}
+
+void Scumm_v8::o8_mul()
+{
+ int a = pop();
+ push(pop() * a);
+}
+
+void Scumm_v8::o8_div()
+{
+ int a = pop();
+ if (a == 0)
+ error("division by zero");
+ push(pop() / a);
+}
+
+void Scumm_v8::o8_land() // Logical And
+{
+ int a = pop();
+ push(pop() && a);
+}
+
+void Scumm_v8::o8_lor() // Logical Or
+{
+ int a = pop();
+ push(pop() || a);
+}
+
+void Scumm_v8::o8_bor() // Bitwise Or
+{
+ int a = pop();
+ push(pop() | a);
+}
+
+void Scumm_v8::o8_band() // Bitwise And
+{
+ int a = pop();
+ push(pop() | a);
+}
+
+void Scumm_v8::o8_mod()
+{
+ int a = pop();
+ push(pop() % a);
+}
+
+void Scumm_v8::o8_breakHere()
+{
+ // TODO
+}
+
+void Scumm_v8::o8_pushNumber()
+{
+ // TODO
+}
+
+void Scumm_v8::o8_startObject()
+{
+ // TODO
+}
+
+void Scumm_v8::o8_startScript()
+{
+ // TODO
+}
+
+void Scumm_v8::o8_pushVariable()
+{
+ // TODO
+}
+
+void Scumm_v8::o8_jump()
+{
+ // TODO
+}
+
+/*
+
+From http://scummrev.mixnmojo.com/specs/CMIOpcodes.shtml
+
+000 O_0
+001 O_PUSH_NUMBER Push number onto stack.
+002 O_PUSH_VARIABLE Push variable value onto stack.
+003 O_PUSH_ARRAY_VALUE Push array value onto stack.
+004 O_PUSH_ARRAY2_VALUE ?
+005 O_DUP Duplicate stack value
+006 O_POP Pop value from stack.
+007 O_NOT NOT (!)
+008 O_EQ Equals (==)
+009 O_NEQ Does not equal (!=)
+00A O_GT Greater than (>)
+00B O_LT Less than (<)
+00C O_LEQ Less than or equal (<=)
+00D O_GEQ Greater than or equal (>=)
+00E O_ADD Add (+)
+00F O_SUB Subtract (-)
+010 O_MUL Multiply (*)
+011 O_DIV Divide (/)
+012 O_LAND Logical AND
+013 O_LOR Logical OR
+014 O_BAND Binary AND
+015 O_BOR Binary OR
+016 O_MOD Modulus (%)
+017 O_23
+018 O_24
+019 O_25
+01A O_26
+01B O_27
+01C O_28
+01D O_29
+01E O_30
+01F O_31
+020 O_32
+021 O_33
+022 O_34
+023 O_35
+024 O_36
+025 O_37
+026 O_38
+027 O_39
+028 O_40
+029 O_41
+02A O_42
+02B O_43
+02C O_44
+02D O_45
+02E O_46
+02F O_47
+030 O_48
+031 O_49
+032 O_50
+033 O_51
+034 O_52
+035 O_53
+036 O_54
+037 O_55
+038 O_56
+039 O_57
+03A O_58
+03B O_59
+03C O_60
+03D O_61
+03E O_62
+03F O_63
+040 O_64
+041 O_65
+042 O_66
+043 O_67
+044 O_68
+045 O_69
+046 O_70
+047 O_71
+048 O_72
+049 O_73
+04A O_74
+04B O_75
+04C O_76
+04D O_77
+04E O_78
+04F O_79
+050 O_80
+051 O_81
+052 O_82
+053 O_83
+054 O_84
+055 O_85
+056 O_86
+057 O_87
+058 O_88
+059 O_89
+05A O_90
+05B O_91
+05C O_92
+05D O_93
+05E O_94
+05F O_95
+060 O_96
+061 O_97
+062 O_98
+063 O_99
+064 O_IF if ()
+065 O_IF_NOT if not ()
+066 O_JUMP jump/goto
+067 O_BREAK_HERE Break out of script
+068 O_BREAK_HERE_VAR
+069 O_WAIT_FOR_STUFF Wait Sub opcodes
+06A O_SLEEP_JIFFIES Sleep for jiffies (10ths of a second)
+06B O_SLEEP_SECONDS Sleep for seconds
+06C O_SLEEP_MINUTES Sleep for minutes
+06D O_STORE_VARIABLE Assign value to variable
+06E O_INC_VARIABLE Increase variable value (++)
+06F O_DEC_VARIABLE Decrease variable value (--)
+070 O_ARRAY_DIM Set dimension of array
+071 O_STORE_ARRAY Assign value to array
+072 O_INC_ARRAY Increase array value
+073 O_DEC_ARRAY Decrease array value
+074 O_ARRAY_DIM2 Set dimensions of 2 dimensional array
+075 O_STORE_ARRAY2 Assign value to 2 dimensional array
+076 O_ASSIGN_ARRAY ?
+077 O_ARRAY_SHUFFLE Shuffle array
+078 O_ARRAY_LOCALIZE ?
+079 O_START_SCRIPT Start script
+07A O_START_SCRIPT_QUICK ?
+07B O_END_SCRIPT End script
+07C O_STOP_SCRIPT Stop script from running
+07D O_CHAIN_SCRIPT ?
+07E O_RETURN Return
+07F O_START_OBJECT ?
+080 O_STOP_OBJECT ?
+081 O_CUT_SCENE Start of cutscene (interface off)
+082 O_END_CUT_SCENE End of cutscene (interface on)
+083 O_FREEZE_SCRIPTS ?
+084 O_OVERRIDE ?
+085 O_OVERRIDE_OFF ?
+086 O_STOP_SENTENCE ?
+087 O_DEBUG Set debug mode
+088 O_DEBUG_WINDEX Set debug mode with output to external window
+089 O_CLASS_OF Set class of script
+08A O_STATE_OF ?
+08B O_OWNER_OF Set owner of object
+08C O_CAMERA_PAN_TO Pan camera to (X,Y)
+08D O_CAMERA_FOLLOW Make camera follow character/object
+08E O_CAMERA_AT Place camera at specific (X,Y)
+08F O_SAY_LINE Talk
+090 O_SAY_LINE_DEFAULT Talk using default actor
+091 O_SAY_LINE_SIMPLE Talk with less arguments
+092 O_SAY_LINE_SIMPLE_DEFAULT Talk with less arguments using default actor
+093 O_PRINT_LINE Print a line on screen
+094 O_PRINT_CURSOR
+095 O_PRINT_DEBUG
+096 O_PRINT_SYSTEM
+097 O_BLAST_TEXT Text to output to screen
+098 O_DRAW_OBJECT Draw object
+099 O_153
+09A O_BLAST_OBJECT
+09B O_155
+09C O_USERFACE ?
+09D O_CURRENT_ROOM Set current room
+09E O_COME_OUT_DOOR
+09F O_WALK_ACTOR_TO_OBJECT Walk to object
+0A0 O_WALK_ACTOR_TO_XY Walk to coordinate
+0A1 O_PUT_ACTOR_AT_XY Put at coordinate
+0A2 O_PUT_ACTOR_AT_OBJECT Put at object
+0A3 O_FACE_TOWARDS Change facing
+0A4 O_DO_ANIMATION Animate
+0A5 O_DO_SENTENCE
+0A6 O_PICK_UP_OBJECT Pick up object
+0A7 O_SET_BOX
+0A8 O_SET_BOX_PATH
+0A9 O_SET_BOX_SET
+0AA O_HEAP_STUFF Heap sub opcodes
+0AB O_ROOM_STUFF Room sub opcodes
+0AC O_ACTOR_STUFF Actor sub opcodes
+0AD O_CAMERA_STUFF Camera sub opcodes
+0AE O_VERB_STUFF Verb sub opcodes
+0AF O_START_SFX Start sound effect
+0B0 O_START_MUSIC Start music
+0B1 O_STOP_SOUND Stop sound (effect or music)
+0B2 O_SOUND_KLUDGE ?
+0B3 O_SYSTEM System sub opcodes
+0B4 O_VERB_SETS
+0B5 O_NEW_NAME_OF Set new name of object
+0B6 O_GET_TIME_DATE Get time and/or date
+0B7 O_DRAW_BOX
+0B8 O_ACTOBJ_STAMP
+0B9 O_START_VIDEO Start cutscene video
+0BA O_KLUDGE
+0BB O_187
+0BC O_188
+0BD O_189
+0BE O_190
+0BF O_191
+0C0 O_192
+0C1 O_193
+0C2 O_194
+0C3 O_195
+0C4 O_196
+0C5 O_197
+0C6 O_198
+0C7 O_199
+0C8 F_START_SCRIPT Start script
+0C9 F_START_OBJECT Start object script
+0CA F_PICK
+0CB F_PICK_DEFAULT
+0CC F_PICK_RANDOM
+0CD F_IN_SET
+0CE F_RANDOM Get random number
+0CF F_RANDOM_BETWEEN Get random number between two values
+0D0 F_CLASS_OF Get class of script
+0D1 F_STATE_OF
+0D2 F_OWNER_OF Get owner of object
+0D3 F_SCRIPT_RUNNING Test if script is running
+0D4 F_OBJECT_RUNNING Test if object is running
+0D5 F_SOUND_RUNNING Test if sound is running
+0D6 F_ABS Get absolute value
+0D7 F_PIXEL
+0D8 F_KLUDGE
+0D9 F_IN_BOX Test if object is in box
+0DA F_VALID_VERB
+0DB F_FIND_ACTOR
+0DC F_FIND_OBJECT
+0DD F_FIND_VERB
+0DE F_FIND_ALL_OBJECTS
+0DF F_ACTOR_INVENTORY
+0E0 F_ACTOR_INVENTORY_COUNT Get number of items in inventory
+0E1 F_ACTOR_VARIABLE Get actor variable (property)
+0E2 F_ACTOR_ROOM Get current room for actor
+0E3 F_ACTOR_BOX Get current box for actor
+0E4 F_ACTOR_MOVING Test if actor is moving
+0E5 F_ACTOR_COSTUME Get current costume for actor
+0E6 F_ACTOR_SCALE Get current scale of actor
+0E7 F_ACTOR_DEPTH Get current Z position of actor
+0E8 F_ACTOR_ELEVATION Get current actor elevation
+0E9 F_ACTOR_WIDTH Get current actor width
+0EA F_ACTOBJ_FACING Get current actor/object facing
+0EB F_ACTOBJ_X Get X position of actor/object
+0EC F_ACTOBJ_Y Get Y position of actor/object
+0ED F_ACTOR_CHORE
+0EE F_PROXIMITY_2ACTOBJS Get distance between 2 actors/objects
+0EF F_PROXIMITY_2POINTS Get distance between 2 points
+0F0 F_OBJECT_IMAGE_X Get X position of object image
+0F1 F_OBJECT_IMAGE_Y Get Y position of object image
+0F2 F_OBJECT_IMAGE_WIDTH Get width of object image
+0F3 F_OBJECT_IMAGE_HEIGHT Get height of object image
+0F4 F_VERB_X Get X position of verb
+0F5 F_VERB_Y Get Y position of verb
+0F6 F_STRING_WIDTH
+0F7 F_ACTOR_ZPLANE
+0F8 O_248
+0F9 O_249
+0FA O_250
+0FB O_251
+0FC O_252
+0FD O_253
+0FE O_254
+0FF O_255
+
+The following are subopcodes - just strip the leading 1
+
+100 SO_256
+101 SO_257
+102 SO_258
+103 SO_259
+104 SO_260
+105 SO_261
+106 SO_262
+107 SO_263
+108 SO_264
+109 SO_265
+10A SO_ARRAY_SCUMMVAR
+10B SO_ARRAY_STRING
+10C SO_ARRAY_UNDIM
+10D SO_269
+10E SO_270
+10F SO_271
+110 SO_272
+111 SO_273
+112 SO_274
+113 SO_275
+114 SO_ASSIGN_STRING
+115 SO_ASSIGN_SCUMMVAR_LIST
+116 SO_ASSIGN_2DIM_LIST
+117 SO_279
+118 SO_280
+119 SO_281
+11A SO_282
+11B SO_283
+11C SO_284
+11D SO_285
+11E SO_WAIT_FOR_ACTOR Wait for actor (to finish current action?)
+11F SO_WAIT_FOR_MESSAGE Wait for message
+120 SO_WAIT_FOR_CAMERA Wait for camera (to finish current action?)
+121 SO_WAIT_FOR_SENTENCE
+122 SO_WAIT_FOR_ANIMATION
+123 SO_WAIT_FOR_TURN
+124 SO_292
+125 SO_293
+126 SO_294
+127 SO_295
+128 SO_SYSTEM_RESTART Restart game
+129 SO_SYSTEM_QUIT Quit game
+12A SO_298
+12B SO_299
+12C SO_300
+12D SO_301
+12E SO_302
+12F SO_303
+130 SO_304
+131 SO_305
+132 SO_CAMERA_PAUSE
+133 SO_CAMERA_RESUME
+134 SO_308
+135 SO_309
+136 SO_310
+137 SO_311
+138 SO_312
+139 SO_313
+13A SO_314
+13B SO_315
+13C SO_HEAP_LOAD_CHARSET Load character set to heap
+13D SO_HEAP_LOAD_COSTUME Load costume to heap
+13E SO_HEAP_LOAD_OBJECT Load object to heap
+13F SO_HEAP_LOAD_ROOM Load room to heap
+140 SO_HEAP_LOAD_SCRIPT Load script to heap
+141 SO_HEAP_LOAD_SOUND Load sound to heap
+142 SO_HEAP_LOCK_COSTUME Lock costume in heap
+143 SO_HEAP_LOCK_ROOM Lock room in heap
+144 SO_HEAP_LOCK_SCRIPT Lock script in heap
+145 SO_HEAP_LOCK_SOUND Lock sound in heap
+146 SO_HEAP_UNLOCK_COSTUME Unlock costume
+147 SO_HEAP_UNLOCK_ROOM Unlock room
+148 SO_HEAP_UNLOCK_SCRIPT Unlock script
+149 SO_HEAP_UNLOCK_SOUND Unlock sound
+14A SO_HEAP_NUKE_COSTUME Remove costume from heap
+14B SO_HEAP_NUKE_ROOM Remove room from heap
+14C SO_HEAP_NUKE_SCRIPT Remove script from heap
+14D SO_HEAP_NUKE_SOUND Remove sound from heap
+14E SO_334
+14F SO_335
+150 SO_336
+151 SO_337
+152 SO_ROOM_PALETTE Set room palette
+153 SO_339
+154 SO_340
+155 SO_ROOM_INTENSITY Set room intensity
+156 SO_342
+157 SO_ROOM_FADE Fade room
+158 SO_ROOM_RGB_INTENSITY Set room color intensity
+159 SO_ROOM_TRANSFORM Transform room
+15A SO_ROOM_CYCLE_SPEED Set palette cycling speed
+15B SO_ROOM_COPY_PALETTE Copy palette
+15C SO_ROOM_NEW_PALETTE Create new palette
+15D SO_ROOM_SAVE_GAME Save game
+15E SO_ROOM_LOAD_GAME Load game
+15F SO_ROOM_SATURATION Set saturation of room colors
+160 SO_352
+161 SO_353
+162 SO_354
+163 SO_355
+164 SO_ACTOR_COSTUME Set actor costume
+165 SO_ACTOR_STEP_DIST Set actor width of steps
+166 SO_358
+167 SO_ACTOR_ANIMATION_DEFAULT Set actor animation to default
+168 SO_ACTOR_ANIMATION_INIT Initialize animation
+169 SO_ACTOR_ANIMATION_TALK Set actor animation to talk animation
+16A SO_ACTOR_ANIMATION_WALK Set actor animation to walk animation
+16B SO_ACTOR_ANIMATION_STAND Set actor animation to standing animation
+16C SO_ACTOR_ANIMATION_SPEED Set speed of animation
+16D SO_ACTOR_DEFAULT
+16E SO_ACTOR_ELEVATION
+16F SO_ACTOR_PALETTE Set actor palette
+170 SO_ACTOR_TALK_COLOR Set actor talk color
+171 SO_ACTOR_NAME Set name of actor
+172 SO_ACTOR_WIDTH Set width of actor
+173 SO_ACTOR_SCALE Set scaling of actor
+174 SO_ACTOR_NEVER_ZCLIP ?
+175 SO_ACTOR_ALWAYS_ZCLIP ?
+176 SO_ACTOR_IGNORE_BOXES Make actor ignore boxes
+177 SO_ACTOR_FOLLOW_BOXES Make actor follow boxes
+178 SO_ACTOR_SPECIAL_DRAW
+179 SO_ACTOR_TEXT_OFFSET Set text offset relative to actor
+17A SO_ACTOR_INIT Initialize actor
+17B SO_ACTOR_VARIABLE Set actor variable
+17C SO_ACTOR_IGNORE_TURNS_ON Make actor ignore turns
+17D SO_ACTOR_IGNORE_TURNS_OFF Make actor follow turns
+17E SO_ACTOR_NEW New actor
+17F SO_ACTOR_DEPTH Set actor Z position
+180 SO_ACTOR_STOP
+181 SO_ACTOR_FACE Make actor face angle
+182 SO_ACTOR_TURN Turn actor
+183 SO_ACTOR_WALK_SCRIPT Set walk script for actor?
+184 SO_ACTOR_TALK_SCRIPT Set talk script for actor?
+185 SO_ACTOR_WALK_PAUSE
+186 SO_ACTOR_WALK_RESUME
+187 SO_ACTOR_VOLUME Set volume of actor speech
+188 SO_ACTOR_FREQUENCY Set frequency of actor speech
+189 SO_ACTOR_PAN
+18A SO_394
+18B SO_395
+18C SO_396
+18D SO_397
+18E SO_398
+18F SO_399
+190 SO_400
+191 SO_401
+192 SO_402
+193 SO_403
+194 SO_404
+195 SO_405
+196 SO_VERB_INIT Choose verb number for editing
+197 SO_VERB_NEW New verb
+198 SO_VERB_DELETE Delete verb
+199 SO_VERB_NAME Set verb name
+19A SO_VERB_AT Set verb (X,Y) placement
+19B SO_VERB_ON Turn verb on
+19C SO_VERB_OFF Turn verb off
+19D SO_VERB_COLOR Set verb color
+19E SO_VERB_HICOLOR Set verb highlighted color
+19F SO_415
+1A0 SO_VERB_DIMCOLOR Set verb dimmed (disabled) color
+1A1 SO_VERB_DIM
+1A2 SO_VERB_KEY Set keypress to associate with verb
+1A3 SO_VERB_IMAGE Set verb image
+1A4 SO_VERB_NAME_STR Set verb name
+1A5 SO_VERB_CENTER Center verb
+1A6 SO_VERB_CHARSET Choose charset for verb
+1A7 SO_VERB_LINE_SPACING Choose linespacing for verb
+1A8 SO_424
+1A9 SO_425
+1AA SO_426
+1AB SO_427
+1AC SO_428
+1AD SO_429
+1AE SO_430
+1AF SO_431
+1B0 SO_432
+1B1 SO_433
+1B2 SO_434
+1B3 SO_435
+1B4 SO_VERBS_SAVE
+1B5 SO_VERBS_RESTORE
+1B6 SO_VERBS_DELETE
+1B7 SO_439
+1B8 SO_440
+1B9 SO_441
+1BA SO_442
+1BB SO_443
+1BC SO_444
+1BD SO_445
+1BE SO_446
+1BF SO_447
+1C0 SO_448
+1C1 SO_449
+1C2 SO_450
+1C3 SO_451
+1C4 SO_452
+1C5 SO_453
+1C6 SO_454
+1C7 SO_455
+1C8 SO_PRINT_BASEOP
+1C9 SO_PRINT_END
+1CA SO_PRINT_AT Print at coordinates (x,y)
+1CB SO_PRINT_COLOR Print color
+1CC SO_PRINT_CENTER Center output
+1CD SO_PRINT_CHARSET Set print character set
+1CE SO_PRINT_LEFT Left justify output
+1CF SO_PRINT_OVERHEAD
+1D0 SO_PRINT_MUMBLE
+1D1 SO_PRINT_STRING Set string to print
+1D2 SO_PRINT_WRAP Set print wordwrap
+1D3 SO_467
+1D4 SO_468
+1D5 SO_469
+1D6 SO_470
+1D7 SO_471
+1D8 SO_472
+1D9 SO_473
+1DA SO_474
+1DB SO_475
+1DC SO_CURSOR_ON Turn cursor on
+1DD SO_CURSOR_OFF Turn cursor off
+1DE SO_CURSOR_SOFT_ON Turn soft cursor on
+1DF SO_CURSOR_SOFT_OFF Turn soft cursor off
+1E0 SO_USERPUT_ON
+1E1 SO_USERPUT_OFF
+1E2 SO_USERPUT_SOFT_ON
+1E3 SO_USERPUT_SOFT_OFF
+1E4 SO_CURSOR_IMAGE Set cursor image
+1E5 SO_CURSOR_HOTSPOT Set cursor hotspot
+1E6 SO_CURSOR_TRANSPARENT Set cursor transparent color
+1E7 SO_CHARSET_SET
+1E8 SO_CHARSET_COLOR
+1E9 SO_CURSOR_PUT
+1EA SO_490
+1EB SO_491
+1EC SO_492
+1ED SO_493
+1EE SO_494
+1EF SO_495
+1F0 SO_496
+1F1 SO_497
+1F2 SO_498
+1F3 SO_499
+1F4 SO_500
+1F5 SO_501
+1F6 SO_502
+1F7 SO_503
+1F8 SO_504
+1F9 SO_505
+1FA SO_506
+1FB SO_507
+1FC SO_508
+1FD SO_509
+1FE SO_510
+1FF SO_511
+
+*/ \ No newline at end of file
diff --git a/scumm/scumm.h b/scumm/scumm.h
index fa2a1a1036..d9e8f93136 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -48,7 +48,6 @@ extern Scumm *g_scumm;
/* System Wide Constants */
enum {
- NUM_MIXER = 4,
NUM_SCRIPT_SLOT = 40,
NUM_LOCALSCRIPT = 60,
NUM_SHADOW_PALETTE = 8,
@@ -528,6 +527,7 @@ public:
void allocateArrays();
void openRoom(int room);
+ void closeRoom();
void deleteRoomOffsets();
void readRoomsOffsets();
void askForDisk(const char *filename);
@@ -1063,356 +1063,6 @@ public:
void updatePalette();
};
-class Scumm_v5 : public Scumm
-{
-protected:
- typedef void (Scumm_v5::*OpcodeProcV5)();
- struct OpcodeEntryV5 {
- OpcodeProcV5 proc;
- const char *desc;
- };
-
- const OpcodeEntryV5 *_opcodesV5;
-
-public:
- Scumm_v5(GameDetector *detector, OSystem *syst) : Scumm(detector, syst) {}
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(int i);
- virtual const char *getOpcodeDesc(int i);
-
- void decodeParseString();
- int getWordVararg(int16 *ptr);
- int getVarOrDirectWord(byte mask);
- int getVarOrDirectByte(byte mask);
-
- /* Version 5 script opcodes */
- void o5_actorFollowCamera();
- void o5_actorFromPos();
- void o5_actorSet();
- void o5_add();
- void o5_and();
- void o5_animateActor();
- void o5_badOpcode();
- void o5_breakHere();
- void o5_chainScript();
- void o5_cursorCommand();
- void o5_cutscene();
- void o5_debug();
- void o5_decrement();
- void o5_delay();
- void o5_delayVariable();
- void o5_divide();
- void o5_doSentence();
- void o5_drawBox();
- void o5_drawObject();
- void o5_dummy();
- void o5_endCutscene();
- void o5_equalZero();
- void o5_expression();
- void o5_faceActor();
- void o5_findInventory();
- void o5_findObject();
- void o5_freezeScripts();
- void o5_getActorCostume();
- void o5_getActorElevation();
- void o5_getActorFacing();
- void o5_getActorMoving();
- void o5_getActorRoom();
- void o5_getActorScale();
- void o5_getActorWalkBox();
- void o5_getActorWidth();
- void o5_getActorX();
- void o5_getActorY();
- void o5_getAnimCounter();
- void o5_getClosestObjActor();
- void o5_getDist();
- void o5_getInventoryCount();
- void o5_getObjectOwner();
- void o5_getObjectState();
- void o5_getRandomNr();
- void o5_isScriptRunning();
- void o5_getVerbEntrypoint();
- void o5_ifClassOfIs();
- void o5_increment();
- void o5_isActorInBox();
- void o5_isEqual();
- void o5_isGreater();
- void o5_isGreaterEqual();
- void o5_isLess();
- void o5_isNotEqual();
- void o5_ifState();
- void o5_ifNotState();
- void o5_isSoundRunning();
- void o5_jumpRelative();
- void o5_lessOrEqual();
- void o5_lights();
- void o5_loadRoom();
- void o5_loadRoomWithEgo();
- void o5_matrixOps();
- void o5_move();
- void o5_multiply();
- void o5_notEqualZero();
- void o5_or();
- void o5_overRide();
- void o5_panCameraTo();
- void o5_pickupObject();
- void o5_print();
- void o5_printEgo();
- void o5_pseudoRoom();
- void o5_putActor();
- void o5_putActorAtObject();
- void o5_putActorInRoom();
- void o5_quitPauseRestart();
- void o5_resourceRoutines();
- void o5_roomOps();
- void o5_saveRestoreVerbs();
- void o5_setCameraAt();
- void o5_setClass();
- void o5_setObjectName();
- void o5_setOwnerOf();
- void o5_setState();
- void o5_setVarRange();
- void o5_soundKludge();
- void o5_startMusic();
- void o5_startObject();
- void o5_startScript();
- void o5_startSound();
- void o5_stopMusic();
- void o5_stopObjectCode();
- void o5_stopObjectScript();
- void o5_stopScript();
- void o5_stopSound();
- void o5_stringOps();
- void o5_subtract();
- void o5_verbOps();
- void o5_wait();
- void o5_walkActorTo();
- void o5_walkActorToActor();
- void o5_walkActorToObject();
- void o5_oldRoomEffect();
- void o5_pickupObjectOld();
-};
-
-// FIXME - subclassing V2 from Scumm_v5 is a hack: V2 should have its own opcode table
-class Scumm_v2 : public Scumm_v5
-{
-public:
- Scumm_v2(GameDetector *detector, OSystem *syst) : Scumm_v5(detector, syst) {}
-
- virtual void readIndexFile();
-};
-
-// FIXME - maybe we should move the opcodes from v5 to v3, and change the inheritance
-// accordingly - that would be more logical I guess. However, if you do so, take care
-// of preserving the right readIndexFile / loadCharset !!!
-class Scumm_v3 : public Scumm_v5
-{
-public:
- Scumm_v3(GameDetector *detector, OSystem *syst) : Scumm_v5(detector, syst) {}
-
- void readIndexFile();
- virtual void loadCharset(int no);
-};
-
-class Scumm_v4 : public Scumm_v3
-{
-public:
- Scumm_v4(GameDetector *detector, OSystem *syst) : Scumm_v3(detector, syst) {}
-
- void loadCharset(int no);
-};
-
-class Scumm_v6 : public Scumm
-{
-protected:
- typedef void (Scumm_v6::*OpcodeProcV6)();
- struct OpcodeEntryV6 {
- OpcodeProcV6 proc;
- const char *desc;
- };
-
- const OpcodeEntryV6 *_opcodesV6;
-
-public:
- Scumm_v6(GameDetector *detector, OSystem *syst) : Scumm(detector, syst) {}
-
-protected:
- virtual void setupOpcodes();
-
- virtual void executeOpcode(int i);
- virtual const char *getOpcodeDesc(int i);
-
- int popRoomAndObj(int *room);
-
- void decodeParseString2(int a, int b);
- int getStackList(int16 *args, uint maxnum);
-
- /* Version 6 script opcodes */
- void o6_setBlastObjectWindow();
- void o6_pushByte();
- void o6_pushWord();
- void o6_pushByteVar();
- void o6_pushWordVar();
- void o6_invalid();
- void o6_byteArrayRead();
- void o6_wordArrayRead();
- void o6_byteArrayIndexedRead();
- void o6_wordArrayIndexedRead();
- void o6_dup();
- void o6_not();
- void o6_eq();
- void o6_neq();
- void o6_gt();
- void o6_lt();
- void o6_le();
- void o6_ge();
- void o6_add();
- void o6_sub();
- void o6_mul();
- void o6_div();
- void o6_land();
- void o6_lor();
- void o6_kill();
- void o6_writeByteVar();
- void o6_writeWordVar();
- void o6_byteArrayWrite();
- void o6_wordArrayWrite();
- void o6_byteArrayIndexedWrite();
- void o6_wordArrayIndexedWrite();
- void o6_byteVarInc();
- void o6_wordVarInc();
- void o6_byteArrayInc();
- void o6_wordArrayInc();
- void o6_byteVarDec();
- void o6_wordVarDec();
- void o6_byteArrayDec();
- void o6_wordArrayDec();
- void o6_jumpTrue();
- void o6_jumpFalse();
- void o6_jump();
- void o6_startScriptEx();
- void o6_startScript();
- void o6_startObject();
- void o6_setObjectState();
- void o6_setObjectXY();
- void o6_stopObjectCode();
- void o6_endCutscene();
- void o6_cutScene();
- void o6_stopMusic();
- void o6_freezeUnfreeze();
- void o6_cursorCommand();
- void o6_breakHere();
- void o6_ifClassOfIs();
- void o6_setClass();
- void o6_getState();
- void o6_setState();
- void o6_setOwner();
- void o6_getOwner();
- void o6_startSound();
- void o6_stopSound();
- void o6_startMusic();
- void o6_stopObjectScript();
- void o6_panCameraTo();
- void o6_actorFollowCamera();
- void o6_setCameraAt();
- void o6_loadRoom();
- void o6_stopScript();
- void o6_walkActorToObj();
- void o6_walkActorTo();
- void o6_putActorInRoom();
- void o6_putActorAtObject();
- void o6_faceActor();
- void o6_animateActor();
- void o6_doSentence();
- void o6_pickupObject();
- void o6_loadRoomWithEgo();
- void o6_getRandomNumber();
- void o6_getRandomNumberRange();
- void o6_getActorMoving();
- void o6_isScriptRunning();
- void o6_getActorRoom();
- void o6_getObjectX();
- void o6_getObjectY();
- void o6_getObjectOldDir();
- void o6_getObjectNewDir();
- void o6_getActorWalkBox();
- void o6_getActorCostume();
- void o6_findInventory();
- void o6_getInventoryCount();
- void o6_getVerbFromXY();
- void o6_beginOverride();
- void o6_endOverride();
- void o6_setObjectName();
- void o6_isSoundRunning();
- void o6_setBoxFlags();
- void o6_createBoxMatrix();
- void o6_resourceRoutines();
- void o6_roomOps();
- void o6_actorSet();
- void o6_verbOps();
- void o6_getActorFromXY();
- void o6_findObject();
- void o6_pseudoRoom();
- void o6_getActorElevation();
- void o6_getVerbEntrypoint();
- void o6_arrayOps();
- void o6_saveRestoreVerbs();
- void o6_drawBox();
- void o6_getActorWidth();
- void o6_wait();
- void o6_getActorScaleX();
- void o6_getActorAnimCounter1();
- void o6_soundKludge();
- void o6_isAnyOf();
- void o6_quitPauseRestart();
- void o6_isActorInBox();
- void o6_delay();
- void o6_delayLonger();
- void o6_delayVeryLong();
- void o6_stopSentence();
- void o6_print_0();
- void o6_print_1();
- void o6_print_2();
- void o6_print_3();
- void o6_printActor();
- void o6_printEgo();
- void o6_talkActor();
- void o6_talkEgo();
- void o6_dim();
- void o6_dummy();
- void o6_runVerbCodeQuick();
- void o6_runScriptQuick();
- void o6_dim2();
- void o6_abs();
- void o6_distObjectObject();
- void o6_distObjectPt();
- void o6_distPtPt();
- void o6_miscOps();
- void o6_delayFrames();
- void o6_pickOneOf();
- void o6_pickOneOfDefault();
- void o6_jumpToScript();
- void o6_isRoomScriptRunning();
- void o6_kernelFunction();
- void o6_getAnimateVariable();
- void o6_drawBlastObject();
- void o6_getActorPriority();
- void o6_unknownCD();
- void o6_bor();
- void o6_band();
-};
-
-class Scumm_v7 : public Scumm_v6
-{
-public:
- Scumm_v7(GameDetector *detector, OSystem *syst) : Scumm_v6(detector, syst) {}
-
-protected:
- virtual void setupScummVars();
-};
-
// This is a constant lookup table of reverse bit masks
extern const byte revBitMask[8];
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 6bfab40d85..79a9b34640 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -27,6 +27,7 @@
#include "debugger.h"
#include "dialogs.h"
#include "imuse.h"
+#include "intern.h"
#include "object.h"
#include "resource.h"
#include "sound.h"
@@ -61,6 +62,8 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst)
engine = new Scumm_v3(detector, syst);
else if (detector->_features & GF_SMALL_HEADER) // this forces loomCD as v4
engine = new Scumm_v4(detector, syst);
+ else if (detector->_features & GF_AFTER_V8)
+ engine = new Scumm_v8(detector, syst);
else if (detector->_features & GF_AFTER_V7)
engine = new Scumm_v7(detector, syst);
else if (detector->_features & GF_AFTER_V6) // this forces SamnmaxCD as v6
diff --git a/scumm/vars.cpp b/scumm/vars.cpp
index 2393ad68dd..481b896fce 100644
--- a/scumm/vars.cpp
+++ b/scumm/vars.cpp
@@ -23,6 +23,7 @@
#include "stdafx.h"
#include "scumm.h"
+#include "intern.h"
void Scumm::setupScummVars()
{