diff options
| author | Ludvig Strigeus | 2001-11-05 19:21:49 +0000 | 
|---|---|---|
| committer | Ludvig Strigeus | 2001-11-05 19:21:49 +0000 | 
| commit | e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3 (patch) | |
| tree | 56763f74cbefb6091d6d76d1d3dca234acca2eeb | |
| parent | cd6443a8e571bdabfd3add2d105c97db704fe31d (diff) | |
| download | scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.tar.gz scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.tar.bz2 scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.zip | |
bug fixes,
speech in dott
svn-id: r3454
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | actor.cpp | 36 | ||||
| -rw-r--r-- | boxes.cpp | 36 | ||||
| -rw-r--r-- | costume.cpp | 65 | ||||
| -rw-r--r-- | gfx.cpp | 103 | ||||
| -rw-r--r-- | object.cpp | 46 | ||||
| -rw-r--r-- | resource.cpp | 153 | ||||
| -rw-r--r-- | saveload.cpp | 172 | ||||
| -rw-r--r-- | script.cpp | 39 | ||||
| -rw-r--r-- | script_v1.cpp | 77 | ||||
| -rw-r--r-- | script_v2.cpp | 72 | ||||
| -rw-r--r-- | scumm.h | 225 | ||||
| -rw-r--r-- | scummsys.h | 9 | ||||
| -rw-r--r-- | scummvm.cpp | 66 | ||||
| -rw-r--r-- | scummvm.dsp | 20 | ||||
| -rw-r--r-- | sdl.cpp | 166 | ||||
| -rw-r--r-- | sound.cpp | 295 | ||||
| -rw-r--r-- | stdafx.h | 12 | ||||
| -rw-r--r-- | string.cpp | 92 | ||||
| -rw-r--r-- | sys.cpp | 22 | ||||
| -rw-r--r-- | verbs.cpp | 20 | ||||
| -rw-r--r-- | windows.cpp | 109 | 
22 files changed, 1363 insertions, 488 deletions
| @@ -1,17 +1,8 @@ -# $Id$ -# -# $Log$ -# Revision 1.7  2001/11/03 06:17:36  cmatsuoka -# Using full path for SDL includes (-ISDL doesn't seem to work for -# native builds). -# -  CC	= gcc  CFLAGS	= -g -Wno-multichar  DEFINES	= -DUNIX -LDFLAGS := -INCLUDES:= -I/usr/include/SDL -D_REENTRANT -LIBS	:= -lSDL +LDFLAGS := `sdl-config --libs` +INCLUDES:= `sdl-config --cflags`  CPPFLAGS= $(DEFINES) $(INCLUDES)  ZIPFILE := scummvm-`date '+%Y-%m-%d'`.zip @@ -44,6 +35,3 @@ dist:  check:  $(OBJS): $(INCS) - -$(OBJS): Makefile - @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.8  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.7  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -241,7 +245,7 @@ void Scumm::setupActorScale(Actor *a) {  	if (scale & 0x8000) {  		scale = (scale&0x7FFF)+1; -		resptr = getResourceAddress(0xB, scale); +		resptr = getResourceAddress(rtScaleTable, scale);  		if (resptr==NULL)  			error("Scale table %d not defined",scale);  		if (a->y >= 0) @@ -584,7 +588,7 @@ void Scumm::showActor(Actor *a) {  	adjustActorPos(a); -	ensureResourceLoaded(3, a->costume); +	ensureResourceLoaded(rtCostume, a->costume);  	if (a->costumeNeedsInit) {  		startAnimActor(a, a->initFrame, a->facing); @@ -615,8 +619,9 @@ void Scumm::stopTalk() {  	act = _vars[VAR_TALK_ACTOR];  	if (act && act<0x80) {  		Actor *a = derefActorSafe(act, "stopTalk"); -		if (_currentRoom == a->room) { -			startAnimActor(a, a->talkFrame2, a->facing);			 +		if (_currentRoom == a->room && _useTalkAnims) { +			startAnimActor(a, a->talkFrame2, a->facing); +			_useTalkAnims = false;  		}  		_vars[VAR_TALK_ACTOR] = 0xFF;  	} @@ -824,7 +829,7 @@ void Scumm::actorAnimate(Actor *a) {  	if (a->animProgress >= a->animSpeed) {  		a->animProgress = 0;  		cost.loadCostume(a->costume); -		if (cost.animate(&a->cost)) { +		if (cost.animate(a)) {  			a->needRedraw = true;  			a->needBgReset = true;  		} @@ -885,7 +890,10 @@ void Scumm::actorTalk() {  			if (!_keepText)  				stopTalk();  			_vars[VAR_TALK_ACTOR] = a->number; -			startAnimActor(a,a->talkFrame1,a->facing); +			if (!string[0].no_talk_anim) { +				startAnimActor(a,a->talkFrame1,a->facing); +				_useTalkAnims = true; +			}  			oldact = _vars[VAR_TALK_ACTOR];  		}  	} @@ -976,8 +984,22 @@ void Scumm::startWalkActor(Actor *a, int x, int y, int dir) {  }  byte *Scumm::getActorName(Actor *a) { -	byte *ptr = getResourceAddress(9, a->number); +	byte *ptr = getResourceAddress(rtActorName, a->number);  	if(ptr==NULL)  		return (byte*)" ";  	return ptr;  } + +bool Scumm::isCostumeInUse(int cost) { +	int i; +	Actor *a; + +	if (_roomResource!=0) +		for (i=1; i<13; i++) { +			a = derefActor(i); +			if (a->room == _currentRoom && a->costume == cost) +				return true; +		} + +	return false; +}
\ No newline at end of file @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.3  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.2  2001/10/11 10:45:39  strigeus   * Fixed bug in Scumm::getBoxCoordinates where unsigned integers were read   * instead of signed ones. @@ -47,12 +51,12 @@ int Scumm::getBoxScale(int box) {  }  byte Scumm::getNumBoxes() { -	byte *ptr = getResourceAddress(0xE, 2); +	byte *ptr = getResourceAddress(rtMatrix, 2);  	return ptr[8];  }  Box *Scumm::getBoxBaseAddr(int box) { -	byte *ptr = getResourceAddress(0xE, 2); +	byte *ptr = getResourceAddress(rtMatrix, 2);  	checkRange(ptr[8]-1, 0, box, "Illegal box %d");  	return (Box*)(ptr + box*SIZEOF_BOX + 10);  } @@ -295,7 +299,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {  }  byte *Scumm::getBoxMatrixBaseAddr() { -	byte *ptr = getResourceAddress(0xE, 1) + 8; +	byte *ptr = getResourceAddress(rtMatrix, 1) + 8;  	if (*ptr==0xFF) ptr++;  	return ptr;  } @@ -512,19 +516,19 @@ void Scumm::createBoxMatrix() {  	_maxBoxVertexHeap = 1000; -	createResource(0xE, 4, 1000); -	createResource(0xE, 3, 4160); //65 items of something of size 64 -	createResource(0xE, 1, BOX_MATRIX_SIZE+8); +	createResource(rtMatrix, 4, 1000); +	createResource(rtMatrix, 3, 4160); //65 items of something of size 64 +	createResource(rtMatrix, 1, BOX_MATRIX_SIZE+8); -	matrix_ptr = getResourceAddress(0xE, 1); +	matrix_ptr = getResourceAddress(rtMatrix, 1);  	/* endian & alignment safe */  	((uint32*)matrix_ptr)[1] = TO_BE_32(BOX_MATRIX_SIZE+8);  	((uint32*)matrix_ptr)[0] = MKID('BOXM'); -	_boxMatrixPtr4 = getResourceAddress(0xE, 4); -	_boxMatrixPtr1 = getResourceAddress(0xE, 1) + 8; -	_boxMatrixPtr3 = getResourceAddress(0xE, 3); +	_boxMatrixPtr4 = getResourceAddress(rtMatrix, 4); +	_boxMatrixPtr1 = getResourceAddress(rtMatrix, 1) + 8; +	_boxMatrixPtr3 = getResourceAddress(rtMatrix, 3);  	_boxPathVertexHeapIndex = _boxMatrixItem = 0; @@ -628,8 +632,8 @@ void Scumm::createBoxMatrix() {  	}  	addToBoxMatrix(0xFF); -	nukeResource(0xE, 4); -	nukeResource(0xE, 3); +	nukeResource(rtMatrix, 4); +	nukeResource(rtMatrix, 3);  }  PathVertex *Scumm::unkMatrixProc1(PathVertex *vtx, PathNode *node) { @@ -716,7 +720,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  			if (upperRightX == upperLeftX &&  				  box.upperLeftX == upperLeftX &&  					box.upperRightX == upperRightX) { -				/* 5b74 */  				n = m = 0;  				if (upperRightY < upperLeftY) {  					n = 1; @@ -732,7 +735,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  						 box.upperRightY==upperLeftY) &&  						 upperRightY != upperLeftY &&  						 box.upperLeftY!=box.upperRightY) { -					/* if_1_if */  					if (n) {  						SWAP(upperRightY, upperLeftY);  					} @@ -740,7 +742,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  						SWAP(box.upperRightY, box.upperLeftY);  					}  				} else { -					/* if_1_else */  					if (n) {  						SWAP(upperRightY, upperLeftY);  					} @@ -751,7 +752,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  				}	  			} -			/* do_it_for_y */  			if (upperRightY == upperLeftY &&   					box.upperLeftY == upperLeftY &&  					box.upperRightY == upperRightY) { @@ -771,7 +771,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  						 upperRightX != upperLeftX &&  						 box.upperLeftX!=box.upperRightX) { -					/* if_2_if */  					if (n) {  						SWAP(upperRightX, upperLeftX);  					} @@ -779,7 +778,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) {  						SWAP(box.upperRightX, box.upperLeftX);  					}  				} else { -					/* if_2_else */  					if (n) {  						SWAP(upperRightX, upperLeftX);  					} @@ -836,7 +834,7 @@ void *Scumm::addToBoxVertexHeap(int size) {  }  PathVertex *Scumm::addPathVertex() { -	_boxMatrixPtr4 = getResourceAddress(0xE, 4); +	_boxMatrixPtr4 = getResourceAddress(rtMatrix, 4);  	_boxPathVertexHeapIndex = 0;  	return (PathVertex*)addToBoxVertexHeap(sizeof(PathVertex));  } diff --git a/costume.cpp b/costume.cpp index 62d882b9ea..d4327290de 100644 --- a/costume.cpp +++ b/costume.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.7  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.6  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -275,6 +279,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {  	if ((uint)_top > (uint)_vscreenheight)  		_top = 0; +	if (_left<0) _left=0; +  	if ((uint)_bottom > _vscreenheight)  		_bottom = _vscreenheight; @@ -289,19 +295,20 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {  		return 2;  	} -	_bgbak_ptr = _vm->getResourceAddress(0xA, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; -	_backbuff_ptr = _vm->getResourceAddress(0xA, 1) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; + +	_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; +	_backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1) + _vm->virtscr[0].xstart + _ypos*320 + _xpos;  	charsetmask = _vm->hasCharsetMask(_left, _top + _vm->virtscr[0].topline, _right, _vm->virtscr[0].topline + _bottom);  	masking = 0;  	if (_zbuf) {  		masking = _vm->isMaskActiveAt(_left, _top, _right, _bottom, -			_vm->getResourceAddress(0xA, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip +			_vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip  		);  	}  	if (_zbuf || charsetmask) { -		_mask_ptr = _vm->getResourceAddress(0xA, 9) + _ypos*40 + _vm->_screenStartStrip; +		_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _ypos*40 + _vm->_screenStartStrip;  		_imgbufoffs = _vm->gdi._imgBufOffs[_zbuf];  		if (!charsetmask && _zbuf!=0) @@ -680,7 +687,6 @@ StartPos:;  }  void CostumeRenderer::loadCostume(int id) { -	  	_ptr = _vm->getResourceAddress(3, id);  	if (_vm->_majorScummVersion == 6) { @@ -739,51 +745,62 @@ byte CostumeRenderer::drawCostume(Actor *a) {  	return r;  } -byte CostumeRenderer::animateOneSlot(CostumeData *cd, int slot) { +byte CostumeRenderer::animateOneSlot(Actor *a, int slot) {  	int highflag; -	int i,end,code; +	int i,end; +	byte code,nc; -	if (cd->a[slot]==0xFFFF) +	if (a->cost.a[slot]==0xFFFF)  		return 0; -	highflag = cd->a[slot]&0x8000; -	i = cd->a[slot]&0x7FFF; -	end = cd->c[slot]; +	highflag = a->cost.a[slot]&0x8000; +	i = a->cost.a[slot]&0x7FFF; +	end = a->cost.c[slot];  	code=_dataptr[i]&0x7F;  	do {  		if (!highflag) {  			if (i++ >= end) -				i = cd->b[slot]; +				i = a->cost.b[slot];  		} else {  			if (i != end)  				i++;  		} -		if (_dataptr[i]==0x7C) { -			cd->animCounter1++; -			if(cd->b[slot] != end) -				continue; -		} +		nc = _dataptr[i]; -		if (_dataptr[i]==0x78) { -			cd->animCounter2++; -			if(cd->b[slot] != end) +		if (nc==0x7C) { +			a->cost.animCounter1++; +			if(a->cost.b[slot] != end)  				continue; +		} else { +			if (_vm->_majorScummVersion == 6) { +				if (nc>=0x71 && nc<=0x78) { +					_vm->addSoundToQueue2(a->sound[nc-0x71]); +					if(a->cost.b[slot] != end) +						continue; +				} +			} else { +				if (nc==0x78) { +					a->cost.animCounter2++; +					if(a->cost.b[slot] != end) +						continue; +				} +			}  		} -		cd->a[slot] = i|highflag; +		a->cost.a[slot] = i|highflag;  		return (_dataptr[i]&0x7F) != code;  	} while(1);  } -byte CostumeRenderer::animate(CostumeData *cd) { +byte CostumeRenderer::animate(Actor *a) {  	int i;  	byte r = 0;  	for (i=0; i<16; i++) { -		if(cd->a[i]!=0xFFFF) -			r+=animateOneSlot(cd, i); +		if(a->cost.a[i]!=0xFFFF) +			r+=animateOneSlot(a, i);  	}  	return r;  } @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.11  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.10  2001/10/29 23:07:24  strigeus   * better MI1 compatibility   * @@ -82,11 +86,11 @@ void Scumm::initScreens(int a, int b, int w, int h) {  	int i;  	for (i=0; i<3; i++) { -		nukeResource(10, i+1); -		nukeResource(10, i+5); +		nukeResource(rtBuffer, i+1); +		nukeResource(rtBuffer, i+5);  	} -	if (!getResourceAddress(10,4)) { +	if (!getResourceAddress(rtBuffer,4)) {  		initVirtScreen(3, 80, 13, false, false);  	}  	initVirtScreen(0, b, h-b, true, true); @@ -118,10 +122,10 @@ void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs, bool fou  	if (vs->scrollable)  		size += 320*4; -	memset(createResource(10, slot+1, size),0,size); +	memset(createResource(rtBuffer, slot+1, size),0,size);  	if (twobufs) { -		memset(createResource(10, slot+5, size),0x23,size); +		memset(createResource(rtBuffer, slot+5, size),0x23,size);  	}  	if (slot != 3) { @@ -149,7 +153,7 @@ void Scumm::unkVirtScreen2() {  	} else {  		vs = &virtscr[0]; -		blitToScreen(this, getResourceAddress(10, 1) + _screenStartStrip*8, +		blitToScreen(this, getResourceAddress(rtBuffer, 1) + _screenStartStrip*8,  			0, vs->topline, 320, vs->height);  		for (i = 0; i<40; i++) { @@ -206,7 +210,7 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b) {  	if (b > vs->height)  		b = vs->height; -	ptr = _vm->getResourceAddress(10, vs->number+1) + (t*40+x)*8 + _readOffs; +	ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (t*40+x)*8 + _readOffs;  	blitToScreen(_vm, ptr, x*8, vs->topline+t, w, b-t);  } @@ -344,7 +348,7 @@ void Scumm::initBGBuffers() {  	int size, itemsize, i;  	byte *room; -	room = getResourceAddress(1, _roomResource); +	room = getResourceAddress(rtRoom, _roomResource);  	ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room, 0), 0); @@ -355,7 +359,7 @@ void Scumm::initBGBuffers() {  	itemsize = (_scrHeight + 4) * 40;  	size = itemsize * gdi._numZBuffer; -	memset(createResource(10, 9, size), 0, size); +	memset(createResource(rtBuffer, 9, size), 0, size);  	for (i=0; i<4; i++)  		gdi._imgBufOffs[i] = i*itemsize; @@ -391,7 +395,7 @@ void Scumm::setPaletteFromPtr(byte *ptr) {  	}  	if (_videoMode==0xE) { -		epal = getResourceAddress(1, _roomResource) + _EPAL_offs + 8; +		epal = getResourceAddress(rtRoom, _roomResource) + _EPAL_offs + 8;  		for (i=0; i<256; i++,epal++) {  			_currentPalette[i] = *epal&0xF;  			_currentPalette[i+256] = *epal>>4; @@ -403,7 +407,7 @@ void Scumm::setPaletteFromPtr(byte *ptr) {  void Scumm::setPaletteFromRes() {  	byte *ptr; -	ptr = getResourceAddress(1, _roomResource) + _CLUT_offs; +	ptr = getResourceAddress(rtRoom, _roomResource) + _CLUT_offs;  	setPaletteFromPtr(ptr);  } @@ -503,11 +507,11 @@ void Scumm::moveMemInPalRes(int start, int end, byte direction) {  	if (!_palManipCounter)	  		return; -	startptr = getResourceAddress(0xC, 4) + start * 6; -	endptr = getResourceAddress(0xC, 4) + end * 6; +	startptr = getResourceAddress(rtTemp, 4) + start * 6; +	endptr = getResourceAddress(rtTemp, 4) + end * 6; -	startptr2 = getResourceAddress(0xC, 5) + start * 6; -	endptr2 = getResourceAddress(0xC, 5) + end * 6; +	startptr2 = getResourceAddress(rtTemp, 5) + start * 6; +	endptr2 = getResourceAddress(rtTemp, 5) + end * 6;  	num = end - start; @@ -541,7 +545,7 @@ void Scumm::unkVirtScreen4(int a) {  		return;  	vs = &virtscr[0]; -	gdi._backbuff_ptr = getResourceAddress(0xA, 1) + vs->xstart; +	gdi._backbuff_ptr = getResourceAddress(rtBuffer, 1) + vs->xstart;  	memset(gdi._backbuff_ptr, 0, vs->size);  	switch(a) { @@ -655,12 +659,12 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr  		if (bottom > vs->bdirty[sx])  			vs->bdirty[sx] = bottom; -		_backbuff_ptr = _vm->getResourceAddress(0xA, vs->number+1) + (y*40+x)*8; -		_bgbak_ptr = _vm->getResourceAddress(0xA, vs->number+5) + (y*40+x)*8; +		_backbuff_ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (y*40+x)*8; +		_bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number+5) + (y*40+x)*8;  		if (!twobufs) {  			_bgbak_ptr = _backbuff_ptr;  		} -		_mask_ptr = _vm->getResourceAddress(0xA, 9) + (y*40+x); +		_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + (y*40+x);  		where_draw_ptr = _bgbak_ptr;  		decompressBitmap(); @@ -688,8 +692,8 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr  			if (!zplane_list[i])  				continue;  			_z_plane_ptr = zplane_list[i] + READ_LE_UINT16(zplane_list[i] + stripnr*2 + 8); -			_mask_ptr_dest = _vm->getResourceAddress(0xA, 9) + y*40 + x + _imgBufOffs[i]; -			if (dseg_4E3B!=0 && flag) +			_mask_ptr_dest = _vm->getResourceAddress(rtBuffer, 9) + y*40 + x + _imgBufOffs[i]; +			if (_useOrDecompress && flag)  				decompressMaskImgOr();  			else  				decompressMaskImg(); @@ -706,7 +710,7 @@ void Gdi::decompressBitmap() {  		0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x0,  	}; -	dseg_4E3B = 0; +	_useOrDecompress = true;  	byte code = *_smap_ptr++; @@ -729,14 +733,14 @@ void Gdi::decompressBitmap() {  		break;  	case 34: case 35: case 36: case 37: case 38: -		dseg_4E3B = 1; +		_useOrDecompress = true;  		_decomp_shr = code - 30;  		_decomp_mask = decompress_table[code - 30 ];  		unkDecode4();  		break;  	case 44: case 45: case 46: case 47: case 48: -		dseg_4E3B = 1; +		_useOrDecompress = true;  		_decomp_shr = code - 40;  		_decomp_mask = decompress_table[code - 40];  		unkDecode2(); @@ -749,7 +753,7 @@ void Gdi::decompressBitmap() {  		break;  	case 84: case 85: case 86: case 87: case 88: -		dseg_4E3B = 1; +		_useOrDecompress = true;  		_decomp_shr = code - 80;  		_decomp_mask = decompress_table[code - 80];  		unkDecode3(); @@ -764,7 +768,7 @@ void Gdi::decompressBitmap() {  	/* New since version 6 */  	case 124: case 125: case 126: case 127: case 128: -		dseg_4E3B = 1; +		_useOrDecompress = true;  		_decomp_shr = code - 120;  		_decomp_mask = decompress_table[code - 120];  		unkDecode3(); @@ -918,7 +922,7 @@ void Scumm::redrawBGStrip(int start, int num) {  			_scrHeight);  	} -	gdi.drawBitmap(getResourceAddress(1, _roomResource)+_IM00_offs, +	gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource)+_IM00_offs,  		_curVirtScreen, s, 0, _curVirtScreen->height, s, num, 0);  } @@ -1250,9 +1254,9 @@ void Scumm::restoreBG(int left, int top, int right, int bottom) {  	height = (top-topline) * 320 + vs->xstart + left; -	backbuff = getResourceAddress(0xA, vs->number+1) + height; -	bgbak = getResourceAddress(0xA, vs->number+5) + height; -	mask = getResourceAddress(0xA, 9) + top * 40 + (left>>3) + _screenStartStrip; +	backbuff = getResourceAddress(rtBuffer, vs->number+1) + height; +	bgbak = getResourceAddress(rtBuffer, vs->number+5) + height; +	mask = getResourceAddress(rtBuffer, 9) + top * 40 + (left>>3) + _screenStartStrip;  	if (vs->number==0) {  		mask += vs->topline * 216;  	} @@ -1455,7 +1459,7 @@ void Scumm::setShake(int mode) {  void Gdi::clearUpperMask() {  	memset( -		_vm->getResourceAddress(0xA, 9), +		_vm->getResourceAddress(rtBuffer, 9),  		0,  		_imgBufOffs[1] - _imgBufOffs[0]  	); @@ -1593,8 +1597,8 @@ void Scumm::palManipulate() {  	if (!_palManipCounter)  		return; -	srcptr = getResourceAddress(0xC, 4) + _palManipStart*6; -	destptr = getResourceAddress(0xC, 5) + _palManipStart*6; +	srcptr = getResourceAddress(rtTemp, 4) + _palManipStart*6; +	destptr = getResourceAddress(rtTemp, 5) + _palManipStart*6;  	pal = _currentPalette + _palManipStart * 3;  	i = _palManipStart; @@ -1618,8 +1622,8 @@ void Scumm::palManipulate() {  	}  	setDirtyColors(_palManipStart, _palManipEnd);  	if (!--_palManipCounter) { -		nukeResource(0xC, 4); -		nukeResource(0xC, 5); +		nukeResource(rtTemp, 4); +		nukeResource(rtTemp, 5);  	}  } @@ -1635,6 +1639,7 @@ void Scumm::screenEffect(int effect) {  	case 133:	unkScreenEffect4();	break;  	case 134:	unkScreenEffect5(0); break;  	case 135:	unkScreenEffect5(1); break; +	case 129: break;  	default:  		warning("Unknown screen effect, %d", effect);  	} @@ -1683,9 +1688,9 @@ void Gdi::resetBackground(byte top, byte bottom, int strip) {  		vs->bdirty[strip] = bottom;  	offs = (top * 40 + _vm->_screenStartStrip + strip); -	_mask_ptr = _vm->getResourceAddress(0xA, 9)	+ offs; -	_bgbak_ptr = _vm->getResourceAddress(0xA, 5)	+ (offs<<3); -	_backbuff_ptr = _vm->getResourceAddress(0xA, 1)	+ (offs<<3); +	_mask_ptr = _vm->getResourceAddress(rtBuffer, 9)	+ offs; +	_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5)	+ (offs<<3); +	_backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1)	+ (offs<<3);  	_numLinesToProcess = bottom - top;  	if (_numLinesToProcess) { @@ -1762,6 +1767,10 @@ void Scumm::setCursorImg(int room, int img) {  byte Scumm::isMaskActiveAt(int l, int t, int r, int b, byte *mem) {  	int w,h,inc,i; +	 +	if (l<0 || t<0) { +		l = 0; +	}  	mem += b*40 + (l>>3); @@ -1812,7 +1821,7 @@ byte *Scumm::findPalInPals(byte *pal, int index) {  byte *Scumm::getPalettePtr() {  	byte *cptr; -	cptr = getResourceAddress(1, _roomResource); +	cptr = getResourceAddress(rtRoom, _roomResource);  	if (_CLUT_offs) {  		cptr += _CLUT_offs;  	} else { @@ -1876,13 +1885,21 @@ void Scumm::unkMiscOp4(int a, int b, int c, int d) {  	}  	grabCursor( -		getResourceAddress(10, vs->number+1) + (b-vs->topline)*320 + a,  +		getResourceAddress(rtBuffer, vs->number+1) + (b-vs->topline)*320 + a,   		c,d); -	 -	 -	warning("stub unkMiscOp4(%d,%d,%d,%d)", a,b,c,d); + +//	_cursor_width = c; +//	_cursor_height = d;  }  void Scumm::grabCursor(byte *ptr, int width, int height) { +#if 0 +	int size; +	byte *ptr; +	size = width * height; +	if (size > 10240) +		error("grabCursor: grabbed cursor too big"); +	ptr = createResource( +#endif  } diff --git a/object.cpp b/object.cpp index 36b8390998..5d44855b19 100644 --- a/object.cpp +++ b/object.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.8  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.7  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -154,10 +158,10 @@ void Scumm::getObjectXYPos(int object) {  			state = 0;  		if (od->fl_object_index) { -			ptr = getResourceAddress(0xD, od->fl_object_index); +			ptr = getResourceAddress(rtFlObject, od->fl_object_index);  			ptr = findResource(MKID('OBIM'), ptr, 0);  		} else { -			ptr = getResourceAddress(1, _roomResource); +			ptr = getResourceAddress(rtRoom, _roomResource);  			ptr += od->offs_obim_to_room;  		} @@ -302,10 +306,10 @@ void Scumm::drawObject(int obj, int arg) {  		return;  	if (od->fl_object_index) { -		ptr = getResourceAddress(0xD, od->fl_object_index); +		ptr = getResourceAddress(rtFlObject, od->fl_object_index);  		ptr = findResource(MKID('OBIM'), ptr, 0);   	} else { -		ptr = getResourceAddress(1, _roomResource); +		ptr = getResourceAddress(rtRoom, _roomResource);  		ptr = ptr + od->offs_obim_to_room;  	} @@ -351,7 +355,7 @@ void Scumm::loadRoomObjects() {  	CHECK_HEAP -	room = getResourceAddress(1, _roomResource); +	room = getResourceAddress(rtRoom, _roomResource);  	roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room, 0);  	_numObjectsInRoom = READ_LE_UINT16(&roomhdr->numObjects); @@ -465,7 +469,7 @@ void Scumm::clearOwnerOf(int obj) {  			if (_objs[i].obj_nr==obj) {  				if (!_objs[i].fl_object_index)  					return; -				nukeResource(0xD, _objs[i].fl_object_index); +				nukeResource(rtFlObject, _objs[i].fl_object_index);  				_objs[i].obj_nr = 0;  				_objs[i].fl_object_index = 0;  			} @@ -476,7 +480,7 @@ void Scumm::clearOwnerOf(int obj) {  		if (_inventory[i] == obj) {  			j = whereIsObject(obj);  			if (j==0) { -				nukeResource(5, i); +				nukeResource(rtInventory, i);  				_inventory[i] = 0;  			}  			a = &_inventory[1]; @@ -484,7 +488,7 @@ void Scumm::clearOwnerOf(int obj) {  				if (!a[0] && a[1]) {  					a[0] = a[1];  					a[1] = 0; -					ptr = getResourceAddress(5, i+1); +					ptr = getResourceAddress(rtInventory, i+1);  					_baseInventoryItems[i] = _baseInventoryItems[i+1];  					_baseInventoryItems[i+1] = 0;  					/* TODO: some wacky write is done here */ @@ -558,14 +562,14 @@ byte *Scumm::getObjectAddress(int obj) {  	if ((_objectFlagTable[obj]&0xF)!=0xF) {  		for(i=0; i<_maxInventoryItems; i++) {  			if (_inventory[i] == obj) -				return getResourceAddress(5, i); +				return getResourceAddress(rtInventory, i);  		}  	} 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; +					return getResourceAddress(rtFlObject, _objs[i].fl_object_index)+8; +				return getResourceAddress(rtRoom, _roomResource) + _objs[i].offs_obcd_to_room;  			}  		}  	} @@ -587,18 +591,18 @@ void Scumm::addObjectToInventory(int obj, int room) {  	if (whereIsObject(obj)==4) {  		i = getObjectIndex(obj); -		ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64; +		ptr = getResourceAddress(rtFlObject, _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; -		memcpy(getResourceAddress(5, slot), ptr, size); +		createResource(rtInventory, slot, size); +		ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64; +		memcpy(getResourceAddress(rtInventory, slot), ptr, size);  		CHECK_HEAP  		return;  	} -	ensureResourceLoaded(1, room); -	roomptr = getResourceAddress(1, room); +//	ensureResourceLoaded(rtRoom, room); +	roomptr = getResourceAddress(rtRoom, room);  	roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0);  	numobj = READ_LE_UINT16(&roomhdr->numObjects);  	if (numobj==0) @@ -616,9 +620,9 @@ void Scumm::addObjectToInventory(int obj, int room) {  			size = READ_BE_UINT32_UNALIGNED(obcdptr+4);  			slot = getInventorySlot();  			_inventory[slot] = obj; -			createResource(5, slot, size); -			obcdptr = getResourceAddress(1, room) + cdoffs; -			memcpy(getResourceAddress(5,slot),obcdptr,size); +			createResource(rtInventory, slot, size); +			obcdptr = getResourceAddress(rtRoom, room) + cdoffs; +			memcpy(getResourceAddress(rtInventory,slot),obcdptr,size);  			CHECK_HEAP  			return;  		} @@ -713,7 +717,7 @@ void Scumm::setObjectState(int obj, int state, int x, int y) {  	if (x != -1) {  		_objs[i].x_pos = x; -		_objs[i].x_pos = y; +		_objs[i].y_pos = y;  	}  	addObjectToDrawQue(i); diff --git a/resource.cpp b/resource.cpp index 973940eabb..fa0f3c5033 100644 --- a/resource.cpp +++ b/resource.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.9  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.8  2001/10/29 21:49:25  strigeus   * fixed bug in validateResource   * @@ -424,7 +428,7 @@ void Scumm::loadCharset(int no) {  	debug(9, "loadCharset(%d)",no);  	checkRange(_maxCharsets-1, 1, no, "Loading illegal charset %d"); -	ensureResourceLoaded(6, no); +//	ensureResourceLoaded(6, no);  	ptr = getResourceAddress(6, no);  	for (i=0; i<15; i++) { @@ -434,7 +438,7 @@ void Scumm::loadCharset(int no) {  void Scumm::nukeCharset(int i) {  	checkRange(_maxCharsets-1, 1, i, "Nuking illegal charset %d"); -	nukeResource(6, i); +	nukeResource(rtCharset, i);  }  void Scumm::ensureResourceLoaded(int type, int i) { @@ -506,7 +510,7 @@ int Scumm::loadResource(int type, int index) {  			/* dump the resource */  #ifdef DUMP_SCRIPTS  			if(type==2) { -				dumpResource("script-", index, getResourceAddress(2, index)); +				dumpResource("script-", index, getResourceAddress(rtScript, index));  			}  #endif @@ -540,11 +544,11 @@ int Scumm::readSoundResource(int type, int index) {  		resStart += size2 + 8; -		for (i=0,ptr=_soundTagTable; i<_numSoundTags; i++,ptr+=5) { +		for (i=0,ptr=_soundTagTable; i<_numSoundTags; i++,ptr+=4) {  /* endian OK, tags are in native format */  			if (READ_UINT32_UNALIGNED(ptr) == tag) {  				fileSeek(_fileHandle, -8, SEEK_CUR); -				fileRead(_fileHandle,createResource(type, index, size2+8), size+8); +				fileRead(_fileHandle,createResource(type, index, size2+8), size2+8);  				return 1;  			}  		} @@ -575,7 +579,7 @@ byte *Scumm::getResourceAddress(int type, int index) {  		ensureResourceLoaded(type, index);  	}	 -	setResourceFlags(type, index, 1); +	setResourceCounter(type, index, 1);  	ptr=(byte*)res.address[type][index];  	if (!ptr) @@ -585,7 +589,7 @@ byte *Scumm::getResourceAddress(int type, int index) {  }  byte *Scumm::getStringAddress(int i) { -	byte *b = getResourceAddress(7, i); +	byte *b = getResourceAddress(rtString, i);  	if (!b)  		return b; @@ -594,11 +598,14 @@ byte *Scumm::getStringAddress(int i) {  	return b;  } -void Scumm::setResourceFlags(int type, int index, byte flag) { +void Scumm::setResourceCounter(int type, int index, byte flag) {  	res.flags[type][index] &= 0x80;  	res.flags[type][index] |= flag;  } +/* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */ +#define SAFETY_AREA 2 +  byte *Scumm::createResource(int type, int index, uint32 size) {  	byte *ptr; @@ -612,19 +619,20 @@ byte *Scumm::createResource(int type, int index, uint32 size) {  	validateResource("allocating", type, index);  	nukeResource(type, index); +	expireResources(size); +  	CHECK_HEAP -	ptr = (byte*)alloc(size + sizeof(ResHeader)); +	ptr = (byte*)alloc(size + sizeof(ResHeader) + SAFETY_AREA);  	if (ptr==NULL) {  		error("Out of memory while allocating %d", size);  	} -	res.address[type][index] = ptr; +	_allocatedSize += size; +	res.address[type][index] = ptr;  	((ResHeader*)ptr)->size = size; - -	setResourceFlags(type, index, 1); - +	setResourceCounter(type, index, 1);  	return ptr + sizeof(ResHeader); /* skip header */  } @@ -635,27 +643,22 @@ void Scumm::validateResource(const char *str, int type, int index) {  }  void Scumm::nukeResource(int type, int index) { -	 +	byte *ptr; +  	debug(9, "nukeResource(%d,%d)", type, index);  	CHECK_HEAP  	assert( res.address[type] );  	assert( index>=0 && index < res.num[type]); -	if (res.address[type][index]) { -		free(res.address[type][index]); +	if ((ptr = res.address[type][index]) != NULL) {  		res.address[type][index] = 0; +		res.flags[type][index] = 0; +		_allocatedSize -= ((ResHeader*)ptr)->size; +		free(ptr);  	}  } -void Scumm::unkResourceProc() { -	int i; -	for (i=1; i<16; i++) { -	} -	/* TODO: not implemented */ -	warning("unkResourceProc: not implemented"); -} -  byte *findResource(uint32 tag, byte *searchin, int index) {  	uint32 maxsize,curpos,totalsize,size; @@ -687,11 +690,97 @@ byte *findResource(uint32 tag, byte *searchin, int index) {  void Scumm::lock(int type, int i) {  	validateResource("Locking", type, i);  	res.flags[type][i] |= 0x80; + +	debug(9, "locking %d,%d", type, i);  }  void Scumm::unlock(int type, int i) {  	validateResource("Unlocking", type, i); -	res.flags[type][i] &= ~0x7F; +	res.flags[type][i] &= ~0x80; + +	debug(9, "unlocking %d,%d", type, i); +} + +bool Scumm::isResourceInUse(int type, int i) { +	validateResource("isResourceInUse", type, i); +	switch(type) { +	case rtRoom: +		return _roomResource == (byte)i; +	case rtScript: +		return isScriptInUse(i); +	case rtCostume: +		return isCostumeInUse(i); +	case rtSound: +		return isSoundRunning(i)!=0; +	default: +		return false; +	} +} + +void Scumm::increaseResourceCounter() { +	int i,j; +	byte counter; + +	for (i=1; i<=16; i++) { +		for(j=res.num[i]; --j>=0;) { +			counter = res.flags[i][j] & 0x7F; +			if (counter && counter < 0x7F) { +				setResourceCounter(i, j, counter+1); +			} +		} +	} +} + +#define EXPIRE_FREQ 40 + +void Scumm::expireResources(uint32 size) { +	int i,j; +	byte flag; +	byte best_counter; +	int best_type, best_res; + +	if (_expire_counter != 0xFF) { +		_expire_counter = 0xFF; +		increaseResourceCounter(); +	} + +	if (size + _allocatedSize < _maxHeapThreshold) +		return; + +	do { +		best_type = 0; +		best_counter = 2; + +		for (i=1; i<=16; i++) +			if (res.mode[i]) { +				for(j=res.num[i]; --j>=0;) { +					flag = res.flags[i][j]; +					if (!(flag&0x80) && flag >= best_counter && !isResourceInUse(i,j)) { +						best_counter = flag; +						best_type = i; +						best_res = j; +					} +				} +			} + +		if (!best_type) +			break; +		nukeResource(best_type, best_res); +	} while (size + _allocatedSize > _minHeapThreshold); +} + +void Scumm::freeResources() { +	int i,j; +	for (i=1; i<=16; i++) { +		for(j=res.num[i]; --j>=0;) { +			if (isResourceLoaded(i,j)) +				nukeResource(i,j); +		} +		free(res.address[i]); +		free(res.flags[i]); +		free(res.roomno[i]); +		free(res.roomoffs[i]); +	}  }  void Scumm::loadPtrToResource(int type, int resindex, byte *source) { @@ -717,6 +806,15 @@ void Scumm::loadPtrToResource(int type, int resindex, byte *source) {  	}  } +bool Scumm::isResourceLoaded(int type, int index) { +	validateResource("isLoaded", type, index); +	return res.address[type][index] != NULL; +} + +void Scumm::resourceStats() { +	printf("Total allocated size=%d\n", _allocatedSize); +} +  void Scumm::heapClear(int mode) {  	/* TODO: implement this */  	warning("heapClear: not implemented"); @@ -727,11 +825,10 @@ void Scumm::unkHeapProc2(int a, int b) {  	warning("unkHeapProc2: not implemented");  }  -void Scumm::unkResProc(int a, int b) { -	warning("unkResProc:not implemented"); +void Scumm::loadFlObject(int a, int b) { +	debug(9, "loadFlObject(%d,%d):not implemented", a, b);  } -  void Scumm::readMAXS() {  	_numVariables = fileReadWordLE();  	fileReadWordLE(); diff --git a/saveload.cpp b/saveload.cpp index 2a8af2d5d2..fdd4b1b32c 100644 --- a/saveload.cpp +++ b/saveload.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.7  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.6  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -55,6 +59,7 @@ struct SaveGameHeader {  bool Scumm::saveState(const char *filename) {  	FILE *out = fopen(filename,"wb");  	SaveGameHeader hdr; +	Serializer ser;  	if (out==NULL)  		return false; @@ -65,7 +70,10 @@ bool Scumm::saveState(const char *filename) {  	fwrite(&hdr, sizeof(hdr), 1, out); -	saveOrLoad(out,true); +	ser._saveLoadStream = out; +	ser._saveOrLoad = true; +	saveOrLoad(&ser); +  	fclose(out);  	debug(1,"State saved as '%s'", filename);  	return true; @@ -75,6 +83,7 @@ bool Scumm::loadState(const char *filename) {  	FILE *out = fopen(filename,"rb");  	int i,j;  	SaveGameHeader hdr; +	Serializer ser;  	int sb,sh;  	if (out==NULL) @@ -106,7 +115,9 @@ bool Scumm::loadState(const char *filename) {  	initScummVars(); -	saveOrLoad(out,false); +	ser._saveLoadStream = out; +	ser._saveOrLoad = false; +	saveOrLoad(&ser);  	fclose(out);  	sb = _screenB; @@ -137,12 +148,11 @@ bool Scumm::loadState(const char *filename) {  #define OFFS(type,item) ((int)(&((type*)0)->item))  #define SIZE(type,item) sizeof(((type*)0)->item) -  #define MKLINE(type,item,saveas) {OFFS(type,item),saveas,SIZE(type,item)}  #define MKARRAY(type,item,saveas,num) {OFFS(type,item),128|saveas,SIZE(type,item)}, {num,0,0}  #define MKEND() {0xFFFF,0xFF,0xFF} -void Scumm::saveOrLoad(FILE *inout, bool mode) { +void Scumm::saveOrLoad(Serializer *s) {  	const SaveLoadEntry objectEntries[] = {  		MKLINE(ObjectData,offs_obim_to_room,sleUint32),  		MKLINE(ObjectData,offs_obcd_to_room,sleUint32), @@ -290,6 +300,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {  		MKLINE(Scumm,_charsetColor,sleByte),  		MKLINE(Scumm,charset._bufPos,sleByte),  		MKLINE(Scumm,_haveMsg,sleByte), +		MKLINE(Scumm,_useTalkAnims,sleByte),  		MKLINE(Scumm,_talkDelay,sleInt16),  		MKLINE(Scumm,_defaultTalkDelay,sleInt16), @@ -380,7 +391,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {  		MKLINE(StringTab,t_ypos,sleInt16),  		MKLINE(StringTab,t_center,sleInt16),  		MKLINE(StringTab,t_overhead,sleInt16), -		MKLINE(StringTab,t_new3,sleInt16), +		MKLINE(StringTab,t_no_talk_anim,sleInt16),  		MKLINE(StringTab,t_right,sleInt16),  		MKLINE(StringTab,t_color,sleInt16),  		MKLINE(StringTab,t_charset,sleInt16), @@ -390,7 +401,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {  		MKLINE(StringTab,ypos2,sleInt16),  		MKLINE(StringTab,center,sleInt16),  		MKLINE(StringTab,overhead,sleInt16), -		MKLINE(StringTab,new_3,sleInt16), +		MKLINE(StringTab,no_talk_anim,sleInt16),  		MKLINE(StringTab,right,sleInt16),  		MKLINE(StringTab,mask_top,sleInt16),  		MKLINE(StringTab,mask_bottom,sleInt16), @@ -405,43 +416,60 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) {  		MKLINE(ColorCycle,flags,sleUint16),  		MKLINE(ColorCycle,start,sleByte),  		MKLINE(ColorCycle,end,sleByte), +		MKEND()  	};  	int i,j; - -	_saveLoadStream = inout; -	_saveOrLoad = mode; - -	saveLoadEntries(this,mainEntries); -	for (i=1; i<13; i++) -		saveLoadEntries(&actor[i],actorEntries); -	for (i=0; i<NUM_SCRIPT_SLOT; i++) -		saveLoadEntries(&vm.slot[i],scriptSlotEntries); -	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=0; i<16; i++) -		saveLoadEntries(&_colorCycle,colorCycleEntries); - -	for (i=1; i<16; i++) +	 +	s->saveLoadEntries(this,mainEntries); + +	s->saveLoadArrayOf(actor+1, 12, sizeof(actor[0]), actorEntries); +	s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries); +	s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries); +	s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries); +	s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries); +	s->saveLoadArrayOf(sentence, 6, sizeof(sentence[0]), sentenceTabEntries); +	s->saveLoadArrayOf(string, 6, sizeof(string[0]), stringTabEntries); +	s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries); + +//	debug(1, "1) At position %d", ftell(inout)); +//	for (i=1; i<13; i++) +//		s->saveLoadEntries(&actor[i],actorEntries); +//	debug(1, "2) At position %d", ftell(inout)); +//	for (i=0; i<NUM_SCRIPT_SLOT; i++) +//		s->saveLoadEntries(&vm.slot[i],scriptSlotEntries); +//	debug(1, "3) At position %d", ftell(inout)); +//	for (i=0; i<_numLocalObjects; i++) +//		s->saveLoadEntries(&_objs[i],objectEntries); +//	debug(1, "4) At position %d", ftell(inout));	 +//	for (i=0; i<_numVerbs; i++) +//		s->saveLoadEntries(&_verbs[i],verbEntries); +//	debug(1, "5) At position %d", ftell(inout));	 +//	for (i=0; i<16; i++) +//		s->saveLoadEntries(&vm.nest[i],nestedScriptEntries); +//	debug(1, "6) At position %d", ftell(inout));	 +//	for (i=0; i<6; i++) +//		s->saveLoadEntries(&sentence[i],sentenceTabEntries); +//	debug(1, "7) At position %d", ftell(inout));	 +//	for (i=0; i<6; i++) +//		s->saveLoadEntries(&string[i],stringTabEntries); +//	debug(1, "8) At position %d", ftell(inout));	 +//	for (i=0; i<16; i++) +//		s->saveLoadEntries(&_colorCycle[i],colorCycleEntries); +//	debug(1, "9) At position %d", ftell(inout)); + +	for (i=1; i<=16; i++)  		if (res.mode[i]==0)  			for(j=1; j<res.num[i]; j++) -				saveLoadResource(i,j); +				saveLoadResource(s,i,j); -	saveLoadArrayOf(_objectFlagTable, _numGlobalObjects, sizeof(_objectFlagTable[0]), sleByte); -	saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32); -	saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16); -	saveLoadArrayOf(_bitVars, _numBitVariables>>3, 1, sleByte); +	s->saveLoadArrayOf(_objectFlagTable, _numGlobalObjects, sizeof(_objectFlagTable[0]), sleByte); +	s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32); +	s->saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16); +	s->saveLoadArrayOf(_bitVars, _numBitVariables>>3, 1, sleByte);  } -void Scumm::saveLoadResource(int type, int index) { +void Scumm::saveLoadResource(Serializer *ser, int type, int index) {  	byte *ptr;  	uint32 size,sizele; @@ -449,76 +477,82 @@ void Scumm::saveLoadResource(int type, int index) {  	if (type==13 || type==12 || type==10 || res.mode[type])  		return; -	if (_saveOrLoad) { +	if (ser->isSaving()) {  		ptr = res.address[type][index];  		if (ptr==NULL) { -			saveUint32(0); +			ser->saveUint32(0);  			return;  		}  		size = ((ResHeader*)ptr)->size; -		 -		saveUint32(size); -		saveLoadBytes(ptr+sizeof(ResHeader),size); + +		ser->saveUint32(size); +		ser->saveLoadBytes(ptr+sizeof(ResHeader),size);  		if (type==5) { -			saveWord(_inventory[index]); +			ser->saveWord(_inventory[index]);  		}  	} else { -		size = loadUint32(); +		size = ser->loadUint32();  		if (size) {  			createResource(type, index, size); -			saveLoadBytes(getResourceAddress(type, index), size); +			ser->saveLoadBytes(getResourceAddress(type, index), size);  			if (type==5) { -				_inventory[index] = loadWord(); +				_inventory[index] = ser->loadWord();  			}  		}  	}  } -void Scumm::saveLoadBytes(void *b, int len) { +void Serializer::saveLoadBytes(void *b, int len) {  	if (_saveOrLoad)  		fwrite(b, 1, len, _saveLoadStream);  	else  		fread(b, 1, len, _saveLoadStream);  } -void Scumm::saveUint32(uint32 d) { +void Serializer::saveUint32(uint32 d) {  	uint32 e = FROM_LE_32(d);  	saveLoadBytes(&e,4);  } -void Scumm::saveWord(uint16 d) { +void Serializer::saveWord(uint16 d) {  	uint16 e = FROM_LE_16(d);  	saveLoadBytes(&e,2);  } -void Scumm::saveByte(byte b) { +void Serializer::saveByte(byte b) {  	saveLoadBytes(&b,1);  } -uint32 Scumm::loadUint32() { +uint32 Serializer::loadUint32() {  	uint32 e;  	saveLoadBytes(&e,4);  	return FROM_LE_32(e);  } -uint16 Scumm::loadWord() { +uint16 Serializer::loadWord() {  	uint16 e;  	saveLoadBytes(&e,2);  	return FROM_LE_16(e);  } -byte Scumm::loadByte() { +byte Serializer::loadByte() {  	byte e;  	saveLoadBytes(&e,1);  	return e;  } -void Scumm::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) { +void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) {  	byte *at = (byte*)b;  	uint32 data; +	/* speed up byte arrays */ +	if (datasize==1 && filetype==sleByte) { +		saveLoadBytes(b, len); +		return; +	} +  	while (--len>=0) {  		if (_saveOrLoad) {  			/* saving */ @@ -570,11 +604,20 @@ void Scumm::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) {  	}  } +void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle) { +	byte *data = (byte*)b; +	while (--num) { +		saveLoadEntries(data, sle);		 +		data += datasize; +	} +} + -void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) { +void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {  	int replen;  	byte type;  	byte *at; +  	int size;  	int value; @@ -582,14 +625,25 @@ void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) {  		at = (byte*)d + sle->offs;  		size = sle->size;  		type = sle->type; -		replen = 1; -		if (type&128) { +		 +		if (size==0xFF) { +			if (_saveOrLoad) { +				/* save reference */ +				saveWord((*_save_ref)(_ref_me, type, *((void**)at))); +			} else { +				/* load reference */ +				*((void**)at) = (*_load_ref)(_ref_me, type, loadWord()); +			} +		} else { +			replen = 1; +			if (type&128) { +				sle++; +				replen = sle->offs; +				type&=~128; +			} +			saveLoadArrayOf(at, replen, size, type);  			sle++; -			replen = sle->offs; -			type&=~128;  		} -		sle++; -		saveLoadArrayOf(at, replen, size, type);  	}  } diff --git a/script.cpp b/script.cpp index b6c036be79..654d2570a1 100644 --- a/script.cpp +++ b/script.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.6  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.5  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -61,7 +65,7 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {  		stopScriptNr(script);  	if (script < _numGlobalScripts) { -		scriptPtr = getResourceAddress(2, script); +		scriptPtr = getResourceAddress(rtScript, script);  		scriptOffs = 8;  		scriptType = 2;  	} else { @@ -194,7 +198,6 @@ void Scumm::runScriptNested(int script) {  		slot = &vm.slot[_currentScript];  		nest->number = slot->number;  		nest->type = slot->type; -		/* scumm is buggy here */  		nest->slot = _currentScript;  	} @@ -242,24 +245,24 @@ void Scumm::getScriptBaseAddress() {  	switch(ss->type) {  	case 0: /* inventory script **/  		index = getObjectIndex(ss->number); -		_scriptOrgPointer = getResourceAddress(5, index); +		_scriptOrgPointer = getResourceAddress(rtInventory, index);  		_lastCodePtr = &_baseInventoryItems[index];  		break;  	case 3:  	case 1: /* room script */ -		_scriptOrgPointer = getResourceAddress(1, _roomResource); +		_scriptOrgPointer = getResourceAddress(rtRoom, _roomResource);  		_lastCodePtr = &_baseRooms[_roomResource];  		break;  	case 2: /* global script */ -		_scriptOrgPointer = getResourceAddress(2, ss->number); +		_scriptOrgPointer = getResourceAddress(rtScript, ss->number);  		_lastCodePtr = &_baseScripts[ss->number];  		break;  	case 4: /* flobject script */  		index = getObjectIndex(ss->number); -		_scriptOrgPointer = getResourceAddress(13,_objs[index].fl_object_index); +		_scriptOrgPointer = getResourceAddress(rtFlObject,_objs[index].fl_object_index);  		_lastCodePtr = &_baseFLObject[ss->number];  		break;  	default: @@ -443,7 +446,7 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) {  	updateDirtyRect(vs->number, x, x2, y-top, y2-top, 0); -	backbuff = getResourceAddress(0xA, vs->number+1) + vs->xstart	+ (y-top)*320 + x; +	backbuff = getResourceAddress(rtBuffer, vs->number+1) + vs->xstart + (y-top)*320 + x;  	count = y2 - y;  	while (count) { @@ -475,7 +478,7 @@ void Scumm::stopObjectCode() {  	_currentScript = 0xFF;  } -bool Scumm::isScriptLoaded(int script) { +bool Scumm::isScriptInUse(int script) {  	ScriptSlot *ss;  	int i; @@ -602,11 +605,23 @@ void Scumm::killScriptsAndResources() {  		}  	} +	/* Nuke FL objects */  	i = 0;  	do {  		if (_objs[i].fl_object_index)  			nukeResource(0xD, _objs[i].fl_object_index);  	} while (++i <= _numObjectsInRoom); + +	/* Nuke local object names */ +	if (_newNames) { +		for (i=0; i<50; i++) { +			int j = _newNames[i]; +			if (j && (getOwner(j)&0xF) == 0) { +				_newNames[i] = 0; +				nukeResource(rtObjectName, i); +			} +		} +	}  }  void Scumm::checkAndRunVar33() { @@ -614,7 +629,7 @@ void Scumm::checkAndRunVar33() {  	ScriptSlot *ss;  	memset(_localParamList, 0, sizeof(_localParamList)); -	if (isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) { +	if (isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) {  		ss = vm.slot;  		for (i=0; i<NUM_SCRIPT_SLOT; i++,ss++)  			if (ss->number==_vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0) @@ -910,7 +925,7 @@ int Scumm::defineArray(int array, int type, int dim2, int dim1) {  	size *= dim1+1;  	size >>= 3; -	ah = (ArrayHeader*)createResource(7, id, size+sizeof(ArrayHeader)); +	ah = (ArrayHeader*)createResource(rtString, id, size+sizeof(ArrayHeader));  	ah->type = type;  	ah->dim1_size = dim1+1; @@ -925,7 +940,7 @@ void Scumm::nukeArray(int a) {  	data = readVar(a);  	if (data) -		nukeResource(7, data); +		nukeResource(rtString, data);  	_arrays[data] = 0;  	writeVar(a, 0); @@ -948,7 +963,7 @@ void Scumm::arrayop_1(int a, byte *ptr) {  	int len = getStringLen(ptr);  	r = defineArray(a, 4, 0, len); -	ah = (ArrayHeader*)getResourceAddress(7,r); +	ah = (ArrayHeader*)getResourceAddress(rtString,r);  	copyString(ah->data,ptr,len);  } diff --git a/script_v1.cpp b/script_v1.cpp index 0c1a3522cb..481a10c10f 100644 --- a/script_v1.cpp +++ b/script_v1.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.6  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.5  2001/10/29 22:09:20  strigeus   * script invoked loading&saving in compatible mode   * @@ -1046,7 +1050,7 @@ void Scumm::o5_isSoundRunning() {  	getResultPos();  	snd = getVarOrDirectByte(0x80);  	if (snd) -		snd = unkSoundProc23(snd); +		snd = isSoundRunning(snd);  	setResult(snd);  } @@ -1071,7 +1075,6 @@ void Scumm::o5_lights() {  void Scumm::o5_loadRoom() {  	int room = getVarOrDirectByte(0x80); -	debug(1,"Loading room %d", room);  	startScene(room, 0, 0);  	_fullRedraw = 1;  } @@ -1259,60 +1262,60 @@ void Scumm::o5_resourceRoutines() {  		res = getVarOrDirectByte(0x80);  	switch(_opcode&0x1F) {  	case 1: /* load script */ -		ensureResourceLoaded(2, res); +		ensureResourceLoaded(rtScript, res);  		break;  	case 2: /* load sound */ -		ensureResourceLoaded(4, res); +		ensureResourceLoaded(rtSound, res);  		break;  	case 3: /* load costume */ -		ensureResourceLoaded(3, res); +		ensureResourceLoaded(rtCostume, res);  		break;  	case 4: /* load room */ -		ensureResourceLoaded(1, res); +		ensureResourceLoaded(rtRoom, res);  		break;  	case 5: /* nuke script */ -		setResourceFlags(2, res, 0x7F); +		setResourceCounter(rtScript, res, 0x7F);  		break;  	case 6: /* nuke sound */ -		setResourceFlags(4, res, 0x7F); +		setResourceCounter(rtSound, res, 0x7F);  		break;  	case 7: /* nuke costume */ -		setResourceFlags(3, res, 0x7F); +		setResourceCounter(rtCostume, res, 0x7F);  		break;  	case 8: /* nuke room */ -		setResourceFlags(1, res, 0x7F); +		setResourceCounter(rtRoom, res, 0x7F);  		break;  	case 9:  /* lock script */  		if (res >= _numGlobalScripts)  			break; -		lock(2,res); +		lock(rtScript,res);  		break;  	case 10:/* lock sound */ -		lock(4,res); +		lock(rtSound,res);  		break;  	case 11:/* lock costume */ -		lock(3,res); +		lock(rtCostume,res);  		break;  	case 12:/* lock room */  		if (res > 0x7F)  			res = _resourceMapper[res&0x7F]; -		lock(1,res); +		lock(rtRoom,res);  		break;  	case 13:/* unlock script */  		if (res >= _numGlobalScripts)  			break; -		unlock(2,res); +		unlock(rtScript,res);  		break;  	case 14:/* unlock sound */ -		unlock(4,res); +		unlock(rtSound,res);  		break;  	case 15:/* unlock costume */ -		unlock(3,res); +		unlock(rtCostume,res);  		break;  	case 16:/* unlock room */  		if (res > 0x7F)  			res = _resourceMapper[res&0x7F]; -		unlock(1,res); +		unlock(rtRoom,res);  		break;  	case 17:/* clear heap */  		heapClear(0); @@ -1324,8 +1327,8 @@ void Scumm::o5_resourceRoutines() {  	case 19:/* nuke charset */  		nukeCharset(res);  		break; -	case 20:/* ? */ -		unkResProc(getVarOrDirectWord(0x40), res); +	case 20:/* load fl object */ +		loadFlObject(getVarOrDirectWord(0x40), res);  		break;  	}  } @@ -1573,7 +1576,6 @@ void Scumm::o5_soundKludge() {  	getWordVararg(items);  	soundKludge(items); -  }  void Scumm::o5_startMusic() { @@ -1613,8 +1615,7 @@ void Scumm::o5_startSound() {  }  void Scumm::o5_stopMusic() { -	/* TODO: not implemented */ -	warning("o5_stopMusic: not implemented"); +	stopAllSounds();  }  void Scumm::o5_stopObjectCode() { @@ -1636,7 +1637,7 @@ void Scumm::o5_stopScript() {  }  void Scumm::o5_stopSound() { -	unkSoundProc1(getVarOrDirectByte(0x80)); +	stopSound(getVarOrDirectByte(0x80));  }  void Scumm::o5_stringOps() { @@ -1651,9 +1652,9 @@ void Scumm::o5_stringOps() {  	case 2: /* copystring */  		a = getVarOrDirectByte(0x80);  		b = getVarOrDirectByte(0x40); -		nukeResource(7, a); -		ptr = getResourceAddress(7, b); -		if (ptr) loadPtrToResource(7, a, ptr); +		nukeResource(rtString, a); +		ptr = getResourceAddress(rtString, b); +		if (ptr) loadPtrToResource(rtString, a, ptr);  		break;  	case 3: /* set string char */  		a = getVarOrDirectByte(0x80); @@ -1668,7 +1669,7 @@ void Scumm::o5_stringOps() {  		getResultPos();  		a = getVarOrDirectByte(0x80);  		b = getVarOrDirectByte(0x40); -		ptr = getResourceAddress(7, a); +		ptr = getResourceAddress(rtString, a);  		if (ptr==NULL) error("String %d does not exist", a);  		setResult(ptr[b]);  		break; @@ -1676,9 +1677,9 @@ void Scumm::o5_stringOps() {  	case 5: /* create empty string */  		a = getVarOrDirectByte(0x80);  		b = getVarOrDirectByte(0x40); -		nukeResource(7, a); +		nukeResource(rtString, a);  		if (b) { -			ptr = createResource(7, a, b); +			ptr = createResource(rtString, a, b);  			if (ptr) {  				for(i=0; i<b; i++)  					ptr[i] = 0; @@ -1719,9 +1720,9 @@ void Scumm::o5_verbOps() {  			}  			break;  		case 2: /* load from code */ -			loadPtrToResource(8, slot, NULL); +			loadPtrToResource(rtVerb, slot, NULL);  			if (slot==0) -				nukeResource(8, slot); +				nukeResource(rtVerb, slot);  			vs->type = 0;  			vs->imgindex = 0;  			break; @@ -1781,14 +1782,14 @@ void Scumm::o5_verbOps() {  			vs->center = 1;  			break;  		case 20: /* set to string */ -			ptr = getResourceAddress(7, getVarOrDirectWord(0x80)); +			ptr = getResourceAddress(rtString, getVarOrDirectWord(0x80));  			if (!ptr) -				nukeResource(8, slot); +				nukeResource(rtVerb, slot);  			else { -				loadPtrToResource(8, slot, ptr); +				loadPtrToResource(rtVerb, slot, ptr);  			}  			if (slot==0) -				nukeResource(8, slot); +				nukeResource(rtVerb, slot);  			vs->type = 0;  			vs->imgindex = 0;  			break; @@ -1832,11 +1833,11 @@ void Scumm::o5_wait() {  	case 4: /* wait for sentence */  		if (_sentenceIndex!=0xFF) {  			if (sentence[_sentenceIndex].unk && -				!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) +				!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]) )  				return;  			break;  		} -		if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) +		if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))  			return;  		break;  	default: diff --git a/script_v2.cpp b/script_v2.cpp index f1327b4ab7..fc49844cc2 100644 --- a/script_v2.cpp +++ b/script_v2.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.5  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.4  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -364,7 +368,7 @@ void Scumm::setupOpcodes2() {  }  int Scumm::readArray(int array, int index, int base) { -	ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); +	ArrayHeader *ah = (ArrayHeader*)getResourceAddress(rtString, readVar(array));  	assert(ah); @@ -380,7 +384,7 @@ int Scumm::readArray(int array, int index, int base) {  }  void Scumm::writeArray(int array, int index, int base, int value) { -	ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); +	ArrayHeader *ah = (ArrayHeader*)getResourceAddress(rtString, readVar(array));  	assert(ah);  	base += index*ah->dim1_size; @@ -676,7 +680,7 @@ void Scumm::o6_cutScene() {  }  void Scumm::o6_stopMusic() { -	warning("o6_stopMusic: not implemented"); +	stopAllSounds();  }  void Scumm::o6_freezeUnfreeze() { @@ -818,7 +822,7 @@ void Scumm::o6_startSound() {  }  void Scumm::o6_stopSound() { -	unkSoundProc1(pop()); +	stopSound(pop());  }  void Scumm::o6_startMusic() { @@ -843,7 +847,6 @@ void Scumm::o6_setCameraAt() {  void Scumm::o6_loadRoom() {  	int room = pop(); -	debug(1,"Loading room %d", room);  	startScene(room, 0, 0);  	_fullRedraw = 1;  } @@ -946,6 +949,12 @@ void Scumm::o6_faceActor() {  void Scumm::o6_animateActor() {  	int anim = pop();  	int act = pop(); + +	if (_gameId==GID_TENTACLE && act==593) { +		warning("o6_animateActor(%d,%d): fixed tentacle bug", act, anim); +		return; +	} +  	animateActor(act, anim);  } @@ -1102,7 +1111,7 @@ void Scumm::o6_setObjectName() {  	for (i=1; i<50; i++) {  		if (_newNames[i] == obj) { -			nukeResource(16, i); +			nukeResource(rtObjectName, i);  			_newNames[i] = 0;  			break;  		} @@ -1110,7 +1119,7 @@ void Scumm::o6_setObjectName() {  	for (i=1; i<50; i++) {  		if (_newNames[i] == 0) { -			loadPtrToResource(16, i, NULL); +			loadPtrToResource(rtObjectName, i, NULL);  			_newNames[i] = obj;  			runHook(0);  			return; @@ -1123,7 +1132,7 @@ void Scumm::o6_setObjectName() {  void Scumm::o6_isSoundRunning() {  	int snd = pop();  	if (snd) -		snd = unkSoundProc23(snd); +		snd = isSoundRunning(snd);  	push(snd);  } @@ -1149,75 +1158,76 @@ void Scumm::o6_resourceRoutines() {  	switch(fetchScriptByte()) {  	case 100: /* load script */  		res = pop(); -		ensureResourceLoaded(2, res); +		ensureResourceLoaded(rtScript, res);  		break;  	case 101: /* load sound */  		res = pop(); -		ensureResourceLoaded(4, res); +		ensureResourceLoaded(rtSound, res);  		break;  	case 102: /* load costume */  		res = pop(); -		ensureResourceLoaded(3, res); +		ensureResourceLoaded(rtCostume, res);  		break;  	case 103: /* load room */  		res = pop(); -		ensureResourceLoaded(1, res); +		ensureResourceLoaded(rtRoom, res);  		break;  	case 104: /* nuke script */  		res = pop(); -		setResourceFlags(2, res, 0x7F); +		setResourceCounter(rtScript, res, 0x7F); +		debug(5, "nuke script %d", res);  		break;  	case 105: /* nuke sound */  		res = pop(); -		setResourceFlags(4, res, 0x7F); +		setResourceCounter(rtSound, res, 0x7F);  		break;  	case 106: /* nuke costume */  		res = pop(); -		setResourceFlags(3, res, 0x7F); +		setResourceCounter(rtCostume, res, 0x7F);  		break;  	case 107: /* nuke room */  		res = pop(); -		setResourceFlags(1, res, 0x7F); +		setResourceCounter(rtRoom, res, 0x7F);  		break;  	case 108:  /* lock script */  		res = pop();  		if (res >= _numGlobalScripts)  			break; -		lock(2,res); +		lock(rtScript,res);  		break;  	case 109:/* lock sound */  		res = pop(); -		lock(4,res); +		lock(rtSound,res);  		break;  	case 110:/* lock costume */  		res = pop(); -		lock(3,res); +		lock(rtCostume,res);  		break;  	case 111:/* lock room */  		res = pop();  		if (res > 0x7F)  			res = _resourceMapper[res&0x7F]; -		lock(1,res); +		lock(rtRoom,res);  		break;  	case 112:/* unlock script */  		res = pop();  		if (res >= _numGlobalScripts)  			break; -		unlock(2,res); +		unlock(rtScript,res);  		break;  	case 113:/* unlock sound */  		res = pop(); -		unlock(4,res); +		unlock(rtSound,res);  		break;  	case 114:/* unlock costume */  		res = pop(); -		unlock(3,res); +		unlock(rtCostume,res);  		break;  	case 115:/* unlock room */  		res = pop();  		if (res > 0x7F)  			res = _resourceMapper[res&0x7F]; -		unlock(1,res); +		unlock(rtRoom,res);  		break;  	case 116:/* clear heap */  		/* this is actually a scumm message */ @@ -1232,9 +1242,9 @@ void Scumm::o6_resourceRoutines() {  		res = pop();  		nukeCharset(res);  		break; -	case 119:/* ? */ +	case 119:/* load fl object */  		res = pop(); -		unkResProc(pop(), res); +		loadFlObject(pop(), res);  		break;  	default:  		error("o6_resourceRoutines: default case"); @@ -1751,11 +1761,11 @@ void Scumm::o6_wait() {  	case 171:  		if (_sentenceIndex!=0xFF) {  			if (sentence[_sentenceIndex].unk && -				!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) +				!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]) )  				return;  			break;  		} -		if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) +		if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))  			return;  		break;  	default: @@ -2090,13 +2100,13 @@ void Scumm::decodeParseString2(int m, int n) {  		break;  	case 72:  		string[m].overhead = 1; -		string[m].new_3 = 0; +		string[m].no_talk_anim = 0;  		break;  	case 73:  		error("decodeParseString2: case 73");  		break;  	case 74: -		string[m].new_3 = 1; +		string[m].no_talk_anim = 1;  		break;  	case 75:  		_messagePtr = _scriptPointer; @@ -2119,7 +2129,7 @@ void Scumm::decodeParseString2(int m, int n) {  		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_no_talk_anim = string[m].no_talk_anim;  		string[m].t_right = string[m].right;  		string[m].t_color = string[m].color;  		string[m].t_charset = string[m].charset; @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.16  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.15  2001/10/29 23:07:24  strigeus   * better MI1 compatibility   * @@ -251,15 +255,11 @@ struct PathVertex {  	PathNode *right;  }; -struct SaveLoadEntry { -	uint16 offs; -	uint8 type; -	uint8 size; -};  enum {  	sleByte = 1,  	sleUint8 = 1, +	sleInt8 = 1,  	sleInt16 = 2,  	sleUint16 = 3,  	sleInt32 = 4, @@ -342,28 +342,48 @@ enum ScummVars {  }; -#define _maxRooms res.num[1] -#define _maxScripts res.num[2] -#define _maxCostumes res.num[3] -#define _maxInventoryItems res.num[5] -#define _maxCharsets res.num[6] -#define _maxStrings res.num[7] -#define _maxVerbs res.num[8] -#define _maxActorNames res.num[9] -#define _maxBuffer res.num[10] -#define _maxScaleTable res.num[11] -#define _maxTemp res.num[12] -#define _maxFLObject res.num[13] -#define _maxMatrixes res.num[14] -#define _maxBoxes res.num[15] - -#define _baseRooms res.address[1] -#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] +enum ResTypes { +	rtRoom = 1, +	rtScript = 2, +	rtCostume = 3, +	rtSound = 4, +	rtInventory = 5, +	rtCharset = 6, +	rtString = 7, +	rtVerb = 8, +	rtActorName = 9, +	rtBuffer = 10, +	rtScaleTable = 11, +	rtTemp = 12, +	rtFlObject = 13, +	rtMatrix = 14, +	rtBox = 15, +	rtObjectName = 16, + +}; + +#define _maxRooms res.num[rtRoom] +#define _maxScripts res.num[rtScript] +#define _maxCostumes res.num[rtCostume] +#define _maxInventoryItems res.num[rtInventory] +#define _maxCharsets res.num[rtCharset] +#define _maxStrings res.num[rtString] +#define _maxVerbs res.num[rtVerb] +#define _maxActorNames res.num[rtActorName] +#define _maxBuffer res.num[rtBuffer] +#define _maxScaleTable res.num[rtScaleTable] +#define _maxTemp res.num[rtTemp] +#define _maxFLObject res.num[rtFlObject] +#define _maxMatrixes res.num[rtMatrix] +#define _maxBoxes res.num[rtBox] + +#define _baseRooms res.address[rtRoom] +#define _baseScripts res.address[rtScript] +#define _baseInventoryItems res.address[rtInventory] +#define _baseFLObject res.address[rtFlObject] +#define _baseArrays res.address[rtString] + +#define _roomFileOffsets res.roomoffs[rtRoom]  struct CharsetRenderer {  	Scumm *_vm; @@ -459,8 +479,8 @@ struct CostumeRenderer {  	byte drawOneSlot(Actor *a, int slot);  	byte drawCostume(Actor *a); -	byte animateOneSlot(CostumeData *cd, int slot); -	byte animate(CostumeData *cd); +	byte animateOneSlot(Actor *a, int slot); +	byte animate(Actor *a);  };  struct Actor { @@ -520,11 +540,11 @@ struct SentenceTab {  struct StringTab {  	int16 t_xpos, t_ypos, t_center, t_overhead; -	int16 t_new3, t_right, t_color, t_charset; +	int16 t_no_talk_anim, t_right, t_color, t_charset;  	int16 xpos, ypos;  	int16 xpos2,ypos2;  	int16 center, overhead; -	int16 new_3, right; +	int16 no_talk_anim, right;  	int16 color,charset;  	int16 mask_top, mask_bottom, mask_right, mask_left;  }; @@ -549,7 +569,7 @@ struct Gdi {  	int _imgBufOffs[4];  	byte _disable_zbuffer; -	byte dseg_4E3B; +	bool _useOrDecompress;  	byte _numLinesToProcess;  	byte _tempNumLines;  	byte _currentX; @@ -614,7 +634,7 @@ enum GameId {  };  struct ScummDebugger; - +struct Serializer;  struct Scumm {  	const char *_gameText; @@ -629,6 +649,7 @@ struct Scumm {  	int _roomResource;  	byte _encbyte;  	void *_fileHandle; +	void *_sfxFile;  	char *_exe_name;  	byte _saveLoadFlag; @@ -637,12 +658,16 @@ struct Scumm {  	bool _dynamicRoomOffsets;  	byte _resFilePathId; + +	bool _useTalkAnims;  	char *_resFilePrefix;  	char *_resFilePath;  	int _keyPressed; +	void *_soundDriver; +  	uint16 *_inventory;  	byte *_arrays;  	VerbSlot *_verbs; @@ -685,6 +710,13 @@ struct Scumm {  	byte *_scriptPointer, *_scriptOrgPointer;  	byte *_scriptPointerStart;  	byte _opcode; +	 +	byte _expire_counter; + +	bool _noTalkAnims; + +	bool _mouthSyncMode; +	bool _endOfMouthSync;  	uint32 _randSeed1;  	uint32 _randSeed2; @@ -703,6 +735,9 @@ struct Scumm {  	bool _doEffect;  	bool _screenEffectFlag;  	bool _keepText; + +	uint32 _maxHeapThreshold; +	uint32 _minHeapThreshold;  	byte _bkColor;  	uint16 _lastXstart; @@ -714,8 +749,6 @@ struct Scumm {  	byte _charsetColor; -	uint32 _localScriptList[0x39]; -  	uint16 _debugMode;  	byte *_messagePtr; @@ -737,16 +770,18 @@ struct Scumm {  	uint16 _completeScreenRedraw; -	 -  	int8 _userPut;  	int8 _cursorState; +	byte _sfxMode; +  	uint16 _mouseButStat;  	byte _leftBtnPressed, _rightBtnPressed;  	int _numInMsgStack; +	uint32 _localScriptList[0x39]; +  	VirtScreen virtscr[4];  	uint32 _ENCD_offs, _EXCD_offs; @@ -754,6 +789,11 @@ struct Scumm {  	uint32 _IM00_offs;  	uint32 _PALS_offs; +	uint32 _allocatedSize; + +	uint32 _talk_sound_a, _talk_sound_b; +	byte _talk_sound_mode; +  	int _drawObjectQueNr;  	byte _drawObjectQue[0xC8]; @@ -841,6 +881,8 @@ struct Scumm {  	CostumeRenderer cost; +	uint16 _mouthSyncTimes[52]; +  	int16 _soundQuePos;  	int16 _soundQue[0x100]; @@ -858,6 +900,7 @@ struct Scumm {  	int _palDirtyMin, _palDirtyMax; +	uint _curSoundPos;  	ColorCycle _colorCycle[16]; @@ -881,6 +924,8 @@ struct Scumm {  	byte *_boxMatrixPtr4, *_boxMatrixPtr1, *_boxMatrixPtr3;  	int _boxPathVertexHeapIndex;  	int _boxMatrixItem; + +//	void _grabbedCursor[1024];  	OpcodeProc getOpcode(int i) { return _opcodes[i]; } @@ -909,8 +954,8 @@ struct Scumm {  	uint fileReadWordLE();  	uint fileReadWordBE(); -	byte *alloc(int size); -	void free(void *mem); +	static byte *alloc(int size); +	static void free(void *mem);  	void readResTypeList(int id, uint32 tag, const char *name);  	void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode); @@ -943,7 +988,7 @@ struct Scumm {  	int loadResource(int type, int i);  	int getResourceRoomNr(int type, int index);  	int readSoundResource(int type, int index); -	void setResourceFlags(int type, int index, byte flag); +	void setResourceCounter(int type, int index, byte flag);  	void validateResource(const char *str, int type, int index);  	void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra); @@ -1281,7 +1326,7 @@ struct Scumm {  	int getObjectOrActorXY(int object);  	void addSoundToQueue(int sound);  	void addSoundToQueue2(int sound); -	bool isScriptLoaded(int script); +	bool isScriptInUse(int script);  	int getActorXYPos(Actor *a);  	void getObjectXYPos(int object);  	AdjustBoxResult adjustXYToBeInBox(Actor *a, int x, int y); @@ -1289,7 +1334,7 @@ struct Scumm {  	int getWordVararg(int16 *ptr);  	int getObjActToObjActDist(int a, int b); -	void unkSoundProc22(); +	void processSoundQues();  	bool inBoxQuickReject(int box, int x, int y, int threshold);  	AdjustBoxResult getClosestPtOnBox(int box, int x, int y); @@ -1312,7 +1357,8 @@ struct Scumm {  	void runExitScript();  	void runEntryScript(); -	void unkResourceProc(); +	void increaseResourceCounter(); +	bool isResourceInUse(int type, int i);  	void initRoomSubBlocks();  	void loadRoomObjects(); @@ -1321,11 +1367,6 @@ struct Scumm {  	void initBGBuffers();  	void setDirtyColors(int min, int max); -#if 0 -	byte *findResource(uint32 tag, byte *searchin); -	byte *findResource2(uint32 tag, byte *searchin); -#endif -  	void setScaleItem(int slot, int a, int b, int c, int d);  	void cyclePalette(); @@ -1337,8 +1378,6 @@ struct Scumm {  	void redrawBGStrip(int start, int num);  	void drawObject(int obj, int arg); -//	void drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr); -	  	int hasCharsetMask(int x, int y, int x2, int y2);  	void restoreBG(int left, int top, int right, int bottom); @@ -1357,7 +1396,6 @@ struct Scumm {  	void decreaseScriptDelay(int amount);  	void processKbd(); -  	void redrawVerbs();  	void checkExecVerbs(); @@ -1414,7 +1452,7 @@ struct Scumm {  	void initCharset(int charset);  	void addObjectToDrawQue(int object);  	int getVerbEntrypoint(int obj, int entry); -	int unkSoundProc23(int a); +	int isSoundRunning(int a);  	void startWalkActor(Actor *a, int x, int y, int dir);  	void setBoxFlags(int box, int val);  	void setBoxScale(int box, int b); @@ -1428,7 +1466,7 @@ struct Scumm {  	void unlock(int type, int i);  	void heapClear(int mode);  	void unkHeapProc2(int a, int b); -	void unkResProc(int a, int b); +	void loadFlObject(int a, int b);  	void setPalColor(int index, int r, int g, int b);  	void darkenPalette(int a, int b, int c, int d, int e);  	void unkRoomFunc3(int a, int b, int c, int d, int e); @@ -1439,7 +1477,6 @@ struct Scumm {  	byte *getObjOrActorName(int obj);  	void clearOwnerOf(int obj);  	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();  	void unkMessage2(); @@ -1469,25 +1506,13 @@ struct Scumm {  	void dumpResource(char *tag, int index, byte *ptr); -	FILE *_saveLoadStream; -	bool _saveOrLoad;  	bool saveState(const char *filename);  	bool loadState(const char *filename); -	void saveOrLoad(FILE *inout, bool mode); -	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); +	void saveOrLoad(Serializer *s); -	void saveUint32(uint32 d); -	void saveWord(uint16 d); -	void saveByte(byte b); +	void saveLoadResource(Serializer *ser, int type, int index); +	bool isResourceLoaded(int type, int index); -	byte loadByte(); -	uint16 loadWord(); -	uint32 loadUint32();  	Actor *derefActor(int id) { return &actor[id]; }  	Actor *derefActorSafe(int id, const char *errmsg); @@ -1565,12 +1590,26 @@ struct Scumm {  	void unkMiscOp4(int a, int b, int c, int d);  	void unkMiscOp9();  	void startManiac(); -  	void readIndexFileV5(int i); -  	void grabCursor(byte *ptr, int width, int height); -  	byte *getPalettePtr(); +	void setupSound(); +	void stopAllSounds(); +	void stopSound(int sound); +	bool isSoundInQueue(int sound); +	void clearSoundQue(); +	void talkSound(uint32 a, uint32 b, int mode); +	void processSfxQueues(); +	void startTalkSound(uint32 a, uint32 b, int mode); +	bool isMouthSyncOff(uint pos); +	void startSfxSound(void *file); +	void *openSfxFile(); +	void resourceStats(); +	bool isCostumeInUse(int i); +	void expireResources(uint32 size); +	 +	void freeResources(); +	void destroy();  };  struct ScummDebugger { @@ -1595,6 +1634,44 @@ struct ScummDebugger {  	void printScripts();  }; +struct SaveLoadEntry { +	uint16 offs; +	uint8 type; +	uint8 size; +}; + +typedef int SerializerSaveReference(void *me, byte type, void *ref); +typedef void *SerializerLoadReference(void *me, byte type, int ref); + + +struct Serializer { +	FILE *_saveLoadStream; + +	union { +		SerializerSaveReference *_save_ref; +		SerializerLoadReference *_load_ref; +	}; +	void *_ref_me; + +	bool _saveOrLoad; + +	 +	void saveLoadBytes(void *b, int len); +	void saveLoadArrayOf(void *b, int len, int datasize, byte filetype); +	void saveLoadEntries(void *d, const SaveLoadEntry *sle); +	void saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle); + +	void saveUint32(uint32 d); +	void saveWord(uint16 d); +	void saveByte(byte b); + +	byte loadByte(); +	uint16 loadWord(); +	uint32 loadUint32(); + +	bool isSaving() { return _saveOrLoad; } +}; +  void waitForTimer(Scumm *s); @@ -1611,4 +1688,6 @@ void updateScreen(Scumm *s);  void drawMouse(Scumm *s, int x, int y, int color, byte *mask, bool visible);  void blit(byte *dst, byte *src, int w, int h); -byte *findResource(uint32 id, byte *searchin, int index);
\ No newline at end of file +byte *findResource(uint32 id, byte *searchin, int index); +void playSfxSound(void *sound, int size, int rate); +bool isSfxFinished();
\ No newline at end of file diff --git a/scummsys.h b/scummsys.h index b4a07906a5..b46ff58c4a 100644 --- a/scummsys.h +++ b/scummsys.h @@ -17,9 +17,9 @@   *   * Change Log:   * $Log$ - * Revision 1.6  2001/11/03 06:33:29  cmatsuoka - * Protecting VC++-specific pragmas with ifdef _MSC_VER to allow - * a clean Cygwin build. + * Revision 1.7  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott   *   * Revision 1.5  2001/10/23 19:51:50  strigeus   * recompile not needed when switching games @@ -43,11 +43,8 @@  #if defined(WIN32) -/* Pragmas are VC++-specific */ -#if defined(_MSC_VER)  #pragma warning (disable: 4244)  #pragma warning (disable: 4101) -#endif  #define scumm_stricmp stricmp diff --git a/scummvm.cpp b/scummvm.cpp index 8600d0f654..a09833c5a2 100644 --- a/scummvm.cpp +++ b/scummvm.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.15  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.14  2001/10/29 23:07:24  strigeus   * better MI1 compatibility   * @@ -212,7 +216,7 @@ void Scumm::scummInit() {  	_numInMsgStack = 0; -	createResource(12, 6, 500); +	createResource(rtTemp, 6, 500);  	initScummVars(); @@ -254,6 +258,9 @@ void Scumm::scummMain(int argc, char **argv) {  	_fileHandle = NULL;  	_debugMode = 1; + +	_maxHeapThreshold = 350000; +	_minHeapThreshold = 300000;  	parseCommandLine(argc, argv); @@ -285,6 +292,7 @@ void Scumm::scummMain(int argc, char **argv) {  		_vars[74] = 1225;  	} +	setupSound();  	runScript(1,0,0,&_bootParam);  	_scummTimer = 0; @@ -301,6 +309,10 @@ void Scumm::scummMain(int argc, char **argv) {  		if (_debugger)  			_debugger->on_frame(); +		if (!(++_expire_counter)) { +			increaseResourceCounter(); +		} +  		_vars[VAR_TIMER] = _scummTimer >> 2;  		do {  			waitForTimer(this); @@ -340,7 +352,7 @@ void Scumm::scummMain(int argc, char **argv) {  		if (_saveLoadFlag) {  			char buf[256]; -			sprintf(buf, "savegame.%d", _saveLoadSlot); +			sprintf(buf, "%s.%c%.2d", _exe_name, _saveLoadCompatible ? 'c': 's', _saveLoadSlot);  			if (_saveLoadFlag==1) {  				saveState(buf);  				if (_saveLoadCompatible) @@ -372,7 +384,7 @@ void Scumm::scummMain(int argc, char **argv) {  			gdi._unk4 = 0;  			CHARSET_1();  			unkVirtScreen2(); -			unkSoundProc22(); +			processSoundQues();  			camera._lastPos = camera._curPos;  			continue;  		} @@ -414,7 +426,7 @@ void Scumm::scummMain(int argc, char **argv) {  		if (_majorScummVersion==5)  			playActorSounds(); -		unkSoundProc22(); +		processSoundQues();  		camera._lastPos = camera._curPos;  	} while (1);  } @@ -506,6 +518,8 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {  	CHECK_HEAP +	debug(1,"Loading room %d", room); +  	clearMsgQueue();  	unkVirtScreen4(_switchRoomEffect2); @@ -543,7 +557,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {  	_roomResource = _currentRoom = 0xFF; -	unkResourceProc(); +	increaseResourceCounter();  	_currentRoom = room;  	_vars[VAR_ROOM] = room; @@ -619,13 +633,13 @@ void Scumm::initRoomSubBlocks() {  	_CLUT_offs = 0;  	_PALS_offs = 0; -	nukeResource(0xE, 1); -	nukeResource(0xE, 2); +	nukeResource(rtMatrix, 1); +	nukeResource(rtMatrix, 2);  	for (i=1; i<_maxScaleTable; i++) -		nukeResource(0xB, i); +		nukeResource(rtScaleTable, i); -	roomptr = getResourceAddress(1, _roomResource); +	roomptr = getResourceAddress(rtRoom, _roomResource);  	ptr = findResource(MKID('RMHD'), roomptr, 0);  	_scrWidthIn8Unit = READ_LE_UINT16(&((RoomHeader*)ptr)->width) >> 3; @@ -653,19 +667,19 @@ void Scumm::initRoomSubBlocks() {  	ptr = findResource(MKID('BOXD'), roomptr, 0);  	if (ptr) {  		int size = READ_BE_UINT32_UNALIGNED(ptr+4); -		createResource(14, 2, size); -		roomptr = getResourceAddress(1, _roomResource); +		createResource(rtMatrix, 2, size); +		roomptr = getResourceAddress(rtRoom, _roomResource);  		ptr = findResource(MKID('BOXD'), roomptr, 0); -		memcpy(getResourceAddress(0xE, 2), ptr, size); +		memcpy(getResourceAddress(rtMatrix, 2), ptr, size);  	}  	ptr = findResource(MKID('BOXM'), roomptr, 0);  	if (ptr) {  		int size = READ_BE_UINT32_UNALIGNED(ptr+4); -		createResource(14, 1, size); -		roomptr = getResourceAddress(1, _roomResource); +		createResource(rtMatrix, 1, size); +		roomptr = getResourceAddress(rtRoom, _roomResource);  		ptr = findResource(MKID('BOXM'), roomptr, 0); -		memcpy(getResourceAddress(0xE, 1), ptr, size); +		memcpy(getResourceAddress(rtMatrix, 1), ptr, size);  	}  	ptr = findResource(MKID('SCAL'), roomptr, 0); @@ -678,13 +692,13 @@ void Scumm::initRoomSubBlocks() {  			int d = READ_LE_UINT16(roomptr + offs + 14);  			if (a || b || c || d) {  				setScaleItem(i, b, a, d, c); -				roomptr = getResourceAddress(1, _roomResource); +				roomptr = getResourceAddress(rtRoom, _roomResource);  			}  		}  	}  	memset(_localScriptList, 0, (0x100 - _numGlobalScripts) * 4); -	roomptr = getResourceAddress(1, _roomResource); +	roomptr = getResourceAddress(rtRoom, _roomResource);  	for (i=0; ptr = findResource(MKID('LSCR'), roomptr, i++) ;) {  		_localScriptList[ptr[8] - _numGlobalScripts] = ptr - roomptr;  #ifdef DUMP_SCRIPTS @@ -730,7 +744,7 @@ void Scumm::setScaleItem(int slot, int a, int b, int c, int d) {  	byte *ptr;  	int cur,amounttoadd,i,tmp; -	ptr = createResource(11, slot, 200); +	ptr = createResource(rtScaleTable, slot, 200);  	if (a==c)  		return; @@ -908,7 +922,7 @@ void Scumm::setStringVars(int slot) {  	st->ypos = st->t_ypos;  	st->center = st->t_center;  	st->overhead = st->t_overhead; -	st->new_3 = st->t_new3; +	st->no_talk_anim = st->t_no_talk_anim;  	st->right = st->t_right;  	st->color = st->t_color;  	st->charset = st->t_charset; @@ -922,6 +936,20 @@ void Scumm::startManiac() {  	warning("stub startManiac()");  } +void Scumm::destroy() { +	freeResources(); + +	free(_objectFlagTable); +	free(_inventory); +	free(_arrays); +	free(_verbs); +	free(_objs); +	free(_vars); +	free(_bitVars); +	free(_newNames); +	free(_classData); +} +  extern Scumm scumm; diff --git a/scummvm.dsp b/scummvm.dsp index 505c01fbf2..5f67c0f6a1 100644 --- a/scummvm.dsp +++ b/scummvm.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sdl.lib /nologo /subsystem:console /machine:I386
 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib sdl.lib winmm.lib /nologo /subsystem:console /machine:I386
  !ELSEIF  "$(CFG)" == "scummvm - Win32 Debug"
 @@ -75,7 +75,7 @@ BSC32=bscmake.exe  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sdl.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib sdl.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
  !ENDIF 
 @@ -140,6 +140,10 @@ SOURCE=.\debug.cpp  # End Source File
  # Begin Source File
 +SOURCE=.\fmopl.cpp
 +# End Source File
 +# Begin Source File
 +
  SOURCE=.\gfx.cpp
  !IF  "$(CFG)" == "scummvm - Win32 Release"
 @@ -153,6 +157,10 @@ SOURCE=.\gfx.cpp  # End Source File
  # Begin Source File
 +SOURCE=.\midi2.cpp
 +# End Source File
 +# Begin Source File
 +
  SOURCE=.\object.cpp
  !IF  "$(CFG)" == "scummvm - Win32 Release"
 @@ -319,6 +327,10 @@ SOURCE=.\windows.cpp  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # Begin Source File
 +SOURCE=.\fmopl.h
 +# End Source File
 +# Begin Source File
 +
  SOURCE=.\scumm.h
  # End Source File
  # Begin Source File
 @@ -327,6 +339,10 @@ SOURCE=.\scummsys.h  # End Source File
  # Begin Source File
 +SOURCE=.\sound.h
 +# End Source File
 +# Begin Source File
 +
  SOURCE=.\StdAfx.h
  # End Source File
  # End Group
 @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.13  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.12  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -62,11 +66,19 @@  #include "stdafx.h"  #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#endif +  #define SCALEUP_2x2  Scumm scumm;  ScummDebugger debugger; +#if defined(USE_IMUSE) +SoundEngine sound; +#endif +  static SDL_Surface *screen;  void updatePalette(Scumm *s) { @@ -113,9 +125,16 @@ void waitForTimer(Scumm *s) {  				if (event.key.keysym.sym=='f' && event.key.keysym.mod&KMOD_CTRL) {  					s->_fastMode ^= 1;  				} +				if (event.key.keysym.sym=='g' && event.key.keysym.mod&KMOD_CTRL) { +					s->_fastMode ^= 2; +				} +  				if (event.key.keysym.sym=='d' && event.key.keysym.mod&KMOD_CTRL) {  					debugger.attach(s);  				} +				if (event.key.keysym.sym=='s' && event.key.keysym.mod&KMOD_CTRL) { +					s->resourceStats(); +				}  				break;  			case SDL_MOUSEMOTION: { @@ -153,7 +172,9 @@ void waitForTimer(Scumm *s) {  				break;  			}  		} -		SDL_Delay(dontPause ? 10 : 100); +		 +		if (!(s->_fastMode&2)) +			SDL_Delay(dontPause ? 10 : 100);  	} while (!dontPause);  	s->_scummTimer+=3; @@ -175,10 +196,17 @@ void addDirtyRect(int x, int y, int w, int h) {  		fullRedraw = true;  	else if (!fullRedraw) {  		r = &dirtyRects[numDirtyRects++]; +#if defined(SCALEUP_2x2)  		r->x = x*2;  		r->y = y*2;  		r->w = w*2;  		r->h = h*2; +#else +		r->x = x; +		r->y = y; +		r->w = w; +		r->h = h; +#endif  	}  } @@ -209,7 +237,7 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {  	addDirtyRect(x,y,w,h);  	do {  		memcpy(dst, src, w); -		dst += 640; +		dst += 320;  		src += 320;  	} while (--h);  #else @@ -231,7 +259,11 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {  }  void updateScreen(Scumm *s) { -	 + +	if (s->_fastMode&2) +		return; + +  	if (hide_mouse) {  		hide_mouse = false;  		s->drawMouse(); @@ -252,6 +284,7 @@ void updateScreen(Scumm *s) {  			area += (dirtyRects[i].w * dirtyRects[i].h);  		debug(2,"update area %f %%", (float)area/640);  #endif +  		SDL_UpdateRects(screen, numDirtyRects, dirtyRects);	  	} @@ -269,6 +302,8 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib  	if (SDL_LockSurface(screen)==-1)  		error("SDL_LockSurface failed: %s.\n", SDL_GetError()); +#if defined(SCALEUP_2x2) +  	if (has_mouse) {  		dst = (byte*)screen->pixels + old_mouse_y*640*2 + old_mouse_x*2;  		bak = old_backup; @@ -308,6 +343,43 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib  			}  		}  	} +#else +	if (has_mouse) { +		dst = (byte*)screen->pixels + old_mouse_y*320 + old_mouse_x; +		bak = old_backup; + +		for (y=0; y<16; y++,bak+=24,dst+=320) { +			if ( (uint)(old_mouse_y + y) < 200) { +				for (x=0; x<24; x++) { +					if ((uint)(old_mouse_x + x) < 320) { +						dst[x] = bak[x]; +					} +				} +			} +		} +	} +	if (visible) { +		dst = (byte*)screen->pixels + ydraw*320 + xdraw; +		bak = old_backup; + +		for (y=0; y<16; y++,dst+=320,bak+=24) { +			bits = mask[3] | (mask[2]<<8) | (mask[1]<<16); +			mask += 4; +			if ((uint)(ydraw+y)<200) { +				for (x=0; x<24; x++,bits<<=1) { +					if ((uint)(xdraw+x)<320) { +						bak[x] = dst[x]; +						if (bits&(1<<23)) { +							dst[x] = color; +						} +					} +				} +			} +		} +	} + + +#endif	  	SDL_UnlockSurface(screen); @@ -322,13 +394,77 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib  		old_mouse_x = xdraw;  		old_mouse_y = ydraw;  	} -	 + +} + +#define SAMPLES_PER_SEC 22050 +#define BUFFER_SIZE (8192) +#define BITS_PER_SAMPLE 16 + +static void *_sfx_sound; +static int _sfx_pos; +static int _sfx_size; + +static uint32 _sfx_fp_speed; +static uint32 _sfx_fp_pos; + +bool isSfxFinished() { +	return _sfx_size == 0; +} + +void playSfxSound(void *sound, int size, int rate) { +	if (_sfx_sound) { +		free(_sfx_sound); +	} +	_sfx_sound = sound; +	_sfx_pos = 0; +	_sfx_fp_speed = (1<<16) * rate / 22050; +	_sfx_fp_pos = 0; +	_sfx_size = size * 22050 / rate; +} + +void mix_sound(int16 *data, int len) { +	int8 *s; +	int i; +	uint32 fp_pos, fp_speed; + +	if (!_sfx_size) +		return; +	if (len > _sfx_size) +		len = _sfx_size; +	_sfx_size -= len; + +	s = (int8*)_sfx_sound + _sfx_pos; +	fp_pos = _sfx_fp_pos; +	fp_speed = _sfx_fp_speed; + +	do { +		fp_pos += fp_speed; +		*data++ += (*s<<6); +		s += fp_pos >> 16; +		fp_pos &= 0x0000FFFF; +	} while (--len); + +	_sfx_pos = s - (int8*)_sfx_sound; +	_sfx_fp_speed = fp_speed; +	_sfx_fp_pos = fp_pos; +} + +void fill_sound(void *userdata, Uint8 *stream, int len) { +#if defined(USE_IMUSE) +	sound.generate_samples((int16*)stream, len>>1); +#else +	memset(stream, 0, len); +#endif +	mix_sound((int16*)stream, len>>1);  }  void initGraphics(Scumm *s) { -	if (SDL_Init(SDL_INIT_VIDEO)==-1) { +	SDL_AudioSpec desired; + +	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)==-1) {  		error("Could not initialize SDL: %s.\n", SDL_GetError()); -    exit(1); +	    exit(1);  	}  	/* Clean up on exit */ @@ -338,10 +474,20 @@ void initGraphics(Scumm *s) {  	sprintf(buf, "ScummVM - %s", gameName = s->getGameName());  	free(gameName); -	 + +	desired.freq = SAMPLES_PER_SEC; +	desired.format = AUDIO_S16SYS; +	desired.channels = 1; +	desired.samples = 2048; +	desired.callback = fill_sound; +	SDL_OpenAudio(&desired, NULL); +	SDL_PauseAudio(0); + +  	SDL_WM_SetCaption(buf,buf);  	SDL_ShowCursor(SDL_DISABLE); +  #if !defined(SCALEUP_2x2)  	screen = SDL_SetVideoMode(320, 200, 8, SDL_SWSURFACE);  #else @@ -362,6 +508,12 @@ void initGraphics(Scumm *s) {  #undef main  int main(int argc, char* argv[]) {  	scumm._videoMode = 0x13; + +#if defined(USE_IMUSE) +	sound.initialize(NULL); +	scumm._soundDriver = &sound; +#endif +  	scumm.scummMain(argc, argv);  	return 0;  } @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.3  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.2  2001/10/16 10:01:48  strigeus   * preliminary DOTT support   * @@ -30,6 +34,20 @@  #include "stdafx.h"  #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#else +struct SoundEngine { +	byte **_base_sounds; +	int start_sound(int sound) { return -1; } +	int stop_sound(int sound) { return -1; } +	int stop_all_sounds() { return -1; } +	int32 do_command(int a, int b, int c, int d, int e, int f, int g, int h) { return -1; } +	int get_sound_status(int sound) { return -1; } +	int clear_queue() { return -1; } +}; +#endif +  void Scumm::addSoundToQueue(int sound) {  	_vars[VAR_LAST_SOUND] = sound;  	ensureResourceLoaded(4, sound); @@ -42,11 +60,14 @@ void Scumm::addSoundToQueue2(int sound) {  	}  } -void Scumm::unkSoundProc22() { +void Scumm::processSoundQues() {  	byte d;  	int i,j;  	int num;  	int16 data[16]; +	SoundEngine *se; + +	processSfxQueues();  	while (_soundQue2Pos){  		d=_soundQue2[--_soundQue2Pos]; @@ -54,39 +75,199 @@ void Scumm::unkSoundProc22() {  			playSound(d);  	} -#if 0  	for (i=0; i<_soundQuePos; ) {  		num = _soundQue[i++]; +		if (i + num > _soundQuePos) { +			warning("processSoundQues: invalid num value"); +			break; +		}  		for (j=0; j<16; j++)  			data[j] = 0;  		if (num>0) {  			for (j=0; j<num; j++) -				_soundQue[i+j] = data[j]; +				data[j] = _soundQue[i+j];  			i += num; -			/* XXX: not implemented */ -			warning("unkSoundProc22: not implemented"); -//			vm.vars[VAR_SOUNDRESULT] = soundProcPtr1(...); + +			se = (SoundEngine*)_soundDriver; +#if 0 +			debug(1,"processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)",  +				data[0]>>8, +				data[0]&0xFF, +				data[1], +				data[2], +				data[3], +				data[4], +				data[5], +				data[6], +				data[7] +				); +#endif +			if (se)  +				_vars[VAR_SOUNDRESULT] = se->do_command(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]);  		}  	} -	#endif  	_soundQuePos = 0;  }  void Scumm::playSound(int sound) { -	getResourceAddress(4, sound); -	/* XXX: not implemented */ -//	warning("stub playSound(%d)", sound); +	SoundEngine *se = (SoundEngine*)_soundDriver; +	if (se) { +		getResourceAddress(rtSound, sound); +		se->start_sound(sound); +	}  } -int Scumm::unkSoundProc23(int a) { -	/* TODO: implement this */ -//	warning("unkSoundProc23: not implemented"); +void Scumm::processSfxQueues() { +	Actor *a; +	int act; +	bool b,finished; + +	if (_talk_sound_mode != 0) { +		startTalkSound(_talk_sound_a, _talk_sound_b, _talk_sound_mode); +		_talk_sound_mode = 0; +	} +	 +	if (_sfxMode==2) { +		act = _vars[VAR_TALK_ACTOR]; +		finished = isSfxFinished(); + +		if (act!=0 && (uint)act<0x80 && !string[0].no_talk_anim) { +			a = derefActorSafe(act, "processSfxQueues"); +			if (a->room==_currentRoom && (finished || !_endOfMouthSync)) { +				b = true; +				if (!finished) +					b = isMouthSyncOff(_curSoundPos); +				if (_mouthSyncMode != b) { +					_mouthSyncMode = b; +					startAnimActor(a, b ? a->talkFrame2 : a->talkFrame1, a->facing); +				} +			} +		} +		if (finished && _talkDelay==0) { +			stopTalk(); +			_sfxMode = 0; +		} +	} else if (_sfxMode==1) { +		if (isSfxFinished()) { +			_sfxMode = 0; +		} +	} +} + +void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) { +	int num, i; +	byte file_byte,file_byte_2; +	uint16 elem; + +	if (!_sfxFile) { +		warning("startTalkSound: SFX file is not open"); +		return; +	} + +	fileSeek((FILE*)_sfxFile, offset + 8, SEEK_SET); +	i = 0; +	if (b>8) { +		num = (b-8)>>1; +		do { +			fileRead((FILE*)_sfxFile, &file_byte, sizeof(file_byte)); +			fileRead((FILE*)_sfxFile, &file_byte_2, sizeof(file_byte_2)); +			_mouthSyncTimes[i++] = file_byte | (file_byte_2<<8); +		} while (--num); +	} +	_mouthSyncTimes[i] = 0xFFFF; +	_sfxMode = mode; +	_curSoundPos = 0; +	_mouthSyncMode = true; + +	startSfxSound(_sfxFile); +} + +bool Scumm::isMouthSyncOff(uint pos) { +	uint j; +	bool val = true; +	uint16 *ms = _mouthSyncTimes; + +	_endOfMouthSync = false; +	do { +		val ^= 1; +		j = *ms++; +		if (j==0xFFFF) { +			_endOfMouthSync = true; +			break; +		} +	} while (pos > j); +	return val; +} + + +int Scumm::isSoundRunning(int sound) { +	SoundEngine *se; +	int i; + +	i = _soundQue2Pos; +	while (i--) { +		if (_soundQue2[i] == sound) +			return 1; +	} + +	if (isSoundInQueue(sound)) +		return 1; + +	if (!isResourceLoaded(4, sound)) +		return 0; + +	 +	se = (SoundEngine*)_soundDriver; +	if (!se) +		return 0; +	return se->get_sound_status(sound); +} + +bool Scumm::isSoundInQueue(int sound) { +	int i = 0,j, num; +	int16 table[16]; + +	while (i < _soundQuePos) { +		num = _soundQue[i++]; + +		memset(table, 0, sizeof(table)); + +		if (num > 0) { +			for (j=0; j<num; j++) +				table[j] = _soundQue[i+j]; +			i += num; +			if (table[0] == 0x10F && table[1]==8 && table[2] == sound) +				return 1; +		} +	}  	return 0;  } -void Scumm::unkSoundProc1(int a) { -	/* TODO: implement this */ -//	warning("unkSoundProc: not implemented"); +void Scumm::stopSound(int a) { +	SoundEngine *se; +	int i; + +	se = (SoundEngine*)_soundDriver; +	if (se) +		se->stop_sound(a); + +	for (i=0; i<10; i++) +		if (_soundQue2[i] == (byte)a) +			_soundQue2[i] = 0; +} + +void Scumm::stopAllSounds() { +	SoundEngine *se = (SoundEngine*)_soundDriver; +	if (se) { +		se->stop_all_sounds(); +		se->clear_queue(); +	} +	clearSoundQue(); +} + +void Scumm::clearSoundQue() { +	_soundQue2Pos = 0; +	memset(_soundQue2, 0, sizeof(_soundQue2));  }  void Scumm::soundKludge(int16 *list) { @@ -94,7 +275,7 @@ void Scumm::soundKludge(int16 *list) {  	int i;  	if (list[0]==-1) { -		unkSoundProc22(); +		processSoundQues();  		return;  	}  	_soundQue[_soundQuePos++] = 8; @@ -106,4 +287,84 @@ void Scumm::soundKludge(int16 *list) {  		*ptr++ = list[i];  	if (_soundQuePos > 0x100)  		error("Sound que buffer overflow"); +} + +void Scumm::talkSound(uint32 a, uint32 b, int mode) { +	_talk_sound_a = a; +	_talk_sound_b = b; +	_talk_sound_mode = mode; +} + +static const uint32 sound_tags[] = { +	MKID('ADL ') +}; + +void Scumm::setupSound() { +	SoundEngine *se = (SoundEngine*)_soundDriver; +	if (se) { +		se->_base_sounds = res.address[4]; +	} +	_soundTagTable = (byte*)sound_tags; +	_numSoundTags = 1; +	if (_majorScummVersion==6) +		_sfxFile = openSfxFile(); +} + +struct VOCHeader { +	byte id[19]; +	byte extra[7]; +}; + +static const char VALID_VOC_ID[] = "Creative Voice File"; +static const char VALID_VOC_VERSION[] = ""; +void Scumm::startSfxSound(void *file) { +	VOCHeader hdr; +	int block_type; +	byte work[8]; +	uint size,i; +	int rate,comp; +	byte *data; + +	if (fread(&hdr, sizeof(hdr), 1, (FILE*)file) != 1 ||  +		memcmp(hdr.id, VALID_VOC_ID, sizeof(hdr.id)) != 0) { +		warning("startSfxSound: invalid header"); +		return; +	} + +	block_type = getc( (FILE*)file ); +	if (block_type != 1) { +		warning("startSfxSound: Expecting block_type == 1, got %d", block_type); +		return; +	} + +	fread(work, 3, 1, (FILE*)file); + +	size = ( work[0] | ( work[1] << 8 ) | ( work[2] << 16 ) ) - 2; +	rate = getc( (FILE*)file ); +	comp = getc( (FILE*)file ); + +	if (comp != 0) { +		warning("startSfxSound: Unsupported compression type %d", comp); +		return; +	} + +	data = (byte*) malloc(size); +	if (data==NULL) { +		error("startSfxSound: out of memory"); +		return; +	} +	 +	if (fread(data, size, 1, (FILE*)file) != 1) { +		/* no need to free the memory since error will shut down */ +		error("startSfxSound: cannot read %d bytes", size); +		return; +	} +	for(i=0;i<size; i++) +		data[i] ^= 0x80; + +	playSfxSound(data, size, 1000000 / (256 - rate) ); +} + +void *Scumm::openSfxFile() { +	return fopen("monster.sou", "rb");  }
\ No newline at end of file @@ -1,12 +1,3 @@ -/* - * $Id$ - * - * $Log$ - * Revision 1.4  2001/11/03 06:40:51  cmatsuoka - * Not including unistd.h in BeOS (breaks cross-compilation). - * - */ -  #if defined(WIN32)  #if _MSC_VER > 1000 @@ -48,6 +39,7 @@  #include <conio.h>  #include <malloc.h>  #include <assert.h> +#include <mmsystem.h>  #else @@ -56,9 +48,7 @@  #endif  #include <sys/types.h>  #include <sys/uio.h> -#if !defined(__BEOS__)  #include <unistd.h> -#endif  #include <stdio.h>  #include <fcntl.h>  #include <stdlib.h> diff --git a/string.cpp b/string.cpp index 556b6aa249..7ed750f133 100644 --- a/string.cpp +++ b/string.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.6  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.5  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -46,7 +50,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {  	byte chr;  	width = 1; -	ptr = _vm->getResourceAddress(6, _curId) + 29; +	ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;  	while ( (chr = text[pos++]) != 0) {  		if (chr==0xD) @@ -74,7 +78,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {  			if (chr==14) {  				int set = text[pos] | (text[pos+1]<<8);  				pos+=2; -				ptr = _vm->getResourceAddress(6, set) + 29; +				ptr = _vm->getResourceAddress(rtCharset, set) + 29;  				continue;  			}  		} @@ -99,7 +103,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {  	byte *ptr;  	byte chr; -	ptr = _vm->getResourceAddress(6, _curId) + 29; +	ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;  	while ( (chr=str[pos++]) != 0) {  		if (chr=='@') @@ -131,7 +135,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {  			if (chr==14) {  				int set = str[pos] | (str[pos+1]<<8);  				pos+=2; -				ptr = _vm->getResourceAddress(6, set) + 29; +				ptr = _vm->getResourceAddress(rtCharset, set) + 29;  				continue;  			}  		} @@ -160,10 +164,18 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {  }  void Scumm::unkMessage1() { -	byte buf[100]; -	_msgPtrToAdd = buf; +	byte buffer[100]; +	_msgPtrToAdd = buffer;  	_messagePtr = addMessageToStack(_messagePtr); +	if (buffer[0] == 0xFF && buffer[1]==10) { +		uint32 a,b; + +		a = buffer[2] | (buffer[3]<<8) | (buffer[6]<<16) | (buffer[7]<<24); +		b = buffer[10] | (buffer[11]<<8) | (buffer[14]<<16) | (buffer[15]<<24); +		talkSound(a,b,1); +	} +  //	warning("unkMessage1(\"%s\")", buf);  } @@ -185,6 +197,7 @@ void Scumm::CHARSET_1() {  	int s, i, t, c;  	int frme;  	Actor *a; +	byte *buffer;  	if (!_haveMsg || (camera._destPos>>3) != (camera._curPos>>3) ||  			camera._curPos != camera._lastPos  @@ -253,12 +266,14 @@ void Scumm::CHARSET_1() {  		return;  	if (_haveMsg!=0xFF) { -		stopTalk(); +		if (_sfxMode==0) +			stopTalk();  		return;  	} -	if (a) { +	if (a && !string[0].no_talk_anim) {  		startAnimActor(a, a->talkFrame1, a->facing); +		_useTalkAnims = true;  	}  	_talkDelay = _defaultTalkDelay; @@ -275,17 +290,20 @@ void Scumm::CHARSET_1() {  			t = string[0].xpos2;  		t <<= 1;  	} -	charset.addLinebreaks(0, charset._buffer, charset._bufPos, t); + +	buffer = charset._buffer + charset._bufPos; +	 +	charset.addLinebreaks(0, buffer,0, t);  	_lastXstart = virtscr[0].xstart;  	if (charset._center) { -		string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos) >> 1; +		string[0].xpos2 -= charset.getStringWidth(0, buffer,0) >> 1;  	}  	charset._disableOffsX = charset._unk12 = !_keepText;  	do { -		c = charset._buffer[charset._bufPos++]; +		c = *buffer++;  		if (c==0) {  			_haveMsg = 1;  			_keepText = false; @@ -295,9 +313,9 @@ void Scumm::CHARSET_1() {  newLine:;  			string[0].xpos2 = string[0].xpos;  			if (charset._center) { -				string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos)>>1; +				string[0].xpos2 -= charset.getStringWidth(0, buffer, 0)>>1;  			} -			string[0].ypos2 += getResourceAddress(6,charset._curId)[30]; +			string[0].ypos2 += getResourceAddress(rtCharset,charset._curId)[30];  			charset._disableOffsX = 1;  			continue;  		} @@ -323,7 +341,7 @@ newLine:;  			continue;  		} -		c = charset._buffer[charset._bufPos++]; +		c = *buffer++;  		if (c==3) {  			_haveMsg = 0xFF;  			_keepText = false; @@ -335,36 +353,42 @@ newLine:;  			_keepText = true;  			break;  		} else if (c==9) { -			frme = charset._buffer[charset._bufPos++]; -			frme |= charset._buffer[charset._bufPos++]<<8; +			frme = *buffer++; +			frme |= *buffer++<<8;  			if (a)  				startAnimActor(a, frme, a->facing);  		} else if (c==10) { -			warning("CHARSET_1: code 10 unimplemented"); -			charset._bufPos += 14; +			uint32 a,b; + +			a = buffer[0] | (buffer[1]<<8) | (buffer[4]<<16) | (buffer[5]<<24); +			b = buffer[8] | (buffer[9]<<8) | (buffer[12]<<16) | (buffer[13]<<24); +			talkSound(a,b,2); +			buffer += 14;  		} else if (c==14) { -			int oldy = getResourceAddress(6,charset._curId)[30]; +			int oldy = getResourceAddress(rtCharset,charset._curId)[30]; -			charset._curId = charset._buffer[charset._bufPos]; -			charset._bufPos += 2; +			charset._curId = *buffer++; +			buffer += 2;  			for (i=0; i<4; i++)  				charset._colorMap[i] = _charsetData[charset._curId][i]; -			string[0].ypos2 -= getResourceAddress(6,charset._curId)[30] - oldy; +			string[0].ypos2 -= getResourceAddress(rtCharset,charset._curId)[30] - oldy;  		} else if (c==12) {  			int color; -			color = charset._buffer[charset._bufPos++]; -			color |= charset._buffer[charset._bufPos++]<<8; +			color = *buffer++; +			color |= *buffer++<<8;  			if (color==0xFF)  				charset._color = _charsetColor;  			else  				charset._color = color;  		} else if (c==13) { -			charset._bufPos += 2; +			buffer += 2;  		} else {  			warning("CHARSET_1: invalid code %d", c);  		}  	} while (1); +	charset._bufPos = buffer - charset._buffer; +  	string[0].mask_left = charset._strLeft;  	string[0].mask_right = charset._strRight;  	string[0].mask_top = charset._strTop; @@ -391,7 +415,7 @@ void Scumm::drawString(int a) {  	charset._unk12 = 1;  	charset._disableOffsX = 1; -	charsetptr = getResourceAddress(6, charset._curId); +	charsetptr = getResourceAddress(rtCharset, charset._curId);  	assert(charsetptr);  	charsetptr += 29; @@ -469,7 +493,7 @@ byte *Scumm::addMessageToStack(byte *msg) {  	byte *ptr, chr;  	numorg = num = _numInMsgStack; -	ptr = getResourceAddress(0xC, 6); +	ptr = getResourceAddress(rtTemp, 6);  	if (ptr==NULL)  		error("Message stack not allocated"); @@ -495,7 +519,7 @@ byte *Scumm::addMessageToStack(byte *msg) {  	num = numorg;  	while (1) { -		ptr = getResourceAddress(0xC, 6); +		ptr = getResourceAddress(rtTemp, 6);  		chr = ptr[num++];  		if (chr == 0)   			break; @@ -573,7 +597,7 @@ void Scumm::unkAddMsgToStack3(int var) {  	if (num) {  		for (i=1; i<_maxVerbs; i++) {  			if (num==_verbs[i].verbid && !_verbs[i].type && !_verbs[i].saveid) { -				addMessageToStack(getResourceAddress(8, i)); +				addMessageToStack(getResourceAddress(rtVerb, i));  				break;  			}  		} @@ -612,7 +636,7 @@ void Scumm::unkAddMsgToStack5(int var) {  void Scumm::initCharset(int charsetno) {  	int i; -	if (!getResourceAddress(6, charsetno)) +	if (!getResourceAddress(rtCharset, charsetno))  		loadCharset(charsetno);  	string[0].t_charset = charsetno; @@ -633,7 +657,7 @@ void CharsetRenderer::printChar(int chr) {  	if (chr=='@')  		return; -	_ptr = _vm->getResourceAddress(6, _curId) + 29; +	_ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;  	_bpp = _unk2 = *_ptr;  	_invNumBits = 8 - _bpp; @@ -716,7 +740,7 @@ void CharsetRenderer::printChar(int chr) {  		_hasMask = true;  #endif -	_bg_ptr2 = _backbuff_ptr = _vm->getResourceAddress(0xA, vs->number+1)  +	_bg_ptr2 = _backbuff_ptr = _vm->getResourceAddress(rtBuffer, vs->number+1)   		+ vs->xstart + _drawTop * 320 + _left;  #if !defined(OLD) @@ -724,11 +748,11 @@ void CharsetRenderer::printChar(int chr) {  #else  	if (1) {  #endif -		_bg_ptr2 = _bgbak_ptr = _vm->getResourceAddress(0xA, vs->number+5) +		_bg_ptr2 = _bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number+5)  			+ vs->xstart + _drawTop * 320 + _left;  	} -	_mask_ptr = _vm->getResourceAddress(0xA, 9) +	_mask_ptr = _vm->getResourceAddress(rtBuffer, 9)  		+ _drawTop * 40 + _left/8   		+ _vm->_screenStartStrip; @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.3  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.2  2001/10/10 10:02:33  strigeus   * alternative mouse cursor   * basic save&load @@ -96,7 +100,7 @@ void Scumm::fileRead(void *file, void *ptr, uint32 size) {  		if (size==0)  			return; -		src = getResourceAddress(0xC, 3) + _whereInResToRead; +		src = getResourceAddress(rtTemp, 3) + _whereInResToRead;  		_whereInResToRead += size;  		do {  			*ptr2++ = *src++ ^ _encbyte; @@ -116,7 +120,7 @@ int Scumm::fileReadByte() {  		return b ^ _encbyte;  	case 3: -		src = getResourceAddress(0xC, 3) + _whereInResToRead; +		src = getResourceAddress(rtTemp, 3) + _whereInResToRead;  		_whereInResToRead++;  		return *src ^ _encbyte;  	} @@ -157,13 +161,15 @@ byte *Scumm::alloc(int size) {  }  void Scumm::free(void *mem) { -	byte *me = (byte*)mem - 4; -	if ( *((uint32*)me) != 0xDEADBEEF) { -		error("Freeing invalid block."); +	if (mem) { +		byte *me = (byte*)mem - 4; +		if ( *((uint32*)me) != 0xDEADBEEF) { +			error("Freeing invalid block."); +		} + +		*((uint32*)me) = 0xC007CAFE; +		::free(me);  	} - -	*((uint32*)me) = 0xC007CAFE; -	::free(me);  }  bool Scumm::checkFixedDisk() { @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.5  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.4  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -143,7 +147,7 @@ void Scumm::drawVerb(int vrb, int mode) {  		string[4].color = color;  		if (vs->curmode==2)  			string[4].color = vs->dimcolor; -		_messagePtr = getResourceAddress(8, vrb); +		_messagePtr = getResourceAddress(rtVerb, vrb);  		assert(_messagePtr);  		tmp = charset._center;  		charset._center = 0; @@ -198,7 +202,7 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {  	ydiff = y - vs->topline; -	obim = getResourceAddress(8, vrb); +	obim = getResourceAddress(rtVerb, vrb);  	IMHD_ptr = findResource(MKID('IMHD'), obim, 0);  	imgw = READ_LE_UINT16(IMHD_ptr+0x14) >> 3; @@ -247,7 +251,7 @@ void Scumm::killVerb(int slot) {  	vs->verbid = 0;  	vs->curmode = 0; -	nukeResource(8, slot); +	nukeResource(rtVerb, slot);  	if (vs->saveid==0) {  		drawVerb(slot, 0); @@ -267,8 +271,8 @@ void Scumm::setVerbObject(int room, int object, int verb) {  	if (whereIsObject(object) == 4)  		error("Can't grab verb image from flobject"); -	ensureResourceLoaded(1,room); -	roomptr = getResourceAddress(1, room); +	ensureResourceLoaded(rtRoom,room); +	roomptr = getResourceAddress(rtRoom, room);  	roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0);  	numobj = READ_LE_UINT16(&roomhdr->numObjects); @@ -285,9 +289,9 @@ void Scumm::setVerbObject(int room, int object, int verb) {  		if ( READ_LE_UINT16(&imhd->obj_id) == object) {  			imoffs = obimptr - roomptr;  			size = READ_BE_UINT32_UNALIGNED(obimptr+4); -			createResource(8, verb, size); -			obimptr = getResourceAddress(1, room) + imoffs; -			memcpy(getResourceAddress(8, verb), obimptr, size); +			createResource(rtVerb, verb, size); +			obimptr = getResourceAddress(rtRoom, room) + imoffs; +			memcpy(getResourceAddress(rtVerb, verb), obimptr, size);  			return;  		}  	} diff --git a/windows.cpp b/windows.cpp index dcb0f6d947..2092ffd775 100644 --- a/windows.cpp +++ b/windows.cpp @@ -17,6 +17,10 @@   *   * Change Log:   * $Log$ + * Revision 1.9  2001/11/05 19:21:49  strigeus + * bug fixes, + * speech in dott + *   * Revision 1.8  2001/10/26 17:34:50  strigeus   * bug fixes, code cleanup   * @@ -61,6 +65,10 @@  #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#endif +  #define SRC_WIDTH 320  #define SRC_HEIGHT 200  #define SRC_PITCH (320) @@ -72,6 +80,13 @@  #define USE_DRAWDIB 0  #define USE_GDI 1 +#define SAMPLES_PER_SEC 22050 +#define BUFFER_SIZE (8192) +#define BITS_PER_SAMPLE 16 + +static bool shutdown; + +  #if USE_GDI  typedef struct DIB {  	HBITMAP hSect; @@ -115,6 +130,11 @@ public:  	void InitDirectX();  #endif +	HANDLE _event; +	DWORD _threadId; +	HWAVEOUT _handle; +	WAVEHDR _hdr[2]; +  public:  	void init(); @@ -123,6 +143,10 @@ public:  	void setPalette(byte *ctab, int first, int num);  	void writeToScreen(); +	void prepare_header(WAVEHDR *wh, int i); +	void sound_init(); +	static DWORD _stdcall sound_thread(WndMan *wm); +  #if USE_GDI  	bool allocateDIB(int w, int h);  #endif @@ -137,6 +161,7 @@ void Error(const char *msg) {  int sel;  Scumm scumm;  ScummDebugger debugger; +SoundEngine sound;  WndMan wm[1];  byte veryFastMode; @@ -150,7 +175,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l  	{  		case WM_DESTROY:  		case WM_CLOSE: -			PostQuitMessage(0); +//			TerminateThread((void*)wm->_threadId, 0); +//			wm->_scumm->destroy(); +			exit(0);  			break;  		case WM_CHAR: @@ -178,6 +205,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l  			if (wParam=='D') {  				debugger.attach(wm->_scumm);  			} +			 +			if (wParam=='S') { +				wm->_scumm->resourceStats(); +			}  			break; @@ -761,28 +792,28 @@ void outputdisplay2(Scumm *s, int disp) {  	case 0:  		wm->_vgabuf = buf;  		memcpy(buf, wm->_vgabuf, 64000); -		memcpy(buf+320*144,s->getResourceAddress(0xA, 7),320*56); +		memcpy(buf+320*144,s->getResourceAddress(rtBuffer, 7),320*56);  		break;  	case 1:  		wm->_vgabuf = buf;  		memcpy(buf, wm->_vgabuf, 64000); -		memcpy(buf+320*144,s->getResourceAddress(0xA, 3),320*56); +		memcpy(buf+320*144,s->getResourceAddress(rtBuffer, 3),320*56);  		break;  	case 2:  		wm->_vgabuf = NULL; -		decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+s->_screenStartStrip); +		decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+s->_screenStartStrip);  		break;  	case 3:  		wm->_vgabuf = NULL; -		decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920+s->_screenStartStrip); +		decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920+s->_screenStartStrip);  		break;  	case 4:  		wm->_vgabuf = NULL; -		decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920*2+s->_screenStartStrip); +		decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920*2+s->_screenStartStrip);  		break;  	case 5:  		wm->_vgabuf = NULL; -		decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920*3+s->_screenStartStrip); +		decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920*3+s->_screenStartStrip);  		break;  	}  	wm->writeToScreen();	 @@ -838,17 +869,81 @@ void initGraphics(Scumm *s) {  void drawMouse(Scumm *s, int, int, int, byte*, bool) {  } +void WndMan::prepare_header(WAVEHDR *wh, int i) { +	memset(wh, 0, sizeof(WAVEHDR)); +	wh->lpData = (char*)malloc(BUFFER_SIZE); +	wh->dwBufferLength = BUFFER_SIZE; + +	waveOutPrepareHeader(_handle, wh, sizeof(WAVEHDR)); + +	sound.generate_samples((int16*)wh->lpData, wh->dwBufferLength>>1); +	waveOutWrite(_handle, wh, sizeof(WAVEHDR)); +} + +void WndMan::sound_init() { +	WAVEFORMATEX wfx; + +	memset(&wfx, 0, sizeof(wfx)); +	wfx.wFormatTag = WAVE_FORMAT_PCM; +	wfx.nChannels = 1; +	wfx.nSamplesPerSec = SAMPLES_PER_SEC; +	wfx.nAvgBytesPerSec = SAMPLES_PER_SEC * BITS_PER_SAMPLE / 8; +	wfx.wBitsPerSample = BITS_PER_SAMPLE; +	wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8; + +	CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))&sound_thread, this, 0, &_threadId); + +	_event = CreateEvent(NULL, false, false, NULL); + +	memset(_hdr,0,sizeof(_hdr)); +	 +	waveOutOpen(&_handle, WAVE_MAPPER, &wfx, (long)_event, (long)this, CALLBACK_EVENT ); + +	prepare_header(&_hdr[0], 0); +	prepare_header(&_hdr[1], 1); +} + +DWORD _stdcall WndMan::sound_thread(WndMan *wm) { +	int i; +	while (1) { +		WaitForSingleObject(wm->_event, INFINITE); +		for(i=0; i<2; i++) { +			WAVEHDR *hdr = &wm->_hdr[i]; +			if (hdr->dwFlags & WHDR_DONE) { +				sound.generate_samples((int16*)hdr->lpData, hdr->dwBufferLength>>1); +				waveOutWrite(wm->_handle, hdr, sizeof(WAVEHDR)); +			} +		} +	} +} + +  #undef main  int main(int argc, char* argv[]) {  	scumm._videoMode = 0x13;  	wm->init(); +	wm->sound_init();  	wm->_vgabuf = (byte*)calloc(320,200);  	wm->_scumm = &scumm; +#if defined(USE_IMUSE) +	sound.initialize(NULL); +	scumm._soundDriver = &sound; +#endif +  	scumm.scummMain(argc, argv);  	return 0;  } + +bool isSfxFinished() { +	return true; +} + +void playSfxSound(void *sound, int size, int rate) { +	 +} + | 
