scummvm/engines/gob/mult_v1.cpp
2007-02-05 14:08:50 +00:00

985 lines
26 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 Ivan Dubrov
* Copyright (C) 2004-2006 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "common/stream.h"
#include "gob/gob.h"
#include "gob/mult.h"
#include "gob/game.h"
#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_v1::Mult_v1(GobEngine *vm) : Mult(vm) {
}
void Mult_v1::loadMult(int16 resId) {
int16 palIndex;
int16 i, j;
char *extData;
_multData = new Mult_Data;
memset(_multData, 0, sizeof(Mult_Data));
_multData->sndSlotsCount = 0;
_multData->frameStart = 0;
extData = _vm->_game->loadExtData(resId, 0, 0);
Common::MemoryReadStream data((byte *) extData, 4294967295U);
_multData->staticCount = data.readSByte() + 1;
_multData->animCount = data.readSByte() + 1;
for (i = 0; i < _multData->staticCount; i++, data.seek(14, SEEK_CUR)) {
_multData->staticIndices[i] = _vm->_scenery->loadStatic(1);
if (_multData->staticIndices[i] >= 100) {
_multData->staticIndices[i] -= 100;
_multData->staticLoaded[i] = 1;
} else {
_multData->staticLoaded[i] = 0;
}
}
for (i = 0; i < _multData->animCount; i++, data.seek(14, SEEK_CUR)) {
_multData->animIndices[i] = _vm->_scenery->loadAnim(1);
if (_multData->animIndices[i] >= 100) {
_multData->animIndices[i] -= 100;
_multData->animLoaded[i] = 1;
} else {
_multData->animLoaded[i] = 0;
}
}
_multData->frameRate = data.readSint16LE();
_multData->staticKeysCount = data.readSint16LE();
_multData->staticKeys = new Mult_StaticKey[_multData->staticKeysCount];
for (i = 0; i < _multData->staticKeysCount; i++) {
_multData->staticKeys[i].frame = data.readSint16LE();
_multData->staticKeys[i].layer = data.readSint16LE();
}
for (j = 0; j < 4; j++) {
_multData->animKeysCount[j] = data.readSint16LE();
_multData->animKeys[j] = new Mult_AnimKey[_multData->animKeysCount[j]];
for (i = 0; i < _multData->animKeysCount[j]; i++) {
_multData->animKeys[j][i].frame = data.readSint16LE();
_multData->animKeys[j][i].layer = data.readSint16LE();
_multData->animKeys[j][i].posX = data.readSint16LE();
_multData->animKeys[j][i].posY = data.readSint16LE();
_multData->animKeys[j][i].order = data.readSint16LE();
}
}
for (palIndex = 0; palIndex < 5; palIndex++) {
for (i = 0; i < 16; i++) {
_fadePal[palIndex][i].red = data.readByte();
_fadePal[palIndex][i].green = data.readByte();
_fadePal[palIndex][i].blue = data.readByte();
}
}
_multData->palFadeKeysCount = data.readSint16LE();
_multData->palFadeKeys = new Mult_PalFadeKey[_multData->palFadeKeysCount];
for (i = 0; i < _multData->palFadeKeysCount; i++) {
_multData->palFadeKeys[i].frame = data.readSint16LE();
_multData->palFadeKeys[i].fade = data.readSint16LE();
_multData->palFadeKeys[i].palIndex = data.readSint16LE();
_multData->palFadeKeys[i].flag = data.readSByte();
}
_multData->palKeysCount = data.readSint16LE();
_multData->palKeys = new Mult_PalKey[_multData->palKeysCount];
for (i = 0; i < _multData->palKeysCount; i++) {
_multData->palKeys[i].frame = data.readSint16LE();
_multData->palKeys[i].cmd = data.readSint16LE();
_multData->palKeys[i].rates[0] = data.readSint16LE();
_multData->palKeys[i].rates[1] = data.readSint16LE();
_multData->palKeys[i].rates[2] = data.readSint16LE();
_multData->palKeys[i].rates[3] = data.readSint16LE();
_multData->palKeys[i].unknown0 = data.readSint16LE();
_multData->palKeys[i].unknown1 = data.readSint16LE();
data.read(_multData->palKeys[i].subst, 64);
}
_multData->textKeysCount = data.readSint16LE();
_multData->textKeys = new Mult_TextKey[_multData->textKeysCount];
for (i = 0; i < _multData->textKeysCount; i++) {
_multData->textKeys[i].frame = data.readSint16LE();
_multData->textKeys[i].cmd = data.readSint16LE();
for (int k = 0; k < 9; ++k)
_multData->textKeys[i].unknown0[k] = data.readSint16LE();
_multData->textKeys[i].index = data.readSint16LE();
_multData->textKeys[i].unknown1[0] = data.readSint16LE();
_multData->textKeys[i].unknown1[1] = data.readSint16LE();
}
_multData->sndKeysCount = data.readSint16LE();
_multData->sndKeys = new Mult_SndKey[_multData->sndKeysCount];
for (i = 0; i < _multData->sndKeysCount; i++) {
_multData->sndKeys[i].frame = data.readSint16LE();
_multData->sndKeys[i].cmd = data.readSint16LE();
_multData->sndKeys[i].freq = data.readSint16LE();
_multData->sndKeys[i].fadeLength = data.readSint16LE();
_multData->sndKeys[i].repCount = data.readSint16LE();
_multData->sndKeys[i].soundIndex = -1;
_multData->sndKeys[i].resId = -1;
data.seek(26, SEEK_CUR);
switch (_multData->sndKeys[i].cmd) {
case 1:
case 4:
_multData->sndKeys[i].resId = READ_LE_UINT16(_vm->_global->_inter_execPtr);
for (j = 0; j < i; j++) {
if (_multData->sndKeys[i].resId ==
_multData->sndKeys[j].resId) {
_multData->sndKeys[i].soundIndex =
_multData->sndKeys[j].soundIndex;
_vm->_global->_inter_execPtr += 2;
break;
}
}
if (i == j) {
_vm->_inter->loadSound(19 - _multData->sndSlotsCount);
_multData->sndKeys[i].soundIndex =
19 - _multData->sndSlotsCount;
_multData->sndSlotsCount++;
}
break;
case 3:
_vm->_global->_inter_execPtr += 6;
break;
case 5:
_vm->_global->_inter_execPtr += _multData->sndKeys[i].freq * 2;
break;
}
}
}
void Mult_v1::setMultData(uint16 multindex) {
error("Switching mults not supported for Gob1");
}
void Mult_v1::multSub(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(_multData->frameRate);
_vm->_anim->_areaTop = 0;
_vm->_anim->_areaLeft = 0;
_vm->_anim->_areaWidth = 320;
_vm->_anim->_areaHeight = 200;
_objCount = 4;
_objects = new Mult_Object[_objCount];
memset(_objects, 0, _objCount * sizeof(Mult_Object));
_renderData = new int16[9 * _objCount];
memset(_renderData, 0, _objCount * 9 * sizeof(int16));
_animArrayX = new int32[_objCount];
_animArrayY = new int32[_objCount];
_animArrayData = new Mult_AnimData[_objCount];
memset(_animArrayData, 0, _objCount * sizeof(Mult_AnimData));
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, _frame);
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 && !_vm->_quitRequested);
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;
_vm->_video->freeSurfDesc(_vm->_anim->_animSurf);
_vm->_anim->_animSurf = 0;
_vm->_draw->_spritesArray[22] = 0;
_animDataAllocated = 0;
}
if (_vm->_snd->_playingSound != 0)
_vm->_snd->stopSound(10);
WRITE_VAR(57, (uint32)-1);
} else
WRITE_VAR(57, _frame - 1 - _multData->frameStart);
}
char Mult_v1::drawStatics(char stop) {
if (_multData->staticKeys[_multData->staticKeysCount - 1].frame > _frame)
stop = 0;
for (_counter = 0; _counter < _multData->staticKeysCount;
_counter++) {
if (_multData->staticKeys[_counter].frame != _frame
|| _multData->staticKeys[_counter].layer == -1)
continue;
_vm->_scenery->_curStaticLayer = _multData->staticKeys[_counter].layer;
for (_vm->_scenery->_curStatic = 0;
_vm->_scenery->_curStaticLayer >=
_vm->_scenery->_statics[_multData->staticIndices[_vm->_scenery->_curStatic]].layersCount;
_vm->_scenery->_curStatic++) {
_vm->_scenery->_curStaticLayer -=
_vm->_scenery->_statics[_multData->staticIndices[_vm->_scenery->_curStatic]].layersCount;
}
_vm->_scenery->_curStatic = _multData->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 < _multData->animKeysCount[_index]; _counter++) {
key = &_multData->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[_multData->animIndices[0]].layersCount;
i = 0;
while (animObj->pAnimData->layer >= count) {
animObj->pAnimData->layer -= count;
i++;
count =
_vm->_scenery->_animations[_multData->animIndices[i]].layersCount;
}
animObj->pAnimData->animation = _multData->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 < _multData->textKeysCount; _index++) {
if (_multData->textKeys[_index].frame != _frame)
continue;
cmd = _multData->textKeys[_index].cmd;
if (cmd == 0) {
*pStop = 0;
} else if (cmd == 1) {
*pStopNoClear = 1;
_multData->frameStart = 0;
} else if (cmd == 3) {
*pStop = 0;
savedIP = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr =
(char *)(&_multData->textKeys[_index].index);
_vm->_global->_inter_execPtr = savedIP;
}
}
}
char Mult_v1::prepPalAnim(char stop) {
_palKeyIndex = -1;
do {
_palKeyIndex++;
if (_palKeyIndex >= _multData->palKeysCount)
return stop;
} while (_multData->palKeys[_palKeyIndex].frame != _frame);
if (_multData->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 = &_multData->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 < _multData->palFadeKeysCount; _index++) {
fadeKey = &_multData->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, int16 frame) {
Mult_SndKey *sndKey;
for (_index = 0; _index < _multData->sndKeysCount; _index++) {
sndKey = &_multData->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->fadeLength);
} else if (sndKey->cmd == 4) {
_vm->_snd->stopSound(0);
stop = 0;
playSound(_vm->_game->_soundSamples[sndKey->soundIndex],
sndKey->repCount, sndKey->freq, sndKey->fadeLength);
}
} else {
if (_vm->_snd->_playingSound)
_vm->_snd->stopSound(sndKey->fadeLength);
}
}
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++;
}
}
}
void Mult_v1::freeMult(void) {
if ((_vm->_anim->_animSurf != 0) && (_vm->_draw->_spritesArray[22] != 0))
_vm->_video->freeSurfDesc(_vm->_anim->_animSurf);
delete[] _objects;
delete[] _renderData;
delete[] _orderArray;
_objects = 0;
_renderData = 0;
_orderArray = 0;
_vm->_anim->_animSurf = 0;
_vm->_draw->_spritesArray[22] = 0;
}
void Mult_v1::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
int16 fadeLength) {
_vm->_snd->playSample(soundDesc, repCount, freq, fadeLength);
}
void Mult_v1::freeMultKeys(void) {
int i;
for (i = 0; i < _multData->staticCount; i++) {
if (_multData->staticLoaded[i] != 0)
_vm->_scenery->freeStatic(_multData->staticIndices[i]);
}
for (i = 0; i < _multData->animCount; i++) {
if (_multData->animLoaded[i] != 0)
_vm->_scenery->freeAnim(_multData->animIndices[i]);
}
delete[] _multData->staticKeys;
for (i = 0; i < 4; i++)
delete[] _multData->animKeys[i];
delete[] _multData->palFadeKeys;
delete[] _multData->palKeys;
delete[] _multData->textKeys;
for (i = 0; i < _multData->sndSlotsCount; i++) {
_vm->_game->freeSoundSlot(19 - i);
}
delete[] _multData->sndKeys;
if (_animDataAllocated != 0) {
delete[] _objects;
_objects = 0;
delete[] _renderData;
_renderData = 0;
delete[] _animArrayX;
_animArrayX = 0;
delete[] _animArrayY;
_animArrayY = 0;
delete[] _animArrayData;
_animArrayData = 0;
_vm->_video->freeSurfDesc(_vm->_anim->_animSurf);
_vm->_anim->_animSurf = 0;
_vm->_draw->_spritesArray[22] = 0;
_animDataAllocated = 0;
}
delete _multData;
_multData = 0;
}
} // End of namespace Gob