aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--actor.cpp56
-rw-r--r--costume.cpp50
-rw-r--r--gfx.cpp316
-rw-r--r--object.cpp312
-rw-r--r--resource.cpp237
-rw-r--r--saveload.cpp257
-rw-r--r--script.cpp2564
-rw-r--r--script_v1.cpp1986
-rw-r--r--script_v2.cpp2124
-rw-r--r--scumm.h403
-rw-r--r--scummsys.h20
-rw-r--r--scummvm.cpp266
-rw-r--r--scummvm.dsp10
-rw-r--r--sdl.cpp6
-rw-r--r--sound.cpp35
-rw-r--r--string.cpp274
-rw-r--r--verbs.cpp43
-rw-r--r--windows.cpp37
19 files changed, 6197 insertions, 2801 deletions
diff --git a/Makefile b/Makefile
index 7757dc9e74..a378423e05 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ INCS = scumm.h scummsys.h stdafx.h
OBJS = actor.o boxes.o costume.o gfx.o object.o resource.o \
saveload.o script.o scummvm.o sound.o string.o \
- sys.o verbs.o sdl.o
+ sys.o verbs.o sdl.o script_v1.o script_v2.o
DISTFILES=actor.cpp boxes.cpp costume.cpp gfx.cpp object.cpp resource.cpp \
saveload.cpp script.cpp scummvm.cpp sound.cpp string.cpp \
diff --git a/actor.cpp b/actor.cpp
index afcefb18fa..1f090c7c06 100644
--- a/actor.cpp
+++ b/actor.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.5 2001/10/16 10:01:44 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.4 2001/10/10 17:18:33 strigeus
* fixed swapped parameters in o_walkActorToActor
*
@@ -38,26 +41,43 @@
#include "scumm.h"
void Scumm::initActor(Actor *a, int mode) {
- if (mode) {
- a->facing = 2;
+ if (mode==1) {
a->costume = 0;
a->room = 0;
a->x = 0;
a->y = 0;
+ a->facing = 2;
+ } else if (mode==2) {
+ a->facing = 2;
}
a->elevation = 0;
a->width = 0x18;
a->talkColor = 0xF;
+#if defined(DOTT)
+ a->new_2 = 0;
+ a->new_1 = -80;
+#endif
a->scaley = a->scalex = 0xFF;
a->charset = 0;
- a->sound = 0;
+ a->sound[0] = 0;
+ a->sound[1] = 0;
+ a->sound[2] = 0;
+ a->sound[3] = 0;
+ a->sound[4] = 0;
+ a->sound[5] = 0;
+ a->sound[6] = 0;
+ a->sound[7] = 0;
+ a->newDirection = 0;
a->moving = 0;
setActorWalkSpeed(a, 8, 2);
a->ignoreBoxes = 0;
a->neverZClip = 0;
+#if defined(DOTT)
+ a->new_3 = 0;
+#endif
a->initFrame = 1;
a->walkFrame = 2;
a->standFrame = 3;
@@ -415,7 +435,7 @@ void Scumm::decodeCostData(Actor *a, int frame, uint usemask) {
}
void Scumm::putActor(Actor *a, int x, int y, byte room) {
- if (a->visible && _currentRoom!=room && vm.vars[VAR_TALK_ACTOR]==a->number) {
+ if (a->visible && _currentRoom!=room && _vars[VAR_TALK_ACTOR]==a->number) {
clearMsgQueue();
}
@@ -425,7 +445,7 @@ void Scumm::putActor(Actor *a, int x, int y, byte room) {
a->needRedraw = true;
a->needBgReset = true;
- if (vm.vars[VAR_UNK_ACTOR]==a->number) {
+ if (_vars[VAR_UNK_ACTOR]==a->number) {
dseg_3A76 = 1;
}
@@ -589,13 +609,13 @@ void Scumm::stopTalk() {
_haveMsg = 0;
_talkDelay = 0;
- act = vm.vars[VAR_TALK_ACTOR];
+ act = _vars[VAR_TALK_ACTOR];
if (act && act<0x80) {
Actor *a = derefActorSafe(act, "stopTalk");
if (_currentRoom == a->room) {
startAnimActor(a, a->talkFrame2, a->facing);
}
- vm.vars[VAR_TALK_ACTOR] = 0xFF;
+ _vars[VAR_TALK_ACTOR] = 0xFF;
}
_keepText = false;
restoreCharsetBg();
@@ -616,6 +636,7 @@ void Scumm::walkActors() {
}
}
+#if !defined(DOTT)
void Scumm::playActorSounds() {
int i;
Actor *a;
@@ -624,7 +645,7 @@ void Scumm::playActorSounds() {
a = derefActor(i);
if (a->cost.animCounter2 && a->room==_currentRoom && a->sound) {
_currentScript = 0xFF;
- addSoundToQueue(a->sound);
+ addSoundToQueue(a->sound[0]);
for (i=1; i<13; i++) {
a = derefActor(i);
a->cost.animCounter2 = 0;
@@ -633,6 +654,7 @@ void Scumm::playActorSounds() {
}
}
}
+#endif
void Scumm::walkActor(Actor *a) {
int j;
@@ -741,9 +763,9 @@ void Scumm::processActors() {
setupActorScale(a);
setupCostumeRenderer(&cost, a);
setActorCostPalette(a);
- checkHeap();
+ CHECK_HEAP
drawActorCostume(a);
- checkHeap();
+ CHECK_HEAP
actorAnimate(a);
}
} while (ac++,--cnt);
@@ -851,7 +873,7 @@ void Scumm::actorTalk() {
if (_actorToPrintStrFor==0xFF) {
if (!_keepText)
stopTalk();
- vm.vars[VAR_TALK_ACTOR] = 0xFF;
+ _vars[VAR_TALK_ACTOR] = 0xFF;
oldact = 0;
} else {
a = derefActorSafe(_actorToPrintStrFor, "actorTalk");
@@ -860,24 +882,24 @@ void Scumm::actorTalk() {
} else {
if (!_keepText)
stopTalk();
- vm.vars[VAR_TALK_ACTOR] = a->number;
+ _vars[VAR_TALK_ACTOR] = a->number;
startAnimActor(a,a->talkFrame1,a->facing);
- oldact = vm.vars[VAR_TALK_ACTOR];
+ oldact = _vars[VAR_TALK_ACTOR];
}
}
if (oldact>=0x80)
return;
- if (vm.vars[VAR_TALK_ACTOR]>0x7F) {
- _charsetColor = (byte)_stringColor[0];
+ if (_vars[VAR_TALK_ACTOR]>0x7F) {
+ _charsetColor = (byte)string[0].color;
} else {
- a = derefActorSafe(vm.vars[VAR_TALK_ACTOR], "actorTalk(2)");
+ a = derefActorSafe(_vars[VAR_TALK_ACTOR], "actorTalk(2)");
_charsetColor = a->talkColor;
}
charset._bufPos = 0;
_talkDelay = 0;
_haveMsg = 0xFF;
- vm.vars[VAR_HAVE_MSG] = 0xFF;
+ _vars[VAR_HAVE_MSG] = 0xFF;
CHARSET_1();
}
diff --git a/costume.cpp b/costume.cpp
index 0cc6a68068..5ed79da40b 100644
--- a/costume.cpp
+++ b/costume.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:45 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/09 18:35:02 strigeus
* fixed object parent bug
* fixed some signed/unsigned comparisons
@@ -85,8 +88,9 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
byte scaling;
byte charsetmask, masking;
byte unk19;
+ int ex1,ex2;
- checkHeap();
+ CHECK_HEAP
_maskval = 0xF;
_shrval = 4;
@@ -105,6 +109,19 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_ymove -= (int16)READ_LE_UINT16(_srcptr+10);
_srcptr += 12;
+#if defined(DOTT)
+ switch(_ptr[7]&0x7F) {
+ case 0x60: case 0x61:
+ ex1 = _srcptr[0];
+ ex2 = _srcptr[1];
+ _srcptr += 2;
+ if (ex1!=0xFF || ex2!=0xFF) {
+ ex1=READ_LE_UINT16(_ptr + _numColors + 10 + ex1*2);
+ _srcptr = _ptr + READ_LE_UINT16(_ptr + ex1 + ex2*2) + 14;
+ }
+ }
+#endif
+
_xpos = _actorX;
_ypos = _actorY;
@@ -200,10 +217,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_vscreenheight = _vm->virtscr[0].height;
_vm->updateDirtyRect(0, _left, _right+1,_top,_bottom,1<<a->number);
- if (_top >= (int)_vscreenheight || _bottom <= 0) {
- checkHeap();
+ if (_top >= (int)_vscreenheight || _bottom <= 0)
return 0;
- }
_ypitch = _height * 320;
_docontinue = 0;
@@ -246,7 +261,10 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
}
}
- if ((uint)_top > (uint)_vscreenheight || _top < 0)
+ if (_width2==0)
+ return 0;
+
+ if ((uint)_top > (uint)_vscreenheight)
_top = 0;
if ((uint)_bottom > _vscreenheight)
@@ -259,7 +277,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
a->bottom = _bottom;
if (_height2 + _top >= 256) {
- checkHeap();
+ CHECK_HEAP
return 2;
}
@@ -283,7 +301,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_mask_ptr_dest = _mask_ptr + _xpos / 8;
}
- checkHeap();
+ CHECK_HEAP
switch ((scaling<<2)|(masking<<1)|charsetmask) {
case 0:
@@ -306,7 +324,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
break;
}
- checkHeap();
+ CHECK_HEAP
return b;
}
@@ -611,7 +629,12 @@ StartPos:;
}
void CostumeRenderer::loadCostume(int id) {
- _ptr = _vm->getResourceAddress(3, id) + 2;
+ _ptr = _vm->getResourceAddress(3, id)
+#if defined(DOTT)
+ + 8;
+#else
+ + 2;
+#endif
switch(_ptr[7]&0x7F) {
case 0x58:
_numColors = 16;
@@ -619,6 +642,14 @@ void CostumeRenderer::loadCostume(int id) {
case 0x59:
_numColors = 32;
break;
+#if defined(DOTT)
+ case 0x60:
+ _numColors = 16;
+ break;
+ case 0x61:
+ _numColors = 32;
+ break;
+#endif
default:
error("Costume %d is invalid", id);
}
@@ -649,6 +680,7 @@ byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {
byte CostumeRenderer::drawCostume(Actor *a) {
int i;
byte r = 0;
+
_xmove = _ymove = 0;
for (i=0; i<16; i++)
r|=drawOneSlot(a, i);
diff --git a/gfx.cpp b/gfx.cpp
index e3cc858481..abb636024b 100644
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.4 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.3 2001/10/10 12:52:21 strigeus
* fixed bug in GDI_UnkDecode7()
*
@@ -42,7 +45,7 @@ void Scumm::getGraphicsPerformance() {
initScreens(0, 0, 320, 200);
}
- vm.vars[VAR_PERFORMANCE_1] = _scummTimer;
+ _vars[VAR_PERFORMANCE_1] = _scummTimer;
_scummTimer = 0;
for (i=10; i!=0; i--) {
@@ -50,7 +53,7 @@ void Scumm::getGraphicsPerformance() {
unkVirtScreen2();
}
- vm.vars[VAR_PERFORMANCE_2] = _scummTimer;
+ _vars[VAR_PERFORMANCE_2] = _scummTimer;
initScreens(0, 16, 320, 144);
}
@@ -314,15 +317,15 @@ void Scumm::setCameraAt(int dest) {
}
cd->_destPos = dest;
- t = vm.vars[VAR_CAMERA_MIN];
+ t = _vars[VAR_CAMERA_MIN];
if (cd->_curPos < t) cd->_curPos = t;
- t = vm.vars[VAR_CAMERA_MAX];
+ t = _vars[VAR_CAMERA_MAX];
if (cd->_curPos > t) cd->_curPos = t;
- if (vm.vars[VAR_SCROLL_SCRIPT]) {
- vm.vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
- runScript(vm.vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
+ if (_vars[VAR_SCROLL_SCRIPT]) {
+ _vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
+ runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
if (cd->_curPos != cd->_lastPos && charset._hasMask)
@@ -378,8 +381,7 @@ void Scumm::initBGBuffers() {
_imgBufOffs[i] = i*itemsize;
}
-void Scumm::setPaletteFromRes() {
- byte *ptr = getResourceAddress(1, _roomResource) + _CLUT_offs;
+void Scumm::setPaletteFromPtr(byte *ptr) {
uint32 size = READ_BE_UINT32_UNALIGNED(ptr+4);
int i, r, g, b;
byte *dest, *epal;
@@ -419,6 +421,12 @@ void Scumm::setPaletteFromRes() {
setDirtyColors(0, numcolor-1);
}
+void Scumm::setPaletteFromRes() {
+ byte *ptr;
+ ptr = getResourceAddress(1, _roomResource) + _CLUT_offs;
+ setPaletteFromPtr(ptr);
+}
+
void Scumm::setDirtyColors(int min, int max) {
if (_palDirtyMin > min)
@@ -465,9 +473,9 @@ void Scumm::cyclePalette() {
if(_videoMode != 0x13)
return;
- valueToAdd = vm.vars[VAR_TIMER];
- if (valueToAdd < vm.vars[VAR_TIMER_NEXT])
- valueToAdd = vm.vars[VAR_TIMER_NEXT];
+ valueToAdd = _vars[VAR_TIMER];
+ if (valueToAdd < _vars[VAR_TIMER_NEXT])
+ valueToAdd = _vars[VAR_TIMER_NEXT];
for (i=1; i<=16; i++) {
if (_colorCycleDelays[i] &&
@@ -571,6 +579,8 @@ void Scumm::unkVirtScreen4(int a) {
case 135:
unkScreenEffect5(1);
break;
+ default:
+ error("unkVirtScreen4: default case %d", a);
}
}
@@ -615,7 +625,6 @@ const uint32 zplane_tags[] = {
MKID('ZP03')
};
-
void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr) {
byte *smap_ptr;
int i;
@@ -626,14 +635,10 @@ void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr)
int x;
byte *where_draw_ptr;
- checkHeap();
+ CHECK_HEAP
smap_ptr = findResource(MKID('SMAP'), ptr);
- if (objnr==209) {
- warning("tst");
- }
-
for(i=1; i<_numZBuffer; i++) {
zplane_list[i] = findResource(zplane_tags[i], ptr);
}
@@ -662,7 +667,7 @@ void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr)
if (vs->fourlinesextra)
x -= _screenStartStrip;
- checkHeap();
+ CHECK_HEAP
if (x >= 40)
return;
@@ -683,11 +688,11 @@ void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr)
where_draw_ptr = gdi.where_to_draw_ptr;
decompressBitmap();
- checkHeap();
+ CHECK_HEAP
if (twobufs) {
gdi.where_to_draw_ptr = where_draw_ptr;
- if (vm.vars[VAR_DRAWFLAGS]&2) {
+ if (_vars[VAR_DRAWFLAGS]&2) {
if (hasCharsetMask(x<<3, _drawBmpY, (x+1)<<3, t))
draw8ColWithMasking();
else {
@@ -700,7 +705,7 @@ void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr)
clear8Col();
}
}
- checkHeap();
+ CHECK_HEAP
for (i=1; i<_numZBuffer; i++) {
if (!zplane_list[i])
@@ -712,7 +717,7 @@ void Scumm::drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr)
else
decompressMaskImg();
}
- checkHeap();
+ CHECK_HEAP
_drawBmpX++;
a++;
} while (--b);
@@ -728,6 +733,8 @@ void Scumm::decompressBitmap() {
byte code = *gdi.smap_ptr++;
+ assert(gdi.numLinesToProcess);
+
switch(code) {
case 1:
GDI_UnkDecode7();
@@ -747,7 +754,7 @@ void Scumm::decompressBitmap() {
case 34: case 35: case 36: case 37: case 38:
dseg_4E3B = 1;
gdi.decomp_shr = code - 30;
- gdi.decomp_mask = decompress_table[code - 30];
+ gdi.decomp_mask = decompress_table[code - 30 ];
GDI_UnkDecode4();
break;
@@ -770,12 +777,30 @@ void Scumm::decompressBitmap() {
gdi.decomp_mask = decompress_table[code - 80];
GDI_UnkDecode3();
break;
+
+#if defined(DOTT)
+ case 104: case 105: case 106: case 107: case 108:
+ gdi.decomp_shr = code - 100;
+ gdi.decomp_mask = decompress_table[code - 100];
+ GDI_UnkDecode1();
+ break;
+
+ case 124: case 125: case 126: case 127: case 128:
+ dseg_4E3B = 1;
+ gdi.decomp_shr = code - 120;
+ gdi.decomp_mask = decompress_table[code - 120];
+ GDI_UnkDecode3();
+ break;
+#endif
+
+ default:
+ error("decompressBitmap: default case %d", code);
}
}
int Scumm::hasCharsetMask(int x, int y, int x2, int y2) {
- if (!charset._hasMask || y > charset._mask_bottom || x > charset._mask_right ||
- y2 < charset._mask_top || x2 < charset._mask_left )
+ if (!charset._hasMask || y > string[0].mask_bottom || x > string[0].mask_right ||
+ y2 < string[0].mask_top || x2 < string[0].mask_left )
return 0;
return 1;
}
@@ -928,6 +953,7 @@ void Scumm::redrawBGStrip(int start, int num) {
#define READ_BIT (cl--,bit = bits&1, bits>>=1,bit)
#define FILL_BITS if (cl <= 8) { bits |= (*src++ << cl); cl += 8;}
+#if defined(DOTT)
void Scumm::GDI_UnkDecode1() {
byte *src = gdi.smap_ptr;
byte *dst = gdi.where_to_draw_ptr;
@@ -935,6 +961,7 @@ void Scumm::GDI_UnkDecode1() {
uint bits = *src++;
byte cl = 8;
byte bit;
+ byte incm,reps;
gdi.tempNumLines = gdi.numLinesToProcess;
do {
@@ -943,11 +970,31 @@ void Scumm::GDI_UnkDecode1() {
FILL_BITS
*dst++=color;
+againPos:;
+
if (!READ_BIT) {}
else if (READ_BIT) {
- color += (bits&7)-4;
+ incm = (bits&7)-4;
cl-=3;
bits>>=3;
+ if (!incm) {
+ FILL_BITS
+ reps = bits&0xFF;
+ do {
+ if (!--gdi.currentX) {
+ gdi.currentX = 8;
+ dst += 312;
+ if (!--gdi.tempNumLines)
+ return;
+ }
+ *dst++=color;
+ } while (--reps);
+ bits>>=8;
+ bits |= (*src++)<<(cl-8);
+ goto againPos;
+ } else {
+ color += incm;
+ }
} else {
FILL_BITS
color = bits&gdi.decomp_mask;
@@ -957,8 +1004,39 @@ void Scumm::GDI_UnkDecode1() {
} while (--gdi.currentX);
dst += 312;
} while (--gdi.tempNumLines);
+}
+#else
+void Scumm::GDI_UnkDecode1() {
+ byte *src = gdi.smap_ptr;
+ byte *dst = gdi.where_to_draw_ptr;
+ byte color = *src++;
+ uint bits = *src++;
+ byte cl = 8;
+ byte bit;
+ gdi.tempNumLines = gdi.numLinesToProcess;
+ do {
+ gdi.currentX = 8;
+ do {
+ FILL_BITS
+ *dst++=color;
+
+ if (!READ_BIT) {}
+ else if (READ_BIT) {
+ color += (bits&7)-4;
+ cl-=3;
+ bits>>=3;
+ } else {
+ FILL_BITS
+ color = bits&gdi.decomp_mask;
+ cl -= gdi.decomp_shr;
+ bits >>= gdi.decomp_shr;
+ }
+ } while (--gdi.currentX);
+ dst += 312;
+ } while (--gdi.tempNumLines);
}
+#endif
void Scumm::GDI_UnkDecode2() {
byte *src = gdi.smap_ptr;
@@ -996,6 +1074,74 @@ void Scumm::GDI_UnkDecode2() {
} while (--gdi.tempNumLines);
}
+#if defined(DOTT)
+void Scumm::GDI_UnkDecode3() {
+ byte *src = gdi.smap_ptr;
+ byte *dst = gdi.where_to_draw_ptr;
+ byte color = *src++;
+ uint bits = *src++;
+ byte cl = 8;
+ byte bit;
+ byte incm,reps;
+
+ gdi.tempNumLines = gdi.numLinesToProcess;
+
+ do {
+ gdi.currentX = 8;
+ do {
+ FILL_BITS
+ if (color!=gdi.transparency) *dst=color;
+ dst++;
+
+againPos:;
+ if (!READ_BIT) {}
+ else if (READ_BIT) {
+ incm = (bits&7)-4;
+
+ cl-=3;
+ bits>>=3;
+ if (incm) {
+ color += incm;
+ } else {
+ FILL_BITS
+ reps = bits&0xFF;
+ if (color==gdi.transparency) {
+ do {
+ if (!--gdi.currentX) {
+ gdi.currentX = 8;
+ dst += 312;
+ if (!--gdi.tempNumLines)
+ return;
+ }
+ dst++;
+ } while (--reps);
+ } else {
+ do {
+ if (!--gdi.currentX) {
+ gdi.currentX = 8;
+ dst += 312;
+ if (!--gdi.tempNumLines)
+ return;
+ }
+ *dst++=color;
+ } while (--reps);
+ }
+ bits>>=8;
+ bits |= (*src++)<<(cl-8);
+ goto againPos;
+ }
+ } else {
+ FILL_BITS
+ color = bits&gdi.decomp_mask;
+ cl -= gdi.decomp_shr;
+ bits >>= gdi.decomp_shr;
+ }
+ } while (--gdi.currentX);
+ dst += 312;
+ } while (--gdi.tempNumLines);
+}
+
+#else
void Scumm::GDI_UnkDecode3() {
byte *src = gdi.smap_ptr;
byte *dst = gdi.where_to_draw_ptr;
@@ -1028,6 +1174,8 @@ void Scumm::GDI_UnkDecode3() {
dst += 312;
} while (--gdi.tempNumLines);
}
+#endif
+
void Scumm::GDI_UnkDecode4() {
byte *src = gdi.smap_ptr;
@@ -1154,13 +1302,18 @@ void Scumm::GDI_UnkDecode7() {
void Scumm::restoreCharsetBg() {
dseg_4E3C = 0;
- if (charset._mask_left != -1) {
- restoreBG(charset._mask_left, charset._mask_top, charset._mask_right, charset._mask_bottom);
+ if (string[0].mask_left != -1) {
+ restoreBG(string[0].mask_left, string[0].mask_top, string[0].mask_right, string[0].mask_bottom);
charset._hasMask = false;
- charset._mask_left = -1;
+ string[0].mask_left = -1;
+#if defined(DOTT)
+ charset._strLeft = -1;
+ charset._left = -1;
+#endif
}
- _stringXpos2[0] = _stringXPos[0];
- _stringYpos2[0] = _stringYPos[0];
+
+ string[0].xpos2 = string[0].xpos;
+ string[0].ypos2 = string[0].ypos;
}
void Scumm::restoreBG(int left, int top, int right, int bottom) {
@@ -1209,7 +1362,7 @@ void Scumm::restoreBG(int left, int top, int right, int bottom) {
width = right - left;
widthmod = (width >> 2) + 2;
- if (vs->alloctwobuffers && _currentRoom!=0 && vm.vars[VAR_DRAWFLAGS]&2) {
+ if (vs->alloctwobuffers && _currentRoom!=0 && _vars[VAR_DRAWFLAGS]&2) {
blit(gdi.bg_ptr, gdi.where_to_draw_ptr, width, height);
if (gdi.virtScreen==0 && charset._hasMask && height) {
do {
@@ -1245,8 +1398,8 @@ void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom,
rp = (right >> 3) + _screenStartStrip;
lp = (left >> 3) + _screenStartStrip;
if (lp<0) lp=0;
- if (rp >= 160)
- rp = 159;
+ if (rp >= 200)
+ rp = 200;
if (lp <= rp) {
num = rp - lp + 1;
sp = &actorDrawBits[lp];
@@ -1328,18 +1481,18 @@ void Scumm::moveCamera() {
cd->_curPos &= 0xFFF8;
- if (cd->_curPos < vm.vars[VAR_CAMERA_MIN]) {
- if (vm.vars[VAR_CAMERA_FAST])
- cd->_curPos = vm.vars[VAR_CAMERA_MIN];
+ if (cd->_curPos < _vars[VAR_CAMERA_MIN]) {
+ if (_vars[VAR_CAMERA_FAST])
+ cd->_curPos = _vars[VAR_CAMERA_MIN];
else
cd->_curPos += 8;
cameraMoved();
return;
}
- if (cd->_curPos > vm.vars[VAR_CAMERA_MAX]) {
- if (vm.vars[VAR_CAMERA_FAST])
- cd->_curPos = vm.vars[VAR_CAMERA_MAX];
+ if (cd->_curPos > _vars[VAR_CAMERA_MAX]) {
+ if (_vars[VAR_CAMERA_FAST])
+ cd->_curPos = _vars[VAR_CAMERA_MAX];
else
cd->_curPos-=8;
cameraMoved();
@@ -1353,7 +1506,7 @@ void Scumm::moveCamera() {
t = (actorx>>3) - _screenStartStrip;
if (t < cd->_leftTrigger || t > cd->_rightTrigger) {
- if (vm.vars[VAR_CAMERA_FAST]) {
+ if (_vars[VAR_CAMERA_FAST]) {
if (t > 35)
cd->_destPos = actorx + 80;
if (t < 5)
@@ -1368,13 +1521,13 @@ void Scumm::moveCamera() {
cd->_destPos = a->x;
}
- if (cd->_destPos < vm.vars[VAR_CAMERA_MIN])
- cd->_destPos = vm.vars[VAR_CAMERA_MIN];
+ if (cd->_destPos < _vars[VAR_CAMERA_MIN])
+ cd->_destPos = _vars[VAR_CAMERA_MIN];
- if (cd->_destPos > vm.vars[VAR_CAMERA_MAX])
- cd->_destPos = vm.vars[VAR_CAMERA_MAX];
+ if (cd->_destPos > _vars[VAR_CAMERA_MAX])
+ cd->_destPos = _vars[VAR_CAMERA_MAX];
- if (vm.vars[VAR_CAMERA_FAST]) {
+ if (_vars[VAR_CAMERA_FAST]) {
cd->_curPos = cd->_destPos;
} else {
if (cd->_curPos < cd->_destPos)
@@ -1390,9 +1543,9 @@ void Scumm::moveCamera() {
cameraMoved();
- if (pos != cd->_curPos && vm.vars[VAR_SCROLL_SCRIPT]) {
- vm.vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
- runScript(vm.vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
+ if (pos != cd->_curPos && _vars[VAR_SCROLL_SCRIPT]) {
+ _vars[VAR_CAMERA_CUR_POS] = cd->_curPos;
+ runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
}
@@ -1410,6 +1563,31 @@ void Scumm::cameraMoved() {
virtscr[0].xstart = _screenStartStrip << 3;
}
+void Scumm::panCameraTo(int x) {
+ CameraData *cd = &camera;
+ cd->_destPos = x;
+ cd->_mode = 3;
+ cd->_movingToActor = 0;
+}
+
+void Scumm::actorFollowCamera(int act) {
+ int old = camera._follows;
+
+ setCameraFollows(derefActorSafe(act, "actorFollowCamera"));
+ if (camera._follows != old)
+ runHook(0);
+
+ camera._movingToActor = 0;
+}
+
+void Scumm::setCameraAtEx(int at) {
+ CameraData *cd = &camera;
+ cd->_mode = 1;
+ cd->_curPos = at;
+ setCameraAt(at);
+ cd->_movingToActor = 0;
+}
+
void Scumm::palManipulate() {
byte *srcptr, *destptr;
byte *pal;
@@ -1484,7 +1662,7 @@ void Scumm::resetActorBgs() {
+ (top * 40 + _screenStartStrip + i);
gdi.numLinesToProcess = bottom - top;
if (gdi.numLinesToProcess) {
- if (vm.vars[VAR_DRAWFLAGS]&2) {
+ if (_vars[VAR_DRAWFLAGS]&2) {
if(hasCharsetMask(i<<3, top, (i+1)<<3, bottom))
draw8ColWithMasking();
else
@@ -1510,6 +1688,7 @@ void Scumm::setPalColor(int index, int r, int g, int b) {
_currentPalette[index*3+0] = r>>2;
_currentPalette[index*3+1] = g>>2;
_currentPalette[index*3+2] = b>>2;
+ setDirtyColors(index,index);
}
if (_videoMode==0xE) {
/* TODO: implement this */
@@ -1567,6 +1746,41 @@ byte Scumm::isMaskActiveAt(int l, int t, int r, int b, byte *mem) {
return false;
}
+byte *Scumm::findPalInPals(byte *pal, int index) {
+ byte *offs;
+ uint32 size;
+
+ pal = findResource(MKID('WRAP'), pal);
+ if (pal==NULL)
+ return NULL;
+
+ offs = findResource(MKID('OFFS'),pal);
+ if (offs==NULL)
+ return NULL;
+
+ size = (READ_BE_UINT32_UNALIGNED(offs+4)-8) >> 2;
+
+ if ((uint32)index >= (uint32)size)
+ return NULL;
+
+ return offs + READ_LE_UINT32(offs + 8 + index * sizeof(uint32));
+}
+
+void Scumm::setPalette(int palindex) {
+ byte *pals;
+
+ _curPalIndex = palindex;
+
+ pals = getResourceAddress(1, _roomResource) + _PALS_offs;
+
+ pals = findPalInPals(pals, palindex);
+
+ if (pals==NULL)
+ error("invalid palette %d", palindex);
+
+ setPaletteFromPtr(pals);
+}
+
#if 0
void Scumm::GDI_drawMouse() {
byte *dst,*src,*dstorg;
diff --git a/object.cpp b/object.cpp
index e47b2239e2..79bea00fbb 100644
--- a/object.cpp
+++ b/object.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/09 18:35:02 strigeus
* fixed object parent bug
* fixed some signed/unsigned comparisons
@@ -32,7 +35,7 @@
#include "scumm.h"
bool Scumm::getClass(int obj, int cls) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getClass");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
cls &= 0x7F;
checkRange(32,1,cls,"Class %d out of range in getClass");
@@ -41,7 +44,7 @@ bool Scumm::getClass(int obj, int cls) {
}
void Scumm::putClass(int obj, int cls, bool set) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getClass");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getClass");
cls &= 0x7F;
checkRange(32,1,cls,"Class %d out of range in getClass");
@@ -53,23 +56,23 @@ void Scumm::putClass(int obj, int cls, bool set) {
}
int Scumm::getOwner(int obj) {
- checkRange(_maxNrObjects-1, 0, obj, "Object %d out of range in getOwner");
+ checkRange(_numGlobalObjects-1, 0, obj, "Object %d out of range in getOwner");
return _objectFlagTable[obj]&0xF;
}
void Scumm::putOwner(int act, int owner) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in putOwner");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putOwner");
checkRange(15, 0, owner, "Owner %d out of range in putOwner");
_objectFlagTable[act] = (_objectFlagTable[act]&0xF0) | owner;
}
int Scumm::getState(int act) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in getState");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in getState");
return _objectFlagTable[act]>>4;
}
void Scumm::putState(int act, int state) {
- checkRange(_maxNrObjects-1, 0, act, "Object %d out of range in putState");
+ checkRange(_numGlobalObjects-1, 0, act, "Object %d out of range in putState");
checkRange(15, 0, state, "State %d out of range in putState");
_objectFlagTable[act] = (_objectFlagTable[act]&0x0F) | (state<<4);
}
@@ -84,7 +87,7 @@ int Scumm::getObjectIndex(int object) {
return -1;
} else {
for (i=_numObjectsInRoom; i>0; i--) {
- if (objs[i].obj_nr==object)
+ if (_objs[i].obj_nr==object)
return i;
}
return -1;
@@ -102,8 +105,8 @@ int Scumm::whereIsObject(int object) {
}
for (i=_numObjectsInRoom; i>0; i--)
- if (objs[i].obj_nr == object) {
- if (objs[i].fl_object_index)
+ if (_objs[i].obj_nr == object) {
+ if (_objs[i].fl_object_index)
return 4;
return 1;
}
@@ -111,7 +114,7 @@ int Scumm::whereIsObject(int object) {
}
int Scumm::getObjectOrActorXY(int object) {
- if (object <= vm.vars[VAR_NUM_ACTOR]) {
+ if (object <= _vars[VAR_NUM_ACTOR]) {
return getActorXYPos(derefActorSafe(object, "getObjectOrActorXY"));
}
switch(whereIsObject(object)) {
@@ -124,24 +127,56 @@ int Scumm::getObjectOrActorXY(int object) {
return 0;
}
+#if defined(DOTT)
+void Scumm::getObjectXYPos(int object) {
+ ObjectData *od = &_objs[getObjectIndex(object)];
+ int state;
+ byte *ptr;
+ ImageHeader *imhd;
+ int x,y;
+ AdjustBoxResult abr;
+
+ state = getState(object)-1;
+ if (state<0)
+ state = 0;
+
+ if (od->fl_object_index) {
+ ptr = getResourceAddress(0xD, od->fl_object_index);
+ ptr = findResource(MKID('OBIM'), ptr);
+ } else {
+ ptr = getResourceAddress(1, _roomResource);
+ ptr += od->offs_obim_to_room;
+ }
+
+ imhd = (ImageHeader*)findResource2(MKID('IMHD'), ptr);
+ x = od->x_pos*8 + imhd->hotspot[state].x;
+ y = od->y_pos*8 + imhd->hotspot[state].y;
+
+ abr = adjustXYToBeInBox(0, x, y);
+ _xPos = abr.x;
+ _yPos = abr.y;
+ _dir = od->actordir&3;
+}
+#else
void Scumm::getObjectXYPos(int object) {
- ObjectData *od = &objs[getObjectIndex(object)];
+ ObjectData *od = &_objs[getObjectIndex(object)];
AdjustBoxResult abr;
abr = adjustXYToBeInBox(0, od->cdhd_10, od->cdhd_12);
_xPos = abr.x;
_yPos = abr.y;
_dir = od->actordir&3;
}
+#endif
int Scumm::getObjActToObjActDist(int a, int b) {
int x,y;
Actor *acta = NULL;
Actor *actb = NULL;
- if (a<=vm.vars[VAR_NUM_ACTOR])
+ if (a<=_vars[VAR_NUM_ACTOR])
acta = derefActorSafe(a, "getObjActToObjActDist");
- if (b<=vm.vars[VAR_NUM_ACTOR])
+ if (b<=_vars[VAR_NUM_ACTOR])
actb = derefActorSafe(b, "getObjActToObjActDist(2)");
if (acta && actb && acta->room==actb->room && acta->room &&
@@ -175,21 +210,21 @@ int Scumm::findObject(int x, int y) {
int i,a,b;
for (i=1; i<=_numObjectsInRoom; i++) {
- if (!objs[i].obj_nr || getClass(objs[i].obj_nr, 32))
+ if (!_objs[i].obj_nr || getClass(_objs[i].obj_nr, 32))
continue;
b = i;
do {
- a = objs[b].parentstate;
- b = objs[b].parent;
+ a = _objs[b].parentstate;
+ b = _objs[b].parent;
if (b==0) {
- if (objs[i].x_pos <= (x>>3) &&
- objs[i].numstrips + objs[i].x_pos > (x>>3) &&
- objs[i].y_pos <= (y>>3) &&
- objs[i].height + objs[i].y_pos > (y>>3))
- return objs[i].obj_nr;
+ if (_objs[i].x_pos <= (x>>3) &&
+ _objs[i].numstrips + _objs[i].x_pos > (x>>3) &&
+ _objs[i].y_pos <= (y>>3) &&
+ _objs[i].height + _objs[i].y_pos > (y>>3))
+ return _objs[i].obj_nr;
break;
}
- } while ( (objs[b].ownerstate&0xF0) == a);
+ } while ( (_objs[b].ownerstate&0xF0) == a);
}
return 0;
}
@@ -203,7 +238,7 @@ void Scumm::drawRoomObjects(int arg) {
return;
do {
- od = &objs[num];
+ od = &_objs[num];
if (!od->obj_nr || !(od->ownerstate&0xF0))
continue;
@@ -213,7 +248,7 @@ void Scumm::drawRoomObjects(int arg) {
drawObject(num, arg);
break;
}
- od = &objs[od->parent];
+ od = &_objs[od->parent];
} while ((od->ownerstate & 0xF0)==a);
} while (--num);
@@ -249,7 +284,7 @@ void Scumm::drawObject(int obj, int arg) {
gdi.virtScreen = 0;
- od = &objs[obj];
+ od = &_objs[obj];
xpos = od->x_pos;
ypos = od->y_pos;
@@ -308,7 +343,7 @@ void Scumm::loadRoomObjects() {
CodeHeader *cdhd;
- checkHeap();
+ CHECK_HEAP
room = getResourceAddress(1, _roomResource);
roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room);
@@ -318,12 +353,12 @@ void Scumm::loadRoomObjects() {
if (_numObjectsInRoom == 0)
return;
- if (_numObjectsInRoom > 200)
- error("More than %d objects in room %d", 200, _roomResource);
+ if (_numObjectsInRoom > _numLocalObjects)
+ error("More than %d objects in room %d", _numLocalObjects, _roomResource);
tmp_room = room;
- od = &objs[1];
+ od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
ptr = findResource(MKID('OBCD'), tmp_room);
if (ptr==NULL)
@@ -353,40 +388,49 @@ void Scumm::loadRoomObjects() {
obim_id = READ_LE_UINT16(&imhd->obj_id);
for(j=1; j<=_numObjectsInRoom; j++) {
- if (objs[j].obj_nr==obim_id)
- objs[j].offs_obim_to_room = ptr - room;
+ if (_objs[j].obj_nr==obim_id)
+ _objs[j].offs_obim_to_room = ptr - room;
}
tmp_room = NULL;
}
- od = &objs[1];
+ od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
- ptr = room + objs[i].offs_obcd_to_room;
+ ptr = room + _objs[i].offs_obcd_to_room;
cdhd = (CodeHeader*)findResource2(MKID('CDHD'), ptr);
- objs[i].obj_nr = READ_LE_UINT16(&cdhd->obj_id);
- objs[i].numstrips = cdhd->w;
- objs[i].height = cdhd->h;
- objs[i].x_pos = cdhd->x;
- objs[i].y_pos = cdhd->y;
-
+ _objs[i].obj_nr = READ_LE_UINT16(&cdhd->obj_id);
+
+#if defined(DOTT)
+ _objs[i].numstrips = cdhd->w>>3;
+ _objs[i].height = cdhd->h>>3;
+ _objs[i].x_pos = cdhd->x>>3;
+ _objs[i].y_pos = cdhd->y>>3;
+#else
+ _objs[i].numstrips = cdhd->w;
+ _objs[i].height = cdhd->h;
+ _objs[i].x_pos = cdhd->x;
+ _objs[i].y_pos = cdhd->y;
+#endif
if (cdhd->flags == 0x80) {
- objs[i].parentstate = 1<<4;
+ _objs[i].parentstate = 1<<4;
} else {
- objs[i].parentstate = (cdhd->flags&0xF)<<4;
+ _objs[i].parentstate = (cdhd->flags&0xF)<<4;
}
- objs[i].parent = cdhd->unk1;
- objs[i].cdhd_10 = READ_LE_UINT16(&cdhd->unk2);
- objs[i].cdhd_12 = READ_LE_UINT16(&cdhd->unk3);
- objs[i].actordir = cdhd->unk4;
- objs[i].fl_object_index = 0;
+ _objs[i].parent = cdhd->parent;
+#if !defined(DOTT)
+ _objs[i].cdhd_10 = READ_LE_UINT16(&cdhd->unk2);
+ _objs[i].cdhd_12 = READ_LE_UINT16(&cdhd->unk3);
+#endif
+ _objs[i].actordir = cdhd->actordir;
+ _objs[i].fl_object_index = 0;
}
- checkHeap();
+ CHECK_HEAP
}
void Scumm::fixObjectFlags() {
int i;
- ObjectData *od = &objs[1];
+ ObjectData *od = &_objs[1];
for (i=1; i<=_numObjectsInRoom; i++,od++) {
od->ownerstate = _objectFlagTable[od->obj_nr];
}
@@ -412,12 +456,12 @@ void Scumm::clearOwnerOf(int obj) {
if (getOwner(obj)==0xF) {
i = 0;
do {
- if (objs[i].obj_nr==obj) {
- if (!objs[i].fl_object_index)
+ if (_objs[i].obj_nr==obj) {
+ if (!_objs[i].fl_object_index)
return;
- nukeResource(0xD, objs[i].fl_object_index);
- objs[i].obj_nr = 0;
- objs[i].fl_object_index = 0;
+ nukeResource(0xD, _objs[i].fl_object_index);
+ _objs[i].obj_nr = 0;
+ _objs[i].fl_object_index = 0;
}
} while(++i <= _numObjectsInRoom);
return;
@@ -449,10 +493,10 @@ void Scumm::removeObjectFromRoom(int obj) {
uint16 *ptr;
for(i=1; i<=_numObjectsInRoom; i++) {
- if (objs[i].obj_nr==obj) {
- if (objs[i].numstrips != 0) {
- ptr = &actorDrawBits[objs[i].x_pos];
- cnt = objs[i].numstrips;
+ if (_objs[i].obj_nr==obj) {
+ if (_objs[i].numstrips != 0) {
+ ptr = &actorDrawBits[_objs[i].x_pos];
+ cnt = _objs[i].numstrips;
do {
*ptr++ |= 0x8000;
} while (--cnt);
@@ -476,7 +520,7 @@ void Scumm::clearDrawObjectQueue() {
byte *Scumm::getObjOrActorName(int obj) {
byte *objptr;
- if (obj <= vm.vars[VAR_NUM_ACTOR])
+ if (obj <= _vars[VAR_NUM_ACTOR])
return getActorName(derefActorSafe(obj, "getObjOrActorName"));
objptr = getObjectAddress(obj);
@@ -492,10 +536,10 @@ uint32 Scumm::getOBCDOffs(int object) {
if ((_objectFlagTable[object]&0xF)!=0xF)
return 0;
for (i=_numObjectsInRoom; i>0; i--) {
- if (objs[i].obj_nr == object) {
- if (objs[i].fl_object_index!=0)
+ if (_objs[i].obj_nr == object) {
+ if (_objs[i].fl_object_index!=0)
return 8;
- return objs[i].offs_obcd_to_room;
+ return _objs[i].offs_obcd_to_room;
}
}
return 0;
@@ -511,10 +555,10 @@ byte *Scumm::getObjectAddress(int obj) {
}
} else {
for(i=_numObjectsInRoom; i>0; --i) {
- if (objs[i].obj_nr==obj) {
- if (objs[i].fl_object_index)
- return getResourceAddress(0xD, objs[i].fl_object_index)+8;
- return getResourceAddress(1, _roomResource) + objs[i].offs_obcd_to_room;
+ if (_objs[i].obj_nr==obj) {
+ if (_objs[i].fl_object_index)
+ return getResourceAddress(0xD, _objs[i].fl_object_index)+8;
+ return getResourceAddress(1, _roomResource) + _objs[i].offs_obcd_to_room;
}
}
}
@@ -532,18 +576,18 @@ void Scumm::addObjectToInventory(int obj, int room) {
debug(1,"Adding object %d from room %d into inventory", obj, room);
- checkHeap();
+ CHECK_HEAP
if (whereIsObject(obj)==4) {
i = getObjectIndex(obj);
- ptr = getResourceAddress(0xD, objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64;
size = READ_BE_UINT32_UNALIGNED(ptr+4);
slot = getInventorySlot();
_inventory[slot] = obj;
createResource(5, slot, size);
- ptr = getResourceAddress(0xD, objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64;
memcpy(getResourceAddress(5, slot), ptr, size);
- checkHeap();
+ CHECK_HEAP
return;
}
ensureResourceLoaded(1, room);
@@ -569,7 +613,7 @@ void Scumm::addObjectToInventory(int obj, int room) {
createResource(5, slot, size);
obcdptr = getResourceAddress(1, room) + cdoffs;
memcpy(getResourceAddress(5,slot),obcdptr,size);
- checkHeap();
+ CHECK_HEAP
return;
}
tmp_roomptr = NULL;
@@ -587,3 +631,131 @@ int Scumm::getInventorySlot() {
error("Inventory full, %d max items", _maxInventoryItems);
}
+void Scumm::setOwnerOf(int obj, int owner) {
+ ScriptSlot *ss;
+ if (owner==0) {
+ clearOwnerOf(obj);
+ ss = &vm.slot[_currentScript];
+ if (ss->type==0 && _inventory[ss->number]==obj) {
+ putOwner(obj, 0);
+ runHook(0);
+ stopObjectCode();
+ return;
+ }
+ }
+ putOwner(obj, owner);
+ runHook(0);
+}
+
+int Scumm::getObjX(int obj) {
+ if (obj <= _vars[VAR_NUM_ACTOR]) {
+ return derefActorSafe(obj,"getObjX")->x;
+ } else {
+ if (whereIsObject(obj)==-1)
+ return -1;
+ getObjectOrActorXY(obj);
+ return _xPos;
+ }
+}
+
+int Scumm::getObjY(int obj) {
+ if (obj <= _vars[VAR_NUM_ACTOR]) {
+ return derefActorSafe(obj,"getObjY")->y;
+ } else {
+ if (whereIsObject(obj)==-1)
+ return -1;
+ getObjectOrActorXY(obj);
+ return _yPos;
+ }
+}
+
+int Scumm::getObjDir(int obj) {
+ if (obj <= _vars[VAR_NUM_ACTOR]) {
+ return derefActorSafe(obj,"getObjDir")->facing;
+ } else {
+ getObjectXYPos(obj);
+ return _dir;
+ }
+}
+
+int Scumm::findInventory(int owner, int index) {
+ int count = 1, i, obj;
+ for (i=0; i!=_maxInventoryItems; i++) {
+ obj = _inventory[i];
+ if (obj && getOwner(obj)==owner && count++ == index)
+ return obj;
+ }
+ return 0;
+}
+
+int Scumm::getInventoryCount(int owner) {
+ int i,obj;
+ int count = 0;
+ for (i=0; i!=_maxInventoryItems; i++) {
+ obj = _inventory[i];
+ if (obj && getOwner(obj) == owner)
+ count++;
+ }
+ return count;
+}
+
+#if defined(DOTT)
+void Scumm::setObjectState(int obj, int state, int x, int y) {
+ int i;
+
+ i = getObjectIndex(obj);
+ if (i==-1)
+ return;
+
+ if (x != -1) {
+ _objs[i].x_pos = x;
+ _objs[i].x_pos = y;
+ }
+
+ addObjectToDrawQue(i);
+ putState(obj, state);
+}
+
+static int getDist(int x, int y, int x2, int y2) {
+ int a = abs(y-y2);
+ int b = abs(x-x2);
+ if (a>b)
+ return a;
+ return b;
+}
+
+
+int Scumm::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f) {
+ int i,j;
+ int x,y;
+ int x2,y2;
+
+ j = i = 0xFF;
+
+ if (is_obj_1) {
+ if (getObjectOrActorXY(b)==-1)
+ return -1;
+ if (b < _vars[VAR_NUM_ACTOR])
+ i = derefActorSafe(b, "unkObjProc1")->scalex;
+ x = _xPos;
+ y = _yPos;
+ } else {
+ x = b;
+ y = c;
+ }
+
+ if (is_obj_2) {
+ if (getObjectOrActorXY(e)==-1)
+ return -1;
+ if (e < _vars[VAR_NUM_ACTOR])
+ j = derefActorSafe(e, "unkObjProc1(2)")->scalex;
+ x2 = _xPos;
+ y2 = _yPos;
+ } else {
+ x2 = e;
+ y2 = f;
+ }
+
+ return getDist(x,y,x2,y2) * 0xFF / ((i + j)>>1);
+}
+#endif \ No newline at end of file
diff --git a/resource.cpp b/resource.cpp
index 1afb2351a6..bff925159a 100644
--- a/resource.cpp
+++ b/resource.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/10 10:02:33 strigeus
* alternative mouse cursor
* basic save&load
@@ -164,6 +167,7 @@ void Scumm::askForDisk() {
error("askForDisk: not yet implemented");
}
+#if !defined(DOTT)
void Scumm::readIndexFile(int mode) {
uint32 blocktype,itemsize;
@@ -192,18 +196,18 @@ void Scumm::readIndexFile(int mode) {
break;
case MKID('DOBJ'):
- _maxNrObjects = fileReadWordLE();
- _objectFlagTable = (byte*)alloc(_maxNrObjects);
+ _numGlobalObjects = fileReadWordLE();
+ _objectFlagTable = (byte*)alloc(_numGlobalObjects);
if (mode==1) {
fileSeek(_fileHandle, itemsize - 10, 1);
break;
}
- _classData = (uint32*)alloc(_maxNrObjects * sizeof(uint32));
- fileRead(_fileHandle, _objectFlagTable, _maxNrObjects);
- fileRead(_fileHandle, _classData, _maxNrObjects * sizeof(uint32));
+ _classData = (uint32*)alloc(_numGlobalObjects * sizeof(uint32));
+ fileRead(_fileHandle, _objectFlagTable, _numGlobalObjects);
+ fileRead(_fileHandle, _classData, _numGlobalObjects * sizeof(uint32));
#if defined(SCUMM_BIG_ENDIAN)
- for (i=0; i<_maxNrObjects; i++)
+ for (i=0; i<_numGlobalObjects; i++)
_classData[i] = FROM_LE_32(_classData[i]);
#endif
break;
@@ -239,7 +243,7 @@ void Scumm::readIndexFile(int mode) {
case MKID('DSOU'):
readResTypeList(4,MKID('SOUN'),"sound");
break;
-
+
default:
error("Bad ID %c%c%c%c found in directory!", blocktype&0xFF, blocktype>>8, blocktype>>16, blocktype>>24);
return;
@@ -253,27 +257,147 @@ void Scumm::readIndexFile(int mode) {
openRoom(-1);
- _numGlobalScriptsUsed = _maxScripts;
+ _numGlobalScripts = _maxScripts;
_dynamicRoomOffsets = true;
}
+#else
-void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
+
+void Scumm::readIndexFile() {
+ uint32 blocktype,itemsize;
+ int numblock = 0;
int num;
+
+ debug(9, "readIndexFile()");
+
+ openRoom(-1);
+ openRoom(0);
+
+ while (1) {
+ blocktype = fileReadDword();
+
+ if (fileReadFailed(_fileHandle))
+ break;
+ itemsize = fileReadDwordBE();
+
+ numblock++;
+
+ switch(blocktype) {
+ case MKID('DCHR'):
+ readResTypeList(6,MKID('CHAR'),"charset");
+ break;
+
+ case MKID('DOBJ'):
+ num = fileReadWordLE();
+ assert(num == _numGlobalObjects);
+ fileRead(_fileHandle, _objectFlagTable, num);
+ fileRead(_fileHandle, _classData, num * sizeof(uint32));
#if defined(SCUMM_BIG_ENDIAN)
- int i;
+ for (i=0; i<_numGlobalObjects; i++)
+ _classData[i] = FROM_LE_32(_classData[i]);
#endif
+ break;
+
+ case MKID('RNAM'):
+ fileSeek(_fileHandle, itemsize-8,1);
+ break;
+
+ case MKID('DROO'):
+ readResTypeList(1,MKID('ROOM'),"room");
+ break;
+
+ case MKID('DSCR'):
+ readResTypeList(2,MKID('SCRP'),"script");
+ break;
+
+ case MKID('DCOS'):
+ readResTypeList(3,MKID('COST'),"costume");
+ break;
+
+ case MKID('MAXS'):
+ readMAXS();
+ break;
+
+ case MKID('DSOU'):
+ readResTypeList(4,MKID('SOUN'),"sound");
+ break;
+
+ case MKID('AARY'):
+ readArrayFromIndexFile();
+ break;
+
+ default:
+ error("Bad ID %c%c%c%c found in directory!", blocktype&0xFF, blocktype>>8, blocktype>>16, blocktype>>24);
+ return;
+ }
+ }
+
+ clearFileReadFailed(_fileHandle);
+
+ if (numblock!=9)
+ error("Not enough blocks read from directory");
+
+ openRoom(-1);
+}
+#endif
+
+
+#if defined(DOTT)
+void Scumm::readArrayFromIndexFile() {
+ int num;
+ int a,b,c;
+
+ while ((num = fileReadWordLE()) != 0) {
+ a = fileReadWordLE();
+ b = fileReadWordLE();
+ c = fileReadWordLE();
+ if (c==1)
+ defineArray(num, 1, a, b);
+ else
+ defineArray(num, 5, a, b);
+ }
+}
+
+#endif
+
+#if defined(DOTT)
+
+void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
+ int num,i;
+
+ debug(9, "readResTypeList(%d,%x,%s)",id,FROM_LE_32(tag),name);
+
+ num = fileReadWordLE();
+ assert(num == res.num[id]);
+
+ fileRead(_fileHandle, res.roomno[id], num*sizeof(uint8));
+ fileRead(_fileHandle, res.roomoffs[id], num*sizeof(uint32));
+#if defined(SCUMM_BIG_ENDIAN)
+ for (i=0; i<num; i++)
+ res.roomoffs[id][i] = FROM_LE_32(res.roomoffs[id][i]);
+#endif
+
+}
+
+
+
+#else
+
+void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
+ int num;
+ int i;
debug(9, "readResTypeList(%d,%x,%s)",id,FROM_LE_32(tag),name);
num = fileReadWordLE();
- if (num>0xFF) {
+ if (num>=0xFF) {
error("Too many %ss (%d) in directory", name, num);
}
allocResTypeData(id, tag, num, name, 1);
- fileRead(_fileHandle, res.roomno[id], num);
+ fileRead(_fileHandle, res.roomno[id], num*sizeof(uint8));
fileRead(_fileHandle, res.roomoffs[id], num*sizeof(uint32));
#if defined(SCUMM_BIG_ENDIAN)
@@ -282,8 +406,16 @@ void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
#endif
}
+#endif
+
void Scumm::allocResTypeData(int id, uint32 tag, int num, const char *name, int mode) {
debug(9, "allocResTypeData(%d,%x,%d,%s,%d)",id,FROM_LE_32(tag),num,name,mode);
+ assert(id>=0 && id<sizeof(res.mode)/sizeof(res.mode[0]));
+
+ if (num>=512) {
+ error("Too many %ss (%d) in directory", name, num);
+ }
+
res.mode[id] = mode;
res.num[id] = num;
res.tags[id] = tag;
@@ -336,7 +468,7 @@ void Scumm::ensureResourceLoaded(int type, int i) {
loadResource(type, i);
if (type==1 && i==_roomResource)
- vm.vars[VAR_ROOM_FLAG] = 1;
+ _vars[VAR_ROOM_FLAG] = 1;
}
int Scumm::loadResource(int type, int index) {
@@ -436,7 +568,6 @@ int Scumm::readSoundResource(int type, int index) {
return 0;
}
-
int Scumm::getResourceRoomNr(int type, int index) {
if (type==1)
return index;
@@ -448,7 +579,7 @@ byte *Scumm::getResourceAddress(int type, int index) {
debug(9, "getResourceAddress(%d,%d)", type, index);
- checkHeap();
+ CHECK_HEAP
validateResource("getResourceAddress", type, index);
@@ -473,7 +604,7 @@ void Scumm::setResourceFlags(int type, int index, byte flag) {
byte *Scumm::createResource(int type, int index, uint32 size) {
byte *ptr;
- checkHeap();
+ CHECK_HEAP
debug(9, "createResource(%d,%d,%d)", type, index,size);
@@ -483,7 +614,7 @@ byte *Scumm::createResource(int type, int index, uint32 size) {
validateResource("allocating", type, index);
nukeResource(type, index);
- checkHeap();
+ CHECK_HEAP
ptr = (byte*)alloc(size + sizeof(ResHeader));
if (ptr==NULL) {
@@ -509,7 +640,7 @@ void Scumm::nukeResource(int type, int index) {
debug(9, "nukeResource(%d,%d)", type, index);
- checkHeap();
+ CHECK_HEAP
assert( res.address[type] );
assert( index>=0 && index < res.num[type]);
@@ -607,22 +738,10 @@ void Scumm::loadPtrToResource(int type, int resindex, byte *source) {
int i,len;
nukeResource(type, resindex);
- if (!source) {
- ptr = _scriptPointer;
- } else {
- ptr = source;
- }
- len = 0;
- do {
- i = *ptr++;
- if (!i) break;
- len++;
- if (i==0xFF)
- ptr += 3, len += 3;
- } while (1);
-
- if (++len <= 1)
+ len = getStringLen(source);
+
+ if (len <= 1)
return;
alloced = createResource(type, resindex, len);
@@ -648,7 +767,57 @@ void Scumm::unkHeapProc2(int a, int b) {
}
void Scumm::unkResProc(int a, int b) {
- error("unkResProc:not implemented");
+ warning("unkResProc:not implemented");
}
+#if defined(DOTT)
+void Scumm::readMAXS() {
+ _numVariables = fileReadWordLE();
+ fileReadWordLE();
+ _numBitVariables = fileReadWordLE();
+ _numLocalObjects = fileReadWordLE();
+ _numArray = fileReadWordLE();
+ fileReadWordLE();
+ _numVerbs = fileReadWordLE();
+ _numFlObject = fileReadWordLE();
+ _numInventory = fileReadWordLE();
+ _numRooms = fileReadWordLE();
+ _numScripts = fileReadWordLE();
+ _numSounds = fileReadWordLE();
+ _numCharsets = fileReadWordLE();
+ _numCostumes = fileReadWordLE();
+ _numGlobalObjects = fileReadWordLE();
+
+ allocResTypeData(3, MKID('COST'), _numCostumes, "costume", 1);
+ allocResTypeData(1, MKID('ROOM'), _numRooms, "room", 1);
+ allocResTypeData(4, MKID('SOUN'), _numSounds, "sound", 1);
+ allocResTypeData(2, MKID('SCRP'), _numScripts, "script", 1);
+ allocResTypeData(6, MKID('CHAR'), _numCharsets, "charset", 1);
+ allocResTypeData(5, MKID('NONE'), _numInventory, "inventory", 0);
+ allocResTypeData(8, MKID('NONE'), _numVerbs,"verb", 0);
+ allocResTypeData(7, MKID('NONE'), _numArray,"array", 0);
+ allocResTypeData(13, MKID('NONE'),_numFlObject,"flobject", 0);
+ allocResTypeData(12,MKID('NONE'),10, "temp", 0);
+ allocResTypeData(11,MKID('NONE'),5, "scale table", 0);
+ allocResTypeData(9, MKID('NONE'),13,"actor name", 0);
+ allocResTypeData(10, MKID('NONE'),10,"buffer", 0);
+ allocResTypeData(14, MKID('NONE'),10,"boxes", 0);
+ allocResTypeData(16, MKID('NONE'),50,"new name", 0);
+
+ _objectFlagTable = (byte*)alloc(_numGlobalObjects);
+ _inventory = (uint16*)alloc(_numInventory * sizeof(uint16));
+ _arrays = (byte*)alloc(_numArray);
+ _verbs = (VerbSlot*)alloc(_numVerbs * sizeof(VerbSlot));
+ _objs = (ObjectData*)alloc(_numLocalObjects * sizeof(ObjectData));
+ _vars = (int16*)alloc(_numVariables * sizeof(int16));
+ _bitVars = (byte*)alloc(_numBitVariables >> 3);
+ _newNames = (uint16*)alloc(50 * sizeof(uint16));
+ _classData = (uint32*)alloc(_numGlobalObjects * sizeof(uint32));
+
+ _numGlobalScripts = 200;
+ _dynamicRoomOffsets = 1;
+}
+#endif
+
+
diff --git a/saveload.cpp b/saveload.cpp
index d9f530b1ac..37c7801dba 100644
--- a/saveload.cpp
+++ b/saveload.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/10 10:02:33 strigeus
* alternative mouse cursor
* basic save&load
@@ -31,10 +34,25 @@
#include "stdafx.h"
#include "scumm.h"
+struct SaveGameHeader {
+ uint32 type;
+ uint32 size;
+ uint32 ver;
+};
+
bool Scumm::saveState(const char *filename) {
FILE *out = fopen(filename,"wb");
+ SaveGameHeader hdr;
+
if (out==NULL)
return false;
+
+ hdr.type = MKID('SCVM');
+ hdr.size = 0;
+ hdr.ver = 1;
+
+ fwrite(&hdr, sizeof(hdr), 1, out);
+
saveOrLoad(out,true);
fclose(out);
debug(1,"State saved as '%s'", filename);
@@ -44,11 +62,25 @@ bool Scumm::saveState(const char *filename) {
bool Scumm::loadState(const char *filename) {
FILE *out = fopen(filename,"rb");
int i,j;
+ SaveGameHeader hdr;
if (out==NULL)
return false;
+
+ fread(&hdr, sizeof(hdr), 1, out);
+ if (hdr.type != MKID('SCVM')) {
+ warning("Invalid savegame '%s'", filename);
+ fclose(out);
+ return false;
+ }
+
+ if (hdr.ver != 1) {
+ warning("Invalid version of '%s'", filename);
+ fclose(out);
+ return false;
+ }
- checkHeap();
+ CHECK_HEAP
openRoom(-1);
memset(_inventory, 0, sizeof(_inventory));
@@ -74,7 +106,7 @@ bool Scumm::loadState(const char *filename) {
initBGBuffers();
- checkHeap();
+ CHECK_HEAP
debug(1,"State loaded from '%s'", filename);
@@ -95,10 +127,10 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(ObjectData,cdhd_10,sleUint16),
MKLINE(ObjectData,cdhd_12,sleUint16),
MKLINE(ObjectData,obj_nr,sleUint16),
- MKLINE(ObjectData,x_pos,sleByte),
- MKLINE(ObjectData,y_pos,sleByte),
- MKLINE(ObjectData,numstrips,sleByte),
- MKLINE(ObjectData,height,sleByte),
+ MKLINE(ObjectData,x_pos,sleInt16),
+ MKLINE(ObjectData,y_pos,sleInt16),
+ MKLINE(ObjectData,numstrips,sleUint16),
+ MKLINE(ObjectData,height,sleUint16),
MKLINE(ObjectData,actordir,sleByte),
MKLINE(ObjectData,parentstate,sleByte),
MKLINE(ObjectData,parent,sleByte),
@@ -116,13 +148,13 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Actor,elevation,sleInt16),
MKLINE(Actor,width,sleUint16),
MKLINE(Actor,facing,sleByte),
- MKLINE(Actor,costume,sleByte),
+ MKLINE(Actor,costume,sleUint16),
MKLINE(Actor,room,sleByte),
MKLINE(Actor,talkColor,sleByte),
MKLINE(Actor,scalex,sleByte),
MKLINE(Actor,scaley,sleByte),
MKLINE(Actor,charset,sleByte),
- MKLINE(Actor,sound,sleByte),
+ MKARRAY(Actor,sound[0],sleByte, 8),
MKLINE(Actor,newDirection,sleByte),
MKLINE(Actor,moving,sleByte),
MKLINE(Actor,ignoreBoxes,sleByte),
@@ -147,6 +179,10 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Actor,needBgReset,sleByte),
MKLINE(Actor,costumeNeedsInit,sleByte),
+ MKLINE(Actor,new_1,sleInt16),
+ MKLINE(Actor,new_2,sleInt16),
+ MKLINE(Actor,new_3,sleByte),
+
MKLINE(Actor,walkdata.destx,sleInt16),
MKLINE(Actor,walkdata.desty,sleInt16),
MKLINE(Actor,walkdata.destbox,sleByte),
@@ -203,14 +239,14 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Scumm,_IM00_offs,sleUint32),
MKLINE(Scumm,_CLUT_offs,sleUint32),
MKLINE(Scumm,_EPAL_offs,sleUint32),
+ MKLINE(Scumm,_PALS_offs,sleUint32),
+ MKLINE(Scumm,_curPalIndex,sleByte),
MKLINE(Scumm,_currentRoom,sleByte),
MKLINE(Scumm,_roomResource,sleByte),
MKLINE(Scumm,_numObjectsInRoom,sleByte),
MKLINE(Scumm,_currentScript,sleByte),
MKARRAY(Scumm,_localScriptList[0],sleUint32,0x39),
- MKARRAY(Scumm,vm.vars[0],sleUint16,801),
MKARRAY(Scumm,vm.localvar[0],sleUint16,20*17),
- MKARRAY(Scumm,vm.bitvars[0],sleByte,256),
MKARRAY(Scumm,_resourceMapper[0],sleByte,128),
MKARRAY(Scumm,charset._colorMap[0],sleByte,16),
MKARRAY(Scumm,_charsetData[0][0],sleByte,10*16),
@@ -238,12 +274,6 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Scumm,_numInMsgStack,sleInt16),
MKLINE(Scumm,_sentenceIndex,sleByte),
- MKARRAY(Scumm,_sentenceTab[0],sleByte,6),
- MKARRAY(Scumm,_sentenceTab2[0],sleByte,6),
- MKARRAY(Scumm,_sentenceTab3[0],sleUint16,6),
- MKARRAY(Scumm,_sentenceTab4[0],sleUint16,6),
- MKARRAY(Scumm,_sentenceTab5[0],sleByte,6),
-
MKLINE(Scumm,vm.cutSceneStackPointer,sleByte),
MKARRAY(Scumm,vm.cutScenePtr[0],sleUint32,5),
MKARRAY(Scumm,vm.cutSceneScript[0],sleByte,5),
@@ -256,7 +286,6 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Scumm,_cursorState,sleByte),
MKLINE(Scumm,gdi.unk4,sleByte),
MKLINE(Scumm,gdi.currentCursor,sleByte),
-// MKLINE(Scumm,gdi.unk3,sleByte),
MKLINE(Scumm,dseg_4F8A,sleUint16),
MKLINE(Scumm,_switchRoomEffect,sleByte),
@@ -264,37 +293,13 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(Scumm,_switchRoomEffect2,sleByte),
MKLINE(Scumm,_BgNeedsRedraw,sleByte),
- MKARRAY(Scumm,actorDrawBits[0],sleUint16,160),
+ MKARRAY(Scumm,actorDrawBits[0],sleUint16,200),
MKLINE(Scumm,gdi.transparency,sleByte),
MKARRAY(Scumm,_currentPalette[0],sleByte,768),
-
/* virtscr */
MKARRAY(Scumm,charset._buffer[0],sleByte,256),
- MKARRAY(Scumm,textslot.x[0],sleInt16,6),
- MKARRAY(Scumm,textslot.y[0],sleInt16,6),
- MKARRAY(Scumm,textslot.center[0],sleInt16,6),
- MKARRAY(Scumm,textslot.overhead[0],sleInt16,6),
- MKARRAY(Scumm,textslot.right[0],sleInt16,6),
- MKARRAY(Scumm,textslot.color[0],sleInt16,6),
- MKARRAY(Scumm,textslot.charset[0],sleInt16,6),
-
- MKARRAY(Scumm,_stringXpos[0],sleInt16,6),
- MKARRAY(Scumm,_stringYpos[0],sleInt16,6),
- MKARRAY(Scumm,_stringXpos2[0],sleInt16,6),
- MKARRAY(Scumm,_stringYpos2[0],sleInt16,6),
- MKARRAY(Scumm,_stringCenter[0],sleInt16,6),
- MKARRAY(Scumm,_stringOverhead[0],sleUint16,6),
- MKARRAY(Scumm,_stringRight[0],sleUint16,6),
- MKARRAY(Scumm,_stringColor[0],sleUint16,6),
- MKARRAY(Scumm,_stringCharset[0],sleUint16,6),
-
- MKLINE(Scumm,charset._mask_left,sleInt16),
- MKLINE(Scumm,charset._mask_top,sleInt16),
- MKLINE(Scumm,charset._mask_right,sleInt16),
- MKLINE(Scumm,charset._mask_bottom,sleInt16),
-
MKLINE(Scumm,dseg_3A76,sleUint16),
MKARRAY(Scumm,_imgBufOffs[0],sleUint16,4),
@@ -327,6 +332,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKLINE(ScriptSlot,offs,sleUint32),
MKLINE(ScriptSlot,delay,sleInt32),
MKLINE(ScriptSlot,number,sleUint16),
+ MKLINE(ScriptSlot,newfield,sleUint16),
MKLINE(ScriptSlot,status,sleByte),
MKLINE(ScriptSlot,type,sleByte),
MKLINE(ScriptSlot,unk1,sleByte),
@@ -345,6 +351,39 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
MKEND()
};
+ const SaveLoadEntry sentenceTabEntries[] = {
+ MKLINE(SentenceTab,unk5,sleUint8),
+ MKLINE(SentenceTab,unk2,sleUint8),
+ MKLINE(SentenceTab,unk4,sleUint16),
+ MKLINE(SentenceTab,unk3,sleUint16),
+ MKLINE(SentenceTab,unk,sleUint8),
+ MKEND()
+ };
+
+ const SaveLoadEntry stringTabEntries[] = {
+ MKLINE(StringTab,t_xpos,sleInt16),
+ MKLINE(StringTab,t_ypos,sleInt16),
+ MKLINE(StringTab,t_center,sleInt16),
+ MKLINE(StringTab,t_overhead,sleInt16),
+ MKLINE(StringTab,t_new3,sleInt16),
+ MKLINE(StringTab,t_right,sleInt16),
+ MKLINE(StringTab,t_color,sleInt16),
+ MKLINE(StringTab,t_charset,sleInt16),
+ MKLINE(StringTab,xpos,sleInt16),
+ MKLINE(StringTab,ypos,sleInt16),
+ MKLINE(StringTab,xpos2,sleInt16),
+ MKLINE(StringTab,ypos2,sleInt16),
+ MKLINE(StringTab,center,sleInt16),
+ MKLINE(StringTab,overhead,sleInt16),
+ MKLINE(StringTab,new_3,sleInt16),
+ MKLINE(StringTab,right,sleInt16),
+ MKLINE(StringTab,mask_top,sleInt16),
+ MKLINE(StringTab,mask_bottom,sleInt16),
+ MKLINE(StringTab,mask_right,sleInt16),
+ MKLINE(StringTab,mask_left,sleInt16),
+ MKEND()
+ };
+
int i,j;
_saveLoadStream = inout;
@@ -355,29 +394,26 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {
saveLoadEntries(&actor[i],actorEntries);
for (i=0; i<20; i++)
saveLoadEntries(&vm.slot[i],scriptSlotEntries);
- for (i=0; i<184; i++)
- saveLoadEntries(&objs[i],objectEntries);
- for (i=0; i<102; i++)
- saveLoadEntries(&verbs[i],verbEntries);
+ for (i=0; i<_numLocalObjects; i++)
+ saveLoadEntries(&_objs[i],objectEntries);
+ for (i=0; i<_numVerbs; i++)
+ saveLoadEntries(&_verbs[i],verbEntries);
for (i=0; i<16; i++)
saveLoadEntries(&vm.nest[i],nestedScriptEntries);
+ for (i=0; i<6; i++)
+ saveLoadEntries(&sentence[i],sentenceTabEntries);
+ for (i=0; i<6; i++)
+ saveLoadEntries(&string[i],stringTabEntries);
for (i=1; i<16; i++)
if (res.mode[i]==0)
for(j=1; j<res.num[i]; j++)
saveLoadResource(i,j);
- if (_saveOrLoad) {
- for (i=0; i<_maxNrObjects; i++) {
- saveByte(_objectFlagTable[i]);
- saveUint32(_classData[i]);
- }
- } else {
- for (i=0; i<_maxNrObjects; i++) {
- _objectFlagTable[i] = loadByte();
- _classData[i] = loadUint32();
- }
- }
+ saveLoadArrayOf(_objectFlagTable, _numGlobalObjects, sizeof(_objectFlagTable[0]), sleByte);
+ saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32);
+ saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16);
+ saveLoadArrayOf(_bitVars, _numBitVariables>>8, 1, sleByte);
}
void Scumm::saveLoadResource(int type, int index) {
@@ -454,6 +490,61 @@ byte Scumm::loadByte() {
return e;
}
+void Scumm::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) {
+ byte *at = (byte*)b;
+ uint32 data;
+
+ while (--len>=0) {
+ if (_saveOrLoad) {
+ /* saving */
+ if (datasize==1) {
+ data = *(byte*)at;
+ at += 1;
+ } else if (datasize==2) {
+ data = *(uint16*)at;
+ at += 2;
+ } else if (datasize==4) {
+ data = *(uint32*)at;
+ at += 4;
+ } else {
+ error("saveLoadArrayOf: invalid size %d", datasize);
+ }
+ switch(filetype) {
+ case sleByte: saveByte(data); break;
+ case sleUint16:
+ case sleInt16:saveWord(data); break;
+ case sleInt32:
+ case sleUint32:saveUint32(data); break;
+ default:
+ error("saveLoadArrayOf: invalid filetype %d", filetype);
+ }
+ } else {
+ /* loading */
+ switch(filetype) {
+ case sleByte: data = loadByte(); break;
+ case sleUint16: data = loadWord(); break;
+ case sleInt16: data = (int16)loadWord(); break;
+ case sleUint32: data = loadUint32(); break;
+ case sleInt32: data = (int32)loadUint32(); break;
+ default:
+ error("saveLoadArrayOf: invalid filetype %d", filetype);
+ }
+ if (datasize==1) {
+ *(byte*)at = data;
+ at += 1;
+ } else if (datasize==2) {
+ *(uint16*)at = data;
+ at += 2;
+ } else if (datasize==4) {
+ *(uint32*)at = data;
+ at += 4;
+ } else {
+ error("saveLoadArrayOf: invalid size %d", datasize);
+ }
+ }
+ }
+}
+
void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
int replen;
@@ -461,7 +552,6 @@ void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
byte *at;
int size;
int value;
- uint32 data;
while(sle->offs != 0xFFFF) {
at = (byte*)d + sle->offs;
@@ -474,56 +564,7 @@ void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
type&=~128;
}
sle++;
-
- do {
- if (_saveOrLoad) {
- /* saving */
- if (size==1) {
- data = *(byte*)at;
- at += 1;
- } else if (size==2) {
- data = *(uint16*)at;
- at += 2;
- } else if (size==4) {
- data = *(uint32*)at;
- at += 4;
- } else {
- warning("invalid size %d", size);
- }
- switch(type) {
- case sleByte: saveByte(data); break;
- case sleUint16:
- case sleInt16:saveWord(data); break;
- case sleInt32:
- case sleUint32:saveUint32(data); break;
- default:
- warning("invalid type %d", type);
- }
- } else {
- /* loading */
- switch(type) {
- case sleByte: data = loadByte(); break;
- case sleUint16: data = loadWord(); break;
- case sleInt16: data = (int16)loadWord(); break;
- case sleUint32: data = loadUint32(); break;
- case sleInt32: data = (int32)loadUint32(); break;
- default:
- warning("invalid type %d", type);
- }
- if (size==1) {
- *(byte*)at = data;
- at += 1;
- } else if (size==2) {
- *(uint16*)at = data;
- at += 2;
- } else if (size==4) {
- *(uint32*)at = data;
- at += 4;
- } else {
- warning("invalid size %d", size);
- }
- }
- } while (--replen);
+ saveLoadArrayOf(at, replen, size, type);
}
}
diff --git a/script.cpp b/script.cpp
index 698b09c8bf..fbad851263 100644
--- a/script.cpp
+++ b/script.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/11 13:36:25 strigeus
* fixed swapped parameters in o_walkActorToActor
*
@@ -50,12 +53,12 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {
if (b==0)
stopScriptNr(script);
- if (script < _numGlobalScriptsUsed) {
+ if (script < _numGlobalScripts) {
scriptPtr = getResourceAddress(2, script);
scriptOffs = 8;
scriptType = 2;
} else {
- scriptOffs = _localScriptList[script - _numGlobalScriptsUsed];
+ scriptOffs = _localScriptList[script - _numGlobalScripts];
if (scriptOffs == 0)
error("Local script %d is not in room %d", script, _roomResource);
scriptOffs += 9;
@@ -114,7 +117,7 @@ void Scumm::stopScriptNr(int script) {
do {
if (nest->number == script && (nest->type==2 || nest->type==3)) {
- nest->number = 0xFFFF;
+ nest->number = 0xFF;
nest->slot = 0xFF;
nest->type = 0xFF;
}
@@ -132,15 +135,14 @@ void Scumm::stopObjectScript(int script) {
ss = &vm.slot[1];
for (i=1; i<20; i++,ss++) {
- if (script!=ss->number || ss->type!=1 && ss->type!=0 && ss->type!=4 || ss->status==0)
- continue;
-
- if (ss->cutsceneOverride)
- error("Object %d stopped with active cutscene/override", script);
- ss->number = 0;
- ss->status = 0;
- if (_currentScript == i)
- _currentScript = 0xFF;
+ if (script==ss->number && (ss->type==1 || ss->type==0 || ss->type==4) && ss->status!=0) {
+ if (ss->cutsceneOverride)
+ error("Object %d stopped with active cutscene/override", script);
+ ss->number = 0;
+ ss->status = 0;
+ if (_currentScript == i)
+ _currentScript = 0xFF;
+ }
}
if (_numNestedScripts==0)
@@ -151,7 +153,7 @@ void Scumm::stopObjectScript(int script) {
do {
if (nest->number == script && (nest->type==1 || nest->type==4 || nest->type==0)) {
- nest->number = 0xFFFF;
+ nest->number = 0xFF;
nest->slot = 0xFF;
nest->type = 0xFF;
}
@@ -250,7 +252,7 @@ void Scumm::getScriptBaseAddress() {
case 4: /* flobject script */
index = getObjectIndex(ss->number);
- _scriptOrgPointer = getResourceAddress(13,objs[index].fl_object_index);
+ _scriptOrgPointer = getResourceAddress(13,_objs[index].fl_object_index);
_lastCodePtr = &_baseFLObject[ss->number];
break;
default:
@@ -265,345 +267,17 @@ void Scumm::getScriptEntryPoint() {
_scriptPointer = _scriptOrgPointer + vm.slot[_currentScript].offs;
}
-OpcodeProc FORCEINLINE Scumm::getOpcode(int i) {
- static const OpcodeProc opcode_list[] = {
- /* 00 */
- &Scumm::o_stopObjectCode,
- &Scumm::o_putActor,
- &Scumm::o_startMusic,
- &Scumm::o_getActorRoom,
- /* 04 */
- &Scumm::o_isGreaterEqual, /* hmm, seems to be less or equal */
- &Scumm::o_drawObject,
- &Scumm::o_getActorElevation,
- &Scumm::o_setState,
- /* 08 */
- &Scumm::o_isNotEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 0C */
- &Scumm::o_resourceRoutines,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_getObjectState,
- /* 10 */
- &Scumm::o_getObjectOwner,
- &Scumm::o_animateActor,
- &Scumm::o_panCameraTo,
- &Scumm::o_actorSet,
- /* 14 */
- &Scumm::o_print,
- &Scumm::o_actorFromPos,
- &Scumm::o_getRandomNr,
- &Scumm::o_and,
- /* 18 */
- &Scumm::o_jumpRelative,
- &Scumm::o_doSentence,
- &Scumm::o_move,
- &Scumm::o_multiply,
- /* 1C */
- &Scumm::o_startSound,
- &Scumm::o_ifClassOfIs,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* 20 */
- &Scumm::o_stopMusic,
- &Scumm::o_putActor,
- &Scumm::o_getAnimCounter,
- &Scumm::o_getActorY,
- /* 24 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_setVarRange,
- &Scumm::o_stringOps,
- /* 28 */
- &Scumm::o_equalZero,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_delayVariable,
- /* 2C */
- &Scumm::o_cursorCommand,
- &Scumm::o_putActorInRoom,
- &Scumm::o_delay,
- &Scumm::o_badOpcode,
- /* 30 */
- &Scumm::o_matrixOps,
- &Scumm::o_getInventoryCount,
- &Scumm::o_setCameraAt,
- &Scumm::o_roomOps,
- /* 34 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* 38 */
- &Scumm::o_lessOrEqual,
- &Scumm::o_doSentence,
- &Scumm::o_subtract,
- &Scumm::o_getActorScale,
- /* 3C */
- &Scumm::o_stopSound,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* 40 */
- &Scumm::o_cutscene,
- &Scumm::o_putActor,
- &Scumm::o_chainScript,
- &Scumm::o_getActorX,
- /* 44 */
- &Scumm::o_isLess,
- &Scumm::o_badOpcode,
- &Scumm::o_increment,
- &Scumm::o_setState,
- /* 48 */
- &Scumm::o_isEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 4C */
- &Scumm::o_soundKludge,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_badOpcode,
- /* 50 */
- &Scumm::o_badOpcode,
- &Scumm::o_animateActor,
- &Scumm::o_actorFollowCamera,
- &Scumm::o_actorSet,
- /* 54 */
- &Scumm::o_setObjectName,
- &Scumm::o_actorFromPos,
- &Scumm::o_getActorMoving,
- &Scumm::o_or,
- /* 58 */
- &Scumm::o_overRide,
- &Scumm::o_doSentence,
- &Scumm::o_add,
- &Scumm::o_divide,
- /* 5C */
- &Scumm::o_badOpcode,
- &Scumm::o_actorSetClass,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* 60 */
- &Scumm::o_freezeScripts,
- &Scumm::o_putActor,
- &Scumm::o_stopScript,
- &Scumm::o_getActorFacing,
- /* 64 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_getClosestObjActor,
- &Scumm::o_dummy,
- /* 68 */
- &Scumm::o_getScriptRunning,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_debug,
- /* 6C */
- &Scumm::o_getActorWidth,
- &Scumm::o_putActorInRoom,
- &Scumm::o_stopObjectScript,
- &Scumm::o_badOpcode,
- /* 70 */
- &Scumm::o_lights,
- &Scumm::o_getActorCostume,
- &Scumm::o_loadRoom,
- &Scumm::o_roomOps,
- /* 74 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* 78 */
- &Scumm::o_isGreater, /* less? */
- &Scumm::o_doSentence,
- &Scumm::o_verbOps,
- &Scumm::o_getActorWalkBox,
- /* 7C */
- &Scumm::o_isSoundRunning,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* 80 */
- &Scumm::o_breakHere,
- &Scumm::o_putActor,
- &Scumm::o_startMusic,
- &Scumm::o_getActorRoom,
- /* 84 */
- &Scumm::o_isGreaterEqual, /* less equal? */
- &Scumm::o_drawObject,
- &Scumm::o_getActorElevation,
- &Scumm::o_setState,
- /* 88 */
- &Scumm::o_isNotEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* 8C */
- &Scumm::o_resourceRoutines,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_getObjectState,
- /* 90 */
- &Scumm::o_getObjectOwner,
- &Scumm::o_animateActor,
- &Scumm::o_panCameraTo,
- &Scumm::o_actorSet,
- /* 94 */
- &Scumm::o_print,
- &Scumm::o_actorFromPos,
- &Scumm::o_getRandomNr,
- &Scumm::o_and,
- /* 98 */
- &Scumm::o_quitPauseRestart,
- &Scumm::o_doSentence,
- &Scumm::o_move,
- &Scumm::o_multiply,
- /* 9C */
- &Scumm::o_startSound,
- &Scumm::o_ifClassOfIs,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* A0 */
- &Scumm::o_stopObjectCode,
- &Scumm::o_putActor,
- &Scumm::o_getAnimCounter,
- &Scumm::o_getActorY,
- /* A4 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_setVarRange,
- &Scumm::o_dummy,
- /* A8 */
- &Scumm::o_notEqualZero,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_saveRestoreVerbs,
- /* AC */
- &Scumm::o_expression,
- &Scumm::o_putActorInRoom,
- &Scumm::o_wait,
- &Scumm::o_badOpcode,
- /* B0 */
- &Scumm::o_matrixOps,
- &Scumm::o_getInventoryCount,
- &Scumm::o_setCameraAt,
- &Scumm::o_roomOps,
- /* B4 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* B8 */
- &Scumm::o_lessOrEqual,
- &Scumm::o_doSentence,
- &Scumm::o_subtract,
- &Scumm::o_getActorScale,
- /* BC */
- &Scumm::o_stopSound,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox,
- /* C0 */
- &Scumm::o_endCutscene,
- &Scumm::o_putActor,
- &Scumm::o_chainScript,
- &Scumm::o_getActorX,
- /* C4 */
- &Scumm::o_isLess,
- &Scumm::o_badOpcode,
- &Scumm::o_decrement,
- &Scumm::o_setState,
- /* C8 */
- &Scumm::o_isEqual,
- &Scumm::o_faceActor,
- &Scumm::o_startScript,
- &Scumm::o_getVerbEntrypoint,
- /* CC */
- &Scumm::o_pseudoRoom,
- &Scumm::o_walkActorToActor,
- &Scumm::o_putActorAtObject,
- &Scumm::o_badOpcode,
- /* D0 */
- &Scumm::o_badOpcode,
- &Scumm::o_animateActor,
- &Scumm::o_actorFollowCamera,
- &Scumm::o_actorSet,
- /* D4 */
- &Scumm::o_setObjectName,
- &Scumm::o_actorFromPos,
- &Scumm::o_getActorMoving,
- &Scumm::o_or,
- /* D8 */
- &Scumm::o_printEgo,
- &Scumm::o_doSentence,
- &Scumm::o_add,
- &Scumm::o_divide,
- /* DC */
- &Scumm::o_badOpcode,
- &Scumm::o_actorSetClass,
- &Scumm::o_walkActorTo,
- &Scumm::o_isActorInBox,
- /* E0 */
- &Scumm::o_freezeScripts,
- &Scumm::o_putActor,
- &Scumm::o_stopScript,
- &Scumm::o_getActorFacing,
- /* E4 */
- &Scumm::o_loadRoomWithEgo,
- &Scumm::o_pickupObject,
- &Scumm::o_getClosestObjActor,
- &Scumm::o_dummy,
- /* E8 */
- &Scumm::o_getScriptRunning,
- &Scumm::o_setOwnerOf,
- &Scumm::o_startScript,
- &Scumm::o_debug,
- /* EC */
- &Scumm::o_getActorWidth,
- &Scumm::o_putActorInRoom,
- &Scumm::o_stopObjectScript,
- &Scumm::o_badOpcode,
- /* F0 */
- &Scumm::o_lights,
- &Scumm::o_getActorCostume,
- &Scumm::o_loadRoom,
- &Scumm::o_roomOps,
- /* F4 */
- &Scumm::o_getDist,
- &Scumm::o_findObject,
- &Scumm::o_walkActorToObject,
- &Scumm::o_startObject,
- /* F8 */
- &Scumm::o_isGreater,
- &Scumm::o_doSentence,
- &Scumm::o_verbOps,
- &Scumm::o_getActorWalkBox,
- /* FC */
- &Scumm::o_isSoundRunning,
- &Scumm::o_findInventory,
- &Scumm::o_walkActorTo,
- &Scumm::o_drawBox
- };
-
- return opcode_list[i];
-}
-
-
void Scumm::executeScript() {
OpcodeProc op;
while (_currentScript != 0xFF) {
_opcode = fetchScriptByte();
_scriptPointerStart = _scriptPointer;
vm.slot[_currentScript].didexec = 1;
- debug(9, "%X", _opcode);
+// debug(1, "%X", _opcode);
op = getOpcode(_opcode);
(this->*op)();
}
- checkHeap();
+ CHECK_HEAP
}
byte Scumm::fetchScriptByte() {
@@ -639,18 +313,33 @@ void Scumm::ignoreScriptByte() {
fetchScriptByte();
}
-int Scumm::getVarOrDirectWord(byte mask) {
- if (_opcode&mask)
- return readVar(fetchScriptWord());
- return (int16)fetchScriptWord();
-}
-int Scumm::getVarOrDirectByte(byte mask) {
- if (_opcode&mask)
- return readVar(fetchScriptWord());
- return fetchScriptByte();
+#if defined(DOTT)
+int Scumm::readVar(uint var) {
+ int a;
+
+ if (!(var&0xF000)) {
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(r)");
+ return _vars[var];
+ }
+
+ if (var&0x8000) {
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(r)");
+ return (_bitVars[var>>3] & (1<<(var&7))) ? 1 : 0;
+ }
+
+ if (var&0x4000) {
+ var &= 0xFFF;
+ checkRange(0x10, 0, var, "Local variable %d out of range(r)");
+ return vm.localvar[_currentScript * 17 + var];
+ }
+
+ error("Illegal varbits (r)");
}
+#else
+
int Scumm::readVar(uint var) {
int a;
#ifdef BYPASS_COPY_PROT
@@ -658,8 +347,8 @@ int Scumm::readVar(uint var) {
#endif
debug(9, "readvar=%d", var);
if (!(var&0xF000)) {
- checkRange(0x31F, 0, var, "Variable %d out of range(r)");
- return vm.vars[var];
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(r)");
+ return _vars[var];
}
if (var&0x2000) {
@@ -671,12 +360,12 @@ int Scumm::readVar(uint var) {
}
if (!(var&0xF000))
- return vm.vars[var];
+ return _vars[var];
if (var&0x8000) {
- var &= 0xFFF;
- checkRange(0x7FF, 0, var, "Bit variable %d out of range(r)");
- return (vm.bitvars[var>>3] & (1<<(var&7))) ? 1 : 0;
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(r)");
+ return (_bitVars[var>>3] & (1<<(var&7))) ? 1 : 0;
}
if (var&0x4000) {
@@ -695,44 +384,24 @@ int Scumm::readVar(uint var) {
error("Illegal varbits (r)");
}
-void Scumm::getResultPos() {
- int a;
-
- _resultVarNumber = fetchScriptWord();
- if (_resultVarNumber&0x2000) {
- a = fetchScriptWord();
- if (a&0x2000) {
- _resultVarNumber += readVar(a&~0x2000);
- } else {
- _resultVarNumber += a&0xFFF;
- }
- _resultVarNumber&=~0x2000;
- }
-
- debug(9, "getResultPos=%d", _resultVarNumber);
-}
+#endif
-void Scumm::setResult(int value) {
- int var = _resultVarNumber;
- debug(9, "setResult %d,%d", var,value);
+void Scumm::writeVar(uint var, int value) {
+ int a;
if (!(var&0xF000)) {
- checkRange(0x31F, 0, var, "Variable %d out of range(w)");
- vm.vars[var] = value;
-
- if (var==518) {
- printf("The answer is %d\n", value);
- }
+ checkRange(_numVariables-1, 0, var, "Variable %d out of range(w)");
+ _vars[var] = value;
return;
}
- if(var&0x8000) {
- var&=0xFFF;
- checkRange(0x7FF, 0, var, "Bit variable %d out of range(w)");
+ if (var&0x8000) {
+ var &= 0x7FFF;
+ checkRange(_numBitVariables-1, 0, var, "Bit variable %d out of range(w)");
if (value)
- vm.bitvars[var>>3] |= (1<<(var&7));
+ _bitVars[var>>3] |= (1<<(var&7));
else
- vm.bitvars[var>>3] &= ~(1<<(var&7));
+ _bitVars[var>>3] &= ~(1<<(var&7));
return;
}
@@ -742,410 +411,29 @@ void Scumm::setResult(int value) {
vm.localvar[_currentScript * 17 + var] = value;
return;
}
- error("Illegal varbits (w)");
-}
-
-void Scumm::o_actorFollowCamera() {
- int a = camera._follows;
-
- setCameraFollows(derefActorSafe(getVarOrDirectByte(0x80), "actorFollowCamera"));
-
- if (camera._follows != a)
- runHook(0);
-
- camera._movingToActor = 0;
-}
-
-void Scumm::o_actorFromPos() {
- int x,y;
- getResultPos();
- x = getVarOrDirectWord(0x80);
- y = getVarOrDirectWord(0x40);
- setResult(getActorFromPos(x,y));
-}
-
-void Scumm::o_actorSet() {
- int act = getVarOrDirectByte(0x80);
- Actor *a = derefActorSafe(act, "actorSet");
- int i,j;
-
- while ( (_opcode = fetchScriptByte()) != 0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* costume */
- setActorCostume(a, getVarOrDirectByte(0x80));
- break;
- case 2: /* walkspeed */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- setActorWalkSpeed(a, i, j);
- break;
- case 3: /* sound */
- a->sound = getVarOrDirectByte(0x80);
- break;
- case 4: /* walkanim */
- a->walkFrame = getVarOrDirectByte(0x80);
- break;
- case 5: /* talkanim */
- a->talkFrame1 = getVarOrDirectByte(0x80);
- a->talkFrame2 = getVarOrDirectByte(0x40);
- break;
- case 6: /* standanim */
- a->standFrame = getVarOrDirectByte(0x80);
- break;
- case 7: /* ignore */
- getVarOrDirectByte(0x80);
- getVarOrDirectByte(0x40);
- getVarOrDirectByte(0x20);
- break;
- case 8: /* init */
- initActor(a, 0);
- break;
- case 9: /* elevation */
- a->elevation = getVarOrDirectWord(0x80);
- a->needRedraw = true;
- a->needBgReset = true;
- break;
- case 10: /* defaultanims */
- a->initFrame = 1;
- a->walkFrame = 2;
- a->standFrame = 3;
- a->talkFrame1 = 4;
- a->talkFrame2 = 4;
- break;
- case 11: /* palette */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- checkRange(32, 0, i, "Illegal palet slot %d");
- a->palette[i] = j;
- a->needRedraw = 1;
- break;
- case 12: /* talk color */
- a->talkColor = getVarOrDirectByte(0x80);
- break;
- case 13: /* name */
- loadPtrToResource(9, a->number, NULL);
- break;
- case 14: /* initanim */
- a->initFrame = getVarOrDirectByte(0x80);
- break;
- case 15: /* unk */
- error("o_actorset:unk not implemented");
- break;
- case 16: /* width */
- a->width = getVarOrDirectByte(0x80);
- break;
- case 17: /* scale */
- a->scalex = getVarOrDirectByte(0x80);
- a->scaley = getVarOrDirectByte(0x40);
- break;
- case 18: /* neverzclip */
- a->neverZClip = 0;
- break;
- case 19: /* setzclip */
- a->neverZClip = getVarOrDirectByte(0x80);
- break;
- case 20: /* ignoreboxes */
- a->ignoreBoxes = 1;
- a->neverZClip = 0;
-FixRoom:
- if (a->room==_currentRoom)
- putActor(a, a->x, a->y, a->room);
- break;
- case 21: /* followboxes */
- a->ignoreBoxes = 0;
- a->neverZClip = 0;
- goto FixRoom;
-
- case 22: /* animspeed */
- a->animSpeed = getVarOrDirectByte(0x80);
- break;
- case 23: /* unk2 */
- a->data8 = getVarOrDirectByte(0x80); /* unused */
- break;
- default:
- error("o_actorSet: default case");
- }
- }
-}
-
-void Scumm::o_actorSetClass() {
- int act = getVarOrDirectWord(0x80);
- int i;
- while ( (_opcode=fetchScriptByte()) != 0xFF) {
- i = getVarOrDirectWord(0x80);
- if (i==0) {
- _classData[act] = 0;
- continue;
- }
- if (i&0x80)
- putClass(act, i, 1);
- else
- putClass(act, i, 0);
- }
-}
-
-void Scumm::o_add() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) + a);
+ error("Illegal varbits (w)");
}
-void Scumm::o_and() {
+void Scumm::getResultPos() {
int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) & a);
-}
-
-void Scumm::o_animateActor() {
- int anim,shr,dir;
- bool inRoom;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "animateActor");
- anim = getVarOrDirectByte(0x40);
-
- shr = anim>>2;
- dir = anim&3;
-
- inRoom = (a->room == _currentRoom);
-
- if (shr == 0x3F) {
- if (inRoom) {
- startAnimActor(a, a->standFrame, a->facing);
- a->moving = 0;
- }
- return;
- }
-
- if (shr == 0x3E) {
- if (inRoom) {
- startAnimActor(a, 0x3E, dir);
- a->moving &= ~4;
- }
- a->facing = dir;
- return;
- }
- if (shr == 0x3D) {
- if (inRoom) {
- turnToDirection(a, dir);
+ _resultVarNumber = fetchScriptWord();
+ if (_resultVarNumber&0x2000) {
+ a = fetchScriptWord();
+ if (a&0x2000) {
+ _resultVarNumber += readVar(a&~0x2000);
} else {
- a->facing = dir;
- }
- return;
- }
-
- startAnimActor(a, anim, a->facing);
-}
-
-void Scumm::o_badOpcode() {
- error("Scumm opcode %d illegal", _opcode);
-}
-
-void Scumm::o_breakHere() {
- updateScriptPtr();
- _currentScript = 0xFF;
-}
-
-void Scumm::o_chainScript() {
- int16 vars[16];
- int data;
- int cur;
-
- data = getVarOrDirectByte(0x80);
-
- getWordVararg(vars);
-
- cur = _currentScript;
-
- if (vm.slot[cur].cutsceneOverride != 0) {
- error("Script %d chaining with active cutscene/override");
- }
-
- vm.slot[cur].number = 0;
- vm.slot[cur].status = 0;
- _currentScript = 0xFF;
-
- runScript(data, vm.slot[cur].unk1, vm.slot[cur].unk2, vars);
-}
-
-void Scumm::o_cursorCommand() {
- int i,j,k;
- int16 table[16];
-
- switch((_opcode=fetchScriptByte())&0x1F) {
- case 1: /* cursor show */
- _cursorState = 1;
- verbMouseOver(0);
- break;
- case 2: /* cursor hide */
- _cursorState = 0;
- verbMouseOver(0);
- break;
- case 3: /* userput on */
- _userPut = 1;
- break;
- case 4: /* userput off */
- _userPut = 0;
- break;
- case 5: /* cursor soft on */
- _cursorState++;
- if (_cursorState > 1) {
- error("Cursor state greater than 1 in script");
+ _resultVarNumber += a&0xFFF;
}
- break;
- case 6: /* cursor soft off */
- _cursorState--;
- break;
- case 7: /* userput soft on */
- _userPut++;
- break;
- case 8: /* userput soft off */
- _userPut--;
- break;
- case 10: /* set cursor img */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- setCursorImg(i, j);
- break;
- case 11: /* set cursor hotspot */
- i = getVarOrDirectByte(0x80);
- j = getVarOrDirectByte(0x40);
- k = getVarOrDirectByte(0x20);
- setCursorHotspot(i, j, k);
- break;
-
- case 12: /* init cursor */
- setCursor(getVarOrDirectByte(0x80));
- break;
- case 13: /* init charset */
- initCharset(getVarOrDirectByte(0x80));
- break;
- case 14: /* unk */
- getWordVararg(table);
- for (i=0; i<16; i++)
- charset._colorMap[i] = _charsetData[textslot.charset[1]][i] = table[i];
- break;
+ _resultVarNumber&=~0x2000;
}
- vm.vars[VAR_CURSORSTATE] = _cursorState;
- vm.vars[VAR_USERPUT] = _userPut;
-}
-
-void Scumm::o_cutscene() {
- int scr = _currentScript;
-
- getWordVararg(_vararg_temp_pos);
-
- vm.slot[scr].cutsceneOverride++;
-
- if (++vm.cutSceneStackPointer > 5)
- error("Cutscene stack overflow");
-
- vm.cutSceneData[vm.cutSceneStackPointer] = _vararg_temp_pos[0];
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
-
- vm.cutSceneScriptIndex = scr;
- if (vm.vars[VAR_CUTSCENE_START_SCRIPT])
- runScript(vm.vars[VAR_CUTSCENE_START_SCRIPT], 0, 0, _vararg_temp_pos);
- vm.cutSceneScriptIndex = 0xFF;
-}
-
-void Scumm::o_endCutscene() {
- ScriptSlot *ss = &vm.slot[_currentScript];
- uint32 *csptr;
-
- ss->cutsceneOverride--;
-
- _vararg_temp_pos[0] = vm.cutSceneData[vm.cutSceneStackPointer];
- vm.vars[VAR_OVERRIDE] = 0;
-
- csptr = &vm.cutScenePtr[vm.cutSceneStackPointer];
- if (*csptr)
- ss->cutsceneOverride--;
-
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- *csptr = 0;
- vm.cutSceneStackPointer--;
-
- if (vm.vars[VAR_CUTSCENE_END_SCRIPT])
- runScript(vm.vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, _vararg_temp_pos);
-}
-
-
-void Scumm::o_debug() {
- getVarOrDirectWord(0x80);
-}
-
-void Scumm::o_decrement() {
- getResultPos();
- setResult(readVar(_resultVarNumber)-1);
-}
-
-void Scumm::o_delay() {
- int delay = fetchScriptByte();
- delay |= fetchScriptByte()<<8;
- delay |= fetchScriptByte()<<16;
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = 1;
- o_breakHere();
-}
-
-void Scumm::o_delayVariable() {
- vm.slot[_currentScript].delay = readVar(fetchScriptWord());
- vm.slot[_currentScript].status = 1;
- o_breakHere();
-}
-
-void Scumm::o_divide() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- if(a==0) {
- error("Divide by zero");
- setResult(0);
- } else
- setResult(readVar(_resultVarNumber) / a);
-}
-
-void Scumm::o_doSentence() {
- int a,b;
- _sentenceIndex++;
-
- a = getVarOrDirectByte(0x80);
- if (a==0xFE) {
- _sentenceIndex = 0xFF;
- stopScriptNr(vm.vars[VAR_SENTENCE_SCRIPT]);
- clearClickedStatus();
- return;
- }
- _sentenceTab5[_sentenceIndex] = a;
- _sentenceTab4[_sentenceIndex] = getVarOrDirectWord(0x40);
- b = _sentenceTab3[_sentenceIndex] = getVarOrDirectWord(0x20);
- if (b==0) {
- _sentenceTab2[_sentenceIndex] = 0;
- } else {
- _sentenceTab2[_sentenceIndex] = 1;
- }
- _sentenceTab[_sentenceIndex] = 0;
+ debug(9, "getResultPos=%d", _resultVarNumber);
}
-void Scumm::o_drawBox() {
- int x,y,x2,y2,color;
-
- x = getVarOrDirectWord(0x80);
- y = getVarOrDirectWord(0x40);
-
- _opcode = fetchScriptByte();
- x2 = getVarOrDirectWord(0x80);
- y2 = getVarOrDirectWord(0x40);
- color = getVarOrDirectByte(0x20);
-
- drawBox(x, y, x2, y2, color);
+void Scumm::setResult(int value) {
+ writeVar(_resultVarNumber, value);
}
void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
@@ -1186,1314 +474,6 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {
}
}
-void Scumm::o_drawObject() {
- int state,obj,index,i;
- ObjectData *od;
- byte x,y,w,h;
-
- state = 1;
- _xPos = _yPos = 255;
- obj = getVarOrDirectWord(0x80);
-
- switch((_opcode = fetchScriptByte())&0x1F) {
- case 1: /* draw at */
- _xPos = getVarOrDirectWord(0x80);
- _yPos = getVarOrDirectWord(0x40);
- break;
- case 2: /* set state */
- state = getVarOrDirectWord(0x80);
- break;
- case 0x1F: /* neither */
- break;
- default:
- error("o_drawObject: default case");
- }
- index = getObjectIndex(obj);
- if (index==-1)
- return;
- od = &objs[index];
- if (_xPos!=0xFF) {
- od->cdhd_10 += (_xPos - od->x_pos)<<3;
- od->x_pos = _xPos;
- od->cdhd_12 += (_yPos - od->y_pos)<<3;
- od->y_pos = _yPos;
- }
- addObjectToDrawQue(index);
-
- x = od->x_pos;
- y = od->y_pos;
- w = od->numstrips;
- h = od->height;
-
- i = _numObjectsInRoom;
- do {
- if (objs[i].x_pos == x && objs[i].y_pos == y
- && objs[i].numstrips == w && objs[i].height==h)
- putState(objs[i].obj_nr, 0);
- } while (--i);
-
- putState(obj, state);
-}
-
-void Scumm::o_dummy() {
- /* nothing */
-}
-
-
-void Scumm::o_expression() {
- int dst, i;
-
- _scummStackPos = 0;
- getResultPos();
- dst = _resultVarNumber;
-
- while ((_opcode = fetchScriptByte())!=0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* varordirect */
- stackPush(getVarOrDirectWord(0x80));
- break;
- case 2: /* add */
- i = stackPop();
- stackPush(i + stackPop());
- break;
- case 3: /* sub */
- i = stackPop();
- stackPush(stackPop() - i);
- break;
- case 4: /* mul */
- i = stackPop();
- stackPush(i * stackPop());
- break;
- case 5: /* div */
- i = stackPop();
- if (i==0)
- error("Divide by zero");
- stackPush(stackPop() / i);
- break;
- case 6: /* normal opcode */
- _opcode = fetchScriptByte();
- (this->*(getOpcode(_opcode)))();
- stackPush(vm.vars[0]);
- break;
- }
- }
-
- _resultVarNumber = dst;
- setResult(stackPop());
-}
-
-void Scumm::o_faceActor() {
- int act, obj;
- int x;
- byte dir;
-
- act = getVarOrDirectByte(0x80);
- obj = getVarOrDirectWord(0x40);
-
- if (getObjectOrActorXY(act)==-1)
- return;
-
- x = _xPos;
-
- if (getObjectOrActorXY(obj)==-1)
- return;
-
- dir = (_xPos > x) ? 1 : 0;
- turnToDirection(derefActorSafe(act, "o_faceActor"), dir);
-}
-
-void Scumm::o_findInventory() {
- int owner, b, count, i, obj;
-
- getResultPos();
- owner = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- count = 1;
- for (i=0; i!=_maxInventoryItems; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj)==owner && count++ == b) {
- setResult(obj);
- return;
- }
- }
- setResult(0);
-}
-
-void Scumm::o_findObject() {
- int t;
- getResultPos();
- t = getVarOrDirectWord(0x80);
- setResult(findObject(t, getVarOrDirectWord(0x40)));
-}
-
-void Scumm::o_freezeScripts() {
- int scr = getVarOrDirectByte(0x80);
-
- if (scr!=0)
- freezeScripts(scr);
- else
- unfreezeScripts();
-}
-
-void Scumm::o_getActorCostume() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorCostume")->costume);
-}
-
-void Scumm::o_getActorElevation() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorElevation")->elevation);
-}
-
-void Scumm::o_getActorFacing() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorFacing")->facing);
-}
-
-void Scumm::o_getActorMoving() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorMoving")->moving);
-}
-
-void Scumm::o_getActorRoom() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorRoom")->room);
-}
-
-void Scumm::o_getActorScale() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorScale")->scalex);
-}
-
-void Scumm::o_getActorWalkBox() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWalkbox")->walkbox);
-}
-
-void Scumm::o_getActorWidth() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWidth")->width);
-}
-
-void Scumm::o_getActorX() {
- int index;
- getResultPos();
- index = getVarOrDirectWord(0x80);
- if (index <= vm.vars[VAR_NUM_ACTOR]) {
- setResult(derefActorSafe(index,"o_getActorX")->x);
- } else {
- if (whereIsObject(index)==-1)
- setResult(-1);
- else {
- getObjectOrActorXY(index);
- setResult(_xPos);
- }
- }
-}
-
-void Scumm::o_getActorY() {
- int index;
- getResultPos();
- index = getVarOrDirectWord(0x80);
- if (index <= vm.vars[VAR_NUM_ACTOR]) {
- setResult(derefActorSafe(index,"o_getActorY")->y);
- } else {
- if (whereIsObject(index)==-1)
- setResult(-1);
- else {
- getObjectOrActorXY(index);
- setResult(_yPos);
- }
- }
-}
-
-void Scumm::o_getAnimCounter() {
- getResultPos();
- setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorAnimCounter")->cost.animCounter1);
-}
-
-void Scumm::o_getClosestObjActor() {
- int obj;
- int act;
- int closobj=-1, closnum=-1;
- int dist;
-
- getResultPos();
-
- act = getVarOrDirectWord(0x80);
- obj = vm.vars[VAR_OBJECT_HI];
-
- do {
- dist = getObjActToObjActDist(obj,act);
- if (dist < closnum) {
- closnum = dist;
- closobj = obj;
- }
- } while (--obj >= vm.vars[VAR_OBJECT_LO]);
-
- setResult(closnum);
-}
-
-void Scumm::o_getDist() {
- int o1,o2;
- getResultPos();
- o1 = getVarOrDirectWord(0x80);
- o2 = getVarOrDirectWord(0x40);
- setResult(getObjActToObjActDist(o1,o2));
-}
-
-void Scumm::o_getInventoryCount() {
- int owner, count, i, obj;
-
- getResultPos();
-
- owner = getVarOrDirectByte(0x80);
- count = 0;
- for (i=0; i!=_maxInventoryItems; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj)==owner)
- count++;
- }
- setResult(count);
-}
-
-void Scumm::o_getObjectOwner() {
- getResultPos();
- setResult(getOwner(getVarOrDirectWord(0x80)));
-}
-
-void Scumm::o_getObjectState() {
- getResultPos();
- setResult(getState(getVarOrDirectWord(0x80)));
-}
-
-void Scumm::o_getRandomNr() {
- getResultPos();
- setResult(getRandomNumber(getVarOrDirectByte(0x80)));
-}
-
-void Scumm::o_getScriptRunning() {
- int i;
- ScriptSlot *ss;
- int script;
-
- getResultPos();
- script = getVarOrDirectByte(0x80);
-
- ss = vm.slot;
- for (i=0; i<20; i++,ss++) {
- if (ss->number==script && (ss->type==2 || ss->type==3) && ss->status) {
- setResult(1);
- return;
- }
- }
- setResult(0);
-}
-
-void Scumm::o_getVerbEntrypoint() {
- int a,b;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- setResult(getVerbEntrypoint(a, b));
-}
-
-void Scumm::o_ifClassOfIs() {
- int act,cls;
- bool cond = true, b;
-
- act = getVarOrDirectWord(0x80);
- while ( (_opcode = fetchScriptByte()) != 0xFF) {
- cls = getVarOrDirectWord(0x80);
- b = getClass(act, cls);
-
- if (cls&0x80 && !b)
- cond = false;
- if (!(cls&0x80) && b)
- cond = false;
- }
- if (cond)
- ignoreScriptWord();
- else
- o_jumpRelative();
-}
-
-void Scumm::o_increment() {
- getResultPos();
- setResult(readVar(_resultVarNumber)+1);
-}
-
-void Scumm::o_isActorInBox() {
- int box;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_isActorInBox");
- box = getVarOrDirectByte(0x40);
-
- if (!checkXYInBoxBounds(box, a->x, a->y))
- o_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void Scumm::o_isEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b == a) ignoreScriptWord();
- else o_jumpRelative();
-
-}
-
-void Scumm::o_isGreater() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b > a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isGreaterEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b >= a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isLess() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b < a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_lessOrEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b <= a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isNotEqual() {
- int16 a = readVar(fetchScriptWord());
- int16 b = getVarOrDirectWord(0x80);
- if (b != a) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_notEqualZero() {
- int a = readVar(fetchScriptWord());
- if (a != 0) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_equalZero() {
- int a = readVar(fetchScriptWord());
- if (a == 0) ignoreScriptWord();
- else o_jumpRelative();
-}
-
-void Scumm::o_isSoundRunning() {
- int snd;
- getResultPos();
- snd = getVarOrDirectByte(0x80);
- if (snd)
- setResult(unkSoundProc23(snd));
- else
- setResult(0);
-}
-
-void Scumm::o_jumpRelative() {
- _scriptPointer += (int16)fetchScriptWord();
-}
-
-void Scumm::o_lights() {
- int a,b,c;
-
- a = getVarOrDirectByte(0x80);
- b = fetchScriptByte();
- c = fetchScriptByte();
- if (c==0)
- vm.vars[VAR_DRAWFLAGS] = a;
- else if (c==1) {
- _lightsValueA = a;
- _lightsValueB = b;
- }
- _fullRedraw=1;
-}
-
-void Scumm::o_loadRoom() {
- int room = getVarOrDirectByte(0x80);
- debug(1,"Loading room %d", room);
- startScene(room, 0, 0);
- _fullRedraw = 1;
-}
-
-void Scumm::o_loadRoomWithEgo() {
- int obj, room, x,y;
- Actor *a;
-
- obj = getVarOrDirectWord(0x80);
- room = getVarOrDirectByte(0x40);
-
- a = derefActorSafe(vm.vars[VAR_UNK_ACTOR], "o_loadRoomWithEgo");
-
- /* Warning: uses _xPos, _yPos from a previous update of those */
- putActor(a, _xPos, _yPos, room);
-
- x = (int16)fetchScriptWord();
- y = (int16)fetchScriptWord();
-
- dseg_3A76 = 0;
-
- vm.vars[VAR_WALKTO_OBJ] = obj;
-
- startScene(a->room, a, obj);
-
- vm.vars[VAR_WALKTO_OBJ] = 0;
- camera._destPos = camera._curPos = a->x;
- setCameraFollows(a);
- _fullRedraw=1;
-
- if (x != -1) {
- startWalkActor(a, x, y, 0xFF);
- }
-}
-
-void Scumm::o_matrixOps() {
- int a,b;
-
- _opcode = fetchScriptByte();
- switch(_opcode & 0x1F) {
- case 1:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxFlags(a,b);
- break;
- case 2:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxScale(a,b);
- break;
- case 3:
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- setBoxScale(a,(b-1)|0x8000);
- break;
- case 4:
- createBoxMatrix();
- break;
- }
-}
-
-void Scumm::o_move() {
- getResultPos();
- setResult(getVarOrDirectWord(0x80));
-}
-
-void Scumm::o_multiply() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) * a);
-}
-
-
-void Scumm::o_or() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) | a);
-}
-
-void Scumm::o_overRide() {
- byte b;
- int index;
- uint32 *ptr;
-
- b = fetchScriptByte();
- if(b!=0) {
- index = vm.cutSceneStackPointer;
- ptr = &vm.cutScenePtr[index];
- if (!*ptr) {
- vm.slot[_currentScript].cutsceneOverride++;
- }
- *ptr = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[index] = _currentScript;
-
- ignoreScriptByte();
- ignoreScriptWord();
- } else {
- index = vm.cutSceneStackPointer;
- ptr = &vm.cutScenePtr[index];
- if (*ptr) {
- vm.slot[_currentScript].cutsceneOverride--;
- }
- *ptr = 0;
- vm.cutSceneScript[index] = 0;
- }
- vm.vars[VAR_OVERRIDE] = 0;
-}
-
-void Scumm::o_panCameraTo() {
- CameraData *cd = &camera;
- cd->_destPos = getVarOrDirectWord(0x80);
- cd->_mode = 3;
- cd->_movingToActor = 0;
-}
-
-void Scumm::o_pickupObject() {
- int obj, room;
-
- obj = getVarOrDirectWord(0x80);
- room = getVarOrDirectByte(0x40);
- if (room==0)
- room = _roomResource;
- addObjectToInventory(obj, room);
- putOwner(obj, vm.vars[VAR_UNK_ACTOR]);
- putClass(obj, 32, 1);
- putState(obj, 1);
- removeObjectFromRoom(obj);
- clearDrawObjectQueue();
- runHook(1);
-}
-
-void Scumm::o_print() {
- _actorToPrintStrFor = getVarOrDirectByte(0x80);
- decodeParseString();
-}
-
-void Scumm::o_printEgo() {
- _actorToPrintStrFor = vm.vars[VAR_UNK_ACTOR];
- decodeParseString();
-}
-
-void Scumm::o_pseudoRoom() {
- int i = fetchScriptByte(), j;
- while ((j = fetchScriptByte()) != 0) {
- if (j >= 0x80) {
- _resourceMapper[j&0x7F] = i;
- }
- }
-}
-
-void Scumm::o_putActor() {
- int x,y;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActor");
- x = getVarOrDirectWord(0x40);
- y = getVarOrDirectWord(0x20);
-
- putActor(a, x, y, a->room);
-}
-
-
-void Scumm::o_putActorAtObject() {
- int obj;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorAtObject");
- obj = getVarOrDirectWord(0x40);
- if (whereIsObject(obj)!=-1)
- getObjectXYPos(obj);
- else {
- _xPos = 240;
- _yPos = 120;
- }
- putActor(a, _xPos, _yPos, a->room);
-}
-
-void Scumm::o_putActorInRoom() {
- int room;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorInRoom");
- room = getVarOrDirectByte(0x40);
- if (a->visible && _currentRoom!=room && vm.vars[VAR_TALK_ACTOR]==a->number) {
- clearMsgQueue();
- }
- a->room = room;
- if (!room)
- putActor(a, 0, 0, 0);
-}
-
-void Scumm::o_quitPauseRestart() {
- switch(fetchScriptByte()) {
- case 1:
- pauseGame(0);
- break;
- case 3:
- shutDown(0);
- break;
- }
-}
-
-void Scumm::o_resourceRoutines() {
- int res;
-
- _opcode = fetchScriptByte();
- if (_opcode != 17)
- res = getVarOrDirectByte(0x80);
- switch(_opcode&0x1F) {
- case 1: /* load script */
- ensureResourceLoaded(2, res);
- break;
- case 2: /* load sound */
- ensureResourceLoaded(4, res);
- break;
- case 3: /* load costume */
- ensureResourceLoaded(3, res);
- break;
- case 4: /* load room */
- ensureResourceLoaded(1, res);
- break;
- case 5: /* nuke script */
- setResourceFlags(2, res, 0x7F);
- break;
- case 6: /* nuke sound */
- setResourceFlags(4, res, 0x7F);
- break;
- case 7: /* nuke costume */
- setResourceFlags(3, res, 0x7F);
- break;
- case 8: /* nuke room */
- setResourceFlags(1, res, 0x7F);
- break;
- case 9: /* lock script */
- if (res >= _numGlobalScriptsUsed)
- break;
- lock(2,res);
- break;
- case 10:/* lock sound */
- lock(4,res);
- break;
- case 11:/* lock costume */
- lock(3,res);
- break;
- case 12:/* lock room */
- if (res > 0x7F)
- res = _resourceMapper[res&0x7F];
- lock(1,res);
- break;
- case 13:/* unlock script */
- if (res >= _numGlobalScriptsUsed)
- break;
- unlock(2,res);
- break;
- case 14:/* unlock sound */
- unlock(4,res);
- break;
- case 15:/* unlock costume */
- unlock(3,res);
- break;
- case 16:/* unlock room */
- if (res > 0x7F)
- res = _resourceMapper[res&0x7F];
- unlock(1,res);
- break;
- case 17:/* clear heap */
- heapClear(0);
- unkHeapProc2(0,0);
- break;
- case 18:/* load charset */
- loadCharset(res);
- break;
- case 19:/* nuke charset */
- nukeCharset(res);
- break;
- case 20:/* ? */
- unkResProc(getVarOrDirectWord(0x40), res);
- break;
- }
-}
-
-void Scumm::o_roomOps() {
- int a,b,c,d,e;
-
- _opcode = fetchScriptByte();
-
- switch(_opcode & 0x1F) {
- case 1: /* room scroll */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- if (a < 160) a=160;
- if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
- if (b < 160) b=160;
- if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
- vm.vars[VAR_CAMERA_MIN] = a;
- vm.vars[VAR_CAMERA_MAX] = b;
- break;
- case 2: /* room color */
- error("room-color is no longer a valid command");
- break;
-
- case 3: /* set screen */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- initScreens(0,a,320,b);
- break;
- case 4: /* set palette color */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- setPalColor(d, a, b, c); /* index, r, g, b */
- break;
- case 5: /* shake on */
- setShake(1);
- break;
- case 6: /* shake off */
- setShake(0);
- break;
- case 8: /* room scale? */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- c = getVarOrDirectByte(0x20);
- unkRoomFunc2(b, c, a, a, a);
- break;
- case 9: /* ? */
- _saveLoadFlag = getVarOrDirectByte(0x80);
- _saveLoadData = getVarOrDirectByte(0x40);
- _saveLoadData = 0; /* TODO: weird behaviour */
- break;
- case 10: /* ? */
- a = getVarOrDirectWord(0x80);
- if (a) {
- _switchRoomEffect = (byte)(a);
- _switchRoomEffect2 = (byte)(a>>8);
- } else {
- screenEffect(_newEffect);
- }
- break;
- case 11: /* ? */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- e = getVarOrDirectByte(0x40);
- unkRoomFunc2(d, e, a, b, c);
- break;
- case 12: /* ? */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- e = getVarOrDirectByte(0x40);
- unkRoomFunc3(d, e, a, b, c);
- break;
-
- case 13: /* ? */
- error("roomops:13 not implemented");
- break;
- case 14: /* ? */
- error("roomops:14 not implemented");
- break;
- case 15: /* palmanip? */
- a = getVarOrDirectByte(0x80);
- _opcode = fetchScriptByte();
- b = getVarOrDirectByte(0x80);
- c = getVarOrDirectByte(0x40);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- unkRoomFunc4(b, c, a, d, 1);
- break;
-
- case 16: /* ? */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- if (b!=0)
- _colorCycleDelays[a] = 0x4000 / (b*0x4C);
- else
- _colorCycleDelays[a] = 0;
- break;
- }
-}
-
-void Scumm::o_saveRestoreVerbs() {
- int a,b,c,slot, slot2;
-
- _opcode = fetchScriptByte();
-
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- c = getVarOrDirectByte(0x20);
-
- switch(_opcode) {
- case 1: /* hide verbs */
- while (a<=b) {
- slot = getVerbSlot(a,0);
- if (slot && verbs[slot].saveid==0) {
- verbs[slot].saveid = c;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 2: /* show verbs */
- while (a<=b) {
- slot = getVerbSlot(a, c);
- if (slot) {
- slot2 = getVerbSlot(a,0);
- if (slot2)
- killVerb(slot2);
- slot = getVerbSlot(a,c);
- verbs[slot].saveid = 0;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 3: /* kill verbs */
- while (a<=b) {
- slot = getVerbSlot(a,c);
- if (slot)
- killVerb(slot);
- a++;
- }
- break;
- default:
- error("o_saveRestoreVerbs: invalid opcode");
- }
-}
-
-void Scumm::o_setCameraAt() {
- CameraData *cd = &camera;
- cd->_curPos = getVarOrDirectWord(0x80);
- cd->_mode = 1;
- setCameraAt(cd->_curPos);
- cd->_movingToActor = 0;
-}
-
-void Scumm::o_setObjectName() {
- int act = getVarOrDirectWord(0x80);
- int size;
- int a;
- int i;
-
- if (vm.vars[VAR_NUM_ACTOR] >= act)
- error("Can't set actor %d name with new-name-of", act);
-
- if (!getObjectAddress(act))
- error("Can't set name of object %d", act);
-
- size = READ_BE_UINT32_UNALIGNED(getObjOrActorName(act) - 4)-9;
- i = 0;
-
- while ((a = fetchScriptByte()) != 0) {
- getObjOrActorName(act)[i++] = a;
-
- if (a==0xFF) {
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
- }
-
- if (i > size)
- error("New name of object %d too long", act);
- }
-
- getObjOrActorName(act)[i] = 0;
- runHook(0);
-}
-
-void Scumm::o_setOwnerOf() {
- int obj, owner;
- ScriptSlot *ss;
-
- obj = getVarOrDirectWord(0x80);
- owner = getVarOrDirectByte(0x40);
-
- if (owner==0) {
- clearOwnerOf(obj);
- ss = &vm.slot[_currentScript];
- if (ss->type==0 && _inventory[ss->number]==obj) {
- putOwner(obj, owner);
- runHook(0);
- stopObjectCode();
- return;
- }
- }
- putOwner(obj, owner);
- runHook(0);
-}
-
-void Scumm::o_setState() {
- int obj, state;
- obj = getVarOrDirectWord(0x80);
- state = getVarOrDirectByte(0x40);
- putState(obj, state);
- removeObjectFromRoom(obj);
- if (_BgNeedsRedraw)
- clearDrawObjectQueue();
-}
-
-void Scumm::o_setVarRange() {
- int a,b;
-
- getResultPos();
- a=fetchScriptByte();
- do {
- if (_opcode&0x80)
- b=fetchScriptWord();
- else
- b=fetchScriptByte();
-
- setResult(b);
- _resultVarNumber++;
- } while (--a);
-}
-
-void Scumm::o_soundKludge() {
- int16 items[15];
- int i;
- int16 *ptr;
-
- for (i=0; i<15; i++)
- items[i] = 0;
-
- getWordVararg(items);
- if (items[0]==-1)
- unkSoundProc22();
- else {
- _soundQue[_soundQuePos++] = 8;
-
- ptr = _soundQue + _soundQuePos;
- _soundQuePos += 8;
-
- for (i=0; i<8; i++)
- *ptr++ = items[i];
- if (_soundQuePos > 0x100)
- error("Sound que buffer overflow");
- }
-}
-
-void Scumm::o_startMusic() {
- addSoundToQueue(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_startObject() {
- int obj, script;
- int16 data[16];
-
- obj = getVarOrDirectWord(0x80);
- script = getVarOrDirectByte(0x40);
-
- getWordVararg(data);
- runVERBCode(obj, script, 0, 0, data);
-}
-
-void Scumm::o_startScript() {
- int op,script;
- int16 data[16];
- int a,b;
-
- op = _opcode;
- script = getVarOrDirectByte(0x80);
-
- getWordVararg(data);
-
- a = b = 0;
- if (op&0x40) b=1;
- if (op&0x20) a=1;
-
- runScript(script, a, b, data);
-}
-
-void Scumm::o_startSound() {
- addSoundToQueue(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_stopMusic() {
- /* TODO: not implemented */
- warning("o_stopMusic: not implemented");
-}
-
-void Scumm::o_stopObjectCode() {
- stopObjectCode();
-}
-
-void Scumm::o_stopObjectScript() {
- stopObjectScript(getVarOrDirectWord(0x80));
-}
-
-void Scumm::o_stopScript() {
- int script;
-
- script = getVarOrDirectByte(0x80);
- if (script==0)
- stopObjectCode();
- else
- stopScriptNr(script);
-}
-
-void Scumm::o_stopSound() {
- unkSoundProc1(getVarOrDirectByte(0x80));
-}
-
-void Scumm::o_stringOps() {
- int a,b,c,i;
- byte *ptr;
-
- _opcode = fetchScriptByte();
- switch(_opcode&0x1F) {
- case 1: /* loadstring */
- loadPtrToResource(7, getVarOrDirectByte(0x80), NULL);
- break;
- case 2: /* copystring */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- nukeResource(7, a);
- ptr = getResourceAddress(7, b);
- if (ptr) loadPtrToResource(7, a, ptr);
- break;
- case 3: /* set string char */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- ptr = getResourceAddress(7, a);
- if (ptr==NULL) error("String %d does not exist", a);
- c = getVarOrDirectByte(0x20);
- ptr[b] = c;
- break;
-
- case 4: /* get string char */
- getResultPos();
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- ptr = getResourceAddress(7, a);
- if (ptr==NULL) error("String %d does not exist", a);
- setResult(ptr[b]);
- break;
-
- case 5: /* create empty string */
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- nukeResource(7, a);
- if (b) {
- ptr = createResource(7, a, b);
- if (ptr) {
- for(i=0; i<b; i++)
- ptr[i] = 0;
- }
- }
- break;
- }
-}
-
-void Scumm::o_subtract() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(0x80);
- setResult(readVar(_resultVarNumber) - a);
-}
-
-void Scumm::o_verbOps() {
- int verb,slot;
- VerbSlot *vs;
- int a,b;
- byte *ptr;
-
- verb = getVarOrDirectByte(0x80);
-
- slot = getVerbSlot(verb,0);
- checkRange(_maxVerbs-1, 0, slot, "Illegal new verb slot %d");
-
- vs = &verbs[slot];
- vs->verbid = verb;
-
- while ((_opcode=fetchScriptByte()) != 0xFF) {
- switch(_opcode&0x1F) {
- case 1: /* load image */
- a = getVarOrDirectWord(0x80);
- if (verb) {
- setVerbObject(_roomResource, a, verb);
- vs->type = 1;
- }
- break;
- case 2: /* load from code */
- loadPtrToResource(8, slot, NULL);
- if (slot==0)
- nukeResource(8, slot);
- vs->type = 0;
- vs->imgindex = 0;
- break;
- case 3: /* color */
- vs->color = getVarOrDirectByte(0x80);
- break;
- case 4: /* set hi color */
- vs->hicolor = getVarOrDirectByte(0x80);
- break;
- case 5: /* set xy */
- vs->x = getVarOrDirectWord(0x80);
- vs->y = getVarOrDirectWord(0x40);
- break;
- case 6: /* set on */
- vs->curmode=1;
- break;
- case 7: /* set off */
- vs->curmode=0;
- break;
- case 8: /* delete */
- killVerb(slot);
- break;
- case 9: /* new */
- slot = getVerbSlot(verb, 0);
- if (slot==0) {
- for (slot=1; slot<_maxVerbs; slot++) {
- if(verbs[slot].verbid==0)
- break;
- }
- if (slot==_maxVerbs)
- error("Too many verbs");
- }
- vs = &verbs[slot];
- vs->verbid = verb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = 0;
- vs->charset_nr = textslot.charset[0];
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
-
- case 16: /* set dim color */
- vs->dimcolor = getVarOrDirectByte(0x80);
- break;
- case 17: /* dim */
- vs->curmode = 2;
- break;
- case 18: /* set key */
- vs->key = getVarOrDirectByte(0x80);
- break;
- case 19: /* set center */
- vs->center = 1;
- break;
- case 20: /* set to string */
- ptr = getResourceAddress(7, getVarOrDirectWord(0x80));
- if (!ptr)
- nukeResource(8, slot);
- else {
- loadPtrToResource(8, slot, ptr);
- }
- if (slot==0)
- nukeResource(8, slot);
- vs->type = 0;
- vs->imgindex = 0;
- break;
- case 22: /* assign object */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectByte(0x40);
- if (slot && vs->imgindex!=a) {
- setVerbObject(b, a, slot);
- vs->type = 1;
- vs->imgindex = a;
- }
- break;
- case 23: /* set back color */
- vs->bkcolor = getVarOrDirectByte(0x80);
- break;
- }
- }
- drawVerb(slot, 0);
- verbMouseOver(0);
-}
-
-void Scumm::o_wait() {
- byte *oldaddr;
-
- oldaddr = _scriptPointer - 1;
-
- _opcode = fetchScriptByte();
- switch(_opcode&0x1F) {
- case 1: /* wait for actor */
- if (derefActorSafe(getVarOrDirectByte(0x80), "o_wait")->moving)
- break;
- return;
- case 2: /* wait for message */
- if (vm.vars[VAR_HAVE_MSG])
- break;
- return;
- case 3: /* wait for camera */
- if (camera._curPos>>3 != camera._destPos>>3)
- break;
- return;
- case 4: /* wait for sentence */
- if (_sentenceIndex!=0xFF) {
- if (_sentenceTab[_sentenceIndex] &&
- !isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT]) )
- return;
- break;
- }
- if (!isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT]))
- return;
- break;
-
- default:
- return;
- }
-
- _scriptPointer = oldaddr;
- o_breakHere();
-}
-
-void Scumm::o_walkActorTo() {
- int x, y;
- Actor *a;
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorTo");
- x = getVarOrDirectWord(0x40);
- y = getVarOrDirectWord(0x20);
- startWalkActor(a, x, y, 0xFF);
-}
-
-void Scumm::o_walkActorToActor() {
- int b,x,y;
- Actor *a, *a2;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToActor");
- if (a->room != _currentRoom) {
- getVarOrDirectByte(0x40);
- fetchScriptByte();
- return;
- }
-
- a2 = derefActorSafe(getVarOrDirectByte(0x40), "o_walkActorToActor(2)");
- if (a2->room != _currentRoom) {
- fetchScriptByte();
- return;
- }
- b = fetchScriptByte(); /* distance from actor */
- if (b==0xFF) {
- b = a2->scalex * a->width / 0xFF;
- b = b + b/2;
- }
- x = a2->x;
- y = a2->y;
- if (x < a->x)
- x += b;
- else
- x -= b;
-
- startWalkActor(a, x, y, 0xFF);
-}
-
-void Scumm::o_walkActorToObject() {
- int obj;
- Actor *a;
-
- a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToObject");
- obj = getVarOrDirectWord(0x40);
- if (whereIsObject(obj)!=-1) {
- getObjectXYPos(obj);
- startWalkActor(a, _xPos, _yPos, _dir);
- }
-}
void Scumm::stopObjectCode() {
ScriptSlot *ss;
@@ -2501,28 +481,21 @@ void Scumm::stopObjectCode() {
ss = &vm.slot[_currentScript];
if (ss->type!=2 && ss->type!=3) {
- stopObjectScript(ss->number);
+ if (ss->cutsceneOverride)
+ error("Object %d ending with active cutscene/override", ss->number);
+
+ /* I wonder if the removal of this breaks anything.
+ * put ss->number and ss->status at another place if using this
+ * stopObjectScript(ss->number); */
} else {
if (ss->cutsceneOverride)
error("Script %d ending with active cutscene/override", ss->number);
- ss->number = 0;
- ss->status = 0;
}
+ ss->number = 0;
+ ss->status = 0;
_currentScript = 0xFF;
}
-int Scumm::getWordVararg(int16 *ptr) {
- int i;
- for (i=0; i<16; i++)
- ptr[i] = 0;
-
- i = 0;
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- ptr[i++] = getVarOrDirectWord(0x80);
- }
- return i;
-}
-
bool Scumm::isScriptLoaded(int script) {
ScriptSlot *ss;
int i;
@@ -2538,8 +511,8 @@ bool Scumm::isScriptLoaded(int script) {
void Scumm::runHook(int i) {
int16 tmp[16];
tmp[0] = i;
- if (vm.vars[VAR_HOOK_SCRIPT]) {
- runScript(vm.vars[VAR_HOOK_SCRIPT], 0, 0, tmp);
+ if (_vars[VAR_HOOK_SCRIPT]) {
+ runScript(_vars[VAR_HOOK_SCRIPT], 0, 0, tmp);
}
}
@@ -2554,7 +527,7 @@ void Scumm::freezeScripts(int flag) {
}
for (i=0; i<6; i++)
- _sentenceTab[i]++;
+ sentence[i].unk++;
if(vm.cutSceneScriptIndex != 0xFF) {
vm.slot[vm.cutSceneScriptIndex].status&=0x7F;
@@ -2573,8 +546,8 @@ void Scumm::unfreezeScripts() {
}
for (i=0; i<6; i++) {
- if (((int8)--_sentenceTab[i])<0)
- _sentenceTab[i] = 0;
+ if (((int8)--sentence[i].unk)<0)
+ sentence[i].unk = 0;
}
}
@@ -2597,8 +570,8 @@ void Scumm::runAllScripts() {
}
void Scumm::runExitScript() {
- if (vm.vars[VAR_EXIT_SCRIPT])
- runScript(vm.vars[VAR_EXIT_SCRIPT], 0, 0, 0);
+ if (_vars[VAR_EXIT_SCRIPT])
+ runScript(_vars[VAR_EXIT_SCRIPT], 0, 0, 0);
if (_EXCD_offs) {
int slot = getScriptSlot();
vm.slot[slot].status = 2;
@@ -2610,13 +583,13 @@ void Scumm::runExitScript() {
vm.slot[slot].freezeCount = 0;
runScriptNested(slot);
}
- if (vm.vars[VAR_EXIT_SCRIPT2])
- runScript(vm.vars[VAR_EXIT_SCRIPT2], 0, 0, 0);
+ if (_vars[VAR_EXIT_SCRIPT2])
+ runScript(_vars[VAR_EXIT_SCRIPT2], 0, 0, 0);
}
void Scumm::runEntryScript() {
- if (vm.vars[VAR_ENTRY_SCRIPT])
- runScript(vm.vars[VAR_ENTRY_SCRIPT], 0, 0, 0);
+ if (_vars[VAR_ENTRY_SCRIPT])
+ runScript(_vars[VAR_ENTRY_SCRIPT], 0, 0, 0);
if (_ENCD_offs) {
int slot = getScriptSlot();
vm.slot[slot].status = 2;
@@ -2628,8 +601,8 @@ void Scumm::runEntryScript() {
vm.slot[slot].freezeCount = 0;
runScriptNested(slot);
}
- if (vm.vars[VAR_ENTRY_SCRIPT2])
- runScript(vm.vars[VAR_ENTRY_SCRIPT2], 0, 0, 0);
+ if (_vars[VAR_ENTRY_SCRIPT2])
+ runScript(_vars[VAR_ENTRY_SCRIPT2], 0, 0, 0);
}
void Scumm::killScriptsAndResources() {
@@ -2652,8 +625,8 @@ void Scumm::killScriptsAndResources() {
i = 0;
do {
- if (objs[i].fl_object_index)
- nukeResource(0xD, objs[i].fl_object_index);
+ if (_objs[i].fl_object_index)
+ nukeResource(0xD, _objs[i].fl_object_index);
} while (++i <= _numObjectsInRoom);
}
@@ -2662,29 +635,29 @@ void Scumm::checkAndRunVar33() {
ScriptSlot *ss;
memset(_localParamList, 0, sizeof(_localParamList));
- if (isScriptLoaded(vm.vars[VAR_SENTENCE_SCRIPT])) {
+ if (isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) {
ss = vm.slot;
for (i=0; i<20; i++,ss++)
- if (ss->number==vm.vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0)
+ if (ss->number==_vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0)
return;
}
- if (_sentenceIndex > 0x7F || _sentenceTab[_sentenceIndex])
+ if (_sentenceIndex > 0x7F || sentence[_sentenceIndex].unk)
return;
- if (_sentenceTab2[_sentenceIndex] &&
- _sentenceTab3[_sentenceIndex]==_sentenceTab4[_sentenceIndex]) {
+ if (sentence[_sentenceIndex].unk2 &&
+ sentence[_sentenceIndex].unk3==sentence[_sentenceIndex].unk4) {
_sentenceIndex--;
return;
}
- _localParamList[0] = _sentenceTab5[_sentenceIndex];
- _localParamList[1] = _sentenceTab4[_sentenceIndex];
- _localParamList[2] = _sentenceTab3[_sentenceIndex];
+ _localParamList[0] = sentence[_sentenceIndex].unk5;
+ _localParamList[1] = sentence[_sentenceIndex].unk4;
+ _localParamList[2] = sentence[_sentenceIndex].unk3;
_sentenceIndex--;
_currentScript = 0xFF;
- if (vm.vars[VAR_SENTENCE_SCRIPT])
- runScript(vm.vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList);
+ if (_vars[VAR_SENTENCE_SCRIPT])
+ runScript(_vars[VAR_SENTENCE_SCRIPT], 0, 0, _localParamList);
}
void Scumm::runInputScript(int a, int cmd, int mode) {
@@ -2692,8 +665,8 @@ void Scumm::runInputScript(int a, int cmd, int mode) {
_localParamList[0] = a;
_localParamList[1] = cmd;
_localParamList[2] = mode;
- if (vm.vars[VAR_VERB_SCRIPT])
- runScript(vm.vars[VAR_VERB_SCRIPT], 0, 0, _localParamList);
+ if (_vars[VAR_VERB_SCRIPT])
+ runScript(_vars[VAR_VERB_SCRIPT], 0, 0, _localParamList);
}
void Scumm::decreaseScriptDelay(int amount) {
@@ -2710,85 +683,9 @@ void Scumm::decreaseScriptDelay(int amount) {
}
}
-void Scumm::decodeParseString() {
- int textSlot;
- switch(_actorToPrintStrFor) {
- case 252:
- textSlot = 3;
- break;
- case 253:
- textSlot = 2;
- break;
- case 254:
- textSlot = 1;
- break;
- default:
- textSlot = 0;
- }
- _stringXpos[textSlot] = textslot.x[textSlot];
- _stringYpos[textSlot] = textslot.y[textSlot];
- _stringCenter[textSlot] = textslot.center[textSlot];
- _stringOverhead[textSlot] = textslot.overhead[textSlot];
- _stringRight[textSlot] = textslot.right[textSlot];
- _stringColor[textSlot] = textslot.color[textSlot];
- _stringCharset[textSlot] = textslot.charset[textSlot];
-
- while((_opcode=fetchScriptByte()) != 0xFF) {
- switch(_opcode&0xF) {
- case 0: /* set string xy */
- _stringXpos[textSlot] = getVarOrDirectWord(0x80);
- _stringYpos[textSlot] = getVarOrDirectWord(0x40);
- _stringOverhead[textSlot] = 0;
- break;
- case 1: /* color */
- _stringColor[textSlot] = getVarOrDirectByte(0x80);
- break;
- case 2: /* right */
- _stringRight[textSlot] = getVarOrDirectWord(0x80);
- break;
- case 4: /* center*/
- _stringCenter[textSlot] = 1;
- _stringOverhead[textSlot] = 0;
- break;
- case 6: /* left */
- _stringCenter[textSlot] = 0;
- _stringOverhead[textSlot] = 0;
- break;
- case 7: /* overhead */
- _stringOverhead[textSlot] = 1;
- break;
- case 8: /* ignore */
- getVarOrDirectWord(0x80);
- getVarOrDirectWord(0x40);
- break;
- case 15:
- _messagePtr = _scriptPointer;
- switch(textSlot) {
- case 0: actorTalk(); break;
- case 1: drawString(1); break;
- case 2: unkMessage1(); break;
- case 3: unkMessage2(); break;
- }
- _scriptPointer = _messagePtr;
- return;
- default:
- return;
- }
- }
-
- textslot.x[textSlot] = _stringXpos[textSlot];
- textslot.y[textSlot] = _stringYpos[textSlot];
- textslot.center[textSlot] = _stringCenter[textSlot];
- textslot.overhead[textSlot] = _stringOverhead[textSlot];
- textslot.right[textSlot] = _stringRight[textSlot];
- textslot.color[textSlot] = _stringColor[textSlot];
- textslot.charset[textSlot] = _stringCharset[textSlot];
-}
-
-
-void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
+void Scumm::runVerbCode(int object, int entry, int a, int b, int16 *vars) {
uint32 obcd;
int slot, where, offs,i;
@@ -2817,6 +714,9 @@ void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
vm.slot[slot].unk1 = a;
vm.slot[slot].unk2 = b;
vm.slot[slot].freezeCount = 0;
+#if defined(DOTT)
+ vm.slot[slot].newfield = 0;
+#endif
if (!vars) {
for(i=0; i<16; i++)
@@ -2829,16 +729,6 @@ void Scumm::runVERBCode(int object, int entry, int a, int b, int16 *vars) {
runScriptNested(slot);
}
-void Scumm::stackPush(int a) {
- assert(_scummStackPos >=0 && _scummStackPos < sizeof(_scummStack)-1);
- _scummStack[_scummStackPos++] = a;
-}
-
-int Scumm::stackPop() {
- assert(_scummStackPos >0 && _scummStackPos < sizeof(_scummStack));
- return _scummStack[--_scummStackPos];
-}
-
int Scumm::getVerbEntrypoint(int obj, int entry) {
byte *objptr, *verbptr;
int verboffs;
@@ -2866,3 +756,239 @@ int Scumm::getVerbEntrypoint(int obj, int entry) {
return verboffs + READ_LE_UINT16(verbptr+1);
}
+
+void Scumm::push(int a) {
+ assert(_scummStackPos >=0 && _scummStackPos < sizeof(_scummStack)-1);
+ _scummStack[_scummStackPos++] = a;
+}
+
+int Scumm::pop() {
+ assert(_scummStackPos >0 && _scummStackPos < sizeof(_scummStack));
+ return _scummStack[--_scummStackPos];
+}
+
+
+void Scumm::endCutscene() {
+ ScriptSlot *ss = &vm.slot[_currentScript];
+ uint32 *csptr;
+ int16 args[16];
+
+ memset(args, 0, sizeof(args));
+
+ ss->cutsceneOverride--;
+
+ args[0] = vm.cutSceneData[vm.cutSceneStackPointer];
+ _vars[VAR_OVERRIDE] = 0;
+
+ csptr = &vm.cutScenePtr[vm.cutSceneStackPointer];
+ if (*csptr)
+ ss->cutsceneOverride--;
+
+ vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
+ *csptr = 0;
+ vm.cutSceneStackPointer--;
+
+ if (_vars[VAR_CUTSCENE_END_SCRIPT])
+ runScript(_vars[VAR_CUTSCENE_END_SCRIPT], 0, 0, args);
+}
+
+void Scumm::cutscene(int16 *args) {
+ int scr = _currentScript;
+ vm.slot[scr].cutsceneOverride++;
+
+ if (++vm.cutSceneStackPointer > 5)
+ error("Cutscene stack overflow");
+
+ vm.cutSceneData[vm.cutSceneStackPointer] = args[0];
+ vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
+ vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
+
+ vm.cutSceneScriptIndex = scr;
+ if (_vars[VAR_CUTSCENE_START_SCRIPT])
+ runScript(_vars[VAR_CUTSCENE_START_SCRIPT], 0, 0, args);
+ vm.cutSceneScriptIndex = 0xFF;
+}
+
+void Scumm::faceActorToObj(int act, int obj) {
+ int x,dir;
+
+ if (getObjectOrActorXY(act)==-1)
+ return;
+
+ x = _xPos;
+
+ if (getObjectOrActorXY(obj)==-1)
+ return;
+
+ dir = (_xPos > x) ? 1 : 0;
+ turnToDirection(derefActorSafe(act, "faceActorToObj"), dir);
+}
+
+void Scumm::animateActor(int act, int anim) {
+ int shr,dir;
+ bool inRoom;
+ Actor *a;
+
+ a = derefActorSafe(act, "animateActor");
+
+ shr = anim>>2;
+ dir = anim&3;
+
+ inRoom = (a->room == _currentRoom);
+
+ if (shr == 0x3F) {
+ if (inRoom) {
+ startAnimActor(a, a->standFrame, a->facing);
+ a->moving = 0;
+ }
+ return;
+ }
+
+ if (shr == 0x3E) {
+ if (inRoom) {
+ startAnimActor(a, 0x3E, dir);
+ a->moving &= ~4;
+ }
+ a->facing = dir;
+ return;
+ }
+
+ if (shr == 0x3D) {
+ if (inRoom) {
+ turnToDirection(a, dir);
+ } else {
+ a->facing = dir;
+ }
+ return;
+ }
+
+ startAnimActor(a, anim, a->facing);
+}
+
+int Scumm::getScriptRunning(int script) {
+ int i;
+ ScriptSlot *ss = vm.slot;
+ for (i=0; i<20; i++,ss++)
+ if (ss->number==script && (ss->type==2 || ss->type==3) && ss->status)
+ return 1;
+ return 0;
+}
+
+void Scumm::beginOverride() {
+ int index;
+ uint32 *ptr;
+
+ index = vm.cutSceneStackPointer;
+ ptr = &vm.cutScenePtr[index];
+ if (!*ptr) {
+ vm.slot[_currentScript].cutsceneOverride++;
+ }
+ *ptr = _scriptPointer - _scriptOrgPointer;
+ vm.cutSceneScript[index] = _currentScript;
+
+ fetchScriptByte();
+ fetchScriptWord();
+ _vars[VAR_OVERRIDE] = 0;
+}
+
+void Scumm::endOverride() {
+ int index;
+ uint32 *ptr;
+
+ index = vm.cutSceneStackPointer;
+ ptr = &vm.cutScenePtr[index];
+ if (*ptr) {
+ vm.slot[_currentScript].cutsceneOverride--;
+ }
+ *ptr = 0;
+ vm.cutSceneScript[index] = 0;
+ _vars[VAR_OVERRIDE] = 0;
+}
+
+
+#if defined(DOTT)
+int Scumm::defineArray(int array, int type, int dim2, int dim1) {
+ int id;
+ int size;
+ ArrayHeader *ah;
+
+ if (type!=5 && type!=4)
+ type=5;
+
+ nukeArray(array);
+
+ id = getArrayId();
+
+ if (array&0x4000) {
+ _arrays[id] = vm.slot[_currentScript].number;
+ }
+
+ if (array&0x8000) {
+ error("Can't define bit variable as array pointer");
+ }
+
+ writeVar(array, id);
+
+ size = (type==5) ? 16 : 8;
+ size *= dim2+1;
+ size *= dim1+1;
+ size >>= 3;
+
+ ah = (ArrayHeader*)createResource(7, id, size+sizeof(ArrayHeader));
+
+ ah->type = type;
+ ah->dim1_size = dim1+1;
+ ah->dim2_size = dim2+1;
+
+ return id;
+}
+
+void Scumm::nukeArray(int a) {
+ int data;
+
+ data = readVar(a);
+
+ if (data)
+ nukeResource(7, data);
+ _arrays[data] = 0;
+
+ writeVar(a, 0);
+}
+
+int Scumm::getArrayId() {
+ byte **addr = _baseArrays;
+ int i;
+
+ for (i=1; i<_numArray; i++) {
+ if (!addr[i])
+ return i;
+ }
+ error("Out of array pointers, %d max", _numArray);
+}
+
+void Scumm::copyString(byte *dst, byte *src, int len) {
+ if (!src) {
+ while (--len>=0)
+ *dst++ = fetchScriptByte();
+ } else {
+ while (--len>=0)
+ *dst++ = *src++;
+ }
+}
+#endif
+
+int Scumm::getStringLen(byte *ptr) {
+ int len;
+ byte c;
+ if (!ptr)
+ ptr = _scriptPointer;
+ len = 0;
+ do {
+ c = *ptr++;
+ if (!c) break;
+ len++;
+ if (c==0xFF)
+ ptr += 3, len += 3;
+ } while (1);
+ return len+1;
+}
diff --git a/script_v1.cpp b/script_v1.cpp
new file mode 100644
index 0000000000..dde9cbb908
--- /dev/null
+++ b/script_v1.cpp
@@ -0,0 +1,1986 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ *
+ * 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.
+ *
+ * Change Log:
+ * $Log$
+ * Revision 1.1 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
+ */
+
+
+#include "stdafx.h"
+#include "scumm.h"
+
+#if !defined(DOTT)
+
+void Scumm::setupOpcodes() {
+ static const OpcodeProc opcode_list[] = {
+ /* 00 */
+ &Scumm::o_stopObjectCode,
+ &Scumm::o_putActor,
+ &Scumm::o_startMusic,
+ &Scumm::o_getActorRoom,
+ /* 04 */
+ &Scumm::o_isGreaterEqual,
+ &Scumm::o_drawObject,
+ &Scumm::o_getActorElevation,
+ &Scumm::o_setState,
+ /* 08 */
+ &Scumm::o_isNotEqual,
+ &Scumm::o_faceActor,
+ &Scumm::o_startScript,
+ &Scumm::o_getVerbEntrypoint,
+ /* 0C */
+ &Scumm::o_resourceRoutines,
+ &Scumm::o_walkActorToActor,
+ &Scumm::o_putActorAtObject,
+ &Scumm::o_getObjectState,
+ /* 10 */
+ &Scumm::o_getObjectOwner,
+ &Scumm::o_animateActor,
+ &Scumm::o_panCameraTo,
+ &Scumm::o_actorSet,
+ /* 14 */
+ &Scumm::o_print,
+ &Scumm::o_actorFromPos,
+ &Scumm::o_getRandomNr,
+ &Scumm::o_and,
+ /* 18 */
+ &Scumm::o_jumpRelative,
+ &Scumm::o_doSentence,
+ &Scumm::o_move,
+ &Scumm::o_multiply,
+ /* 1C */
+ &Scumm::o_startSound,
+ &Scumm::o_ifClassOfIs,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_isActorInBox,
+ /* 20 */
+ &Scumm::o_stopMusic,
+ &Scumm::o_putActor,
+ &Scumm::o_getAnimCounter,
+ &Scumm::o_getActorY,
+ /* 24 */
+ &Scumm::o_loadRoomWithEgo,
+ &Scumm::o_pickupObject,
+ &Scumm::o_setVarRange,
+ &Scumm::o_stringOps,
+ /* 28 */
+ &Scumm::o_equalZero,
+ &Scumm::o_setOwnerOf,
+ &Scumm::o_startScript,
+ &Scumm::o_delayVariable,
+ /* 2C */
+ &Scumm::o_cursorCommand,
+ &Scumm::o_putActorInRoom,
+ &Scumm::o_delay,
+ &Scumm::o_badOpcode,
+ /* 30 */
+ &Scumm::o_matrixOps,
+ &Scumm::o_getInventoryCount,
+ &Scumm::o_setCameraAt,
+ &Scumm::o_roomOps,
+ /* 34 */
+ &Scumm::o_getDist,
+ &Scumm::o_findObject,
+ &Scumm::o_walkActorToObject,
+ &Scumm::o_startObject,
+ /* 38 */
+ &Scumm::o_lessOrEqual,
+ &Scumm::o_doSentence,
+ &Scumm::o_subtract,
+ &Scumm::o_getActorScale,
+ /* 3C */
+ &Scumm::o_stopSound,
+ &Scumm::o_findInventory,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_drawBox,
+ /* 40 */
+ &Scumm::o_cutscene,
+ &Scumm::o_putActor,
+ &Scumm::o_chainScript,
+ &Scumm::o_getActorX,
+ /* 44 */
+ &Scumm::o_isLess,
+ &Scumm::o_badOpcode,
+ &Scumm::o_increment,
+ &Scumm::o_setState,
+ /* 48 */
+ &Scumm::o_isEqual,
+ &Scumm::o_faceActor,
+ &Scumm::o_startScript,
+ &Scumm::o_getVerbEntrypoint,
+ /* 4C */
+ &Scumm::o_soundKludge,
+ &Scumm::o_walkActorToActor,
+ &Scumm::o_putActorAtObject,
+ &Scumm::o_badOpcode,
+ /* 50 */
+ &Scumm::o_badOpcode,
+ &Scumm::o_animateActor,
+ &Scumm::o_actorFollowCamera,
+ &Scumm::o_actorSet,
+ /* 54 */
+ &Scumm::o_setObjectName,
+ &Scumm::o_actorFromPos,
+ &Scumm::o_getActorMoving,
+ &Scumm::o_or,
+ /* 58 */
+ &Scumm::o_overRide,
+ &Scumm::o_doSentence,
+ &Scumm::o_add,
+ &Scumm::o_divide,
+ /* 5C */
+ &Scumm::o_badOpcode,
+ &Scumm::o_actorSetClass,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_isActorInBox,
+ /* 60 */
+ &Scumm::o_freezeScripts,
+ &Scumm::o_putActor,
+ &Scumm::o_stopScript,
+ &Scumm::o_getActorFacing,
+ /* 64 */
+ &Scumm::o_loadRoomWithEgo,
+ &Scumm::o_pickupObject,
+ &Scumm::o_getClosestObjActor,
+ &Scumm::o_dummy,
+ /* 68 */
+ &Scumm::o_getScriptRunning,
+ &Scumm::o_setOwnerOf,
+ &Scumm::o_startScript,
+ &Scumm::o_debug,
+ /* 6C */
+ &Scumm::o_getActorWidth,
+ &Scumm::o_putActorInRoom,
+ &Scumm::o_stopObjectScript,
+ &Scumm::o_badOpcode,
+ /* 70 */
+ &Scumm::o_lights,
+ &Scumm::o_getActorCostume,
+ &Scumm::o_loadRoom,
+ &Scumm::o_roomOps,
+ /* 74 */
+ &Scumm::o_getDist,
+ &Scumm::o_findObject,
+ &Scumm::o_walkActorToObject,
+ &Scumm::o_startObject,
+ /* 78 */
+ &Scumm::o_isGreater, /* less? */
+ &Scumm::o_doSentence,
+ &Scumm::o_verbOps,
+ &Scumm::o_getActorWalkBox,
+ /* 7C */
+ &Scumm::o_isSoundRunning,
+ &Scumm::o_findInventory,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_drawBox,
+ /* 80 */
+ &Scumm::o_breakHere,
+ &Scumm::o_putActor,
+ &Scumm::o_startMusic,
+ &Scumm::o_getActorRoom,
+ /* 84 */
+ &Scumm::o_isGreaterEqual, /* less equal? */
+ &Scumm::o_drawObject,
+ &Scumm::o_getActorElevation,
+ &Scumm::o_setState,
+ /* 88 */
+ &Scumm::o_isNotEqual,
+ &Scumm::o_faceActor,
+ &Scumm::o_startScript,
+ &Scumm::o_getVerbEntrypoint,
+ /* 8C */
+ &Scumm::o_resourceRoutines,
+ &Scumm::o_walkActorToActor,
+ &Scumm::o_putActorAtObject,
+ &Scumm::o_getObjectState,
+ /* 90 */
+ &Scumm::o_getObjectOwner,
+ &Scumm::o_animateActor,
+ &Scumm::o_panCameraTo,
+ &Scumm::o_actorSet,
+ /* 94 */
+ &Scumm::o_print,
+ &Scumm::o_actorFromPos,
+ &Scumm::o_getRandomNr,
+ &Scumm::o_and,
+ /* 98 */
+ &Scumm::o_quitPauseRestart,
+ &Scumm::o_doSentence,
+ &Scumm::o_move,
+ &Scumm::o_multiply,
+ /* 9C */
+ &Scumm::o_startSound,
+ &Scumm::o_ifClassOfIs,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_isActorInBox,
+ /* A0 */
+ &Scumm::o_stopObjectCode,
+ &Scumm::o_putActor,
+ &Scumm::o_getAnimCounter,
+ &Scumm::o_getActorY,
+ /* A4 */
+ &Scumm::o_loadRoomWithEgo,
+ &Scumm::o_pickupObject,
+ &Scumm::o_setVarRange,
+ &Scumm::o_dummy,
+ /* A8 */
+ &Scumm::o_notEqualZero,
+ &Scumm::o_setOwnerOf,
+ &Scumm::o_startScript,
+ &Scumm::o_saveRestoreVerbs,
+ /* AC */
+ &Scumm::o_expression,
+ &Scumm::o_putActorInRoom,
+ &Scumm::o_wait,
+ &Scumm::o_badOpcode,
+ /* B0 */
+ &Scumm::o_matrixOps,
+ &Scumm::o_getInventoryCount,
+ &Scumm::o_setCameraAt,
+ &Scumm::o_roomOps,
+ /* B4 */
+ &Scumm::o_getDist,
+ &Scumm::o_findObject,
+ &Scumm::o_walkActorToObject,
+ &Scumm::o_startObject,
+ /* B8 */
+ &Scumm::o_lessOrEqual,
+ &Scumm::o_doSentence,
+ &Scumm::o_subtract,
+ &Scumm::o_getActorScale,
+ /* BC */
+ &Scumm::o_stopSound,
+ &Scumm::o_findInventory,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_drawBox,
+ /* C0 */
+ &Scumm::o_endCutscene,
+ &Scumm::o_putActor,
+ &Scumm::o_chainScript,
+ &Scumm::o_getActorX,
+ /* C4 */
+ &Scumm::o_isLess,
+ &Scumm::o_badOpcode,
+ &Scumm::o_decrement,
+ &Scumm::o_setState,
+ /* C8 */
+ &Scumm::o_isEqual,
+ &Scumm::o_faceActor,
+ &Scumm::o_startScript,
+ &Scumm::o_getVerbEntrypoint,
+ /* CC */
+ &Scumm::o_pseudoRoom,
+ &Scumm::o_walkActorToActor,
+ &Scumm::o_putActorAtObject,
+ &Scumm::o_badOpcode,
+ /* D0 */
+ &Scumm::o_badOpcode,
+ &Scumm::o_animateActor,
+ &Scumm::o_actorFollowCamera,
+ &Scumm::o_actorSet,
+ /* D4 */
+ &Scumm::o_setObjectName,
+ &Scumm::o_actorFromPos,
+ &Scumm::o_getActorMoving,
+ &Scumm::o_or,
+ /* D8 */
+ &Scumm::o_printEgo,
+ &Scumm::o_doSentence,
+ &Scumm::o_add,
+ &Scumm::o_divide,
+ /* DC */
+ &Scumm::o_badOpcode,
+ &Scumm::o_actorSetClass,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_isActorInBox,
+ /* E0 */
+ &Scumm::o_freezeScripts,
+ &Scumm::o_putActor,
+ &Scumm::o_stopScript,
+ &Scumm::o_getActorFacing,
+ /* E4 */
+ &Scumm::o_loadRoomWithEgo,
+ &Scumm::o_pickupObject,
+ &Scumm::o_getClosestObjActor,
+ &Scumm::o_dummy,
+ /* E8 */
+ &Scumm::o_getScriptRunning,
+ &Scumm::o_setOwnerOf,
+ &Scumm::o_startScript,
+ &Scumm::o_debug,
+ /* EC */
+ &Scumm::o_getActorWidth,
+ &Scumm::o_putActorInRoom,
+ &Scumm::o_stopObjectScript,
+ &Scumm::o_badOpcode,
+ /* F0 */
+ &Scumm::o_lights,
+ &Scumm::o_getActorCostume,
+ &Scumm::o_loadRoom,
+ &Scumm::o_roomOps,
+ /* F4 */
+ &Scumm::o_getDist,
+ &Scumm::o_findObject,
+ &Scumm::o_walkActorToObject,
+ &Scumm::o_startObject,
+ /* F8 */
+ &Scumm::o_isGreater,
+ &Scumm::o_doSentence,
+ &Scumm::o_verbOps,
+ &Scumm::o_getActorWalkBox,
+ /* FC */
+ &Scumm::o_isSoundRunning,
+ &Scumm::o_findInventory,
+ &Scumm::o_walkActorTo,
+ &Scumm::o_drawBox
+ };
+
+ _opcodes = opcode_list;
+}
+
+void Scumm::o_actorFollowCamera() {
+ actorFollowCamera(getVarOrDirectByte(0x80));
+}
+
+void Scumm::o_actorFromPos() {
+ int x,y;
+ getResultPos();
+ x = getVarOrDirectWord(0x80);
+ y = getVarOrDirectWord(0x40);
+ setResult(getActorFromPos(x,y));
+}
+
+void Scumm::o_actorSet() {
+ int act = getVarOrDirectByte(0x80);
+ Actor *a = derefActorSafe(act, "actorSet");
+ int i,j;
+
+ while ( (_opcode = fetchScriptByte()) != 0xFF) {
+ switch(_opcode&0x1F) {
+ case 1: /* costume */
+ setActorCostume(a, getVarOrDirectByte(0x80));
+ break;
+ case 2: /* walkspeed */
+ i = getVarOrDirectByte(0x80);
+ j = getVarOrDirectByte(0x40);
+ setActorWalkSpeed(a, i, j);
+ break;
+ case 3: /* sound */
+ a->sound[0] = getVarOrDirectByte(0x80);
+ break;
+ case 4: /* walkanim */
+ a->walkFrame = getVarOrDirectByte(0x80);
+ break;
+ case 5: /* talkanim */
+ a->talkFrame1 = getVarOrDirectByte(0x80);
+ a->talkFrame2 = getVarOrDirectByte(0x40);
+ break;
+ case 6: /* standanim */
+ a->standFrame = getVarOrDirectByte(0x80);
+ break;
+ case 7: /* ignore */
+ getVarOrDirectByte(0x80);
+ getVarOrDirectByte(0x40);
+ getVarOrDirectByte(0x20);
+ break;
+ case 8: /* init */
+ initActor(a, 0);
+ break;
+ case 9: /* elevation */
+ a->elevation = getVarOrDirectWord(0x80);
+ a->needRedraw = true;
+ a->needBgReset = true;
+ break;
+ case 10: /* defaultanims */
+ a->initFrame = 1;
+ a->walkFrame = 2;
+ a->standFrame = 3;
+ a->talkFrame1 = 4;
+ a->talkFrame2 = 5;
+ break;
+ case 11: /* palette */
+ i = getVarOrDirectByte(0x80);
+ j = getVarOrDirectByte(0x40);
+ checkRange(31, 0, i, "Illegal palet slot %d");
+ a->palette[i] = j;
+ a->needRedraw = true;
+ break;
+ case 12: /* talk color */
+ a->talkColor = getVarOrDirectByte(0x80);
+ break;
+ case 13: /* name */
+ loadPtrToResource(9, a->number, NULL);
+ break;
+ case 14: /* initanim */
+ a->initFrame = getVarOrDirectByte(0x80);
+ break;
+ case 15: /* unk */
+ error("o_actorset:unk not implemented");
+ break;
+ case 16: /* width */
+ a->width = getVarOrDirectByte(0x80);
+ break;
+ case 17: /* scale */
+ a->scalex = getVarOrDirectByte(0x80);
+ a->scaley = getVarOrDirectByte(0x40);
+ a->needRedraw = true;
+ a->needBgReset = true;
+ break;
+ case 18: /* neverzclip */
+ a->neverZClip = 0;
+ break;
+ case 19: /* setzclip */
+ a->neverZClip = getVarOrDirectByte(0x80);
+ break;
+ case 20: /* ignoreboxes */
+ a->ignoreBoxes = 1;
+ a->neverZClip = 0;
+FixRoom:
+ if (a->room==_currentRoom)
+ putActor(a, a->x, a->y, a->room);
+ break;
+ case 21: /* followboxes */
+ a->ignoreBoxes = 0;
+ a->neverZClip = 0;
+ goto FixRoom;
+
+ case 22: /* animspeed */
+ a->animSpeed = getVarOrDirectByte(0x80);
+ a->animProgress = 0;
+ break;
+ case 23: /* unk2 */
+ a->data8 = getVarOrDirectByte(0x80); /* unused */
+ break;
+ default:
+ error("o_actorSet: default case");
+ }
+ }
+}
+
+void Scumm::o_actorSetClass() {
+ int act = getVarOrDirectWord(0x80);
+ int i;
+
+ while ( (_opcode=fetchScriptByte()) != 0xFF) {
+ i = getVarOrDirectWord(0x80);
+ if (i==0) {
+ _classData[act] = 0;
+ continue;
+ }
+ if (i&0x80)
+ putClass(act, i, 1);
+ else
+ putClass(act, i, 0);
+ }
+}
+
+void Scumm::o_add() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ setResult(readVar(_resultVarNumber) + a);
+}
+
+void Scumm::o_and() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ setResult(readVar(_resultVarNumber) & a);
+}
+
+void Scumm::o_animateActor() {
+ int act, anim;
+
+ act = getVarOrDirectByte(0x80);
+ anim = getVarOrDirectByte(0x40);
+ animateActor(act,anim);
+}
+
+void Scumm::o_badOpcode() {
+ error("Scumm opcode %d illegal", _opcode);
+}
+
+void Scumm::o_breakHere() {
+ updateScriptPtr();
+ _currentScript = 0xFF;
+}
+
+void Scumm::o_chainScript() {
+ int16 vars[16];
+ int data;
+ int cur;
+
+ data = getVarOrDirectByte(0x80);
+
+ getWordVararg(vars);
+
+ cur = _currentScript;
+
+ if (vm.slot[cur].cutsceneOverride != 0) {
+ error("Script %d chaining with active cutscene/override");
+ }
+
+ vm.slot[cur].number = 0;
+ vm.slot[cur].status = 0;
+ _currentScript = 0xFF;
+
+ runScript(data, vm.slot[cur].unk1, vm.slot[cur].unk2, vars);
+}
+
+void Scumm::o_cursorCommand() {
+ int i,j,k;
+ int16 table[16];
+
+ switch((_opcode=fetchScriptByte())&0x1F) {
+ case 1: /* cursor show */
+ _cursorState = 1;
+ verbMouseOver(0);
+ break;
+ case 2: /* cursor hide */
+ _cursorState = 0;
+ verbMouseOver(0);
+ break;
+ case 3: /* userput on */
+ _userPut = 1;
+ break;
+ case 4: /* userput off */
+ _userPut = 0;
+ break;
+ case 5: /* cursor soft on */
+ _cursorState++;
+ if (_cursorState > 1) {
+ error("Cursor state greater than 1 in script");
+ }
+ verbMouseOver(0);
+ break;
+ case 6: /* cursor soft off */
+ _cursorState--;
+ verbMouseOver(0);
+ break;
+ case 7: /* userput soft on */
+ _userPut++;
+ break;
+ case 8: /* userput soft off */
+ _userPut--;
+ break;
+ case 10: /* set cursor img */
+ i = getVarOrDirectByte(0x80);
+ j = getVarOrDirectByte(0x40);
+ setCursorImg(i, j);
+ break;
+ case 11: /* set cursor hotspot */
+ i = getVarOrDirectByte(0x80);
+ j = getVarOrDirectByte(0x40);
+ k = getVarOrDirectByte(0x20);
+ setCursorHotspot(i, j, k);
+ break;
+
+ case 12: /* init cursor */
+ setCursor(getVarOrDirectByte(0x80));
+ break;
+ case 13: /* init charset */
+ initCharset(getVarOrDirectByte(0x80));
+ break;
+ case 14: /* unk */
+ getWordVararg(table);
+ for (i=0; i<16; i++)
+ charset._colorMap[i] = _charsetData[string[1].t_charset][i] = table[i];
+ break;
+ }
+
+ _vars[VAR_CURSORSTATE] = _cursorState;
+ _vars[VAR_USERPUT] = _userPut;
+}
+
+void Scumm::o_cutscene() {
+ int16 args[16];
+ getWordVararg(args);
+ cutscene(args);
+}
+
+void Scumm::o_endCutscene() {
+ endCutscene();
+}
+
+void Scumm::o_debug() {
+ getVarOrDirectWord(0x80);
+}
+
+void Scumm::o_decrement() {
+ getResultPos();
+ setResult(readVar(_resultVarNumber)-1);
+}
+
+void Scumm::o_delay() {
+ int delay = fetchScriptByte();
+ delay |= fetchScriptByte()<<8;
+ delay |= fetchScriptByte()<<16;
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o_breakHere();
+}
+
+void Scumm::o_delayVariable() {
+ vm.slot[_currentScript].delay = readVar(fetchScriptWord());
+ vm.slot[_currentScript].status = 1;
+ o_breakHere();
+}
+
+void Scumm::o_divide() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ if(a==0) {
+ error("Divide by zero");
+ setResult(0);
+ } else
+ setResult(readVar(_resultVarNumber) / a);
+}
+
+void Scumm::o_doSentence() {
+ int a,b;
+ SentenceTab *st;
+
+ _sentenceIndex++;
+
+ a = getVarOrDirectByte(0x80);
+ if (a==0xFE) {
+ _sentenceIndex = 0xFF;
+ stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]);
+ clearClickedStatus();
+ return;
+ }
+
+ st = &sentence[_sentenceIndex];
+
+ st->unk5 = a;
+ st->unk4 = getVarOrDirectWord(0x40);
+ b = st->unk3 = getVarOrDirectWord(0x20);
+ if (b==0) {
+ st->unk2 = 0;
+ } else {
+ st->unk2 = 1;
+ }
+ st->unk = 0;
+}
+
+void Scumm::o_drawBox() {
+ int x,y,x2,y2,color;
+
+ x = getVarOrDirectWord(0x80);
+ y = getVarOrDirectWord(0x40);
+
+ _opcode = fetchScriptByte();
+ x2 = getVarOrDirectWord(0x80);
+ y2 = getVarOrDirectWord(0x40);
+ color = getVarOrDirectByte(0x20);
+
+ drawBox(x, y, x2, y2, color);
+}
+
+void Scumm::o_drawObject() {
+ int state,obj,index,i;
+ ObjectData *od;
+ byte x,y,w,h;
+
+ state = 1;
+ _xPos = _yPos = 255;
+ obj = getVarOrDirectWord(0x80);
+
+ switch((_opcode = fetchScriptByte())&0x1F) {
+ case 1: /* draw at */
+ _xPos = getVarOrDirectWord(0x80);
+ _yPos = getVarOrDirectWord(0x40);
+ break;
+ case 2: /* set state */
+ state = getVarOrDirectWord(0x80);
+ break;
+ case 0x1F: /* neither */
+ break;
+ default:
+ error("o_drawObject: default case");
+ }
+ index = getObjectIndex(obj);
+ if (index==-1)
+ return;
+ od = &_objs[index];
+ if (_xPos!=0xFF) {
+ od->cdhd_10 += (_xPos - od->x_pos)<<3;
+ od->x_pos = _xPos;
+ od->cdhd_12 += (_yPos - od->y_pos)<<3;
+ od->y_pos = _yPos;
+ }
+ addObjectToDrawQue(index);
+
+ x = od->x_pos;
+ y = od->y_pos;
+ w = od->numstrips;
+ h = od->height;
+
+ i = _numObjectsInRoom;
+ do {
+ if (_objs[i].x_pos == x && _objs[i].y_pos == y
+ && _objs[i].numstrips == w && _objs[i].height==h)
+ putState(_objs[i].obj_nr, 0);
+ } while (--i);
+
+ putState(obj, state);
+}
+
+void Scumm::o_dummy() {
+ /* nothing */
+}
+
+
+void Scumm::o_expression() {
+ int dst, i;
+
+ _scummStackPos = 0;
+ getResultPos();
+ dst = _resultVarNumber;
+
+ while ((_opcode = fetchScriptByte())!=0xFF) {
+ switch(_opcode&0x1F) {
+ case 1: /* varordirect */
+ push(getVarOrDirectWord(0x80));
+ break;
+ case 2: /* add */
+ i = pop();
+ push(i + pop());
+ break;
+ case 3: /* sub */
+ i = pop();
+ push(pop() - i);
+ break;
+ case 4: /* mul */
+ i = pop();
+ push(i * pop());
+ break;
+ case 5: /* div */
+ i = pop();
+ if (i==0)
+ error("Divide by zero");
+ push(pop() / i);
+ break;
+ case 6: /* normal opcode */
+ _opcode = fetchScriptByte();
+ (this->*(getOpcode(_opcode)))();
+ push(_vars[0]);
+ break;
+ }
+ }
+
+ _resultVarNumber = dst;
+ setResult(pop());
+}
+
+void Scumm::o_faceActor() {
+ int act, obj;
+ act = getVarOrDirectByte(0x80);
+ obj = getVarOrDirectWord(0x40);
+ faceActorToObj(act, obj);
+}
+
+void Scumm::o_findInventory() {
+ int t;
+ getResultPos();
+ t = getVarOrDirectByte(0x80);
+ setResult(findInventory(t,getVarOrDirectByte(0x40)));
+}
+
+void Scumm::o_findObject() {
+ int t;
+ getResultPos();
+ t = getVarOrDirectWord(0x80);
+ setResult(findObject(t, getVarOrDirectWord(0x40)));
+}
+
+void Scumm::o_freezeScripts() {
+ int scr = getVarOrDirectByte(0x80);
+
+ if (scr!=0)
+ freezeScripts(scr);
+ else
+ unfreezeScripts();
+}
+
+void Scumm::o_getActorCostume() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorCostume")->costume);
+}
+
+void Scumm::o_getActorElevation() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorElevation")->elevation);
+}
+
+void Scumm::o_getActorFacing() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorFacing")->facing);
+}
+
+void Scumm::o_getActorMoving() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorMoving")->moving);
+}
+
+void Scumm::o_getActorRoom() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorRoom")->room);
+}
+
+void Scumm::o_getActorScale() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorScale")->scalex);
+}
+
+void Scumm::o_getActorWalkBox() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWalkbox")->walkbox);
+}
+
+void Scumm::o_getActorWidth() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorWidth")->width);
+}
+
+void Scumm::o_getActorX() {
+ getResultPos();
+ setResult(getObjX(getVarOrDirectWord(0x80)));
+}
+
+void Scumm::o_getActorY() {
+ getResultPos();
+ setResult(getObjY(getVarOrDirectWord(0x80)));
+}
+
+void Scumm::o_getAnimCounter() {
+ getResultPos();
+ setResult(derefActorSafe(getVarOrDirectByte(0x80),"o_getActorAnimCounter")->cost.animCounter1);
+}
+
+void Scumm::o_getClosestObjActor() {
+ int obj;
+ int act;
+ int closobj=-1, closnum=-1;
+ int dist;
+
+ getResultPos();
+
+ act = getVarOrDirectWord(0x80);
+ obj = _vars[VAR_OBJECT_HI];
+
+ do {
+ dist = getObjActToObjActDist(obj,act);
+ if (dist < closnum) {
+ closnum = dist;
+ closobj = obj;
+ }
+ } while (--obj >= _vars[VAR_OBJECT_LO]);
+
+ setResult(closnum);
+}
+
+void Scumm::o_getDist() {
+ int o1,o2;
+ getResultPos();
+ o1 = getVarOrDirectWord(0x80);
+ o2 = getVarOrDirectWord(0x40);
+ setResult(getObjActToObjActDist(o1,o2));
+}
+
+void Scumm::o_getInventoryCount() {
+ getResultPos();
+ setResult(getInventoryCount(getVarOrDirectByte(0x80)));
+}
+
+void Scumm::o_getObjectOwner() {
+ getResultPos();
+ setResult(getOwner(getVarOrDirectWord(0x80)));
+}
+
+void Scumm::o_getObjectState() {
+ getResultPos();
+ setResult(getState(getVarOrDirectWord(0x80)));
+}
+
+void Scumm::o_getRandomNr() {
+ getResultPos();
+ setResult(getRandomNumber(getVarOrDirectByte(0x80)+1));
+}
+
+void Scumm::o_getScriptRunning() {
+ getResultPos();
+ setResult(getScriptRunning(getVarOrDirectByte(0x80)));
+}
+
+void Scumm::o_getVerbEntrypoint() {
+ int a,b;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ setResult(getVerbEntrypoint(a, b));
+}
+
+void Scumm::o_ifClassOfIs() {
+ int act,cls;
+ bool cond = true, b;
+
+ act = getVarOrDirectWord(0x80);
+ while ( (_opcode = fetchScriptByte()) != 0xFF) {
+ cls = getVarOrDirectWord(0x80);
+ b = getClass(act, cls);
+
+ if (cls&0x80 && !b || !(cls&0x80) && b)
+ cond = false;
+ }
+ if (cond)
+ ignoreScriptWord();
+ else
+ o_jumpRelative();
+}
+
+void Scumm::o_increment() {
+ getResultPos();
+ setResult(readVar(_resultVarNumber)+1);
+}
+
+void Scumm::o_isActorInBox() {
+ int box;
+ Actor *a;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_isActorInBox");
+ box = getVarOrDirectByte(0x40);
+
+ if (!checkXYInBoxBounds(box, a->x, a->y))
+ o_jumpRelative();
+ else
+ ignoreScriptWord();
+}
+
+void Scumm::o_isEqual() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b == a) ignoreScriptWord();
+ else o_jumpRelative();
+
+}
+
+void Scumm::o_isGreater() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b > a) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_isGreaterEqual() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b >= a) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_isLess() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b < a) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_lessOrEqual() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b <= a) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_isNotEqual() {
+ int16 a = readVar(fetchScriptWord());
+ int16 b = getVarOrDirectWord(0x80);
+ if (b != a) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_notEqualZero() {
+ int a = readVar(fetchScriptWord());
+ if (a != 0) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_equalZero() {
+ int a = readVar(fetchScriptWord());
+ if (a == 0) ignoreScriptWord();
+ else o_jumpRelative();
+}
+
+void Scumm::o_isSoundRunning() {
+ int snd;
+ getResultPos();
+ snd = getVarOrDirectByte(0x80);
+ if (snd)
+ snd = unkSoundProc23(snd);
+ setResult(snd);
+}
+
+void Scumm::o_jumpRelative() {
+ _scriptPointer += (int16)fetchScriptWord();
+}
+
+void Scumm::o_lights() {
+ int a,b,c;
+
+ a = getVarOrDirectByte(0x80);
+ b = fetchScriptByte();
+ c = fetchScriptByte();
+ if (c==0)
+ _vars[VAR_DRAWFLAGS] = a;
+ else if (c==1) {
+ _lightsValueA = a;
+ _lightsValueB = b;
+ }
+ _fullRedraw=1;
+}
+
+void Scumm::o_loadRoom() {
+ int room = getVarOrDirectByte(0x80);
+ debug(1,"Loading room %d", room);
+ startScene(room, 0, 0);
+ _fullRedraw = 1;
+}
+
+void Scumm::o_loadRoomWithEgo() {
+ int obj, room, x,y;
+ Actor *a;
+
+ obj = getVarOrDirectWord(0x80);
+ room = getVarOrDirectByte(0x40);
+
+ a = derefActorSafe(_vars[VAR_UNK_ACTOR], "o_loadRoomWithEgo");
+
+ /* Warning: uses _xPos, _yPos from a previous update of those */
+ putActor(a, _xPos, _yPos, room);
+
+ x = (int16)fetchScriptWord();
+ y = (int16)fetchScriptWord();
+
+ dseg_3A76 = 0;
+
+ _vars[VAR_WALKTO_OBJ] = obj;
+
+ startScene(a->room, a, obj);
+
+ _vars[VAR_WALKTO_OBJ] = 0;
+ camera._destPos = camera._curPos = a->x;
+ setCameraFollows(a);
+ _fullRedraw=1;
+
+ if (x != -1) {
+ startWalkActor(a, x, y, 0xFF);
+ }
+}
+
+void Scumm::o_matrixOps() {
+ int a,b;
+
+ _opcode = fetchScriptByte();
+ switch(_opcode & 0x1F) {
+ case 1:
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ setBoxFlags(a,b);
+ break;
+ case 2:
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ setBoxScale(a,b);
+ break;
+ case 3:
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ setBoxScale(a,(b-1)|0x8000);
+ break;
+ case 4:
+ createBoxMatrix();
+ break;
+ }
+}
+
+void Scumm::o_move() {
+ getResultPos();
+ setResult(getVarOrDirectWord(0x80));
+}
+
+void Scumm::o_multiply() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ setResult(readVar(_resultVarNumber) * a);
+}
+
+
+void Scumm::o_or() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ setResult(readVar(_resultVarNumber) | a);
+}
+
+void Scumm::o_overRide() {
+ if(fetchScriptByte()!=0)
+ beginOverride();
+ else
+ endOverride();
+}
+
+void Scumm::o_panCameraTo() {
+ panCameraTo(getVarOrDirectWord(0x80));
+}
+
+void Scumm::o_pickupObject() {
+ int obj, room;
+
+ obj = getVarOrDirectWord(0x80);
+ room = getVarOrDirectByte(0x40);
+ if (room==0)
+ room = _roomResource;
+ addObjectToInventory(obj, room);
+ putOwner(obj, _vars[VAR_UNK_ACTOR]);
+ putClass(obj, 32, 1);
+ putState(obj, 1);
+ removeObjectFromRoom(obj);
+ clearDrawObjectQueue();
+ runHook(1);
+}
+
+void Scumm::o_print() {
+ _actorToPrintStrFor = getVarOrDirectByte(0x80);
+ decodeParseString();
+}
+
+void Scumm::o_printEgo() {
+ _actorToPrintStrFor = _vars[VAR_UNK_ACTOR];
+ decodeParseString();
+}
+
+void Scumm::o_pseudoRoom() {
+ int i = fetchScriptByte(), j;
+ while ((j = fetchScriptByte()) != 0) {
+ if (j >= 0x80) {
+ _resourceMapper[j&0x7F] = i;
+ }
+ }
+}
+
+void Scumm::o_putActor() {
+ int x,y;
+ Actor *a;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActor");
+ x = getVarOrDirectWord(0x40);
+ y = getVarOrDirectWord(0x20);
+
+ putActor(a, x, y, a->room);
+}
+
+
+void Scumm::o_putActorAtObject() {
+ int obj;
+ Actor *a;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorAtObject");
+ obj = getVarOrDirectWord(0x40);
+ if (whereIsObject(obj)!=-1)
+ getObjectXYPos(obj);
+ else {
+ _xPos = 240;
+ _yPos = 120;
+ }
+ putActor(a, _xPos, _yPos, a->room);
+}
+
+void Scumm::o_putActorInRoom() {
+ int room;
+ Actor *a;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_putActorInRoom");
+ room = getVarOrDirectByte(0x40);
+ if (a->visible && _currentRoom!=room && _vars[VAR_TALK_ACTOR]==a->number) {
+ clearMsgQueue();
+ }
+ a->room = room;
+ if (!room)
+ putActor(a, 0, 0, 0);
+}
+
+void Scumm::o_quitPauseRestart() {
+ switch(fetchScriptByte()) {
+ case 1:
+ pauseGame(0);
+ break;
+ case 3:
+ shutDown(0);
+ break;
+ }
+}
+
+void Scumm::o_resourceRoutines() {
+ int res;
+
+ _opcode = fetchScriptByte();
+ if (_opcode != 17)
+ res = getVarOrDirectByte(0x80);
+ switch(_opcode&0x1F) {
+ case 1: /* load script */
+ ensureResourceLoaded(2, res);
+ break;
+ case 2: /* load sound */
+ ensureResourceLoaded(4, res);
+ break;
+ case 3: /* load costume */
+ ensureResourceLoaded(3, res);
+ break;
+ case 4: /* load room */
+ ensureResourceLoaded(1, res);
+ break;
+ case 5: /* nuke script */
+ setResourceFlags(2, res, 0x7F);
+ break;
+ case 6: /* nuke sound */
+ setResourceFlags(4, res, 0x7F);
+ break;
+ case 7: /* nuke costume */
+ setResourceFlags(3, res, 0x7F);
+ break;
+ case 8: /* nuke room */
+ setResourceFlags(1, res, 0x7F);
+ break;
+ case 9: /* lock script */
+ if (res >= _numGlobalScripts)
+ break;
+ lock(2,res);
+ break;
+ case 10:/* lock sound */
+ lock(4,res);
+ break;
+ case 11:/* lock costume */
+ lock(3,res);
+ break;
+ case 12:/* lock room */
+ if (res > 0x7F)
+ res = _resourceMapper[res&0x7F];
+ lock(1,res);
+ break;
+ case 13:/* unlock script */
+ if (res >= _numGlobalScripts)
+ break;
+ unlock(2,res);
+ break;
+ case 14:/* unlock sound */
+ unlock(4,res);
+ break;
+ case 15:/* unlock costume */
+ unlock(3,res);
+ break;
+ case 16:/* unlock room */
+ if (res > 0x7F)
+ res = _resourceMapper[res&0x7F];
+ unlock(1,res);
+ break;
+ case 17:/* clear heap */
+ heapClear(0);
+ unkHeapProc2(0,0);
+ break;
+ case 18:/* load charset */
+ loadCharset(res);
+ break;
+ case 19:/* nuke charset */
+ nukeCharset(res);
+ break;
+ case 20:/* ? */
+ unkResProc(getVarOrDirectWord(0x40), res);
+ break;
+ }
+}
+
+void Scumm::o_roomOps() {
+ int a,b,c,d,e;
+
+ _opcode = fetchScriptByte();
+
+ switch(_opcode & 0x1F) {
+ case 1: /* room scroll */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ if (a < 160) a=160;
+ if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
+ if (b < 160) b=160;
+ if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
+ _vars[VAR_CAMERA_MIN] = a;
+ _vars[VAR_CAMERA_MAX] = b;
+ break;
+ case 2: /* room color */
+ error("room-color is no longer a valid command");
+ break;
+
+ case 3: /* set screen */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ initScreens(0,a,320,b);
+ break;
+ case 4: /* set palette color */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ c = getVarOrDirectWord(0x20);
+ _opcode = fetchScriptByte();
+ d = getVarOrDirectByte(0x80);
+ setPalColor(d, a, b, c); /* index, r, g, b */
+ break;
+ case 5: /* shake on */
+ setShake(1);
+ break;
+ case 6: /* shake off */
+ setShake(0);
+ break;
+ case 8: /* room scale? */
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ c = getVarOrDirectByte(0x20);
+ unkRoomFunc2(b, c, a, a, a);
+ break;
+ case 9: /* ? */
+ _saveLoadFlag = getVarOrDirectByte(0x80);
+ _saveLoadData = getVarOrDirectByte(0x40);
+ _saveLoadData = 0; /* TODO: weird behaviour */
+ break;
+ case 10: /* ? */
+ a = getVarOrDirectWord(0x80);
+ if (a) {
+ _switchRoomEffect = (byte)(a);
+ _switchRoomEffect2 = (byte)(a>>8);
+ } else {
+ screenEffect(_newEffect);
+ }
+ break;
+ case 11: /* ? */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ c = getVarOrDirectWord(0x20);
+ _opcode = fetchScriptByte();
+ d = getVarOrDirectByte(0x80);
+ e = getVarOrDirectByte(0x40);
+ unkRoomFunc2(d, e, a, b, c);
+ break;
+ case 12: /* ? */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ c = getVarOrDirectWord(0x20);
+ _opcode = fetchScriptByte();
+ d = getVarOrDirectByte(0x80);
+ e = getVarOrDirectByte(0x40);
+ unkRoomFunc3(d, e, a, b, c);
+ break;
+
+ case 13: /* ? */
+ error("roomops:13 not implemented");
+ break;
+ case 14: /* ? */
+ error("roomops:14 not implemented");
+ break;
+ case 15: /* palmanip? */
+ a = getVarOrDirectByte(0x80);
+ _opcode = fetchScriptByte();
+ b = getVarOrDirectByte(0x80);
+ c = getVarOrDirectByte(0x40);
+ _opcode = fetchScriptByte();
+ d = getVarOrDirectByte(0x80);
+ unkRoomFunc4(b, c, a, d, 1);
+ break;
+
+ case 16: /* ? */
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ if (b!=0)
+ _colorCycleDelays[a] = 0x4000 / (b*0x4C);
+ else
+ _colorCycleDelays[a] = 0;
+ break;
+ }
+}
+
+void Scumm::o_saveRestoreVerbs() {
+ int a,b,c,slot, slot2;
+
+ _opcode = fetchScriptByte();
+
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ c = getVarOrDirectByte(0x20);
+
+ switch(_opcode) {
+ case 1: /* hide verbs */
+ while (a<=b) {
+ slot = getVerbSlot(a,0);
+ if (slot && _verbs[slot].saveid==0) {
+ _verbs[slot].saveid = c;
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+ }
+ a++;
+ }
+ break;
+ case 2: /* show verbs */
+ while (a<=b) {
+ slot = getVerbSlot(a, c);
+ if (slot) {
+ slot2 = getVerbSlot(a,0);
+ if (slot2)
+ killVerb(slot2);
+ slot = getVerbSlot(a,c);
+ _verbs[slot].saveid = 0;
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+ }
+ a++;
+ }
+ break;
+ case 3: /* kill verbs */
+ while (a<=b) {
+ slot = getVerbSlot(a,c);
+ if (slot)
+ killVerb(slot);
+ a++;
+ }
+ break;
+ default:
+ error("o_saveRestoreVerbs: invalid opcode");
+ }
+}
+
+void Scumm::o_setCameraAt() {
+ setCameraAtEx(getVarOrDirectWord(0x80));
+}
+
+void Scumm::o_setObjectName() {
+ int act = getVarOrDirectWord(0x80);
+ int size;
+ int a;
+ int i;
+
+ if (act <= _vars[VAR_NUM_ACTOR])
+ error("Can't set actor %d name with new-name-of", act);
+
+ if (!getObjectAddress(act))
+ error("Can't set name of object %d", act);
+
+ size = READ_BE_UINT32_UNALIGNED(getObjOrActorName(act) - 4)-9;
+ i = 0;
+
+ while ((a = fetchScriptByte()) != 0) {
+ getObjOrActorName(act)[i++] = a;
+
+ if (a==0xFF) {
+ getObjOrActorName(act)[i++] = fetchScriptByte();
+ getObjOrActorName(act)[i++] = fetchScriptByte();
+ getObjOrActorName(act)[i++] = fetchScriptByte();
+ }
+
+ if (i > size)
+ error("New name of object %d too long", act);
+ }
+
+ getObjOrActorName(act)[i] = 0;
+ runHook(0);
+}
+
+void Scumm::o_setOwnerOf() {
+ int obj, owner;
+
+ obj = getVarOrDirectWord(0x80);
+ owner = getVarOrDirectByte(0x40);
+
+ setOwnerOf(obj, owner);
+}
+
+void Scumm::o_setState() {
+ int obj, state;
+ obj = getVarOrDirectWord(0x80);
+ state = getVarOrDirectByte(0x40);
+ putState(obj, state);
+ removeObjectFromRoom(obj);
+ if (_BgNeedsRedraw)
+ clearDrawObjectQueue();
+}
+
+void Scumm::o_setVarRange() {
+ int a,b;
+
+ getResultPos();
+ a=fetchScriptByte();
+ do {
+ if (_opcode&0x80)
+ b=fetchScriptWord();
+ else
+ b=fetchScriptByte();
+
+ setResult(b);
+ _resultVarNumber++;
+ } while (--a);
+}
+
+void Scumm::o_soundKludge() {
+ int16 items[15];
+ int i;
+
+ for (i=0; i<15; i++)
+ items[i] = 0;
+
+ getWordVararg(items);
+
+ soundKludge(items);
+
+}
+
+void Scumm::o_startMusic() {
+ addSoundToQueue(getVarOrDirectByte(0x80));
+}
+
+void Scumm::o_startObject() {
+ int obj, script;
+ int16 data[16];
+
+ obj = getVarOrDirectWord(0x80);
+ script = getVarOrDirectByte(0x40);
+
+ getWordVararg(data);
+ runVerbCode(obj, script, 0, 0, data);
+}
+
+void Scumm::o_startScript() {
+ int op,script;
+ int16 data[16];
+ int a,b;
+
+ op = _opcode;
+ script = getVarOrDirectByte(0x80);
+
+ getWordVararg(data);
+
+ a = b = 0;
+ if (op&0x40) b=1;
+ if (op&0x20) a=1;
+
+ runScript(script, a, b, data);
+}
+
+void Scumm::o_startSound() {
+ addSoundToQueue(getVarOrDirectByte(0x80));
+}
+
+void Scumm::o_stopMusic() {
+ /* TODO: not implemented */
+ warning("o_stopMusic: not implemented");
+}
+
+void Scumm::o_stopObjectCode() {
+ stopObjectCode();
+}
+
+void Scumm::o_stopObjectScript() {
+ stopObjectScript(getVarOrDirectWord(0x80));
+}
+
+void Scumm::o_stopScript() {
+ int script;
+
+ script = getVarOrDirectByte(0x80);
+ if (script==0)
+ stopObjectCode();
+ else
+ stopScriptNr(script);
+}
+
+void Scumm::o_stopSound() {
+ unkSoundProc1(getVarOrDirectByte(0x80));
+}
+
+void Scumm::o_stringOps() {
+ int a,b,c,i;
+ byte *ptr;
+
+ _opcode = fetchScriptByte();
+ switch(_opcode&0x1F) {
+ case 1: /* loadstring */
+ loadPtrToResource(7, getVarOrDirectByte(0x80), NULL);
+ break;
+ case 2: /* copystring */
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ nukeResource(7, a);
+ ptr = getResourceAddress(7, b);
+ if (ptr) loadPtrToResource(7, a, ptr);
+ break;
+ case 3: /* set string char */
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ ptr = getResourceAddress(7, a);
+ if (ptr==NULL) error("String %d does not exist", a);
+ c = getVarOrDirectByte(0x20);
+ ptr[b] = c;
+ break;
+
+ case 4: /* get string char */
+ getResultPos();
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ ptr = getResourceAddress(7, a);
+ if (ptr==NULL) error("String %d does not exist", a);
+ setResult(ptr[b]);
+ break;
+
+ case 5: /* create empty string */
+ a = getVarOrDirectByte(0x80);
+ b = getVarOrDirectByte(0x40);
+ nukeResource(7, a);
+ if (b) {
+ ptr = createResource(7, a, b);
+ if (ptr) {
+ for(i=0; i<b; i++)
+ ptr[i] = 0;
+ }
+ }
+ break;
+ }
+}
+
+void Scumm::o_subtract() {
+ int a;
+ getResultPos();
+ a = getVarOrDirectWord(0x80);
+ setResult(readVar(_resultVarNumber) - a);
+}
+
+void Scumm::o_verbOps() {
+ int verb,slot;
+ VerbSlot *vs;
+ int a,b;
+ byte *ptr;
+
+ verb = getVarOrDirectByte(0x80);
+
+ slot = getVerbSlot(verb,0);
+ checkRange(_maxVerbs-1, 0, slot, "Illegal new verb slot %d");
+
+ vs = &_verbs[slot];
+ vs->verbid = verb;
+
+ while ((_opcode=fetchScriptByte()) != 0xFF) {
+ switch(_opcode&0x1F) {
+ case 1: /* load image */
+ a = getVarOrDirectWord(0x80);
+ if (verb) {
+ setVerbObject(_roomResource, a, verb);
+ vs->type = 1;
+ }
+ break;
+ case 2: /* load from code */
+ loadPtrToResource(8, slot, NULL);
+ if (slot==0)
+ nukeResource(8, slot);
+ vs->type = 0;
+ vs->imgindex = 0;
+ break;
+ case 3: /* color */
+ vs->color = getVarOrDirectByte(0x80);
+ break;
+ case 4: /* set hi color */
+ vs->hicolor = getVarOrDirectByte(0x80);
+ break;
+ case 5: /* set xy */
+ vs->x = getVarOrDirectWord(0x80);
+ vs->y = getVarOrDirectWord(0x40);
+ break;
+ case 6: /* set on */
+ vs->curmode=1;
+ break;
+ case 7: /* set off */
+ vs->curmode=0;
+ break;
+ case 8: /* delete */
+ killVerb(slot);
+ break;
+ case 9: /* new */
+ slot = getVerbSlot(verb, 0);
+ if (slot==0) {
+ for (slot=1; slot<_maxVerbs; slot++) {
+ if(_verbs[slot].verbid==0)
+ break;
+ }
+ if (slot==_maxVerbs)
+ error("Too many verbs");
+ }
+ vs = &_verbs[slot];
+ vs->verbid = verb;
+ vs->color = 2;
+ vs->hicolor = 0;
+ vs->dimcolor = 8;
+ vs->type = 0;
+ vs->charset_nr = string[0].t_charset;
+ vs->curmode = 0;
+ vs->saveid = 0;
+ vs->key = 0;
+ vs->center = 0;
+ vs->imgindex = 0;
+ break;
+
+ case 16: /* set dim color */
+ vs->dimcolor = getVarOrDirectByte(0x80);
+ break;
+ case 17: /* dim */
+ vs->curmode = 2;
+ break;
+ case 18: /* set key */
+ vs->key = getVarOrDirectByte(0x80);
+ break;
+ case 19: /* set center */
+ vs->center = 1;
+ break;
+ case 20: /* set to string */
+ ptr = getResourceAddress(7, getVarOrDirectWord(0x80));
+ if (!ptr)
+ nukeResource(8, slot);
+ else {
+ loadPtrToResource(8, slot, ptr);
+ }
+ if (slot==0)
+ nukeResource(8, slot);
+ vs->type = 0;
+ vs->imgindex = 0;
+ break;
+ case 22: /* assign object */
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectByte(0x40);
+ if (slot && vs->imgindex!=a) {
+ setVerbObject(b, a, slot);
+ vs->type = 1;
+ vs->imgindex = a;
+ }
+ break;
+ case 23: /* set back color */
+ vs->bkcolor = getVarOrDirectByte(0x80);
+ break;
+ }
+ }
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+}
+
+void Scumm::o_wait() {
+ byte *oldaddr;
+
+ oldaddr = _scriptPointer - 1;
+
+ _opcode = fetchScriptByte();
+ switch(_opcode&0x1F) {
+ case 1: /* wait for actor */
+ if (derefActorSafe(getVarOrDirectByte(0x80), "o_wait")->moving)
+ break;
+ return;
+ case 2: /* wait for message */
+ if (_vars[VAR_HAVE_MSG])
+ break;
+ return;
+ case 3: /* wait for camera */
+ if (camera._curPos>>3 != camera._destPos>>3)
+ break;
+ return;
+ case 4: /* wait for sentence */
+ if (_sentenceIndex!=0xFF) {
+ if (sentence[_sentenceIndex].unk &&
+ !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) )
+ return;
+ break;
+ }
+ if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]))
+ return;
+ break;
+ default:
+ error("o_wait: default case");
+ return;
+ }
+
+ _scriptPointer = oldaddr;
+ o_breakHere();
+}
+
+void Scumm::o_walkActorTo() {
+ int x, y;
+ Actor *a;
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorTo");
+ x = getVarOrDirectWord(0x40);
+ y = getVarOrDirectWord(0x20);
+ startWalkActor(a, x, y, 0xFF);
+}
+
+void Scumm::o_walkActorToActor() {
+ int b,x,y;
+ Actor *a, *a2;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToActor");
+ if (a->room != _currentRoom) {
+ getVarOrDirectByte(0x40);
+ fetchScriptByte();
+ return;
+ }
+
+ a2 = derefActorSafe(getVarOrDirectByte(0x40), "o_walkActorToActor(2)");
+ if (a2->room != _currentRoom) {
+ fetchScriptByte();
+ return;
+ }
+ b = fetchScriptByte(); /* distance from actor */
+ if (b==0xFF) {
+ b = a2->scalex * a->width / 0xFF;
+ b = b + b/2;
+ }
+ x = a2->x;
+ y = a2->y;
+ if (x < a->x)
+ x += b;
+ else
+ x -= b;
+
+ startWalkActor(a, x, y, 0xFF);
+}
+
+void Scumm::o_walkActorToObject() {
+ int obj;
+ Actor *a;
+
+ a = derefActorSafe(getVarOrDirectByte(0x80), "o_walkActorToObject");
+ obj = getVarOrDirectWord(0x40);
+ if (whereIsObject(obj)!=-1) {
+ getObjectXYPos(obj);
+ startWalkActor(a, _xPos, _yPos, _dir);
+ }
+}
+
+int Scumm::getWordVararg(int16 *ptr) {
+ int i;
+ for (i=0; i<16; i++)
+ ptr[i] = 0;
+
+ i = 0;
+ while ((_opcode = fetchScriptByte()) != 0xFF) {
+ ptr[i++] = getVarOrDirectWord(0x80);
+ }
+ return i;
+}
+
+int Scumm::getVarOrDirectWord(byte mask) {
+ if (_opcode&mask)
+ return readVar(fetchScriptWord());
+ return (int16)fetchScriptWord();
+}
+
+int Scumm::getVarOrDirectByte(byte mask) {
+ if (_opcode&mask)
+ return readVar(fetchScriptWord());
+ return fetchScriptByte();
+}
+
+void Scumm::decodeParseString() {
+ int textSlot;
+
+ switch(_actorToPrintStrFor) {
+ case 252:
+ textSlot = 3;
+ break;
+ case 253:
+ textSlot = 2;
+ break;
+ case 254:
+ textSlot = 1;
+ break;
+ default:
+ textSlot = 0;
+ }
+
+ string[textSlot].xpos = string[textSlot].t_xpos;
+ string[textSlot].ypos = string[textSlot].t_ypos;
+ string[textSlot].center = string[textSlot].t_center;
+ string[textSlot].overhead = string[textSlot].t_overhead;
+ string[textSlot].right = string[textSlot].t_right;
+ string[textSlot].color = string[textSlot].t_color;
+ string[textSlot].charset = string[textSlot].t_charset;
+
+ while((_opcode=fetchScriptByte()) != 0xFF) {
+ switch(_opcode&0xF) {
+ case 0: /* set string xy */
+ string[textSlot].xpos = getVarOrDirectWord(0x80);
+ string[textSlot].ypos = getVarOrDirectWord(0x40);
+ string[textSlot].overhead = 0;
+ break;
+ case 1: /* color */
+ string[textSlot].color = getVarOrDirectByte(0x80);
+ break;
+ case 2: /* right */
+ string[textSlot].right = getVarOrDirectWord(0x80);
+ break;
+ case 4: /* center*/
+ string[textSlot].center = 1;
+ string[textSlot].overhead = 0;
+ break;
+ case 6: /* left */
+ string[textSlot].center = 0;
+ string[textSlot].overhead = 0;
+ break;
+ case 7: /* overhead */
+ string[textSlot].overhead = 1;
+ break;
+ case 8: /* ignore */
+ getVarOrDirectWord(0x80);
+ getVarOrDirectWord(0x40);
+ break;
+ case 15:
+ _messagePtr = _scriptPointer;
+ switch(textSlot) {
+ case 0: actorTalk(); break;
+ case 1: drawString(1); break;
+ case 2: unkMessage1(); break;
+ case 3: unkMessage2(); break;
+ }
+ _scriptPointer = _messagePtr;
+ return;
+ default:
+ return;
+ }
+ }
+
+ string[textSlot].t_xpos = string[textSlot].xpos;
+ string[textSlot].t_ypos = string[textSlot].ypos;
+ string[textSlot].t_center = string[textSlot].center;
+ string[textSlot].t_overhead = string[textSlot].overhead;
+ string[textSlot].t_right = string[textSlot].right;
+ string[textSlot].t_color = string[textSlot].color;
+ string[textSlot].t_charset = string[textSlot].charset;
+}
+
+
+#endif \ No newline at end of file
diff --git a/script_v2.cpp b/script_v2.cpp
new file mode 100644
index 0000000000..d27bfd2507
--- /dev/null
+++ b/script_v2.cpp
@@ -0,0 +1,2124 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ *
+ * 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.
+ *
+ * Change Log:
+ * $Log$
+ * Revision 1.1 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
+ */
+
+
+#include "stdafx.h"
+#include "scumm.h"
+
+#if defined(DOTT)
+
+void Scumm::setupOpcodes2() {
+ static const OpcodeProc opcode_list[256] = {
+ /* 00 */
+ &Scumm::o2_pushByte,
+ &Scumm::o2_pushWord,
+ &Scumm::o2_pushByteVar,
+ &Scumm::o2_pushWordVar,
+ /* 04 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayRead,
+ &Scumm::o2_wordArrayRead,
+ /* 08 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayIndexedRead,
+ &Scumm::o2_wordArrayIndexedRead,
+ /* 0C */
+ &Scumm::o2_dup,
+ &Scumm::o2_zero,
+ &Scumm::o2_eq,
+ &Scumm::o2_neq,
+ /* 10 */
+ &Scumm::o2_gt,
+ &Scumm::o2_lt,
+ &Scumm::o2_le,
+ &Scumm::o2_ge,
+ /* 14 */
+ &Scumm::o2_add,
+ &Scumm::o2_sub,
+ &Scumm::o2_mul,
+ &Scumm::o2_div,
+ /* 18 */
+ &Scumm::o2_land,
+ &Scumm::o2_lor,
+ &Scumm::o2_kill,
+ &Scumm::o2_invalid,
+ /* 1C */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 20 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 24 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 28 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 2C */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 30 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 34 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 38 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 3C */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* 40 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_writeByteVar,
+ &Scumm::o2_writeWordVar,
+ /* 44 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayWrite,
+ &Scumm::o2_wordArrayWrite,
+ /* 48 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayIndexedWrite,
+ &Scumm::o2_wordArrayIndexedWrite,
+ /* 4C */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteVarInc,
+ &Scumm::o2_wordVarInc,
+ /* 50 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayInc,
+ &Scumm::o2_wordArrayInc,
+ /* 54 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteVarDec,
+ &Scumm::o2_wordVarDec,
+ /* 58 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_byteArrayDec,
+ &Scumm::o2_wordArrayDec,
+ /* 5C */
+ &Scumm::o2_jumpTrue,
+ &Scumm::o2_jumpFalse,
+ &Scumm::o2_startScriptEx,
+ &Scumm::o2_startScript,
+ /* 60 */
+ &Scumm::o2_startObject,
+ &Scumm::o2_setObjectState,
+ &Scumm::o2_setObjectXY,
+ &Scumm::o2_invalid,
+ /* 64 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_stopObjectCode,
+ &Scumm::o2_stopObjectCode,
+ &Scumm::o2_endCutscene,
+ /* 68 */
+ &Scumm::o2_cutScene,
+ &Scumm::o2_stopMusic,
+ &Scumm::o2_freezeUnfreeze,
+ &Scumm::o2_cursorCommand,
+ /* 6C */
+ &Scumm::o2_breakHere,
+ &Scumm::o2_ifClassOfIs,
+ &Scumm::o2_setClass,
+ &Scumm::o2_getState,
+ /* 70 */
+ &Scumm::o2_setState,
+ &Scumm::o2_setOwner,
+ &Scumm::o2_getOwner,
+ &Scumm::o2_jump,
+ /* 74 */
+ &Scumm::o2_startSound,
+ &Scumm::o2_stopSound,
+ &Scumm::o2_startMusic,
+ &Scumm::o2_stopObjectScript,
+ /* 78 */
+ &Scumm::o2_panCameraTo,
+ &Scumm::o2_actorFollowCamera,
+ &Scumm::o2_setCameraAt,
+ &Scumm::o2_loadRoom,
+ /* 7C */
+ &Scumm::o2_stopScript,
+ &Scumm::o2_walkActorToObj,
+ &Scumm::o2_walkActorTo,
+ &Scumm::o2_putActorInRoom,
+ /* 80 */
+ &Scumm::o2_putActorAtObject,
+ &Scumm::o2_faceActor,
+ &Scumm::o2_animateActor,
+ &Scumm::o2_doSentence,
+ /* 84 */
+ &Scumm::o2_pickupObject,
+ &Scumm::o2_loadRoomWithEgo,
+ &Scumm::o2_invalid,
+ &Scumm::o2_getRandomNumber,
+ /* 88 */
+ &Scumm::o2_getRandomNumberRange,
+ &Scumm::o2_invalid,
+ &Scumm::o2_getActorMoving,
+ &Scumm::o2_getScriptRunning,
+ /* 8C */
+ &Scumm::o2_getActorRoom,
+ &Scumm::o2_getObjectX,
+ &Scumm::o2_getObjectY,
+ &Scumm::o2_getObjectDir,
+ /* 90 */
+ &Scumm::o2_getActorWalkBox,
+ &Scumm::o2_getActorCostume,
+ &Scumm::o2_findInventory,
+ &Scumm::o2_getInventoryCount,
+ /* 94 */
+ &Scumm::o2_getVerbFromXY,
+ &Scumm::o2_beginOverride,
+ &Scumm::o2_endOverride,
+ &Scumm::o2_setObjectName,
+ /* 98 */
+ &Scumm::o2_isSoundRunning,
+ &Scumm::o2_setBoxFlags,
+ &Scumm::o2_createBoxMatrix,
+ &Scumm::o2_resourceRoutines,
+ /* 9C */
+ &Scumm::o2_roomOps,
+ &Scumm::o2_actorSet,
+ &Scumm::o2_verbOps,
+ &Scumm::o2_getActorFromXY,
+ /* A0 */
+ &Scumm::o2_findObject,
+ &Scumm::o2_pseudoRoom,
+ &Scumm::o2_getActorElevation,
+ &Scumm::o2_getVerbEntrypoint,
+ /* A4 */
+ &Scumm::o2_arrayOps,
+ &Scumm::o2_saveRestoreVerbs,
+ &Scumm::o2_drawBox,
+ &Scumm::o2_invalid,
+ /* A8 */
+ &Scumm::o2_getActorWidth,
+ &Scumm::o2_wait,
+ &Scumm::o2_getActorScaleX,
+ &Scumm::o2_getActorAnimCounter1,
+ /* AC */
+ &Scumm::o2_soundKludge,
+ &Scumm::o2_isAnyOf,
+ &Scumm::o2_quitPauseRestart,
+ &Scumm::o2_isActorInBox,
+ /* B0 */
+ &Scumm::o2_delay,
+ &Scumm::o2_delayLonger,
+ &Scumm::o2_delayVeryLong,
+ &Scumm::o2_stopSentence,
+ /* B4 */
+ &Scumm::o2_print_0,
+ &Scumm::o2_print_1,
+ &Scumm::o2_print_2,
+ &Scumm::o2_print_3,
+ /* B8 */
+ &Scumm::o2_printActor,
+ &Scumm::o2_printEgo,
+ &Scumm::o2_talkActor,
+ &Scumm::o2_talkEgo,
+ /* BC */
+ &Scumm::o2_dim,
+ &Scumm::o2_invalid,
+ &Scumm::o2_runVerbCodeQuick,
+ &Scumm::o2_runScriptQuick,
+ /* C0 */
+ &Scumm::o2_dim2,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* C4 */
+ &Scumm::o2_abs,
+ &Scumm::o2_distObjectObject,
+ &Scumm::o2_distObjectPt,
+ &Scumm::o2_distPtPt,
+ /* C8 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_miscOps,
+ &Scumm::o2_breakMaybe,
+ &Scumm::o2_pickOneOf,
+ /* CC */
+ &Scumm::o2_pickOneOfDefault,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* D0 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* D4 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* D8 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* DC */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* E0 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* E4 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* E8 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* EC */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* F0 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* F4 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* F8 */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ /* FC */
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ &Scumm::o2_invalid,
+ };
+
+ _opcodes = opcode_list;
+}
+
+int Scumm::readArray(int array, int index, int base) {
+ ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array));
+
+ assert(ah);
+
+ base += index*ah->dim1_size;
+
+ assert(base>=0 && base < ah->dim1_size*ah->dim2_size);
+
+ if (ah->type==4) {
+ return ah->data[base];
+ } else {
+ return (int16)READ_LE_UINT16(ah->data + base*2);
+ }
+}
+
+void Scumm::writeArray(int array, int index, int base, int value) {
+ ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array));
+ assert(ah);
+ base += index*ah->dim1_size;
+
+ assert(base>=0 && base < ah->dim1_size*ah->dim2_size);
+
+ if (ah->type==4) {
+ ah->data[base] = value;
+ } else {
+ ((uint16*)ah->data)[base] = TO_LE_16(value);
+ }
+}
+
+int Scumm::getStackList(int16 *args, uint maxnum) {
+ uint num, i;
+
+ for (i=0; i<maxnum; i++)
+ args[i] = 0;
+
+ num = pop();
+
+ if (num > maxnum)
+ error("Too many items %d in stack list, max %d", num, maxnum);
+
+ i = num;
+ while (((int)--i)>=0) {
+ args[i] = pop();
+ }
+
+ return num;
+}
+
+void Scumm::o2_pushByte() {
+ push(fetchScriptByte());
+}
+
+void Scumm::o2_pushWord() {
+ push((int16)fetchScriptWord());
+}
+
+void Scumm::o2_pushByteVar() {
+ push(readVar(fetchScriptByte()));
+}
+
+void Scumm::o2_pushWordVar() {
+ push(readVar(fetchScriptWord()));
+}
+
+void Scumm::o2_invalid() {
+ error("Invalid opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer);
+}
+
+void Scumm::o2_byteArrayRead() {
+ int base = pop();
+ push(readArray(fetchScriptByte(), 0, base));
+}
+
+void Scumm::o2_wordArrayRead() {
+ int base = pop();
+ push(readArray(fetchScriptWord(), 0, base));
+}
+
+void Scumm::o2_byteArrayIndexedRead() {
+ int base = pop();
+ int index = pop();
+ push(readArray(fetchScriptByte(), index, base));
+}
+
+void Scumm::o2_wordArrayIndexedRead() {
+ int base = pop();
+ int index = pop();
+ push(readArray(fetchScriptWord(), index, base));
+}
+
+void Scumm::o2_dup() {
+ int a = pop();
+ push(a);
+ push(a);
+}
+
+void Scumm::o2_zero() {
+ push( pop() == 0 );
+}
+
+void Scumm::o2_eq() {
+ push( pop() == pop() );
+}
+
+void Scumm::o2_neq() {
+ push( pop() != pop() );
+}
+
+void Scumm::o2_gt() {
+ int a = pop();
+ push( pop() > a );
+}
+
+void Scumm::o2_lt() {
+ int a = pop();
+ push( pop() < a );
+}
+
+void Scumm::o2_le() {
+ int a = pop();
+ push( pop() <= a );
+}
+
+void Scumm::o2_ge() {
+ int a = pop();
+ push( pop() >= a );
+}
+
+void Scumm::o2_add() {
+ int a = pop();
+ push( pop() + a );
+}
+
+void Scumm::o2_sub() {
+ int a = pop();
+ push( pop() - a );
+}
+
+void Scumm::o2_mul() {
+ int a = pop();
+ push( pop() * a );
+}
+
+void Scumm::o2_div() {
+ int a = pop();
+ if (a==0) error("division by zero");
+ push( pop() / a );
+}
+
+void Scumm::o2_land() {
+ int a = pop();
+ push( pop() && a );
+}
+
+void Scumm::o2_lor() {
+ int a = pop();
+ push( pop() || a );
+}
+
+void Scumm::o2_kill() {
+ pop();
+}
+
+void Scumm::o2_writeByteVar() {
+ writeVar(fetchScriptByte(), pop());
+}
+
+void Scumm::o2_writeWordVar() {
+ writeVar(fetchScriptWord(), pop());
+}
+
+void Scumm::o2_byteArrayWrite() {
+ int a = pop();
+ writeArray(fetchScriptByte(), 0, pop(), a);
+}
+
+void Scumm::o2_wordArrayWrite() {
+ int a = pop();
+ writeArray(fetchScriptWord(), 0, pop(), a);
+}
+
+void Scumm::o2_byteArrayIndexedWrite() {
+ int val = pop();
+ int base = pop();
+ writeArray(fetchScriptByte(), pop(), base, val);
+}
+
+void Scumm::o2_wordArrayIndexedWrite() {
+ int val = pop();
+ int base = pop();
+ writeArray(fetchScriptWord(), pop(), base, val);
+}
+
+void Scumm::o2_byteVarInc() {
+ int var = fetchScriptByte();
+ writeVar(var,readVar(var)+1);
+}
+
+void Scumm::o2_wordVarInc() {
+ int var = fetchScriptWord();
+ writeVar(var,readVar(var)+1);
+}
+
+void Scumm::o2_byteArrayInc() {
+ int var = fetchScriptByte();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) + 1);
+}
+
+void Scumm::o2_wordArrayInc() {
+ int var = fetchScriptWord();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) + 1);
+}
+
+
+void Scumm::o2_byteVarDec() {
+ int var = fetchScriptByte();
+ writeVar(var,readVar(var)-1);
+}
+
+void Scumm::o2_wordVarDec() {
+ int var = fetchScriptWord();
+ writeVar(var,readVar(var)-1);
+}
+
+void Scumm::o2_byteArrayDec() {
+ int var = fetchScriptByte();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) - 1);
+}
+
+void Scumm::o2_wordArrayDec() {
+ int var = fetchScriptWord();
+ int base = pop();
+ writeArray(var, 0, base, readArray(var, 0, base) - 1);
+}
+
+void Scumm::o2_jumpTrue() {
+ if (pop())
+ o2_jump();
+ else
+ fetchScriptWord();
+}
+
+void Scumm::o2_jumpFalse() {
+ if (!pop())
+ o2_jump();
+ else
+ fetchScriptWord();
+}
+
+void Scumm::o2_jump() {
+ _scriptPointer += (int16)fetchScriptWord();
+}
+
+void Scumm::o2_startScriptEx() {
+ int16 args[16];
+ int script,flags;
+
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ script = pop();
+ flags = pop();
+ runScript(script, flags&1, flags&2, args);
+}
+
+void Scumm::o2_startScript() {
+ int16 args[16];
+ int script;
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ script = pop();
+ runScript(script, 0, 0, args);
+}
+
+void Scumm::o2_startObject() {
+ int16 args[16];
+ int script,entryp;
+ int flags;
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ entryp = pop();
+ script = pop();
+ flags = pop();
+ runVerbCode(script, entryp, flags&1, flags&2, args);
+}
+
+void Scumm::o2_setObjectState() {
+ int a = pop();
+ if (a==0) a=1;
+ setObjectState(pop(), a, -1, -1);
+}
+
+void Scumm::o2_setObjectXY() {
+ int y = pop();
+ int x = pop();
+ setObjectState(pop(), 1, x, y);
+}
+
+void Scumm::o2_stopObjectCode() {
+ stopObjectCode();
+}
+
+void Scumm::o2_endCutscene() {
+ endCutscene();
+}
+
+void Scumm::o2_cutScene() {
+ int16 args[16];
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ cutscene(args);
+}
+
+void Scumm::o2_stopMusic() {
+ warning("o2_stopMusic: not implemented");
+}
+
+void Scumm::o2_freezeUnfreeze() {
+ int a = pop();
+ if (a)
+ freezeScripts(a);
+ else
+ unfreezeScripts();
+}
+
+void Scumm::o2_cursorCommand() {
+ int a,num,i;
+ int16 args[16];
+
+ switch(fetchScriptByte()) {
+ case 0x90:
+ _cursorState = 1;
+ verbMouseOver(0);
+ break;
+ case 0x91:
+ _cursorState = 0;
+ verbMouseOver(0);
+ break;
+ case 0x92:
+ _userPut = 1;
+ break;
+ case 0x93:
+ _userPut = 0;
+ break;
+ case 0x94:
+ _cursorState++;
+ if (_cursorState > 1)
+ error("Cursor state greater than 1 in script");
+ verbMouseOver(0);
+ break;
+ case 0x95:
+ _cursorState--;
+ verbMouseOver(0);
+ break;
+ case 0x96:
+ _userPut++;
+ break;
+ case 0x97:
+ _userPut--;
+ break;
+ case 0x99:
+ a = pop();
+ setCursorImg(a, pop());
+ break;
+ case 0x9A:
+ a = pop();
+ setCursorHotspot2(pop(),a);
+ break;
+ case 0x9C: /* init charset */
+ initCharset(pop());
+ break;
+ case 0x9D: /* set charset colors */
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ for (i=0; i<16; i++)
+ charset._colorMap[i] = _charsetData[string[1].t_charset][i] = args[i];
+ break;
+ case 0xD6:
+ new_unk_1(pop());
+ break;
+ }
+
+ _vars[VAR_CURSORSTATE] = _cursorState;
+ _vars[VAR_USERPUT] = _userPut;
+}
+
+void Scumm::o2_breakHere() {
+ updateScriptPtr();
+ _currentScript = 0xFF;
+}
+
+void Scumm::o2_ifClassOfIs() {
+ int16 args[16];
+ int num,obj,cls;
+ bool b;
+ int cond = 1;
+
+ num = getStackList(args,sizeof(args)/sizeof(args[0]));
+ obj = pop();
+
+ while (--num>=0) {
+ cls = args[num];
+ b = getClass(obj, cls);
+ if (cls&0x80 && !b || !(cls&0x80) && b)
+ cond = 0;
+ }
+ push(cond);
+}
+
+void Scumm::o2_setClass() {
+ int16 args[16];
+ int num,obj,cls;
+
+ num = getStackList(args,sizeof(args)/sizeof(args[0]));
+ obj = pop();
+
+ while (--num>=0) {
+ cls = args[num];
+ if (cls==0)
+ _classData[num] = 0;
+ else if (cls&0x80)
+ putClass(obj, cls, 1);
+ else
+ putClass(obj, cls, 0);
+ }
+}
+
+void Scumm::o2_getState() {
+ push(getState(pop()));
+}
+
+void Scumm::o2_setState() {
+ int state = pop();
+ int obj = pop();
+
+ putState(obj, state);
+ removeObjectFromRoom(obj);
+ if (_BgNeedsRedraw)
+ clearDrawObjectQueue();
+}
+
+void Scumm::o2_setOwner() {
+ int owner = pop();
+ int obj = pop();
+
+ setOwnerOf(obj, owner);
+}
+
+void Scumm::o2_getOwner() {
+ push(getOwner(pop()));
+}
+
+void Scumm::o2_startSound() {
+ addSoundToQueue(pop());
+}
+
+void Scumm::o2_stopSound() {
+ unkSoundProc1(pop());
+}
+
+void Scumm::o2_startMusic() {
+ addSoundToQueue(pop());
+}
+
+void Scumm::o2_stopObjectScript() {
+ stopObjectScript(pop());
+}
+
+void Scumm::o2_panCameraTo() {
+ panCameraTo(pop());
+}
+
+void Scumm::o2_actorFollowCamera() {
+ actorFollowCamera(pop());
+}
+
+void Scumm::o2_setCameraAt() {
+ setCameraAtEx(pop());
+}
+
+void Scumm::o2_loadRoom() {
+ int room = pop();
+ debug(1,"Loading room %d", room);
+ startScene(room, 0, 0);
+ _fullRedraw = 1;
+}
+
+void Scumm::o2_stopScript() {
+ int script = pop();
+ if (script==0)
+ stopObjectCode();
+ else
+ stopScriptNr(script);
+}
+
+void Scumm::o2_walkActorToObj() {
+ int obj,dist;
+ Actor *a, *a2;
+ int x;
+
+ dist = pop();
+ obj = pop();
+ a = derefActorSafe(pop(), "o2_walkActorToObj");
+
+ if (obj >= 17) {
+ if (whereIsObject(obj)==-1)
+ return;
+ getObjectXYPos(obj);
+ startWalkActor(a, _xPos, _yPos, _dir);
+ } else {
+ a2 = derefActorSafe(obj, "o2_walkActorToObj(2)");
+ if (a2->room != _currentRoom ||
+ a->room != _currentRoom)
+ return;
+ if (dist==0) {
+ dist = a2->scalex * a2->width / 0xFF;
+ dist += dist>>1;
+ }
+ x = a2->x;
+ if (x < a->x)
+ x += dist;
+ else
+ x -= dist;
+ startWalkActor(a, x, a2->y, 0xFF);
+ }
+}
+
+void Scumm::o2_walkActorTo() {
+ int x,y;
+ y = pop();
+ x = pop();
+ startWalkActor(derefActorSafe(pop(), "o2_walkActorTo"), x, y, 0xFF);
+}
+
+void Scumm::o2_putActorInRoom() {
+ int room, x, y;
+ Actor *a;
+
+ room = pop();
+ y = pop();
+ x = pop();
+ a = derefActorSafe(pop(), "o2_putActorInRoom");
+ if (room==0xFF) {
+ room = a->room;
+ } else {
+ if (a->visible && _currentRoom != room && _vars[VAR_TALK_ACTOR]==a->number) {
+ clearMsgQueue();
+ }
+ if (room != 0)
+ a->room = room;
+ }
+ putActor(a, x, y, room);
+}
+
+void Scumm::o2_putActorAtObject() {
+ int room,obj,x,y;
+ Actor *a;
+
+ room = pop();
+ obj = pop();
+
+ a = derefActorSafe(pop(), "o2_putActorAtObject");
+ if (whereIsObject(obj)!=-1) {
+ getObjectXYPos(obj);
+ x = _xPos;
+ y = _yPos;
+ } else {
+ x = 160;
+ y = 120;
+ }
+ if (room == 0xFF)
+ room = a->room;
+ putActor(a, x, y, room);
+}
+
+void Scumm::o2_faceActor() {
+ int act,obj;
+ obj = pop();
+ act = pop();
+ faceActorToObj(act, obj);
+}
+
+void Scumm::o2_animateActor() {
+ int anim = pop();
+ int act = pop();
+ animateActor(act, anim);
+}
+
+void Scumm::o2_doSentence() {
+ int a,b,c;
+ SentenceTab *st;
+
+ a = pop();
+ pop(); //dummy pop
+ b = pop();
+ c = pop();
+
+ st = &sentence[++_sentenceIndex];
+
+ st->unk5 = c;
+ st->unk4 = b;
+ st->unk3 = a;
+
+ if (!(st->unk3&0xFF00))
+ st->unk2 = 0;
+ else
+ st->unk2 = 1;
+
+ st->unk = 0;
+}
+
+void Scumm::o2_pickupObject() {
+ int obj, room;
+
+ room = pop();
+ obj = pop();
+
+ if (room==0)
+ room = _roomResource;
+ addObjectToInventory(obj, room);
+ putOwner(obj, _vars[VAR_UNK_ACTOR]);
+ putClass(obj, 32, 1);
+ putState(obj, 1);
+ removeObjectFromRoom(obj);
+ clearDrawObjectQueue();
+ runHook(obj); /* Difference */
+}
+
+void Scumm::o2_loadRoomWithEgo() {
+ Actor *a;
+ int room,obj,x,y;
+
+ y = pop();
+ x = pop();
+ room = pop();
+ obj = pop();
+
+ a = derefActorSafe(_vars[VAR_UNK_ACTOR], "o_loadRoomWithEgo");
+
+ putActor(a, 0, 0, room);
+ dseg_3A76 = 0;
+ _vars[VAR_WALKTO_OBJ] = obj;
+ startScene(a->room, a, obj);
+ _vars[VAR_WALKTO_OBJ] = 0;
+
+ /* startScene maybe modifies VAR_UNK_ACTOR, i hope not */
+ camera._destPos = camera._curPos = a->x;
+ setCameraFollows(a);
+ _fullRedraw=1;
+ if (x != -1) {
+ startWalkActor(a, x, y, 0xFF);
+ }
+}
+
+void Scumm::o2_getRandomNumber() {
+ int rnd;
+ rnd = getRandomNumber(pop()+1);
+ _vars[VAR_RANDOM_NR] = rnd;
+ push(rnd);
+}
+
+void Scumm::o2_getRandomNumberRange() {
+ int max = pop();
+ int min = pop();
+ int rnd = getRandomNumber(max-min+1) + min;
+ _vars[VAR_RANDOM_NR] = rnd;
+ push(rnd);
+}
+
+void Scumm::o2_getActorMoving() {
+ push(derefActorSafe(pop(),"o2_getActorMoving")->moving);
+}
+
+void Scumm::o2_getScriptRunning() {
+ push(getScriptRunning(pop()));
+}
+
+void Scumm::o2_getActorRoom() {
+ push(derefActorSafe(pop(),"o2_getActorRoom")->room);
+}
+
+void Scumm::o2_getObjectX() {
+ push(getObjX(pop()));
+}
+
+void Scumm::o2_getObjectY() {
+ push(getObjY(pop()));
+}
+
+void Scumm::o2_getObjectDir() {
+ push(getObjDir(pop()));
+}
+
+void Scumm::o2_getActorWalkBox() {
+ push(derefActorSafe(pop(),"o2_getActorWalkBox")->walkbox);
+}
+
+void Scumm::o2_getActorCostume() {
+ push(derefActorSafe(pop(),"o2_getActorCostume")->costume);
+}
+
+void Scumm::o2_findInventory() {
+ int index = pop();
+ int owner = pop();
+ push(findInventory(owner,index));
+}
+
+void Scumm::o2_getInventoryCount() {
+ push(getInventoryCount(pop()));
+}
+
+void Scumm::o2_getVerbFromXY() {
+ int y = pop();
+ int x = pop();
+ int over = checkMouseOver(x,y);
+ if (over)
+ over = _verbs[over].verbid;
+ push(over);
+}
+
+void Scumm::o2_beginOverride() {
+ beginOverride();
+}
+
+void Scumm::o2_endOverride() {
+ endOverride();
+}
+
+void Scumm::o2_setObjectName() {
+ int obj = pop();
+ int i;
+
+ if (obj <= _vars[VAR_NUM_ACTOR])
+ error("Can't set actor %d name with new-name-of", obj);
+
+ if (!getObjectAddress(obj))
+ error("Can't set name of object %d", obj);
+
+ for (i=1; i<50; i++) {
+ if (_newNames[i] == obj) {
+ nukeResource(16, i);
+ _newNames[i] = 0;
+ break;
+ }
+ }
+
+ for (i=1; i<50; i++) {
+ if (_newNames[i] == 0) {
+ loadPtrToResource(16, i, NULL);
+ _newNames[i] = obj;
+ runHook(0);
+ return;
+ }
+ }
+
+ error("New name of %d overflows name table (max = %d)", obj, 50);
+}
+
+void Scumm::o2_isSoundRunning() {
+ int snd = pop();
+ if (snd)
+ snd = unkSoundProc23(snd);
+ push(snd);
+}
+
+void Scumm::o2_setBoxFlags() {
+ int16 table[65];
+ int num,value;
+
+ value = pop();
+ num = getStackList(table,sizeof(table)/sizeof(table[0]));
+
+ while (--num>=0) {
+ setBoxFlags(table[num], value);
+ }
+}
+
+void Scumm::o2_createBoxMatrix() {
+ createBoxMatrix();
+}
+
+void Scumm::o2_resourceRoutines() {
+ int res;
+
+ switch(fetchScriptByte()) {
+ case 100: /* load script */
+ res = pop();
+ ensureResourceLoaded(2, res);
+ break;
+ case 101: /* load sound */
+ res = pop();
+ ensureResourceLoaded(4, res);
+ break;
+ case 102: /* load costume */
+ res = pop();
+ ensureResourceLoaded(3, res);
+ break;
+ case 103: /* load room */
+ res = pop();
+ ensureResourceLoaded(1, res);
+ break;
+ case 104: /* nuke script */
+ res = pop();
+ setResourceFlags(2, res, 0x7F);
+ break;
+ case 105: /* nuke sound */
+ res = pop();
+ setResourceFlags(4, res, 0x7F);
+ break;
+ case 106: /* nuke costume */
+ res = pop();
+ setResourceFlags(3, res, 0x7F);
+ break;
+ case 107: /* nuke room */
+ res = pop();
+ setResourceFlags(1, res, 0x7F);
+ break;
+ case 108: /* lock script */
+ res = pop();
+ if (res >= _numGlobalScripts)
+ break;
+ lock(2,res);
+ break;
+ case 109:/* lock sound */
+ res = pop();
+ lock(4,res);
+ break;
+ case 110:/* lock costume */
+ res = pop();
+ lock(3,res);
+ break;
+ case 111:/* lock room */
+ res = pop();
+ if (res > 0x7F)
+ res = _resourceMapper[res&0x7F];
+ lock(1,res);
+ break;
+ case 112:/* unlock script */
+ res = pop();
+ if (res >= _numGlobalScripts)
+ break;
+ unlock(2,res);
+ break;
+ case 113:/* unlock sound */
+ res = pop();
+ unlock(4,res);
+ break;
+ case 114:/* unlock costume */
+ res = pop();
+ unlock(3,res);
+ break;
+ case 115:/* unlock room */
+ res = pop();
+ if (res > 0x7F)
+ res = _resourceMapper[res&0x7F];
+ unlock(1,res);
+ break;
+ case 116:/* clear heap */
+ /* this is actually a scumm message */
+ error("clear heap not working yet");
+ break;
+ case 117:/* load charset */
+ res = pop();
+ loadCharset(res);
+ break;
+ case 118:/* nuke charset */
+ warning("popping extra argument in nukeCharset");
+ res = pop();
+ nukeCharset(res);
+ break;
+ case 119:/* ? */
+ res = pop();
+ unkResProc(pop(), res);
+ break;
+ default:
+ error("o2_resourceRoutines: default case");
+ }
+}
+
+void Scumm::o2_roomOps() {
+ int a,b,c,d,e;
+
+ switch(fetchScriptByte()) {
+ case 172: /* room scroll */
+ b = pop();
+ a = pop();
+ if (a < 160) a=160;
+ if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
+ if (b < 160) b=160;
+ if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
+ _vars[VAR_CAMERA_MIN] = a;
+ _vars[VAR_CAMERA_MAX] = b;
+ break;
+
+ case 174: /* set screen */
+ b = pop();
+ a = pop();
+ initScreens(0,a,320,b);
+ break;
+
+ case 175: /* set palette color */
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ setPalColor(d, a, b, c);
+ break;
+
+ case 176: /* shake on */
+ setShake(1);
+ break;
+
+ case 177: /* shake off */
+ setShake(0);
+ break;
+
+ case 179:
+ c = pop();
+ b = pop();
+ a = pop();
+ unkRoomFunc2(b,c,a,a,a);
+ break;
+
+ case 180:
+ _saveLoadData = pop();
+ _saveLoadFlag = pop();
+ warning("o2_roomops:180: partially unimplemented");
+ break;
+
+ case 181:
+ a = pop();
+ if (a) {
+ _switchRoomEffect = (byte)(a);
+ _switchRoomEffect2 = (byte)(a>>8);
+ } else {
+ screenEffect(_newEffect);
+ }
+ break;
+
+ case 182:
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ unkRoomFunc2(d, e, a, b, c);
+ break;
+
+ case 183:
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ unkRoomFunc3(d, e, a, b, c);
+ break;
+
+ case 184:
+ error("save string not implemented");
+ break;
+
+ case 185:
+ error("load string not implemented");
+ break;
+
+ case 186: /* palmanip? */
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ unkRoomFunc4(a, b, c, d, 1);
+ break;
+
+ case 187: /* color cycle delay */
+ b = pop();
+ a = pop();
+ if (b!=0)
+ _colorCycleDelays[a] = 0x4000 / (b*0x4C);
+ else
+ _colorCycleDelays[a] = 0;
+ break;
+
+ case 213: /* set palette */
+ setPalette(pop());
+ break;
+
+ default:
+ error("o2_roomOps: default case");
+ }
+}
+
+void Scumm::o2_actorSet() {
+ Actor *a;
+ int i,j,k;
+ int16 args[8];
+ byte b;
+
+ b = fetchScriptByte();
+ if (b==197) {
+ _curActor = pop();
+ return;
+ }
+
+ a = derefActorSafe(_curActor, "o2_actorSet");
+
+ switch(b) {
+ case 76: /* actor-costume */
+ setActorCostume(a, pop());
+ break;
+ case 77: /* actor-speed */
+ j = pop();
+ i = pop();
+ setActorWalkSpeed(a, i, j);
+ break;
+ case 78: /* actor-sound */
+ k = getStackList(args, sizeof(args)/sizeof(args[0]));
+ for (i=0; i<k; i++)
+ a->sound[i] = args[i];
+ break;
+ case 79: /* actor-walkframe */
+ a->walkFrame = pop();
+ break;
+ case 80: /* actor-talkframe */
+ a->talkFrame2 = pop();
+ a->talkFrame1 = pop();
+ break;
+ case 81: /* actor-standframe */
+ a->standFrame = pop();
+ break;
+ case 82:
+ pop();
+ pop();
+ pop();
+ break;
+ case 83:
+ initActor(a, 0);
+ break;
+ case 84: /* actor-elevation */
+ a->elevation = pop();
+ a->needRedraw = true;
+ a->needBgReset = true;
+ break;
+ case 85: /* actor-defaultanims */
+ a->initFrame = 1;
+ a->walkFrame = 2;
+ a->standFrame = 3;
+ a->talkFrame1 = 4;
+ a->talkFrame2 = 5;
+ break;
+ case 86: /* actor-palette */
+ j = pop();
+ i = pop();
+ checkRange(31, 0, i, "Illegal palet slot %d");
+ a->palette[i] = j;
+ a->needRedraw = true;
+ break;
+ case 87: /* actor-talkcolor */
+ a->talkColor = pop();
+ break;
+ case 88: /* actor-name */
+ loadPtrToResource(9, a->number, NULL);
+ break;
+ case 89: /* actor-initframe */
+ a->initFrame = pop();
+ break;
+ case 91:
+ a->width = pop();
+ break;
+ case 92:
+ a->scalex = a->scaley = pop();
+ a->needRedraw = true;
+ a->needBgReset = true;
+ break;
+ case 93:
+ a->neverZClip = 0;
+ break;
+ case 94:
+ a->neverZClip = pop();
+ break;
+ case 95:
+ a->ignoreBoxes = 1;
+ a->neverZClip = 0;
+FixRooms:;
+ if (a->room==_currentRoom)
+ putActor(a, a->x, a->y, a->room);
+ break;
+ case 96:
+ a->ignoreBoxes = 0;
+ a->neverZClip = 0;
+ goto FixRooms;
+ case 97:
+ a->animSpeed = pop();
+ a->animProgress = 0;
+ break;
+ case 98:
+ a->data8 = pop();
+ break;
+ case 99:
+ a->new_1 = pop();
+ a->new_2 = pop();
+ break;
+ case 215:
+ a->new_3 = 1;
+ break;
+ case 216:
+ a->new_3 = 0;
+ break;
+ case 217:
+ initActor(a, 2);
+ break;
+ default:
+ error("o2_actorset: default case");
+ }
+}
+
+void Scumm::o2_verbOps() {
+ int slot,a,b;
+ VerbSlot *vs;
+ byte *ptr, op;
+
+ op = fetchScriptByte();
+ if(op==196) {
+ _curVerb = pop();
+ _curVerbSlot = getVerbSlot(_curVerb, 0);
+ checkRange(_maxVerbs-1,0,_curVerbSlot,"Illegal new verb slot %d");
+ return;
+ }
+ vs = &_verbs[_curVerbSlot];
+ slot = _curVerbSlot;
+ switch(op) {
+ case 124: /* load img */
+ a = pop();
+ if (_curVerbSlot) {
+ setVerbObject(_roomResource,a,slot);
+ vs->type=1;
+ }
+ break;
+ case 125:
+ loadPtrToResource(8, slot, NULL);
+ vs->type = 0;
+ vs->imgindex = 0;
+ break;
+ case 126:
+ vs->color = pop();
+ break;
+ case 127:
+ vs->hicolor = pop();
+ break;
+ case 128:
+ vs->y = pop();
+ vs->x = pop();
+ break;
+ case 129:
+ vs->curmode = 1;
+ break;
+ case 130:
+ vs->curmode = 0;
+ break;
+ case 131:
+ killVerb(slot);
+ break;
+ case 132:
+ slot = getVerbSlot(_curVerb, 0);
+ if (slot==0) {
+ for (slot=1; slot<_maxVerbs; slot++) {
+ if(_verbs[slot].verbid==0)
+ break;
+ }
+ if (slot==_maxVerbs)
+ error("Too many verbs");
+ _curVerbSlot = slot;
+ }
+ vs = &_verbs[slot];
+ vs->verbid = _curVerb;
+ vs->color = 2;
+ vs->hicolor = 0;
+ vs->dimcolor = 8;
+ vs->type = 0;
+ vs->charset_nr = string[0].t_charset;
+ vs->curmode = 0;
+ vs->saveid = 0;
+ vs->key = 0;
+ vs->center = 0;
+ vs->imgindex = 0;
+ break;
+ case 133:
+ vs->dimcolor = pop();
+ break;
+ case 134:
+ vs->curmode = 2;
+ break;
+ case 135:
+ vs->key = pop();
+ break;
+ case 136:
+ vs->center = 1;
+ break;
+ case 137:
+ a = pop();
+ if (a==0) {
+ ptr = (byte*)"";
+ } else {
+ ptr = getResourceAddress(7, a);
+ }
+ loadPtrToResource(8, slot, ptr);
+ vs->type = 0;
+ vs->imgindex = 0;
+ break;
+ case 139:
+ b = pop();
+ a = pop();
+ if (slot && a != vs->imgindex) {
+ setVerbObject(b, a, slot);
+ vs->type = 1;
+ vs->imgindex = a;
+ }
+ break;
+ case 140:
+ vs->bkcolor = pop();
+ break;
+ case 255:
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+ break;
+ default:
+ error("o2_verbops: default case");
+ }
+}
+
+void Scumm::o2_getActorFromXY() {
+ int y = pop();
+ int x = pop();
+ push(getActorFromPos(x,y));
+}
+
+void Scumm::o2_findObject() {
+ int y = pop();
+ int x = pop();
+ int r = findObject(x,y);
+ push(r);
+}
+
+void Scumm::o2_pseudoRoom() {
+ int16 list[100];
+ int num,a,value;
+
+ num = getStackList(list,sizeof(list)/sizeof(list[0]));
+ value = pop();
+
+ while (--num>=0) {
+ a = list[num];
+ if (a > 0x7F)
+ _resourceMapper[a&0x7F] = value;
+ }
+}
+
+void Scumm::o2_getActorElevation() {
+ push(derefActorSafe(pop(),"o2_getActorElevation")->elevation);
+}
+
+void Scumm::o2_getVerbEntrypoint() {
+ int e = pop();
+ int v = pop();
+ push(getVerbEntrypoint(v,e));
+}
+
+void Scumm::o2_arrayOps() {
+ int a,b,c,d,num;
+ int16 list[128];
+
+ switch(fetchScriptByte()) {
+ case 205:
+ a = fetchScriptWord();
+ pop();
+ arrayop_1(a, NULL);
+ break;
+ case 208:
+ a = fetchScriptWord();
+ b = pop();
+ c = pop();
+ d = readVar(a);
+ if (d==0) {
+ defineArray(a, 5, 0, b+c);
+ }
+ while (c--) {
+ writeArray(a, 0, b+c, pop());
+ }
+ break;
+ case 212:
+ a = fetchScriptWord();
+ b = pop();
+ num = getStackList(list,sizeof(list)/sizeof(list[0]));
+ d = readVar(a);
+ if (d==0)
+ error("Must DIM a two dimensional array before assigning");
+ c = pop();
+ while (--num>=0) {
+ writeArray(a, c, b+num, list[num]);
+ }
+ break;
+ default:
+ error("o2_arrayOps: default case");
+ }
+}
+
+void Scumm::o2_saveRestoreVerbs() {
+ int a,b,c;
+ int slot,slot2;
+
+ c = pop();
+ b = pop();
+ a = pop();
+
+ switch(fetchScriptByte()) {
+ case 141:
+ while (a<=b) {
+ slot = getVerbSlot(a,0);
+ if (slot && _verbs[slot].saveid==0) {
+ _verbs[slot].saveid = c;
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+ }
+ a++;
+ }
+ break;
+ case 142:
+ while (a<=b) {
+ slot = getVerbSlot(a, c);
+ if (slot) {
+ slot2 = getVerbSlot(a,0);
+ if (slot2)
+ killVerb(slot2);
+ slot = getVerbSlot(a,c);
+ _verbs[slot].saveid = 0;
+ drawVerb(slot, 0);
+ verbMouseOver(0);
+ }
+ a++;
+ }
+ break;
+ case 143:
+ while (a<=b) {
+ slot = getVerbSlot(a,c);
+ if (slot)
+ killVerb(slot);
+ a++;
+ }
+ break;
+ default:
+ error("o2_saveRestoreVerbs: default case");
+ }
+}
+
+void Scumm::o2_drawBox() {
+ int x,y,x2,y2,color;
+ color = pop();
+ y2 = pop();
+ x2 = pop();
+ y = pop();
+ x = pop();
+ drawBox(x, y, x2, y2, color);
+}
+
+void Scumm::o2_getActorWidth() {
+ push(derefActorSafe(pop(),"o2_getActorWidth")->width);
+}
+
+void Scumm::o2_wait() {
+ byte oldaddr;
+
+ switch(fetchScriptByte()) {
+ case 168:
+ if (derefActorSafe(pop(), "o2_wait")->moving) {
+ _scriptPointer += (int16)fetchScriptWord();
+ o2_breakHere();
+ } else {
+ fetchScriptWord();
+ }
+ return;
+ case 169:
+ if (_vars[VAR_HAVE_MSG])
+ break;
+ return;
+ case 170:
+ if (camera._curPos>>3 != camera._destPos>>3)
+ break;
+ return;
+ case 171:
+ if (_sentenceIndex!=0xFF) {
+ if (sentence[_sentenceIndex].unk &&
+ !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) )
+ return;
+ break;
+ }
+ if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]))
+ return;
+ break;
+ default:
+ error("o2_wait: default case");
+ }
+
+ _scriptPointer -= 2;
+ o2_breakHere();
+}
+
+void Scumm::o2_getActorScaleX() {
+ push(derefActorSafe(pop(),"o2_getActorScale")->scalex);
+}
+
+void Scumm::o2_getActorAnimCounter1() {
+ push(derefActorSafe(pop(),"o2_getActorAnimCounter")->cost.animCounter1);
+}
+
+void Scumm::o2_soundKludge() {
+ int16 list[8];
+ getStackList(list,sizeof(list)/sizeof(list[0]));
+ soundKludge(list);
+}
+
+void Scumm::o2_isAnyOf() {
+ int16 list[100];
+ int num;
+ int16 val;
+
+ num = getStackList(list,sizeof(list)/sizeof(list[0]));
+ val = pop();
+
+ while (--num>=0) {
+ if (list[num] == val) {
+ push(1);
+ return;
+ }
+ }
+ push(0);
+ return;
+}
+
+void Scumm::o2_quitPauseRestart() {
+ switch(fetchScriptByte()) {
+ case 158:
+ pauseGame(0);
+ break;
+ case 160:
+ shutDown(0);
+ break;
+ default:
+ error("o2_quitPauseRestart: invalid case");
+ }
+}
+
+void Scumm::o2_isActorInBox() {
+ int box = pop();
+ Actor *a = derefActorSafe(pop(), "o2_isActorInBox");
+ push(checkXYInBoxBounds(box, a->x, a->y));
+}
+
+void Scumm::o2_delay() {
+ uint32 delay = (uint16)pop();
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o2_breakHere();
+}
+
+void Scumm::o2_delayLonger() {
+ uint32 delay = (uint16)pop() * 60;
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o2_breakHere();
+}
+
+void Scumm::o2_delayVeryLong() {
+ uint32 delay = (uint16)pop() * 3600;
+ vm.slot[_currentScript].delay = delay;
+ vm.slot[_currentScript].status = 1;
+ o2_breakHere();
+}
+
+void Scumm::o2_stopSentence() {
+ _sentenceIndex = 0xFF;
+ stopScriptNr(_vars[VAR_SENTENCE_SCRIPT]);
+ clearClickedStatus();
+}
+
+void Scumm::o2_print_0() {
+ _actorToPrintStrFor = 0xFF;
+ decodeParseString2(0,0);
+}
+
+void Scumm::o2_print_1() {
+ decodeParseString2(1,0);
+}
+
+void Scumm::o2_print_2() {
+ decodeParseString2(2,0);
+}
+
+void Scumm::o2_print_3() {
+ decodeParseString2(3,0);
+}
+
+void Scumm::o2_printActor() {
+ decodeParseString2(0,1);
+}
+
+void Scumm::o2_printEgo() {
+ push(_vars[VAR_UNK_ACTOR]);
+ decodeParseString2(0,1);
+}
+
+void Scumm::o2_talkActor() {
+ _actorToPrintStrFor = pop();
+ _messagePtr = _scriptPointer;
+ setStringVars(0);
+ actorTalk();
+ _scriptPointer = _messagePtr;
+}
+
+void Scumm::o2_talkEgo() {
+ _actorToPrintStrFor = _vars[VAR_UNK_ACTOR];
+ _messagePtr = _scriptPointer;
+ setStringVars(0);
+ actorTalk();
+ _scriptPointer = _messagePtr;
+}
+
+void Scumm::o2_dim() {
+ byte b;
+ int data;
+
+ switch(fetchScriptByte()) {
+ case 199:
+ data = 5;
+ break;
+ case 200:
+ data = 1;
+ break;
+ case 201:
+ data = 2;
+ break;
+ case 202:
+ data = 3;
+ break;
+ case 203:
+ data = 4;
+ break;
+ case 204:
+ nukeArray(fetchScriptWord());
+ return;
+ default:
+ error("o2_dim: default case");
+ }
+
+ defineArray(fetchScriptWord(), data, 0, pop());
+}
+
+void Scumm::o2_runVerbCodeQuick() {
+ int16 args[16];
+ int script,entryp;
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ entryp = pop();
+ script = pop();
+ runVerbCode(script, entryp, 0, 1, args);
+}
+
+void Scumm::o2_runScriptQuick() {
+ int16 args[16];
+ int script;
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ script = pop();
+ runScript(script, 0, 1, args);
+}
+
+void Scumm::o2_dim2() {
+ int a,b,data;
+ switch(fetchScriptByte()) {
+ case 199:
+ data = 5;
+ break;
+ case 200:
+ data = 1;
+ break;
+ case 201:
+ data = 2;
+ break;
+ case 202:
+ data = 3;
+ break;
+ case 203:
+ data = 4;
+ break;
+ default:
+ error("o2_dim2: default case");
+ }
+
+ b = pop();
+ a = pop();
+ defineArray(fetchScriptWord(), data, a, b);
+}
+
+void Scumm::o2_abs() {
+ push(abs(pop()));
+}
+
+
+void Scumm::o2_distObjectObject() {
+ int a,b;
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(true, a, 0, true, b, 0));
+}
+
+void Scumm::o2_distObjectPt() {
+ int a,b,c;
+ c = pop();
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(true, a, 0, false, b, c));
+}
+
+void Scumm::o2_distPtPt() {
+ int a,b,c,d;
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ push(getDistanceBetween(false, a, b, false, c, d));
+}
+
+void Scumm::o2_dummy_stacklist() {
+ error("opcode o2_dummy_stacklist invalid");
+}
+
+void Scumm::o2_miscOps() {
+ int16 args[30];
+ int i;
+
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ switch(args[0]) {
+ case 3:
+ warning("o2_miscOps: nothing in 3");
+ break;
+ case 4:
+ unkMiscOp4(args[1], args[2], args[3], args[4]);
+ break;
+ case 5:
+ unkVirtScreen4(args[1]);
+ break;
+ case 6:
+ _fullRedraw = 1;
+ redrawBGAreas();
+ for (i=0; i<13; i++)
+ derefActor(i)->needRedraw = true;
+ processActors();
+ screenEffect(args[1]);
+ break;
+ case 8:
+ startManiac();
+ break;
+ case 9:
+ unkMiscOp9();
+ break;
+ }
+}
+
+void Scumm::o2_breakMaybe() {
+ ScriptSlot *ss = &vm.slot[_currentScript];
+ if (ss->newfield == 0) {
+ ss->newfield = pop();
+ } else {
+ ss->newfield--;
+ }
+ if (ss->newfield) {
+ _scriptPointer--;
+ o2_breakHere();
+ }
+}
+
+void Scumm::o2_pickOneOf() {
+ int16 args[100];
+ int i,num;
+
+ num = getStackList(args,sizeof(args)/sizeof(args[0]));
+ i = pop();
+ if (i<0 || i>=num)
+ error("o2_pickOneOf: out of range");
+ push(args[i]);
+}
+
+void Scumm::o2_pickOneOfDefault() {
+ int16 args[100];
+ int i,num,def;
+
+ def = pop();
+ num = getStackList(args,sizeof(args)/sizeof(args[0]));
+ i = pop();
+ if (i<0 || i>=num)
+ i = def;
+ else
+ i = args[i];
+ push(i);
+}
+
+void Scumm::decodeParseString2(int m, int n) {
+ byte b;
+
+ b = fetchScriptByte();
+
+ switch(b) {
+ case 65:
+ string[m].ypos = pop();
+ string[m].xpos = pop();
+ string[m].overhead = 0;
+ break;
+ case 66:
+ string[m].color = pop();
+ break;
+ case 67:
+ string[m].right = pop();
+ break;
+ case 69:
+ string[m].center = 1;
+ string[m].overhead = 0;
+ break;
+ case 71:
+ string[m].center = 0;
+ string[m].overhead = 0;
+ break;
+ case 72:
+ string[m].overhead = 1;
+ string[m].new_3 = 0;
+ break;
+ case 73:
+ error("decodeParseString2: case 73");
+ break;
+ case 74:
+ string[m].new_3 = 1;
+ break;
+ case 75:
+ _messagePtr = _scriptPointer;
+ switch(m) {
+ case 0: actorTalk(); break;
+ case 1: drawString(1); break;
+ case 2: unkMessage1(); break;
+ case 3: unkMessage2(); break;
+ }
+ _scriptPointer = _messagePtr;
+ return;
+
+ case 0xFE:
+ setStringVars(m);
+ if (n)
+ _actorToPrintStrFor = pop();
+ return;
+ case 0xFF:
+ string[m].t_xpos = string[m].xpos;
+ string[m].t_ypos = string[m].ypos;
+ string[m].t_center = string[m].center;
+ string[m].t_overhead = string[m].overhead;
+ string[m].t_new3 = string[m].new_3;
+ string[m].t_right = string[m].right;
+ string[m].t_color = string[m].color;
+ string[m].t_charset = string[m].charset;
+ return;
+ default:
+ error("decodeParseString: default case");
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/scumm.h b/scumm.h
index ab63389218..680f6cd47a 100644
--- a/scumm.h
+++ b/scumm.h
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.8 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.7 2001/10/11 12:07:35 strigeus
* Determine caption from file name.
*
@@ -129,6 +132,7 @@ struct ScriptSlot {
uint32 offs;
int32 delay;
uint16 number;
+ uint16 newfield;
byte status;
byte type;
byte unk1,unk2,freezeCount,didexec;
@@ -146,6 +150,25 @@ struct ResHeader {
uint32 size;
};
+#if defined(DOTT)
+class ObjectData {
+public:
+ uint32 offs_obim_to_room;
+ uint32 offs_obcd_to_room;
+ uint16 cdhd_10, cdhd_12;
+ uint16 obj_nr;
+ int16 x_pos;
+ int16 y_pos;
+ uint16 numstrips;
+ uint16 height;
+ byte actordir;
+ byte parent;
+ byte parentstate;
+ byte ownerstate;
+ byte fl_object_index;
+ byte unk_3;
+};
+#else
class ObjectData {
public:
uint32 offs_obim_to_room;
@@ -154,15 +177,16 @@ public:
uint16 obj_nr;
byte x_pos;
byte y_pos;
- byte numstrips;
- byte height;
+ uint16 numstrips;
+ uint16 height;
byte actordir;
- byte parentstate;
byte parent;
+ byte parentstate;
byte ownerstate;
byte fl_object_index;
byte unk_3;
};
+#endif
struct RoomHeader {
uint32 tag, size;
@@ -170,22 +194,43 @@ struct RoomHeader {
uint16 numObjects;
};
+#if !defined(DOTT)
struct CodeHeader { /* file format */
uint32 id;
uint32 size;
uint16 obj_id;
byte x,y,w,h;
byte flags;
- byte unk1;
+ byte parent;
uint16 unk2;
uint16 unk3;
- byte unk4;
+ byte actordir;
+};
+#else
+struct CodeHeader { /* file format */
+ uint32 id;
+ uint32 size;
+ uint16 obj_id;
+ int16 x, y;
+ uint16 w,h;
+ byte flags, parent;
+ uint16 unk2;
+ uint16 unk3;
+ byte actordir;
};
+#endif
struct ImageHeader { /* file format */
uint32 id;
uint32 size;
uint16 obj_id;
+ uint16 unk[5];
+ uint16 img_w;
+ uint16 img_h;
+ uint16 unk_2;
+ struct {
+ int16 x,y;
+ } hotspot[15];
};
#pragma END_PACK_STRUCTS
@@ -208,6 +253,7 @@ struct SaveLoadEntry {
enum {
sleByte = 1,
+ sleUint8 = 1,
sleInt16 = 2,
sleUint16 = 3,
sleInt32 = 4,
@@ -287,6 +333,10 @@ enum ScummVars {
VAR_CUTSCENEEXIT_KEY = 24,
VAR_TALKSTOP_KEY = 57,
VAR_SAVELOADDIALOG_KEY = 50,
+
+#if defined(DOTT)
+ VAR_RANDOM_NR = 118,
+#endif
};
#define _maxRooms res.num[1]
@@ -308,6 +358,7 @@ enum ScummVars {
#define _baseScripts res.address[2]
#define _baseInventoryItems res.address[5]
#define _baseFLObject res.address[13]
+#define _baseArrays res.address[7]
#define _roomFileOffsets res.roomoffs[1]
@@ -322,7 +373,7 @@ struct CharsetRenderer {
bool _hasMask;
int _strLeft, _strRight, _strTop, _strBottom;
- int _mask_bottom, _mask_right, _mask_top, _mask_left;
+// int _mask_bottom, _mask_right, _mask_top, _mask_left;
byte _curId;
byte _bufPos;
@@ -413,11 +464,11 @@ struct Actor {
uint width;
byte number;
byte facing;
- byte costume;
+ uint16 costume;
byte room;
byte talkColor;
byte scalex,scaley;
- byte charset,sound;
+ byte charset;
byte newDirection;
byte moving;
byte ignoreBoxes;
@@ -430,6 +481,9 @@ struct Actor {
byte walkbox;
byte mask;
byte animProgress, animSpeed;
+ int16 new_1,new_2;
+ byte new_3;
+ byte sound[8];
ActorWalkData walkdata;
CostumeData cost;
byte palette[32];
@@ -442,6 +496,34 @@ struct CameraData {
uint16 _movingToActor;
};
+#define ARRAY_HDR_SIZE 6
+struct ArrayHeader {
+ int16 dim1_size;
+ int16 type;
+ int16 dim2_size;
+ byte data[1];
+};
+
+struct SentenceTab {
+ byte unk5;
+ byte unk2;
+ uint16 unk4;
+ uint16 unk3;
+ byte unk;
+ byte pad;
+};
+
+struct StringTab {
+ int16 t_xpos, t_ypos, t_center, t_overhead;
+ int16 t_new3, t_right, t_color, t_charset;
+ int16 xpos, ypos;
+ int16 xpos2,ypos2;
+ int16 center, overhead;
+ int16 new_3, right;
+ int16 color,charset;
+ int16 mask_top, mask_bottom, mask_right, mask_left;
+};
+
struct Scumm {
int _lastLoadedRoom;
int _roomResource;
@@ -459,13 +541,41 @@ struct Scumm {
int _keyPressed;
+ uint16 *_inventory;
+ byte *_arrays;
+ VerbSlot *_verbs;
+ ObjectData *_objs;
+ uint16 *_newNames;
+ int16 *_vars;
+ byte *_bitVars;
+
+ const OpcodeProc *_opcodes;
+
+ byte _curActor;
+ int _curVerb;
+ int _curVerbSlot;
+
+ int _curPalIndex;
+
+ int _numVariables;
+ int _numBitVariables;
+ int _numLocalObjects;
+ int _numGlobalObjects;
+ int _numArray;
+ int _numVerbs;
+ int _numFlObject;
+ int _numInventory;
+ int _numRooms;
+ int _numScripts;
+ int _numSounds;
+ int _numCharsets;
+ int _numCostumes;
+
uint8 *_roomFileIndexes;
byte *_objectFlagTable;
uint32 *_classData;
- byte _numGlobalScriptsUsed;
-
- uint16 _maxNrObjects;
+ byte _numGlobalScripts;
uint16 _numZBuffer;
@@ -509,8 +619,6 @@ struct Scumm {
uint32 _localScriptList[0x39];
- uint16 _inventory[0x50];
-
uint16 _debugMode;
byte *_messagePtr;
@@ -543,12 +651,13 @@ struct Scumm {
int _numInMsgStack;
- VerbSlot verbs[102];
+// VerbSlot verbs[102];
VirtScreen virtscr[4];
uint32 _ENCD_offs, _EXCD_offs;
uint32 _CLUT_offs, _EPAL_offs;
uint32 _IM00_offs;
+ uint32 _PALS_offs;
int _drawObjectQueNr;
byte _drawObjectQue[0xC8];
@@ -556,7 +665,6 @@ struct Scumm {
uint16 _currentDrive;
uint16 _soundCardType;
uint16 _videoMode;
- uint16 _heapSpace;
byte _mousePresent;
int16 _palManipStart;
@@ -564,19 +672,17 @@ struct Scumm {
int16 _palManipCounter;
struct {
- byte mode[16];
- uint16 num[16];
- uint32 tags[16];
- const char *name[16];
- byte **address[16];
- byte *flags[16];
- byte *roomno[16];
- uint32 *roomoffs[16];
+ byte mode[17];
+ uint16 num[17];
+ uint32 tags[17];
+ const char *name[17];
+ byte **address[17];
+ byte *flags[17];
+ byte *roomno[17];
+ uint32 *roomoffs[17];
} res;
struct {
- int16 vars[801];
- byte bitvars[256];
uint32 cutScenePtr[5];
byte cutSceneScript[5];
int16 cutSceneData[5];
@@ -592,16 +698,6 @@ struct Scumm {
} mouse;
struct {
- int16 x[6];
- int16 y[6];
- int16 center[6];
- int16 overhead[6];
- int16 right[6];
- int16 color[6];
- int16 charset[6];
- } textslot;
-
- struct {
byte *readPtr;
uint16 readOffs;
uint16 drawY;
@@ -644,7 +740,7 @@ struct Scumm {
Actor actor[13];
- uint16 actorDrawBits[160];
+ uint16 actorDrawBits[200];
struct {
int upperLeftX;
@@ -691,12 +787,21 @@ struct Scumm {
uint16 _imgBufOffs[4];
byte _sentenceIndex;
+ SentenceTab sentence[6];
+
+
+#if 0
byte _sentenceTab[6];
byte _sentenceTab2[6];
uint16 _sentenceTab3[6];
uint16 _sentenceTab4[6];
byte _sentenceTab5[6];
+#endif
+
+ StringTab string[6];
+#if 0
+// int _stringXPos[4], _stringYPos[4];
uint16 _stringOverhead[6];
uint16 _stringCenter[6];
uint16 _stringRight[6];
@@ -708,10 +813,11 @@ struct Scumm {
int16 _stringXpos2[6];
int16 _stringYpos2[6];
+#endif
CostumeRenderer cost;
- ObjectData objs[184];
+// ObjectData objs[184];
int16 _soundQuePos;
int16 _soundQue[0x100];
@@ -748,7 +854,7 @@ struct Scumm {
bool _BgNeedsRedraw;
- int _stringXPos[4], _stringYPos[4];
+
int16 _localParamList[16];
@@ -760,7 +866,7 @@ struct Scumm {
uint16 _lastKeyHit;
int _scummStackPos;
- int16 _scummStack[0x15];
+ int16 _scummStack[100];
int _maxBoxVertexHeap;
byte *_boxMatrixPtr4, *_boxMatrixPtr1, *_boxMatrixPtr3;
@@ -769,12 +875,14 @@ struct Scumm {
byte *_msgPtrToAdd;
+ OpcodeProc getOpcode(int i) { return _opcodes[i]; }
+
void openRoom(int room);
void deleteRoomOffsets();
void readRoomsOffsets();
void askForDisk();
- void readIndexFile(int i);
+
bool openResourceFile(const char *filename);
void fileClose(void *file);
@@ -897,6 +1005,7 @@ struct Scumm {
int getVarOrDirectWord(byte mask);
int getVarOrDirectByte(byte mask);
int readVar(uint var);
+ void writeVar(uint var, int value);
void getResultPos();
void setResult(int result);
@@ -1004,6 +1113,150 @@ struct Scumm {
void o_walkActorToActor();
void o_walkActorToObject();
+ void o2_pushByte();
+ void o2_pushWord();
+ void o2_pushByteVar();
+ void o2_pushWordVar();
+ void o2_invalid();
+ void o2_byteArrayRead();
+ void o2_wordArrayRead();
+ void o2_byteArrayIndexedRead();
+ void o2_wordArrayIndexedRead();
+ void o2_dup();
+ void o2_zero();
+ void o2_eq();
+ void o2_neq();
+ void o2_gt();
+ void o2_lt();
+ void o2_le();
+ void o2_ge();
+ void o2_add();
+ void o2_sub();
+ void o2_mul();
+ void o2_div();
+ void o2_land();
+ void o2_lor();
+ void o2_kill();
+ void o2_writeByteVar();
+ void o2_writeWordVar();
+ void o2_byteArrayWrite();
+ void o2_wordArrayWrite();
+ void o2_byteArrayIndexedWrite();
+ void o2_wordArrayIndexedWrite();
+ void o2_byteVarInc();
+ void o2_wordVarInc();
+ void o2_byteArrayInc();
+ void o2_wordArrayInc();
+ void o2_byteVarDec();
+ void o2_wordVarDec();
+ void o2_byteArrayDec();
+ void o2_wordArrayDec();
+ void o2_jumpTrue();
+ void o2_jumpFalse();
+ void o2_jump();
+ void o2_startScriptEx();
+ void o2_startScript();
+ void o2_startObject();
+ void o2_setObjectState();
+ void o2_setObjectXY();
+ void o2_stopObjectCode();
+ void o2_endCutscene();
+ void o2_cutScene();
+ void o2_stopMusic();
+ void o2_freezeUnfreeze();
+ void o2_cursorCommand();
+ void o2_breakHere();
+ void o2_ifClassOfIs();
+ void o2_setClass();
+ void o2_getState();
+ void o2_setState();
+ void o2_setOwner();
+ void o2_getOwner();
+ void o2_startSound();
+ void o2_stopSound();
+ void o2_startMusic();
+ void o2_stopObjectScript();
+ void o2_panCameraTo();
+ void o2_actorFollowCamera();
+ void o2_setCameraAt();
+ void o2_loadRoom();
+ void o2_stopScript();
+ void o2_walkActorToObj();
+ void o2_walkActorTo();
+ void o2_putActorInRoom();
+ void o2_putActorAtObject();
+ void o2_faceActor();
+ void o2_animateActor();
+ void o2_doSentence();
+ void o2_pickupObject();
+ void o2_loadRoomWithEgo();
+ void o2_getRandomNumber();
+ void o2_getRandomNumberRange();
+ void o2_getActorMoving();
+ void o2_getScriptRunning();
+ void o2_getActorRoom();
+ void o2_getObjectX();
+ void o2_getObjectY();
+ void o2_getObjectDir();
+ void o2_getActorWalkBox();
+ void o2_getActorCostume();
+ void o2_findInventory();
+ void o2_getInventoryCount();
+ void o2_getVerbFromXY();
+ void o2_beginOverride();
+ void o2_endOverride();
+ void o2_setObjectName();
+ void o2_isSoundRunning();
+ void o2_setBoxFlags();
+ void o2_createBoxMatrix();
+ void o2_resourceRoutines();
+ void o2_roomOps();
+ void o2_actorSet();
+ void o2_verbOps();
+ void o2_getActorFromXY();
+ void o2_findObject();
+ void o2_pseudoRoom();
+ void o2_getActorElevation();
+ void o2_getVerbEntrypoint();
+ void o2_arrayOps();
+ void o2_saveRestoreVerbs();
+ void o2_drawBox();
+ void o2_getActorWidth();
+ void o2_wait();
+ void o2_getActorScaleX();
+ void o2_getActorAnimCounter1();
+ void o2_soundKludge();
+ void o2_isAnyOf();
+ void o2_quitPauseRestart();
+ void o2_isActorInBox();
+ void o2_delay();
+ void o2_delayLonger();
+ void o2_delayVeryLong();
+ void o2_stopSentence();
+ void o2_print_0();
+ void o2_print_1();
+ void o2_print_2();
+ void o2_print_3();
+ void o2_printActor();
+ void o2_printEgo();
+ void o2_talkActor();
+ void o2_talkEgo();
+ void o2_dim();
+ void o2_runVerbCodeQuick();
+ void o2_runScriptQuick();
+ void o2_dim2();
+ void o2_abs();
+ void o2_distObjectObject();
+ void o2_distObjectPt();
+ void o2_distPtPt();
+ void o2_dummy_stacklist();
+ void o2_miscOps();
+ void o2_breakMaybe();
+ void o2_pickOneOf();
+ void o2_pickOneOfDefault();
+
+ void soundKludge(int16 *list);
+
void stopObjectCode();
void stopObjectScript(int script);
void putActor(Actor *a, int x, int y, byte room);
@@ -1148,8 +1401,8 @@ struct Scumm {
void setActorCostume(Actor *a, int c);
void loadPtrToResource(int type, int i, byte *ptr);
- void stackPush(int a);
- int stackPop();
+ void push(int a);
+ int pop();
void walkActorTo(Actor *a, int x, int y, int direction);
@@ -1182,7 +1435,7 @@ struct Scumm {
byte *getObjectAddress(int obj);
byte *getObjOrActorName(int obj);
void clearOwnerOf(int obj);
- void runVERBCode(int script, int entry, int a, int b, int16 *vars);
+ void runVerbCode(int script, int entry, int a, int b, int16 *vars);
void unkSoundProc1(int a);
void setVerbObject(int room, int object, int verb);
void unkMessage1();
@@ -1207,8 +1460,6 @@ struct Scumm {
int getKeyInput(int a);
void convertKeysToClicks();
- OpcodeProc getOpcode(int i);
-
void drawBox(int x, int y, int x2, int y2, int color);
void drawMouse();
@@ -1226,6 +1477,7 @@ struct Scumm {
void saveLoadBytes(void *b, int len);
void saveLoadResource(int type, int index);
bool isResourceLoaded(int type, int index);
+ void saveLoadArrayOf(void *b, int len, int datasize, byte filetype);
void saveLoadEntries(void *d, const SaveLoadEntry *sle);
@@ -1256,6 +1508,67 @@ struct Scumm {
void showHelpAndExit();
char *getGameName();
+
+ void setupOpcodes();
+ void setupOpcodes2();
+ void endCutscene();
+ void cutscene(int16 *args);
+
+ void setOwnerOf(int obj, int owner);
+ void panCameraTo(int x);
+ void actorFollowCamera(int act);
+ void setCameraAtEx(int at);
+
+ void setCursorHotspot2(int x,int y);
+
+ void new_unk_1(int a);
+
+ void faceActorToObj(int act, int obj);
+ void animateActor(int act, int anim);
+ int getScriptRunning(int script);
+ int getObjX(int obj);
+ int getObjY(int obj);
+ int getObjDir(int obj);
+ int findInventory(int owner, int index);
+ int getInventoryCount(int owner);
+
+ void beginOverride();
+ void endOverride();
+
+ void setPalette(int pal);
+ void setPaletteFromPtr(byte *ptr);
+ byte *findPalInPals(byte *pal, int index);
+
+ int getStringLen(byte *ptr);
+
+#if defined(DOTT)
+ void readArrayFromIndexFile();
+ void readMAXS();
+ void readIndexFile();
+
+ int readArray(int array, int index, int base);
+ void writeArray(int array, int index, int base, int value);
+
+ int getStackList(int16 *args, uint maxnum);
+ void setObjectState(int obj, int state, int x, int y);
+
+ void setStringVars(int i);
+ void decodeParseString2(int a, int b);
+
+ void arrayop_1(int a, byte *ptr);
+
+ void copyString(byte *dst, byte *src, int len);
+ int getArrayId();
+
+ void nukeArray(int a);
+ int defineArray(int a, int b, int c, int d);
+ int getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f);
+ void unkMiscOp4(int a, int b, int c, int d);
+ void unkMiscOp9();
+ void startManiac();
+#else
+ void readIndexFile(int i);
+#endif
};
void waitForTimer(Scumm *s);
diff --git a/scummsys.h b/scummsys.h
index e1513f6372..301622f134 100644
--- a/scummsys.h
+++ b/scummsys.h
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.4 2001/10/16 10:01:47 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.3 2001/10/09 18:35:02 strigeus
* fixed object parent bug
* fixed some signed/unsigned comparisons
@@ -36,6 +39,13 @@
#pragma warning (disable: 4101)
+#if defined(CHECK_HEAP)
+#undef CHECK_HEAP
+#define CHECK_HEAP checkHeap();
+#else
+#define CHECK_HEAP
+#endif
+
#define SCUMM_LITTLE_ENDIAN
#define FORCEINLINE __forceinline
@@ -55,8 +65,9 @@ typedef signed long int32;
#elif defined(UNIX)
-/* need this for the SDL_BYTEORDER define */
+#define CHECK_HEAP
+/* need this for the SDL_BYTEORDER define */
#include <SDL_byteorder.h>
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
@@ -122,6 +133,9 @@ uint32 FORCEINLINE READ_BE_UINT32(void *ptr) {
#define FROM_LE_32(__a__) __a__
#define FROM_LE_16(__a__) __a__
+#define TO_LE_32(__a__) __a__
+#define TO_LE_16(__a__) __a__
+
#define TO_BE_32(a) ((((a)>>24)&0xFF) | (((a)>>8)&0xFF00) | (((a)<<8)&0xFF0000) | (((a)<<24)&0xFF000000))
#elif defined(SCUMM_BIG_ENDIAN)
@@ -136,6 +150,9 @@ uint16 FORCEINLINE FROM_LE_16(uint16 a) {
return ((a>>8)&0xFF) + ((a<<8)&0xFF00);
}
+#define TO_LE_32 FROM_LE_32
+#define TO_LE_16 FROM_LE_16
+
uint32 FORCEINLINE READ_LE_UINT32(void *ptr) {
byte *b = (byte*)ptr;
return (b[3]<<24)+(b[2]<<16)+(b[1]<<8)+(b[0]);
@@ -158,7 +175,6 @@ int FORCEINLINE READ_BE_UINT16_UNALIGNED(void *ptr) {
return (((byte*)ptr)[0]<<8)|((byte*)ptr)[1];
}
-
uint32 FORCEINLINE READ_BE_UINT32_UNALIGNED(void *ptr) {
byte *b = (byte*)ptr;
return (b[0]<<24)+(b[1]<<16)+(b[2]<<8)+(b[3]);
diff --git a/scummvm.cpp b/scummvm.cpp
index c51846e708..b6b3696d39 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.7 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.6 2001/10/11 11:49:51 strigeus
* Determine caption from file name.
*
@@ -44,9 +47,20 @@
#include "stdafx.h"
#include "scumm.h"
+#if !defined(DOTT)
void Scumm::initThings() {
readIndexFile(1);
+ _numVariables = 800;
+ _numBitVariables = 2048;
+ _numLocalObjects = 200;
+
+ _inventory = (uint16*)alloc(0x50 * sizeof(uint16));
+ _verbs = (VerbSlot*)alloc(102 * sizeof(VerbSlot));
+ _objs = (ObjectData*)alloc(200 * sizeof(ObjectData));
+ _vars = (int16*)alloc(800 * sizeof(int16));
+ _bitVars = (byte*)alloc(2048 >> 3);
+
allocResTypeData(5, MKID('NONE'), 0x50, "inventory", 0);
allocResTypeData(12,MKID('NONE'),10, "temp", 0);
allocResTypeData(11,MKID('NONE'),5, "scale table", 0);
@@ -56,11 +70,19 @@ void Scumm::initThings() {
allocResTypeData(7, MKID('NONE'),0x32,"string", 0);
allocResTypeData(13, MKID('NONE'),0x32,"flobject", 0);
allocResTypeData(14, MKID('NONE'),10,"boxes", 0);
-
readIndexFile(2);
initRandSeeds();
+
+ setupOpcodes();
}
+#else
+void Scumm::initThings() {
+ setupOpcodes2();
+ readIndexFile();
+}
+
+#endif
void Scumm::initRandSeeds() {
_randSeed1 = 0xA943DE35;
@@ -71,7 +93,7 @@ uint Scumm::getRandomNumber(uint max) {
/* TODO: my own random number generator */
_randSeed1 = 0xDEADBEEF * (_randSeed1 + 1);
_randSeed1 = (_randSeed1>>13) | (_randSeed1<<19);
- return _randSeed1%(max+1);
+ return _randSeed1%max;
}
void Scumm::scummInit() {
@@ -79,7 +101,7 @@ void Scumm::scummInit() {
Actor *a;
debug(9, "scummInit");
- readIndexFile(3);
+// readIndexFile(3);
loadCharset(1);
initScreens(0, 16, 320, 144);
@@ -91,11 +113,11 @@ void Scumm::scummInit() {
initActor(a, 1);
}
- memset(vm.vars, 0, sizeof(vm.vars));
- memset(vm.bitvars, 0, sizeof(vm.bitvars));
+// memset(vm.vars, 0, sizeof(vm.vars));
+// memset(vm.bitvars, 0, sizeof(vm.bitvars));
_defaultTalkDelay = 60;
- vm.vars[37] = 4;
+ _vars[VAR_CHARINC] = 4;
_numNestedScripts = 0;
vm.cutSceneStackPointer = 0;
@@ -104,17 +126,17 @@ void Scumm::scummInit() {
memset(vm.cutSceneData, 0, sizeof(vm.cutSceneData));
for (i=0; i<_maxVerbs; i++) {
- verbs[i].verbid = 0;
- verbs[i].right = 319;
- verbs[i].oldleft = -1;
- verbs[i].type = 0;
- verbs[i].color = 2;
- verbs[i].hicolor = 0;
- verbs[i].charset_nr = 1;
- verbs[i].curmode = 0;
- verbs[i].saveid = 0;
- verbs[i].center=0;
- verbs[i].key = 0;
+ _verbs[i].verbid = 0;
+ _verbs[i].right = 319;
+ _verbs[i].oldleft = -1;
+ _verbs[i].type = 0;
+ _verbs[i].color = 2;
+ _verbs[i].hicolor = 0;
+ _verbs[i].charset_nr = 1;
+ _verbs[i].curmode = 0;
+ _verbs[i].saveid = 0;
+ _verbs[i].center=0;
+ _verbs[i].key = 0;
}
camera._leftTrigger = 10;
@@ -122,14 +144,13 @@ void Scumm::scummInit() {
camera._mode = 0;
camera._follows = 0;
-
virtscr[0].xstart = 0;
- vm.vars[9] = 11;
+ _vars[9] = 11;
_lightsValueA = _lightsValueB = 7;
- vm.vars[59] = 3;
+ _vars[59] = 3;
mouse.x = 104;
mouse.y = 56;
@@ -149,7 +170,7 @@ void Scumm::scummInit() {
_screenStartStrip = 0;
- vm.vars[25] = 0;
+ _vars[25] = 0;
_talkDelay = 0;
_keepText = false;
@@ -163,12 +184,12 @@ void Scumm::scummInit() {
clearDrawObjectQueue();
for (i=0; i<6; i++) {
- textslot.x[i] = 2;
- textslot.y[i] = 5;
- textslot.right[i] = 319;
- textslot.color[i] = 0xF;
- textslot.center[i] = 0;
- textslot.charset[i] = 0;
+ string[i].t_xpos = 2;
+ string[i].t_ypos = 5;
+ string[i].t_right = 319;
+ string[i].t_color = 0xF;
+ string[i].t_center = 0;
+ string[i].t_charset = 0;
}
_numInMsgStack = 0;
@@ -177,22 +198,22 @@ void Scumm::scummInit() {
initScummVars();
- vm.vars[54] = -0x50;
+ _vars[54] = -0x50;
getGraphicsPerformance();
}
void Scumm::initScummVars() {
- vm.vars[VAR_CURRENTDRIVE] = _currentDrive;
- vm.vars[VAR_FIXEDDISK] = checkFixedDisk();
- vm.vars[VAR_SOUNDCARD] = _soundCardType;
- vm.vars[VAR_VIDEOMODE] = _videoMode;
- vm.vars[VAR_HEAPSPACE] = _heapSpace;
- vm.vars[VAR_MOUSEPRESENT] = _mousePresent;
- vm.vars[VAR_SOUNDPARAM] = _soundParam;
- vm.vars[VAR_SOUNDPARAM2] = _soundParam2;
- vm.vars[VAR_SOUNDPARAM3] = _soundParam3;
+ _vars[VAR_CURRENTDRIVE] = _currentDrive;
+ _vars[VAR_FIXEDDISK] = checkFixedDisk();
+ _vars[VAR_SOUNDCARD] = _soundCardType;
+ _vars[VAR_VIDEOMODE] = _videoMode;
+ _vars[VAR_HEAPSPACE] = 600;
+ _vars[VAR_MOUSEPRESENT] = _mousePresent;
+ _vars[VAR_SOUNDPARAM] = _soundParam;
+ _vars[VAR_SOUNDPARAM2] = _soundParam2;
+ _vars[VAR_SOUNDPARAM3] = _soundParam3;
}
void Scumm::checkRange(int max, int min, int no, const char *str) {
@@ -220,33 +241,34 @@ void Scumm::scummMain(int argc, char **argv) {
initThings();
scummInit();
- vm.vars[VAR_VERSION] = 21;
- vm.vars[VAR_DEBUGMODE] = _debugMode;
+ _vars[VAR_VERSION] = 21;
+ _vars[VAR_DEBUGMODE] = _debugMode;
runScript(1,0,0,&_bootParam);
_scummTimer = 0;
do {
if (_playBackFile) {
- while ((_scummTimer>>2) < vm.vars[VAR_PLAYBACKTIMER]) {}
- _scummTimer = vm.vars[VAR_PLAYBACKTIMER] << 2;
+ while ((_scummTimer>>2) < _vars[VAR_PLAYBACKTIMER]) {}
+ _scummTimer = _vars[VAR_PLAYBACKTIMER] << 2;
}
+ CHECK_HEAP
updateScreen(this);
- vm.vars[VAR_TIMER] = _scummTimer >> 2;
+ _vars[VAR_TIMER] = _scummTimer >> 2;
do {
waitForTimer(this);
tmr = _scummTimer >> 2;
if (_fastMode)
tmr += 15;
- } while (tmr < vm.vars[VAR_TIMER_NEXT]);
+ } while (tmr < _vars[VAR_TIMER_NEXT]);
_scummTimer = 0;
- vm.vars[VAR_TMR_1] += tmr;
- vm.vars[VAR_TMR_2] += tmr;
- vm.vars[VAR_TMR_3] += tmr;
- vm.vars[VAR_TMR_4] += tmr;
+ _vars[VAR_TMR_1] += tmr;
+ _vars[VAR_TMR_2] += tmr;
+ _vars[VAR_TMR_3] += tmr;
+ _vars[VAR_TMR_4] += tmr;
if (tmr > 15)
tmr = 15;
@@ -259,13 +281,13 @@ void Scumm::scummMain(int argc, char **argv) {
processKbd();
/* XXX: memory low check skipped */
- vm.vars[VAR_CAMERA_CUR_POS] = camera._curPos;
- vm.vars[VAR_HAVE_MSG] = _haveMsg;
- vm.vars[VAR_VIRT_MOUSE_X] = _virtual_mouse_x;
- vm.vars[VAR_VIRT_MOUSE_Y] = _virtual_mouse_y;
- vm.vars[VAR_MOUSE_X] = mouse.x;
- vm.vars[VAR_MOUSE_Y] = mouse.y;
- vm.vars[VAR_DEBUGMODE] = _debugMode;
+ _vars[VAR_CAMERA_CUR_POS] = camera._curPos;
+ _vars[VAR_HAVE_MSG] = _haveMsg;
+ _vars[VAR_VIRT_MOUSE_X] = _virtual_mouse_x;
+ _vars[VAR_VIRT_MOUSE_Y] = _virtual_mouse_y;
+ _vars[VAR_MOUSE_X] = mouse.x;
+ _vars[VAR_MOUSE_Y] = mouse.y;
+ _vars[VAR_DEBUGMODE] = _debugMode;
if (_saveLoadFlag) {
char buf[256];
@@ -288,13 +310,9 @@ void Scumm::scummMain(int argc, char **argv) {
a->needRedraw = 1;
}
- checkHeap();
runAllScripts();
- checkHeap();
checkExecVerbs();
- checkHeap();
checkAndRunVar33();
- checkHeap();
if (_currentRoom==0) {
gdi.unk4 = 0;
@@ -305,38 +323,25 @@ void Scumm::scummMain(int argc, char **argv) {
continue;
}
- checkHeap();
walkActors();
- checkHeap();
moveCamera();
- checkHeap();
fixObjectFlags();
- checkHeap();
CHARSET_1();
- checkHeap();
if (camera._curPos != camera._lastPos || _BgNeedsRedraw || _fullRedraw) {
redrawBGAreas();
- checkHeap();
}
processDrawQue();
- checkHeap();
setActorRedrawFlags();
- checkHeap();
resetActorBgs();
- checkHeap();
- if (!(vm.vars[VAR_DRAWFLAGS]&2) && vm.vars[VAR_DRAWFLAGS]&4) {
+ if (!(_vars[VAR_DRAWFLAGS]&2) && _vars[VAR_DRAWFLAGS]&4) {
error("Flashlight not implemented in this version");
}
processActors(); /* process actors makes the heap invalid */
- checkHeap();
clear_fullRedraw();
- checkHeap();
cyclePalette();
- checkHeap();
palManipulate();
- checkHeap();
if (dseg_4F8A) {
screenEffect(_newEffect);
@@ -352,7 +357,9 @@ void Scumm::scummMain(int argc, char **argv) {
unkVirtScreen2();
+#if !defined(DOTT)
playActorSounds();
+#endif
unkSoundProc22();
camera._lastPos = camera._curPos;
} while (1);
@@ -420,7 +427,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
int i;
Actor *at;
- checkHeap();
+ CHECK_HEAP
clearMsgQueue();
@@ -439,7 +446,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
}
}
- vm.vars[VAR_NEW_ROOM] = room;
+ _vars[VAR_NEW_ROOM] = room;
runExitScript();
killScriptsAndResources();
stopCycle(0);
@@ -454,7 +461,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
clearDrawObjectQueue();
- vm.vars[VAR_ROOM] = room;
+ _vars[VAR_ROOM] = room;
_fullRedraw = 1;
_roomResource = _currentRoom = 0xFF;
@@ -462,14 +469,14 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
unkResourceProc();
_currentRoom = room;
- vm.vars[VAR_ROOM] = room;
+ _vars[VAR_ROOM] = room;
if (room >= 0x80)
_roomResource = _resourceMapper[room&0x7F];
else
_roomResource = room;
- vm.vars[VAR_ROOM_RESOURCE] = _roomResource;
+ _vars[VAR_ROOM_RESOURCE] = _roomResource;
if (room!=0)
ensureResourceLoaded(1, room);
@@ -490,8 +497,8 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
if (_roomResource == 0)
return;
- vm.vars[VAR_CAMERA_MAX] = (_scrWidthIn8Unit<<3) - 160;
- vm.vars[VAR_CAMERA_MIN] = 160;
+ _vars[VAR_CAMERA_MAX] = (_scrWidthIn8Unit<<3) - 160;
+ _vars[VAR_CAMERA_MIN] = 160;
memset(actorDrawBits, 0, sizeof(actorDrawBits));
@@ -518,7 +525,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
dseg_4F8A = 1;
- checkHeap();
+ CHECK_HEAP
}
void Scumm::initRoomSubBlocks() {
@@ -528,6 +535,8 @@ void Scumm::initRoomSubBlocks() {
_ENCD_offs = 0;
_EXCD_offs = 0;
+ _CLUT_offs = 0;
+ _PALS_offs = 0;
nukeResource(0xE, 1);
nukeResource(0xE, 2);
@@ -592,12 +601,12 @@ void Scumm::initRoomSubBlocks() {
}
}
}
- memset(_localScriptList, 0, (0x100 - _numGlobalScriptsUsed) * 4);
+ memset(_localScriptList, 0, (0x100 - _numGlobalScripts) * 4);
roomptr = getResourceAddress(1, _roomResource);
ptr = findResource(MKID('LSCR'), roomptr);
while (ptr) {
- _localScriptList[ptr[8] - _numGlobalScriptsUsed] = ptr - roomptr;
+ _localScriptList[ptr[8] - _numGlobalScripts] = ptr - roomptr;
#ifdef DUMP_SCRIPTS
do {
@@ -610,12 +619,24 @@ void Scumm::initRoomSubBlocks() {
ptr = findResource(MKID('LSCR'), NULL);
}
- _CLUT_offs = findResource(MKID('CLUT'), roomptr) - roomptr;
ptr = findResource(MKID('EPAL'), roomptr);
if (ptr)
_EPAL_offs = ptr - roomptr;
+
+ ptr = findResource(MKID('CLUT'), roomptr);
+ if (ptr) {
+ _CLUT_offs = ptr - roomptr;
+ setPaletteFromRes();
+ }
- setPaletteFromRes();
+#if defined(DOTT)
+ ptr = findResource(MKID('PALS'), roomptr);
+ if (ptr) {
+ _PALS_offs = ptr - roomptr;
+ setPalette(0);
+ }
+#endif
+
initCycl(findResource(MKID('CYCL'), roomptr) + 8);
ptr = findResource(MKID('TRNS'), roomptr);
@@ -651,11 +672,10 @@ void Scumm::setScaleItem(int slot, int a, int b, int c, int d) {
void Scumm::dumpResource(char *tag, int index, byte *ptr) {
char buf[256];
FILE *out;
-
uint32 size = READ_BE_UINT32_UNALIGNED(ptr+4);
- sprintf(buf, "f:\\descumm\\%s%d.dmp", tag,index);
+ sprintf(buf, "dumps\\%s%d.dmp", tag,index);
out = fopen(buf,"rb");
if (!out) {
@@ -699,7 +719,13 @@ void Scumm::unkRoomFunc2(int a, int b, int c, int d, int e) {
}
if (_videoMode==0x13) {
- cptr = getResourceAddress(1, _roomResource) + _CLUT_offs + 8 + a*3;
+ cptr = getResourceAddress(1, _roomResource);
+ if (_CLUT_offs) {
+ cptr += _CLUT_offs;
+ } else {
+ cptr = findPalInPals(cptr + _PALS_offs, _curPalIndex);
+ }
+ cptr += 8 + a*3;
cur = _currentPalette + a*3;
if (a <= b) {
num = b - a + 1;
@@ -764,19 +790,19 @@ void Scumm::processKbd() {
if (!_lastKeyHit)
return;
- if (_lastKeyHit==vm.vars[VAR_RESTART_KEY]) {
+ if (_lastKeyHit==_vars[VAR_RESTART_KEY]) {
warning("Restart not implemented");
pauseGame(1);
return;
}
- if (_lastKeyHit==vm.vars[VAR_PAUSE_KEY]) {
+ if (_lastKeyHit==_vars[VAR_PAUSE_KEY]) {
warning("Pause not implemented");
/* pause */
return;
}
- if (_lastKeyHit==vm.vars[VAR_CUTSCENEEXIT_KEY]) {
+ if (_lastKeyHit==_vars[VAR_CUTSCENEEXIT_KEY]) {
uint32 offs = vm.cutScenePtr[vm.cutSceneStackPointer];
if (offs) {
ScriptSlot *ss = &vm.slot[vm.cutSceneScript[vm.cutSceneStackPointer]];
@@ -784,12 +810,12 @@ void Scumm::processKbd() {
ss->status = 2;
ss->freezeCount = 0;
ss->cutsceneOverride--;
- vm.vars[VAR_OVERRIDE] = 1;
+ _vars[VAR_OVERRIDE] = 1;
vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
}
}
- if (_lastKeyHit==vm.vars[VAR_TALKSTOP_KEY]) {
+ if (_lastKeyHit==_vars[VAR_TALKSTOP_KEY]) {
_talkDelay = 0;
return;
}
@@ -811,7 +837,7 @@ int Scumm::getKeyInput(int a) {
if (_leftBtnPressed&1 && _rightBtnPressed&1) {
_mouseButStat = 0;
- _lastKeyHit = vm.vars[VAR_CUTSCENEEXIT_KEY];
+ _lastKeyHit = _vars[VAR_CUTSCENEEXIT_KEY];
} else if (_leftBtnPressed&1) {
_mouseButStat = 0x8000;
} else if (_rightBtnPressed&1) {
@@ -842,6 +868,51 @@ Actor *Scumm::derefActorSafe(int id, const char *errmsg) {
return derefActor(id);
}
+#if defined(DOTT)
+void Scumm::new_unk_1(int a) {
+ error("stub new_unk_1(%d)", a);
+}
+
+void Scumm::setCursorHotspot2(int x,int y) {
+ warning("stub setCursorHotspot2(%d,%d)", x,y);
+}
+
+void Scumm::setStringVars(int slot) {
+ string[slot].xpos = string[slot].t_xpos;
+ string[slot].ypos = string[slot].t_ypos;
+ string[slot].center = string[slot].t_center;
+ string[slot].overhead = string[slot].t_overhead;
+ string[slot].new_3 = string[slot].t_new3;
+ string[slot].right = string[slot].t_right;
+ string[slot].color = string[slot].t_color;
+ string[slot].charset = string[slot].t_charset;
+}
+
+void Scumm::arrayop_1(int a, byte *ptr) {
+ ArrayHeader *ah;
+ int r;
+ int len = getStringLen(ptr);
+
+ r = defineArray(a, 4, 0, len);
+ ah = (ArrayHeader*)getResourceAddress(7,r);
+ copyString(ah->data,ptr,len);
+}
+
+
+void Scumm::unkMiscOp4(int a, int b, int c, int d) {
+ warning("stub unkMiscOp4(%d,%d,%d,%d)", a,b,c,d);
+}
+
+void Scumm::unkMiscOp9() {
+ warning("stub unkMiscOp9()");
+}
+
+void Scumm::startManiac() {
+ warning("stub startManiac()");
+}
+
+#endif
+
extern Scumm scumm;
void NORETURN CDECL error(const char *s, ...) {
@@ -886,11 +957,8 @@ void CDECL debug(int level, const char *s, ...) {
}
void checkHeap() {
-#if 1
-
-//if (_heapchk() != _HEAPOK) {
-// error("Heap is invalid!");
-// }
-#endif
+ if (_heapchk() != _HEAPOK) {
+ error("Heap is invalid!");
+ }
}
diff --git a/scummvm.dsp b/scummvm.dsp
index 6aa598cb93..7a2d635705 100644
--- a/scummvm.dsp
+++ b/scummvm.dsp
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CHECK_HEAP" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x41d /d "_DEBUG"
# ADD RSC /l 0x41d /d "_DEBUG"
BSC32=bscmake.exe
@@ -119,6 +119,14 @@ SOURCE=.\script.cpp
# End Source File
# Begin Source File
+SOURCE=.\script_v1.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\script_v2.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\scummvm.cpp
# End Source File
# Begin Source File
diff --git a/sdl.cpp b/sdl.cpp
index 65e59df60d..f54229e3d4 100644
--- a/sdl.cpp
+++ b/sdl.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.8 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.7 2001/10/11 11:49:51 strigeus
* Determine caption from file name.
*
@@ -328,14 +331,13 @@ void initGraphics(Scumm *s) {
screen = SDL_SetVideoMode(640, 400, 8, SDL_SWSURFACE);
#endif
- printf("%d %d, %d %d, %d %d %d, %d %d %d %d %d %d\n",
+ printf("%d %d, %d %d, %d %d %d, %d %d %d %d %d\n",
sizeof(int8), sizeof(uint8),
sizeof(int16), sizeof(uint16),
sizeof(int32), sizeof(uint32),
sizeof(void*),
sizeof(Box), sizeof(MouseCursor),sizeof(CodeHeader),
sizeof(ImageHeader),
- &((CodeHeader*)0)->unk4,
sizeof(Scumm)
);
diff --git a/sound.cpp b/sound.cpp
index 35f855529f..cfee9440a0 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -17,8 +17,12 @@
*
* Change Log:
* $Log$
- * Revision 1.1 2001/10/09 14:30:13 strigeus
- * Initial revision
+ * Revision 1.2 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
+ * Revision 1.1.1.1 2001/10/09 14:30:13 strigeus
+ *
+ * initial revision
*
*
*/
@@ -27,7 +31,7 @@
#include "scumm.h"
void Scumm::addSoundToQueue(int sound) {
- vm.vars[VAR_LAST_SOUND] = sound;
+ _vars[VAR_LAST_SOUND] = sound;
ensureResourceLoaded(4, sound);
addSoundToQueue2(sound);
}
@@ -71,16 +75,35 @@ void Scumm::unkSoundProc22() {
void Scumm::playSound(int sound) {
getResourceAddress(4, sound);
/* XXX: not implemented */
- warning("stub playSound(%d)", sound);
+// warning("stub playSound(%d)", sound);
}
int Scumm::unkSoundProc23(int a) {
/* TODO: implement this */
- warning("unkSoundProc23: not implemented");
+// warning("unkSoundProc23: not implemented");
return 0;
}
void Scumm::unkSoundProc1(int a) {
/* TODO: implement this */
- warning("unkSoundProc: not implemented");
+// warning("unkSoundProc: not implemented");
}
+
+void Scumm::soundKludge(int16 *list) {
+ int16 *ptr;
+ int i;
+
+ if (list[0]==-1) {
+ unkSoundProc22();
+ return;
+ }
+ _soundQue[_soundQuePos++] = 8;
+
+ ptr = _soundQue + _soundQuePos;
+ _soundQuePos += 8;
+
+ for (i=0; i<8; i++)
+ *ptr++ = list[i];
+ if (_soundQuePos > 0x100)
+ error("Sound que buffer overflow");
+} \ No newline at end of file
diff --git a/string.cpp b/string.cpp
index f7785e5f88..df22980174 100644
--- a/string.cpp
+++ b/string.cpp
@@ -17,8 +17,12 @@
*
* Change Log:
* $Log$
- * Revision 1.1 2001/10/09 14:30:13 strigeus
- * Initial revision
+ * Revision 1.2 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
+ * Revision 1.1.1.1 2001/10/09 14:30:13 strigeus
+ *
+ * initial revision
*
*
*/
@@ -51,8 +55,18 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {
text[pos++] = '@';
continue;
}
- if (chr==1 || chr==2)
+ if (chr==10 || chr==21 || chr==12 || chr==13) {
+ pos += 2;
+ continue;
+ }
+ if (chr==9 || chr==1 || chr==2)
break;
+ if (chr==14) {
+ int set = text[pos] | (text[pos+1]<<8);
+ pos+=2;
+ ptr = _vm->getResourceAddress(6, set) + 29;
+ continue;
+ }
}
offs = READ_LE_UINT32(ptr + chr*4 + 4);
@@ -94,12 +108,22 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
}
continue;
}
+ if (chr==10 || chr==21 || chr==12 || chr==13) {
+ pos += 2;
+ continue;
+ }
if (chr==1) {
curw = 1;
continue;
}
if (chr==2)
break;
+ if (chr==14) {
+ int set = str[pos] | (str[pos+1]<<8);
+ pos+=2;
+ ptr = _vm->getResourceAddress(6, set) + 29;
+ continue;
+ }
}
if (chr==' ')
@@ -137,11 +161,10 @@ void Scumm::unkMessage2() {
_msgPtrToAdd = buf;
tmp = _messagePtr = addMessageToStack(_messagePtr);
- if (_stringColor[3]==0)
- _stringColor[3] = 4;
+ if (string[3].color==0)
+ string[3].color = 4;
error("unkMessage2: call to printScummMessage(%s)", buf);
- vm.vars[0] = 0;
_messagePtr = tmp;
}
@@ -156,37 +179,52 @@ void Scumm::CHARSET_1() {
) return;
a = NULL;
- if (vm.vars[VAR_TALK_ACTOR] != 0xFF)
- a = derefActorSafe(vm.vars[VAR_TALK_ACTOR], "CHARSET_1");
+ if (_vars[VAR_TALK_ACTOR] != 0xFF)
+ a = derefActorSafe(_vars[VAR_TALK_ACTOR], "CHARSET_1");
- if (a && _stringOverhead[0]!=0) {
- _stringXpos[0] = a->x - camera._curPos + 160;
+#if !defined(DOTT)
+ if (a && string[0].overhead!=0) {
+ string[0].xpos = a->x - camera._curPos + 160;
- if (vm.vars[VAR_TALK_STRING_Y] < 0) {
- s = (a->scaley * (int)vm.vars[VAR_TALK_STRING_Y]) / 0xFF;
- _stringYpos[0] = ((vm.vars[VAR_TALK_STRING_Y]-s)>>1) + s - a->elevation + a->y;
+ if (_vars[VAR_TALK_STRING_Y] < 0) {
+ s = (a->scaley * (int)_vars[VAR_TALK_STRING_Y]) / 0xFF;
+ string[0].ypos = ((_vars[VAR_TALK_STRING_Y]-s)>>1) + s - a->elevation + a->y;
} else {
- _stringYpos[0] = vm.vars[VAR_TALK_STRING_Y];
+ string[0].ypos = _vars[VAR_TALK_STRING_Y];
}
- if (_stringYpos[0] < 1)
- _stringYpos[0] = 1;
+ if (string[0].ypos < 1)
+ string[0].ypos = 1;
- if (_stringXpos[0] < 80)
- _stringXpos[0] = 80;
- if (_stringXpos[0] > 240)
- _stringXpos[0] = 240;
+ if (string[0].xpos < 80)
+ string[0].xpos = 80;
+ if (string[0].xpos > 240)
+ string[0].xpos = 240;
}
-
- charset._top = _stringYpos[0];
- charset._left = _stringXpos[0];
- charset._left2 = _stringXpos[0];
- charset._curId = _stringCharset[0];
+#else
+ if (a && string[0].overhead!=0) {
+ s = a->scaley * a->new_1 / 0xFF;
+ string[0].ypos = ((a->new_1 - s)>>1) + s - a->elevation + a->y;
+ if (string[0].ypos<1)
+ string[0].ypos = 1;
+
+ s = a->scalex * a->new_2 / 0xFF;
+ string[0].xpos = ((a->new_2 - s)>>1) + s + a->x - camera._curPos + 160;
+ if (string[0].xpos < 80)
+ string[0].xpos = 80;
+ if (string[0].xpos > 240)
+ string[0].xpos = 240;
+ }
+#endif
+ charset._top = string[0].ypos;
+ charset._left = string[0].xpos;
+ charset._left2 = string[0].xpos;
+ charset._curId = string[0].charset;
if (a && a->charset)
charset._curId = a->charset;
- charset._center = _stringCenter[0];
- charset._right = _stringRight[0];
+ charset._center = string[0].center;
+ charset._right = string[0].right;
charset._color = _charsetColor;
dseg_4E3C = 0;
@@ -194,10 +232,10 @@ void Scumm::CHARSET_1() {
charset._colorMap[i] = _charsetData[charset._curId][i];
if (_keepText) {
- charset._strLeft = charset._mask_left;
- charset._strRight = charset._mask_right;
- charset._strTop = charset._mask_top;
- charset._strBottom = charset._mask_bottom;
+ charset._strLeft = string[0].mask_left;
+ charset._strRight = string[0].mask_right;
+ charset._strTop = string[0].mask_top;
+ charset._strBottom = string[0].mask_bottom;
}
if (!_haveMsg || _talkDelay)
@@ -216,21 +254,21 @@ void Scumm::CHARSET_1() {
if (!_keepText) {
restoreCharsetBg();
- _stringXpos2[0] = _stringXpos[0];
- _stringYpos2[0] = _stringYpos[0];
+ string[0].xpos2 = string[0].xpos;
+ string[0].ypos2 = string[0].ypos;
}
- t = charset._right - _stringXpos2[0] - 1;
+ t = charset._right - string[0].xpos - 1;
if (charset._center) {
- if (t > _stringXpos2[0])
- t = _stringXpos2[0];
+ if (t > string[0].xpos2)
+ t = string[0].xpos2;
t <<= 1;
}
charset.addLinebreaks(0, charset._buffer, charset._bufPos, t);
_lastXstart = virtscr[0].xstart;
if (charset._center) {
- _stringXpos2[0] -= charset.getStringWidth(0, charset._buffer, charset._bufPos) >> 1;
+ string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos) >> 1;
}
charset._disableOffsX = charset._unk12 = !_keepText;
@@ -242,58 +280,79 @@ void Scumm::CHARSET_1() {
_keepText = false;
break;
}
- if (c != 13) {
- if (c==0xFE)
- c=0xFF;
-
- if (c!=0xFF) {
-PrintChar:;
- charset._left = _stringXpos2[0];
- charset._top = _stringYpos2[0];
-
- if (!vm.vars[VAR_CHARFLAG]) {
- charset.printChar(c);
- }
- _stringXpos2[0] = charset._left;
- _stringYpos2[0] = charset._top;
-
- _talkDelay += vm.vars[VAR_CHARINC];
- continue;
+ if (c == 13) {
+newLine:;
+ string[0].xpos2 = string[0].xpos;
+ if (charset._center) {
+ string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos)>>1;
}
+ string[0].ypos2 += getResourceAddress(6,charset._curId)[30];
+ charset._disableOffsX = 1;
+ continue;
+ }
- c = charset._buffer[charset._bufPos++];
- if (c==3) {
- _haveMsg = 0xFF;
- _keepText = false;
- break;
- }
- if (c!=1) {
- if (c==2) {
- _haveMsg = 0;
- _keepText = true;
- break;
- }
- if (c==9) {
- frme = charset._buffer[charset._bufPos++];
- frme |= charset._buffer[charset._bufPos++]<<8;
- if (a)
- startAnimActor(a, frme, a->facing);
- }
- goto PrintChar;
+ if (c==0xFE) c=0xFF;
+
+ if (c!=0xFF) {
+ charset._left = string[0].xpos2;
+ charset._top = string[0].ypos2;
+
+ if (!_vars[VAR_CHARFLAG]) {
+ charset.printChar(c);
}
+ string[0].xpos2 = charset._left;
+ string[0].ypos2 = charset._top;
+
+ _talkDelay += _vars[VAR_CHARINC];
+ continue;
}
- _stringXpos2[0] = _stringXpos[0];
- if (charset._center) {
- _stringXpos2[0] -= charset.getStringWidth(0, charset._buffer, charset._bufPos)>>1;
+
+ c = charset._buffer[charset._bufPos++];
+ if (c==3) {
+ _haveMsg = 0xFF;
+ _keepText = false;
+ break;
+ } else if (c==1) {
+ goto newLine;
+ } else if (c==2) {
+ _haveMsg = 0;
+ _keepText = true;
+ break;
+ } else if (c==9) {
+ frme = charset._buffer[charset._bufPos++];
+ frme |= charset._buffer[charset._bufPos++]<<8;
+ if (a)
+ startAnimActor(a, frme, a->facing);
+ } else if (c==10) {
+ warning("CHARSET_1: code 10 unimplemented");
+ charset._bufPos += 14;
+ } else if (c==14) {
+ int oldy = getResourceAddress(6,charset._curId)[30];
+
+ charset._curId = charset._buffer[charset._bufPos];
+ charset._bufPos += 2;
+ for (i=0; i<4; i++)
+ charset._colorMap[i] = _charsetData[charset._curId][i];
+ string[0].ypos2 -= getResourceAddress(6,charset._curId)[30] - oldy;
+ } else if (c==12) {
+ int color;
+ color = charset._buffer[charset._bufPos++];
+ color |= charset._buffer[charset._bufPos++]<<8;
+ if (color==0xFF)
+ charset._color = _charsetColor;
+ else
+ charset._color = color;
+ } else if (c==13) {
+ charset._bufPos += 2;
+ } else {
+ warning("CHARSET_1: invalid code %d", c);
}
- _stringYpos2[0] += getResourceAddress(6,charset._curId)[30];
- charset._disableOffsX = 1;
} while (1);
- charset._mask_left = charset._strLeft;
- charset._mask_right = charset._strRight;
- charset._mask_top = charset._strTop;
- charset._mask_bottom = charset._strBottom;
+ string[0].mask_left = charset._strLeft;
+ string[0].mask_right = charset._strRight;
+ string[0].mask_top = charset._strTop;
+ string[0].mask_bottom = charset._strBottom;
}
void Scumm::drawString(int a) {
@@ -305,12 +364,12 @@ void Scumm::drawString(int a) {
_msgPtrToAdd = buf;
_messagePtr = addMessageToStack(_messagePtr);
- charset._left2 = charset._left = _stringXpos[a];
- charset._top = _stringYpos[a];
- charset._curId = _stringCharset[a];
- charset._center = _stringCenter[a];
- charset._right = _stringRight[a];
- charset._color = _stringColor[a];
+ charset._left2 = charset._left = string[a].xpos;
+ charset._top = string[a].ypos;
+ charset._curId = string[a].charset;
+ charset._center = string[a].center;
+ charset._right = string[a].right;
+ charset._color = string[a].color;
dseg_4E3C = 0;
charset._unk12 = 1;
charset._disableOffsX = 1;
@@ -371,8 +430,8 @@ void Scumm::drawString(int a) {
}
charset._ignoreCharsetMask = 0;
- _stringXpos2[a] = charset._left;
- _stringYpos2[a] = charset._top;
+ string[a].xpos2 = charset._left;
+ string[a].ypos2 = charset._top;
}
byte *Scumm::addMessageToStack(byte *msg) {
@@ -394,7 +453,7 @@ byte *Scumm::addMessageToStack(byte *msg) {
if (chr==255) {
ptr[num++] = chr = *msg++;
- if (chr==0 || chr!=2 && chr!=3 && chr!=8) {
+ if (chr!=1 && chr!=2 && chr!=3 && chr!=8) {
ptr[num++] = chr = *msg++;
ptr[num++] = chr = *msg++;
}
@@ -411,38 +470,32 @@ byte *Scumm::addMessageToStack(byte *msg) {
if (chr == 0)
break;
if (chr == 0xFF) {
- ptr = getResourceAddress(0xC, 6);
chr = ptr[num++];
switch(chr) {
case 4:
- unkAddMsgToStack2(
- READ_LE_UINT16(getResourceAddress(0xC, 6)+ num)
- );
+ unkAddMsgToStack2(READ_LE_UINT16(ptr + num));
num+=2;
break;
case 5:
- unkAddMsgToStack3(
- READ_LE_UINT16(getResourceAddress(0xC, 6)+ num)
- );
+ unkAddMsgToStack3(READ_LE_UINT16(ptr + num));
num+=2;
break;
case 6:
- unkAddMsgToStack4(
- READ_LE_UINT16(getResourceAddress(0xC, 6)+ num)
- );
+ unkAddMsgToStack4(READ_LE_UINT16(ptr + num));
num+=2;
break;
case 7:
- unkAddMsgToStack5(
- READ_LE_UINT16(getResourceAddress(0xC, 6)+num)
- );
+ unkAddMsgToStack5(READ_LE_UINT16(ptr + num));
num+=2;
break;
- case 9:
+ case 9:
+#if defined(DOTT)
+ case 10: case 12: case 13: case 14:
+#endif
*_msgPtrToAdd++ = 0xFF;
*_msgPtrToAdd++ = chr;
- *_msgPtrToAdd++ = getResourceAddress(0xC, 6)[num++];
- *_msgPtrToAdd++ = getResourceAddress(0xC, 6)[num++];
+ *_msgPtrToAdd++ = ptr[num++];
+ *_msgPtrToAdd++ = ptr[num++];
break;
default:
*_msgPtrToAdd++ = 0xFF;
@@ -489,7 +542,7 @@ void Scumm::unkAddMsgToStack3(int var) {
num = readVar(var);
if (num) {
for (i=1; i<_maxVerbs; i++) {
- if (num==verbs[i].verbid && !verbs[i].type && !verbs[i].saveid) {
+ if (num==_verbs[i].verbid && !_verbs[i].type && !_verbs[i].saveid) {
addMessageToStack(getResourceAddress(8, i));
break;
}
@@ -528,8 +581,8 @@ void Scumm::initCharset(int charsetno) {
if (!getResourceAddress(6, charsetno))
loadCharset(charsetno);
- textslot.charset[0] = charsetno;
- textslot.charset[1] = charsetno;
+ string[0].t_charset = charsetno;
+ string[1].t_charset = charsetno;
for (i=0; i<0x10; i++)
charset._colorMap[i] = _charsetData[charsetno][i];
@@ -615,6 +668,7 @@ void CharsetRenderer::printChar(int chr) {
_strTop = _top;
_drawTop = _top - vs->topline;
+
_bottom = _drawTop + _height + _offsY;
_vm->updateDirtyRect(_vm->gdi.virtScreen, _left, right, _drawTop, _bottom, 0);
diff --git a/verbs.cpp b/verbs.cpp
index 992c3e88c7..50087eec89 100644
--- a/verbs.cpp
+++ b/verbs.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.3 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.2 2001/10/09 19:02:28 strigeus
* command line parameter support
*
@@ -46,7 +49,7 @@ void Scumm::checkExecVerbs() {
if (_mouseButStat < 0x200) {
/* Check keypresses */
- vs = &verbs[1];
+ vs = &_verbs[1];
for (i=1; i<_maxVerbs; i++,vs++) {
if (vs->verbid && vs->saveid && vs->curmode==1) {
if (_mouseButStat == vs->key) {
@@ -61,13 +64,13 @@ void Scumm::checkExecVerbs() {
if (mouse.y >= virtscr[0].topline && mouse.y < virtscr[0].topline + virtscr[0].height) {
over = checkMouseOver(mouse.x, mouse.y);
if (over != 0) {
- runInputScript(1,verbs[over].verbid,code);
+ runInputScript(1,_verbs[over].verbid,code);
return;
}
runInputScript(2, 0, code);
} else {
over=checkMouseOver(mouse.x, mouse.y);
- runInputScript(1, over!=0 ? verbs[over].verbid : 0, code);
+ runInputScript(1, over!=0 ? _verbs[over].verbid : 0, code);
}
}
}
@@ -76,12 +79,12 @@ void Scumm::verbMouseOver(int verb) {
if (_verbMouseOver==verb)
return;
- if (verbs[_verbMouseOver].type!=1) {
+ if (_verbs[_verbMouseOver].type!=1) {
drawVerb(_verbMouseOver, 0);
_verbMouseOver = verb;
}
- if (verbs[verb].type!=1 && verbs[verb].hicolor) {
+ if (_verbs[verb].type!=1 && _verbs[verb].hicolor) {
drawVerb(verb, 1);
_verbMouseOver = verb;
}
@@ -89,9 +92,9 @@ void Scumm::verbMouseOver(int verb) {
int Scumm::checkMouseOver(int x, int y) {
VerbSlot *vs;
- int i = _maxVerbs;
+ int i = _maxVerbs-1;
- vs = &verbs[i];
+ vs = &_verbs[i];
do {
if (vs->curmode!=1 || !vs->verbid || vs->saveid ||
y < vs->y || y >= vs->bottom)
@@ -104,7 +107,7 @@ int Scumm::checkMouseOver(int x, int y) {
continue;
}
return i;
- } while (--vs, i--);
+ } while (--vs,--i);
return 0;
}
@@ -116,7 +119,7 @@ void Scumm::drawVerb(int vrb, int mode) {
if (!vrb)
return;
- vs = &verbs[vrb];
+ vs = &_verbs[vrb];
if (!vs->saveid && vs->curmode && vs->verbid) {
if (vs->type==1) {
@@ -125,18 +128,18 @@ void Scumm::drawVerb(int vrb, int mode) {
}
restoreVerbBG(vrb);
- _stringCharset[4] = vs->charset_nr;
- _stringXpos[4] = vs->x;
- _stringYpos[4] = vs->y;
- _stringRight[4] = 319;
- _stringCenter[4] = vs->center;
+ string[4].charset = vs->charset_nr;
+ string[4].xpos = vs->x;
+ string[4].ypos = vs->y;
+ string[4].right = 319;
+ string[4].center = vs->center;
if (mode && vs->hicolor)
color = vs->hicolor;
else
color = vs->color;
- _stringColor[4] = color;
+ string[4].color = color;
if (vs->curmode==2)
- _stringColor[4] = vs->dimcolor;
+ string[4].color = vs->dimcolor;
_messagePtr = getResourceAddress(8, vrb);
assert(_messagePtr);
tmp = charset._center;
@@ -158,7 +161,7 @@ void Scumm::drawVerb(int vrb, int mode) {
void Scumm::restoreVerbBG(int verb) {
VerbSlot *vs;
- vs = &verbs[verb];
+ vs = &_verbs[verb];
if (vs->oldleft != -1) {
dseg_4E3C = vs->bkcolor;
@@ -210,7 +213,7 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
}
}
- vst = &verbs[vrb];
+ vst = &_verbs[vrb];
vst->right = vst->x + imgw*8;
vst->bottom = vst->y + imgh*8;
vst->oldleft = vst->x;
@@ -225,7 +228,7 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
int Scumm::getVerbSlot(int id, int mode) {
int i;
for (i=1; i<_maxVerbs; i++) {
- if (verbs[i].verbid == id && verbs[i].saveid == mode) {
+ if (_verbs[i].verbid == id && _verbs[i].saveid == mode) {
return i;
}
}
@@ -238,7 +241,7 @@ void Scumm::killVerb(int slot) {
if (slot==0)
return;
- vs = &verbs[slot];
+ vs = &_verbs[slot];
vs->verbid = 0;
vs->curmode = 0;
diff --git a/windows.cpp b/windows.cpp
index bfb66abb0f..9b3988eedf 100644
--- a/windows.cpp
+++ b/windows.cpp
@@ -17,6 +17,9 @@
*
* Change Log:
* $Log$
+ * Revision 1.5 2001/10/16 10:01:48 strigeus
+ * preliminary DOTT support
+ *
* Revision 1.4 2001/10/12 07:24:06 strigeus
* fast mode support
*
@@ -124,8 +127,7 @@ void Error(const char *msg) {
int sel;
Scumm scumm;
WndMan wm[1];
-
-
+byte veryFastMode;
void modifyslot(int sel, int what);
@@ -156,6 +158,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
wm->_scumm->_fastMode ^= 1;
}
+ if (wParam=='G') {
+ veryFastMode ^= 1;
+ }
+
break;
case WM_MOUSEMOVE:
@@ -711,7 +717,6 @@ int _declspec(naked) endpentiumtest() {
-#ifdef _DEBUG
void decompressMask(byte *d, byte *s) {
int x,y;
@@ -732,12 +737,19 @@ void decompressMask(byte *d, byte *s) {
void outputdisplay2(Scumm *s, int disp) {
byte *old = wm->_vgabuf;
+
+ byte buf[64000];
+
switch(disp) {
case 0:
- wm->_vgabuf = s->getResourceAddress(0xA, 5);
+ wm->_vgabuf = buf;
+ memcpy(buf, wm->_vgabuf, 64000);
+ memcpy(buf+320*144,s->getResourceAddress(0xA, 7),320*56);
break;
case 1:
- wm->_vgabuf = s->getResourceAddress(0xA, 1);
+ wm->_vgabuf = buf;
+ memcpy(buf, wm->_vgabuf, 64000);
+ memcpy(buf+320*144,s->getResourceAddress(0xA, 3),320*56);
break;
case 2:
wm->_vgabuf = NULL;
@@ -759,7 +771,7 @@ void outputdisplay2(Scumm *s, int disp) {
wm->writeToScreen();
wm->_vgabuf = old;
}
-#endif
+
#if 0
void outputdisplay(Scumm *s) {
@@ -783,6 +795,8 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {
}
+int clock;
+
void updateScreen(Scumm *s) {
if (s->_palDirtyMax != -1) {
wm->setPalette(s->_currentPalette, 0, 256);
@@ -792,8 +806,12 @@ void updateScreen(Scumm *s) {
wm->writeToScreen();
}
+
+
void waitForTimer(Scumm *s) {
- Sleep(10);
+ if (!veryFastMode) {
+ Sleep(5);
+ }
s->_scummTimer+=2;
wm->handleMessage();
}
@@ -808,7 +826,12 @@ void drawMouse(Scumm *s, int, int, int, byte*, bool) {
#undef main
int main(int argc, char* argv[]) {
scumm._videoMode = 0x13;
+
+#if defined(DOTT)
+ scumm._exe_name = "tentacle";
+#else
scumm._exe_name = "monkey2";
+#endif
wm->init();
wm->_vgabuf = (byte*)calloc(320,200);