diff options
Diffstat (limited to 'engines/parallaction')
31 files changed, 2205 insertions, 1626 deletions
diff --git a/engines/parallaction/animation.cpp b/engines/parallaction/animation.cpp index d4f538c451..118f35e705 100644 --- a/engines/parallaction/animation.cpp +++ b/engines/parallaction/animation.cpp @@ -468,7 +468,7 @@ void jobRunScripts(void *parm, Job *j) { while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) { - debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _instructionNamesRes[(*inst)->_index - 1]); + debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _vm->_instructionNamesRes[(*inst)->_index - 1]); switch ((*inst)->_index) { case INST_ENDLOOP: // endloop @@ -566,7 +566,7 @@ void jobRunScripts(void *parm, Job *j) { case INST_CALL: // call - _callables[(*inst)->_opBase._index](0); + _vm->callFunction((*inst)->_opBase._index, 0); break; case INST_WAIT: // wait diff --git a/engines/parallaction/archive.cpp b/engines/parallaction/archive.cpp deleted file mode 100644 index 9eef3f44e9..0000000000 --- a/engines/parallaction/archive.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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/file.h" - -#include "parallaction/disk.h" -#include "parallaction/parallaction.h" - - -namespace Parallaction { - -// HACK: Several archives ('de', 'en', 'fr' and 'disk0') in the multi-lingual -// Amiga version of Nippon Safes, and one archive ('fr') in the Amiga Demo of -// Nippon Safes used different internal offsets than all the other archives. -// -// When an archive is opened in the Amiga demo, its size is checked against -// SIZEOF_SMALL_ARCHIVE to detect when the smaller archive is used. -// -// When an archive is opened in Amiga multi-lingual version, the header is -// checked again NDOS to detect when a smaller archive is used. -// -#define SIZEOF_SMALL_ARCHIVE 12778 - -#define ARCHIVE_FILENAMES_OFS 0x16 - -#define NORMAL_ARCHIVE_FILES_NUM 384 -#define SMALL_ARCHIVE_FILES_NUM 180 - -#define NORMAL_ARCHIVE_SIZES_OFS 0x3016 -#define SMALL_ARCHIVE_SIZES_OFS 0x1696 - -#define NORMAL_ARCHIVE_DATA_OFS 0x4000 -#define SMALL_ARCHIVE_DATA_OFS 0x1966 - -Archive::Archive() { - resetArchivedFile(); -} - -void Archive::open(const char *file) { - debugC(1, kDebugDisk, "Archive::open(%s)", file); - - if (_archive.isOpen()) - close(); - - char path[PATH_LEN]; - - strcpy(path, file); - if (!_archive.open(path)) - error("archive '%s' not found", path); - - _archiveName = file; - - bool isSmallArchive = false; - if (_vm->getPlatform() == Common::kPlatformAmiga) { - if (_vm->getFeatures() & GF_DEMO) { - isSmallArchive = _archive.size() == SIZEOF_SMALL_ARCHIVE; - } else if (_vm->getFeatures() & GF_LANG_MULT) { - isSmallArchive = (_archive.readUint32BE() != MKID_BE('NDOS')); - } - } - - _numFiles = (isSmallArchive) ? SMALL_ARCHIVE_FILES_NUM : NORMAL_ARCHIVE_FILES_NUM; - - _archive.seek(ARCHIVE_FILENAMES_OFS); - _archive.read(_archiveDir, _numFiles*32); - - _archive.seek((isSmallArchive) ? SMALL_ARCHIVE_SIZES_OFS : NORMAL_ARCHIVE_SIZES_OFS); - - uint32 dataOffset = (isSmallArchive) ? SMALL_ARCHIVE_DATA_OFS : NORMAL_ARCHIVE_DATA_OFS; - for (uint16 i = 0; i < _numFiles; i++) { - _archiveOffsets[i] = dataOffset; - _archiveLenghts[i] = _archive.readUint32BE(); - dataOffset += _archiveLenghts[i]; - } - - return; -} - - -void Archive::close() { - if (!_archive.isOpen()) return; - - resetArchivedFile(); - - _archive.close(); - _archiveName.clear(); -} - -Common::String Archive::name() const { - return _archiveName; -} - -bool Archive::openArchivedFile(const char *filename) { - debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); - - resetArchivedFile(); - - debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); - - if (!_archive.isOpen()) - error("Archive::openArchivedFile: the archive is not open"); - - uint16 i = 0; - for ( ; i < _numFiles; i++) { - if (!scumm_stricmp(_archiveDir[i], filename)) break; - } - if (i == _numFiles) return false; - - debugC(9, kDebugDisk, "Archive::openArchivedFile: '%s' found in slot %i", filename, i); - - _file = true; - - _fileOffset = _archiveOffsets[i]; - _fileCursor = _archiveOffsets[i]; - _fileEndOffset = _archiveOffsets[i] + _archiveLenghts[i]; - - _archive.seek(_fileOffset); - - return true; -} - -void Archive::resetArchivedFile() { - _file = false; - _fileCursor = 0; - _fileOffset = 0; - _fileEndOffset = 0; -} - -void Archive::closeArchivedFile() { - resetArchivedFile(); -} - - -uint32 Archive::size() const { - return (_file == true ? _fileEndOffset - _fileOffset : 0); -} - -uint32 Archive::pos() const { - return (_file == true ? _fileCursor - _fileOffset : 0 ); -} - -bool Archive::eos() const { - return (_file == true ? _fileCursor == _fileEndOffset : true ); -} - -void Archive::seek(int32 offs, int whence) { - assert(_file == true && _fileCursor <= _fileEndOffset); - - switch (whence) { - case SEEK_CUR: - _fileCursor += offs; - break; - case SEEK_SET: - _fileCursor = _fileOffset + offs; - break; - case SEEK_END: - _fileCursor = _fileEndOffset - offs; - break; - } - assert(_fileCursor <= _fileEndOffset && _fileCursor >= _fileOffset); - - _archive.seek(_fileCursor, SEEK_SET); -} - -uint32 Archive::read(void *dataPtr, uint32 dataSize) { -// printf("read(%i, %i)\n", file->_cursor, file->_endOffset); - if (_file == false) - error("Archive::read: no archived file is currently open"); - - if (_fileCursor >= _fileEndOffset) - error("can't read beyond end of archived file"); - - if (_fileEndOffset - _fileCursor < dataSize) - dataSize = _fileEndOffset - _fileCursor; - - int32 readBytes = _archive.read(dataPtr, dataSize); - _fileCursor += readBytes; - - return readBytes; -} - - - -} // namespace Parallaction diff --git a/engines/parallaction/callables.cpp b/engines/parallaction/callables.cpp deleted file mode 100644 index be92ca1daa..0000000000 --- a/engines/parallaction/callables.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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/system.h" - -#include "common/file.h" - -#include "parallaction/parallaction.h" -#include "parallaction/menu.h" -#include "parallaction/sound.h" - - -namespace Parallaction { - - - - -static Zone *_moveSarcZones[5]; -static Zone *_moveSarcExaZones[5]; - -void _c_null(void *parm) { - - return; -} - -void _c_play_boogie(void *parm) { - - static uint16 flag = 1; - - if (flag == 0) - return; - flag = 0; - - _vm->_soundMan->setMusicFile("boogie2"); - _vm->_soundMan->playMusic(); - - return; -} - - -void _c_score(void *parm) { - _score += 5; - return; -} - -void _c_fade(void *parm) { - - _vm->_gfx->setBlackPalette(); - - Gfx::Palette pal; - memset(pal, 0, sizeof(Gfx::Palette)); - - for (uint16 _di = 0; _di < 64; _di++) { - _vm->_gfx->fadePalette(pal); - _vm->_gfx->setPalette(pal); - - _vm->waitTime( 1 ); - } - - return; -} - -Zone *_moveSarcZone0 = NULL; -int16 _introSarcData1 = 0; -Zone *_moveSarcZone1 = NULL; - -void _c_moveSarc(void *parm) { - - Animation *a; - - if (_introSarcData2 != 0) { - - _introSarcData2 = 0; - if (_moveSarcZones[0] == NULL) { - - _moveSarcZones[0] = _vm->findZone("sarc1"); - _moveSarcZones[1] = _vm->findZone("sarc2"); - _moveSarcZones[2] = _vm->findZone("sarc3"); - _moveSarcZones[3] = _vm->findZone("sarc4"); - _moveSarcZones[4] = _vm->findZone("sarc5"); - - _moveSarcExaZones[0] = _vm->findZone("sarc1exa"); - _moveSarcExaZones[1] = _vm->findZone("sarc2exa"); - _moveSarcExaZones[2] = _vm->findZone("sarc3exa"); - _moveSarcExaZones[3] = _vm->findZone("sarc4exa"); - _moveSarcExaZones[4] = _vm->findZone("sarc5exa"); - - } - - a = _vm->findAnimation("sposta"); - - _moveSarcZone1 = (Zone*)parm; - - for (uint16 _si = 0; _si < 5; _si++) { - if (_moveSarcZones[_si] == _moveSarcZone1) { - _moveSarcZone0 = _moveSarcExaZones[_si]; - } - } - - _introSarcData1 = _introSarcData3 - _moveSarcZone1->_left; - a->_z = _introSarcData3; - a->_frame = _moveSarcZone1->_top - (_introSarcData1 / 20); - _introSarcData3 = _moveSarcZone1->_left; - - if (_introSarcData1 > 0) { - a->_left = _introSarcData1 / 2; - } else { - a->_left = -_introSarcData1 / 2; - } - - if (_introSarcData1 > 0) { - a->_top = 2; - } else { - a->_top = -2; - } - - return; - - } - - _introSarcData2 = 1; - _moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20); - _moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20); - - if (_moveSarcZones[0]->_left == 35 && - _moveSarcZones[1]->_left == 68 && - _moveSarcZones[2]->_left == 101 && - _moveSarcZones[3]->_left == 134 && - _moveSarcZones[4]->_left == 167) { - - a = _vm->findAnimation("finito"); - - a->_flags |= (kFlagsActive | kFlagsActing); - _localFlags[_vm->_currentLocationIndex] |= 0x20; // GROSS HACK: activates 'finito' flag in dinoit_museo.loc - } - - return; - -} - - -static uint16 num_foglie = 0; - -void _c_contaFoglie(void *parm) { - - num_foglie++; - if (num_foglie != 6) - return; - - _commandFlags |= 0x1000; - - return; -} - -void _c_zeroFoglie(void *parm) { - num_foglie = 0; - return; -} - -void _c_trasformata(void *parm) { - _engineFlags ^= kEngineTransformedDonna; - return; -} - -void _c_offMouse(void *parm) { - _vm->showCursor(false); - _engineFlags |= kEngineBlockInput; - return; -} - -void _c_onMouse(void *parm) { - _engineFlags &= ~kEngineBlockInput; - _vm->showCursor(true); - return; -} - - - -void _c_setMask(void *parm) { - - _vm->_gfx->intGrottaHackMask(); - - return; -} - -void _c_endComment(void *param) { - - byte* _enginePal = _vm->_gfx->_palette; - Gfx::Palette pal; - - uint32 si; - for (si = 0; si < 32; si++) { - - byte al = _enginePal[si*3+1]; - if (al > _enginePal[si*3+2]) { - al = _enginePal[si*3+1]; - } else { - al = _enginePal[si*3+2]; - } - - if (al < _enginePal[si*3]) { - al = _enginePal[si*3]; - } else { - al = _enginePal[si*3+1]; - } - - if (al > _enginePal[si*3+2]) { - al = _enginePal[si*3+1]; - } else { - al = _enginePal[si*3+2]; - } - - pal[si*3] = al; - pal[si*3+2] = al; - pal[si*3+1] = al; - - } - - int16 w = 0, h = 0; - _vm->_gfx->getStringExtent(_vm->_location._endComment, 130, &w, &h); - - Common::Rect r(w+5, h+5); - r.moveTo(5, 5); - _vm->_gfx->floodFill(Gfx::kBitFront, r, 0); - - r.setWidth(w+3); - r.setHeight(h+3); - r.moveTo(7, 7); - _vm->_gfx->floodFill(Gfx::kBitFront, r, 1); - - _vm->_gfx->setFont(kFontDialogue); - _vm->_gfx->displayWrappedString(_vm->_location._endComment, 3, 5, 0, 130); - _vm->_gfx->updateScreen(); - - uint32 di = 0; - for (di = 0; di < PALETTE_COLORS; di++) { - for (si = 0; si <= 93; si +=3) { - - int8 al; - - if (_enginePal[si] != pal[si]) { - al = _enginePal[si]; - if (al > pal[si]) - al = 1; - else - al = -1; - _enginePal[si] += al; - } - - if (_enginePal[si+1] != pal[si+1]) { - al = _enginePal[si+1]; - if (al > pal[si+1]) - al = 1; - else - al = -1; - _enginePal[si+1] += al; - } - - if (_enginePal[si+2] != pal[si+2]) { - al = _enginePal[si+2]; - if (al > pal[si+2]) - al = 1; - else - al = -1; - _enginePal[si+2] += al; - } - - } - - _vm->_gfx->setPalette(_enginePal); - } - - waitUntilLeftClick(); - - return; -} - -void _c_frankenstein(void *parm) { - - Gfx::Palette pal0; - Gfx::Palette pal1; - - for (uint16 i = 0; i <= BASE_PALETTE_COLORS; i++) { - pal0[(i+FIRST_BASE_COLOR)] = _vm->_gfx->_palette[i]; - pal0[(i+FIRST_BASE_COLOR)*3+1] = 0; - pal0[(i+FIRST_BASE_COLOR)*3+2] = 0; - - pal1[(i+FIRST_BASE_COLOR)*3+1] = 0; - pal1[(i+FIRST_BASE_COLOR)*3+2] = 0; - } - - for (uint16 _di = 0; _di < 30; _di++) { - g_system->delayMillis(20); - _vm->_gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); - g_system->delayMillis(20); - _vm->_gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); - } - - _vm->_gfx->setPalette(_vm->_gfx->_palette); - - return; -} -// part completion messages -const char *endMsg0[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"}; -const char *endMsg1[] = {"HAI FINITO QUESTA PARTE", "TU AS COMPLETE' CETTE AVENTURE", "YOU HAVE COMPLETED THIS PART", "DU HAST EIN ABENTEUER ERFOLGREICH"}; -const char *endMsg2[] = {"ORA COMPLETA IL RESTO ", "AVEC SUCCES.", "NOW GO ON WITH THE REST OF", "ZU ENDE GEFUHRT"}; -const char *endMsg3[] = {"DELL' AVVENTURA", "CONTINUE AVEC LES AUTRES", "THIS ADVENTURE", "MACH' MIT DEN ANDEREN WEITER"}; -// game completion messages -const char *endMsg4[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"}; -const char *endMsg5[] = {"HAI FINITO LE TRE PARTI", "TU AS COMPLETE' LES TROIS PARTIES", "YOU HAVE COMPLETED THE THREE PARTS", "DU HAST DREI ABENTEURE ERFOLGREICH"}; -const char *endMsg6[] = {"DELL' AVVENTURA", "DE L'AVENTURE", "OF THIS ADVENTURE", "ZU ENDE GEFUHRT"}; -const char *endMsg7[] = {"ED ORA IL GRAN FINALE ", "ET MAINTENANT LE GRAND FINAL", "NOW THE GREAT FINAL", "UND YETZT DER GROSSE SCHLUSS!"}; - - -void _c_finito(void *parm) { - - const char **v8C = endMsg0; - const char **v7C = endMsg1; - const char **v6C = endMsg2; - const char **v5C = endMsg3; - const char **v4C = endMsg4; - const char **v3C = endMsg5; - const char **v2C = endMsg6; - const char **v1C = endMsg7; - - Common::File stream; - - stream.open(_vm->_characterName, Common::File::kFileWriteMode); - if (stream.isOpen()) - stream.close(); - - Common::File streamDino, streamDough, streamDonna; - - streamDino.open("dino"); - streamDough.open("dough"); - streamDonna.open("donna"); - - bool gameCompleted = streamDino.isOpen() && streamDough.isOpen() && streamDonna.isOpen(); - - streamDino.close(); - streamDough.close(); - streamDonna.close(); - - cleanInventory(); - - _vm->_gfx->setPalette(_vm->_gfx->_palette); - - if (gameCompleted) { - _vm->_gfx->setFont(kFontMenu); - _vm->_gfx->displayCenteredString(70, v4C[_language]); - _vm->_gfx->displayCenteredString(100, v3C[_language]); - _vm->_gfx->displayCenteredString(130, v2C[_language]); - _vm->_gfx->displayCenteredString(160, v1C[_language]); - - _vm->_gfx->updateScreen(); - waitUntilLeftClick(); - - strcpy(_vm->_location._name, "estgrotta.drki"); - - _engineFlags |= kEngineChangeLocation; - } else { - _vm->_gfx->setFont(kFontMenu); - _vm->_gfx->displayCenteredString(70, v8C[_language]); - _vm->_gfx->displayCenteredString(100, v7C[_language]); - _vm->_gfx->displayCenteredString(130, v6C[_language]); - _vm->_gfx->displayCenteredString(160, v5C[_language]); - - _vm->_gfx->updateScreen(); - waitUntilLeftClick(); - - _vm->_menu->selectCharacter(); - } - - // this code saves main character animation from being removed from the following code - _vm->_animations.remove(&_vm->_char._ani); - _vm->_locationNames[0][0] = '\0'; - _vm->_numLocations = 0; - _commandFlags = 0; - - // this flag tells freeZones to unconditionally remove *all* Zones - _engineFlags |= kEngineQuit; - - // TODO (LIST): this sequence should be just _zones.clear() - _vm->freeZones(); - - // TODO (LIST): this sequence should be just _animations.clear() - _vm->freeAnimations(); - - // this dangerous flag can now be cleared - _engineFlags &= ~kEngineQuit; - - // main character animation is restored - _vm->_animations.push_front(&_vm->_char._ani); - _score = 0; - - return; -} - -void _c_ridux(void *parm) { - _vm->changeCharacter(_minidinoName); - return; -} - -void _c_testResult(void *parm) { - _vm->_gfx->swapBuffers(); - - _vm->_disk->selectArchive("disk1"); - _vm->parseLocation("common"); - - _vm->_gfx->setFont(kFontMenu); - - _vm->_gfx->displayCenteredString(38, _slideText[0]); - _vm->_gfx->displayCenteredString(58, _slideText[1]); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); - - return; -} - -void _c_offSound(void*) { - _vm->_soundMan->stopSfx(0); - _vm->_soundMan->stopSfx(1); - _vm->_soundMan->stopSfx(2); - _vm->_soundMan->stopSfx(3); -} - -void _c_startMusic(void*) { - _vm->_soundMan->playMusic(); -} - -void _c_closeMusic(void*) { - _vm->_soundMan->stopMusic(); -} - -} // namespace Parallaction diff --git a/engines/parallaction/callables_br.cpp b/engines/parallaction/callables_br.cpp new file mode 100644 index 0000000000..829195fd7a --- /dev/null +++ b/engines/parallaction/callables_br.cpp @@ -0,0 +1,60 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 "parallaction/parallaction.h" + +namespace Parallaction { + + +void Parallaction_br::_c_blufade(void*) { + warning("Parallaction_br::_c_blufade() not yet implemented"); +} + +void Parallaction_br::_c_resetpalette(void*) { + warning("Parallaction_br::_c_resetpalette() not yet implemented"); +} + +void Parallaction_br::_c_ferrcycle(void*) { + warning("Parallaction_br::_c_ferrcycle() not yet implemented"); +} + +void Parallaction_br::_c_lipsinc(void*) { + warning("Parallaction_br::_c_lipsinc() not yet implemented"); +} + +void Parallaction_br::_c_albcycle(void*) { + warning("Parallaction_br::_c_albcycle() not yet implemented"); +} + +void Parallaction_br::_c_password(void*) { + warning("Parallaction_br::_c_password() not yet implemented"); +} + + + + +} // namespace Parallaction diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp new file mode 100644 index 0000000000..94a0747ab1 --- /dev/null +++ b/engines/parallaction/callables_ns.cpp @@ -0,0 +1,718 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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/system.h" + +#include "common/file.h" + +#include "graphics/primitives.h" // for Graphics::drawLine + +#include "parallaction/parallaction.h" +#include "parallaction/menu.h" +#include "parallaction/sound.h" + + +namespace Parallaction { + +/* + game callables data members +*/ + +static Zone *_moveSarcZone0 = NULL; +static int16 _introSarcData1 = 0; +static Zone *_moveSarcZone1 = NULL; + +// part completion messages +static const char *endMsg0[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"}; +static const char *endMsg1[] = {"HAI FINITO QUESTA PARTE", "TU AS COMPLETE' CETTE AVENTURE", "YOU HAVE COMPLETED THIS PART", "DU HAST EIN ABENTEUER ERFOLGREICH"}; +static const char *endMsg2[] = {"ORA COMPLETA IL RESTO ", "AVEC SUCCES.", "NOW GO ON WITH THE REST OF", "ZU ENDE GEFUHRT"}; +static const char *endMsg3[] = {"DELL' AVVENTURA", "CONTINUE AVEC LES AUTRES", "THIS ADVENTURE", "MACH' MIT DEN ANDEREN WEITER"}; +// game completion messages +static const char *endMsg4[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"}; +static const char *endMsg5[] = {"HAI FINITO LE TRE PARTI", "TU AS COMPLETE' LES TROIS PARTIES", "YOU HAVE COMPLETED THE THREE PARTS", "DU HAST DREI ABENTEURE ERFOLGREICH"}; +static const char *endMsg6[] = {"DELL' AVVENTURA", "DE L'AVENTURE", "OF THIS ADVENTURE", "ZU ENDE GEFUHRT"}; +static const char *endMsg7[] = {"ED ORA IL GRAN FINALE ", "ET MAINTENANT LE GRAND FINAL", "NOW THE GREAT FINAL", "UND YETZT DER GROSSE SCHLUSS!"}; + +static uint16 num_foglie = 0; +static Zone *_moveSarcZones[5]; +static Zone *_moveSarcExaZones[5]; + +/* + intro callables data members +*/ + +static Animation *_rightHandAnim; + +static uint16 _rightHandPositions[684] = { + 0x0064, 0x0046, 0x006c, 0x0046, 0x0074, 0x0046, 0x007c, 0x0046, + 0x0084, 0x0046, 0x008c, 0x0046, 0x0094, 0x0046, 0x009c, 0x0046, + 0x00a4, 0x0046, 0x00ac, 0x0046, 0x00b4, 0x0046, 0x00bc, 0x0046, + 0x00c4, 0x0046, 0x00cc, 0x0046, 0x00d4, 0x0046, 0x00dc, 0x0046, + 0x00e4, 0x0046, 0x00ec, 0x0046, 0x00f4, 0x0046, 0x00fc, 0x0046, + 0x0104, 0x0046, 0x00ff, 0x0042, 0x00ff, 0x004a, 0x00ff, 0x0052, + 0x00ff, 0x005a, 0x00ff, 0x0062, 0x00ff, 0x006a, 0x00ff, 0x0072, + 0x00ff, 0x007a, 0x00ff, 0x0082, 0x00ff, 0x008a, 0x00ff, 0x0092, + 0x00ff, 0x009a, 0x00ff, 0x00a2, 0x0104, 0x0097, 0x00fc, 0x0097, + 0x00f4, 0x0097, 0x00ec, 0x0097, 0x00e4, 0x0097, 0x00dc, 0x0097, + 0x00d4, 0x0097, 0x00cc, 0x0097, 0x00c4, 0x0097, 0x00bc, 0x0097, + 0x00b4, 0x0097, 0x00ac, 0x0097, 0x00a4, 0x0097, 0x009c, 0x0097, + 0x0094, 0x0097, 0x008c, 0x0097, 0x0084, 0x0097, 0x007c, 0x0097, + 0x0074, 0x0097, 0x006c, 0x0097, 0x0064, 0x0097, 0x0066, 0x0042, + 0x0066, 0x004a, 0x0066, 0x0052, 0x0066, 0x005a, 0x0066, 0x0062, + 0x0066, 0x006a, 0x0066, 0x0072, 0x0066, 0x007a, 0x0066, 0x0082, + 0x0066, 0x008a, 0x0066, 0x0092, 0x0066, 0x009a, 0x0066, 0x00a2, + 0x008c, 0x0091, 0x0099, 0x0042, 0x0099, 0x004a, 0x0099, 0x0052, + 0x0099, 0x005a, 0x0099, 0x0062, 0x0099, 0x006a, 0x0099, 0x0072, + 0x0099, 0x007a, 0x0099, 0x0082, 0x0099, 0x008a, 0x0099, 0x0092, + 0x0099, 0x009a, 0x0099, 0x00a2, 0x00a0, 0x004d, 0x00cc, 0x0042, + 0x00cc, 0x004a, 0x00cc, 0x0052, 0x00cc, 0x005a, 0x00cc, 0x0062, + 0x00cc, 0x006a, 0x00cc, 0x0072, 0x00cc, 0x007a, 0x00cc, 0x0082, + 0x00cc, 0x008a, 0x00cc, 0x0092, 0x00cc, 0x009a, 0x00cc, 0x00a2, + 0x00ca, 0x0050, 0x00b1, 0x0050, 0x0081, 0x0052, 0x007e, 0x0052, + 0x007c, 0x0055, 0x007c, 0x005c, 0x007e, 0x005e, 0x0080, 0x005e, + 0x0082, 0x005c, 0x0082, 0x0054, 0x0080, 0x0052, 0x0078, 0x0052, + 0x007c, 0x005e, 0x0077, 0x0061, 0x0074, 0x006e, 0x0074, 0x0078, + 0x0076, 0x007a, 0x0079, 0x0078, 0x0079, 0x0070, 0x0078, 0x0070, + 0x0078, 0x006b, 0x007b, 0x0066, 0x007a, 0x006f, 0x0084, 0x006f, + 0x0085, 0x0066, 0x0086, 0x0070, 0x0085, 0x0070, 0x0085, 0x0079, + 0x0088, 0x0079, 0x008a, 0x0078, 0x008a, 0x006c, 0x0087, 0x0061, + 0x0085, 0x005f, 0x0082, 0x005f, 0x0080, 0x0061, 0x007e, 0x0061, + 0x007b, 0x005f, 0x007c, 0x006f, 0x007c, 0x0071, 0x0079, 0x0074, + 0x0079, 0x0089, 0x0076, 0x008c, 0x0076, 0x008e, 0x007a, 0x008e, + 0x007f, 0x0089, 0x007f, 0x0083, 0x007e, 0x0083, 0x007e, 0x0077, + 0x0080, 0x0077, 0x0080, 0x0083, 0x0080, 0x008b, 0x0084, 0x0090, + 0x0088, 0x0090, 0x0088, 0x008e, 0x0085, 0x008b, 0x0085, 0x0074, + 0x0082, 0x0071, 0x00b2, 0x0052, 0x00b0, 0x0054, 0x00b0, 0x0056, + 0x00ae, 0x0058, 0x00af, 0x0059, 0x00af, 0x005e, 0x00b2, 0x0061, + 0x00b5, 0x0061, 0x00b8, 0x005e, 0x00b8, 0x005a, 0x00b9, 0x0059, + 0x00b9, 0x0058, 0x00b7, 0x0056, 0x00b7, 0x0054, 0x00b5, 0x0052, + 0x00b2, 0x0052, 0x00ae, 0x005a, 0x00ab, 0x005b, 0x00ab, 0x006d, + 0x00ae, 0x0072, 0x00b8, 0x0072, 0x00bc, 0x006d, 0x00bc, 0x005b, + 0x00b9, 0x005a, 0x00bc, 0x005c, 0x00be, 0x005c, 0x00c1, 0x005f, + 0x00c4, 0x0067, 0x00c4, 0x006d, 0x00c1, 0x0076, 0x00c0, 0x0077, + 0x00bd, 0x0077, 0x00bb, 0x0075, 0x00bd, 0x0073, 0x00bb, 0x0072, + 0x00be, 0x0070, 0x00be, 0x006a, 0x00a9, 0x006a, 0x00a9, 0x0070, + 0x00ac, 0x0072, 0x00aa, 0x0073, 0x00ac, 0x0075, 0x00aa, 0x0077, + 0x00a7, 0x0077, 0x00a3, 0x006d, 0x00a3, 0x0067, 0x00a6, 0x005f, + 0x00a9, 0x005c, 0x00ab, 0x005c, 0x00ac, 0x0077, 0x00ac, 0x007c, + 0x00ab, 0x007c, 0x00ab, 0x0084, 0x00ac, 0x0084, 0x00ac, 0x008b, + 0x00a9, 0x008e, 0x00a9, 0x0090, 0x00ae, 0x0090, 0x00ae, 0x008d, + 0x00b2, 0x008c, 0x00b2, 0x0087, 0x00b1, 0x0086, 0x00b1, 0x007b, + 0x00b2, 0x0079, 0x00b4, 0x0079, 0x00b4, 0x007d, 0x00b5, 0x007d, + 0x00b5, 0x0087, 0x00b4, 0x0087, 0x00b4, 0x008c, 0x00b6, 0x008c, + 0x00b9, 0x0091, 0x00b4, 0x0091, 0x00bd, 0x008f, 0x00ba, 0x008c, + 0x00ba, 0x0083, 0x00bb, 0x0082, 0x00bb, 0x0075, 0x00cc, 0x006e, + 0x00d4, 0x006c, 0x00db, 0x0069, 0x00d9, 0x0068, 0x00d9, 0x0064, + 0x00dc, 0x0064, 0x00dc, 0x0060, 0x00df, 0x0056, 0x00e5, 0x0052, + 0x00e7, 0x0052, 0x00ec, 0x0056, 0x00ef, 0x005d, 0x00f1, 0x0065, + 0x00f3, 0x0064, 0x00f3, 0x0069, 0x00f0, 0x0069, 0x00ec, 0x0065, + 0x00ec, 0x005e, 0x00e9, 0x005f, 0x00e9, 0x005a, 0x00e7, 0x0058, + 0x00e4, 0x0058, 0x00e3, 0x0054, 0x00e3, 0x0058, 0x00e1, 0x005c, + 0x00e4, 0x0061, 0x00e7, 0x0061, 0x00e9, 0x005f, 0x00eb, 0x005d, + 0x00e4, 0x0062, 0x00e0, 0x0064, 0x00e0, 0x0069, 0x00e2, 0x006b, + 0x00e0, 0x0072, 0x00e0, 0x0077, 0x00ec, 0x0077, 0x00ec, 0x0071, + 0x00ea, 0x006b, 0x00ec, 0x006a, 0x00ec, 0x0063, 0x00e7, 0x0063, + 0x00e7, 0x0065, 0x00e1, 0x0069, 0x00e3, 0x0068, 0x00e6, 0x0069, + 0x00ec, 0x005e, 0x00ea, 0x006b, 0x00e7, 0x006b, 0x00e7, 0x006a, + 0x00e5, 0x006a, 0x00e5, 0x006b, 0x00e2, 0x006b, 0x00df, 0x006c, + 0x00dc, 0x006f, 0x00dc, 0x0071, 0x00da, 0x0073, 0x00d8, 0x0073, + 0x00d8, 0x006f, 0x00dc, 0x006b, 0x00dc, 0x0069, 0x00dd, 0x0068, + 0x00ef, 0x0068, 0x00f0, 0x0069, 0x00f0, 0x006b, 0x00f4, 0x006f, + 0x00f4, 0x0072, 0x00f3, 0x0073, 0x00f2, 0x0073, 0x00f0, 0x0071, + 0x00f0, 0x006f, 0x00ec, 0x006b, 0x00ec, 0x007a, 0x00eb, 0x007b, + 0x00eb, 0x007f, 0x00ec, 0x0080, 0x00ec, 0x0084, 0x00eb, 0x0085, + 0x00eb, 0x008b, 0x00ec, 0x008c, 0x00ec, 0x008f, 0x00ed, 0x0091, + 0x00e9, 0x0091, 0x00e9, 0x008f, 0x00e7, 0x008d, 0x00e7, 0x0090, + 0x00e7, 0x0089, 0x00e8, 0x0088, 0x00e8, 0x0086, 0x00e7, 0x0085, + 0x00e7, 0x007d, 0x00e6, 0x007c, 0x00e6, 0x0078, 0x00e5, 0x007d, + 0x00e5, 0x0085, 0x00e4, 0x0086, 0x00e4, 0x0088, 0x00e5, 0x0089, + 0x00e5, 0x0090, 0x00e5, 0x008b, 0x00e3, 0x0091, 0x00df, 0x0091, + 0x00e0, 0x0090, 0x00e0, 0x008c, 0x00e2, 0x008b, 0x00e1, 0x0085, + 0x00e0, 0x0084, 0x00e0, 0x0080, 0x00e1, 0x007f, 0x00e1, 0x007c, + 0x00e0, 0x007b, 0x00e0, 0x0077 +}; + +struct Credit { + const char *_role; + const char *_name; +} _credits[] = { + {"Music and Sound Effects", "MARCO CAPRELLI"}, + {"PC Version", "RICCARDO BALLARINO"}, + {"Project Manager", "LOVRANO CANEPA"}, + {"Production", "BRUNO BOZ"}, + {"Special Thanks to", "LUIGI BENEDICENTI - GILDA and DANILO"}, + {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"} +}; + +/* + game callables +*/ + +void Parallaction_ns::_c_null(void *parm) { + + return; +} + +void Parallaction_ns::_c_play_boogie(void *parm) { + + static uint16 flag = 1; + + if (flag == 0) + return; + flag = 0; + + _soundMan->setMusicFile("boogie2"); + _soundMan->playMusic(); + + return; +} + + +void Parallaction_ns::_c_score(void *parm) { + _score += 5; + return; +} + +void Parallaction_ns::_c_fade(void *parm) { + + _gfx->setBlackPalette(); + + Gfx::Palette pal; + memset(pal, 0, sizeof(Gfx::Palette)); + + for (uint16 _di = 0; _di < 64; _di++) { + _gfx->fadePalette(pal, _gfx->_palette, 1); + _gfx->setPalette(pal); + + _gfx->updateScreen(); + g_system->delayMillis(20); + } + + return; +} + + + +void Parallaction_ns::_c_moveSarc(void *parm) { + + Animation *a; + + if (_introSarcData2 != 0) { + + _introSarcData2 = 0; + if (_moveSarcZones[0] == NULL) { + + _moveSarcZones[0] = findZone("sarc1"); + _moveSarcZones[1] = findZone("sarc2"); + _moveSarcZones[2] = findZone("sarc3"); + _moveSarcZones[3] = findZone("sarc4"); + _moveSarcZones[4] = findZone("sarc5"); + + _moveSarcExaZones[0] = findZone("sarc1exa"); + _moveSarcExaZones[1] = findZone("sarc2exa"); + _moveSarcExaZones[2] = findZone("sarc3exa"); + _moveSarcExaZones[3] = findZone("sarc4exa"); + _moveSarcExaZones[4] = findZone("sarc5exa"); + + } + + a = findAnimation("sposta"); + + _moveSarcZone1 = (Zone*)parm; + + for (uint16 _si = 0; _si < 5; _si++) { + if (_moveSarcZones[_si] == _moveSarcZone1) { + _moveSarcZone0 = _moveSarcExaZones[_si]; + } + } + + _introSarcData1 = _introSarcData3 - _moveSarcZone1->_left; + a->_z = _introSarcData3; + a->_frame = _moveSarcZone1->_top - (_introSarcData1 / 20); + _introSarcData3 = _moveSarcZone1->_left; + + if (_introSarcData1 > 0) { + a->_left = _introSarcData1 / 2; + } else { + a->_left = -_introSarcData1 / 2; + } + + if (_introSarcData1 > 0) { + a->_top = 2; + } else { + a->_top = -2; + } + + return; + + } + + _introSarcData2 = 1; + _moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20); + _moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20); + + if (_moveSarcZones[0]->_left == 35 && + _moveSarcZones[1]->_left == 68 && + _moveSarcZones[2]->_left == 101 && + _moveSarcZones[3]->_left == 134 && + _moveSarcZones[4]->_left == 167) { + + a = findAnimation("finito"); + + a->_flags |= (kFlagsActive | kFlagsActing); + _localFlags[_currentLocationIndex] |= 0x20; // GROSS HACK: activates 'finito' flag in dinoit_museo.loc + } + + return; + +} + + + + +void Parallaction_ns::_c_contaFoglie(void *parm) { + + num_foglie++; + if (num_foglie != 6) + return; + + _commandFlags |= 0x1000; + + return; +} + +void Parallaction_ns::_c_zeroFoglie(void *parm) { + num_foglie = 0; + return; +} + +void Parallaction_ns::_c_trasformata(void *parm) { + _engineFlags ^= kEngineTransformedDonna; + return; +} + +void Parallaction_ns::_c_offMouse(void *parm) { + showCursor(false); + _engineFlags |= kEngineBlockInput; + return; +} + +void Parallaction_ns::_c_onMouse(void *parm) { + _engineFlags &= ~kEngineBlockInput; + showCursor(true); + return; +} + + + +void Parallaction_ns::_c_setMask(void *parm) { + + _gfx->intGrottaHackMask(); + + return; +} + +void Parallaction_ns::_c_endComment(void *param) { + + int16 w = 0, h = 0; + _gfx->getStringExtent(_location._endComment, 130, &w, &h); + + Common::Rect r(w+5, h+5); + r.moveTo(5, 5); + _gfx->floodFill(Gfx::kBitFront, r, 0); + + r.setWidth(w+3); + r.setHeight(h+3); + r.moveTo(7, 7); + _gfx->floodFill(Gfx::kBitFront, r, 1); + + _gfx->setFont(kFontDialogue); + _gfx->displayWrappedString(_location._endComment, 3, 5, 0, 130); + _gfx->updateScreen(); + + + Gfx::Palette pal; + _gfx->makeGrayscalePalette(pal); + + for (uint di = 0; di < 64; di++) { + _gfx->fadePalette(_gfx->_palette, pal, 1); + _gfx->setPalette(_gfx->_palette); + + _gfx->updateScreen(); + g_system->delayMillis(20); + } + + waitUntilLeftClick(); + + return; +} + +void Parallaction_ns::_c_frankenstein(void *parm) { + + Gfx::Palette pal0; + Gfx::Palette pal1; + + for (uint16 i = 0; i <= BASE_PALETTE_COLORS; i++) { + pal0[(i+FIRST_BASE_COLOR)] = _gfx->_palette[i]; + pal0[(i+FIRST_BASE_COLOR)*3+1] = 0; + pal0[(i+FIRST_BASE_COLOR)*3+2] = 0; + + pal1[(i+FIRST_BASE_COLOR)*3+1] = 0; + pal1[(i+FIRST_BASE_COLOR)*3+2] = 0; + } + + for (uint16 _di = 0; _di < 30; _di++) { + g_system->delayMillis(20); + _gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->updateScreen(); + g_system->delayMillis(20); + _gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->updateScreen(); + } + + _gfx->setPalette(_gfx->_palette); + _gfx->updateScreen(); + + return; +} + + +void Parallaction_ns::_c_finito(void *parm) { + + const char **v8C = endMsg0; + const char **v7C = endMsg1; + const char **v6C = endMsg2; + const char **v5C = endMsg3; + const char **v4C = endMsg4; + const char **v3C = endMsg5; + const char **v2C = endMsg6; + const char **v1C = endMsg7; + + Common::File stream; + + stream.open(_characterName, Common::File::kFileWriteMode); + if (stream.isOpen()) + stream.close(); + + Common::File streamDino, streamDough, streamDonna; + + streamDino.open("dino"); + streamDough.open("dough"); + streamDonna.open("donna"); + + bool gameCompleted = streamDino.isOpen() && streamDough.isOpen() && streamDonna.isOpen(); + + streamDino.close(); + streamDough.close(); + streamDonna.close(); + + cleanInventory(); + + _gfx->setPalette(_gfx->_palette); + + if (gameCompleted) { + _gfx->setFont(kFontMenu); + _gfx->displayCenteredString(70, v4C[_language]); + _gfx->displayCenteredString(100, v3C[_language]); + _gfx->displayCenteredString(130, v2C[_language]); + _gfx->displayCenteredString(160, v1C[_language]); + + _gfx->updateScreen(); + waitUntilLeftClick(); + + strcpy(_location._name, "estgrotta.drki"); + + _engineFlags |= kEngineChangeLocation; + } else { + _gfx->setFont(kFontMenu); + _gfx->displayCenteredString(70, v8C[_language]); + _gfx->displayCenteredString(100, v7C[_language]); + _gfx->displayCenteredString(130, v6C[_language]); + _gfx->displayCenteredString(160, v5C[_language]); + + _gfx->updateScreen(); + waitUntilLeftClick(); + + _menu->selectCharacter(); + } + + // this code saves main character animation from being removed from the following code + _animations.remove(&_char._ani); + _locationNames[0][0] = '\0'; + _numLocations = 0; + _commandFlags = 0; + + // this flag tells freeZones to unconditionally remove *all* Zones + _engineFlags |= kEngineQuit; + + freeZones(); + freeAnimations(); + + // this dangerous flag can now be cleared + _engineFlags &= ~kEngineQuit; + + // main character animation is restored + _animations.push_front(&_char._ani); + _score = 0; + + return; +} + +void Parallaction_ns::_c_ridux(void *parm) { + changeCharacter(_minidinoName); + return; +} + +void Parallaction_ns::_c_testResult(void *parm) { + _gfx->swapBuffers(); + + _disk->selectArchive("disk1"); + parseLocation("common"); + + _gfx->setFont(kFontMenu); + + _gfx->displayCenteredString(38, _slideText[0]); + _gfx->displayCenteredString(58, _slideText[1]); + + _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); + _gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); + + return; +} + +void Parallaction_ns::_c_offSound(void*) { + _soundMan->stopSfx(0); + _soundMan->stopSfx(1); + _soundMan->stopSfx(2); + _soundMan->stopSfx(3); +} + +void Parallaction_ns::_c_startMusic(void*) { + _soundMan->playMusic(); +} + +void Parallaction_ns::_c_closeMusic(void*) { + _soundMan->stopMusic(); +} + +/* + intro callables +*/ + +void Parallaction_ns::_c_startIntro(void *parm) { + _rightHandAnim = findAnimation("righthand"); + + if (getPlatform() == Common::kPlatformPC) { + _soundMan->setMusicFile("intro"); + _soundMan->playMusic(); + } + + _engineFlags |= kEngineBlockInput; + + return; +} + +void Parallaction_ns::_c_endIntro(void *parm) { + + _gfx->setFont(kFontMenu); + + debugC(1, kDebugLocation, "endIntro()"); + + for (uint16 _si = 0; _si < 6; _si++) { + _gfx->displayCenteredString(80, _credits[_si]._role); + _gfx->displayCenteredString(100, _credits[_si]._name); + + _gfx->updateScreen(); + + for (uint16 v2 = 0; v2 < 100; v2++) { + _mouseButtons = kMouseNone; + updateInput(); + if (_mouseButtons == kMouseLeftUp) + break; + + waitTime( 1 ); + } + + _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + } + debugC(1, kDebugLocation, "endIntro(): done showing credits"); + + if ((getFeatures() & GF_DEMO) == 0) { + _gfx->displayCenteredString(80, "CLICK MOUSE BUTTON TO START"); + _gfx->updateScreen(); + + waitUntilLeftClick(); + + _engineFlags &= ~kEngineBlockInput; + _menu->selectCharacter(); + } else { + waitUntilLeftClick(); + } + + return; +} + +void Parallaction_ns::_c_moveSheet(void *parm) { + + static uint16 x = 319; + + if (x > 66) + x -= 16; + + Common::Rect r; + + r.left = x; + r.top = 47; + r.right = (x + 32 > 319) ? 319 : (x + 32); + r.bottom = 199; + _gfx->floodFill(Gfx::kBitBack, r, 1); + _gfx->floodFill(Gfx::kBit2, r, 1); + + if (x >= 104) return; + + r.left = x+215; + r.top = 47; + r.right = (x + 247 > 319) ? 319 : (x + 247); + r.bottom = 199; + _gfx->floodFill(Gfx::kBitBack, r, 12); + _gfx->floodFill(Gfx::kBit2, r, 12); + + return; +} + +void plotPixel(int x, int y, int color, void *data) { + _vm->_gfx->plotMaskPixel(x, y, color); +} + +void Parallaction_ns::_c_sketch(void *parm) { + + static uint16 index = 1; + + uint16 newy = _rightHandPositions[2*index+1]; + uint16 newx = _rightHandPositions[2*index]; + + uint16 oldy = _rightHandPositions[2*(index-1)+1]; + uint16 oldx = _rightHandPositions[2*(index-1)]; + + Graphics::drawLine(oldx, oldy, newx, newy, 0, plotPixel, NULL); + + _rightHandAnim->_left = newx; + _rightHandAnim->_top = newy - 20; + + index++; + + return; +} + + + + +void Parallaction_ns::_c_shade(void *parm) { + + Common::Rect r( + _rightHandAnim->_left - 36, + _rightHandAnim->_top - 36, + _rightHandAnim->_left, + _rightHandAnim->_top + ); + + _gfx->fillMaskRect(r, 0); + + return; + +} + +void Parallaction_ns::_c_projector(void*) { +#ifdef HALFBRITE + static int dword_16032 = 0; + +// Bitmap bm; +// InitBitMap(&bm); + + if (dword_16032 != 0) { +/* // keep drawing spotlight in its final place + _gfx->flatBlitCnv(&scnv, 110, 25, Gfx::kBitFront); + BltBitMap(&bm, 0, 0, &_screen._bitMap, 110, 25, a3->??, a3->??, 0x20, 0x20); +*/ return; + } + + _gfx->setHalfbriteMode(true); +/* + // move spot light around the stage + int d7, d6; + for (d7 = 0; d7 < 150; d7++) { + + if (d7 < 100) { + int d1 = d7; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = 50 - d1; + } else { + int d1 = d7 / 100; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = d1; + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0xFA, 0x20); + } + + for (d7 = 50; d7 > -10; d7--) { + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0xFA, 0x20); + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + _gfx->flatBlitCnv(&scnv, d7+120, d6, Gfx::kBitFront); +*/ + + dword_16032 = 1; + return; +#endif +} + +void Parallaction_ns::_c_HBOff(void*) { +#ifdef HALFBRITE + _gfx->setHalfbriteMode(false); +#endif +} + +void Parallaction_ns::_c_HBOn(void*) { +#ifdef HALFBRITE + _gfx->setHalfbriteMode(true); +#endif +} + + +} // namespace Parallaction diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp index 15acdd2d86..dc392fde2c 100644 --- a/engines/parallaction/commands.cpp +++ b/engines/parallaction/commands.cpp @@ -274,6 +274,9 @@ void Parallaction::runCommands(CommandList& list, Zone *z) { case CMD_CLOSE: // close u->_zone->_flags |= kFlagsClosed; + if (u->_zone->u.door->_cnv) { + addJob(&jobToggleDoor, (void*)u->_zone, kPriority18 ); + } break; case CMD_ON: // on @@ -302,7 +305,7 @@ void Parallaction::runCommands(CommandList& list, Zone *z) { break; case CMD_CALL: // call - _callables[u->_callable](z); + callFunction(u->_callable, z); break; case CMD_QUIT: // quit @@ -314,7 +317,7 @@ void Parallaction::runCommands(CommandList& list, Zone *z) { continue; } - WalkNodeList *vC = _vm->_char._builder.buildPath(u->_move._x, u->_move._y); + WalkNodeList *vC = _char._builder.buildPath(u->_move._x, u->_move._y); addJob(&jobWalk, vC, kPriority19 ); _engineFlags |= kEngineWalking; diff --git a/engines/parallaction/detection.cpp b/engines/parallaction/detection.cpp index 8e069c5f08..84c45584a4 100644 --- a/engines/parallaction/detection.cpp +++ b/engines/parallaction/detection.cpp @@ -27,6 +27,7 @@ #include "base/plugins.h" +#include "common/config-manager.h" #include "common/advancedDetector.h" #include "parallaction/parallaction.h" @@ -47,8 +48,8 @@ Common::Platform Parallaction::getPlatform() const { return _gameDescription->de } static const PlainGameDescriptor parallactionGames[] = { - {"parallaction", "Parallaction engine game"}, {"nippon", "Nippon Safes Inc."}, + {"bra", "The Big Red Adventure"}, {0, 0} }; @@ -140,6 +141,24 @@ static const PARALLACTIONGameDescription gameDescriptions[] = { GF_LANG_IT, }, + { + { + "bra", + "Multi-lingual", + { + {"tbra.bmp", 0, "3174c095a0e1a4eaf05c403445711e9b", 80972 }, + {"russia.fnt", 0, "57f85ff62aeca6334fdcaf718e313b49", 18344 }, + {NULL, 0, NULL, 0 } + }, + Common::UNK_LANG, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GType_BRA, + GF_LANG_EN | GF_LANG_FR | GF_LANG_DE | GF_LANG_IT | GF_LANG_MULT + }, + + { AD_TABLE_END_MARKER, 0, 0 } }; @@ -157,7 +176,7 @@ static const Common::ADParams detectionParams = { // Structure for autoupgrading obsolete targets 0, // Name of single gameid (optional) - "parallaction", + 0, // List of files for file-based fallback detection (optional) 0, // Fallback callback @@ -166,7 +185,32 @@ static const Common::ADParams detectionParams = { Common::kADFlagAugmentPreferredTarget }; -ADVANCED_DETECTOR_DEFINE_PLUGIN(PARALLACTION, Parallaction::Parallaction, detectionParams); +GameList Engine_PARALLACTION_gameIDList() { + return GameList(parallactionGames); +} + +GameDescriptor Engine_PARALLACTION_findGameID(const char *gameid) { + return Common::AdvancedDetector::findGameID(gameid, parallactionGames); +} + +GameList Engine_PARALLACTION_detectGames(const FSList &fslist) { + return Common::AdvancedDetector::detectAllGames(fslist, detectionParams); +} + +PluginError Engine_PARALLACTION_create(OSystem *syst, Engine **engine) { + assert(engine); + const char *gameid = ConfMan.get("gameid").c_str(); + + if (!scumm_stricmp("nippon", gameid)) { + *engine = new Parallaction::Parallaction_ns(syst); + } else + if (!scumm_stricmp("bra", gameid)) { + *engine = new Parallaction::Parallaction_br(syst); + } else + error("Parallaction engine created with invalid gameid ('%s')", gameid); + + return kNoError; +} REGISTER_PLUGIN(PARALLACTION, "Parallaction engine", "Nippon Safes Inc. (C) Dynabyte"); diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 7d2224164a..84ecde6e64 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -236,11 +236,12 @@ uint16 DialogueManager::askPassword() { debugC(1, kDebugDialogue, "checkDialoguePassword()"); char password[100]; - uint16 passwordLen = 0; + uint16 passwordLen; while (true) { clear(); + passwordLen = 0; strcpy(password, "......."); Common::Rect r(_answerBalloonW[0], _answerBalloonH[0]); @@ -491,13 +492,12 @@ void Parallaction::runDialogue(SpeakData *data) { _gfx->setFont(kFontDialogue); - if (_vm->getPlatform() == Common::kPlatformPC) + if (getPlatform() == Common::kPlatformPC) showCursor(false); DialogueManager man(this, data); man.run(); - refreshInventory(_characterName); showCursor(true); return; diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h index 14ea4f0e16..ae572b1122 100644 --- a/engines/parallaction/disk.h +++ b/engines/parallaction/disk.h @@ -29,19 +29,8 @@ #include "parallaction/defs.h" #include "common/file.h" -namespace Audio { - class AudioStream; -} - namespace Parallaction { -//------------------------------------------------------ -// ARCHIVE MANAGEMENT -//------------------------------------------------------ - - -#define MAX_ARCHIVE_ENTRIES 384 - class Table; class Parallaction; class Gfx; @@ -51,22 +40,49 @@ class Font; struct Cnv; struct StaticCnv; + +class Disk { + +public: + Disk() { } + virtual ~Disk() { } + + virtual Common::String selectArchive(const Common::String &name) = 0; + virtual void setLanguage(uint16 language) = 0; + + virtual Script* loadLocation(const char *name) = 0; + virtual Script* loadScript(const char* name) = 0; + virtual Cnv* loadTalk(const char *name) = 0; + virtual Cnv* loadObjects(const char *name) = 0; + virtual StaticCnv* loadPointer() = 0; + virtual StaticCnv* loadHead(const char* name) = 0; + virtual Font* loadFont(const char* name) = 0; + virtual StaticCnv* loadStatic(const char* name) = 0; + virtual Cnv* loadFrames(const char* name) = 0; + virtual void loadSlide(const char *filename) = 0; + virtual void loadScenery(const char* background, const char* mask) = 0; + virtual Table* loadTable(const char* name) = 0; + virtual Common::SeekableReadStream* loadMusic(const char* name) = 0; + virtual Common::ReadStream* loadSound(const char* name) = 0; +}; + + + + +#define MAX_ARCHIVE_ENTRIES 384 + class Archive : public Common::SeekableReadStream { protected: - bool _file; uint32 _fileOffset; uint32 _fileCursor; uint32 _fileEndOffset; - Common::String _archiveName; char _archiveDir[MAX_ARCHIVE_ENTRIES][32]; uint32 _archiveLenghts[MAX_ARCHIVE_ENTRIES]; uint32 _archiveOffsets[MAX_ARCHIVE_ENTRIES]; - Common::File _archive; - uint32 _numFiles; protected: @@ -77,21 +93,17 @@ public: void open(const char* file); void close(); - Common::String name() const; - bool openArchivedFile(const char *name); void closeArchivedFile(); - uint32 size() const; uint32 pos() const; bool eos() const; void seek(int32 offs, int whence = SEEK_SET); - uint32 read(void *dataPtr, uint32 dataSize); }; -class Disk { +class Disk_ns : public Disk { protected: Archive _resArchive; @@ -103,29 +115,14 @@ protected: void errorFileNotFound(const char *s); public: - Disk(Parallaction *vm); - virtual ~Disk(); + Disk_ns(Parallaction *vm); + virtual ~Disk_ns(); Common::String selectArchive(const Common::String &name); void setLanguage(uint16 language); - - virtual Script* loadLocation(const char *name) = 0; - virtual Script* loadScript(const char* name) = 0; - virtual Cnv* loadTalk(const char *name) = 0; - virtual Cnv* loadObjects(const char *name) = 0; - virtual StaticCnv* loadPointer() = 0; - virtual StaticCnv* loadHead(const char* name) = 0; - virtual Font* loadFont(const char* name) = 0; - virtual StaticCnv* loadStatic(const char* name) = 0; - virtual Cnv* loadFrames(const char* name) = 0; - virtual void loadSlide(const char *filename) = 0; - virtual void loadScenery(const char* background, const char* mask) = 0; - virtual Table* loadTable(const char* name) = 0; - virtual Common::ReadStream* loadMusic(const char* name) = 0; - virtual Common::ReadStream* loadSound(const char* name) = 0; }; -class DosDisk : public Disk { +class DosDisk_ns : public Disk_ns { private: void unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path); @@ -142,8 +139,8 @@ protected: Gfx *_gfx; public: - DosDisk(Parallaction *vm); - virtual ~DosDisk(); + DosDisk_ns(Parallaction *vm); + virtual ~DosDisk_ns(); Script* loadLocation(const char *name); Script* loadScript(const char* name); @@ -157,11 +154,11 @@ public: void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); - Common::ReadStream* loadMusic(const char* name); + Common::SeekableReadStream* loadMusic(const char* name); Common::ReadStream* loadSound(const char* name); }; -class AmigaDisk : public Disk { +class AmigaDisk_ns : public Disk_ns { protected: Cnv* makeCnv(Common::SeekableReadStream &stream); @@ -176,8 +173,8 @@ protected: void loadBackground(const char *name); public: - AmigaDisk(Parallaction *vm); - virtual ~AmigaDisk(); + AmigaDisk_ns(Parallaction *vm); + virtual ~AmigaDisk_ns(); Script* loadLocation(const char *name); Script* loadScript(const char* name); @@ -191,10 +188,45 @@ public: void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); - Common::ReadStream* loadMusic(const char* name); + Common::SeekableReadStream* loadMusic(const char* name); Common::ReadStream* loadSound(const char* name); }; + +// for the moment DosDisk_br subclasses Disk. When Amiga support will +// be taken into consideration, it might be useful to add another level +// like we did for Nippon Safes. +class DosDisk_br : public Disk { + +protected: + Parallaction *_vm; + +protected: + void errorFileNotFound(const char *s); + +public: + DosDisk_br(Parallaction *vm); + virtual ~DosDisk_br(); + + Common::String selectArchive(const Common::String &name); + void setLanguage(uint16 language); + Script* loadLocation(const char *name); + Script* loadScript(const char* name); + Cnv* loadTalk(const char *name); + Cnv* loadObjects(const char *name); + StaticCnv* loadPointer(); + StaticCnv* loadHead(const char* name); + Font* loadFont(const char* name); + StaticCnv* loadStatic(const char* name); + Cnv* loadFrames(const char* name); + void loadSlide(const char *filename); + void loadScenery(const char* background, const char* mask); + Table* loadTable(const char* name); + Common::SeekableReadStream* loadMusic(const char* name); + Common::ReadStream* loadSound(const char* name); +}; + + } // namespace Parallaction diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp new file mode 100644 index 0000000000..452b74be51 --- /dev/null +++ b/engines/parallaction/disk_br.cpp @@ -0,0 +1,134 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 "parallaction/parallaction.h" + + +namespace Parallaction { + + +void DosDisk_br::errorFileNotFound(const char *s) { + error("File '%s' not found", s); +} + +Common::String DosDisk_br::selectArchive(const Common::String& name) { + debugC(5, kDebugDisk, "DosDisk_br::selectArchive"); + return ""; +} + +void DosDisk_br::setLanguage(uint16 language) { + debugC(5, kDebugDisk, "DosDisk_br::setLanguage"); + + return; +} + +DosDisk_br::DosDisk_br(Parallaction* vm) : _vm(vm) { + +} + +DosDisk_br::~DosDisk_br() { +} + +Cnv* DosDisk_br::loadTalk(const char *name) { + debugC(5, kDebugDisk, "DosDisk_br::loadTalk"); + + return 0; +} + +Script* DosDisk_br::loadLocation(const char *name) { + debugC(5, kDebugDisk, "DosDisk_br::loadLocation"); + return 0; +} + +Script* DosDisk_br::loadScript(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadScript"); + return 0; +} + +// there are no Head resources in Big Red Adventure +StaticCnv* DosDisk_br::loadHead(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadHead"); + return 0; +} + + +StaticCnv* DosDisk_br::loadPointer() { + debugC(5, kDebugDisk, "DosDisk_br::loadPointer"); + return 0; +} + + +Font* DosDisk_br::loadFont(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadFont"); + return 0; +} + + +Cnv* DosDisk_br::loadObjects(const char *name) { + debugC(5, kDebugDisk, "DosDisk_br::loadObjects"); + return 0; +} + + +StaticCnv* DosDisk_br::loadStatic(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadStatic"); + return 0; +} + +Cnv* DosDisk_br::loadFrames(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadFrames"); + return 0; +} + +// there are no Slide resources in Big Red Adventure +void DosDisk_br::loadSlide(const char *filename) { + debugC(5, kDebugDisk, "DosDisk_br::loadSlide"); + return; +} + +void DosDisk_br::loadScenery(const char *name, const char *mask) { + debugC(5, kDebugDisk, "DosDisk_br::loadScenery"); + return; +} + +Table* DosDisk_br::loadTable(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadTable"); + return 0; +} + +Common::SeekableReadStream* DosDisk_br::loadMusic(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadMusic"); + return 0; +} + + +Common::ReadStream* DosDisk_br::loadSound(const char* name) { + debugC(5, kDebugDisk, "DosDisk_br::loadSound"); + return 0; +} + + +} // namespace Parallaction diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk_ns.cpp index 2e6d9e4820..c0bb2691ef 100644 --- a/engines/parallaction/disk.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -32,11 +32,188 @@ namespace Audio { + class AudioStream; + AudioStream *make8SVXStream(Common::ReadStream &input); } namespace Parallaction { + +// HACK: Several archives ('de', 'en', 'fr' and 'disk0') in the multi-lingual +// Amiga version of Nippon Safes, and one archive ('fr') in the Amiga Demo of +// Nippon Safes used different internal offsets than all the other archives. +// +// When an archive is opened in the Amiga demo, its size is checked against +// SIZEOF_SMALL_ARCHIVE to detect when the smaller archive is used. +// +// When an archive is opened in Amiga multi-lingual version, the header is +// checked again NDOS to detect when a smaller archive is used. +// +#define SIZEOF_SMALL_ARCHIVE 12778 + +#define ARCHIVE_FILENAMES_OFS 0x16 + +#define NORMAL_ARCHIVE_FILES_NUM 384 +#define SMALL_ARCHIVE_FILES_NUM 180 + +#define NORMAL_ARCHIVE_SIZES_OFS 0x3016 +#define SMALL_ARCHIVE_SIZES_OFS 0x1696 + +#define NORMAL_ARCHIVE_DATA_OFS 0x4000 +#define SMALL_ARCHIVE_DATA_OFS 0x1966 + +Archive::Archive() { + resetArchivedFile(); +} + +void Archive::open(const char *file) { + debugC(1, kDebugDisk, "Archive::open(%s)", file); + + if (_archive.isOpen()) + close(); + + char path[PATH_LEN]; + + strcpy(path, file); + if (!_archive.open(path)) + error("archive '%s' not found", path); + + _archiveName = file; + + bool isSmallArchive = false; + if (_vm->getPlatform() == Common::kPlatformAmiga) { + if (_vm->getFeatures() & GF_DEMO) { + isSmallArchive = _archive.size() == SIZEOF_SMALL_ARCHIVE; + } else if (_vm->getFeatures() & GF_LANG_MULT) { + isSmallArchive = (_archive.readUint32BE() != MKID_BE('NDOS')); + } + } + + _numFiles = (isSmallArchive) ? SMALL_ARCHIVE_FILES_NUM : NORMAL_ARCHIVE_FILES_NUM; + + _archive.seek(ARCHIVE_FILENAMES_OFS); + _archive.read(_archiveDir, _numFiles*32); + + _archive.seek((isSmallArchive) ? SMALL_ARCHIVE_SIZES_OFS : NORMAL_ARCHIVE_SIZES_OFS); + + uint32 dataOffset = (isSmallArchive) ? SMALL_ARCHIVE_DATA_OFS : NORMAL_ARCHIVE_DATA_OFS; + for (uint16 i = 0; i < _numFiles; i++) { + _archiveOffsets[i] = dataOffset; + _archiveLenghts[i] = _archive.readUint32BE(); + dataOffset += _archiveLenghts[i]; + } + + return; +} + + +void Archive::close() { + if (!_archive.isOpen()) return; + + resetArchivedFile(); + + _archive.close(); + _archiveName.clear(); +} + +Common::String Archive::name() const { + return _archiveName; +} + +bool Archive::openArchivedFile(const char *filename) { + debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); + + resetArchivedFile(); + + debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); + + if (!_archive.isOpen()) + error("Archive::openArchivedFile: the archive is not open"); + + uint16 i = 0; + for ( ; i < _numFiles; i++) { + if (!scumm_stricmp(_archiveDir[i], filename)) break; + } + if (i == _numFiles) return false; + + debugC(9, kDebugDisk, "Archive::openArchivedFile: '%s' found in slot %i", filename, i); + + _file = true; + + _fileOffset = _archiveOffsets[i]; + _fileCursor = _archiveOffsets[i]; + _fileEndOffset = _archiveOffsets[i] + _archiveLenghts[i]; + + _archive.seek(_fileOffset); + + return true; +} + +void Archive::resetArchivedFile() { + _file = false; + _fileCursor = 0; + _fileOffset = 0; + _fileEndOffset = 0; +} + +void Archive::closeArchivedFile() { + resetArchivedFile(); +} + + +uint32 Archive::size() const { + return (_file == true ? _fileEndOffset - _fileOffset : 0); +} + +uint32 Archive::pos() const { + return (_file == true ? _fileCursor - _fileOffset : 0 ); +} + +bool Archive::eos() const { + return (_file == true ? _fileCursor == _fileEndOffset : true ); +} + +void Archive::seek(int32 offs, int whence) { + assert(_file == true && _fileCursor <= _fileEndOffset); + + switch (whence) { + case SEEK_CUR: + _fileCursor += offs; + break; + case SEEK_SET: + _fileCursor = _fileOffset + offs; + break; + case SEEK_END: + _fileCursor = _fileEndOffset - offs; + break; + } + assert(_fileCursor <= _fileEndOffset && _fileCursor >= _fileOffset); + + _archive.seek(_fileCursor, SEEK_SET); +} + +uint32 Archive::read(void *dataPtr, uint32 dataSize) { +// printf("read(%i, %i)\n", file->_cursor, file->_endOffset); + if (_file == false) + error("Archive::read: no archived file is currently open"); + + if (_fileCursor >= _fileEndOffset) + error("can't read beyond end of archived file"); + + if (_fileEndOffset - _fileCursor < dataSize) + dataSize = _fileEndOffset - _fileCursor; + + int32 readBytes = _archive.read(dataPtr, dataSize); + _fileCursor += readBytes; + + return readBytes; +} + + + + + /* This stream class is just a wrapper around Archive, so deallocation is not a problem. In fact, this class doesn't @@ -79,26 +256,26 @@ public: -Disk::Disk(Parallaction *vm) : _vm(vm) { - +void Disk_ns::errorFileNotFound(const char *s) { + error("File '%s' not found", s); } -Disk::~Disk() { +Disk_ns::Disk_ns(Parallaction *vm) : _vm(vm) { } -void Disk::errorFileNotFound(const char *s) { - error("File '%s' not found", s); +Disk_ns::~Disk_ns() { + } -Common::String Disk::selectArchive(const Common::String& name) { +Common::String Disk_ns::selectArchive(const Common::String& name) { Common::String oldName = _resArchive.name(); _resArchive.open(name.c_str()); return oldName; } -void Disk::setLanguage(uint16 language) { +void Disk_ns::setLanguage(uint16 language) { debugC(1, kDebugDisk, "setLanguage(%i)", language); switch (language) { @@ -134,18 +311,18 @@ void Disk::setLanguage(uint16 language) { -DosDisk::DosDisk(Parallaction* vm) : Disk(vm) { +DosDisk_ns::DosDisk_ns(Parallaction* vm) : Disk_ns(vm) { } -DosDisk::~DosDisk() { +DosDisk_ns::~DosDisk_ns() { } // // loads a cnv from an external file // -Cnv* DosDisk::loadExternalCnv(const char *filename) { +Cnv* DosDisk_ns::loadExternalCnv(const char *filename) { // printf("Gfx::loadExternalCnv(%s)...", filename); char path[PATH_LEN]; @@ -168,7 +345,7 @@ Cnv* DosDisk::loadExternalCnv(const char *filename) { return new Cnv(numFrames, width, height, data); } -StaticCnv *DosDisk::loadExternalStaticCnv(const char *filename) { +StaticCnv *DosDisk_ns::loadExternalStaticCnv(const char *filename) { char path[PATH_LEN]; @@ -193,7 +370,7 @@ StaticCnv *DosDisk::loadExternalStaticCnv(const char *filename) { return cnv; } -Cnv* DosDisk::loadCnv(const char *filename) { +Cnv* DosDisk_ns::loadCnv(const char *filename) { // printf("Gfx::loadCnv(%s)\n", filename); char path[PATH_LEN]; @@ -218,7 +395,7 @@ Cnv* DosDisk::loadCnv(const char *filename) { return new Cnv(numFrames, width, height, data); } -Cnv* DosDisk::loadTalk(const char *name) { +Cnv* DosDisk_ns::loadTalk(const char *name) { const char *ext = strstr(name, ".talk"); if (ext != NULL) { @@ -243,7 +420,7 @@ Cnv* DosDisk::loadTalk(const char *name) { return loadExternalCnv(v20); } -Script* DosDisk::loadLocation(const char *name) { +Script* DosDisk_ns::loadLocation(const char *name) { char archivefile[PATH_LEN]; @@ -260,11 +437,11 @@ Script* DosDisk::loadLocation(const char *name) { strcat(archivefile, name); strcat(archivefile, ".loc"); - debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + debugC(3, kDebugDisk, "DosDisk_ns::loadLocation(%s): trying '%s'", name, archivefile); if (!_locArchive.openArchivedFile(archivefile)) { sprintf(archivefile, "%s%s.loc", _languageDir, name); - debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + debugC(3, kDebugDisk, "DosDisk_ns::loadLocation(%s): trying '%s'", name, archivefile); if (!_locArchive.openArchivedFile(archivefile)) errorFileNotFound(name); @@ -273,7 +450,7 @@ Script* DosDisk::loadLocation(const char *name) { return new Script(new DummyArchiveStream(_locArchive), true); } -Script* DosDisk::loadScript(const char* name) { +Script* DosDisk_ns::loadScript(const char* name) { char vC8[PATH_LEN]; @@ -285,7 +462,7 @@ Script* DosDisk::loadScript(const char* name) { return new Script(new DummyArchiveStream(_resArchive), true); } -StaticCnv* DosDisk::loadHead(const char* name) { +StaticCnv* DosDisk_ns::loadHead(const char* name) { char path[PATH_LEN]; @@ -300,19 +477,19 @@ StaticCnv* DosDisk::loadHead(const char* name) { } -StaticCnv* DosDisk::loadPointer() { +StaticCnv* DosDisk_ns::loadPointer() { return loadExternalStaticCnv("pointer"); } -Font* DosDisk::loadFont(const char* name) { +Font* DosDisk_ns::loadFont(const char* name) { char path[PATH_LEN]; sprintf(path, "%scnv", name); return createFont(name, loadExternalCnv(path)); } -Cnv* DosDisk::loadObjects(const char *name) { +Cnv* DosDisk_ns::loadObjects(const char *name) { if (IS_MINI_CHARACTER(name)) { name += 4; @@ -324,7 +501,7 @@ Cnv* DosDisk::loadObjects(const char *name) { } -StaticCnv* DosDisk::loadStatic(const char* name) { +StaticCnv* DosDisk_ns::loadStatic(const char* name) { char path[PATH_LEN]; @@ -350,7 +527,7 @@ StaticCnv* DosDisk::loadStatic(const char* name) { return cnv; } -Cnv* DosDisk::loadFrames(const char* name) { +Cnv* DosDisk_ns::loadFrames(const char* name) { return loadCnv(name); } @@ -362,7 +539,7 @@ Cnv* DosDisk::loadFrames(const char* name) { // * mask data [bits 6-7] (z buffer) // * path data [bit 8] (walkable areas) // -void DosDisk::unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path) { +void DosDisk_ns::unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path) { byte b; uint32 i = 0; @@ -380,7 +557,7 @@ void DosDisk::unpackBackground(Common::ReadStream *stream, byte *screen, byte *m } -void DosDisk::parseDepths(Common::SeekableReadStream &stream) { +void DosDisk_ns::parseDepths(Common::SeekableReadStream &stream) { _vm->_gfx->_bgLayers[0] = stream.readByte(); _vm->_gfx->_bgLayers[1] = stream.readByte(); _vm->_gfx->_bgLayers[2] = stream.readByte(); @@ -388,7 +565,7 @@ void DosDisk::parseDepths(Common::SeekableReadStream &stream) { } -void DosDisk::parseBackground(Common::SeekableReadStream &stream) { +void DosDisk_ns::parseBackground(Common::SeekableReadStream &stream) { stream.read(_vm->_gfx->_palette, BASE_PALETTE_SIZE); _vm->_gfx->setPalette(_vm->_gfx->_palette); @@ -405,16 +582,16 @@ void DosDisk::parseBackground(Common::SeekableReadStream &stream) { } -void DosDisk::loadBackground(const char *filename) { +void DosDisk_ns::loadBackground(const char *filename) { if (!_resArchive.openArchivedFile(filename)) errorFileNotFound(filename); parseBackground(_resArchive); - byte *bg = (byte*)calloc(1, SCREEN_WIDTH*SCREEN_HEIGHT); - byte *mask = (byte*)calloc(1, SCREENMASK_WIDTH*SCREEN_HEIGHT); - byte *path = (byte*)calloc(1, SCREENPATH_WIDTH*SCREEN_HEIGHT); + byte *bg = (byte*)calloc(1, _vm->_screenSize); + byte *mask = (byte*)calloc(1, _vm->_screenMaskSize); + byte *path = (byte*)calloc(1, _vm->_screenPathSize); Graphics::PackBitsReadStream stream(_resArchive); @@ -437,20 +614,20 @@ void DosDisk::loadBackground(const char *filename) { // mask and path are normally combined (via OR) into the background picture itself // read the comment on the top of this file for more // -void DosDisk::loadMaskAndPath(const char *name) { +void DosDisk_ns::loadMaskAndPath(const char *name) { char path[PATH_LEN]; sprintf(path, "%s.msk", name); if (!_resArchive.openArchivedFile(path)) errorFileNotFound(name); - byte *maskBuf = (byte*)calloc(1, SCREENMASK_WIDTH*SCREEN_HEIGHT); - byte *pathBuf = (byte*)calloc(1, SCREENPATH_WIDTH*SCREEN_HEIGHT); + byte *maskBuf = (byte*)calloc(1, _vm->_screenMaskSize); + byte *pathBuf = (byte*)calloc(1, _vm->_screenPathSize); parseDepths(_resArchive); - _resArchive.read(pathBuf, SCREENPATH_WIDTH*SCREEN_HEIGHT); - _resArchive.read(maskBuf, SCREENMASK_WIDTH*SCREEN_HEIGHT); + _resArchive.read(pathBuf, _vm->_screenPathSize); + _resArchive.read(maskBuf, _vm->_screenMaskSize); _vm->_gfx->setMask(maskBuf); _vm->setPath(pathBuf); @@ -458,13 +635,13 @@ void DosDisk::loadMaskAndPath(const char *name) { return; } -void DosDisk::loadSlide(const char *filename) { +void DosDisk_ns::loadSlide(const char *filename) { char path[PATH_LEN]; sprintf(path, "%s.slide", filename); loadBackground(path); } -void DosDisk::loadScenery(const char *name, const char *mask) { +void DosDisk_ns::loadScenery(const char *name, const char *mask) { char path[PATH_LEN]; sprintf(path, "%s.dyn", name); loadBackground(path); @@ -476,7 +653,7 @@ void DosDisk::loadScenery(const char *name, const char *mask) { } -Table* DosDisk::loadTable(const char* name) { +Table* DosDisk_ns::loadTable(const char* name) { char path[PATH_LEN]; sprintf(path, "%s.tab", name); @@ -497,7 +674,7 @@ Table* DosDisk::loadTable(const char* name) { return t; } -Common::ReadStream* DosDisk::loadMusic(const char* name) { +Common::SeekableReadStream* DosDisk_ns::loadMusic(const char* name) { char path[PATH_LEN]; sprintf(path, "%s.mid", name); @@ -509,7 +686,7 @@ Common::ReadStream* DosDisk::loadMusic(const char* name) { } -Common::ReadStream* DosDisk::loadSound(const char* name) { +Common::ReadStream* DosDisk_ns::loadSound(const char* name) { return NULL; } @@ -684,12 +861,12 @@ public: -AmigaDisk::AmigaDisk(Parallaction *vm) : Disk(vm) { +AmigaDisk_ns::AmigaDisk_ns(Parallaction *vm) : Disk_ns(vm) { } -AmigaDisk::~AmigaDisk() { +AmigaDisk_ns::~AmigaDisk_ns() { } @@ -699,7 +876,7 @@ AmigaDisk::~AmigaDisk() { unpackFrame transforms images from 5-bitplanes format to 8-bit color-index mode */ -void AmigaDisk::unpackFrame(byte *dst, byte *src, uint16 planeSize) { +void AmigaDisk_ns::unpackFrame(byte *dst, byte *src, uint16 planeSize) { byte s0, s1, s2, s3, s4, mask, t0, t1, t2, t3, t4; @@ -727,7 +904,7 @@ void AmigaDisk::unpackFrame(byte *dst, byte *src, uint16 planeSize) { /* patchFrame applies DLTA data (dlta) to specified buffer (dst) */ -void AmigaDisk::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height) { +void AmigaDisk_ns::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height) { uint32 *dataIndex = (uint32*)dlta; uint32 *ofslenIndex = (uint32*)dlta + 8; @@ -763,7 +940,7 @@ void AmigaDisk::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 h } // FIXME: no mask is loaded -void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height) { +void AmigaDisk_ns::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height) { byte *baseFrame = src; byte *tempBuffer = 0; @@ -797,7 +974,7 @@ void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 byte } -StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) { +StaticCnv* AmigaDisk_ns::makeStaticCnv(Common::SeekableReadStream &stream) { stream.skip(1); uint16 width = stream.readByte(); @@ -827,7 +1004,7 @@ StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) { return cnv; } -Cnv* AmigaDisk::makeCnv(Common::SeekableReadStream &stream) { +Cnv* AmigaDisk_ns::makeCnv(Common::SeekableReadStream &stream) { uint16 numFrames = stream.readByte(); uint16 width = stream.readByte(); @@ -852,8 +1029,8 @@ Cnv* AmigaDisk::makeCnv(Common::SeekableReadStream &stream) { } #undef NUM_PLANES -Script* AmigaDisk::loadLocation(const char *name) { - debugC(1, kDebugDisk, "AmigaDisk()::loadLocation '%s'", name); +Script* AmigaDisk_ns::loadLocation(const char *name) { + debugC(1, kDebugDisk, "AmigaDisk_ns()::loadLocation '%s'", name); char path[PATH_LEN]; if (IS_MINI_CHARACTER(_vm->_characterName)) { @@ -873,8 +1050,8 @@ Script* AmigaDisk::loadLocation(const char *name) { return new Script(new PowerPackerStream(_locArchive), true); } -Script* AmigaDisk::loadScript(const char* name) { - debugC(1, kDebugDisk, "AmigaDisk::loadScript '%s'", name); +Script* AmigaDisk_ns::loadScript(const char* name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadScript '%s'", name); char vC8[PATH_LEN]; @@ -886,8 +1063,8 @@ Script* AmigaDisk::loadScript(const char* name) { return new Script(new DummyArchiveStream(_resArchive), true); } -StaticCnv* AmigaDisk::loadPointer() { - debugC(1, kDebugDisk, "AmigaDisk::loadPointer"); +StaticCnv* AmigaDisk_ns::loadPointer() { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadPointer"); Common::File stream; if (!stream.open("pointer")) @@ -896,8 +1073,8 @@ StaticCnv* AmigaDisk::loadPointer() { return makeStaticCnv(stream); } -StaticCnv* AmigaDisk::loadStatic(const char* name) { - debugC(1, kDebugDisk, "AmigaDisk::loadStatic '%s'", name); +StaticCnv* AmigaDisk_ns::loadStatic(const char* name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadStatic '%s'", name); Common::SeekableReadStream *s = openArchivedFile(name, true); StaticCnv *cnv = makeStaticCnv(*s); @@ -907,8 +1084,8 @@ StaticCnv* AmigaDisk::loadStatic(const char* name) { return cnv; } -Common::SeekableReadStream *AmigaDisk::openArchivedFile(const char* name, bool errorOnFileNotFound) { - debugC(3, kDebugDisk, "AmigaDisk::openArchivedFile(%s)", name); +Common::SeekableReadStream *AmigaDisk_ns::openArchivedFile(const char* name, bool errorOnFileNotFound) { + debugC(3, kDebugDisk, "AmigaDisk_ns::openArchivedFile(%s)", name); if (_resArchive.openArchivedFile(name)) { return new DummyArchiveStream(_resArchive); @@ -932,7 +1109,12 @@ Common::SeekableReadStream *AmigaDisk::openArchivedFile(const char* name, bool e return NULL; } -// FIXME: mask values are not computed correctly for level 1 and 2 +/* + FIXME: mask values are not computed correctly for level 1 and 2 + + NOTE: this routine is only able to build masks for Nippon Safes, since mask widths are hardcoded + into the main loop. +*/ void buildMask(byte* buf) { byte mask1[16] = { 0, 0x80, 0x20, 0xA0, 8, 0x88, 0x28, 0xA8, 2, 0x82, 0x22, 0xA2, 0xA, 0x8A, 0x2A, 0xAA }; @@ -941,7 +1123,7 @@ void buildMask(byte* buf) { byte plane0[40]; byte plane1[40]; - for (uint32 i = 0; i < 200; i++) { + for (int32 i = 0; i < _vm->_screenHeight; i++) { memcpy(plane0, buf, 40); memcpy(plane1, buf+40, 40); @@ -1004,7 +1186,7 @@ public: }; -void AmigaDisk::loadBackground(const char *name) { +void AmigaDisk_ns::loadBackground(const char *name) { Common::SeekableReadStream *s = openArchivedFile(name, true); @@ -1025,14 +1207,17 @@ void AmigaDisk::loadBackground(const char *name) { } -void AmigaDisk::loadMask(const char *name) { +void AmigaDisk_ns::loadMask(const char *name) { + debugC(5, kDebugDisk, "AmigaDisk_ns::loadMask(%s)", name); char path[PATH_LEN]; sprintf(path, "%s.mask", name); Common::SeekableReadStream *s = openArchivedFile(path, false); - if (s == NULL) + if (s == NULL) { + debugC(5, kDebugDisk, "Mask file not found"); return; // no errors if missing mask files: not every location has one + } s->seek(0x30, SEEK_SET); @@ -1051,9 +1236,10 @@ void AmigaDisk::loadMask(const char *name) { s->seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic Graphics::PackBitsReadStream stream(*s); - byte *buf = (byte*)malloc(SCREENMASK_WIDTH*SCREEN_HEIGHT); - stream.read(buf, SCREENMASK_WIDTH*SCREEN_HEIGHT); + byte *buf = (byte*)malloc(_vm->_screenMaskSize); + stream.read(buf, _vm->_screenMaskSize); buildMask(buf); + _vm->_gfx->setMask(buf); free(buf); delete s; @@ -1061,7 +1247,7 @@ void AmigaDisk::loadMask(const char *name) { return; } -void AmigaDisk::loadPath(const char *name) { +void AmigaDisk_ns::loadPath(const char *name) { char path[PATH_LEN]; sprintf(path, "%s.path", name); @@ -1074,8 +1260,8 @@ void AmigaDisk::loadPath(const char *name) { s->seek(0x120, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic Graphics::PackBitsReadStream stream(*s); - byte *buf = (byte*)malloc(SCREENPATH_WIDTH*SCREEN_HEIGHT); - stream.read(buf, SCREENPATH_WIDTH*SCREEN_HEIGHT); + byte *buf = (byte*)malloc(_vm->_screenPathSize); + stream.read(buf, _vm->_screenPathSize); _vm->setPath(buf); free(buf); delete s; @@ -1083,21 +1269,27 @@ void AmigaDisk::loadPath(const char *name) { return; } -void AmigaDisk::loadScenery(const char* background, const char* mask) { - debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask); +void AmigaDisk_ns::loadScenery(const char* background, const char* mask) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadScenery '%s', '%s'", background, mask); char path[PATH_LEN]; sprintf(path, "%s.bkgnd", background); loadBackground(path); - loadMask(background); - loadPath(background); + + if (mask == NULL) { + loadMask(background); + loadPath(background); + } else { + loadMask(mask); + loadPath(mask); + } return; } -void AmigaDisk::loadSlide(const char *name) { - debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name); +void AmigaDisk_ns::loadSlide(const char *name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadSlide '%s'", name); char path[PATH_LEN]; sprintf(path, "slides/%s", name); @@ -1110,8 +1302,8 @@ void AmigaDisk::loadSlide(const char *name) { return; } -Cnv* AmigaDisk::loadFrames(const char* name) { - debugC(1, kDebugDisk, "AmigaDisk::loadFrames '%s'", name); +Cnv* AmigaDisk_ns::loadFrames(const char* name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadFrames '%s'", name); Common::SeekableReadStream *s; @@ -1128,8 +1320,8 @@ Cnv* AmigaDisk::loadFrames(const char* name) { return cnv; } -StaticCnv* AmigaDisk::loadHead(const char* name) { - debugC(1, kDebugDisk, "AmigaDisk::loadHead '%s'", name); +StaticCnv* AmigaDisk_ns::loadHead(const char* name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadHead '%s'", name); char path[PATH_LEN]; sprintf(path, "%s.head", name); @@ -1143,8 +1335,8 @@ StaticCnv* AmigaDisk::loadHead(const char* name) { } -Cnv* AmigaDisk::loadObjects(const char *name) { - debugC(1, kDebugDisk, "AmigaDisk::loadObjects"); +Cnv* AmigaDisk_ns::loadObjects(const char *name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadObjects"); char path[PATH_LEN]; if (_vm->getFeatures() & GF_DEMO) @@ -1161,8 +1353,8 @@ Cnv* AmigaDisk::loadObjects(const char *name) { } -Cnv* AmigaDisk::loadTalk(const char *name) { - debugC(1, kDebugDisk, "AmigaDisk::loadTalk '%s'", name); +Cnv* AmigaDisk_ns::loadTalk(const char *name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadTalk '%s'", name); Common::SeekableReadStream *s; @@ -1183,8 +1375,8 @@ Cnv* AmigaDisk::loadTalk(const char *name) { return cnv; } -Table* AmigaDisk::loadTable(const char* name) { - debugC(1, kDebugDisk, "AmigaDisk::loadTable '%s'", name); +Table* AmigaDisk_ns::loadTable(const char* name) { + debugC(1, kDebugDisk, "AmigaDisk_ns::loadTable '%s'", name); char path[PATH_LEN]; sprintf(path, "%s.table", name); @@ -1223,7 +1415,7 @@ Table* AmigaDisk::loadTable(const char* name) { return t; } -Font* AmigaDisk::loadFont(const char* name) { +Font* AmigaDisk_ns::loadFont(const char* name) { debugC(1, kDebugDisk, "AmigaFullDisk::loadFont '%s'", name); char path[PATH_LEN]; @@ -1245,11 +1437,11 @@ Font* AmigaDisk::loadFont(const char* name) { } -Common::ReadStream* AmigaDisk::loadMusic(const char* name) { +Common::SeekableReadStream* AmigaDisk_ns::loadMusic(const char* name) { return openArchivedFile(name); } -Common::ReadStream* AmigaDisk::loadSound(const char* name) { +Common::ReadStream* AmigaDisk_ns::loadSound(const char* name) { char path[PATH_LEN]; sprintf(path, "%s.snd", name); diff --git a/engines/parallaction/font.cpp b/engines/parallaction/font.cpp index 56c26b7b4f..13e94a4cda 100644 --- a/engines/parallaction/font.cpp +++ b/engines/parallaction/font.cpp @@ -408,7 +408,7 @@ void AmigaFont::drawString(byte *buffer, uint32 pitch, const char *s) { } -Font *DosDisk::createFont(const char *name, Cnv* cnv) { +Font *DosDisk_ns::createFont(const char *name, Cnv* cnv) { Font *f = 0; if (!scumm_stricmp(name, "comic")) @@ -425,7 +425,7 @@ Font *DosDisk::createFont(const char *name, Cnv* cnv) { return f; } -Font *AmigaDisk::createFont(const char *name, Common::SeekableReadStream &stream) { +Font *AmigaDisk_ns::createFont(const char *name, Common::SeekableReadStream &stream) { // TODO: implement AmigaLabelFont for labels return new AmigaFont(stream); } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 59645381b6..8d45c4aaa9 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -30,9 +30,6 @@ #include "parallaction/parallaction.h" - -extern OSystem *g_system; - namespace Parallaction { byte * Gfx::_buffers[]; @@ -83,7 +80,7 @@ void Gfx::drawBalloon(const Common::Rect& r, uint16 winding) { winding = (winding == 0 ? 1 : 0); byte *s = _resBalloon[winding]; - byte *d = _buffers[kBitFront] + (r.left + (r.width()+5)/2 - 5) + (r.bottom - 1) * SCREEN_WIDTH; + byte *d = _buffers[kBitFront] + (r.left + (r.width()+5)/2 - 5) + (r.bottom - 1) * _vm->_screenWidth; for (uint16 i = 0; i < BALLOON_HEIGHT; i++) { for (uint16 j = 0; j < BALLOON_WIDTH; j++) { @@ -92,7 +89,7 @@ void Gfx::drawBalloon(const Common::Rect& r, uint16 winding) { s++; } - d += (SCREEN_WIDTH - BALLOON_WIDTH); + d += (_vm->_screenWidth - BALLOON_WIDTH); } // printf("done\n"); @@ -142,7 +139,7 @@ void Gfx::setPalette(Palette pal, uint32 first, uint32 num) { if (_vm->getPlatform() == Common::kPlatformAmiga) g_system->setPalette(sysExtraPal, first+FIRST_EHB_COLOR, num); - g_system->updateScreen(); +// g_system->updateScreen(); return; } @@ -206,14 +203,7 @@ void Gfx::animatePalette() { return; } -void Gfx::fadePalette(Palette pal) { - for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) - if (pal[i] < _palette[i]) pal[i]++; - - return; -} - -void Gfx::buildBWPalette(Palette pal) { +void Gfx::makeGrayscalePalette(Palette pal) { for (uint16 i = 0; i < BASE_PALETTE_COLORS; i++) { byte max; @@ -229,11 +219,19 @@ void Gfx::buildBWPalette(Palette pal) { return; } -void Gfx::quickFadePalette(Palette pal) { +void Gfx::fadePalette(Palette pal, Palette target, uint step) { + + if (step == 0) + return; for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) { - if (pal[i] == _palette[i]) continue; - pal[i] += (pal[i] < _palette[i] ? 4 : -4); + if (pal[i] == target[i]) continue; + + if (pal[i] < target[i]) + pal[i] = CLIP(pal[i] + step, (uint)0, (uint)target[i]); + else + pal[i] = CLIP(pal[i] - step, (uint)target[i], (uint)255); + } return; @@ -258,7 +256,7 @@ void Gfx::setHalfbriteMode(bool enable) { void Gfx::updateScreen() { // printf("Gfx::updateScreen()\n"); - g_system->copyRectToScreen(_buffers[kBitFront], SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + g_system->copyRectToScreen(_buffers[kBitFront], _vm->_screenWidth, 0, 0, _vm->_screenWidth, _vm->_screenHeight); g_system->updateScreen(); return; } @@ -277,7 +275,7 @@ void Gfx::swapBuffers() { // graphic primitives // void Gfx::clearScreen(Gfx::Buffers buffer) { - memset(_buffers[buffer], 0, SCREEN_WIDTH*SCREEN_HEIGHT); + memset(_buffers[buffer], 0, _vm->_screenSize); if (buffer == kBitFront) updateScreen(); @@ -286,9 +284,9 @@ void Gfx::clearScreen(Gfx::Buffers buffer) { void Gfx::copyScreen(Gfx::Buffers srcbuffer, Gfx::Buffers dstbuffer) { - memcpy(_buffers[dstbuffer], _buffers[srcbuffer], SCREEN_WIDTH*SCREEN_HEIGHT); + memcpy(_buffers[dstbuffer], _buffers[srcbuffer], _vm->_screenSize); - if (dstbuffer == kBitFront) updateScreen(); +// if (dstbuffer == kBitFront) updateScreen(); return; } @@ -296,25 +294,25 @@ void Gfx::copyScreen(Gfx::Buffers srcbuffer, Gfx::Buffers dstbuffer) { void Gfx::floodFill(Gfx::Buffers buffer, const Common::Rect& r, byte color) { // printf("Gfx::floodFill(%i, %i, %i, %i, %i)\n", color, left, top, right, bottom); - byte *d = _buffers[buffer] + (r.left + r.top * SCREEN_WIDTH); + byte *d = _buffers[buffer] + (r.left + r.top * _vm->_screenWidth); uint16 w = r.width() + 1; uint16 h = r.height() + 1; for (uint16 i = 0; i < h; i++) { memset(d, color, w); - d += SCREEN_WIDTH; + d += _vm->_screenWidth; } return; } -void screenClip(Common::Rect& r, Common::Point& p) { +void Gfx::screenClip(Common::Rect& r, Common::Point& p) { int32 x = r.left; int32 y = r.top; - Common::Rect screen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + Common::Rect screen(0, 0, _vm->_screenWidth, _vm->_screenHeight); r.clip(screen); @@ -335,7 +333,7 @@ void Gfx::flatBlit(const Common::Rect& r, byte *data, Gfx::Buffers buffer) { screenClip(q, dp); byte *s = data + q.left + q.top * r.width(); - byte *d = _buffers[buffer] + dp.x + dp.y * SCREEN_WIDTH; + byte *d = _buffers[buffer] + dp.x + dp.y * _vm->_screenWidth; for (uint16 i = q.top; i < q.bottom; i++) { for (uint16 j = q.left; j < q.right; j++) { @@ -345,7 +343,7 @@ void Gfx::flatBlit(const Common::Rect& r, byte *data, Gfx::Buffers buffer) { } s += (r.width() - q.width()); - d += (SCREEN_WIDTH - q.width()); + d += (_vm->_screenWidth - q.width()); } return; @@ -360,12 +358,12 @@ void Gfx::blit(const Common::Rect& r, uint16 z, byte *data, Gfx::Buffers buffer) screenClip(q, dp); byte *s = data + q.left + q.top * r.width(); - byte *d = _buffers[buffer] + dp.x + dp.y * SCREEN_WIDTH; + byte *d = _buffers[buffer] + dp.x + dp.y * _vm->_screenWidth; for (uint16 i = q.top; i < q.bottom; i++) { uint16 n = dp.x % 4; - byte *m = _buffers[kMask0] + dp.x/4 + (dp.y + i - q.top)*SCREENMASK_WIDTH; + byte *m = _buffers[kMask0] + dp.x/4 + (dp.y + i - q.top)*_vm->_screenMaskWidth; for (uint16 j = q.left; j < q.right; j++) { if (*s != 0) { @@ -382,7 +380,7 @@ void Gfx::blit(const Common::Rect& r, uint16 z, byte *data, Gfx::Buffers buffer) } s += (r.width() - q.right + q.left); - d += (SCREEN_WIDTH - q.right + q.left); + d += (_vm->_screenWidth - q.right + q.left); } return; @@ -420,8 +418,8 @@ void jobEraseLabel(void *parm, Job *j) { if (_si < 0) _si = 0; if (_di > 190) _di = 190; - if (label->_cnv._width + _si > SCREEN_WIDTH) - _si = SCREEN_WIDTH - label->_cnv._width; + if (label->_cnv._width + _si > _vm->_screenWidth) + _si = _vm->_screenWidth - label->_cnv._width; Common::Rect r(label->_cnv._width, label->_cnv._height); r.moveTo(_vm->_gfx->_labelPosition[1]); @@ -438,8 +436,8 @@ void Gfx::initMouse(uint16 arg_0) { _mouseComposedArrow = _vm->_disk->loadPointer(); - byte temp[16*16]; - memcpy(temp, _mouseArrow, 16*16); + byte temp[MOUSEARROW_WIDTH*MOUSEARROW_HEIGHT]; + memcpy(temp, _mouseArrow, MOUSEARROW_WIDTH*MOUSEARROW_HEIGHT); uint16 k = 0; for (uint16 i = 0; i < 4; i++) { @@ -449,20 +447,30 @@ void Gfx::initMouse(uint16 arg_0) { return; } + void Gfx::setMousePointer(int16 index) { if (index == kCursorArrow) { // standard mouse pointer - g_system->setMouseCursor(_mouseArrow, 16, 16, 0, 0, 0); + g_system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0); g_system->showMouse(true); } else { // inventory item pointer byte *v8 = _mouseComposedArrow->_data0; - // FIXME: target offseting is not clear - extractInventoryGraphics(index, v8 + 7 + 32 * 7); - g_system->setMouseCursor(v8, 32, 32, 0, 0, 0); + // FIXME: destination offseting is not clear + byte* s = _vm->_char._objs->getFramePtr(getInventoryItemIndex(index)); + byte* d = v8 + 7 + MOUSECOMBO_WIDTH * 7; + + for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) { + memcpy(d, s, INVENTORYITEM_WIDTH); + + s += INVENTORYITEM_PITCH; + d += MOUSECOMBO_WIDTH; + } + + g_system->setMouseCursor(v8, MOUSECOMBO_WIDTH, MOUSECOMBO_HEIGHT, 0, 0, 0); } return; @@ -505,13 +513,13 @@ void Gfx::blitCnv(StaticCnv *cnv, int16 x, int16 y, uint16 z, Gfx::Buffers buffe void Gfx::backupDoorBackground(DoorData *data, int16 x, int16 y) { - byte *s = _buffers[kBit2] + x + y * SCREEN_WIDTH; + byte *s = _buffers[kBit2] + x + y * _vm->_screenWidth; byte *d = data->_background; for (uint16 i = 0; i < data->_cnv->_height ; i++) { memcpy(d, s, data->_cnv->_width); - s += SCREEN_WIDTH; + s += _vm->_screenWidth; d += data->_cnv->_width; } @@ -521,7 +529,7 @@ void Gfx::backupDoorBackground(DoorData *data, int16 x, int16 y) { void Gfx::backupGetBackground(GetData *data, int16 x, int16 y) { byte *t = data->_cnv->_data0; - byte *s = _buffers[kBitBack] + x + y * SCREEN_WIDTH; + byte *s = _buffers[kBitBack] + x + y * _vm->_screenWidth; byte *d = data->_backup; for (uint16 i = 0; i < data->_cnv->_height ; i++) { @@ -533,16 +541,48 @@ void Gfx::backupGetBackground(GetData *data, int16 x, int16 y) { s++; } - s += (SCREEN_WIDTH - data->_cnv->_width); + s += (_vm->_screenWidth - data->_cnv->_width); + } + + return; +} + +// +// restores background according to specified frame +// +void Gfx::restoreDoorBackground(StaticCnv *cnv, const Common::Rect& r, byte* background) { + + byte *t = cnv->_data0; + byte *s = background; + byte *d0 = _buffers[kBitBack] + r.left + r.top * _vm->_screenWidth; + byte *d1 = _buffers[kBit2] + r.left + r.top * _vm->_screenWidth; + + for (uint16 i = 0; i < r.height() ; i++) { + for (uint16 j = 0; j < r.width() ; j++) { + if (*t) { + *d0 = *s; + *d1 = *s; + } + + d0++; + d1++; + t++; + s++; + } + + d0 += (_vm->_screenWidth - r.width()); + d1 += (_vm->_screenWidth - r.width()); } + return; } + // // copies a rectangular bitmap on the background // -void Gfx::restoreZoneBackground(const Common::Rect& r, byte *data) { +void Gfx::restoreGetBackground(const Common::Rect& r, byte *data) { StaticCnv cnv; @@ -584,17 +624,17 @@ void Gfx::makeCnvFromString(StaticCnv *cnv, char *text) { } void Gfx::displayString(uint16 x, uint16 y, const char *text, byte color) { - byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH; + byte *dst = _buffers[kBitFront] + x + y*_vm->_screenWidth; _font->setColor(color); - _font->drawString(dst, SCREEN_WIDTH, text); + _font->drawString(dst, _vm->_screenWidth, text); } void Gfx::displayCenteredString(uint16 y, const char *text) { - uint16 x = (SCREEN_WIDTH - getStringWidth(text)) / 2; + uint16 x = (_vm->_screenWidth - getStringWidth(text)) / 2; displayString(x, y, text, 1); } -bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, byte color, uint16 wrapwidth) { +bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, byte color, int16 wrapwidth) { // printf("Gfx::displayWrappedString(%s, %i, %i, %i, %i)...", text, x, y, color, wrapwidth); uint16 lines = 0; @@ -606,6 +646,9 @@ bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, byte color, uint1 char token[40]; + if (wrapwidth == -1) + wrapwidth = _vm->_screenWidth; + while (strlen(text) > 0) { text = parseNextToken(text, token, 40, " ", true); @@ -694,11 +737,11 @@ void Gfx::restoreBackground(const Common::Rect& r) { if (left < 0) left = 0; if (top < 0) top = 0; - if (left >= SCREEN_WIDTH) return; - if (top >= SCREEN_HEIGHT) return; + if (left >= _vm->_screenWidth) return; + if (top >= _vm->_screenHeight) return; - if (left+width >= SCREEN_WIDTH) width = SCREEN_WIDTH - left; - if (top+height >= SCREEN_HEIGHT) height = SCREEN_HEIGHT - top; + if (left+width >= _vm->_screenWidth) width = _vm->_screenWidth - left; + if (top+height >= _vm->_screenHeight) height = _vm->_screenHeight - top; Common::Rect q(width, height); q.moveTo(left, top); @@ -706,8 +749,8 @@ void Gfx::restoreBackground(const Common::Rect& r) { copyRect( kBitBack, q, - _buffers[kBit2] + q.left + q.top * SCREEN_WIDTH, - SCREEN_WIDTH + _buffers[kBit2] + q.left + q.top * _vm->_screenWidth, + _vm->_screenWidth ); return; @@ -728,26 +771,26 @@ void Gfx::freeStaticCnv(StaticCnv *cnv) { void Gfx::setBackground(byte *background) { - memcpy(_buffers[kBitBack], background, SCREEN_WIDTH*SCREEN_HEIGHT); + memcpy(_buffers[kBitBack], background, _vm->_screenSize); copyScreen(kBitBack, kBit2); } void Gfx::setMask(byte *mask) { - memcpy(_buffers[kMask0], mask, SCREENMASK_WIDTH*SCREEN_HEIGHT); + memcpy(_buffers[kMask0], mask, _vm->_screenMaskSize); } void Gfx::copyRect(Gfx::Buffers dstbuffer, const Common::Rect& r, byte *src, uint16 pitch) { - byte *d = _buffers[dstbuffer] + r.left + SCREEN_WIDTH * r.top; + byte *d = _buffers[dstbuffer] + r.left + _vm->_screenWidth * r.top; byte *s = src; for (uint16 _si = 0; _si < r.height(); _si++) { memcpy(d, s, r.width()); s += pitch; - d += SCREEN_WIDTH; + d += _vm->_screenWidth; } @@ -756,51 +799,49 @@ void Gfx::copyRect(Gfx::Buffers dstbuffer, const Common::Rect& r, byte *src, uin void Gfx::grabRect(byte *dst, const Common::Rect& r, Gfx::Buffers srcbuffer, uint16 pitch) { - byte *s = _buffers[srcbuffer] + r.left + SCREEN_WIDTH * r.top; + byte *s = _buffers[srcbuffer] + r.left + _vm->_screenWidth * r.top; for (uint16 i = 0; i < r.height(); i++) { memcpy(dst, s, r.width()); - s += SCREEN_WIDTH; + s += _vm->_screenWidth; dst += pitch; } return; } +/* + the following 3 routines are hacks for Nippon Safes coming from the original code, + so they shouldn't be modified when adding support for other games +*/ void Gfx::plotMaskPixel(uint16 x, uint16 y, byte color) { - uint16 _ax = x + y * SCREEN_WIDTH; + uint16 _ax = x + y * _vm->_screenWidth; _buffers[kMask0][_ax >> 2] &= ~(3 << ((_ax & 3) << 1)); return; } - - - void Gfx::fillMaskRect(const Common::Rect& r, byte color) { - uint16 _di = r.left/4 + r.top*80; + uint16 _di = r.left/4 + r.top * _vm->_screenMaskWidth; for (uint16 _si = r.top; _si < r.bottom; _si++) { memset(&_buffers[kMask0][_di], color, r.width()/4+1); - _di += 80; + _di += _vm->_screenMaskWidth; } return; } - -// HACK -// this routine is only invoked from the 'intgrotta scenario' -// void Gfx::intGrottaHackMask() { memset(_buffers[kMask0] + 3600, 0, 3600); _bgLayers[1] = 500; return; } + int16 Gfx::queryMask(int16 v) { for (uint16 _si = 0; _si < 3; _si++) { @@ -814,13 +855,13 @@ Gfx::Gfx(Parallaction* vm) : _vm(vm) { g_system->beginGFXTransaction(); - g_system->initSize(SCREEN_WIDTH, SCREEN_HEIGHT); + g_system->initSize(_vm->_screenWidth, _vm->_screenHeight); g_system->endGFXTransaction(); - _buffers[kBitFront] = (byte*)malloc(SCREEN_SIZE); - _buffers[kBitBack] = (byte*)malloc(SCREEN_SIZE); - _buffers[kBit2] = (byte*)malloc(SCREEN_SIZE); - _buffers[kMask0] = (byte*)malloc(SCREENMASK_WIDTH * SCREEN_HEIGHT); + _buffers[kBitFront] = (byte*)malloc(_vm->_screenSize); + _buffers[kBitBack] = (byte*)malloc(_vm->_screenSize); + _buffers[kBit2] = (byte*)malloc(_vm->_screenSize); + _buffers[kMask0] = (byte*)malloc(_vm->_screenMaskWidth * _vm->_screenHeight); setBlackPalette(); diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index d535d3cf05..f518bd6625 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -36,14 +36,6 @@ namespace Parallaction { - -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 200 -#define SCREEN_SIZE SCREEN_WIDTH*SCREEN_HEIGHT - -#define SCREENMASK_WIDTH SCREEN_WIDTH/4 -#define SCREENPATH_WIDTH SCREEN_WIDTH/8 - #define BASE_PALETTE_COLORS 32 #define FIRST_BASE_COLOR 0 #define LAST_BASE_COLOR (FIRST_BASE_COLOR+BASE_PALETTE_COLORS-1) @@ -57,6 +49,12 @@ namespace Parallaction { #define BASE_PALETTE_SIZE BASE_PALETTE_COLORS*3 #define PALETTE_SIZE PALETTE_COLORS*3 +#define MOUSEARROW_WIDTH 16 +#define MOUSEARROW_HEIGHT 16 + +#define MOUSECOMBO_WIDTH 32 // sizes for cursor + selected inventory item +#define MOUSECOMBO_HEIGHT 32 + #include "common/pack-start.h" // START STRUCT PACKING struct PaletteFxRange { @@ -162,12 +160,13 @@ public: }; public: + void screenClip(Common::Rect& r, Common::Point& p); // dialogue and text void drawBalloon(const Common::Rect& r, uint16 arg_8); void displayString(uint16 x, uint16 y, const char *text, byte color); void displayCenteredString(uint16 y, const char *text); - bool displayWrappedString(char *text, uint16 x, uint16 y, byte color, uint16 wrapwidth = SCREEN_WIDTH); + bool displayWrappedString(char *text, uint16 x, uint16 y, byte color, int16 wrapwidth = -1); uint16 getStringWidth(const char *text); void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); @@ -176,7 +175,8 @@ public: void freeStaticCnv(StaticCnv *cnv); void backupDoorBackground(DoorData *data, int16 x, int16 y); void backupGetBackground(GetData *data, int16 x, int16 y); - void restoreZoneBackground(const Common::Rect& r, byte *data); + void restoreGetBackground(const Common::Rect& r, byte *data); + void restoreDoorBackground(StaticCnv *cnv, const Common::Rect& r, byte* background); // location void setBackground(byte *background); @@ -210,9 +210,8 @@ public: void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = BASE_PALETTE_COLORS); void setBlackPalette(); void animatePalette(); - void fadePalette(Palette palette); - void buildBWPalette(Palette palette); - void quickFadePalette(Palette palette); + void fadePalette(Palette palette, Palette target, uint step); // fades palette to target palette, with specified step + void makeGrayscalePalette(Palette palette); // transform palette into black and white // amiga specific void setHalfbriteMode(bool enable); diff --git a/engines/parallaction/intro.cpp b/engines/parallaction/intro.cpp deleted file mode 100644 index 96a072b28d..0000000000 --- a/engines/parallaction/intro.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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 "parallaction/parallaction.h" -#include "parallaction/menu.h" -#include "parallaction/sound.h" - -#include "graphics/primitives.h" - -namespace Parallaction { - -static Animation *_rightHandAnim; - -static uint16 _rightHandPositions[684] = { - 0x0064, 0x0046, 0x006c, 0x0046, 0x0074, 0x0046, 0x007c, 0x0046, - 0x0084, 0x0046, 0x008c, 0x0046, 0x0094, 0x0046, 0x009c, 0x0046, - 0x00a4, 0x0046, 0x00ac, 0x0046, 0x00b4, 0x0046, 0x00bc, 0x0046, - 0x00c4, 0x0046, 0x00cc, 0x0046, 0x00d4, 0x0046, 0x00dc, 0x0046, - 0x00e4, 0x0046, 0x00ec, 0x0046, 0x00f4, 0x0046, 0x00fc, 0x0046, - 0x0104, 0x0046, 0x00ff, 0x0042, 0x00ff, 0x004a, 0x00ff, 0x0052, - 0x00ff, 0x005a, 0x00ff, 0x0062, 0x00ff, 0x006a, 0x00ff, 0x0072, - 0x00ff, 0x007a, 0x00ff, 0x0082, 0x00ff, 0x008a, 0x00ff, 0x0092, - 0x00ff, 0x009a, 0x00ff, 0x00a2, 0x0104, 0x0097, 0x00fc, 0x0097, - 0x00f4, 0x0097, 0x00ec, 0x0097, 0x00e4, 0x0097, 0x00dc, 0x0097, - 0x00d4, 0x0097, 0x00cc, 0x0097, 0x00c4, 0x0097, 0x00bc, 0x0097, - 0x00b4, 0x0097, 0x00ac, 0x0097, 0x00a4, 0x0097, 0x009c, 0x0097, - 0x0094, 0x0097, 0x008c, 0x0097, 0x0084, 0x0097, 0x007c, 0x0097, - 0x0074, 0x0097, 0x006c, 0x0097, 0x0064, 0x0097, 0x0066, 0x0042, - 0x0066, 0x004a, 0x0066, 0x0052, 0x0066, 0x005a, 0x0066, 0x0062, - 0x0066, 0x006a, 0x0066, 0x0072, 0x0066, 0x007a, 0x0066, 0x0082, - 0x0066, 0x008a, 0x0066, 0x0092, 0x0066, 0x009a, 0x0066, 0x00a2, - 0x008c, 0x0091, 0x0099, 0x0042, 0x0099, 0x004a, 0x0099, 0x0052, - 0x0099, 0x005a, 0x0099, 0x0062, 0x0099, 0x006a, 0x0099, 0x0072, - 0x0099, 0x007a, 0x0099, 0x0082, 0x0099, 0x008a, 0x0099, 0x0092, - 0x0099, 0x009a, 0x0099, 0x00a2, 0x00a0, 0x004d, 0x00cc, 0x0042, - 0x00cc, 0x004a, 0x00cc, 0x0052, 0x00cc, 0x005a, 0x00cc, 0x0062, - 0x00cc, 0x006a, 0x00cc, 0x0072, 0x00cc, 0x007a, 0x00cc, 0x0082, - 0x00cc, 0x008a, 0x00cc, 0x0092, 0x00cc, 0x009a, 0x00cc, 0x00a2, - 0x00ca, 0x0050, 0x00b1, 0x0050, 0x0081, 0x0052, 0x007e, 0x0052, - 0x007c, 0x0055, 0x007c, 0x005c, 0x007e, 0x005e, 0x0080, 0x005e, - 0x0082, 0x005c, 0x0082, 0x0054, 0x0080, 0x0052, 0x0078, 0x0052, - 0x007c, 0x005e, 0x0077, 0x0061, 0x0074, 0x006e, 0x0074, 0x0078, - 0x0076, 0x007a, 0x0079, 0x0078, 0x0079, 0x0070, 0x0078, 0x0070, - 0x0078, 0x006b, 0x007b, 0x0066, 0x007a, 0x006f, 0x0084, 0x006f, - 0x0085, 0x0066, 0x0086, 0x0070, 0x0085, 0x0070, 0x0085, 0x0079, - 0x0088, 0x0079, 0x008a, 0x0078, 0x008a, 0x006c, 0x0087, 0x0061, - 0x0085, 0x005f, 0x0082, 0x005f, 0x0080, 0x0061, 0x007e, 0x0061, - 0x007b, 0x005f, 0x007c, 0x006f, 0x007c, 0x0071, 0x0079, 0x0074, - 0x0079, 0x0089, 0x0076, 0x008c, 0x0076, 0x008e, 0x007a, 0x008e, - 0x007f, 0x0089, 0x007f, 0x0083, 0x007e, 0x0083, 0x007e, 0x0077, - 0x0080, 0x0077, 0x0080, 0x0083, 0x0080, 0x008b, 0x0084, 0x0090, - 0x0088, 0x0090, 0x0088, 0x008e, 0x0085, 0x008b, 0x0085, 0x0074, - 0x0082, 0x0071, 0x00b2, 0x0052, 0x00b0, 0x0054, 0x00b0, 0x0056, - 0x00ae, 0x0058, 0x00af, 0x0059, 0x00af, 0x005e, 0x00b2, 0x0061, - 0x00b5, 0x0061, 0x00b8, 0x005e, 0x00b8, 0x005a, 0x00b9, 0x0059, - 0x00b9, 0x0058, 0x00b7, 0x0056, 0x00b7, 0x0054, 0x00b5, 0x0052, - 0x00b2, 0x0052, 0x00ae, 0x005a, 0x00ab, 0x005b, 0x00ab, 0x006d, - 0x00ae, 0x0072, 0x00b8, 0x0072, 0x00bc, 0x006d, 0x00bc, 0x005b, - 0x00b9, 0x005a, 0x00bc, 0x005c, 0x00be, 0x005c, 0x00c1, 0x005f, - 0x00c4, 0x0067, 0x00c4, 0x006d, 0x00c1, 0x0076, 0x00c0, 0x0077, - 0x00bd, 0x0077, 0x00bb, 0x0075, 0x00bd, 0x0073, 0x00bb, 0x0072, - 0x00be, 0x0070, 0x00be, 0x006a, 0x00a9, 0x006a, 0x00a9, 0x0070, - 0x00ac, 0x0072, 0x00aa, 0x0073, 0x00ac, 0x0075, 0x00aa, 0x0077, - 0x00a7, 0x0077, 0x00a3, 0x006d, 0x00a3, 0x0067, 0x00a6, 0x005f, - 0x00a9, 0x005c, 0x00ab, 0x005c, 0x00ac, 0x0077, 0x00ac, 0x007c, - 0x00ab, 0x007c, 0x00ab, 0x0084, 0x00ac, 0x0084, 0x00ac, 0x008b, - 0x00a9, 0x008e, 0x00a9, 0x0090, 0x00ae, 0x0090, 0x00ae, 0x008d, - 0x00b2, 0x008c, 0x00b2, 0x0087, 0x00b1, 0x0086, 0x00b1, 0x007b, - 0x00b2, 0x0079, 0x00b4, 0x0079, 0x00b4, 0x007d, 0x00b5, 0x007d, - 0x00b5, 0x0087, 0x00b4, 0x0087, 0x00b4, 0x008c, 0x00b6, 0x008c, - 0x00b9, 0x0091, 0x00b4, 0x0091, 0x00bd, 0x008f, 0x00ba, 0x008c, - 0x00ba, 0x0083, 0x00bb, 0x0082, 0x00bb, 0x0075, 0x00cc, 0x006e, - 0x00d4, 0x006c, 0x00db, 0x0069, 0x00d9, 0x0068, 0x00d9, 0x0064, - 0x00dc, 0x0064, 0x00dc, 0x0060, 0x00df, 0x0056, 0x00e5, 0x0052, - 0x00e7, 0x0052, 0x00ec, 0x0056, 0x00ef, 0x005d, 0x00f1, 0x0065, - 0x00f3, 0x0064, 0x00f3, 0x0069, 0x00f0, 0x0069, 0x00ec, 0x0065, - 0x00ec, 0x005e, 0x00e9, 0x005f, 0x00e9, 0x005a, 0x00e7, 0x0058, - 0x00e4, 0x0058, 0x00e3, 0x0054, 0x00e3, 0x0058, 0x00e1, 0x005c, - 0x00e4, 0x0061, 0x00e7, 0x0061, 0x00e9, 0x005f, 0x00eb, 0x005d, - 0x00e4, 0x0062, 0x00e0, 0x0064, 0x00e0, 0x0069, 0x00e2, 0x006b, - 0x00e0, 0x0072, 0x00e0, 0x0077, 0x00ec, 0x0077, 0x00ec, 0x0071, - 0x00ea, 0x006b, 0x00ec, 0x006a, 0x00ec, 0x0063, 0x00e7, 0x0063, - 0x00e7, 0x0065, 0x00e1, 0x0069, 0x00e3, 0x0068, 0x00e6, 0x0069, - 0x00ec, 0x005e, 0x00ea, 0x006b, 0x00e7, 0x006b, 0x00e7, 0x006a, - 0x00e5, 0x006a, 0x00e5, 0x006b, 0x00e2, 0x006b, 0x00df, 0x006c, - 0x00dc, 0x006f, 0x00dc, 0x0071, 0x00da, 0x0073, 0x00d8, 0x0073, - 0x00d8, 0x006f, 0x00dc, 0x006b, 0x00dc, 0x0069, 0x00dd, 0x0068, - 0x00ef, 0x0068, 0x00f0, 0x0069, 0x00f0, 0x006b, 0x00f4, 0x006f, - 0x00f4, 0x0072, 0x00f3, 0x0073, 0x00f2, 0x0073, 0x00f0, 0x0071, - 0x00f0, 0x006f, 0x00ec, 0x006b, 0x00ec, 0x007a, 0x00eb, 0x007b, - 0x00eb, 0x007f, 0x00ec, 0x0080, 0x00ec, 0x0084, 0x00eb, 0x0085, - 0x00eb, 0x008b, 0x00ec, 0x008c, 0x00ec, 0x008f, 0x00ed, 0x0091, - 0x00e9, 0x0091, 0x00e9, 0x008f, 0x00e7, 0x008d, 0x00e7, 0x0090, - 0x00e7, 0x0089, 0x00e8, 0x0088, 0x00e8, 0x0086, 0x00e7, 0x0085, - 0x00e7, 0x007d, 0x00e6, 0x007c, 0x00e6, 0x0078, 0x00e5, 0x007d, - 0x00e5, 0x0085, 0x00e4, 0x0086, 0x00e4, 0x0088, 0x00e5, 0x0089, - 0x00e5, 0x0090, 0x00e5, 0x008b, 0x00e3, 0x0091, 0x00df, 0x0091, - 0x00e0, 0x0090, 0x00e0, 0x008c, 0x00e2, 0x008b, 0x00e1, 0x0085, - 0x00e0, 0x0084, 0x00e0, 0x0080, 0x00e1, 0x007f, 0x00e1, 0x007c, - 0x00e0, 0x007b, 0x00e0, 0x0077 -}; - -extern Credit _credits[]; - -void _c_startIntro(void *parm) { - _rightHandAnim = _vm->findAnimation("righthand"); - - if (_vm->getPlatform() == Common::kPlatformPC) { - _vm->_soundMan->setMusicFile("intro"); - _vm->_soundMan->playMusic(); - } - - _engineFlags |= kEngineBlockInput; - - return; -} - -void _c_endIntro(void *parm) { - - _vm->_gfx->setFont(kFontMenu); - - debugC(1, kDebugLocation, "endIntro()"); - - for (uint16 _si = 0; _si < 6; _si++) { - _vm->_gfx->displayCenteredString(80, _credits[_si]._role); - _vm->_gfx->displayCenteredString(100, _credits[_si]._name); - - _vm->_gfx->updateScreen(); - - for (uint16 v2 = 0; v2 < 100; v2++) { - _mouseButtons = kMouseNone; - _vm->updateInput(); - if (_mouseButtons == kMouseLeftUp) - break; - - _vm->waitTime( 1 ); - } - - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - } - debugC(1, kDebugLocation, "endIntro(): done showing credits"); - - if ((_vm->getFeatures() & GF_DEMO) == 0) { - _vm->_gfx->displayCenteredString(80, "CLICK MOUSE BUTTON TO START"); - _vm->_gfx->updateScreen(); - - waitUntilLeftClick(); - - _engineFlags &= ~kEngineBlockInput; - _vm->_menu->selectCharacter(); - } else { - waitUntilLeftClick(); - } - - return; -} - -void _c_moveSheet(void *parm) { - - static uint16 x = 319; - - if (x > 66) - x -= 16; - - Common::Rect r; - - r.left = x; - r.top = 47; - r.right = (x + 32 > 319) ? 319 : (x + 32); - r.bottom = 199; - _vm->_gfx->floodFill(Gfx::kBitBack, r, 1); - _vm->_gfx->floodFill(Gfx::kBit2, r, 1); - - if (x >= 104) return; - - r.left = x+215; - r.top = 47; - r.right = (x + 247 > 319) ? 319 : (x + 247); - r.bottom = 199; - _vm->_gfx->floodFill(Gfx::kBitBack, r, 12); - _vm->_gfx->floodFill(Gfx::kBit2, r, 12); - - return; -} - -void plotPixel(int x, int y, int color, void *data) { - _vm->_gfx->plotMaskPixel(x, y, color); -} - -void _c_sketch(void *parm) { - - static uint16 index = 1; - - uint16 newy = _rightHandPositions[2*index+1]; - uint16 newx = _rightHandPositions[2*index]; - - uint16 oldy = _rightHandPositions[2*(index-1)+1]; - uint16 oldx = _rightHandPositions[2*(index-1)]; - - Graphics::drawLine(oldx, oldy, newx, newy, 0, plotPixel, NULL); - - _rightHandAnim->_left = newx; - _rightHandAnim->_top = newy - 20; - - index++; - - return; -} - - - - -void _c_shade(void *parm) { - - Common::Rect r( - _rightHandAnim->_left - 36, - _rightHandAnim->_top - 36, - _rightHandAnim->_left, - _rightHandAnim->_top - ); - - _vm->_gfx->fillMaskRect(r, 0); - - return; - -} - -void _c_projector(void*) { -#ifdef HALFBRITE - static int dword_16032 = 0; - -// Bitmap bm; -// InitBitMap(&bm); - - if (dword_16032 != 0) { -/* // keep drawing spotlight in its final place - _vm->_gfx->flatBlitCnv(&scnv, 110, 25, Gfx::kBitFront); - BltBitMap(&bm, 0, 0, &_screen._bitMap, 110, 25, a3->??, a3->??, 0x20, 0x20); -*/ return; - } - - _vm->_gfx->setHalfbriteMode(true); -/* - // move spot light around the stage - int d7, d6; - for (d7 = 0; d7 < 150; d7++) { - - if (d7 < 100) { - int d1 = d7; - if (d1 < 0) - d1++; - - d1 >>= 1; - d6 = 50 - d1; - } else { - int d1 = d7 / 100; - if (d1 < 0) - d1++; - - d1 >>= 1; - d6 = d1; - } - - BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0x20, 0x20); - sub_1590C(d6 + a3->??); - BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0xFA, 0x20); - } - - for (d7 = 50; d7 > -10; d7--) { - BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); - sub_1590C(d6 + a3->??); - BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0xFA, 0x20); - } - - BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); - _vm->_gfx->flatBlitCnv(&scnv, d7+120, d6, Gfx::kBitFront); -*/ - - dword_16032 = 1; - return; -#endif -} - -void _c_HBOff(void*) { -#ifdef HALFBRITE - _vm->_gfx->setHalfbriteMode(false); -#endif -} - -void _c_HBOn(void*) { -#ifdef HALFBRITE - _vm->_gfx->setHalfbriteMode(true); -#endif -} - -} // namespace Parallaction diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp index 3581b956a6..c9e74b2074 100644 --- a/engines/parallaction/inventory.cpp +++ b/engines/parallaction/inventory.cpp @@ -42,10 +42,6 @@ namespace Parallaction { #define INVENTORY_MAX_ITEMS 30 #define INVENTORY_FIRST_ITEM 4 // first four entries are used up by verbs -#define INVENTORYITEM_PITCH 32 -#define INVENTORYITEM_WIDTH 24 -#define INVENTORYITEM_HEIGHT 24 - #define INVENTORY_ITEMS_PER_LINE 5 #define INVENTORY_LINES 6 @@ -89,7 +85,13 @@ InventoryItem _inventory[INVENTORY_MAX_ITEMS] = { { 0, 0 } }; -void drawInventoryItem(uint16 pos, InventoryItem *item); + +int16 getNumUsedSlots() { + int16 num = 0; + while (num < INVENTORY_MAX_ITEMS && _inventory[num]._id != 0) + num++; + return num; +} // get inventory item index at position (x,y) @@ -97,51 +99,55 @@ void drawInventoryItem(uint16 pos, InventoryItem *item); // int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) { - int16 slot = -1; - do { - slot++; - } while (_inventory[slot]._id != 0); - + int16 slot = getNumUsedSlots(); slot = (slot + 4) / INVENTORY_ITEMS_PER_LINE; - if (_invPosition.x >= x) return -1; - if ((_invPosition.x + INVENTORY_WIDTH) <= x) return -1; + Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT); + r.moveTo(_invPosition); - if (_invPosition.y >= y) return -1; - if ((slot * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1; + if (!r.contains(Common::Point(x,y))) + return -1; return ((x - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT)); } +void drawInventoryItem(uint16 pos, InventoryItem *item) { + + uint16 line = pos / INVENTORY_ITEMS_PER_LINE; + uint16 col = pos % INVENTORY_ITEMS_PER_LINE; -void refreshInventory(const char *character) { - for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) { - drawInventoryItem(i, &_inventory[i]); + // FIXME: this will end up in a general blit function + byte* s = _vm->_char._objs->getFramePtr(item->_index); + byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH; + for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) { + memcpy(d, s, INVENTORYITEM_WIDTH); + + d += INVENTORY_WIDTH; + s += INVENTORYITEM_PITCH; } + return; } -void refreshInventoryItem(const char *character, uint16 index) { - drawInventoryItem(index, &_inventory[index]); + +void refreshInventory() { + for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) + drawInventoryItem(i, &_inventory[i]); + return; } int Parallaction::addInventoryItem(uint16 item) { - uint16 slot = 0; - while (_inventory[slot]._id != 0) - slot++; - + int16 slot = getNumUsedSlots(); if (slot == INVENTORY_MAX_ITEMS) return -1; _inventory[slot]._id = MAKE_INVENTORY_ID(item); _inventory[slot]._index = item; - refreshInventoryItem(_characterName, slot); - return 0; } @@ -160,8 +166,6 @@ void Parallaction::dropItem(uint16 v) { memcpy(&_inventory[slot], &_inventory[slot+1], sizeof(InventoryItem)); } - refreshInventory(_characterName); - return; } @@ -177,28 +181,6 @@ int16 Parallaction::isItemInInventory(int32 v) { } - - - - -void drawInventoryItem(uint16 pos, InventoryItem *item) { - - uint16 line = pos / INVENTORY_ITEMS_PER_LINE; - uint16 col = pos % INVENTORY_ITEMS_PER_LINE; - - // FIXME: this will end up in a general blit function - byte* s = _vm->_char._objs->getFramePtr(item->_index); - byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH; - for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) { - memcpy(d, s, INVENTORYITEM_WIDTH); - - d += INVENTORY_WIDTH; - s += INVENTORYITEM_PITCH; - } - - return; -} - void drawBorder(const Common::Rect& r, byte *buffer, byte color) { byte *d = buffer + r.left + INVENTORY_WIDTH * r.top; @@ -237,33 +219,20 @@ void highlightInventoryItem(int16 pos, byte color) { } +int16 getInventoryItemIndex(int16 pos) { + // TODO: should assert against the number of items actually contained, + // not the theoretical limit. + assert(pos >= 0 && pos < INVENTORY_MAX_ITEMS); + return _inventory[pos]._index; +} -void extractInventoryGraphics(int16 pos, byte *dst) { -// printf("extractInventoryGraphics(%i)\n", pos); - - int16 line = pos / INVENTORY_ITEMS_PER_LINE; - int16 col = pos % INVENTORY_ITEMS_PER_LINE; - - // FIXME: this will end up in a general blit function - byte* d = dst; - byte* s = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH; - for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) { - memcpy(d, s, INVENTORYITEM_WIDTH); - - s += INVENTORY_WIDTH; - d += INVENTORYITEM_PITCH; - } - - return; -} void jobShowInventory(void *parm, Job *j) { // printf("job_showInventory()..."); - _numInvLines = 0; - while (_inventory[_numInvLines]._id != 0) _numInvLines++; - _numInvLines = (_numInvLines + 4) / INVENTORY_ITEMS_PER_LINE; + int16 slot = getNumUsedSlots(); + _numInvLines = (slot + 4) / INVENTORY_ITEMS_PER_LINE; Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT); @@ -308,25 +277,13 @@ void jobHideInventory(void *parm, Job *j) { void openInventory() { _engineFlags |= kEngineInventory; - uint16 slot = 0; - while (_inventory[slot]._id != 0) - slot++; - + int16 slot = getNumUsedSlots(); uint16 lines = (slot + 4) / INVENTORY_ITEMS_PER_LINE; - _invPosition.x = _vm->_mousePos.x - (INVENTORY_WIDTH / 2); - if (_invPosition.x < 0) - _invPosition.x = 0; - - if ((_invPosition.x + INVENTORY_WIDTH) > SCREEN_WIDTH) - _invPosition.x = SCREEN_WIDTH - INVENTORY_WIDTH; - - _invPosition.y = _vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT); - if (_invPosition.y < 0) - _invPosition.y = 0; + _invPosition.x = CLIP(_vm->_mousePos.x - (INVENTORY_WIDTH / 2), 0, (int)(_vm->_screenWidth - INVENTORY_WIDTH)); + _invPosition.y = CLIP(_vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, (int)(_vm->_screenHeight - lines * INVENTORYITEM_HEIGHT)); - if (_invPosition.y > SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT) - _invPosition.y = SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT; + refreshInventory(); return; diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h index 0f798ca502..4a3e07cc97 100644 --- a/engines/parallaction/inventory.h +++ b/engines/parallaction/inventory.h @@ -34,10 +34,14 @@ namespace Parallaction { struct Cnv; struct InventoryItem { - uint32 _id; // lowest 16 bits are always zero - uint16 _index; + uint32 _id; // object name (lowest 16 bits are always zero) + uint16 _index; // index to frame in objs file }; +#define INVENTORYITEM_PITCH 32 +#define INVENTORYITEM_WIDTH 24 +#define INVENTORYITEM_HEIGHT 24 + #define MAKE_INVENTORY_ID(x) (((x) & 0xFFFF) << 16) @@ -47,14 +51,11 @@ void initInventory(); void destroyInventory(); void openInventory(); void closeInventory(); -int16 isItemInInventory(int32 v); void cleanInventory(); void addInventoryItem(uint16 item); +int16 getInventoryItemIndex(int16 pos); void highlightInventoryItem(int16 pos, byte color); -void refreshInventory(const char *character); - -void extractInventoryGraphics(int16 pos, byte *dst); } // namespace Parallaction diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp index 3c54460692..024938074b 100644 --- a/engines/parallaction/location.cpp +++ b/engines/parallaction/location.cpp @@ -25,6 +25,8 @@ #include "common/stdafx.h" +#include "common/system.h" + #include "parallaction/parallaction.h" #include "parallaction/sound.h" @@ -249,7 +251,9 @@ void Parallaction::switchBackground(const char* background, const char* mask) { _si += 3; } + g_system->delayMillis(20); _gfx->setPalette(pal); + _gfx->updateScreen(); } _disk->loadScenery(background, mask); @@ -371,6 +375,7 @@ void Parallaction::changeLocation(char *location) { _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); _gfx->setBlackPalette(); + _gfx->updateScreen(); if (_location._commands.size() > 0) { runCommands(_location._commands); @@ -419,7 +424,7 @@ void Parallaction::doLocationEnterTransition() { } byte pal[PALETTE_SIZE]; - _gfx->buildBWPalette(pal); + _gfx->makeGrayscalePalette(pal); _gfx->setPalette(pal); jobRunScripts(NULL, NULL); @@ -447,9 +452,10 @@ void Parallaction::doLocationEnterTransition() { // fades maximum intensity palette towards approximation of main palette for (uint16 _si = 0; _si<6; _si++) { - _gfx->quickFadePalette(pal); + _gfx->fadePalette(pal, _gfx->_palette, 4); _gfx->setPalette(pal); waitTime( 1 ); + _gfx->updateScreen(); } debugC(1, kDebugLocation, "doLocationEnterTransition completed"); diff --git a/engines/parallaction/menu.cpp b/engines/parallaction/menu.cpp index 427f24a467..12b03ab4b0 100644 --- a/engines/parallaction/menu.cpp +++ b/engines/parallaction/menu.cpp @@ -87,14 +87,15 @@ const char *loadGameMsg[] = { #define SLOT_Y 64 #define SLOT_WIDTH (BLOCK_WIDTH+2) +#define PASSWORD_LEN 6 -static uint16 _amigaDinoKey[] = { 5, 3, 6, 2, 2, 7 }; -static uint16 _amigaDonnaKey[] = { 0, 3, 6, 2, 2, 6 }; -static uint16 _amigaDoughKey[] = { 1, 3 ,7, 2, 4, 6 }; +static uint16 _amigaDinoKey[PASSWORD_LEN] = { 5, 3, 6, 2, 2, 7 }; +static uint16 _amigaDonnaKey[PASSWORD_LEN] = { 0, 3, 6, 2, 2, 6 }; +static uint16 _amigaDoughKey[PASSWORD_LEN] = { 1, 3 ,7, 2, 4, 6 }; -static uint16 _pcDinoKey[] = { 5, 3, 6, 1, 4, 7 }; -static uint16 _pcDonnaKey[] = { 0, 2, 8, 5, 5, 1 }; -static uint16 _pcDoughKey[] = { 1, 7 ,7, 2, 2, 6 }; +static uint16 _pcDinoKey[PASSWORD_LEN] = { 5, 3, 6, 1, 4, 7 }; +static uint16 _pcDonnaKey[PASSWORD_LEN] = { 0, 2, 8, 5, 5, 1 }; +static uint16 _pcDoughKey[PASSWORD_LEN] = { 1, 7 ,7, 2, 2, 6 }; Menu::Menu(Parallaction *vm) { @@ -130,11 +131,13 @@ void Menu::splash() { _vm->_disk->loadSlide("intro"); _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _vm->_gfx->updateScreen(); g_system->delayMillis(2000); _vm->_disk->loadSlide("minintro"); _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _vm->_gfx->updateScreen(); g_system->delayMillis(2000); } @@ -161,15 +164,16 @@ void Menu::newGame() { _vm->_gfx->displayCenteredString(100, v14[2]); _vm->_gfx->displayCenteredString(120, v14[3]); + _vm->showCursor(false); + _vm->_gfx->updateScreen(); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); _mouseButtons = kMouseNone; - - for (; _mouseButtons != kMouseLeftUp; ) { + do { _vm->updateInput(); - if (_mouseButtons == kMouseRightUp) break; - } + } while (_mouseButtons != kMouseLeftUp && _mouseButtons != kMouseRightUp); + + _vm->showCursor(true); if (_mouseButtons != kMouseRightUp) { strcpy(_vm->_location._name, "fogne"); @@ -203,14 +207,10 @@ uint16 Menu::chooseLanguage() { _vm->_gfx->displayString(60, 30, "SELECT LANGUAGE", 1); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - _vm->changeCursor(kCursorArrow); do { _vm->updateInput(); - _vm->_gfx->swapBuffers(); if (_mouseButtons == kMouseLeftUp) { for (uint16 _si = 0; _si < 4; _si++) { @@ -242,7 +242,8 @@ uint16 Menu::chooseLanguage() { } } - _vm->waitTime( 1 ); + g_system->delayMillis(30); + _vm->_gfx->updateScreen(); } while (true); @@ -261,41 +262,33 @@ uint16 Menu::selectGame() { _vm->_disk->loadSlide("restore"); _vm->_gfx->setPalette(_vm->_gfx->_palette); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - uint16 _si = 0; uint16 _di = 3; - _vm->updateInput(); + _mouseButtons = kMouseNone; while (_mouseButtons != kMouseLeftUp) { _vm->updateInput(); - _vm->_gfx->swapBuffers(); - _vm->waitTime( 1 ); - _si = 0; - if (_vm->_mousePos.x > 160) - _si = 1; + _si = (_vm->_mousePos.x > 160) ? 1 : 0; - if (_si == _di) continue; + if (_si != _di) { + _di = _si; - _di = _si; - _vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + if (_si != 0) { + // load a game + _vm->_gfx->displayString(60, 30, loadGameMsg[_language], 1); + } else { + // new game + _vm->_gfx->displayString(60, 30, newGameMsg[_language], 1); + } - if (_si != 0) { - // load a game - _vm->_gfx->displayString(60, 30, loadGameMsg[_language], 1); - } else { - // new game - _vm->_gfx->displayString(60, 30, newGameMsg[_language], 1); } + g_system->delayMillis(30); _vm->_gfx->updateScreen(); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - } if (_si == 0) return 0; // new game @@ -316,6 +309,30 @@ uint16 Menu::selectGame() { } +int Menu::getSelectedBlock(const Common::Point &p, Common::Rect &r) { + + for (uint16 _si = 0; _si < 9; _si++) { + + Common::Rect q( + _si * BLOCK_X_OFFSET + BLOCK_SELECTION_X, + BLOCK_SELECTION_Y - _si * BLOCK_Y_OFFSET, + (_si + 1) * BLOCK_X_OFFSET + BLOCK_SELECTION_X, + BLOCK_SELECTION_Y + BLOCK_HEIGHT - _si * BLOCK_Y_OFFSET + ); + + if (q.contains(p)) { + r.setWidth(BLOCK_WIDTH); + r.setHeight(BLOCK_HEIGHT); + r.moveTo(_si * BLOCK_X_OFFSET + BLOCK_X, BLOCK_Y - _si * BLOCK_Y_OFFSET); + return _si; + } + + } + + return -1; +} + + // // character selection and protection // @@ -323,11 +340,8 @@ void Menu::selectCharacter() { debugC(1, kDebugMenu, "Menu::selectCharacter()"); uint16 _di = 0; - bool askPassword = true; - uint16 _donna_points = 0; - uint16 _dino_points = 0; - uint16 _dough_points = 0; + uint16 _donna_points, _dino_points, _dough_points; StaticCnv v14; @@ -343,51 +357,34 @@ void Menu::selectCharacter() { _vm->_disk->selectArchive((_vm->getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0"); _vm->_disk->loadSlide("password"); // loads background into kBitBack buffer - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); // - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); // + _vm->_gfx->setPalette(_vm->_gfx->_palette); - while (askPassword == true) { + while (true) { - askPassword = false; _di = 0; _vm->_gfx->displayString(60, 30, introMsg1[_language], 1); // displays message - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); _donna_points = 0; _dino_points = 0; _dough_points = 0; - while (_di < 6) { + while (_di < PASSWORD_LEN) { _mouseButtons = kMouseNone; do { _vm->updateInput(); - _vm->_gfx->swapBuffers(); - _vm->waitTime(1); + g_system->delayMillis(30); + _vm->_gfx->updateScreen(); } while (_mouseButtons != kMouseLeftUp); // waits for left click - for (uint16 _si = 0; _si < 9; _si++) { - - Common::Rect r( - _si * BLOCK_X_OFFSET + BLOCK_SELECTION_X, - BLOCK_SELECTION_Y - _si * BLOCK_Y_OFFSET, - (_si + 1) * BLOCK_X_OFFSET + BLOCK_SELECTION_X, - BLOCK_SELECTION_Y + BLOCK_HEIGHT - _si * BLOCK_Y_OFFSET - ); - - if (!r.contains(_vm->_mousePos)) continue; - - r.setWidth(BLOCK_WIDTH); - r.setHeight(BLOCK_HEIGHT); - r.moveTo(_si * BLOCK_X_OFFSET + BLOCK_X, BLOCK_Y - _si * BLOCK_Y_OFFSET); + Common::Rect r; + int _si = getSelectedBlock(_vm->_mousePos, r); + if (_si != -1) { _vm->_gfx->grabRect(v14._data0, r, Gfx::kBitFront, BLOCK_WIDTH); - - _vm->_gfx->flatBlitCnv(&v14, _di * SLOT_WIDTH + SLOT_X, SLOT_Y, Gfx::kBitBack); _vm->_gfx->flatBlitCnv(&v14, _di * SLOT_WIDTH + SLOT_X, SLOT_Y, Gfx::kBitFront); - // beep(); if (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT)) { @@ -408,33 +405,33 @@ void Menu::selectCharacter() { _di++; } - - askPassword = (_dino_points < 6 && _donna_points < 6 && _dough_points < 6); } - if (askPassword == false) break; + if (_dino_points == PASSWORD_LEN || _donna_points == PASSWORD_LEN || _dough_points == PASSWORD_LEN) { + break; + } - _vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); _vm->_gfx->displayString(60, 30, introMsg2[_language], 1); _vm->_gfx->updateScreen(); g_system->delayMillis(2000); - _vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); } - - if (_dino_points > _donna_points && _dino_points > _dough_points) { + if (_dino_points == PASSWORD_LEN) { sprintf(_vm->_location._name, "test.%s", _dinoName); - } else { - if (_donna_points > _dino_points && _donna_points > _dough_points) { - sprintf(_vm->_location._name, "test.%s", _donnaName); - } else { - sprintf(_vm->_location._name, "test.%s", _doughName); - } + } else + if (_donna_points == PASSWORD_LEN) { + sprintf(_vm->_location._name, "test.%s", _donnaName); + } else + if (_dough_points == PASSWORD_LEN) { + sprintf(_vm->_location._name, "test.%s", _doughName); } _vm->_gfx->setBlackPalette(); + _vm->_gfx->updateScreen(); _engineFlags |= kEngineChangeLocation; diff --git a/engines/parallaction/menu.h b/engines/parallaction/menu.h index a0b8b95371..bb9eabdfb7 100644 --- a/engines/parallaction/menu.h +++ b/engines/parallaction/menu.h @@ -48,6 +48,7 @@ protected: void newGame(); uint16 chooseLanguage(); uint16 selectGame(); + int getSelectedBlock(const Common::Point &p, Common::Rect& r); public: diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk index 592c0cb6a3..b7f60eeb32 100644 --- a/engines/parallaction/module.mk +++ b/engines/parallaction/module.mk @@ -2,21 +2,23 @@ MODULE := engines/parallaction MODULE_OBJS := \ animation.o \ - archive.o \ - callables.o \ + callables_br.o \ + callables_ns.o \ commands.o \ debug.o \ detection.o \ dialogue.o \ - disk.o \ + disk_br.o \ + disk_ns.o \ font.o \ graphics.o \ - intro.o \ inventory.o \ location.o \ menu.o \ parser.o \ parallaction.o \ + parallaction_br.o \ + parallaction_ns.o \ saveload.o \ sound.o \ staticres.o \ diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index c830b575a9..986bc6ebd7 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -146,73 +146,40 @@ Parallaction::~Parallaction() { int Parallaction::init() { - // Detect game - if (!detectGame()) { - GUIErrorMessage("No valid games were found in the specified directory."); - return -1; - } - + _engineFlags = 0; _objectsNames = NULL; _globalTable = NULL; - _localFlagNames = NULL; - initResources(); - _hasLocationSound = false; - _skipMenu = false; - _transCurrentHoverItem = 0; _actionAfterWalk = false; // actived when the character needs to move before taking an action _activeItem._index = 0; _activeItem._id = 0; _procCurrentHoverItem = -1; - -// _musicData1 = 0; - strcpy(_characterName1, "null"); - - _soundMan = 0; - _baseTime = 0; - - if (getPlatform() == Common::kPlatformPC) { - _disk = new DosDisk(this); - } else { - if (getFeatures() & GF_DEMO) { - strcpy(_location._name, "fognedemo"); - } - _disk = new AmigaDisk(this); - _disk->selectArchive((_vm->getFeatures() & GF_DEMO) ? "disk0" : "disk1"); - } - - _engineFlags = 0; - - strcpy(_characterName, "dough"); - - memset(_locationNames, 0, 120*32); _numLocations = 0; - _location._startPosition.x = -1000; _location._startPosition.y = -1000; _location._startFrame = 0; - _location._comment = NULL; _location._endComment = NULL; - initWalk(); + _screenMaskWidth = _screenWidth / 4; + _screenPathWidth = _screenWidth / 8; + _screenSize = _screenWidth * _screenHeight; + _screenMaskSize = _screenMaskWidth * _screenHeight; + _screenPathSize = _screenPathWidth * _screenHeight; - initInventory(); + strcpy(_characterName1, "null"); + strcpy(_characterName, "dough"); - _animations.push_front(&_vm->_char._ani); - _gfx = new Gfx(this); + memset(_locationNames, 0, 120*32); - if (getPlatform() == Common::kPlatformPC) { - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - _soundMan = new DosSoundMan(this, driver); - _soundMan->setMusicVolume(ConfMan.getInt("music_volume")); - } else { - _soundMan = new AmigaSoundMan(this); - } + initWalk(); // needs to be pushed into subclass + initInventory(); // needs to be pushed into subclass + + _animations.push_front(&_char._ani); + _gfx = new Gfx(this); _debugger = new Debugger(this); @@ -252,9 +219,9 @@ void Parallaction::initGame() { parseLocation(_location._name); if (_location._startPosition.x != -1000) { - _vm->_char._ani._left = _location._startPosition.x; - _vm->_char._ani._top = _location._startPosition.y; - _vm->_char._ani._frame = _location._startFrame; + _char._ani._left = _location._startPosition.x; + _char._ani._top = _location._startPosition.y; + _char._ani._frame = _location._startFrame; _location._startPosition.y = -1000; _location._startPosition.x = -1000; } @@ -346,7 +313,8 @@ void waitUntilLeftClick() { break; } - g_system->delayMillis(10); + _vm->_gfx->updateScreen(); + g_system->delayMillis(30); } @@ -498,9 +466,9 @@ void Parallaction::processInput(InputData *data) { debugC(2, kDebugInput, "processInput: kEvWalk"); _hoverZone = NULL; changeCursor(kCursorArrow); - if (_vm->_char._ani._flags & kFlagsRemove) break; - if ((_vm->_char._ani._flags & kFlagsActive) == 0) break; - WalkNodeList *v4 = _vm->_char._builder.buildPath(data->_mousePos.x, data->_mousePos.y); + if (_char._ani._flags & kFlagsRemove) break; + if ((_char._ani._flags & kFlagsActive) == 0) break; + WalkNodeList *v4 = _char._builder.buildPath(data->_mousePos.x, data->_mousePos.y); addJob(&jobWalk, v4, kPriority19); _engineFlags |= kEngineWalking; // inhibits processing of input until walking is over } @@ -716,27 +684,27 @@ void Parallaction::changeCursor(int32 index) { void Parallaction::freeCharacter() { debugC(3, kDebugLocation, "freeCharacter()"); - if (!IS_DUMMY_CHARACTER(_vm->_characterName)) { + if (!IS_DUMMY_CHARACTER(_characterName)) { if (_objectsNames) delete _objectsNames; _objectsNames = NULL; - if (_vm->_char._ani._cnv) - delete _vm->_char._ani._cnv; - _vm->_char._ani._cnv = NULL; + if (_char._ani._cnv) + delete _char._ani._cnv; + _char._ani._cnv = NULL; - if (_vm->_char._talk) - delete _vm->_char._talk; - _vm->_char._talk = NULL; + if (_char._talk) + delete _char._talk; + _char._talk = NULL; - _vm->_gfx->freeStaticCnv(_vm->_char._head); - if (_vm->_char._head) - delete _vm->_char._head; - _vm->_char._head = NULL; + _gfx->freeStaticCnv(_char._head); + if (_char._head) + delete _char._head; + _char._head = NULL; - if (_vm->_char._objs) - delete _vm->_char._objs; - _vm->_char._objs = NULL; + if (_char._objs) + delete _char._objs; + _char._objs = NULL; } return; @@ -763,18 +731,17 @@ void Parallaction::changeCharacter(const char *name) { // character for sanity before memory is freed freeCharacter(); - Common::String oldArchive = _disk->selectArchive((_vm->getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0"); - _vm->_char._ani._cnv = _disk->loadFrames(fullName); + Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0"); + _char._ani._cnv = _disk->loadFrames(fullName); if (!IS_DUMMY_CHARACTER(name)) { - if (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT)) + if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_LANG_MULT)) _disk->selectArchive("disk0"); - _vm->_char._head = _disk->loadHead(baseName); - _vm->_char._talk = _disk->loadTalk(baseName); - _vm->_char._objs = _disk->loadObjects(baseName); + _char._head = _disk->loadHead(baseName); + _char._talk = _disk->loadTalk(baseName); + _char._objs = _disk->loadObjects(baseName); _objectsNames = _disk->loadTable(baseName); - refreshInventory(baseName); _soundMan->playCharacterMusic(name); diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 561b15acc9..31b125c92a 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -43,6 +43,7 @@ namespace GUI { class CommandSender; } +extern OSystem *g_system; namespace Parallaction { @@ -159,11 +160,6 @@ public: typedef Job* JobPointer; typedef ManagedList<JobPointer> JobList; -struct Credit { - const char *_role; - const char *_name; -}; - typedef void (*callable)(void*); extern uint16 _mouseButtons; @@ -181,8 +177,6 @@ extern uint16 _introSarcData3; // sarcophagus stuff to be saved extern uint16 _introSarcData2; // sarcophagus stuff to be saved extern char _saveData1[]; extern uint32 _commandFlags; -extern const char *_instructionNamesRes[]; -extern const char *_commandsNamesRes[]; extern const char *_dinoName; extern const char *_donnaName; extern const char *_doughName; @@ -360,6 +354,16 @@ private: const PARALLACTIONGameDescription *_gameDescription; public: + // info + int32 _screenWidth; + int32 _screenHeight; + int32 _screenSize; + + int32 _screenMaskWidth; + int32 _screenMaskSize; + int32 _screenPathWidth; + int32 _screenPathSize; + SoundMan *_soundMan; Gfx* _gfx; @@ -424,7 +428,6 @@ protected: // members void initGame(); void initGlobals(); - void initResources(); void runGame(); uint32 getElapsedTime(); void resetTimer(); @@ -467,6 +470,103 @@ protected: // members int16 pickupItem(Zone *z); int16 isItemInInventory(int32 v); int16 getHoverInventoryItem(int16 x, int16 y); + +public: + virtual void callFunction(uint index, void* parm) { } + +public: + const char **_zoneFlagNamesRes; + const char **_zoneTypeNamesRes; + const char **_commandsNamesRes; + const char **_callableNamesRes; + const char **_instructionNamesRes; + +}; + +class Parallaction_ns : public Parallaction { + +public: + Parallaction_ns(OSystem* syst) : Parallaction(syst) { } + ~Parallaction_ns() { } + + int init(); + +public: + typedef void (Parallaction_ns::*Callable)(void*); + + virtual void callFunction(uint index, void* parm); + +private: + void initResources(); + + static const Callable _dosCallables[25]; + static const Callable _amigaCallables[25]; + + // common callables + void _c_play_boogie(void*); + void _c_startIntro(void*); + void _c_endIntro(void*); + void _c_moveSheet(void*); + void _c_sketch(void*); + void _c_shade(void*); + void _c_score(void*); + void _c_fade(void*); + void _c_moveSarc(void*); + void _c_contaFoglie(void*); + void _c_zeroFoglie(void*); + void _c_trasformata(void*); + void _c_offMouse(void*); + void _c_onMouse(void*); + void _c_setMask(void*); + void _c_endComment(void*); + void _c_frankenstein(void*); + void _c_finito(void*); + void _c_ridux(void*); + void _c_testResult(void*); + + // dos specific callables + void _c_null(void*); + + // amiga specific callables + void _c_projector(void*); + void _c_HBOff(void*); + void _c_offSound(void*); + void _c_startMusic(void*); + void _c_closeMusic(void*); + void _c_HBOn(void*); + + const Callable *_callables; +}; + +class Parallaction_br : public Parallaction { + +public: + Parallaction_br(OSystem* syst) : Parallaction(syst) { } + ~Parallaction_br() { } + + int init(); + +public: + typedef void (Parallaction_br::*Callable)(void*); + virtual void callFunction(uint index, void* parm); + +public: + Table *_audioCommandsNames; + const char **_audioCommandsNamesRes; + +private: + void initResources(); + + static const Callable _dosCallables[6]; + + void _c_blufade(void*); + void _c_resetpalette(void*); + void _c_ferrcycle(void*); + void _c_lipsinc(void*); + void _c_albcycle(void*); + void _c_password(void*); + + const Callable *_callables; }; // FIXME: remove global diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp new file mode 100644 index 0000000000..7dcc94d7c6 --- /dev/null +++ b/engines/parallaction/parallaction_br.cpp @@ -0,0 +1,66 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 "parallaction/parallaction.h" +#include "parallaction/sound.h" + +namespace Parallaction { + +int Parallaction_br::init() { + + // Detect game + if (!detectGame()) { + GUIErrorMessage("No valid games were found in the specified directory."); + return -1; + } + + _screenWidth = 640; + _screenHeight = 400; + + if (getGameType() == GType_BRA) { + if (getPlatform() == Common::kPlatformPC) { + _disk = new DosDisk_br(this); + } else + error("unsupported platform for Big Red Adventure"); + } else + error("unknown game type"); + + _soundMan = new DummySoundMan(this); + + initResources(); + + Parallaction::init(); + + return 0; +} + +void Parallaction_br::callFunction(uint index, void* parm) { + assert(index < 6); // magic value 6 is maximum # of callables for Big Red Adventure + + (this->*_callables[index])(parm); +} + +} // namespace Parallaction diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp new file mode 100644 index 0000000000..947cb22a7f --- /dev/null +++ b/engines/parallaction/parallaction_ns.cpp @@ -0,0 +1,78 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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/config-manager.h" + +#include "parallaction/parallaction.h" +#include "parallaction/sound.h" + +namespace Parallaction { + +int Parallaction_ns::init() { + + // Detect game + if (!detectGame()) { + GUIErrorMessage("No valid games were found in the specified directory."); + return -1; + } + + _screenWidth = 320; + _screenHeight = 200; + + if (getPlatform() == Common::kPlatformPC) { + _disk = new DosDisk_ns(this); + } else { + if (getFeatures() & GF_DEMO) { + strcpy(_location._name, "fognedemo"); + } + _disk = new AmigaDisk_ns(this); + _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1"); + } + + if (getPlatform() == Common::kPlatformPC) { + int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + MidiDriver *driver = MidiDriver::createMidi(midiDriver); + _soundMan = new DosSoundMan(this, driver); + _soundMan->setMusicVolume(ConfMan.getInt("music_volume")); + } else { + _soundMan = new AmigaSoundMan(this); + } + + initResources(); + + Parallaction::init(); + + return 0; +} + +void Parallaction_ns::callFunction(uint index, void* parm) { + assert(index < 25); // magic value 25 is maximum # of callables for Nippon Safes + + (this->*_callables[index])(parm); +} + + +} // namespace Parallaction diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 2a9431ef94..279dbda1b9 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -166,8 +166,6 @@ void Parallaction::doLoadGame(uint16 slot) { // freeTable(_objectsNames); // initTable(filename, _objectsNames); -// refreshInventory(_vm->_characterName); - // parseLocation("common"); // force reload of character to solve inventory @@ -238,11 +236,7 @@ void Parallaction::doSaveGame(uint16 slot, const char* name) { delete f; - refreshInventory(_characterName); - return; - - } enum { diff --git a/engines/parallaction/sound.cpp b/engines/parallaction/sound.cpp index 13b989e202..21dcc3c788 100644 --- a/engines/parallaction/sound.cpp +++ b/engines/parallaction/sound.cpp @@ -379,7 +379,7 @@ void AmigaSoundMan::playMusic() { debugC(1, kDebugAudio, "AmigaSoundMan::playMusic()"); - Common::ReadStream *stream = _vm->_disk->loadMusic(_musicFile); + Common::SeekableReadStream *stream = _vm->_disk->loadMusic(_musicFile); _musicStream = Audio::makeProtrackerStream(stream); delete stream; diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h index f244bd4070..7a903ec790 100644 --- a/engines/parallaction/sound.h +++ b/engines/parallaction/sound.h @@ -108,6 +108,22 @@ public: void playLocationMusic(const char *location); }; +class DummySoundMan : public SoundMan { + +public: + DummySoundMan(Parallaction *vm) : SoundMan(vm) { } + ~DummySoundMan() { } + void playMusic() { } + void stopMusic() { } + + void playSfx(const char *filename, uint channel, bool looping, int volume, int rate) { } + void stopSfx(uint channel) { } + + void playCharacterMusic(const char *character) { } + void playLocationMusic(const char *location) { } + +}; + } // namespace Parallaction #endif diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index e6cbc303b0..046176a933 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -219,7 +219,7 @@ byte _amigaTopazFont[2600] = -const char *_zoneFlagNamesRes[] = { +const char *_zoneFlagNamesRes_ns[] = { "closed", "active", "remove", @@ -234,7 +234,7 @@ const char *_zoneFlagNamesRes[] = { "nowalk" }; -const char *_zoneTypeNamesRes[] = { +const char *_zoneTypeNamesRes_ns[] = { "examine", "door", "get", @@ -262,7 +262,7 @@ const char _gameNames[10][20] = { "GAME10" }; -const char *_commandsNamesRes[] = { +const char *_commandsNamesRes_ns[] = { "set", "clear", "start", @@ -281,7 +281,7 @@ const char *_commandsNamesRes[] = { "stop" }; -const char *_instructionNamesRes[] = { +const char *_instructionNamesRes_ns[] = { "on", "off", "x", @@ -302,7 +302,7 @@ const char *_instructionNamesRes[] = { "move" }; -const char *_callableNamesRes[] = { +const char *_callableNamesRes_ns[] = { "Projector", "HBOff", "StartIntro", @@ -330,48 +330,146 @@ const char *_callableNamesRes[] = { "TestResult" }; -typedef void (*callable)(void*); - - -void _c_play_boogie(void*); -void _c_startIntro(void*); -void _c_endIntro(void*); -void _c_moveSheet(void*); -void _c_sketch(void*); -void _c_shade(void*); -void _c_score(void*); -void _c_fade(void*); -void _c_moveSarc(void*); -void _c_contaFoglie(void*); -void _c_zeroFoglie(void*); -void _c_trasformata(void*); -void _c_offMouse(void*); -void _c_onMouse(void*); -void _c_setMask(void*); -void _c_endComment(void*); -void _c_frankenstein(void*); -void _c_finito(void*); -void _c_ridux(void*); -void _c_testResult(void*); -void _c_null(void*); - -void _c_projector(void*); -void _c_HBOff(void*); -void _c_offSound(void*); -void _c_startMusic(void*); -void _c_closeMusic(void*); -void _c_HBOn(void*); - -callable _callables[25]; - - -Credit _credits[] = { - {"Music and Sound Effects", "MARCO CAPRELLI"}, - {"PC Version", "RICCARDO BALLARINO"}, - {"Project Manager", "LOVRANO CANEPA"}, - {"Production", "BRUNO BOZ"}, - {"Special Thanks to", "LUIGI BENEDICENTI - GILDA and DANILO"}, - {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"} +const char *_zoneTypeNamesRes_br[] = { + "examine", + "door", + "get", + "merge", + "taste", + "hear", + "feel", + "speak", + "none", + "trap", + "you", + "command", + "path", + "box" +}; + +const char *_zoneFlagNamesRes_br[] = { + "closed", + "active", + "remove", + "acting", + "locked", + "fixed", + "noname", + "nomasked", + "looping", + "added", + "character", + "nowalk", + "yourself", + "scaled", + "selfuse" +}; + +const char *_instructionNamesRes_br[] = { + "on", + "off", + "x", + "y", + "z", + "f", + "loop", + "endloop", + "show", + "inc", + "dec", + "set", + "put", + "call", + "wait", + "start", + "process", + "move", + "color", + "sound", + "mask", + "print", + "text", + "mul", + "div", + "if", + "ifeq", + "iflt", + "ifgt", + "endif", + "stop" +}; + +const char *_commandsNamesRes_br[] = { + "set", + "clear", + "start", + "speak", + "get" + "location", + "open", + "close", + "on", + "off", + "call", + "toggle", + "drop", + "quit", + "move", + "stop", + "character", + "followme", + "onmouse", + "offmouse", + "add", + "leave", + "inc", + "dec", + "text", + "dummy", + "dummy", + "let", + "music", + "fix", + "unfix", + "zeta", + "scroll", + "swap", + "give", + "text", + "part", + "dummy", + "return", + "onsave", + "offsave" +}; + +const char *_callableNamesRes_br[] = { + "blufade", + "resetpalette", + "ferrcycle", + "lipsinc", + "albycle", + "password" +}; + +const char *_audioCommandsNamesRes_br[] = { + "play", + "stop", + "pause", + "channel_level", + "fadein", + "fadeout", + "volume", + " ", + "faderate", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "loop" }; const char *_dinoName = "dino"; @@ -384,73 +482,124 @@ const char *_minidonnaName = "minidonna"; const char *_minidoughName = "minidough"; const char *_minidrkiName = "minidrki"; +#define CALLABLE_NS(x) &Parallaction_ns::x + +const Parallaction_ns::Callable Parallaction_ns::_dosCallables[] = { + CALLABLE_NS(_c_play_boogie), + CALLABLE_NS(_c_play_boogie), + CALLABLE_NS(_c_startIntro), + CALLABLE_NS(_c_endIntro), + CALLABLE_NS(_c_moveSheet), + CALLABLE_NS(_c_sketch), + CALLABLE_NS(_c_shade), + CALLABLE_NS(_c_score), + CALLABLE_NS(_c_null), + CALLABLE_NS(_c_null), + CALLABLE_NS(_c_null), + CALLABLE_NS(_c_fade), + CALLABLE_NS(_c_play_boogie), + CALLABLE_NS(_c_moveSarc), + CALLABLE_NS(_c_contaFoglie), + CALLABLE_NS(_c_zeroFoglie), + CALLABLE_NS(_c_trasformata), + CALLABLE_NS(_c_offMouse), + CALLABLE_NS(_c_onMouse), + CALLABLE_NS(_c_setMask), + CALLABLE_NS(_c_endComment), + CALLABLE_NS(_c_frankenstein), + CALLABLE_NS(_c_finito), + CALLABLE_NS(_c_ridux), + CALLABLE_NS(_c_testResult) +}; + +const Parallaction_ns::Callable Parallaction_ns::_amigaCallables[] = { + CALLABLE_NS(_c_projector), + CALLABLE_NS(_c_HBOff), + CALLABLE_NS(_c_startIntro), + CALLABLE_NS(_c_endIntro), + CALLABLE_NS(_c_moveSheet), + CALLABLE_NS(_c_sketch), + CALLABLE_NS(_c_shade), + CALLABLE_NS(_c_score), + CALLABLE_NS(_c_offSound), + CALLABLE_NS(_c_startMusic), + CALLABLE_NS(_c_closeMusic), + CALLABLE_NS(_c_fade), + CALLABLE_NS(_c_play_boogie), + CALLABLE_NS(_c_moveSarc), + CALLABLE_NS(_c_contaFoglie), + CALLABLE_NS(_c_zeroFoglie), + CALLABLE_NS(_c_trasformata), + CALLABLE_NS(_c_offMouse), + CALLABLE_NS(_c_onMouse), + CALLABLE_NS(_c_setMask), + CALLABLE_NS(_c_endComment), + CALLABLE_NS(_c_frankenstein), + CALLABLE_NS(_c_finito), + CALLABLE_NS(_c_ridux), + CALLABLE_NS(_c_testResult) +}; + +#define CALLABLE_BR(x) &Parallaction_br::x + +const Parallaction_br::Callable Parallaction_br::_dosCallables[] = { + CALLABLE_BR(_c_blufade), + CALLABLE_BR(_c_resetpalette), + CALLABLE_BR(_c_ferrcycle), + CALLABLE_BR(_c_lipsinc), + CALLABLE_BR(_c_albcycle), + CALLABLE_BR(_c_password) +}; + +void Parallaction_ns::initResources() { -void Parallaction::initResources() { + _zoneFlagNamesRes = _zoneFlagNamesRes_ns; + _zoneTypeNamesRes = _zoneTypeNamesRes_ns; + _commandsNamesRes = _commandsNamesRes_ns; + _callableNamesRes = _callableNamesRes_ns; + _instructionNamesRes = _instructionNamesRes_ns; - _callableNames = new Table(ARRAYSIZE(_callableNamesRes), _callableNamesRes); - _instructionNames = new Table(ARRAYSIZE(_instructionNamesRes), _instructionNamesRes); - _zoneFlagNames = new Table(ARRAYSIZE(_zoneFlagNamesRes), _zoneFlagNamesRes); - _zoneTypeNames = new Table(ARRAYSIZE(_zoneTypeNamesRes), _zoneTypeNamesRes); - _commandsNames = new Table(ARRAYSIZE(_commandsNamesRes), _commandsNamesRes); + _callableNames = new Table(ARRAYSIZE(_callableNamesRes_ns), _callableNamesRes_ns); + _instructionNames = new Table(ARRAYSIZE(_instructionNamesRes_ns), _instructionNamesRes_ns); + _zoneFlagNames = new Table(ARRAYSIZE(_zoneFlagNamesRes_ns), _zoneFlagNamesRes_ns); + _zoneTypeNames = new Table(ARRAYSIZE(_zoneTypeNamesRes_ns), _zoneTypeNamesRes_ns); + _commandsNames = new Table(ARRAYSIZE(_commandsNamesRes_ns), _commandsNamesRes_ns); _localFlagNames = new Table(120); _localFlagNames->addData("visited"); if (getPlatform() == Common::kPlatformPC) { - _callables[0] = _c_play_boogie; - _callables[1] = _c_play_boogie; - _callables[2] = _c_startIntro; - _callables[3] = _c_endIntro; - _callables[4] = _c_moveSheet; - _callables[5] = _c_sketch; - _callables[6] = _c_shade; - _callables[7] = _c_score; - _callables[8] = _c_null; - _callables[9] = _c_null; - _callables[10] = _c_null; - _callables[11] = _c_fade; - _callables[12] = _c_play_boogie; - _callables[13] = _c_moveSarc; - _callables[14] = _c_contaFoglie; - _callables[15] = _c_zeroFoglie; - _callables[16] = _c_trasformata; - _callables[17] = _c_offMouse; - _callables[18] = _c_onMouse; - _callables[19] = _c_setMask; - _callables[20] = _c_endComment; - _callables[21] = _c_frankenstein; - _callables[22] = _c_finito; - _callables[23] = _c_ridux; - _callables[24] = _c_testResult; + _callables = _dosCallables; } else { - _callables[0] = _c_projector; - _callables[1] = _c_HBOff; - _callables[2] = _c_startIntro; - _callables[3] = _c_endIntro; - _callables[4] = _c_moveSheet; - _callables[5] = _c_sketch; - _callables[6] = _c_shade; - _callables[7] = _c_score; - _callables[8] = _c_offSound; - _callables[9] = _c_startMusic; - _callables[10] = _c_closeMusic; - _callables[11] = _c_fade; - _callables[12] = _c_HBOn; - _callables[13] = _c_moveSarc; - _callables[14] = _c_contaFoglie; - _callables[15] = _c_zeroFoglie; - _callables[16] = _c_trasformata; - _callables[17] = _c_offMouse; - _callables[18] = _c_onMouse; - _callables[19] = _c_setMask; - _callables[20] = _c_endComment; - _callables[21] = _c_frankenstein; - _callables[22] = _c_finito; - _callables[23] = _c_ridux; - _callables[24] = _c_testResult; + _callables = _amigaCallables; } } +void Parallaction_br::initResources() { + + _zoneFlagNamesRes = _zoneFlagNamesRes_br; + _zoneTypeNamesRes = _zoneTypeNamesRes_br; + _commandsNamesRes = _commandsNamesRes_br; + _callableNamesRes = _callableNamesRes_br; + _instructionNamesRes = _instructionNamesRes_br; + _audioCommandsNamesRes = _audioCommandsNamesRes_br; + + _callableNames = new Table(ARRAYSIZE(_callableNamesRes_br), _callableNamesRes_br); + _instructionNames = new Table(ARRAYSIZE(_instructionNamesRes_br), _instructionNamesRes_br); + _zoneFlagNames = new Table(ARRAYSIZE(_zoneFlagNamesRes_br), _zoneFlagNamesRes_br); + _zoneTypeNames = new Table(ARRAYSIZE(_zoneTypeNamesRes_br), _zoneTypeNamesRes_br); + _commandsNames = new Table(ARRAYSIZE(_commandsNamesRes_br), _commandsNamesRes_br); + _audioCommandsNames = new Table(ARRAYSIZE(_audioCommandsNamesRes_br), _audioCommandsNamesRes_br); + + // TODO: make sure there are 120 max locations in Big Red Adventure + _localFlagNames = new Table(120); + _localFlagNames->addData("visited"); + + if (getPlatform() == Common::kPlatformPC) { + _callables = _dosCallables; + } + +} } // namespace Parallaction diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 43ded244c5..d57e9d2532 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -41,7 +41,7 @@ static uint16 walkData2 = 0; // next walk frame uint16 queryPath(uint16 x, uint16 y) { // NOTE: a better solution would have us mirror each byte in the mask in the loading routine - // AmigaDisk::loadPath() instead of doing it here. + // AmigaDisk_ns::loadPath() instead of doing it here. byte _al = _buffer[y*40 + x/8]; byte _dl = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); @@ -59,11 +59,11 @@ void PathBuilder::correctPathPoint(Common::Point &to) { int16 left = to.x; do { right++; - } while ((queryPath(right, to.y) == 0) && (right < SCREEN_WIDTH)); + } while ((queryPath(right, to.y) == 0) && (right < _vm->_screenWidth)); do { left--; } while ((queryPath(left, to.y) == 0) && (left > 0)); - right = (right == SCREEN_WIDTH) ? 1000 : right - to.x; + right = (right == _vm->_screenWidth) ? 1000 : right - to.x; left = (left == 0) ? 1000 : to.x - left; @@ -74,9 +74,9 @@ void PathBuilder::correctPathPoint(Common::Point &to) { } while ((queryPath(to.x, top) == 0) && (top > 0)); do { bottom++; - } while ((queryPath(to.x, bottom) == 0) && (bottom < SCREEN_HEIGHT)); + } while ((queryPath(to.x, bottom) == 0) && (bottom < _vm->_screenHeight)); top = (top == 0) ? 1000 : to.y - top; - bottom = (bottom == SCREEN_HEIGHT) ? 1000 : bottom - to.y; + bottom = (bottom == _vm->_screenHeight) ? 1000 : bottom - to.y; int16 closeX = (right >= left) ? left : right; @@ -272,19 +272,19 @@ uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { void Parallaction::clipMove(Common::Point& pos, const WalkNode* from) { - if ((pos.x < from->_x) && (pos.x < SCREEN_WIDTH) && (queryPath(_vm->_char._ani.width()/2 + pos.x + 2, _vm->_char._ani.height() + pos.y) != 0)) { + if ((pos.x < from->_x) && (pos.x < _screenWidth) && (queryPath(_char._ani.width()/2 + pos.x + 2, _char._ani.height() + pos.y) != 0)) { pos.x = (pos.x + 2 < from->_x) ? pos.x + 2 : from->_x; } - if ((pos.x > from->_x) && (pos.x > -20) && (queryPath(_vm->_char._ani.width()/2 + pos.x - 2, _vm->_char._ani.height() + pos.y) != 0)) { + if ((pos.x > from->_x) && (pos.x > -20) && (queryPath(_char._ani.width()/2 + pos.x - 2, _char._ani.height() + pos.y) != 0)) { pos.x = (pos.x - 2 > from->_x) ? pos.x - 2 : from->_x; } - if ((pos.y < from->_y) && (pos.y < (SCREEN_HEIGHT - _vm->_char._ani.height())) && (queryPath(_vm->_char._ani.width()/2 + pos.x, _vm->_char._ani.height() + pos.y + 2) != 0)) { + if ((pos.y < from->_y) && (pos.y < (_screenHeight - _char._ani.height())) && (queryPath(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y + 2) != 0)) { pos.y = (pos.y + 2 <= from->_y) ? pos.y + 2 : from->_y; } - if ((pos.y > from->_y) && (pos.y > -20) && (queryPath(_vm->_char._ani.width()/2 + pos.x, _vm->_char._ani.height() + pos.y- 2) != 0)) { + if ((pos.y > from->_y) && (pos.y > -20) && (queryPath(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y- 2) != 0)) { pos.y = (pos.y - 2 >= from->_y) ? pos.y - 2 :from->_y; } @@ -304,7 +304,7 @@ int16 Parallaction::selectWalkFrame(const Common::Point& pos, const WalkNode* fr // walk frame selection int16 v16; - if (_vm->_char._ani.getFrameNum() == 20) { + if (_char._ani.getFrameNum() == 20) { if (dist.x > dist.y) { walkData2 = (from->_x > pos.x) ? 0 : 7; @@ -336,49 +336,49 @@ int16 Parallaction::selectWalkFrame(const Common::Point& pos, const WalkNode* fr uint16 Parallaction::checkDoor() { // printf("checkDoor()..."); - if (_vm->_currentLocationIndex != _doorData1) { - _doorData1 = _vm->_currentLocationIndex; + if (_currentLocationIndex != _doorData1) { + _doorData1 = _currentLocationIndex; _zoneTrap = NULL; } _engineFlags &= ~kEngineWalking; - Zone *z = _vm->hitZone(kZoneDoor, _vm->_char._ani._left + _vm->_char._ani.width() / 2, _vm->_char._ani._top + _vm->_char._ani.height()); + Zone *z = hitZone(kZoneDoor, _char._ani._left + _char._ani.width() / 2, _char._ani._top + _char._ani.height()); if (z != NULL) { if ((z->_flags & kFlagsClosed) == 0) { - _vm->_location._startPosition.x = z->u.door->_startPos.x; - _vm->_location._startPosition.y = z->u.door->_startPos.y; - _vm->_location._startFrame = z->u.door->_startFrame; - strcpy( _vm->_location._name, z->u.door->_location ); + _location._startPosition.x = z->u.door->_startPos.x; + _location._startPosition.y = z->u.door->_startPos.y; + _location._startFrame = z->u.door->_startFrame; + strcpy(_location._name, z->u.door->_location); _engineFlags |= kEngineChangeLocation; _zoneTrap = NULL; } else { - _vm->runCommands(z->_commands, z); + runCommands(z->_commands, z); } } - z = _vm->hitZone(kZoneTrap, _vm->_char._ani._left + _vm->_char._ani.width() / 2, _vm->_char._ani._top + _vm->_char._ani.height()); + z = hitZone(kZoneTrap, _char._ani._left + _char._ani.width() / 2, _char._ani._top + _char._ani.height()); if (z != NULL) { - _localFlags[_vm->_currentLocationIndex] |= kFlagsEnter; - _vm->runCommands(z->_commands, z); - _localFlags[_vm->_currentLocationIndex] &= ~kFlagsEnter; + _localFlags[_currentLocationIndex] |= kFlagsEnter; + runCommands(z->_commands, z); + _localFlags[_currentLocationIndex] &= ~kFlagsEnter; _zoneTrap = z; } else if (_zoneTrap != NULL) { - _localFlags[_vm->_currentLocationIndex] |= kFlagsExit; - _vm->runCommands(_zoneTrap->_commands, _zoneTrap); - _localFlags[_vm->_currentLocationIndex] &= ~kFlagsExit; + _localFlags[_currentLocationIndex] |= kFlagsExit; + runCommands(_zoneTrap->_commands, _zoneTrap); + _localFlags[_currentLocationIndex] &= ~kFlagsExit; _zoneTrap = NULL; } // printf("done\n"); - _vm->_char._ani._frame = walkData2; - return _vm->_char._ani._frame; + _char._ani._frame = walkData2; + return _char._ani._frame; } @@ -429,11 +429,11 @@ void jobWalk(void *parm, Job *j) { void Parallaction::setPath(byte *path) { - memcpy(_buffer, path, SCREENPATH_WIDTH*SCREEN_HEIGHT); + memcpy(_buffer, path, _screenPathSize); } void Parallaction::initWalk() { - _buffer = (byte*)malloc(SCREENPATH_WIDTH * SCREEN_HEIGHT); + _buffer = (byte*)malloc(_screenPathSize); } diff --git a/engines/parallaction/zone.cpp b/engines/parallaction/zone.cpp index d9bd36a1f5..50f63b3b75 100644 --- a/engines/parallaction/zone.cpp +++ b/engines/parallaction/zone.cpp @@ -295,6 +295,13 @@ void Parallaction::parseZoneTypeBlock(Script &script, Zone *z) { void Parallaction::displayCharacterComment(ExamineData *data) { if (data->_description == NULL) return; + // NOTE: saving visible screen before displaying comment allows + // to restore the exact situation after the comment is deleted. + // This means animations are restored in the exact position as + // they were, thus avoiding clipping effect as signalled in + // BUG item #1762614. + _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); + _gfx->setFont(kFontDialogue); _gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront); @@ -305,11 +312,10 @@ void Parallaction::displayCharacterComment(ExamineData *data) { _gfx->drawBalloon(r, 0); _gfx->displayWrappedString(data->_description, 140, 10, 0, 130); - _gfx->updateScreen(); - waitUntilLeftClick(); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _gfx->updateScreen(); return; } @@ -332,7 +338,7 @@ void Parallaction::displayItemComment(ExamineData *data) { char v68[PATH_LEN]; strcpy(v68, data->_filename); data->_cnv = _disk->loadStatic(v68); - _gfx->flatBlitCnv(data->_cnv, 140, (SCREEN_HEIGHT - data->_cnv->_height)/2, Gfx::kBitFront); + _gfx->flatBlitCnv(data->_cnv, 140, (_screenHeight - data->_cnv->_height)/2, Gfx::kBitFront); _gfx->freeStaticCnv(data->_cnv); delete data->_cnv; @@ -343,7 +349,7 @@ void Parallaction::displayItemComment(ExamineData *data) { Common::Rect r(v6C, v6A); r.moveTo(0, 90); _gfx->drawBalloon(r, 0); - _gfx->flatBlitCnv(_vm->_char._head, 100, 152, Gfx::kBitFront); + _gfx->flatBlitCnv(_char._head, 100, 152, Gfx::kBitFront); _gfx->displayWrappedString(data->_description, 0, 90, 0, 130); jobEraseAnimations((void*)1, NULL); @@ -353,6 +359,7 @@ void Parallaction::displayItemComment(ExamineData *data) { _gfx->setHalfbriteMode(false); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _gfx->updateScreen(); return; } @@ -417,14 +424,17 @@ void jobToggleDoor(void *parm, Job *j) { StaticCnv v14; if (z->u.door->_cnv) { + Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height); + + uint16 _ax = (z->_flags & kFlagsClosed ? 1 : 0); + v14._width = z->u.door->_cnv->_width; v14._height = z->u.door->_cnv->_height; + v14._data0 = z->u.door->_cnv->getFramePtr(_ax); - Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height); - - _vm->_gfx->restoreZoneBackground(r, z->u.door->_background); + _vm->_gfx->restoreDoorBackground(&v14, r, z->u.door->_background); - uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1); + _ax = (z->_flags & kFlagsClosed ? 0 : 1); _vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack); _vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBit2); @@ -462,7 +472,7 @@ void jobRemovePickedItem(void *parm, Job *j) { if (z->u.get->_cnv) { Common::Rect r(z->_left, z->_top, z->_left + z->u.get->_cnv->_width, z->_top + z->u.get->_cnv->_height); - _vm->_gfx->restoreZoneBackground(r, z->u.get->_backup); + _vm->_gfx->restoreGetBackground(r, z->u.get->_backup); } count++; |