diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | actor.cpp | 56 | ||||
| -rw-r--r-- | costume.cpp | 50 | ||||
| -rw-r--r-- | gfx.cpp | 316 | ||||
| -rw-r--r-- | object.cpp | 312 | ||||
| -rw-r--r-- | resource.cpp | 237 | ||||
| -rw-r--r-- | saveload.cpp | 257 | ||||
| -rw-r--r-- | script.cpp | 2564 | ||||
| -rw-r--r-- | script_v1.cpp | 1986 | ||||
| -rw-r--r-- | script_v2.cpp | 2124 | ||||
| -rw-r--r-- | scumm.h | 403 | ||||
| -rw-r--r-- | scummsys.h | 20 | ||||
| -rw-r--r-- | scummvm.cpp | 266 | ||||
| -rw-r--r-- | scummvm.dsp | 10 | ||||
| -rw-r--r-- | sdl.cpp | 6 | ||||
| -rw-r--r-- | sound.cpp | 35 | ||||
| -rw-r--r-- | string.cpp | 274 | ||||
| -rw-r--r-- | verbs.cpp | 43 | ||||
| -rw-r--r-- | windows.cpp | 37 | 
19 files changed, 6197 insertions, 2801 deletions
| @@ -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 \ @@ -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); @@ -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 @@ -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 @@ -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)  	); @@ -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); @@ -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); | 
