diff options
author | Sven Hesse | 2007-02-04 15:45:15 +0000 |
---|---|---|
committer | Sven Hesse | 2007-02-04 15:45:15 +0000 |
commit | f54a97a02cfcf7abf8fd06cbed25aa7bba7d41ee (patch) | |
tree | f2abe52c7d32b98943c1292d47465bdf92041f7d /engines/gob | |
parent | 8f084baf66a2ce3b09103f6ea133cc7d6a3f9611 (diff) | |
download | scummvm-rg350-f54a97a02cfcf7abf8fd06cbed25aa7bba7d41ee.tar.gz scummvm-rg350-f54a97a02cfcf7abf8fd06cbed25aa7bba7d41ee.tar.bz2 scummvm-rg350-f54a97a02cfcf7abf8fd06cbed25aa7bba7d41ee.zip |
- Plugged some leaks and fixed some memory errors
- Fixed the cursor animation loops in Ween and Bargon
- Added Draw_Bargon + Inter_Bargon
- Implemented Bargon Attack's hardcoded intro parts
svn-id: r25387
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/dataio.h | 2 | ||||
-rw-r--r-- | engines/gob/detection.cpp | 4 | ||||
-rw-r--r-- | engines/gob/draw.cpp | 5 | ||||
-rw-r--r-- | engines/gob/draw.h | 8 | ||||
-rw-r--r-- | engines/gob/draw_bargon.cpp | 46 | ||||
-rw-r--r-- | engines/gob/draw_v2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/game.cpp | 108 | ||||
-rw-r--r-- | engines/gob/game.h | 4 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 9 | ||||
-rw-r--r-- | engines/gob/global.cpp | 6 | ||||
-rw-r--r-- | engines/gob/global.h | 1 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 12 | ||||
-rw-r--r-- | engines/gob/gob.h | 5 | ||||
-rw-r--r-- | engines/gob/inter.h | 50 | ||||
-rw-r--r-- | engines/gob/inter_bargon.cpp | 857 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/module.mk | 2 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 5 | ||||
-rw-r--r-- | engines/gob/palanim.cpp | 6 | ||||
-rw-r--r-- | engines/gob/sound.cpp | 38 | ||||
-rw-r--r-- | engines/gob/sound.h | 10 | ||||
-rw-r--r-- | engines/gob/video.cpp | 8 | ||||
-rw-r--r-- | engines/gob/video.h | 1 |
23 files changed, 1138 insertions, 53 deletions
diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index 1e1ebc7875..cf6b5347a3 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -28,7 +28,7 @@ namespace Gob { -#define MAX_DATA_FILES 6 +#define MAX_DATA_FILES 8 #define MAX_SLOT_COUNT 4 class DataIO { diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 1997b117d6..e65416cc61 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -462,7 +462,7 @@ static const GOBGameDescription gameDescriptions[] = { UNK_LANG, kPlatformPC, }, - GF_GOB2, + GF_BARGON, "intro" }, { @@ -536,7 +536,7 @@ static const GOBGameDescription gameDescriptions[] = { "gob3cd", "v1.000", AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"), - UNK_LANG, + EN_USA, kPlatformPC, }, GF_GOB2, diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 9764ea1a16..b4dd65ef6f 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -362,9 +362,10 @@ void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); - if (_vm->_game->_totFileData[0x7E] != 0) { + if (READ_LE_UINT16(_vm->_game->_totFileData + 0x7E) != 0) { storedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _vm->_game->_totFileData + 0x7E; + _vm->_global->_inter_execPtr = _vm->_game->_totFileData + + READ_LE_UINT16(_vm->_game->_totFileData + 0x7E); WRITE_VAR(17, (uint32) arg_0); WRITE_VAR(18, (uint32) left); WRITE_VAR(19, (uint32) top); diff --git a/engines/gob/draw.h b/engines/gob/draw.h index b14d0ffb9e..07a53bc073 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -185,6 +185,14 @@ public: virtual ~Draw_v2() {}; }; +class Draw_Bargon: public Draw_v2 { +public: + virtual void initScreen(void); + + Draw_Bargon(GobEngine *vm); + virtual ~Draw_Bargon() {}; +}; + // Draw operations #define DRAW_BLITSURF 0 diff --git a/engines/gob/draw_bargon.cpp b/engines/gob/draw_bargon.cpp new file mode 100644 index 0000000000..c6f629d3db --- /dev/null +++ b/engines/gob/draw_bargon.cpp @@ -0,0 +1,46 @@ +/* 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 "graphics/cursorman.h" + +#include "gob/gob.h" +#include "gob/draw.h" +#include "gob/global.h" +#include "gob/video.h" + +namespace Gob { + +Draw_Bargon::Draw_Bargon(GobEngine *vm) : Draw_v2(vm) { +} + +void Draw_Bargon::initScreen(void) { + _vm->_global->_videoMode = 0x14; + _vm->_video->_surfWidth = 640; + _vm->_video->initPrimary(_vm->_global->_videoMode); + + Draw_v2::initScreen(); +} + +} // End of namespace Gob diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index baf082a5c0..86998c1436 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -848,7 +848,7 @@ void Draw_v2::animateCursor(int16 cursor) { if (cursorIndex == -1) { cursorIndex = 0; for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { - if ((ptr->flags & 0xF00) || (ptr->flags & 0x4000)) + if ((ptr->flags & 0xF00) || (ptr->id & 0x4000)) continue; if (ptr->left > _vm->_global->_inter_mouseX) diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 72a2a3522c..3d4d01d46d 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -152,6 +152,9 @@ Game::~Game() { delete[] _word_2FC80; if (_infIns) delete _infIns; + + for (int i = 0; i < 60; i++) + freeSoundSlot(i); } char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight, uint32 *dataSize) { @@ -763,35 +766,28 @@ void Game::collAreaSub(int16 index, int8 enter) { Snd::SoundDesc *Game::loadSND(const char *path, int8 arg_4) { Snd::SoundDesc *soundDesc; - uint32 dsize; + uint32 dSize; char *data; char *dataPtr; soundDesc = new Snd::SoundDesc; + dSize = _vm->_dataio->getDataSize(path) - 6; data = _vm->_dataio->getData(path); - if (data == 0) { - delete soundDesc; - return 0; - } - soundDesc->data = data; - soundDesc->flag = *data & 0x7F; - if (*data == 0) - soundDesc->flag = 8; + soundDesc->data = new char[dSize]; + soundDesc->flag = *data ? (*data & 0x7F) : 8; dataPtr = data + 4; WRITE_LE_UINT16(dataPtr, READ_BE_UINT16(dataPtr)); + WRITE_LE_UINT32(data, + (READ_LE_UINT32(data) >> 24) + + ((READ_LE_UINT16(data) & 0xFF00) << 8) + + ((READ_LE_UINT16(data + 2) & 0xFF) >> 8)); - WRITE_LE_UINT32(data, (READ_LE_UINT32(data) >> 24) + ((READ_LE_UINT16(data) & 0xFF00) << 8) + ((READ_LE_UINT16(data + 2) & 0xFF) >> 8)); - - soundDesc->size = READ_LE_UINT32(data); - dsize = _vm->_dataio->getDataSize(path) - 6; - if (dsize > soundDesc->size) - soundDesc->size = dsize; - + soundDesc->size = MAX(dSize, READ_LE_UINT32(data)); soundDesc->frequency = READ_LE_UINT16(dataPtr); - soundDesc->data += 6; soundDesc->timerTicks = 1193180 / READ_LE_UINT16(dataPtr); + memcpy(soundDesc->data, data + 6, dSize - 6); if (arg_4 & 2) arg_4 |= 1; @@ -1316,7 +1312,7 @@ int16 Game::viewImd(Game::Imd *imdPtr, int16 frame) { } else if (imdPtr->framesPos != 0) imdPtr->filePos = imdPtr->framesPos[frame]; else - error("Image %d innaccessible in IMD", frame); + error("Image %d inaccessible in IMD", frame); imdPtr->curFrame = frame; _vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0); } @@ -1432,25 +1428,26 @@ int16 Game::viewImd(Game::Imd *imdPtr, int16 frame) { return retVal; } -void Game::imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y) { - // In the original asm, "sub_2C348" is called instead of Video::drawSprite(); - // it basically just blits. +void Game::imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y, + Video::SurfaceDesc *dest) { + if (!dest) + dest = _vm->_draw->_frontSurface; if (frame == 0) - _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0, + _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, imdPtr->width - 1, imdPtr->height - 1, x, y, 1); else if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1)) - _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, + _vm->_video->drawSprite(imdPtr->surfDesc, dest, imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom, imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, 1); else if (imdPtr->stdX != -1) - _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, + _vm->_video->drawSprite(imdPtr->surfDesc, dest, imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1, imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX, y + imdPtr->stdY, 1); else - _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0, + _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, imdPtr->width - 1, imdPtr->height - 1, x, y, 0); } @@ -1632,6 +1629,67 @@ void Game::imdFrameUncompressor(byte *dest, byte *src) { } } +void Game::playImd(const char *path, int16 x, int16 y, int16 startFrame, int16 frames, + bool fade, bool interruptible) { + int16 mouseX; + int16 mouseY; + int16 buttons; + int curFrame; + int endFrame; + int backFrame; + + _vm->_util->setFrameRate(12); + openImd(path, 0, 0, 0, 0); + _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y, x + _imdFile->width - 1, + y + _imdFile->height - 1, 0); + + if (fade) + _vm->_palanim->fade(0, -2, 0); + + endFrame = frames > 0 ? frames : _imdFile->framesCount; + for (curFrame = 0; curFrame < endFrame; curFrame++) { + viewImd(_imdFile, curFrame); + imdDrawFrame(_imdFile, curFrame, x, y); + if (fade) { + _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); + fade = false; + } + _vm->_video->waitRetrace(_vm->_global->_videoMode); + if ((interruptible && (checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) || + _vm->_quitRequested) { + _vm->_palanim->fade(0, -2, 0); + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + WRITE_VAR(4, buttons); + WRITE_VAR(0, 0x11B); + WRITE_VAR(57, (uint32) -1); + break; + } + _vm->_util->waitEndFrame(); + } + if (frames < 0) { + endFrame = _imdFile->framesCount + frames; + for (curFrame = _imdFile->framesCount - 1; curFrame >= endFrame; curFrame--) { + for (backFrame = 0; backFrame <= curFrame; backFrame++) + viewImd(_imdFile, backFrame); + imdDrawFrame(_imdFile, curFrame, x, y); + _vm->_video->waitRetrace(_vm->_global->_videoMode); + if ((interruptible && (checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) || + _vm->_quitRequested) { + _vm->_palanim->fade(0, -2, 0); + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + WRITE_VAR(4, buttons); + WRITE_VAR(0, 0x11B); + WRITE_VAR(57, (uint32) -1); + break; + } + _vm->_util->waitEndFrame(); + } + } + closeImd(); +} + int16 Game::sub_2C825(Imd *imdPtr) { warning("GOB2 Stub! sub_2C825()"); return 0; diff --git a/engines/gob/game.h b/engines/gob/game.h index d43a1efa30..e29d2d4f5a 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -218,8 +218,10 @@ public: void finishImd(Imd *imdPtr); void setImdXY(Imd *imdPtr, int16 x, int16 y); void playImd(int16 arg_0, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 arg_A); + void playImd(const char *path, int16 x, int16 y, int16 startFrame, int16 frames, + bool fade, bool interruptible); int16 viewImd(Game::Imd *imdPtr, int16 arg_4); - void imdDrawFrame(Imd *imdPtr, int16 arg_4, int16 arg_6, int16 arg_8); + void imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y, Video::SurfaceDesc *dest = 0); void imdRenderFrame(Imd *imdPtr); void imdFrameUncompressor(byte *dest, byte *src); int16 sub_2C825(Imd *imdPtr); diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 5db03b067c..fef153a5c6 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -58,6 +58,7 @@ void Game_v2::playTot(int16 skipPlay) { int32 i; char *filePtr; char *savedIP; + bool totTextLoc; oldNestLevel = _vm->_inter->_nestLevel; oldBreakFrom = _vm->_inter->_breakFromLevel; @@ -134,11 +135,13 @@ void Game_v2::playTot(int16 skipPlay) { filePtr = (char *)_totFileData + 0x30; _totTextData = 0; + totTextLoc = false; if (READ_LE_UINT32(filePtr) != (uint32)-1) { _totTextData = new TotTextTable; - if (READ_LE_UINT32(filePtr) == 0) + if (READ_LE_UINT32(filePtr) == 0) { _totTextData->dataPtr = loadLocTexts(); - else + totTextLoc = true; + } else _totTextData->dataPtr = (_totFileData + READ_LE_UINT32((char *)_totFileData + 0x30)); _totTextData->items = 0; @@ -222,6 +225,8 @@ void Game_v2::playTot(int16 skipPlay) { if (_totTextData) { if (_totTextData->items) delete[] _totTextData->items; + if (totTextLoc) + delete[] _totTextData->dataPtr; delete _totTextData; } _totTextData = 0; diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index 6b2c54ecdd..90606fbb23 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -90,6 +90,7 @@ Global::Global(GobEngine *vm) : _vm(vm) { _oldMode = 3; _dontSetPalette = 0; + _primarySurfDesc.vidPtr = 0; _pPrimarySurfDesc = 0; _pPaletteDesc = 0; @@ -155,4 +156,9 @@ Global::Global(GobEngine *vm) : _vm(vm) { _savedBackSize = -1; } +Global::~Global() { + if (_primarySurfDesc.vidPtr) + delete[] _primarySurfDesc.vidPtr; +} + } // End of namespace Gob diff --git a/engines/gob/global.h b/engines/gob/global.h index aa1c6d95ca..a2ffe651ef 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -219,6 +219,7 @@ public: } Global(GobEngine *vm); + ~Global(); protected: GobEngine *_vm; diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 5561aa994a..961c4a4f86 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -611,6 +611,18 @@ int GobEngine::init() { _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); } + else if (_features & Gob::GF_BARGON) { + _inter = new Inter_Bargon(this); + _parse = new Parse_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_Bargon(this); + _game = new Game_v2(this); + _video = new Video_v2(this); + _init = new Init_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + } else error("GobEngine::init(): Unknown version of game engine"); _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 14aa128f2a..3c0f5179b7 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -90,8 +90,9 @@ enum { GF_GOB2 = 1 << 1, GF_GOB3 = 1 << 2, GF_WOODRUFF = 1 << 3, - GF_CD = 1 << 4, - GF_EGA = 1 << 5 + GF_BARGON = 1 << 4, + GF_CD = 1 << 5, + GF_EGA = 1 << 6 }; enum { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index f0c4812bc9..ef75815e69 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -85,6 +85,10 @@ protected: virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0; virtual const char *getOpcodeGoblinDesc(int i) = 0; virtual void loadMult(void) = 0; + + void o_drawNOP(void) {} + bool o_funcNOP(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } + void o_gobNOP(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {} }; class Inter_v1 : public Inter { @@ -369,6 +373,52 @@ protected: void o2_playInfogrames(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); }; +class Inter_Bargon : public Inter_v2 { +public: + Inter_Bargon(GobEngine *vm); + virtual ~Inter_Bargon() {}; + +protected: + typedef void (Inter_Bargon::*OpcodeDrawProcBargon)(void); + typedef bool (Inter_Bargon::*OpcodeFuncProcBargon)(char &, int16 &, int16 &); + typedef void (Inter_Bargon::*OpcodeGoblinProcBargon)(int16 &, int32 *, Goblin::Gob_Object *); + struct OpcodeDrawEntryBargon { + OpcodeDrawProcBargon proc; + const char *desc; + }; + struct OpcodeFuncEntryBargon { + OpcodeFuncProcBargon proc; + const char *desc; + }; + struct OpcodeGoblinEntryBargon { + OpcodeGoblinProcBargon proc; + const char *desc; + }; + const OpcodeDrawEntryBargon *_opcodesDrawBargon; + const OpcodeFuncEntryBargon *_opcodesFuncBargon; + const OpcodeGoblinEntryBargon *_opcodesGoblinBargon; + static const int _goblinFuncLookUp[][2]; + + virtual void setupOpcodes(void); + virtual void executeDrawOpcode(byte i); + virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); + virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + virtual const char *getOpcodeDrawDesc(byte i); + virtual const char *getOpcodeFuncDesc(byte i, byte j); + virtual const char *getOpcodeGoblinDesc(int i); + + void oBargon_intro0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro1(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro2(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro3(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro4(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro5(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro6(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro7(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro8(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro9(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); +}; + } // End of namespace Gob #endif diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp new file mode 100644 index 0000000000..e9f73d893e --- /dev/null +++ b/engines/gob/inter_bargon.cpp @@ -0,0 +1,857 @@ +/* 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 "gob/gob.h" +#include "gob/global.h" +#include "gob/inter.h" +#include "gob/util.h" +#include "gob/scenery.h" +#include "gob/parse.h" +#include "gob/game.h" +#include "gob/draw.h" +#include "gob/mult.h" +#include "gob/goblin.h" +#include "gob/cdrom.h" +#include "gob/palanim.h" +#include "gob/anim.h" +#include "gob/music.h" +#include "gob/map.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_Bargon, x) + +const int Inter_Bargon::_goblinFuncLookUp[][2] = { + {1, 0}, + {2, 1}, + {3, 2}, + {4, 3}, + {5, 4}, + {6, 5}, + {7, 6}, + {8, 7}, + {9, 8}, + {10, 9}, + {11, 10}, + {13, 11}, + {14, 12}, + {15, 13}, + {16, 14}, + {21, 15}, + {22, 16}, + {23, 17}, + {24, 18}, + {25, 19}, + {26, 20}, + {27, 21}, + {28, 22}, + {29, 23}, + {30, 24}, + {32, 25}, + {33, 26}, + {34, 27}, + {35, 28}, + {36, 29}, + {37, 30}, + {40, 31}, + {41, 32}, + {42, 33}, + {43, 34}, + {44, 35}, + {50, 36}, + {52, 37}, + {53, 38}, + {100, 39}, + {152, 40}, + {200, 41}, + {201, 42}, + {202, 43}, + {203, 44}, + {204, 45}, + {250, 46}, + {251, 47}, + {252, 48}, + {500, 49}, + {502, 50}, + {503, 51}, + {600, 52}, + {601, 53}, + {602, 54}, + {603, 55}, + {604, 56}, + {605, 57}, + {1000, 58}, + {1001, 59}, + {1002, 60}, + {1003, 61}, + {1004, 62}, + {1005, 63}, + {1006, 64}, + {1008, 65}, + {1009, 66}, + {1010, 67}, + {1011, 68}, + {1015, 69}, + {2005, 70} +}; + +Inter_Bargon::Inter_Bargon(GobEngine *vm) : Inter_v2(vm) { + setupOpcodes(); +} + +void Inter_Bargon::setupOpcodes(void) { + static const OpcodeDrawEntryBargon opcodesDraw[256] = { + /* 00 */ + OPCODE(o1_loadMult), + OPCODE(o2_playMult), + OPCODE(o1_freeMult), + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o2_initCursor), + /* 08 */ + OPCODE(o1_initCursorAnim), + OPCODE(o1_clearCursorAnim), + OPCODE(o2_setRenderFlags), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + OPCODE(o1_loadAnim), + OPCODE(o1_freeAnim), + OPCODE(o1_updateAnim), + OPCODE(o2_multSub), + /* 14 */ + OPCODE(o2_initMult), + OPCODE(o1_multFreeMult), + OPCODE(o1_animate), + OPCODE(o1_multLoadMult), + /* 18 */ + OPCODE(o1_storeParams), + OPCODE(o2_getObjAnimSize), + OPCODE(o1_loadStatic), + OPCODE(o1_freeStatic), + /* 1C */ + OPCODE(o2_renderStatic), + OPCODE(o2_loadCurLayer), + {NULL, ""}, + {NULL, ""}, + /* 20 */ + OPCODE(o2_playCDTrack), + OPCODE(o2_drawStub), + OPCODE(o2_stopCD), + OPCODE(o2_readLIC), + /* 24 */ + OPCODE(o2_freeLIC), + OPCODE(o2_getCDTrackPos), + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o2_loadFontToSprite), + OPCODE(o1_freeFontToSprite), + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + OPCODE(o2_totSub), + OPCODE(o2_switchTotSub), + OPCODE(o2_copyVars), + OPCODE(o2_pasteVars), + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 48 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 4C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 50 */ + OPCODE(o2_loadMapObjects), + OPCODE(o2_freeGoblins), + OPCODE(o2_moveGoblin), + OPCODE(o2_writeGoblinPos), + /* 54 */ + OPCODE(o2_stub0x54), + OPCODE(o2_stub0x55), + OPCODE(o2_placeGoblin), + {NULL, ""}, + /* 58 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 5C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 60 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 64 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 68 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 6C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 70 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 74 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 78 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 7C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 80 */ + OPCODE(o2_initScreen), + OPCODE(o2_scroll), + OPCODE(o2_setScrollOffset), + OPCODE(o2_playImd), + /* 84 */ + OPCODE(o2_drawStub), + OPCODE(o2_stub0x85), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 88 */ + OPCODE(o2_drawStub), + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 8C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 90 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 94 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 98 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 9C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* AC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* BC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* CC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* DC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* EC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* FC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""} + }; + + static const OpcodeFuncEntryBargon opcodesFunc[80] = { + /* 00 */ + OPCODE(o1_callSub), + OPCODE(o1_callSub), + OPCODE(o1_drawPrintText), + OPCODE(o1_loadCursor), + /* 04 */ + {NULL, ""}, + OPCODE(o1_call), + OPCODE(o1_repeatUntil), + OPCODE(o1_whileDo), + /* 08 */ + OPCODE(o1_callBool), + OPCODE(o2_evaluateStore), + OPCODE(o1_loadSpriteToPos), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + OPCODE(o2_printText), + OPCODE(o2_loadTot), + OPCODE(o2_palLoad), + /* 14 */ + OPCODE(o1_keyFunc), + OPCODE(o1_capturePush), + OPCODE(o1_capturePop), + OPCODE(o2_animPalInit), + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_drawOperations), + OPCODE(o1_setcmdCount), + /* 20 */ + OPCODE(o1_return), + OPCODE(o1_renewTimeInVars), + OPCODE(o1_speakerOn), + OPCODE(o1_speakerOff), + /* 24 */ + OPCODE(o1_putPixel), + OPCODE(o2_goblinFunc), + OPCODE(o2_createSprite), + OPCODE(o2_freeSprite), + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_returnTo), + OPCODE(o1_loadSpriteContent), + OPCODE(o1_copySprite), + OPCODE(o1_fillRect), + /* 34 */ + OPCODE(o1_drawLine), + OPCODE(o1_strToLong), + OPCODE(o1_invalidate), + OPCODE(o1_setBackDelta), + /* 38 */ + OPCODE(o2_playSound), + OPCODE(o2_stopSound), + OPCODE(o2_loadSound), + OPCODE(o1_freeSoundSlot), + /* 3C */ + OPCODE(o1_waitEndPlay), + OPCODE(o1_playComposition), + OPCODE(o2_getFreeMem), + OPCODE(o2_checkData), + /* 40 */ + {NULL, ""}, + OPCODE(o1_prepareStr), + OPCODE(o1_insertStr), + OPCODE(o1_cutStr), + /* 44 */ + OPCODE(o1_strstr), + OPCODE(o1_istrlen), + OPCODE(o1_setMousePos), + OPCODE(o1_setFrameRate), + /* 48 */ + OPCODE(o1_animatePalette), + OPCODE(o1_animateCursor), + OPCODE(o1_blitCursor), + OPCODE(o1_loadFont), + /* 4C */ + OPCODE(o1_freeFont), + OPCODE(o2_readData), + OPCODE(o2_writeData), + OPCODE(o1_manageDataFile), + }; + + static const OpcodeGoblinEntryBargon opcodesGoblin[71] = { + /* 00 */ + OPCODE(oBargon_intro0), + OPCODE(oBargon_intro1), + OPCODE(oBargon_intro2), + OPCODE(oBargon_intro3), + /* 04 */ + OPCODE(oBargon_intro4), + OPCODE(oBargon_intro5), + OPCODE(oBargon_intro6), + OPCODE(oBargon_intro7), + /* 08 */ + OPCODE(oBargon_intro8), + OPCODE(oBargon_intro9), + OPCODE(o_gobNOP), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 14 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 20 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 24 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + }; + + _opcodesDrawBargon = opcodesDraw; + _opcodesFuncBargon = opcodesFunc; + _opcodesGoblinBargon = opcodesGoblin; +} + +void Inter_Bargon::executeDrawOpcode(byte i) { + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcBargon op = _opcodesDrawBargon[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_Bargon::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d", i, j); + return false; + } + + OpcodeFuncProcBargon op = _opcodesFuncBargon[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (cmdCount, counter, retFlag); + + return false; +} + +void Inter_Bargon::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); + + OpcodeGoblinProcBargon op = NULL; + + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) { + op = _opcodesGoblinBargon[_goblinFuncLookUp[j][1]].proc; + break; + } + + if (op == NULL) { + int16 val; + + _vm->_global->_inter_execPtr -= 2; + val = load16(); + _vm->_global->_inter_execPtr += val << 1; + warning("unimplemented opcodeGob: %d", i); + } + else + (this->*op) (extraData, retVarPtr, objDesc); +} + +const char *Inter_Bargon::getOpcodeDrawDesc(byte i) { + return _opcodesDrawBargon[i].desc; +} + +const char *Inter_Bargon::getOpcodeFuncDesc(byte i, byte j) { + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncBargon[i*16 + j].desc; +} + +const char *Inter_Bargon::getOpcodeGoblinDesc(int i) { + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) + return _opcodesGoblinBargon[_goblinFuncLookUp[j][1]].desc; + return ""; +} + +void Inter_Bargon::oBargon_intro0(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scaa", 0, 160, 0, 92, 0, 1); +} + +void Inter_Bargon::oBargon_intro1(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scaa", 0, 160, 0, -23, 1, 1); +} + +void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + int i; + int16 mouseX; + int16 mouseY; + int16 buttons; + Video::SurfaceDesc *surface; + Snd::SoundDesc *samples[4]; + int8 types[4] = { 2, 2, 2, 2 }; + int16 comp[5] = { 0, 1, 2, 3, -1 }; + static const char *sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; + + surface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); + _vm->_video->drawPackedSprite("2ille.ims", surface); + _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); + _vm->_video->drawPackedSprite("2ille4.ims", surface); + _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); + _vm->_util->setScrollOffset(320); + _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); + _vm->_util->longDelay(1000); + for (i = 320; i >= 0; i--) { + _vm->_util->setScrollOffset(i); + if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || + _vm->_quitRequested) { + _vm->_palanim->fade(0, -2, 0); + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + WRITE_VAR(4, buttons); + WRITE_VAR(0, 0x11B); + WRITE_VAR(57, (uint32) -1); + break; + } + } + if (!_vm->_quitRequested) + _vm->_util->setScrollOffset(0); + _vm->_video->freeSurfDesc(surface); + if (VAR(57) == ((uint32) -1)) + return; + + for (i = 0; i < 4; i++) + samples[i] = _vm->_game->loadSND(sndFiles[i], 0); + _vm->_snd->playComposition(comp, 0, samples, types, 4); + _vm->_snd->waitEndPlay(true, false); + for (i = 0; i < 4; i++) + _vm->_snd->freeSoundDesc(samples[i]); + _vm->_palanim->fade(0, 0, 0); + _vm->_video->clearSurf(_vm->_draw->_frontSurface); +} + +void Inter_Bargon::oBargon_intro3(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + int i; + int j; + int16 mouseX; + int16 mouseY; + int16 buttons; + Video::Color *palBak; + Snd::SoundDesc *samples[2]; + int8 types[2] = { 2, 2 }; + int16 comp[3] = { 0, 1, -1 }; + char *palettes[4]; + static const char *sndFiles[] = {"1INTROIV.snd", "2INTROIV.snd"}; + static const char *palFiles[] = {"2ou2.clt", "2ou3.clt", "2ou4.clt", "2ou5.clt"}; + + for (i = 0; i < 2; i++) + samples[i] = _vm->_game->loadSND(sndFiles[i], 0); + for (i = 0; i < 4; i++) + palettes[i] = _vm->_dataio->getData(palFiles[i]); + palBak = _vm->_global->_pPaletteDesc->vgaPal; + + _vm->_snd->playComposition(comp, 0, samples, types, 2); + for (i = 0; i < 20; i++) { + for (j = 0; j < 4; j++) { + _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *) palettes[j]; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + _vm->_util->longDelay(_vm->_util->getRandom(200)); + } + if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || + _vm->_quitRequested) { + _vm->_snd->stopSound(10); + _vm->_palanim->fade(0, -2, 0); + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + WRITE_VAR(4, buttons); + WRITE_VAR(0, 0x11B); + WRITE_VAR(57, (uint32) -1); + break; + } + } + _vm->_snd->waitEndPlay(false, false); + + _vm->_global->_pPaletteDesc->vgaPal = palBak; + for (i = 0; i < 4; i++) + delete[] palettes[i]; + for (i = 0; i < 2; i++) + _vm->_snd->freeSoundDesc(samples[i]); +} + +void Inter_Bargon::oBargon_intro4(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scba", 191, 54, 0, 0, 1, 1); +} + +void Inter_Bargon::oBargon_intro5(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scbb", 191, 54, 0, 0, 0, 1); +} + +void Inter_Bargon::oBargon_intro6(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scbc", 191, 54, 0, 0, 0, 1); +} + +void Inter_Bargon::oBargon_intro7(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scbf", 191, 54, 0, 0, 0, 1); +} + +void Inter_Bargon::oBargon_intro8(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scbc", 191, 54, 0, 0, 0, 1); +} + +void Inter_Bargon::oBargon_intro9(int16 &extraData, int32 *retVarPtr, + Goblin::Gob_Object *objDesc) { + _vm->_game->playImd("scbd", 191, 54, 0, 0, 0, 1); +} + +} // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index cc84e9036a..22a3ca6d97 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -2387,7 +2387,7 @@ void Inter_v2::animPalette(void) { col = _vm->_global->_pPaletteDesc->vgaPal[_animPalLowIndex[j]]; for (i = _animPalLowIndex[j]; i < _animPalHighIndex[j]; i++) - _vm->_draw->_vgaPalette[i] = _vm->_global->_pPaletteDesc->vgaPal[i + 1]; + _vm->_draw->_vgaPalette[i] = _vm->_draw->_vgaPalette[i + 1]; _vm->_global->_pPaletteDesc->vgaPal[_animPalHighIndex[j]] = col; } else { diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 9b1d5e9675..d1039ba454 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS := \ draw.o \ draw_v1.o \ draw_v2.o \ + draw_bargon.o \ driver_vga.o \ game.o \ game_v1.o \ @@ -23,6 +24,7 @@ MODULE_OBJS := \ inter.o \ inter_v1.o \ inter_v2.o \ + inter_bargon.o \ map.o \ map_v1.o \ map_v2.o \ diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 0fc1ba9770..89d08b7f03 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1304,9 +1304,10 @@ void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, } void Mult_v2::freeMult(void) { - if (_vm->_anim->_animSurf != 0) - delete _vm->_anim->_animSurf; + if ((_vm->_anim->_animSurf != 0) && (_vm->_draw->_spritesArray[22] != 0)) + _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); _vm->_anim->_animSurf = 0; + _vm->_draw->_spritesArray[22] = 0; delete[] _objects; delete[] _renderData2; diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index 7946639c4e..1160b6d2ac 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -141,6 +141,9 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { char stop; int16 i; + if (_vm->_quitRequested) + return; + if (fadeV < 0) _fadeValue = -fadeV; else @@ -187,9 +190,8 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { if (allColors == 0) { do { - _vm->_video->waitRetrace(_vm->_global->_videoMode); - stop = fadeStep(0); + _vm->_video->waitRetrace(_vm->_global->_videoMode); if (fadeV > 0) _vm->_util->delay(fadeV); diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp index 9ee1cb2f98..5475c7407b 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound.cpp @@ -82,6 +82,9 @@ Snd::Snd(GobEngine *vm) : _vm(vm) { _fadeSamples = 0; _curFadeSamples = 0; + _compositionSamples = 0; + _compositionSampleTypes = 0; + _compositionSampleCount = 0; _compositionPos = -1; _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, @@ -119,10 +122,16 @@ void Snd::stopSound(int16 fadeLength) _curFadeSamples = 0; } -void Snd::waitEndPlay(void) { - _compositionPos = -1; - while (!_end && !_vm->_quitRequested) +void Snd::waitEndPlay(bool interruptible, bool stopComp) { + if (stopComp) + _compositionPos = -1; + while (!_end && !_vm->_quitRequested) { + if (interruptible && (_vm->_util->checkKey() == 0x11B)) { + WRITE_VAR(57, -1); + return; + } _vm->_util->longDelay(200); + } stopSound(0); } @@ -137,21 +146,32 @@ void Snd::nextCompositionPos(void) { int8 slot; while ((++_compositionPos < 50) && ((slot = _composition[_compositionPos]) != -1)) { - if ((slot >= 0) && (slot <= 60) && (_vm->_game->_soundSamples[slot] != 0) - && !(_vm->_game->_soundTypes[slot] & 8)) { - setSample(_vm->_game->_soundSamples[slot], 1, 0, 0); + if ((slot >= 0) && (slot < _compositionSampleCount) && + (_compositionSamples[slot] != 0) && !(_compositionSampleTypes[slot] & 8)) { + setSample(_compositionSamples[slot], 1, 0, 0); return; } } _compositionPos = -1; } -void Snd::playComposition(int16 *composition, int16 freqVal) { +void Snd::playComposition(int16 *composition, int16 freqVal, SoundDesc **sndDescs, + int8 *sndTypes, int8 sndCount) { + int i; + waitEndPlay(); stopComposition(); - for (int i = 0; i < 50; i++) + _compositionSamples = sndDescs ? sndDescs : _vm->_game->_soundSamples; + _compositionSampleTypes = sndTypes ? sndTypes : _vm->_game->_soundTypes; + _compositionSampleCount = sndCount; + + i = -1; + do { + i++; _composition[i] = composition[i]; + } while ((i < 50) && (composition[i] != -1)); + nextCompositionPos(); } @@ -255,7 +275,7 @@ int Snd::readBuffer(int16 *buffer, const int numSamples) { *buffer++ = (int16) ((_last + (_cur - _last) * _frac) * _fadeVol); _frac += _ratio; _offset += _ratio; - while (_frac > 1) { + while ((_frac > 1) && (_offset < _length)) { _frac -= 1; _last = _cur; _cur = _data[(int) _offset]; diff --git a/engines/gob/sound.h b/engines/gob/sound.h index acd003b0b9..773193af36 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound.h @@ -54,9 +54,10 @@ public: SoundDesc *loadSoundData(const char *path); void stopSound(int16 fadeLength); void playSample(SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength = 0); - void playComposition(int16 *composition, int16 freqVal); + void playComposition(int16 *composition, int16 freqVal, SoundDesc **sndDescs = 0, + int8 *sndTypes = 0, int8 sndCount = 60); void stopComposition(void); - void waitEndPlay(void); + void waitEndPlay(bool interruptible = false, bool stopComp = true); // This deletes sndDesc and stops playing the sample. // If freedata is set, it also delete[]s the sample data. @@ -95,9 +96,12 @@ protected: SquareWaveStream _speakerStream; Audio::SoundHandle _speakerHandle; - Audio::SoundHandle *_activeHandle; Audio::SoundHandle _compositionHandle; + + SoundDesc **_compositionSamples; + int8 *_compositionSampleTypes; + int8 _compositionSampleCount; int16 _composition[50]; int8 _compositionPos; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 6ea2adb11c..675d7a6f23 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -301,6 +301,14 @@ void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, i _videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest); } +void Video::drawPackedSprite(const char *path, SurfaceDesc * dest, int width) { + char *data; + + data = _vm->_dataio->getData(path); + drawPackedSprite((byte *) data, width, dest->height, 0, 0, 0, dest); + delete[] data; +} + void Video::setPalElem(int16 index, char red, char green, char blue, int16 unused, int16 vidMode) { byte pal[4]; diff --git a/engines/gob/video.h b/engines/gob/video.h index 3f6b5152e8..f59fa48191 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -109,6 +109,7 @@ public: void clearSurf(SurfaceDesc * dest); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, int16 transp, SurfaceDesc * dest); + void drawPackedSprite(const char *path, SurfaceDesc * dest, int width = 320); void setPalElem(int16 index, char red, char green, char blue, int16 unused, int16 vidMode); void setPalette(PalDesc * palDesc); |