diff options
| author | Sven Hesse | 2006-04-12 09:49:08 +0000 | 
|---|---|---|
| committer | Sven Hesse | 2006-04-12 09:49:08 +0000 | 
| commit | adbafccc64fba8f314a302042b78c2a36a61619f (patch) | |
| tree | 0f5d1f58cf50c15cf4475b6a432e58bb4481d72a /engines | |
| parent | 2ca3831777e091d74510e9c0244b88458d0e363d (diff) | |
| download | scummvm-rg350-adbafccc64fba8f314a302042b78c2a36a61619f.tar.gz scummvm-rg350-adbafccc64fba8f314a302042b78c2a36a61619f.tar.bz2 scummvm-rg350-adbafccc64fba8f314a302042b78c2a36a61619f.zip  | |
- Fixed the mistake in Mult_v2::loadMult() that caused Gob2 floppy to
  have a messed up script-pointer afterwards
- Added/Changed parts of Mult_v2::playMult() et al. so that the intro
  works for a few seconds (with glitches) before getting killed while
  trying to draw text (CD) or trying to play sounds (floppy)
svn-id: r21823
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/gob/inter_v2.cpp | 6 | ||||
| -rw-r--r-- | engines/gob/mult.cpp | 698 | ||||
| -rw-r--r-- | engines/gob/mult.h | 61 | ||||
| -rw-r--r-- | engines/gob/mult_v1.cpp | 701 | ||||
| -rw-r--r-- | engines/gob/mult_v2.cpp | 904 | 
5 files changed, 1641 insertions, 729 deletions
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 548e112369..b3e5ac4478 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1178,11 +1178,11 @@ void Inter_v2::o2_initMult(void) {  	animDataVar = _vm->_parse->parseVarIndex();  	if (_vm->_mult->_objects == 0) { -		// GOB2: _vm->_mult->_renderData = new int16[_vm->_mult->_objCount * 2]; +		_vm->_mult->_renderData2 = new Mult::Mult_Object*[_vm->_mult->_objCount];  		_vm->_mult->_renderData = new int16[_vm->_mult->_objCount * 9];  		if (_vm->_inter->_terminate)  			return; -		warning("GOB2 Stub! dword_2FC74 = new int8[_vm->_mult->_objCount];"); +		_vm->_mult->_orderArray = new int8[_vm->_mult->_objCount];  		_vm->_mult->_objects = new Mult::Mult_Object[_vm->_mult->_objCount];  		for (i = 0; i < _vm->_mult->_objCount; i++) { @@ -1221,7 +1221,7 @@ void Inter_v2::o2_initMult(void) {  			_vm->_anim->_animSurf = new Video::SurfaceDesc;  			memcpy(_vm->_anim->_animSurf, _vm->_draw->_frontSurface, sizeof(Video::SurfaceDesc));  			_vm->_anim->_animSurf->width = (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1) | 7; -			_vm->_anim->_animSurf->width -= (_vm->_anim->_areaLeft & 0x0FF8) - 1; +			_vm->_anim->_animSurf->width -= (_vm->_anim->_areaLeft & 0x0FFF8) - 1;  			_vm->_anim->_animSurf->height = _vm->_anim->_areaHeight;  			_vm->_anim->_animSurf->vidPtr += 0x0C000;  		} else { diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index b16e5d9739..396a0964c4 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -43,6 +43,7 @@ namespace Gob {  Mult::Mult(GobEngine *vm) : _vm(vm) {  	_objects = 0;  	_renderData = 0; +	_renderData2 = 0;  	_objCount = 0;  	_underAnimSurf = 0;  	_multData = 0; @@ -117,290 +118,8 @@ Mult::Mult(GobEngine *vm) : _vm(vm) {  			_fadePal[i][j].green = 0;  			_fadePal[i][j].blue = 0;  		} -} - -void Mult::animate(void) { -	int16 minOrder; -	int16 maxOrder; -	int16 *pCurLefts; -	int16 *pCurRights; -	int16 *pCurTops; -	int16 *pCurBottoms; -	int16 *pDirtyLefts; -	int16 *pDirtyRights; -	int16 *pDirtyTops; -	int16 *pDirtyBottoms; -	int16 *pNeedRedraw; -	Mult_AnimData *pAnimData; -	int16 i, j; -	int16 order; - -	if (_renderData == 0) -		return; - -	pDirtyLefts = _renderData; -	pDirtyRights = pDirtyLefts + _objCount; -	pDirtyTops = pDirtyRights + _objCount; -	pDirtyBottoms = pDirtyTops + _objCount; -	pNeedRedraw = pDirtyBottoms + _objCount; -	pCurLefts = pNeedRedraw + _objCount; -	pCurRights = pCurLefts + _objCount; -	pCurTops = pCurRights + _objCount; -	pCurBottoms = pCurTops + _objCount; -	minOrder = 100; -	maxOrder = 0; - -	//Find dirty areas -	for (i = 0; i < _objCount; i++) { -		pNeedRedraw[i] = 0; -		pDirtyTops[i] = 1000; -		pDirtyLefts[i] = 1000; -		pDirtyBottoms[i] = 1000; -		pDirtyRights[i] = 1000; -		pAnimData = _objects[i].pAnimData; - -		if (pAnimData->isStatic == 0 && pAnimData->isPaused == 0 && -		    _objects[i].tick == pAnimData->maxTick) { -			if (pAnimData->order < minOrder) -				minOrder = pAnimData->order; - -			if (pAnimData->order > maxOrder) -				maxOrder = pAnimData->order; - -			pNeedRedraw[i] = 1; -			_vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, -			    pAnimData->animation, 0, -			    *(_objects[i].pPosX), *(_objects[i].pPosY), -			    0); - -			if (_objects[i].lastLeft != -1) { -				pDirtyLefts[i] = -				    MIN(_objects[i].lastLeft, -				    _vm->_scenery->_toRedrawLeft); -				pDirtyTops[i] = -				    MIN(_objects[i].lastTop, -				    _vm->_scenery->_toRedrawTop); -				pDirtyRights[i] = -				    MAX(_objects[i].lastRight, -				    _vm->_scenery->_toRedrawRight); -				pDirtyBottoms[i] = -				    MAX(_objects[i].lastBottom, -				    _vm->_scenery->_toRedrawBottom); -			} else { -				pDirtyLefts[i] = _vm->_scenery->_toRedrawLeft; -				pDirtyTops[i] = _vm->_scenery->_toRedrawTop; -				pDirtyRights[i] = _vm->_scenery->_toRedrawRight; -				pDirtyBottoms[i] = _vm->_scenery->_toRedrawBottom; -			} -			pCurLefts[i] = _vm->_scenery->_toRedrawLeft; -			pCurRights[i] = _vm->_scenery->_toRedrawRight; -			pCurTops[i] = _vm->_scenery->_toRedrawTop; -			pCurBottoms[i] = _vm->_scenery->_toRedrawBottom; -		} else { -			if (_objects[i].lastLeft != -1) { -				if (pAnimData->order < minOrder) -					minOrder = pAnimData->order; - -				if (pAnimData->order > maxOrder) -					maxOrder = pAnimData->order; - -				if (pAnimData->isStatic) -					*pNeedRedraw = 1; - -				pCurLefts[i] = _objects[i].lastLeft; -				pDirtyLefts[i] = _objects[i].lastLeft; - -				pCurTops[i] = _objects[i].lastTop; -				pDirtyTops[i] = _objects[i].lastTop; - -				pCurRights[i] = _objects[i].lastRight; -				pDirtyRights[i] = _objects[i].lastRight; - -				pCurBottoms[i] = _objects[i].lastBottom; -				pDirtyBottoms[i] = _objects[i].lastBottom; -			} -		} -	} - -	// Find intersections -	for (i = 0; i < _objCount; i++) { -		pAnimData = _objects[i].pAnimData; -		pAnimData->intersected = 200; - -		if (pAnimData->isStatic) -			continue; - -		for (j = 0; j < _objCount; j++) { -			if (i == j) -				continue; -			if (_objects[j].pAnimData->isStatic) -				continue; - -			if (pCurRights[i] < pCurLefts[j]) -				continue; - -			if (pCurRights[j] < pCurLefts[i]) -				continue; - -			if (pCurBottoms[i] < pCurTops[j]) -				continue; - -			if (pCurBottoms[j] < pCurTops[i]) -				continue; - -			pAnimData->intersected = j; -			break; -		} -	} - -	// Restore dirty areas -	for (i = 0; i < _objCount; i++) { - -		if (pNeedRedraw[i] == 0 || _objects[i].lastLeft == -1) -			continue; - -		_vm->_draw->_sourceSurface = 22; -		_vm->_draw->_destSurface = 21; -		_vm->_draw->_spriteLeft = pDirtyLefts[i] - _vm->_anim->_areaLeft; -		_vm->_draw->_spriteTop = pDirtyTops[i] - _vm->_anim->_areaTop; -		_vm->_draw->_spriteRight = pDirtyRights[i] - pDirtyLefts[i] + 1; -		_vm->_draw->_spriteBottom = pDirtyBottoms[i] - pDirtyTops[i] + 1; -		_vm->_draw->_destSpriteX = pDirtyLefts[i]; -		_vm->_draw->_destSpriteY = pDirtyTops[i]; -		_vm->_draw->_transparency = 0; -		_vm->_draw->spriteOperation(DRAW_BLITSURF); -		_objects[i].lastLeft = -1; -	} - -	// Update view -	for (order = minOrder; order <= maxOrder; order++) { -		for (i = 0; i < _objCount; i++) { -			pAnimData = _objects[i].pAnimData; -			if (pAnimData->order != order) -				continue; - -			if (pNeedRedraw[i]) { -				if (pAnimData->isStatic == 0) { - -					_vm->_scenery->updateAnim(pAnimData->layer, -					    pAnimData->frame, -					    pAnimData->animation, 2, -					    *(_objects[i].pPosX), -					    *(_objects[i].pPosY), 1); - -					if (_vm->_scenery->_toRedrawLeft != -12345) { -						_objects[i].lastLeft = -						    _vm->_scenery->_toRedrawLeft; -						_objects[i].lastTop = -						    _vm->_scenery->_toRedrawTop; -						_objects[i].lastRight = -						    _vm->_scenery->_toRedrawRight; -						_objects[i].lastBottom = -						    _vm->_scenery->_toRedrawBottom; -					} else { -						_objects[i].lastLeft = -1; -					} -				} -				_vm->_scenery->updateStatic(order + 1); -			} else if (pAnimData->isStatic == 0) { -				for (j = 0; j < _objCount; j++) { -					if (pNeedRedraw[j] == 0) -						continue; - -					if (pDirtyRights[i] < pDirtyLefts[j]) -						continue; - -					if (pDirtyRights[j] < pDirtyLefts[i]) -						continue; - -					if (pDirtyBottoms[i] < pDirtyTops[j]) -						continue; - -					if (pDirtyBottoms[j] < pDirtyTops[i]) -						continue; - -					_vm->_scenery->_toRedrawLeft = pDirtyLefts[j]; -					_vm->_scenery->_toRedrawRight = pDirtyRights[j]; -					_vm->_scenery->_toRedrawTop = pDirtyTops[j]; -					_vm->_scenery->_toRedrawBottom = pDirtyBottoms[j]; - -					_vm->_scenery->updateAnim(pAnimData->layer, -					    pAnimData->frame, -					    pAnimData->animation, 4, -					    *(_objects[i].pPosX), -					    *(_objects[i].pPosY), 1); - -					_vm->_scenery->updateStatic(order + 1); -				} -			} -		} -	} - -	// Advance animations -	for (i = 0; i < _objCount; i++) { -		pAnimData = _objects[i].pAnimData; -		if (pAnimData->isStatic || pAnimData->isPaused) -			continue; - -		if (_objects[i].tick == pAnimData->maxTick) { -			_objects[i].tick = 0; -			if (pAnimData->animType == 4) { -				pAnimData->isPaused = 1; -				pAnimData->frame = 0; -			} else { -				pAnimData->frame++; -				if (pAnimData->frame >= -				    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->framesCount) { -					switch (pAnimData->animType) { -					case 0: -						pAnimData->frame = 0; -						break; - -					case 1: -						pAnimData->frame = 0; - -						*(_objects[i].pPosX) = -						    *(_objects[i].pPosX) + -						    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->animDeltaX; - -						*(_objects[i].pPosY) = -						    *(_objects[i].pPosY) + -						    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->animDeltaY; -						break; - -					case 2: -						pAnimData->frame = 0; -						pAnimData->animation = -						    pAnimData->newAnimation; -						pAnimData->layer = -						    pAnimData->newLayer; -						break; - -					case 3: -						pAnimData->animType = 4; -						pAnimData->frame = 0; -						break; - -					case 5: -						pAnimData->isStatic = 1; -						pAnimData->frame = 0; -						break; - -					case 6: -						pAnimData->frame--; -						pAnimData->isPaused = 1; -						break; -					} -					pAnimData->newCycle = 1; -				} else { -					pAnimData->newCycle = 0; -				} -			} -		} else { -			_objects[i].tick++; -		} -	} +	_orderArray = 0;  }  void Mult::interGetObjAnimSize(void) { @@ -495,419 +214,6 @@ void Mult::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,  	_vm->_snd->playSample(soundDesc, repCount, freq);  } -char Mult::drawStatics(char stop) { -	if (_staticKeys[_staticKeysCount - 1].frame > _frame) -		stop = 0; - -	for (_counter = 0; _counter < _staticKeysCount; -	    _counter++) { -		if (_staticKeys[_counter].frame != _frame -		    || _staticKeys[_counter].layer == -1) -			continue; - -		for (_vm->_scenery->_curStatic = 0, _vm->_scenery->_curStaticLayer = _staticKeys[_counter].layer; -			 _vm->_scenery->_curStaticLayer >= _vm->_scenery->_statics[_staticIndices[_vm->_scenery->_curStatic]].layersCount; -			 _vm->_scenery->_curStatic++) { -			_vm->_scenery->_curStaticLayer -= -			    _vm->_scenery->_statics[_staticIndices[_vm->_scenery->_curStatic]].layersCount; -		} - -		_vm->_scenery->_curStatic = _staticIndices[_vm->_scenery->_curStatic]; -		_vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); -		_vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, -		    0, 0, 319, 199, 0, 0, 0); -	} -	return stop; -} - -void Mult::drawAnims(void) { -	Mult_AnimKey *key; -	Mult_Object *animObj; -	int16 i; -	int16 count; - -	for (_index = 0; _index < 4; _index++) { -		for (_counter = 0; _counter < _animKeysCount[_index]; _counter++) { -			key = &_animKeys[_index][_counter]; -			animObj = &_objects[_index]; -			if (key->frame != _frame) -				continue; - -			if (key->layer != -1) { -				(*animObj->pPosX) = key->posX; -				(*animObj->pPosY) = key->posY; - -				animObj->pAnimData->frame = 0; -				animObj->pAnimData->order = key->order; -				animObj->pAnimData->animType = 1; - -				animObj->pAnimData->isPaused = 0; -				animObj->pAnimData->isStatic = 0; -				animObj->pAnimData->maxTick = 0; -				animObj->tick = 0; -				animObj->pAnimData->layer = key->layer; - -				count = _vm->_scenery->_animations[_animIndices[0]].layersCount; -				i = 0; -				while (animObj->pAnimData->layer >= count) { -					animObj->pAnimData->layer -= count; -					i++; - -					count = _vm->_scenery->_animations[_animIndices[i]].layersCount; -				} -				animObj->pAnimData->animation = _animIndices[i]; -			} else { -				animObj->pAnimData->isStatic = 1; -			} -		} -	} -} - -void Mult::drawText(char *pStop, char *pStopNoClear) { -	char *savedIP; - -	int16 cmd; -	for (_index = 0; _index < _textKeysCount; _index++) { -		if (_textKeys[_index].frame != _frame) -			continue; - -		cmd = _textKeys[_index].cmd; -		if (cmd == 0) { -			*pStop = 0; -		} else if (cmd == 1) { -			*pStopNoClear = 1; -			_frameStart = 0; -		} else if (cmd == 3) { -			*pStop = 0; -			savedIP = _vm->_global->_inter_execPtr; -			_vm->_global->_inter_execPtr = (char *)(&_textKeys[_index].index); -			_vm->_global->_inter_execPtr = savedIP; -		} -	} -} - -char Mult::prepPalAnim(char stop) { -	_palKeyIndex = -1; -	do { -		_palKeyIndex++; -		if (_palKeyIndex >= _palKeysCount) -			return stop; -	} while (_palKeys[_palKeyIndex].frame != _frame); - -	if (_palKeys[_palKeyIndex].cmd == -1) { -		stop = 0; -		_doPalSubst = 0; -		_vm->_global->_pPaletteDesc->vgaPal = _oldPalette; - -		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); - -		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -	} else { -		stop = 0; -		_doPalSubst = 1; -		_palAnimKey = _palKeyIndex; - -		_palAnimIndices[0] = 0; -		_palAnimIndices[1] = 0; -		_palAnimIndices[2] = 0; -		_palAnimIndices[3] = 0; - -		_vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; -	} -	return stop; -} - -void Mult::doPalAnim(void) { -	int16 off; -	int16 off2; -	Video::Color *palPtr; -	Mult_PalKey *palKey; - -	if (_doPalSubst == 0) -		return; - -	for (_index = 0; _index < 4; _index++) { -		palKey = &_palKeys[_palAnimKey]; - -		if ((_frame % palKey->rates[_index]) != 0) -			continue; - -		_palAnimRed[_index] = -		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; -		_palAnimGreen[_index] = -		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; -		_palAnimBlue[_index] = -		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; - -		while (1) { -			off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index]; -			if (off == 0) { -				off = palKey->subst[_palAnimIndices[_index]][_index] - 1; - -				_vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; -				_vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; -				_vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; -			} else { -				off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index] - 1; -				off2 = palKey->subst[_palAnimIndices[_index]][_index] - 1; - -				_vm->_global->_pPaletteDesc->vgaPal[off2].red = _vm->_global->_pPaletteDesc->vgaPal[off].red; -				_vm->_global->_pPaletteDesc->vgaPal[off2].green = _vm->_global->_pPaletteDesc->vgaPal[off].green; -				_vm->_global->_pPaletteDesc->vgaPal[off2].blue = _vm->_global->_pPaletteDesc->vgaPal[off].blue; -			} - -			_palAnimIndices[_index] = (_palAnimIndices[_index] + 1) % 16; - -			off = palKey->subst[_palAnimIndices[_index]][_index]; - -			if (off == 0) { -				_palAnimIndices[_index] = 0; -				off = palKey->subst[0][_index] - 1; - -				_palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; -				_palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; -				_palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; -			} -			if (_palAnimIndices[_index] == 0) -				break; -		} -	} - -	if (_vm->_global->_colorCount == 256) { -		_vm->_video->waitRetrace(_vm->_global->_videoMode); - -		palPtr = _vm->_global->_pPaletteDesc->vgaPal; -		for (_counter = 0; _counter < 16; _counter++) { -			_vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, palPtr->blue, 0, 0x13); -			palPtr++; -		} - -		palPtr = _vm->_global->_pPaletteDesc->vgaPal; -		for (_counter = 0; _counter < 16; _counter++) { -			_vm->_global->_redPalette[_counter] = palPtr->red; -			_vm->_global->_greenPalette[_counter] = palPtr->green; -			_vm->_global->_bluePalette[_counter] = palPtr->blue; -			palPtr++; -		} -	} else { -		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -	} -} - -char Mult::doFadeAnim(char stop) { -	Mult_PalFadeKey *fadeKey; - -	for (_index = 0; _index < _palFadeKeysCount; _index++) { -		fadeKey = &_palFadeKeys[_index]; - -		if (fadeKey->frame != _frame) -			continue; - -		stop = 0; -		if ((fadeKey->flag & 1) == 0) { -			if (fadeKey->fade == 0) { -				_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; -				_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -			} else { -				_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; -				_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); -			} -		} else { -			_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; -			_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); - -			_palFadingRed = (fadeKey->flag >> 1) & 1; -			_palFadingGreen = (fadeKey->flag >> 2) & 1; -			_palFadingBlue = (fadeKey->flag >> 3) & 1; -		} -	} - -	if (_palFadingRed) { -		_palFadingRed = !_vm->_palanim->fadeStep(1); -		stop = 0; -	} -	if (_palFadingGreen) { -		_palFadingGreen = !_vm->_palanim->fadeStep(2); -		stop = 0; -	} -	if (_palFadingBlue) { -		_palFadingBlue = !_vm->_palanim->fadeStep(3); -		stop = 0; -	} -	return stop; -} - -char Mult::doSoundAnim(char stop) { -	Mult_SndKey *sndKey; -	for (_index = 0; _index < _sndKeysCount; _index++) { -		sndKey = &_sndKeys[_index]; -		if (sndKey->frame != _frame) -			continue; - -		if (sndKey->cmd != -1) { -			if (sndKey->cmd == 1) { -				_vm->_snd->stopSound(0); -				stop = 0; -				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, -				    sndKey->freq, sndKey->channel); - -			} else if (sndKey->cmd == 4) { -				_vm->_snd->stopSound(0); -				stop = 0; -				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, -				    sndKey->freq, sndKey->channel); -			} -		} else { -			if (_vm->_snd->_playingSound) -				_vm->_snd->stopSound(sndKey->channel); -		} -	} -	return stop; -} - -void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, -	    char handleMouse) { -	char stopNoClear; -	char stop; -	Mult_Object *multObj; -	Mult_AnimData *animData; - -	if (_multData == 0) -		return; - -	stopNoClear = 0; -	_frame = startFrame; -	if (endFrame == -1) -		endFrame = 32767; - -	if (_frame == -1) { -		_doPalSubst = 0; -		_palFadingRed = 0; -		_palFadingGreen = 0; -		_palFadingBlue = 0; - -		_oldPalette = _vm->_global->_pPaletteDesc->vgaPal; -		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); - -		if (_vm->_anim->_animSurf == 0) { -			_vm->_util->setFrameRate(_frameRate); -			_vm->_anim->_areaTop = 0; -			_vm->_anim->_areaLeft = 0; -			_vm->_anim->_areaWidth = 320; -			_vm->_anim->_areaHeight = 200; -			_objCount = 4; - -			_objects = new Mult_Object[_objCount]; -			_renderData = new int16[9 * _objCount]; - -			_animArrayX = new int32[_objCount]; -			_animArrayY = new int32[_objCount]; - -			_animArrayData = new Mult_AnimData[_objCount]; - -			for (_counter = 0; _counter < _objCount; _counter++) { -				multObj = &_objects[_counter]; - -				multObj->pPosX = (int32 *)&_animArrayX[_counter]; -				multObj->pPosY = (int32 *)&_animArrayY[_counter]; - -				multObj->pAnimData = &_animArrayData[_counter]; - -				animData = multObj->pAnimData; -				animData->isStatic = 1; - -				multObj->tick = 0; -				multObj->lastLeft = -1; -				multObj->lastTop = -1; -				multObj->lastRight = -1; -				multObj->lastBottom = -1; -			} - -			_vm->_anim->_animSurf = -			    _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); -			_vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf; - -			_vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, -			    0, 0, 319, 199, 0, 0, 0); - -			_animDataAllocated = 1; -		} else -			_animDataAllocated = 0; -		_frame = 0; -	} - -	do { -		stop = 1; - -		if (VAR(58) == 0) { -			stop = drawStatics(stop); -			drawAnims(); -		} - -		animate(); -		if (handleMouse) { -			_vm->_draw->animateCursor(-1); -		} else { -			_vm->_draw->blitInvalidated(); -		} - -		if (VAR(58) == 0) { -			drawText(&stop, &stopNoClear); -		} - -		stop = prepPalAnim(stop); -		doPalAnim(); - -		stop = doFadeAnim(stop); -		stop = doSoundAnim(stop); - -		if (_frame >= endFrame) -			stopNoClear = 1; - -		if (_vm->_snd->_playingSound) -			stop = 0; - -		_vm->_util->processInput(); -		if (checkEscape && _vm->_util->checkKey() == 0x11b)	// Esc -			stop = 1; - -		_frame++; -		_vm->_util->waitEndFrame(); -	} while (stop == 0 && stopNoClear == 0); - -	if (stopNoClear == 0) { -		if (_animDataAllocated) { -			delete[] _objects; -			_objects = 0; - -			delete[] _renderData; -			_renderData = 0; - -			delete[] _animArrayX; -			_animArrayX = 0; - -			delete[] _animArrayY; -			_animArrayY = 0; - -			delete[] _animArrayData; -			_animArrayData = 0; - -			if (_vm->_anim->_animSurf) -				_vm->_video->freeSurfDesc(_vm->_anim->_animSurf); -			_vm->_anim->_animSurf = 0; - -			_animDataAllocated = 0; -		} - -		if (_vm->_snd->_playingSound != 0) -			_vm->_snd->stopSound(10); - -		WRITE_VAR(57, (uint32)-1); -	} else { -		WRITE_VAR(57, _frame - 1 - _frameStart); -	} -} -  void Mult::zeroMultData(void) {  	_multData = 0;  } diff --git a/engines/gob/mult.h b/engines/gob/mult.h index d69ee3b6c1..415675865a 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -45,6 +45,11 @@ public:  		int8 newAnimation;  		byte intersected;  		int8 newCycle; +		int8 somethingAnimation; // New in GOB2 +		int8 somethingLayer;     // New in GOB2 +		int8 somethingFrame;     // New in GOB2 +		int8 someFlag;           // New in GOB2 +		int8 field_F;            // New in GOB2  	} GCC_PACK;  	struct Mult_Object { @@ -56,6 +61,11 @@ public:  		int16 lastRight;  		int16 lastTop;  		int16 lastBottom; +		int8 someFlag;         // New in GOB2 +		int16 somethingLeft;   // New in GOB2 +		int16 somethingTop;    // New in GOB2 +		int16 somethingRight;  // New in GOB2 +		int16 somethingBottom; // New in GOB2  	};  	struct Mult_StaticKey { @@ -110,6 +120,7 @@ public:  	Mult_Object *_objects;  	int16 *_renderData; +	Mult_Object **_renderData2;  	int16 _objCount;  	Video::SurfaceDesc *_underAnimSurf; @@ -173,12 +184,11 @@ public:  	int16 _sndKeysCount;  	Mult_SndKey *_sndKeys; +	int8 *_orderArray; +  	void zeroMultData(void);  	void freeMultKeys(void);  	void checkFreeMult(void); -	void playMult(int16 startFrame, int16 endFrame, char checkEscape, -				  char handleMouse); -	void animate(void);  	void interGetObjAnimSize(void);  	void freeMult(void);  	void interLoadMult(void); @@ -189,6 +199,9 @@ public:  	virtual void setMultData(uint16 multindex) = 0;  	virtual void loadMult(int16 resId) = 0; +	virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, +				  char handleMouse) = 0; +	virtual void animate(void) = 0;  	Mult(GobEngine *vm);  	virtual ~Mult() {}; @@ -197,13 +210,13 @@ protected:  	Video::Color _fadePal[5][16];  	GobEngine *_vm; -	char drawStatics(char stop); -	void drawAnims(void); -	void drawText(char *pStop, char *pStopNoClear); -	char prepPalAnim(char stop); -	void doPalAnim(void); -	char doFadeAnim(char stop); -	char doSoundAnim(char stop); +	virtual char drawStatics(char stop) = 0; +	virtual char drawAnims(char stop) = 0; +	virtual void drawText(char *pStop, char *pStopNoClear) = 0; +	virtual char prepPalAnim(char stop) = 0; +	virtual void doPalAnim(void) = 0; +	virtual char doFadeAnim(char stop) = 0; +	virtual char doSoundAnim(char stop) = 0;  };  class Mult_v1 : public Mult { @@ -213,6 +226,18 @@ public:  	virtual void setMultData(uint16 multindex);  	virtual void loadMult(int16 resId); +	virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, +				  char handleMouse); +	virtual void animate(void); + +protected: +	virtual char drawStatics(char stop); +	virtual char drawAnims(char stop); +	virtual void drawText(char *pStop, char *pStopNoClear); +	virtual char prepPalAnim(char stop); +	virtual void doPalAnim(void); +	virtual char doFadeAnim(char stop); +	virtual char doSoundAnim(char stop);  };  class Mult_v2 : public Mult_v1 { @@ -250,6 +275,7 @@ public:  		int16 frameRate;        		Video::Color fadePal[5][16]; +		int16 field_124[4][4]; // Not sure here either  		int16 palAnimIndices[4]; // Not sure here either  		int16 frameStart; @@ -278,6 +304,21 @@ public:  	virtual void setMultData(uint16 multindex);  	virtual void loadMult(int16 resId); +	virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, +				  char handleMouse); +	virtual void animate(void); + +protected: +	virtual char drawStatics(char stop); +	virtual char drawAnims(char stop); +	virtual void drawText(char *pStop, char *pStopNoClear); +	virtual char prepPalAnim(char stop); +	virtual void doPalAnim(void); +	virtual char doFadeAnim(char stop); +	virtual char doSoundAnim(char stop); + +	void sub_62DD(int16 index); +	void sub_6A35(void);  };  }				// End of namespace Gob diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index a35ca3f321..a3d1c82b66 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -30,6 +30,9 @@  #include "gob/scenery.h"  #include "gob/global.h"  #include "gob/inter.h" +#include "gob/anim.h" +#include "gob/draw.h" +#include "gob/palanim.h"  namespace Gob { @@ -204,4 +207,702 @@ void Mult_v1::setMultData(uint16 multindex) {  	error("Switching mults not supported for Gob1");  } +void Mult_v1::playMult(int16 startFrame, int16 endFrame, char checkEscape, +	    char handleMouse) { +	char stopNoClear; +	char stop; +	Mult_Object *multObj; +	Mult_AnimData *animData; + +	if (_multData == 0) +		return; + +	stopNoClear = 0; +	_frame = startFrame; +	if (endFrame == -1) +		endFrame = 32767; + +	if (_frame == -1) { +		_doPalSubst = 0; +		_palFadingRed = 0; +		_palFadingGreen = 0; +		_palFadingBlue = 0; + +		_oldPalette = _vm->_global->_pPaletteDesc->vgaPal; +		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); + +		if (_vm->_anim->_animSurf == 0) { +			_vm->_util->setFrameRate(_frameRate); +			_vm->_anim->_areaTop = 0; +			_vm->_anim->_areaLeft = 0; +			_vm->_anim->_areaWidth = 320; +			_vm->_anim->_areaHeight = 200; +			_objCount = 4; + +			_objects = new Mult_Object[_objCount]; +			_renderData = new int16[9 * _objCount]; + +			_animArrayX = new int32[_objCount]; +			_animArrayY = new int32[_objCount]; + +			_animArrayData = new Mult_AnimData[_objCount]; + +			for (_counter = 0; _counter < _objCount; _counter++) { +				multObj = &_objects[_counter]; + +				multObj->pPosX = (int32 *)&_animArrayX[_counter]; +				multObj->pPosY = (int32 *)&_animArrayY[_counter]; + +				multObj->pAnimData = &_animArrayData[_counter]; + +				animData = multObj->pAnimData; +				animData->isStatic = 1; + +				multObj->tick = 0; +				multObj->lastLeft = -1; +				multObj->lastTop = -1; +				multObj->lastRight = -1; +				multObj->lastBottom = -1; +			} + +			_vm->_anim->_animSurf = +			    _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); +			_vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf; + +			_vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, +			    0, 0, 319, 199, 0, 0, 0); + +			_animDataAllocated = 1; +		} else +			_animDataAllocated = 0; +		_frame = 0; +	} + +	do { +		stop = 1; + +		if (VAR(58) == 0) { +			stop = drawStatics(stop); +			stop = drawAnims(stop); +		} + +		animate(); +		if (handleMouse) { +			_vm->_draw->animateCursor(-1); +		} else { +			_vm->_draw->blitInvalidated(); +		} + +		if (VAR(58) == 0) { +			drawText(&stop, &stopNoClear); +		} + +		stop = prepPalAnim(stop); +		doPalAnim(); + +		stop = doFadeAnim(stop); +		stop = doSoundAnim(stop); + +		if (_frame >= endFrame) +			stopNoClear = 1; + +		if (_vm->_snd->_playingSound) +			stop = 0; + +		_vm->_util->processInput(); +		if (checkEscape && _vm->_util->checkKey() == 0x11b)	// Esc +			stop = 1; + +		_frame++; +		_vm->_util->waitEndFrame(); +	} while (stop == 0 && stopNoClear == 0); + +	if (stopNoClear == 0) { +		if (_animDataAllocated) { +			delete[] _objects; +			_objects = 0; + +			delete[] _renderData; +			_renderData = 0; + +			delete[] _animArrayX; +			_animArrayX = 0; + +			delete[] _animArrayY; +			_animArrayY = 0; + +			delete[] _animArrayData; +			_animArrayData = 0; + +			if (_vm->_anim->_animSurf) +				_vm->_video->freeSurfDesc(_vm->_anim->_animSurf); +			_vm->_anim->_animSurf = 0; + +			_animDataAllocated = 0; +		} + +		if (_vm->_snd->_playingSound != 0) +			_vm->_snd->stopSound(10); + +		WRITE_VAR(57, (uint32)-1); +	} else { +		WRITE_VAR(57, _frame - 1 - _frameStart); +	} +} + +char Mult_v1::drawStatics(char stop) { +	if (_staticKeys[_staticKeysCount - 1].frame > _frame) +		stop = 0; + +	for (_counter = 0; _counter < _staticKeysCount; +	    _counter++) { +		if (_staticKeys[_counter].frame != _frame +		    || _staticKeys[_counter].layer == -1) +			continue; + +		for (_vm->_scenery->_curStatic = 0, _vm->_scenery->_curStaticLayer = _staticKeys[_counter].layer; +			 _vm->_scenery->_curStaticLayer >= _vm->_scenery->_statics[_staticIndices[_vm->_scenery->_curStatic]].layersCount; +			 _vm->_scenery->_curStatic++) { +			_vm->_scenery->_curStaticLayer -= +			    _vm->_scenery->_statics[_staticIndices[_vm->_scenery->_curStatic]].layersCount; +		} + +		_vm->_scenery->_curStatic = _staticIndices[_vm->_scenery->_curStatic]; +		_vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); +		_vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, +		    0, 0, 319, 199, 0, 0, 0); +	} +	return stop; +} + +char Mult_v1::drawAnims(char stop) { +	Mult_AnimKey *key; +	Mult_Object *animObj; +	int16 i; +	int16 count; + +	for (_index = 0; _index < 4; _index++) { +		for (_counter = 0; _counter < _animKeysCount[_index]; _counter++) { +			key = &_animKeys[_index][_counter]; +			animObj = &_objects[_index]; +			if (key->frame != _frame) +				continue; + +			if (key->layer != -1) { +				(*animObj->pPosX) = key->posX; +				(*animObj->pPosY) = key->posY; + +				animObj->pAnimData->frame = 0; +				animObj->pAnimData->order = key->order; +				animObj->pAnimData->animType = 1; + +				animObj->pAnimData->isPaused = 0; +				animObj->pAnimData->isStatic = 0; +				animObj->pAnimData->maxTick = 0; +				animObj->tick = 0; +				animObj->pAnimData->layer = key->layer; + +				count = _vm->_scenery->_animations[_animIndices[0]].layersCount; +				i = 0; +				while (animObj->pAnimData->layer >= count) { +					animObj->pAnimData->layer -= count; +					i++; + +					count = _vm->_scenery->_animations[_animIndices[i]].layersCount; +				} +				animObj->pAnimData->animation = _animIndices[i]; +			} else { +				animObj->pAnimData->isStatic = 1; +			} +		} +	} +	return stop; +} + +void Mult_v1::drawText(char *pStop, char *pStopNoClear) { +	char *savedIP; + +	int16 cmd; +	for (_index = 0; _index < _textKeysCount; _index++) { +		if (_textKeys[_index].frame != _frame) +			continue; + +		cmd = _textKeys[_index].cmd; +		if (cmd == 0) { +			*pStop = 0; +		} else if (cmd == 1) { +			*pStopNoClear = 1; +			_frameStart = 0; +		} else if (cmd == 3) { +			*pStop = 0; +			savedIP = _vm->_global->_inter_execPtr; +			_vm->_global->_inter_execPtr = (char *)(&_textKeys[_index].index); +			_vm->_global->_inter_execPtr = savedIP; +		} +	} +} + +char Mult_v1::prepPalAnim(char stop) { +	_palKeyIndex = -1; +	do { +		_palKeyIndex++; +		if (_palKeyIndex >= _palKeysCount) +			return stop; +	} while (_palKeys[_palKeyIndex].frame != _frame); + +	if (_palKeys[_palKeyIndex].cmd == -1) { +		stop = 0; +		_doPalSubst = 0; +		_vm->_global->_pPaletteDesc->vgaPal = _oldPalette; + +		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); + +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +	} else { +		stop = 0; +		_doPalSubst = 1; +		_palAnimKey = _palKeyIndex; + +		_palAnimIndices[0] = 0; +		_palAnimIndices[1] = 0; +		_palAnimIndices[2] = 0; +		_palAnimIndices[3] = 0; + +		_vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; +	} +	return stop; +} + +void Mult_v1::doPalAnim(void) { +	int16 off; +	int16 off2; +	Video::Color *palPtr; +	Mult_PalKey *palKey; + +	if (_doPalSubst == 0) +		return; + +	for (_index = 0; _index < 4; _index++) { +		palKey = &_palKeys[_palAnimKey]; + +		if ((_frame % palKey->rates[_index]) != 0) +			continue; + +		_palAnimRed[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; +		_palAnimGreen[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; +		_palAnimBlue[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; + +		while (1) { +			off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index]; +			if (off == 0) { +				off = palKey->subst[_palAnimIndices[_index]][_index] - 1; + +				_vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; +				_vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; +				_vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; +			} else { +				off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index] - 1; +				off2 = palKey->subst[_palAnimIndices[_index]][_index] - 1; + +				_vm->_global->_pPaletteDesc->vgaPal[off2].red = _vm->_global->_pPaletteDesc->vgaPal[off].red; +				_vm->_global->_pPaletteDesc->vgaPal[off2].green = _vm->_global->_pPaletteDesc->vgaPal[off].green; +				_vm->_global->_pPaletteDesc->vgaPal[off2].blue = _vm->_global->_pPaletteDesc->vgaPal[off].blue; +			} + +			_palAnimIndices[_index] = (_palAnimIndices[_index] + 1) % 16; + +			off = palKey->subst[_palAnimIndices[_index]][_index]; + +			if (off == 0) { +				_palAnimIndices[_index] = 0; +				off = palKey->subst[0][_index] - 1; + +				_palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; +				_palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; +				_palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; +			} +			if (_palAnimIndices[_index] == 0) +				break; +		} +	} + +	if (_vm->_global->_colorCount == 256) { +		_vm->_video->waitRetrace(_vm->_global->_videoMode); + +		palPtr = _vm->_global->_pPaletteDesc->vgaPal; +		for (_counter = 0; _counter < 16; _counter++) { +			_vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, palPtr->blue, 0, 0x13); +			palPtr++; +		} + +		palPtr = _vm->_global->_pPaletteDesc->vgaPal; +		for (_counter = 0; _counter < 16; _counter++) { +			_vm->_global->_redPalette[_counter] = palPtr->red; +			_vm->_global->_greenPalette[_counter] = palPtr->green; +			_vm->_global->_bluePalette[_counter] = palPtr->blue; +			palPtr++; +		} +	} else { +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +	} +} + +char Mult_v1::doFadeAnim(char stop) { +	Mult_PalFadeKey *fadeKey; + +	for (_index = 0; _index < _palFadeKeysCount; _index++) { +		fadeKey = &_palFadeKeys[_index]; + +		if (fadeKey->frame != _frame) +			continue; + +		stop = 0; +		if ((fadeKey->flag & 1) == 0) { +			if (fadeKey->fade == 0) { +				_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; +				_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +			} else { +				_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; +				_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); +			} +		} else { +			_vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; +			_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); + +			_palFadingRed = (fadeKey->flag >> 1) & 1; +			_palFadingGreen = (fadeKey->flag >> 2) & 1; +			_palFadingBlue = (fadeKey->flag >> 3) & 1; +		} +	} + +	if (_palFadingRed) { +		_palFadingRed = !_vm->_palanim->fadeStep(1); +		stop = 0; +	} +	if (_palFadingGreen) { +		_palFadingGreen = !_vm->_palanim->fadeStep(2); +		stop = 0; +	} +	if (_palFadingBlue) { +		_palFadingBlue = !_vm->_palanim->fadeStep(3); +		stop = 0; +	} +	return stop; +} + +char Mult_v1::doSoundAnim(char stop) { +	Mult_SndKey *sndKey; +	for (_index = 0; _index < _sndKeysCount; _index++) { +		sndKey = &_sndKeys[_index]; +		if (sndKey->frame != _frame) +			continue; + +		if (sndKey->cmd != -1) { +			if (sndKey->cmd == 1) { +				_vm->_snd->stopSound(0); +				stop = 0; +				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, +				    sndKey->freq, sndKey->channel); + +			} else if (sndKey->cmd == 4) { +				_vm->_snd->stopSound(0); +				stop = 0; +				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, +				    sndKey->freq, sndKey->channel); +			} +		} else { +			if (_vm->_snd->_playingSound) +				_vm->_snd->stopSound(sndKey->channel); +		} +	} +	return stop; +} + +void Mult_v1::animate(void) { +	int16 minOrder; +	int16 maxOrder; +	int16 *pCurLefts; +	int16 *pCurRights; +	int16 *pCurTops; +	int16 *pCurBottoms; +	int16 *pDirtyLefts; +	int16 *pDirtyRights; +	int16 *pDirtyTops; +	int16 *pDirtyBottoms; +	int16 *pNeedRedraw; +	Mult_AnimData *pAnimData; +	int16 i, j; +	int16 order; + +	if (_renderData == 0) +		return; + +	pDirtyLefts = _renderData; +	pDirtyRights = pDirtyLefts + _objCount; +	pDirtyTops = pDirtyRights + _objCount; +	pDirtyBottoms = pDirtyTops + _objCount; +	pNeedRedraw = pDirtyBottoms + _objCount; +	pCurLefts = pNeedRedraw + _objCount; +	pCurRights = pCurLefts + _objCount; +	pCurTops = pCurRights + _objCount; +	pCurBottoms = pCurTops + _objCount; +	minOrder = 100; +	maxOrder = 0; + +	//Find dirty areas +	for (i = 0; i < _objCount; i++) { +		pNeedRedraw[i] = 0; +		pDirtyTops[i] = 1000; +		pDirtyLefts[i] = 1000; +		pDirtyBottoms[i] = 1000; +		pDirtyRights[i] = 1000; +		pAnimData = _objects[i].pAnimData; + +		if (pAnimData->isStatic == 0 && pAnimData->isPaused == 0 && +		    _objects[i].tick == pAnimData->maxTick) { +			if (pAnimData->order < minOrder) +				minOrder = pAnimData->order; + +			if (pAnimData->order > maxOrder) +				maxOrder = pAnimData->order; + +			pNeedRedraw[i] = 1; +			_vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, +			    pAnimData->animation, 0, +			    *(_objects[i].pPosX), *(_objects[i].pPosY), +			    0); + +			if (_objects[i].lastLeft != -1) { +				pDirtyLefts[i] = +				    MIN(_objects[i].lastLeft, +				    _vm->_scenery->_toRedrawLeft); +				pDirtyTops[i] = +				    MIN(_objects[i].lastTop, +				    _vm->_scenery->_toRedrawTop); +				pDirtyRights[i] = +				    MAX(_objects[i].lastRight, +				    _vm->_scenery->_toRedrawRight); +				pDirtyBottoms[i] = +				    MAX(_objects[i].lastBottom, +				    _vm->_scenery->_toRedrawBottom); +			} else { +				pDirtyLefts[i] = _vm->_scenery->_toRedrawLeft; +				pDirtyTops[i] = _vm->_scenery->_toRedrawTop; +				pDirtyRights[i] = _vm->_scenery->_toRedrawRight; +				pDirtyBottoms[i] = _vm->_scenery->_toRedrawBottom; +			} +			pCurLefts[i] = _vm->_scenery->_toRedrawLeft; +			pCurRights[i] = _vm->_scenery->_toRedrawRight; +			pCurTops[i] = _vm->_scenery->_toRedrawTop; +			pCurBottoms[i] = _vm->_scenery->_toRedrawBottom; +		} else { +			if (_objects[i].lastLeft != -1) { +				if (pAnimData->order < minOrder) +					minOrder = pAnimData->order; + +				if (pAnimData->order > maxOrder) +					maxOrder = pAnimData->order; + +				if (pAnimData->isStatic) +					*pNeedRedraw = 1; + +				pCurLefts[i] = _objects[i].lastLeft; +				pDirtyLefts[i] = _objects[i].lastLeft; + +				pCurTops[i] = _objects[i].lastTop; +				pDirtyTops[i] = _objects[i].lastTop; + +				pCurRights[i] = _objects[i].lastRight; +				pDirtyRights[i] = _objects[i].lastRight; + +				pCurBottoms[i] = _objects[i].lastBottom; +				pDirtyBottoms[i] = _objects[i].lastBottom; +			} +		} +	} + +	// Find intersections +	for (i = 0; i < _objCount; i++) { +		pAnimData = _objects[i].pAnimData; +		pAnimData->intersected = 200; + +		if (pAnimData->isStatic) +			continue; + +		for (j = 0; j < _objCount; j++) { +			if (i == j) +				continue; + +			if (_objects[j].pAnimData->isStatic) +				continue; + +			if (pCurRights[i] < pCurLefts[j]) +				continue; + +			if (pCurRights[j] < pCurLefts[i]) +				continue; + +			if (pCurBottoms[i] < pCurTops[j]) +				continue; + +			if (pCurBottoms[j] < pCurTops[i]) +				continue; + +			pAnimData->intersected = j; +			break; +		} +	} + +	// Restore dirty areas +	for (i = 0; i < _objCount; i++) { + +		if (pNeedRedraw[i] == 0 || _objects[i].lastLeft == -1) +			continue; + +		_vm->_draw->_sourceSurface = 22; +		_vm->_draw->_destSurface = 21; +		_vm->_draw->_spriteLeft = pDirtyLefts[i] - _vm->_anim->_areaLeft; +		_vm->_draw->_spriteTop = pDirtyTops[i] - _vm->_anim->_areaTop; +		_vm->_draw->_spriteRight = pDirtyRights[i] - pDirtyLefts[i] + 1; +		_vm->_draw->_spriteBottom = pDirtyBottoms[i] - pDirtyTops[i] + 1; +		_vm->_draw->_destSpriteX = pDirtyLefts[i]; +		_vm->_draw->_destSpriteY = pDirtyTops[i]; +		_vm->_draw->_transparency = 0; +		_vm->_draw->spriteOperation(DRAW_BLITSURF); +		_objects[i].lastLeft = -1; +	} + +	// Update view +	for (order = minOrder; order <= maxOrder; order++) { +		for (i = 0; i < _objCount; i++) { +			pAnimData = _objects[i].pAnimData; +			if (pAnimData->order != order) +				continue; + +			if (pNeedRedraw[i]) { +				if (pAnimData->isStatic == 0) { + +					_vm->_scenery->updateAnim(pAnimData->layer, +					    pAnimData->frame, +					    pAnimData->animation, 2, +					    *(_objects[i].pPosX), +					    *(_objects[i].pPosY), 1); + +					if (_vm->_scenery->_toRedrawLeft != -12345) { +						_objects[i].lastLeft = +						    _vm->_scenery->_toRedrawLeft; +						_objects[i].lastTop = +						    _vm->_scenery->_toRedrawTop; +						_objects[i].lastRight = +						    _vm->_scenery->_toRedrawRight; +						_objects[i].lastBottom = +						    _vm->_scenery->_toRedrawBottom; +					} else { +						_objects[i].lastLeft = -1; +					} +				} +				_vm->_scenery->updateStatic(order + 1); +			} else if (pAnimData->isStatic == 0) { +				for (j = 0; j < _objCount; j++) { +					if (pNeedRedraw[j] == 0) +						continue; + +					if (pDirtyRights[i] < pDirtyLefts[j]) +						continue; + +					if (pDirtyRights[j] < pDirtyLefts[i]) +						continue; + +					if (pDirtyBottoms[i] < pDirtyTops[j]) +						continue; + +					if (pDirtyBottoms[j] < pDirtyTops[i]) +						continue; + +					_vm->_scenery->_toRedrawLeft = pDirtyLefts[j]; +					_vm->_scenery->_toRedrawRight = pDirtyRights[j]; +					_vm->_scenery->_toRedrawTop = pDirtyTops[j]; +					_vm->_scenery->_toRedrawBottom = pDirtyBottoms[j]; + +					_vm->_scenery->updateAnim(pAnimData->layer, +					    pAnimData->frame, +					    pAnimData->animation, 4, +					    *(_objects[i].pPosX), +					    *(_objects[i].pPosY), 1); + +					_vm->_scenery->updateStatic(order + 1); +				} +			} +		} +	} + +	// Advance animations +	for (i = 0; i < _objCount; i++) { +		pAnimData = _objects[i].pAnimData; +		if (pAnimData->isStatic || pAnimData->isPaused) +			continue; + +		if (_objects[i].tick == pAnimData->maxTick) { +			_objects[i].tick = 0; +			if (pAnimData->animType == 4) { +				pAnimData->isPaused = 1; +				pAnimData->frame = 0; +			} else { +				pAnimData->frame++; +				if (pAnimData->frame >= +				    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->framesCount) { +					switch (pAnimData->animType) { +					case 0: +						pAnimData->frame = 0; +						break; + +					case 1: +						pAnimData->frame = 0; + +						*(_objects[i].pPosX) = +						    *(_objects[i].pPosX) + +						    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->animDeltaX; + +						*(_objects[i].pPosY) = +						    *(_objects[i].pPosY) + +						    _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer]->animDeltaY; +						break; + +					case 2: +						pAnimData->frame = 0; +						pAnimData->animation = +						    pAnimData->newAnimation; +						pAnimData->layer = +						    pAnimData->newLayer; +						break; + +					case 3: +						pAnimData->animType = 4; +						pAnimData->frame = 0; +						break; + +					case 5: +						pAnimData->isStatic = 1; +						pAnimData->frame = 0; +						break; + +					case 6: +						pAnimData->frame--; +						pAnimData->isPaused = 1; +						break; +					} +					pAnimData->newCycle = 1; +				} else { +					pAnimData->newCycle = 0; +				} +			} +		} else { +			_objects[i].tick++; +		} +	} +} +  } // End of namespace Gob diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 899acc1592..000d7d02ce 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1,4 +1,4 @@ -/* ScummVM - Scumm Interpreter +	/* ScummVM - Scumm Interpreter   * Copyright (C) 2004 Ivan Dubrov   * Copyright (C) 2004-2006 The ScummVM project   * @@ -30,10 +30,16 @@  #include "gob/scenery.h"  #include "gob/global.h"  #include "gob/inter.h" +#include "gob/anim.h" +#include "gob/draw.h" +#include "gob/palanim.h"  namespace Gob {  Mult_v2::Mult_v2(GobEngine *vm) : Mult_v1(vm) { +	int i; + +	for (i = 0; i < 8; i++) _multDatas[i] = 0;  }  void Mult_v2::loadMult(int16 resId) { @@ -52,7 +58,7 @@ void Mult_v2::loadMult(int16 resId) {  	_multDatas[index] = _multData2;  	for (i = 0; i < 4; i++) -		_multData2->palAnimIndices[i] = i; +		_multData2->field_124[0][i] = i;  	_multData2->sndSlotsCount = 0;  	_multData2->frameStart = 0; @@ -60,8 +66,8 @@ void Mult_v2::loadMult(int16 resId) {  	extData = _vm->_game->loadExtData(resId, 0, 0);  	_dataPtr = extData; -	staticCount = _dataPtr[0]; -	animCount = _dataPtr[1]; +	_multData2->staticCount = staticCount = _dataPtr[0]; +	_multData2->animCount = animCount = _dataPtr[1];  	_dataPtr += 2;  	staticCount++;  	animCount++; @@ -167,8 +173,6 @@ void Mult_v2::loadMult(int16 resId) {  	}  	_multData2->textKeysCount = READ_LE_UINT16(_dataPtr); - -	_multData2->textKeysCount = READ_LE_UINT16(_dataPtr);  	_dataPtr += 2;  	_multData2->textKeys = new Mult_TextKey[_multData2->textKeysCount]; @@ -186,10 +190,7 @@ void Mult_v2::loadMult(int16 resId) {  	warning("SoundKeyCount: %d", _multData2->sndKeysCount); -	// TODO: There's still something wrong here, preventing GOB2 floppy -	//       to start correctly  	for (i = 0; i < _multData2->sndKeysCount; i++) { -		warning("-> %d", i);  		_multData2->sndKeys[i].frame = (int16)READ_LE_UINT16(_dataPtr);  		_multData2->sndKeys[i].cmd = (int16)READ_LE_UINT16(_dataPtr + 2);  		_multData2->sndKeys[i].freq = (int16)READ_LE_UINT16(_dataPtr + 4); @@ -208,25 +209,18 @@ void Mult_v2::loadMult(int16 resId) {  		case 1:  		case 4:  			_multData2->sndKeys[i].resId = READ_LE_UINT16(_vm->_global->_inter_execPtr); - -			for (j = 0; j < i; j++) { -				if (_multData2->sndKeys[i].resId == -				    _multData2->sndKeys[j].resId) { -					_multData2->sndKeys[i].soundIndex = -					    _multData2->sndKeys[j].soundIndex; +			for (j = 0; j < i; j++) { // loc_7071 +				if (_multData2->sndKeys[j].resId == _multData2->sndKeys[i].resId) { +					_multData2->sndKeys[i].soundIndex = _multData2->sndKeys[j].soundIndex;  					_vm->_global->_inter_execPtr += 2;  					break;  				}  			}  			if (i == j) { -				warning("GOB2 Stub! Mult_Data.sndSlot"); -				warning("GOB2 Stub! Game::interLoadSound() differs");  				_multData2->sndSlot[_multData2->sndSlotsCount] = _vm->_inter->loadSound(1); -				_vm->_inter->loadSound(1); -				// _multData2->sndKeys[i].soundIndex = _multData2->sndSlot[_multData2->sndSlotsCount] & 0x7FFF; +				_multData2->sndKeys[i].soundIndex = _multData2->sndSlot[_multData2->sndSlotsCount] & 0x7FFF;  				_multData2->sndSlotsCount++;  			} -  			break;  		case 3:  			_vm->_global->_inter_execPtr += 4; @@ -277,4 +271,874 @@ void Mult_v2::setMultData(uint16 multindex) {  	_multData2 = _multDatas[multindex];  } +void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, +	    char handleMouse) { +	char stopNoClear; +	char stop; +	Mult_Object *multObj; +	Mult_AnimData *animData; + +	if (_multData2 == 0) +		return; + +	stopNoClear = 0; +	_frame = startFrame; +	if (endFrame == -1) +		endFrame = 32767; + +	if (_frame == -1) { +		_doPalSubst = 0; +		_palFadingRed = 0; +		_palFadingGreen = 0; +		_palFadingBlue = 0; + +		_oldPalette = _vm->_global->_pPaletteDesc->vgaPal; +//		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); + +		if (_vm->_anim->_animSurf == 0) { +			_vm->_util->setFrameRate(_multData2->frameRate); +			_vm->_anim->_areaTop = 0; +			_vm->_anim->_areaLeft = 0; +			_vm->_anim->_areaWidth = 320; +			_vm->_anim->_areaHeight = 200; +			_objCount = 4; + +			_objects = new Mult_Object[_objCount]; +			_orderArray = new int8[_objCount]; +			_renderData = new int16[9 * _objCount]; +			_renderData2 = new Mult_Object*[_objCount]; + +			_animArrayX = new int32[_objCount]; +			_animArrayY = new int32[_objCount]; + +			_animArrayData = new Mult_AnimData[_objCount]; + +			for (_counter = 0; _counter < _objCount; _counter++) { +				multObj = &_objects[_counter]; + +				multObj->pPosX = (int32 *)&_animArrayX[_counter]; +				multObj->pPosY = (int32 *)&_animArrayY[_counter]; + +				multObj->pAnimData = &_animArrayData[_counter]; + +				animData = multObj->pAnimData; +				animData->isStatic = 1; + +				multObj->tick = 0; +				multObj->lastLeft = -1; +				multObj->lastTop = -1; +				multObj->lastRight = -1; +				multObj->lastBottom = -1; +			} + +			_vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 0); + +			if ((_vm->_global->_videoMode == 0x14) && +				((_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2 +					+ (_vm->_anim->_areaWidth * _vm->_anim->_areaHeight) / 4) < 64000) { +				_vm->_anim->_animSurf = new Video::SurfaceDesc; +				memcpy(_vm->_anim->_animSurf, _vm->_draw->_frontSurface, sizeof(Video::SurfaceDesc)); +				_vm->_anim->_animSurf->width = (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1) | 7; +				_vm->_anim->_animSurf->width -= (_vm->_anim->_areaLeft & 0x0FFF8) - 1; +				_vm->_anim->_animSurf->height = _vm->_anim->_areaHeight; +				_vm->_anim->_animSurf->vidPtr += +					(_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2; +			} else +				_vm->_draw->initBigSprite(22, _vm->_anim->_areaHeight, _vm->_anim->_areaWidth, 0); +		 +			_vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 1); +			_vm->_draw->_sourceSurface = 21; +			_vm->_draw->_destSurface = 22; +			_vm->_draw->_destSpriteX = 0; +			_vm->_draw->_destSpriteY = 0; +			_vm->_draw->_spriteLeft = 0; +			_vm->_draw->_spriteTop = 0; +			_vm->_draw->_spriteRight= 320; +			_vm->_draw->_spriteBottom = 200; +			_vm->_draw->_transparency = 0; +			_vm->_draw->spriteOperation(0); +			_animDataAllocated = 1; + +			for (_counter = 0; _counter < _objCount; _counter++) { +				_multData2->palAnimIndices[_counter] = _counter; +			} + +			_animDataAllocated = 1; +		} else +			_animDataAllocated = 0; +		_frame = 0; +	} + +	do { +		stop = 1; + +		if (VAR(58) == 0) { +			stop = drawStatics(stop); +			stop = drawAnims(stop); +		} + +		animate(); +		if (handleMouse) { +			_vm->_draw->animateCursor(-1); +		} else { +			_vm->_draw->blitInvalidated(); +		} + +		if (VAR(58) == 0) { +			drawText(&stop, &stopNoClear); +		} + +		stop = prepPalAnim(stop); +		doPalAnim(); + +		stop = doFadeAnim(stop); +		stop = doSoundAnim(stop); + +		if (_frame >= endFrame) +			stopNoClear = 1; + +		if (_vm->_snd->_playingSound) +			stop = 0; + +		_vm->_util->processInput(); +		if (checkEscape && _vm->_util->checkKey() == 0x11b)	// Esc +			stop = 1; + +		_frame++; +		_vm->_util->waitEndFrame(); +	} while (stop == 0 && stopNoClear == 0); + +	if (stopNoClear == 0) { +		if (_animDataAllocated) { +			delete[] _objects; +			_objects = 0; + +			delete[] _renderData2; +			_renderData2 = 0; + +			delete[] _animArrayX; +			_animArrayX = 0; + +			delete[] _animArrayY; +			_animArrayY = 0; + +			delete[] _animArrayData; +			_animArrayData = 0; + +			if (_vm->_anim->_animSurf) +				_vm->_video->freeSurfDesc(_vm->_anim->_animSurf); +			_vm->_anim->_animSurf = 0; + +			_animDataAllocated = 0; +		} + +		if (_vm->_snd->_playingSound != 0) +			_vm->_snd->stopSound(10); + +		WRITE_VAR(57, (uint32)-1); +	} else { +		WRITE_VAR(57, _frame - 1 - _frameStart); +	} +} + +char Mult_v2::drawStatics(char stop) { +	int i; + +	if (_multData2->staticKeys[_multData2->staticKeysCount - 1].frame > _frame) +		stop = 0; + +	for (_counter = 0; _counter < _multData2->staticKeysCount; _counter++) { +		if (_multData2->staticKeys[_counter].frame != _frame +		    || _multData2->staticKeys[_counter].layer == -1) +			continue; + +		// loc_4FA8 +		if (_multData2->staticKeys[_counter].layer >= 0) { +			_vm->_scenery->_curStatic = 0; +			_vm->_scenery->_curStaticLayer = _multData2->staticKeys[_counter].layer; +			 +			i = 0; +			while (_vm->_scenery->_statics[_multData2->staticIndices[i]].layersCount <= _vm->_scenery->_curStaticLayer) { +				_vm->_scenery->_curStaticLayer -= +					_vm->_scenery->_statics[_multData2->staticIndices[i]].layersCount; +				i++; +				_vm->_scenery->_curStatic++; +			} +			_vm->_scenery->_curStatic = _multData2->staticIndices[_vm->_scenery->_curStatic]; +			_vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); +		} else { +			_vm->_draw->_spriteLeft = +				READ_LE_UINT16(_multData2->execPtr + ((-_multData2->staticKeys[_counter].layer - 2) * 2)); +			_vm->_draw->_destSpriteX = 0; +			_vm->_draw->_destSpriteY = 0; +			_vm->_draw->_destSurface = 21; +			_vm->_draw->_transparency = 0; +			_vm->_draw->spriteOperation(5); +			_vm->_scenery->_curStatic = -1; +		} +		_vm->_draw->_sourceSurface = 21; +		_vm->_draw->_destSurface = 22; +		_vm->_draw->_destSpriteX = 0; +		_vm->_draw->_destSpriteY = 0; +		_vm->_draw->_spriteLeft = 0; +		_vm->_draw->_spriteTop = 0; +		_vm->_draw->_spriteRight = 320; +		_vm->_draw->_spriteBottom = 200; +		_vm->_draw->_transparency = 0; +		_vm->_draw->spriteOperation(0); +	} +	return stop; +} + +char Mult_v2::drawAnims(char stop) { // loc_50D5 +	Mult_AnimKey *key; +	Mult_Object *animObj; +	int16 i; +	int16 count; +	 +	for (i = 0; i < 4; i++) { +		if (_multData2->animKeys[i][_multData2->animKeysCount[i] - 1].frame > _frame) +			stop = 0; +	} + +	for (_index = 0; _index < 4; _index++) { +		for (_counter = 0; _counter < _multData2->animKeysCount[_index]; _counter++) { +			key = &_multData2->animKeys[_index][_counter]; +			animObj = &_objects[_multData2->field_124[0][_index]]; +			if (key->frame != _frame) +				continue; +			 +			if (key->layer != -1) { +				(*animObj->pPosX) = key->posX; +				(*animObj->pPosY) = key->posY; + +				animObj->pAnimData->frame = 0; +				animObj->pAnimData->order = key->order; +				animObj->pAnimData->animType = 1; + +				animObj->pAnimData->isPaused = 0; +				animObj->pAnimData->isStatic = 0; +				animObj->pAnimData->maxTick = 0; +				animObj->tick = 0; +				animObj->pAnimData->layer = key->layer; + +				count = _vm->_scenery->_animations[_multData2->animIndices[0]].layersCount; +				i = 0; +				while (animObj->pAnimData->layer >= count) { +					animObj->pAnimData->layer -= count; +					i++; + +					count = _vm->_scenery->_animations[_multData2->animIndices[i]].layersCount; +				} +				animObj->pAnimData->animation = _multData2->animIndices[i]; +			} else { +				animObj->pAnimData->isStatic = 1; +			} +		} +	} + +	return stop; +} + +void Mult_v2::drawText(char *pStop, char *pStopNoClear) { +	char *savedIP; + +	int16 cmd; +	for (_index = 0; _index < _multData2->textKeysCount; _index++) { +		if (_multData2->textKeys[_index].frame != _frame) +			continue; + +		cmd = _multData2->textKeys[_index].cmd; +		if (cmd == 0) { +			*pStop = 0; +		} else if (cmd == 1) { +			*pStopNoClear = 1; +			_frameStart = 0; +		} else if (cmd == 3) { +			*pStop = 0; +			savedIP = _vm->_global->_inter_execPtr; +			_vm->_global->_inter_execPtr = (char *)(&_multData2->textKeys[_index].index); +			_vm->_global->_inter_execPtr = savedIP; +		} +	} +} + +char Mult_v2::prepPalAnim(char stop) { +	_palKeyIndex = -1; +	do { +		_palKeyIndex++; +		if (_palKeyIndex >= _multData2->palKeysCount) +			return stop; +	} while (_multData2->palKeys[_palKeyIndex].frame != _frame); + +	if (_multData2->palKeys[_palKeyIndex].cmd == -1) { +		stop = 0; +		_doPalSubst = 0; +		_vm->_global->_pPaletteDesc->vgaPal = _oldPalette; + +		memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); + +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +	} else { +		stop = 0; +		_doPalSubst = 1; +		_palAnimKey = _palKeyIndex; + +		_multData2->palAnimIndices[0] = 0; +		_multData2->palAnimIndices[1] = 0; +		_multData2->palAnimIndices[2] = 0; +		_multData2->palAnimIndices[3] = 0; + +		_vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; +	} +	return stop; +} + +void Mult_v2::doPalAnim(void) { +	int16 off; +	int16 off2; +	Video::Color *palPtr; +	Mult_PalKey *palKey; + +	if (_doPalSubst == 0) +		return; + +	for (_index = 0; _index < 4; _index++) { +		palKey = &_multData2->palKeys[_palAnimKey]; + +		if ((_frame % palKey->rates[_index]) != 0) +			continue; + +		_palAnimRed[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; +		_palAnimGreen[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; +		_palAnimBlue[_index] = +		    _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; + +		while (1) { +			off = palKey->subst[(_multData2->palAnimIndices[_index] + 1) % 16][_index]; +			if (off == 0) { +				off = palKey->subst[_multData2->palAnimIndices[_index]][_index] - 1; + +				_vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; +				_vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; +				_vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; +			} else { +				off = palKey->subst[(_multData2->palAnimIndices[_index] + 1) % 16][_index] - 1; +				off2 = palKey->subst[_multData2->palAnimIndices[_index]][_index] - 1; + +				_vm->_global->_pPaletteDesc->vgaPal[off2].red = _vm->_global->_pPaletteDesc->vgaPal[off].red; +				_vm->_global->_pPaletteDesc->vgaPal[off2].green = _vm->_global->_pPaletteDesc->vgaPal[off].green; +				_vm->_global->_pPaletteDesc->vgaPal[off2].blue = _vm->_global->_pPaletteDesc->vgaPal[off].blue; +			} + +			_multData2->palAnimIndices[_index] = (_multData2->palAnimIndices[_index] + 1) % 16; + +			off = palKey->subst[_multData2->palAnimIndices[_index]][_index]; + +			if (off == 0) { +				_multData2->palAnimIndices[_index] = 0; +				off = palKey->subst[0][_index] - 1; + +				_palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; +				_palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; +				_palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; +			} +			if (_multData2->palAnimIndices[_index] == 0) +				break; +		} +	} + +	if (_vm->_global->_colorCount == 256) { +		_vm->_video->waitRetrace(_vm->_global->_videoMode); + +		palPtr = _vm->_global->_pPaletteDesc->vgaPal; +		for (_counter = 0; _counter < 16; _counter++) { +			_vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, palPtr->blue, 0, 0x13); +			palPtr++; +		} + +		palPtr = _vm->_global->_pPaletteDesc->vgaPal; +		for (_counter = 0; _counter < 16; _counter++) { +			_vm->_global->_redPalette[_counter] = palPtr->red; +			_vm->_global->_greenPalette[_counter] = palPtr->green; +			_vm->_global->_bluePalette[_counter] = palPtr->blue; +			palPtr++; +		} +	} else { +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +	} +} + +char Mult_v2::doFadeAnim(char stop) { +	Mult_PalFadeKey *fadeKey; + +	for (_index = 0; _index < _multData2->palFadeKeysCount; _index++) { +		fadeKey = &_multData2->palFadeKeys[_index]; + +		if (fadeKey->frame != _frame) +			continue; + +		stop = 0; +		if ((fadeKey->flag & 1) == 0) { +			if (fadeKey->fade == 0) { +				_vm->_global->_pPaletteDesc->vgaPal = _multData2->fadePal[fadeKey->palIndex]; +				_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +			} else { +				_vm->_global->_pPaletteDesc->vgaPal = _multData2->fadePal[fadeKey->palIndex]; +				_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); +			} +		} else { +			_vm->_global->_pPaletteDesc->vgaPal = _multData2->fadePal[fadeKey->palIndex]; +			_vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); + +			_palFadingRed = (fadeKey->flag >> 1) & 1; +			_palFadingGreen = (fadeKey->flag >> 2) & 1; +			_palFadingBlue = (fadeKey->flag >> 3) & 1; +		} +	} + +	if (_palFadingRed) { +		_palFadingRed = !_vm->_palanim->fadeStep(1); +		stop = 0; +	} +	if (_palFadingGreen) { +		_palFadingGreen = !_vm->_palanim->fadeStep(2); +		stop = 0; +	} +	if (_palFadingBlue) { +		_palFadingBlue = !_vm->_palanim->fadeStep(3); +		stop = 0; +	} +	return stop; +} + +char Mult_v2::doSoundAnim(char stop) { +	Mult_SndKey *sndKey; +	for (_index = 0; _index < _multData2->sndKeysCount; _index++) { +		sndKey = &_multData2->sndKeys[_index]; +		if (sndKey->frame != _frame) +			continue; + +		if (sndKey->cmd != -1) { +			if (sndKey->cmd == 1) { +				_vm->_snd->stopSound(0); +				stop = 0; +				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, +				    sndKey->freq, sndKey->channel); + +			} else if (sndKey->cmd == 4) { +				_vm->_snd->stopSound(0); +				stop = 0; +				playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, +				    sndKey->freq, sndKey->channel); +			} +		} else { +			if (_vm->_snd->_playingSound) +				_vm->_snd->stopSound(sndKey->channel); +		} +	} +	return stop; +} + +void Mult_v2::sub_62DD(int16 index) { +	Mult_Object *animObj; +	Mult_AnimKey *animKey; +//	void *somep05, *somep05l; +	int16 frame; +	int16 layer; +	int16 layers; +	int16 curanim; +	int i, j; +	 +	// I really doubt animKeysIndices1 is a correct name for that field... +	frame = _multData2->animKeysIndices1[index]; +	if (frame == -1) +		return; + +	for (i = 0; i < 4; i++) { +		if (_multData2->field_124[index][i] != -1) { +			for (j = _multData2->field_15F[index][i]; j < _multData2->animKeysCount[i]; j++) { +				animKey = &_multData2->animKeys[i][j]; +				if (animKey->frame > frame) +					break; +				else if (animKey->frame == frame) { +					animObj = &_objects[_multData2->field_124[index][i]]; +					if (animKey->layer > -1) { +						_multData2->field_15F[index][i] = j; +						(*animObj->pPosX) = animKey->posX; +						(*animObj->pPosY) = animKey->posY; +						animObj->pAnimData->frame = 0; +						animObj->pAnimData->animType = 1; +						animObj->pAnimData->isStatic = 0; +						animObj->pAnimData->isPaused = 0; +						animObj->pAnimData->maxTick = 0; +						animObj->pAnimData->animation = 0; +						animObj->tick = 0; +						curanim = _multData2->animIndices[0]; +						layer = animKey->layer; +						layers = _vm->_scenery->_animations[curanim].layersCount; +						while (layer >= layers) { +							layer -= layers; +							animObj->pAnimData->animation++; +							curanim = _multData2->animIndices[animObj->pAnimData->animation]; +							layers = _vm->_scenery->_animations[curanim].layersCount; +						} +						animObj->pAnimData->layer = 2; +						animObj->pAnimData->animation = +							_multData2->animIndices[animObj->pAnimData->animation]; +						break; +					} +					else { +						animObj->pAnimData->isStatic = 1; +						continue; +					} +				} +			} +		} +		if (_multData2->field_124[index][i] != -1) { +			warning("GOB2 Stub! Messing about with _multData2->somepointer05"); +			for (j = _multData2->field_17F[index][i]; j < _multData2->somepointer05size[i]; j++) { +/* +				somep05 = &_multData2->somepointer05[i][j]; +				somep05l = &_multData2->somepointer05[i][j-1]; +				if (somep05->field_0 > frame) +					break; +				else if (somep05->field_0 == frame) { +					if (somep05->field_2 == -1) +						_multData2->somepointer05indices[i] = -1; +					else { +						_multData2->somepointer05indices[0] = -1; +						_multData2->somepointer05indices[1] = -1; +						_multData2->somepointer05indices[2] = -1; +						_multData2->somepointer05indices[3] = -1; +						if ((_multData2->field_156 == 1) || (somep05l->field_2 == 1)) +							_multData2->somepointer05indices[i] = j; +						else if (_multData2->field_157[index] == frame) +							_multData2->somepointer05indices[i] = -1; +						else +							_multData2->somepointer05indices[i] = j - 1; +					} +				} +*/ +			} +		} +		if (_multData2->somepointer05indices[i] != -1) { +/* +			int arg3 = frame - _multData2->somepointer05[i][_multData2->somepointer05indices[i]].field_0; +			int arg2 =  _multData2->field_156; +			if ((arg2 != 1) && (--arg3 > 0)) +			arg3 = 0; +			int arg1 = _multData2->somepointer05[i][_multData2->somepointer05indices[i]]; +			// somepointer09 is 14 bytes wide (surely a struct) +			int arg0 = _multData2->somepointer09[-_multData2->somepointer05[i][_multData2->somepointer05indices[i]].field_2 - 2]; +*/ +			warning("GOB2 Stub! sub_1CBF8(arg0, arg1, arg2, arg3);"); +		} +	} +} + +void Mult_v2::sub_6A35(void) { +	int i; +	int j; +	 +	for (i = 0; i < 8; i++) +		if (_multDatas[i] != 0) { +			_multData2 = _multDatas[i]; +			for (j = 0; j < 4; j++) +				sub_62DD(j); +		} +} + +void Mult_v2::animate(void) { +	Mult_Object *animObj1, *animObj2; +	Mult_AnimData *animData1, *animData2; +	int i; +	int j; +	int8 minOrder = 100; +	int8 maxOrder = 0; +	int8 *orderArray; +	int orderArrayPos = 0; +	int8 animIndices[150]; +	int numAnims = 0; // di +	// .----- +	int off_2CE67 = 1000; +	int word_2CC88 = 1; +	// '----- +	 +	if (_objects == 0) +		return; + +	if (_objCount == 0) +		orderArray = 0; +	else { +		if (_orderArray == 0) +			return; +		orderArray = _orderArray; +	} + +	sub_6A35(); +	 +	for (i = 0; i < _objCount; i++) { +		animData1 = _objects[i].pAnimData; +		animData1->intersected = 200; +		if ((animData1->isStatic != 2) && +				((animData1->isStatic == 0) || (_objects[i].lastLeft != -1))) { +			animIndices[numAnims] = i; +			_renderData2[numAnims] = &_objects[i]; +			numAnims++; +		} +	} + +	for (i = 0; i < numAnims; i++) { +		animObj1 = _renderData2[i]; + +		animObj1->someFlag = 0; +		// TODO: the region around off_2CE67 is messed up +		// Should be some heigh value so that MIN() works +		animObj1->somethingTop = off_2CE67; // seg011:0AA7 +		animObj1->somethingLeft = off_2CE67; +		animObj1->somethingBottom = 0; +		animObj1->somethingRight = 0; +		 +		animData1 = animObj1->pAnimData; +		if ((animData1->isStatic == 0) && (animData1->isPaused == 0) +				&& (animData1->maxTick == animObj1->tick)) { +			animObj1->someFlag = 1; +			_vm->_scenery->updateAnim(animData1->layer, animData1->frame, +					animData1->animation, 8, *animObj1->pPosX, *animObj1->pPosY, 0); +			if (animObj1->lastLeft == -1) { +				animObj1->somethingLeft = _vm->_scenery->_toRedrawLeft; +				animObj1->somethingTop = _vm->_scenery->_toRedrawTop; +				animObj1->somethingRight = _vm->_scenery->_toRedrawRight; +				animObj1->somethingBottom = _vm->_scenery->_toRedrawBottom; +			} else { +				animObj1->somethingLeft = MIN(animObj1->lastLeft, _vm->_scenery->_toRedrawLeft); +				animObj1->somethingTop = MIN(animObj1->lastTop, _vm->_scenery->_toRedrawTop); +				animObj1->somethingRight = MAX(animObj1->lastRight, _vm->_scenery->_toRedrawRight); +				animObj1->somethingBottom = MAX(animObj1->lastBottom, _vm->_scenery->_toRedrawBottom); +				if ((_vm->_game->_totFileData[0x29] > 50) && +						(animObj1->somethingLeft == animObj1->lastLeft) && +						(animObj1->somethingTop == animObj1->lastTop) && +						(animObj1->somethingRight == animObj1->lastRight) && +						(animObj1->somethingBottom == animObj1->lastBottom) && +						(animData1->somethingLayer == animData1->layer) && +						(animData1->somethingFrame == animData1->frame) && +						(animData1->somethingAnimation == animData1->animation)) { +					animObj1->someFlag = 0; +				} +			} +		} else { +			if (animData1->isStatic == 0) { +				if (animObj1->lastLeft == -1) { +					animObj1->someFlag = 1; +					_vm->_scenery->updateAnim(animData1->layer, animData1->frame, +						animData1->animation, 8, *animObj1->pPosX, *animObj1->pPosY, 0); +				} +				animObj1->somethingLeft = _vm->_scenery->_toRedrawLeft; +				animObj1->somethingTop = _vm->_scenery->_toRedrawTop; +				animObj1->somethingRight = _vm->_scenery->_toRedrawRight; +				animObj1->somethingBottom = _vm->_scenery->_toRedrawBottom; +			} else if (animObj1->lastLeft != -1) { +				animObj1->someFlag = 1; +				animObj1->somethingLeft = _vm->_scenery->_toRedrawLeft; +				animObj1->somethingTop = _vm->_scenery->_toRedrawTop; +				animObj1->somethingRight = _vm->_scenery->_toRedrawRight; +				animObj1->somethingBottom = _vm->_scenery->_toRedrawBottom; +			} +		} +		animData1->somethingLayer = animData1->layer; +		animData1->somethingFrame = animData1->frame; +		animData1->somethingAnimation = animData1->animation; +		if ((animObj1->someFlag != 0) || (animData1->isStatic == 0)) { +			minOrder = MIN(minOrder, animData1->order); +			maxOrder = MAX(maxOrder, animData1->order); +		} +	} + +	for (i = 0; i < numAnims; i++) { +		if ((_renderData2[i]->someFlag != 0) && (_renderData2[i]->lastLeft != -1)) { +			int maxleft = MAX(_renderData2[i]->somethingLeft, _vm->_anim->_areaLeft); +			int maxtop = MAX(_renderData2[i]->somethingTop, _vm->_anim->_areaTop); + +			_vm->_draw->_sourceSurface = 22; +			_vm->_draw->_destSurface = 21; +			_vm->_draw->_spriteLeft = maxleft - _vm->_anim->_areaLeft; +			_vm->_draw->_spriteTop = maxtop - _vm->_anim->_areaTop; +			_vm->_draw->_spriteRight = _renderData2[i]->somethingRight - maxleft + 1; +			_vm->_draw->_spriteBottom = _renderData2[i]->somethingBottom - maxtop + 1; +			if ((_vm->_draw->_spriteRight > 0) && (_vm->_draw->_spriteBottom > 0)) { +				_vm->_draw->_destSpriteX = maxleft; +				_vm->_draw->_destSpriteY = maxtop; +				_vm->_draw->_transparency = 0; +				_vm->_draw->spriteOperation(10); +			} +			_renderData2[i]->lastLeft = -1; +		} +	} + +	for (j = minOrder; j <= maxOrder; j++) { +		for (i = 0; i < numAnims; i++) { +			animData1 = _renderData2[i]->pAnimData; +			if (((animData1->isStatic == 0) || (_renderData2[i]->someFlag != 0)) +					& (animData1->order == j)) +				orderArray[orderArrayPos++] = i; +		} +	} + +	warning("GOB2 Stub! word_2CC88"); +	if (word_2CC88 >= 0) { +		for (i = 0; i < orderArrayPos; i++) { +			animObj1 = _renderData2[orderArray[i]]; +			for (j = i+1; j < orderArrayPos; j++) { +				animObj2 = _renderData2[orderArray[j]]; +				if ((animObj1->pAnimData->order == animObj2->pAnimData->order) && +						((animObj1->somethingBottom > animObj2->somethingBottom) || +						((animObj1->somethingBottom == animObj2->somethingBottom) && +						 (animObj1->pAnimData->someFlag == 1)))) +						SWAP(orderArray[i], orderArray[j]); +			} +		} +	} + +	for (i = 0; i < orderArrayPos; i++) { +		animObj1 = _renderData2[orderArray[i]]; +		animData1 = animObj1->pAnimData; +		if (animObj1->someFlag == 0) { +		} else { +			if (animData1->isStatic == 0) { +				_vm->_scenery->updateAnim(animData1->layer, animData1->frame, +						animData1->animation, 10, *animObj1->pPosX, *animObj1->pPosY, 1); +				if (_vm->_scenery->_toRedrawLeft != -12345) { +					if (_vm->_global->_pressedKeys[0x36]) { +						warning("GOB2 Stub! word_2F3BF & word_2F3C1; someValueToAddToY & someValueToAddToX, respectively"); +						// draws a rectangle around the region to redraw, why? +						_vm->_video->drawLine(_vm->_draw->_frontSurface, +								_vm->_scenery->_toRedrawLeft, _vm->_scenery->_toRedrawTop, +								_vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawTop, 15); +						_vm->_video->drawLine(_vm->_draw->_frontSurface, +								_vm->_scenery->_toRedrawLeft, _vm->_scenery->_toRedrawBottom, +								_vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawBottom, 15); +						_vm->_video->drawLine(_vm->_draw->_frontSurface, +								_vm->_scenery->_toRedrawLeft, _vm->_scenery->_toRedrawTop, +								_vm->_scenery->_toRedrawLeft, _vm->_scenery->_toRedrawBottom, 15); +						_vm->_video->drawLine(_vm->_draw->_frontSurface, +								_vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawTop, +								_vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawBottom, 15); +					} +					animObj1->lastLeft = _vm->_scenery->_toRedrawLeft; +					animObj1->lastRight = _vm->_scenery->_toRedrawRight; +					animObj1->lastTop = _vm->_scenery->_toRedrawTop; +					animObj1->lastBottom = _vm->_scenery->_toRedrawBottom; +				} else { +					animObj1->lastLeft = -1; +				} +			} else { +				_vm->_scenery->_toRedrawLeft = animObj1->somethingLeft; +				_vm->_scenery->_toRedrawRight = animObj1->somethingRight; +				_vm->_scenery->_toRedrawTop = animObj1->somethingTop; +				_vm->_scenery->_toRedrawBottom = animObj1->somethingBottom; +			} +			warning("GOB2 Stub! sub_1A52B(animObj1->pAnimData->order);"); +		} +	} + +	for (i = 0; i < numAnims; i++) { +		animObj1 = _renderData2[i]; +		animData1 = animObj1->pAnimData; +		if (animData1->isStatic != 0) +			continue; + +		if ((animData1->animType == 7) && (animData1->field_F != -1)) { +			animData1->layer = animData1->field_F; +			animData1->frame = 0; +			animData1->field_F = -1; +			animData1->isPaused = 0; +		} +		if (animData1->isPaused != 0) +			continue; + +		if (animData1->maxTick == animObj1->tick) { +			animObj1->tick = 0; +			if ((animData1->animType < 100) || (word_2CC88 < 0)) { +				if (animData1->animType == 4) { +					animData1->frame = 0; +					animData1->isPaused = 1; +				} +				else { +					if (animData1->animType != 8) +						animData1->frame++; +					if (animData1->frame >= +							_vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer]->framesCount) { +						switch(animData1->animType) { +						case 0: +							animData1->frame = 0; +							break; + +						case 1: +							animData1->frame = 0; +							*(_objects[i].pPosX) += +								_vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer]->animDeltaX; +							*(_objects[i].pPosY) += +								_vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer]->animDeltaY; +							break; + +						case 2: +							animData1->frame = 0; +							animData1->animation = animData1->newAnimation; +							animData1->layer = animData1->newLayer; +							break; + +						case 3: +							animData1->animType = 4; +							animData1->frame = 0; +							break; + +						case 5: +							animData1->isStatic = 1; +							animData1->frame = 0; +							break; + +						case 6: +						case 7: +							animData1->frame--; +							animData1->isPaused = 1; +							break; +						} +						animData1->newCycle = 1; +					} else +						animData1->newCycle = 0; +				} +			} +			else if (animData1->animType == 100) +				warning("GOB2 Stub! sub_10C87(animObj1);"); +			else if (animData1->animType == 101) +				warning("GOB2 Stub! sub_11984(animObj1);"); +		} else +			animObj1->tick++; +	} + +	for (i = 0; i < numAnims; i++) { +		animObj1 = _renderData2[i]; +		animData1 = animObj1->pAnimData; +		if ((animData1->isStatic != 0) || (animObj1->lastLeft == -1)) +			continue; + +		for (j = 0; j < numAnims; j++) { +			if (i == j) +				continue; +			animObj2 = _renderData2[j]; +			animData2 = animObj2->pAnimData; +			if ((animData2->isStatic != 0) || (animObj2->lastLeft == -1)) +				continue; +			if ((animObj2->lastRight >= animObj1->lastLeft) && +					(animObj2->lastLeft <= animObj1->lastRight) && +					(animObj2->lastBottom >= animObj1->lastTop) && +					(animObj2->lastTop <= animObj1->lastBottom)) +				animData2->intersected = animIndices[i]; +		} +	} +} +  } // End of namespace Gob  | 
