From adbafccc64fba8f314a302042b78c2a36a61619f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 12 Apr 2006 09:49:08 +0000 Subject: - 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 --- engines/gob/inter_v2.cpp | 6 +- engines/gob/mult.cpp | 698 +----------------------------------- engines/gob/mult.h | 61 +++- engines/gob/mult_v1.cpp | 701 ++++++++++++++++++++++++++++++++++++ engines/gob/mult_v2.cpp | 904 +++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 1641 insertions(+), 729 deletions(-) (limited to 'engines/gob') 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++; @@ -166,8 +172,6 @@ void Mult_v2::loadMult(int16 resId) { memcpy(_multData2->palKeys[i].subst, _dataPtr + 16, 64); } - _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 -- cgit v1.2.3