From 890c4c5f41e74938640f4bc8ddb843ac3ca9928d Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 26 Jan 2019 22:55:25 +0100 Subject: KYRA: (EOB1/Amiga) - fix start up First efforts to get this running. The intro is shown with severe palette glitches. The Main Menu does not show, thanks to the lack of font drawing. - implement endian aware stream wrapper for amiga files - implement sound file handling - implement some Amiga palette handling - etc --- engines/kyra/engine/chargen.cpp | 1 + engines/kyra/engine/darkmoon.cpp | 6 + engines/kyra/engine/darkmoon.h | 2 +- engines/kyra/engine/eob.cpp | 5 +- engines/kyra/engine/eobcommon.cpp | 9 +- engines/kyra/engine/eobcommon.h | 3 + engines/kyra/engine/items_eob.cpp | 22 +-- engines/kyra/graphics/screen.cpp | 9 +- engines/kyra/graphics/screen.h | 2 +- engines/kyra/graphics/screen_eob.cpp | 12 ++ engines/kyra/graphics/screen_eob.h | 1 + engines/kyra/graphics/screen_lok.cpp | 13 ++ engines/kyra/graphics/screen_lok.h | 2 + engines/kyra/resource/resource.cpp | 26 +++ engines/kyra/resource/resource.h | 1 + engines/kyra/resource/staticres_eob.cpp | 67 +++++-- engines/kyra/sequence/sequences_darkmoon.cpp | 7 +- engines/kyra/sequence/sequences_eob.cpp | 23 ++- engines/kyra/sound/drivers/audiomaster2.cpp | 2 +- engines/kyra/sound/sound.h | 6 +- engines/kyra/sound/sound_amiga_eob.cpp | 266 +++++++++------------------ engines/kyra/sound/sound_intern.h | 19 +- engines/kyra/sound/sound_towns_darkmoon.cpp | 26 ++- 23 files changed, 275 insertions(+), 255 deletions(-) diff --git a/engines/kyra/engine/chargen.cpp b/engines/kyra/engine/chargen.cpp index 7bea21e749..5032e86376 100644 --- a/engines/kyra/engine/chargen.cpp +++ b/engines/kyra/engine/chargen.cpp @@ -1972,6 +1972,7 @@ void TransferPartyWiz::giveKhelbensCoin() { // Start functions bool EoBCoreEngine::startCharacterGeneration() { + _sound->selectAudioResourceSet(_flags.platform == Common::kPlatformAmiga ? kMusicIntro : kMusicIngame); return CharacterGenerator(this, _screen).start(_characters, &_faceShapes); } diff --git a/engines/kyra/engine/darkmoon.cpp b/engines/kyra/engine/darkmoon.cpp index 9731f00533..4978164922 100644 --- a/engines/kyra/engine/darkmoon.cpp +++ b/engines/kyra/engine/darkmoon.cpp @@ -70,15 +70,21 @@ Common::Error DarkMoonEngine::init() { } void DarkMoonEngine::startupNew() { + _sound->selectAudioResourceSet(kMusicIngame); _currentLevel = 4; _currentSub = 0; loadLevel(4, 0); _currentBlock = 171; _currentDirection = 2; setHandItem(0); + EoBCoreEngine::startupNew(); } +void DarkMoonEngine::startupLoad() { + _sound->selectAudioResourceSet(kMusicIngame); +} + void DarkMoonEngine::drawNpcScene(int npcIndex) { const uint8 *shpDef = &_npcShpData[npcIndex << 3]; for (int i = npcIndex; i != 255; i = shpDef[7]) { diff --git a/engines/kyra/engine/darkmoon.h b/engines/kyra/engine/darkmoon.h index 3577bdbcec..d1012dbfa6 100644 --- a/engines/kyra/engine/darkmoon.h +++ b/engines/kyra/engine/darkmoon.h @@ -66,7 +66,7 @@ private: // Main loop void startupNew(); - void startupLoad() {} + void startupLoad(); // Intro/Outro void seq_playIntro(); diff --git a/engines/kyra/engine/eob.cpp b/engines/kyra/engine/eob.cpp index 18ed9c623a..b1cf50052c 100644 --- a/engines/kyra/engine/eob.cpp +++ b/engines/kyra/engine/eob.cpp @@ -76,6 +76,8 @@ Common::Error EoBEngine::init() { } void EoBEngine::startupNew() { + _sound->selectAudioResourceSet(kMusicIngame); + _sound->loadSoundFile(0); _currentLevel = 1; _currentSub = 0; loadLevel(1, 0); @@ -87,7 +89,8 @@ void EoBEngine::startupNew() { } void EoBEngine::startupLoad() { - _sound->loadSoundFile("ADLIB"); + _sound->selectAudioResourceSet(kMusicIngame); + _sound->loadSoundFile(0); } void EoBEngine::drawNpcScene(int npcIndex) { diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp index 0e3e130c94..e6e01ff781 100644 --- a/engines/kyra/engine/eobcommon.cpp +++ b/engines/kyra/engine/eobcommon.cpp @@ -214,6 +214,7 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) _menuStringsRest4 = _menuStringsDefeat = _menuStringsTransfer = _menuStringsSpec = 0; _menuStringsSpellNo = _menuYesNoStrings = _2431Strings = _katakanaLines = _katakanaSelectStrings = 0; _errorSlotEmptyString = _errorSlotNoNameString = _menuOkString = 0; + _levelSoundFiles1 = _levelSoundFiles2 = 0; _spellLevelsMage = _spellLevelsCleric = _numSpellsCleric = _numSpellsWisAdj = _numSpellsPal = _numSpellsMage = 0; _mnNumWord = _numSpells = _mageSpellListSize = _spellLevelsMageSize = _spellLevelsClericSize = 0; _inventorySlotsX = _slotValidationFlags = _encodeMonsterShpTable = 0; @@ -435,7 +436,10 @@ Common::Error EoBCoreEngine::init() { assert(_debugger); if (_flags.platform == Common::kPlatformAmiga) { - + if (_res->exists("EOBF6.FONT")) + _screen->loadFont(Screen::FID_6_FNT, "EOBF6.FONT"); + if (_res->exists("EOBF8.FONT")) + _screen->loadFont(Screen::FID_8_FNT, "EOBF8.FONT"); } else { _screen->loadFont(Screen::FID_6_FNT, "FONT6.FNT"); _screen->loadFont(Screen::FID_8_FNT, "FONT8.FNT"); @@ -555,7 +559,6 @@ Common::Error EoBCoreEngine::go() { action = 0; if (_gameToLoad != -1) { - _sound->selectAudioResourceSet(kMusicIngame); if (loadGameState(_gameToLoad).getCode() != Common::kNoError) error("Couldn't load game slot %d on startup", _gameToLoad); startupLoad(); @@ -565,8 +568,6 @@ Common::Error EoBCoreEngine::go() { action = mainMenu(); } - _sound->selectAudioResourceSet(kMusicIngame); - if (action == -1) { // load game repeatLoop = _gui->runLoadMenu(72, 14); diff --git a/engines/kyra/engine/eobcommon.h b/engines/kyra/engine/eobcommon.h index c56a41b6a1..38bdae0a7c 100644 --- a/engines/kyra/engine/eobcommon.h +++ b/engines/kyra/engine/eobcommon.h @@ -1175,6 +1175,9 @@ protected: void snd_stopSound(); void snd_fadeOut(); + const char *const *_levelSoundFiles1; + const char *const *_levelSoundFiles2; + // keymap static const char *const kKeymapName; }; diff --git a/engines/kyra/engine/items_eob.cpp b/engines/kyra/engine/items_eob.cpp index 54d3d5090b..4d11d0dea3 100644 --- a/engines/kyra/engine/items_eob.cpp +++ b/engines/kyra/engine/items_eob.cpp @@ -29,9 +29,9 @@ namespace Kyra { void EoBCoreEngine::loadItemDefs() { - Common::SeekableReadStream *s = _res->createReadStream("item.dat"); + Common::SeekableReadStreamEndian *s = _res->createEndianAwareReadStream("item.dat"); memset(_items, 0, sizeof(EoBItem) * 600); - _numItems = s->readUint16LE(); + _numItems = s->readUint16(); for (int i = 0; i < 600; i++) _items[i].block = -1; @@ -43,29 +43,29 @@ void EoBCoreEngine::loadItemDefs() { _items[i].icon = s->readSByte(); _items[i].type = s->readSByte(); _items[i].pos = s->readSByte(); - _items[i].block = s->readSint16LE(); - _items[i].next = s->readSint16LE(); - _items[i].prev = s->readSint16LE(); + _items[i].block = s->readSint16(); + _items[i].next = s->readSint16(); + _items[i].prev = s->readSint16(); _items[i].level = s->readSByte(); _items[i].value = s->readSByte(); } - _numItemNames = s->readUint16LE(); + _numItemNames = s->readUint16(); for (int i = 0; i < _numItemNames; i++) s->read(_itemNames[i], 35); delete s; - s = _res->createReadStream("itemtype.dat"); - uint16 numTypes = s->readUint16LE(); + s = _res->createEndianAwareReadStream("itemtype.dat"); + uint16 numTypes = s->readUint16(); delete[] _itemTypes; _itemTypes = new EoBItemType[65]; memset(_itemTypes, 0, sizeof(EoBItemType) * 65); for (int i = 0; i < numTypes; i++) { - _itemTypes[i].invFlags = s->readUint16LE(); - _itemTypes[i].handFlags = s->readUint16LE(); + _itemTypes[i].invFlags = s->readUint16(); + _itemTypes[i].handFlags = s->readUint16(); _itemTypes[i].armorClass = s->readSByte(); _itemTypes[i].allowedClasses = s->readSByte(); _itemTypes[i].requiredHands = s->readSByte(); @@ -76,7 +76,7 @@ void EoBCoreEngine::loadItemDefs() { _itemTypes[i].dmgNumPipsL = s->readSByte(); _itemTypes[i].dmgIncL = s->readSByte(); _itemTypes[i].unk1 = s->readByte(); - _itemTypes[i].extraProperties = s->readUint16LE(); + _itemTypes[i].extraProperties = s->readUint16(); } delete s; diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp index 4ceb627ba7..6af970eee5 100644 --- a/engines/kyra/graphics/screen.cpp +++ b/engines/kyra/graphics/screen.cpp @@ -3265,13 +3265,6 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette error("Unhandled bitmap compression %d", compType); } - if (_isAmiga) { - if (!scumm_stricmp(ext, "MSC")) - Screen::convertAmigaMsc(dstData); - else - Screen::convertAmigaGfx(dstData, 320, 200); - } - if (skip) srcData -= 4; @@ -3732,7 +3725,7 @@ int AMIGAFont::getCharWidth(uint16 c) const { } void AMIGAFont::drawChar(uint16 c, byte *dst, int pitch, int) const { - if (c >= 255) + //if (c >= 255) return; if (_chars[c].yOffset == 255) diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h index 68f1927a32..8ed17a12f5 100644 --- a/engines/kyra/graphics/screen.h +++ b/engines/kyra/graphics/screen.h @@ -532,7 +532,7 @@ public: void rectClip(int &x, int &y, int w, int h); // misc - void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip=false); + virtual void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip=false); virtual bool loadPalette(const char *filename, Palette &pal); bool loadPaletteTable(const char *filename, int firstPalette); diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp index 3945c034fc..bf5f7af029 100644 --- a/engines/kyra/graphics/screen_eob.cpp +++ b/engines/kyra/graphics/screen_eob.cpp @@ -219,6 +219,18 @@ void Screen_EoB::loadShapeSetBitmap(const char *file, int tempPage, int destPage _curPage = 2; } +void Screen_EoB::loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool) { + Screen::loadBitmap(filename, tempPage, dstPage, pal); + + if (_isAmiga) { + // Yay, this is where EOB1 Amiga hides the palette data + loadPalette(_pagePtrs[3] + 40000, *_palettes[0], 64); + _palettes[0]->fill(0, 1, 0); + + Screen::convertAmigaGfx(getPagePtr(dstPage), 320, 200); + } +} + void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage) { const char *filePattern = _vm->gameFlags().platform == Common::kPlatformFMTowns ? "%s.SHP" : ((_vm->game() == GI_EOB1 && (_renderMode == Common::kRenderEGA || _renderMode == Common::kRenderCGA)) ? "%s.EGA" : "%s.CPS"); Common::String tmp = Common::String::format(filePattern, file); diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h index 401a229045..60290df488 100644 --- a/engines/kyra/graphics/screen_eob.h +++ b/engines/kyra/graphics/screen_eob.h @@ -47,6 +47,7 @@ public: void printShadedText(const char *string, int x, int y, int col1, int col2); + virtual void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip = false); void loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage); void loadShapeSetBitmap(const char *file, int tempPage, int destPage); diff --git a/engines/kyra/graphics/screen_lok.cpp b/engines/kyra/graphics/screen_lok.cpp index 114382b487..ea619a6271 100644 --- a/engines/kyra/graphics/screen_lok.cpp +++ b/engines/kyra/graphics/screen_lok.cpp @@ -70,6 +70,19 @@ bool Screen_LoK::init() { return true; } +void Screen_LoK::loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip) { + const char *ext = filename + strlen(filename) - 3; + + Screen::loadBitmap(filename, tempPage, dstPage, pal, skip); + + if (_isAmiga) { + if (!scumm_stricmp(ext, "MSC")) + Screen::convertAmigaMsc(getPagePtr(dstPage)); + else + Screen::convertAmigaGfx(getPagePtr(dstPage), 320, 200); + } +} + void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { if (_vm->gameFlags().platform == Common::kPlatformAmiga) return; diff --git a/engines/kyra/graphics/screen_lok.h b/engines/kyra/graphics/screen_lok.h index 3a4ebfd6a4..34d0e2f461 100644 --- a/engines/kyra/graphics/screen_lok.h +++ b/engines/kyra/graphics/screen_lok.h @@ -36,6 +36,8 @@ public: bool init(); + virtual void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip = false); + int getRectSize(int w, int h); void setTextColorMap(const uint8 *cmap); diff --git a/engines/kyra/resource/resource.cpp b/engines/kyra/resource/resource.cpp index e13e644372..19603a1cf9 100644 --- a/engines/kyra/resource/resource.cpp +++ b/engines/kyra/resource/resource.cpp @@ -28,6 +28,28 @@ namespace Kyra { +class EndianAwareStreamWrapper : public Common::SeekableReadStreamEndian { +public: + EndianAwareStreamWrapper(Common::SeekableReadStream *stream, bool bigEndian, bool disposeAfterUse = true) : Common::SeekableReadStreamEndian(bigEndian), _stream(stream), _dispose(disposeAfterUse) {} + ~EndianAwareStreamWrapper() { if (_dispose) delete _stream; } + + // Common::Stream interface + bool err() const { return _stream->err(); } + + // Common::ReadStream interface + bool eos() const { return _stream->eos(); } + uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); } + + // Common::SeekableReadStream interface + int32 pos() const { return _stream->pos(); } + int32 size() const { return _stream->size(); } + bool seek(int32 offset, int whence = SEEK_SET) { return _stream->seek(offset, whence); } + +private: + Common::SeekableReadStream *_stream; + bool _dispose; +}; + Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm) { initializeLoaders(); @@ -316,6 +338,10 @@ Common::SeekableReadStream *Resource::createReadStream(const Common::String &fil return _files.createReadStreamForMember(file); } +Common::SeekableReadStreamEndian *Resource::createEndianAwareReadStream(const Common::String &file) { + return new EndianAwareStreamWrapper(_files.createReadStreamForMember(file), _vm->gameFlags().platform == Common::kPlatformAmiga); +} + Common::Archive *Resource::loadArchive(const Common::String &name, Common::ArchiveMemberPtr member) { ArchiveMap::iterator cachedArchive = _archiveCache.find(name); if (cachedArchive != _archiveCache.end()) diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h index a1ff902a84..02415cf4ff 100644 --- a/engines/kyra/resource/resource.h +++ b/engines/kyra/resource/resource.h @@ -74,6 +74,7 @@ public: uint32 getFileSize(const char *file); uint8 *fileData(const char *file, uint32 *size); Common::SeekableReadStream *createReadStream(const Common::String &file); + Common::SeekableReadStreamEndian *createEndianAwareReadStream(const Common::String &file); bool loadFileToBuf(const char *file, void *buf, uint32 maxSize); protected: diff --git a/engines/kyra/resource/staticres_eob.cpp b/engines/kyra/resource/staticres_eob.cpp index 23a5203a68..eaa911231e 100644 --- a/engines/kyra/resource/staticres_eob.cpp +++ b/engines/kyra/resource/staticres_eob.cpp @@ -269,7 +269,7 @@ const uint8 EoBCoreEngine::_clock2Timers[] = { const uint8 EoBCoreEngine::_numClock2Timers = ARRAYSIZE(EoBCoreEngine::_clock2Timers); void EoBCoreEngine::initStaticResource() { - int temp; + int temp, temp2; _chargenStatStrings = _staticres->loadStrings(kEoBBaseChargenStatStrings, temp); _chargenRaceSexStrings = _staticres->loadStrings(kEoBBaseChargenRaceSexStrings, temp); _chargenClassStrings = _staticres->loadStrings(kEoBBaseChargenClassStrings, temp); @@ -461,12 +461,51 @@ void EoBCoreEngine::initStaticResource() { _coneOfColdDest4 = (const int8 *)_staticres->loadRawData(kEoBBaseConeOfColdDest4, temp); _coneOfColdGfxTbl = _staticres->loadRawData(kEoBBaseConeOfColdGfxTbl, _coneOfColdGfxTblSize); - _staticres->loadStrings(kEoBBaseSoundMap, temp); - _staticres->loadStrings(kEoBBaseLevelSounds1, temp); - _staticres->loadStrings(kEoBBaseLevelSounds2, temp); - _staticres->loadStrings(kEoBBaseSoundFilesIntro, temp); - _staticres->loadStrings(kEoBBaseSoundFilesIngame, temp); - _staticres->loadStrings(kEoBBaseSoundFilesFinale, temp); + void *sndInfo_ingame = 0; + void *sndInfo_intro = 0; + void *sndInfo_finale = 0; + + if (_flags.platform == Common::kPlatformAmiga) { + const char *const *files = _staticres->loadStrings(kEoBBaseSoundFilesIngame, temp); + const char *const *map = _staticres->loadStrings(kEoBBaseSoundMap, temp2); + SoundResourceInfo_AmigaEoB ingame(files, temp, map, temp2); + sndInfo_ingame = &ingame; + files = _staticres->loadStrings(kEoBBaseSoundFilesIntro, temp); + SoundResourceInfo_AmigaEoB intro(files, temp, 0, 0); + sndInfo_intro = &intro; + files = _staticres->loadStrings(kEoBBaseSoundFilesFinale, temp); + SoundResourceInfo_AmigaEoB finale(files, temp, 0, 0); + sndInfo_finale = &finale; + } else if (_flags.platform == Common::kPlatformFMTowns) { + const char *const *files = _staticres->loadStrings(kEoBBaseSoundFilesIngame, temp); + const uint8 *data = _staticres->loadRawData(kEoB2PcmSoundEffectsIngame, temp2); + SoundResourceInfo_TownsEoB ingame(files, temp, data, temp2, 127); + sndInfo_ingame = &ingame; + files = _staticres->loadStrings(kEoBBaseSoundFilesIntro, temp); + data = _staticres->loadRawData(kEoB2PcmSoundEffectsIntro, temp2); + SoundResourceInfo_TownsEoB intro(files, temp, data, temp2, 40); + sndInfo_intro = &intro; + files = _staticres->loadStrings(kEoBBaseSoundFilesFinale, temp); + data = _staticres->loadRawData(kEoB2PcmSoundEffectsFinale, temp2); + SoundResourceInfo_TownsEoB finale(files, temp, data, temp2, 40); + sndInfo_finale = &finale; + } else if (_flags.platform == Common::kPlatformPC98) { + + } else { + const char *const *files = _staticres->loadStrings(kEoBBaseSoundFilesIngame, temp); + SoundResourceInfo_PC ingame(files, temp); + sndInfo_ingame = &ingame; + files = _staticres->loadStrings(kEoBBaseSoundFilesIntro, temp); + SoundResourceInfo_PC intro(files, temp); + sndInfo_intro = &intro; + files = _staticres->loadStrings(kEoBBaseSoundFilesFinale, temp); + SoundResourceInfo_PC finale(files, temp); + sndInfo_finale = &finale; + } + + _sound->initAudioResourceInfo(kMusicIngame, sndInfo_ingame); + _sound->initAudioResourceInfo(kMusicIntro, sndInfo_intro); + _sound->initAudioResourceInfo(kMusicFinale, sndInfo_finale); // Hard code the following strings, since EOB I doesn't have them in the original. // EOB I doesn't have load and save menus, because there is only one single @@ -1106,6 +1145,9 @@ void EoBEngine::initStaticResource() { for (int i = 0; i < 5; i++) _cgaMappingLevel[i] = _staticres->loadRawData(kEoB1CgaMappingLevel0 + i, temp); + _levelSoundFiles1 = _staticres->loadStrings(kEoB1BaseLevelSounds1, temp); + _levelSoundFiles2 = _staticres->loadStrings(kEoB1BaseLevelSounds2, temp); + _turnUndeadString = _staticres->loadStrings(kEoB1TurnUndeadString, temp); _npcShpData = _staticres->loadRawData(kEoB1NpcShpData, temp); @@ -1295,17 +1337,6 @@ void DarkMoonEngine::initStaticResource() { _ascii2SjisTables2 = _staticres->loadStrings(kEoB2Ascii2SjisTables2, temp); _saveNamePatterns = _staticres->loadStrings(kEoB2SaveNamePatterns, temp); - const uint8 *data = _staticres->loadRawData(kEoB2PcmSoundEffectsIngame, temp); - SoundResourceInfo_TownsEoB ingame(data, temp, 127); - data = _staticres->loadRawData(kEoB2PcmSoundEffectsIntro, temp); - SoundResourceInfo_TownsEoB intro(data, temp, 40); - data = _staticres->loadRawData(kEoB2PcmSoundEffectsFinale, temp); - SoundResourceInfo_TownsEoB finale(data, temp, 40); - - _sound->initAudioResourceInfo(kMusicIngame, &ingame); - _sound->initAudioResourceInfo(kMusicIntro, &intro); - _sound->initAudioResourceInfo(kMusicFinale, &finale); - _monsterAcHitChanceTable1 = _monsterAcHitChanceTbl1; _monsterAcHitChanceTable2 = _monsterAcHitChanceTbl2; diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp index 532591e9b0..59f2550389 100644 --- a/engines/kyra/sequence/sequences_darkmoon.cpp +++ b/engines/kyra/sequence/sequences_darkmoon.cpp @@ -111,7 +111,7 @@ int DarkMoonEngine::mainMenu() { _menuChoiceInit = 0; _sound->selectAudioResourceSet(kMusicIntro); - _sound->loadSoundFile("INTRO"); + _sound->loadSoundFile(0); Screen::FontId of = _screen->_currentFont; int op = 0; @@ -542,7 +542,7 @@ void DarkMoonEngine::seq_playFinale() { _screen->setCurPage(0); - _sound->loadSoundFile(_flags.platform == Common::kPlatformFMTowns ? "FINALE" : "FINALE1"); + _sound->loadSoundFile(0); snd_stopSound(); sq.delay(3); @@ -827,8 +827,7 @@ void DarkMoonEngine::seq_playFinale() { snd_stopSound(); sq.delay(3); - if (_flags.platform != Common::kPlatformFMTowns) - _sound->loadSoundFile("FINALE2"); + _sound->loadSoundFile(1); sq.delay(18); if (!skipFlag() && !shouldQuit()) diff --git a/engines/kyra/sequence/sequences_eob.cpp b/engines/kyra/sequence/sequences_eob.cpp index a04c5f75cd..1f0b4ab0f1 100644 --- a/engines/kyra/sequence/sequences_eob.cpp +++ b/engines/kyra/sequence/sequences_eob.cpp @@ -110,7 +110,7 @@ void EoBIntroPlayer::start() { if (!_vm->shouldQuit() && !_vm->skipFlag()) { _vm->snd_playSong(2); - _screen->loadBitmap((_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA) ? "TITLE-E.CMP" : "TITLE-V.CMP", 3, 5, 0); + _screen->loadBitmap(_vm->gameFlags().platform == Common::kPlatformAmiga ? "TITLE.CPS" : (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA) ? "TITLE-E.CMP" : "TITLE-V.CMP", 3, 5, 0); _screen->convertPage(5, 2, _vm->_cgaMappingDefault); _screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0); _vm->delay(120 * _vm->_tickLength); @@ -122,7 +122,7 @@ void EoBIntroPlayer::start() { _screen->loadFileDataToPage(s, 5, s->size() - 768); delete s; } else { - _screen->loadBitmap("TEXT.CMP", 3, 5, 0); + _screen->loadBitmap(_vm->gameFlags().platform == Common::kPlatformAmiga ? "TEXT.CPS" : "TEXT.CMP", 3, 5, 0); } _screen->convertPage(5, 6, _vm->_cgaMappingAlt); @@ -142,11 +142,16 @@ void EoBIntroPlayer::start() { void EoBIntroPlayer::openingCredits() { loadAndSetPalette(_filesOpening[5]); + _vm->snd_playSong(1); + _screen->loadBitmap(_filesOpening[4], 5, 3, 0); _screen->convertPage(3, 0, _vm->_cgaMappingAlt); - _screen->updateScreen(); - _vm->snd_playSong(1); + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + _screen->fadePalette(_screen->getPalette(0), 64); + else + _screen->updateScreen(); + _vm->delay(_openingFrmDelay[0] * _vm->_tickLength); for (int i = 0; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) { @@ -829,7 +834,7 @@ void EoBIntroPlayer::tunnel() { } void EoBIntroPlayer::loadAndSetPalette(const char *filename) { - if (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA) + if (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA || _vm->gameFlags().platform == Common::kPlatformAmiga) return; _screen->loadPalette(filename, _screen->getPalette(0)); _screen->getPalette(0).fill(0, 1, 0); @@ -983,7 +988,7 @@ int EoBEngine::mainMenu() { case 0: { if (_configRenderMode != Common::kRenderEGA) _screen->loadPalette("EOBPAL.COL", _screen->getPalette(0)); - _screen->loadEoBBitmap("INTRO", _cgaMappingDefault, 5, 3, 2); + _screen->loadEoBBitmap(_flags.platform == Common::kPlatformAmiga ? "TITLE" : "INTRO", _cgaMappingDefault, 5, 3, 2); _screen->setScreenPalette(_screen->getPalette(0)); _screen->_curPage = 2; of = _screen->setFont(Screen::FID_6_FNT); @@ -1018,11 +1023,13 @@ int EoBEngine::mainMenu() { case 4: // intro - _sound->loadSoundFile("SOUND"); + _sound->selectAudioResourceSet(kMusicIntro); + _sound->loadSoundFile(0); _screen->hideMouse(); seq_playIntro(); _screen->showMouse(); - _sound->loadSoundFile("ADLIB"); + _sound->selectAudioResourceSet(kMusicIngame); + _sound->loadSoundFile(0); menuChoice = 0; break; } diff --git a/engines/kyra/sound/drivers/audiomaster2.cpp b/engines/kyra/sound/drivers/audiomaster2.cpp index 404bb8468d..3ade175931 100644 --- a/engines/kyra/sound/drivers/audiomaster2.cpp +++ b/engines/kyra/sound/drivers/audiomaster2.cpp @@ -830,7 +830,7 @@ void AudioMaster2ResourceManager::loadResourceFile(Common::SeekableReadStream *d AudioMaster2IFFLoader loader(data, this); Common::Functor1Mem cb(&loader, &AudioMaster2IFFLoader::loadChunk); loader.parse(cb); - } while (data->pos() < data->size()); + } while (data->pos() + 8 < data->size()); } void AudioMaster2ResourceManager::initResource(SoundResource *resource) { diff --git a/engines/kyra/sound/sound.h b/engines/kyra/sound/sound.h index ab0e6a16d1..abeb6050bc 100644 --- a/engines/kyra/sound/sound.h +++ b/engines/kyra/sound/sound.h @@ -67,15 +67,17 @@ struct SoundResourceInfo_TownsPC98V2 { }; struct SoundResourceInfo_TownsEoB { - SoundResourceInfo_TownsEoB(const uint8 *pcmdata, uint dataSize, int pcmvolume) : pcmData(pcmdata), pcmDataSize(dataSize), pcmVolume(pcmvolume) {} + SoundResourceInfo_TownsEoB(const char *const *filelist, uint numfiles, const uint8 *pcmdata, uint pcmdataSize, int pcmvolume) : fileList(filelist), numFiles(numfiles), pcmData(pcmdata), pcmDataSize(pcmdataSize), pcmVolume(pcmvolume) {} const uint8 *pcmData; uint pcmDataSize; int pcmVolume; + const char *const *fileList; + uint numFiles; }; struct SoundResourceInfo_AmigaEoB { - SoundResourceInfo_AmigaEoB(const char *const *files, int numFiles, const char *const *sounds, int numSounds) : fileList(files), fileListSize(numFiles), soundList(sounds), soundListSize(numSounds) {} + SoundResourceInfo_AmigaEoB(const char *const *files, int numFiles, const char *const *soundmap, int numSounds) : fileList(files), fileListSize(numFiles), soundList(soundmap), soundListSize(numSounds) {} const char *const *fileList; uint fileListSize; const char *const *soundList; diff --git a/engines/kyra/sound/sound_amiga_eob.cpp b/engines/kyra/sound/sound_amiga_eob.cpp index 781ec46f4d..de8bf220a1 100644 --- a/engines/kyra/sound/sound_amiga_eob.cpp +++ b/engines/kyra/sound/sound_amiga_eob.cpp @@ -24,13 +24,14 @@ #include "kyra/resource/resource.h" #include "kyra/sound/drivers/audiomaster2.h" +#include "common/config-manager.h" #include "common/memstream.h" namespace Kyra { -SoundAmiga_EoB::SoundAmiga_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _vm(vm), _driver(0), _currentResourceSet(0), _ready(false) { +SoundAmiga_EoB::SoundAmiga_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), + _vm(vm), _driver(0), _currentResourceSet(-1), _currentFile(-1), _levelSoundList1(0), _levelSoundList2(0), _ready(false) { _fileBuffer = new uint8[64000]; - _version2 = _vm->game() == GI_EOB2; memset(_resInfo, 0, sizeof(_resInfo)); } @@ -50,6 +51,10 @@ bool SoundAmiga_EoB::init() { if (!_driver->init()) return false; + int temp = 0; + _levelSoundList1 = _vm->staticres()->loadStrings(kEoB1BaseLevelSounds1, temp); + _levelSoundList2 = _vm->staticres()->loadStrings(kEoB1BaseLevelSounds2, temp); + _ready = true; return true; } @@ -60,6 +65,9 @@ void SoundAmiga_EoB::initAudioResourceInfo(int set, void *info) { } void SoundAmiga_EoB::selectAudioResourceSet(int set) { + if (set == _currentResourceSet || !_ready) + return; + _driver->flushAllResources(); if (!_resInfo[set]) return; @@ -70,50 +78,22 @@ void SoundAmiga_EoB::selectAudioResourceSet(int set) { _currentResourceSet = set; } -bool SoundAmiga_EoB::hasSoundFile(uint file) const { - return false; -} - void SoundAmiga_EoB::loadSoundFile(uint file) { - /* - _sound->loadSoundFile("INTRO1.CPS"); - _sound->loadSoundFile("INTRO2.CPS"); - _sound->loadSoundFile("INTRO4.CPS"); - _sound->loadSoundFile("INTRO5.CPS"); - _sound->loadSoundFile("NEWINTRO1.CPS"); - _sound->loadSoundFile("CHARGEN1.CPS"); - - _sound->loadSoundFile("SFX1.CPS"); - _sound->loadSoundFile("SFX2.CPS"); - _sound->loadSoundFile("SFX3.CPS"); - _sound->loadSoundFile("SFX4.CPS"); - - _sound->loadSoundFile("HUM1.CPS"); - - _sound->loadSoundFile("SPIDERMOV1.CPS"); - _sound->loadSoundFile("MOVE1.CPS"); - _sound->loadSoundFile("MOVE21.CPS"); - _sound->loadSoundFile("MOVE31.CPS"); - _sound->loadSoundFile("BEASTATK1.CPS"); - _sound->loadSoundFile("BLADE1.CPS"); - _sound->loadSoundFile("MANTISMOV1.CPS"); - _sound->loadSoundFile("FLAYERATK1.CPS"); - _sound->loadSoundFile("LEECHMOV1.CPS"); - _sound->loadSoundFile("SLOSHSUCK1.CPS"); - _sound->loadSoundFile("SCREAM1.CPS"); - _sound->loadSoundFile("RUSTATK1.CPS"); - _sound->loadSoundFile("HOUNDATK1.CPS"); - _sound->loadSoundFile("KUOTOAMOV1.CPS"); - - _sound->loadSoundFile("FINALE2.CPS"); - _sound->loadSoundFile("FINALE1.CPS"); - _sound->loadSoundFile("FINALE.CPS"); - - for (int i = 1; i < 12; ++i) { - char n[13]; - sprintf(n, "LEVELSAM%d.CPS", i); - _sound->loadSoundFile(n); - }*/ + if (_vm->gameFlags().platform != Common::kPlatformAmiga || _currentResourceSet != kMusicIngame || !_ready) + return; + + unloadLevelSounds(); + + for (int i = 0; i < 2; ++i) { + if (_levelSoundList1[file * 2 + i][0]) + loadSoundFile(Common::String::format("%s.CPS", _levelSoundList1[file * 2 + i])); + if (_levelSoundList2[file * 2 + i][0]) + loadSoundFile(Common::String::format("%s.CPS", _levelSoundList2[file * 2 + i])); + } + + loadSoundFile(Common::String::format("LEVELSAM%d.CPS", file)); + + _currentFile = file; } void SoundAmiga_EoB::loadSoundFile(Common::String file) { @@ -155,157 +135,77 @@ void SoundAmiga_EoB::loadSoundFile(Common::String file) { } void SoundAmiga_EoB::playTrack(uint8 track) { - _driver->startSound("newintro1.smus"); - //_driver->startSound("hum1.sam"); - //_driver->startSound("hum"); - //_driver->startSound("playswing"); - //_driver->startSound("door"); - //_driver->startSound("death"); - //_driver->startSound("teleport"); - //_driver->startSound("scream"); - //_driver->startSound("magica"); - //_driver->startSound("magicb"); - - //_driver->startSound("chargen1.smus"); - //_driver->startSound("finale.smus"); + Common::String newSound; + if (_vm->game() == GI_EOB1) { + if (_currentResourceSet == kMusicIntro) { + if (track == 1) + newSound = "newintro1.smus"; + else if (track == 20) + newSound = "chargen1.smus"; + } + } else if (_vm->game() == GI_EOB2) { + + } + + if (!newSound.empty() && _ready) { + _driver->startSound(newSound); + _lastSound = newSound; + } } void SoundAmiga_EoB::haltTrack() { - + if (!_lastSound.empty()) + _driver->stopSound(_lastSound); } void SoundAmiga_EoB::playSoundEffect(uint8 track, uint8 volume) { + if (_currentResourceSet == -1 || !_ready) + return; + if (!_resInfo[_currentResourceSet]->soundList || track >= 120 || !_sfxEnabled) return; - _driver->startSound(_resInfo[_currentResourceSet]->soundList[track]); - - static const char *const kEoB1SoundsAmiga[120] = { - 0, - "button", - "L1M1A", - "door", - "door", - "slam", - "button", - "button", - "transmute", - "eat", - "magica", - "throw", - "plate", - "passage", - "unlock", - "teleport", - "undead", - "pit", - "itemland", - 0, - 0, - "playhit", - "death", - "text", - "electric", - "dart", - "dart", - "unlock", - "bonus", - "bump", - 0, - "electric", - "playswing", - "hum", - "panel", - "explode", - "L10M2M", - "L10M2A", - "L4M1M", - "beastatk", - "L9M2M", - "L8M1A", - "L8M1M", - "L7M1A", - "L7M1M", - "L5M1A", - "L5M1M", - "flindatk", - "L3M2M", - "L4M1A", - "L8M2M", - "houndatk", - "scream", - "L6M1M", - "L3M1A", - "L3M1M", - "sloshsuck", - "L1M2M", - "flayeratk", - 0, - "rustatk", - "L9M1M", - "L10M1A", - "L10M1M", - "blade", - "L7M2M", - "blade", - "L2M2M", - "L12M2A", - "L12M2M", - 0, - "L11M1M", - "L11M1A", - "L2M1A", - "L2M1M", - "L1M1M", - "button", - 0, - "drop", - "text", - "magicb", - "lock", - 0, - 0, - 0, - "Missile", - 0, - "burnhands", - "electric", - "fireball", - 0, - "magica", - "magica", - "magica", - "magicb", - "magicb", - "acid", - "magicb", - "fireball", - "acid", - "magica", - "magicb", - "magicb", - "undead", - "magica", - "magica", - "magica", - "magicb", - "cause", - "magicb", - "magicb", - "magica", - "magicb", - "magica", - "magica", - "magica", - "magica", - "cause", - 0, - "door" - }; + Common::String newSound = _resInfo[_currentResourceSet]->soundList[track]; + + if (!newSound.empty()) { + _driver->startSound(newSound); + _lastSound = newSound; + } } void SoundAmiga_EoB::beginFadeOut() { + haltTrack(); +} +void SoundAmiga_EoB::updateVolumeSettings() { + if (!_driver || !_ready) + return; + + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + _driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume"))); + _driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume"))); +} + +void SoundAmiga_EoB::unloadLevelSounds() { + if (_currentFile != -1) { + _driver->flushResource(Common::String::format("L%dM1A1", _currentFile)); + _driver->flushResource(Common::String::format("L%dM2A1", _currentFile)); + + for (int i = 1; i < 5; ++i) { + _driver->flushResource(Common::String::format("L%dM1M%d", _currentFile, i)); + _driver->flushResource(Common::String::format("L%dM2M%d", _currentFile, i)); + } + + for (int i = 0; i < 2; ++i) { + if (_levelSoundList1[_currentFile * 2 + i][0]) + _driver->flushResource(_levelSoundList1[_currentFile * 2 + i]); + if (_levelSoundList2[_currentFile * 2 + i][0]) + _driver->flushResource(_levelSoundList2[_currentFile * 2 + i]); + } + } } } // End of namespace Kyra diff --git a/engines/kyra/sound/sound_intern.h b/engines/kyra/sound/sound_intern.h index fccdc03eaf..b6e28dad17 100644 --- a/engines/kyra/sound/sound_intern.h +++ b/engines/kyra/sound/sound_intern.h @@ -363,7 +363,7 @@ public: virtual void initAudioResourceInfo(int set, void *info); virtual void selectAudioResourceSet(int set); virtual bool hasSoundFile(uint file) const; - virtual void loadSoundFile(uint file) {} + virtual void loadSoundFile(uint file); virtual void loadSoundFile(Common::String name); virtual void playTrack(uint8 track); @@ -388,6 +388,9 @@ private: int16 para2; } _soundTable[120]; + const char *const *_fileList; + uint _fileListLen; + uint8 _lastSfxChan; uint8 _lastEnvChan; uint8 *_pcmData; @@ -397,7 +400,7 @@ private: int _timer; int _timerSwitch; - SoundResourceInfo_TownsEoB *_pcmResource[3]; + SoundResourceInfo_TownsEoB *_resource[3]; TownsAudioInterface *_intf; }; @@ -413,23 +416,31 @@ public: bool init(); void initAudioResourceInfo(int set, void *info); void selectAudioResourceSet(int set); - bool hasSoundFile(uint file) const; + bool hasSoundFile(uint file) const { return false; } void loadSoundFile(uint file); void loadSoundFile(Common::String file); void playTrack(uint8 track); void haltTrack(); void playSoundEffect(uint8 track, uint8 volume = 0xFF); void beginFadeOut(); + void updateVolumeSettings(); private: + void unloadLevelSounds(); + uint8 *_fileBuffer; KyraEngine_v1 *_vm; AudioMaster2 *_driver; SoundResourceInfo_AmigaEoB *_resInfo[3]; + Common::String _lastSound; + int _currentResourceSet; + int _currentFile; + + const char *const *_levelSoundList1; + const char *const *_levelSoundList2; - bool _version2; bool _ready; }; diff --git a/engines/kyra/sound/sound_towns_darkmoon.cpp b/engines/kyra/sound/sound_towns_darkmoon.cpp index 25fd4142b9..747e1bd3f4 100644 --- a/engines/kyra/sound/sound_towns_darkmoon.cpp +++ b/engines/kyra/sound/sound_towns_darkmoon.cpp @@ -39,7 +39,7 @@ SoundTowns_Darkmoon::SoundTowns_Darkmoon(KyraEngine_v1 *vm, Audio::Mixer *mixer) _pcmVol = 0; _timer = 0; _timerSwitch = 0; - memset(_pcmResource, 0, sizeof(_pcmResource)); + memset(_resource, 0, sizeof(_resource)); } SoundTowns_Darkmoon::~SoundTowns_Darkmoon() { @@ -85,31 +85,39 @@ void SoundTowns_Darkmoon::timerCallback(int timerId) { } void SoundTowns_Darkmoon::initAudioResourceInfo(int set, void *info) { - delete _pcmResource[set]; - _pcmResource[set] = info ? new SoundResourceInfo_TownsEoB(*(SoundResourceInfo_TownsEoB*)info) : 0; + delete _resource[set]; + _resource[set] = info ? new SoundResourceInfo_TownsEoB(*(SoundResourceInfo_TownsEoB*)info) : 0; } void SoundTowns_Darkmoon::selectAudioResourceSet(int set) { delete[] _pcmData; - if (!_pcmResource[set] || !_pcmResource[kMusicIngame]) + if (!_resource[set] || !_resource[kMusicIngame]) return; - - _pcmDataSize = _pcmResource[kMusicIngame]->pcmDataSize; + + _fileList = _resource[set]->fileList; + _fileListLen = _resource[set]->numFiles; + + _pcmDataSize = _resource[kMusicIngame]->pcmDataSize; _pcmData = new uint8[_pcmDataSize]; - _pcmVol = _pcmResource[set]->pcmVolume; - memcpy(_pcmData, _pcmResource[kMusicIngame]->pcmData, _pcmDataSize); + _pcmVol = _resource[set]->pcmVolume; + memcpy(_pcmData, _resource[kMusicIngame]->pcmData, _pcmDataSize); if (set == kMusicIngame) return; - memcpy(_pcmData, _pcmResource[set]->pcmData, _pcmResource[set]->pcmDataSize); + memcpy(_pcmData, _resource[set]->pcmData, _resource[set]->pcmDataSize); } bool SoundTowns_Darkmoon::hasSoundFile(uint file) const { return true; } +void SoundTowns_Darkmoon::loadSoundFile(uint file) { + if (file < _fileListLen) + loadSoundFile(_fileList[file]); +} + void SoundTowns_Darkmoon::loadSoundFile(Common::String name) { Common::SeekableReadStream *s = _vm->resource()->createReadStream(Common::String::format("%s.SDT", name.c_str())); if (!s) -- cgit v1.2.3