diff options
Diffstat (limited to 'engines/agos')
-rw-r--r-- | engines/agos/detection_tables.h | 26 | ||||
-rw-r--r-- | engines/agos/gfx.cpp | 2 | ||||
-rw-r--r-- | engines/agos/input.cpp | 10 | ||||
-rw-r--r-- | engines/agos/midi.cpp | 89 | ||||
-rw-r--r-- | engines/agos/midi.h | 8 | ||||
-rw-r--r-- | engines/agos/rooms.cpp | 3 | ||||
-rw-r--r-- | engines/agos/saveload.cpp | 7 |
7 files changed, 121 insertions, 24 deletions
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index 77fc88c6bb..2f4709c49e 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -1259,6 +1259,32 @@ static const AGOSGameDescription gameDescriptions[] = { GF_TALKIE | GF_OLD_BUNDLE | GF_PLANAR }, + // Simon the Sorcerer 1 - English Amiga CD32 demo, from the cover disc of + // issue 5 (October 1994) of Amiga CD32 Gamer + { + { + "simon1", + "CD32 Demo", + + { + { "gameamiga", GAME_BASEFILE, "e243f9229f9728b3476e54d2cf5f18a1", 27998}, + { "icon.pkd", GAME_ICONFILE, "565ef7a98dcc21ef526a2bb10b6f42ed", 18979}, + { "stripped.txt", GAME_STRFILE, "94413c71c86c32ed9baaa1c74a151cb3", 243}, + { "tbllist", GAME_TBLFILE, "f9d5bf2ce09f82289c791c3ca26e1e4b", 696}, + { NULL, 0, NULL, 0} + }, + Common::EN_ANY, + Common::kPlatformAmiga, + ADGF_CD | ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOMIDI) + }, + + GType_SIMON1, + GID_SIMON1CD32, + GF_TALKIE | GF_OLD_BUNDLE | GF_PLANAR + }, + + // Simon the Sorcerer 1 - English DOS Floppy Demo { { diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 33145b7d0d..5a1f9f1917 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -547,7 +547,7 @@ void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) { if ((dst[count * 2] & 0xF0) == 0x20) dst[count * 2] = src[count * 2]; if (mask[count + state->x_skip] & 0x0F) - if ((dst[count * 2 + 1] & 0x0F) == 0x20) + if ((dst[count * 2 + 1] & 0xF0) == 0x20) dst[count * 2 + 1] = src[count * 2 + 1]; } else { /* no transparency */ diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index 8a4e87017a..687a8ef1cf 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -460,7 +460,7 @@ void AGOSEngine_Simon1::handleMouseWheelUp() { _saveLoadEdit = false; listSaveGames(); } - } else { + } else { AGOSEngine::handleMouseWheelUp(); } } @@ -472,11 +472,11 @@ void AGOSEngine_Simon1::handleMouseWheelDown() { _saveLoadRowCurPos += 1; if (_saveLoadRowCurPos >= _numSaveGameRows) _saveLoadRowCurPos = _numSaveGameRows; - + _saveLoadEdit = false; listSaveGames(); } - } else { + } else { AGOSEngine::handleMouseWheelDown(); } } @@ -492,7 +492,7 @@ void AGOSEngine_Elvira2::handleMouseWheelUp() { _saveLoadRowCurPos -= 3; listSaveGames(); - } else { + } else { AGOSEngine::handleMouseWheelUp(); } } @@ -506,7 +506,7 @@ void AGOSEngine_Elvira2::handleMouseWheelDown() { _saveLoadRowCurPos = 1; listSaveGames(); - } else { + } else { AGOSEngine::handleMouseWheelDown(); } } diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp index c26fbe3331..e5875a8353 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -42,6 +42,8 @@ MidiPlayer::MidiPlayer() { _driver = 0; _map_mt32_to_gm = false; + _adlibPatches = NULL; + _enable_sfx = true; _current = 0; @@ -52,7 +54,7 @@ MidiPlayer::MidiPlayer() { _paused = false; _currentTrack = 255; - _loopTrack = 0; + _loopTrackDefault = false; _queuedTrack = 255; _loopQueuedTrack = 0; } @@ -68,6 +70,7 @@ MidiPlayer::~MidiPlayer() { } _driver = NULL; clearConstructs(); + unloadAdlibPatches(); } int MidiPlayer::open(int gameType) { @@ -85,6 +88,12 @@ int MidiPlayer::open(int gameType) { if (_nativeMT32) _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); + /* Disabled due to not sounding right, and low volume level + if (gameType == GType_SIMON1 && MidiDriver::getMusicType(dev) == MT_ADLIB) { + loadAdlibPatches(); + } + */ + _map_mt32_to_gm = (gameType != GType_SIMON2 && !_nativeMT32); int ret = _driver->open(); @@ -114,8 +123,10 @@ void MidiPlayer::send(uint32 b) { else if (_current == &_music) volume = volume * _musicVolume / 255; b = (b & 0xFF00FFFF) | (volume << 16); - } else if ((b & 0xF0) == 0xC0 && _map_mt32_to_gm) { - b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8); + } else if ((b & 0xF0) == 0xC0) { + if (_map_mt32_to_gm && !_adlibPatches) { + b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8); + } } else if ((b & 0xFFF0) == 0x007BB0) { // Only respond to an All Notes Off if this channel // has already been allocated. @@ -144,7 +155,16 @@ void MidiPlayer::send(uint32 b) { else if (_current == &_music) _current->channel[9]->volume(_current->volume[9] * _musicVolume / 255); } - _current->channel[channel]->send(b); + + if ((b & 0xF0) == 0xC0 && _adlibPatches) { + // NOTE: In the percussion channel, this function is a + // no-op. Any percussion instruments you hear may + // be the stock ones from adlib.cpp. + _driver->sysEx_customInstrument(_current->channel[channel]->getNumber(), 'ADL ', _adlibPatches + 30 * ((b >> 8) & 0xFF)); + } else { + _current->channel[channel]->send(b); + } + if ((b & 0xFFF0) == 0x79B0) { // We have received a "Reset All Controllers" message // and passed it on to the MIDI driver. This may or may @@ -166,13 +186,13 @@ void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { return; } else if (_current == &_sfx) { clearConstructs(_sfx); - } else if (_loopTrack) { + } else if (_current->loopTrack) { _current->parser->jumpToTick(0); } else if (_queuedTrack != 255) { _currentTrack = 255; byte destination = _queuedTrack; _queuedTrack = 255; - _loopTrack = _loopQueuedTrack; + _current->loopTrack = _loopQueuedTrack; _loopQueuedTrack = false; // Remember, we're still inside the locked mutex. @@ -300,7 +320,7 @@ void MidiPlayer::setVolume(int musicVol, int sfxVol) { void MidiPlayer::setLoop(bool loop) { Common::StackLock lock(_mutex); - _loopTrack = loop; + _loopTrackDefault = loop; } void MidiPlayer::queueTrack(int track, bool loop) { @@ -355,6 +375,47 @@ void MidiPlayer::resetVolumeTable() { } } +void MidiPlayer::loadAdlibPatches() { + Common::File ibk; + + if (!ibk.open("mt_fm.ibk")) + return; + + if (ibk.readUint32BE() == 0x49424b1a) { + _adlibPatches = new byte[128 * 30]; + byte *ptr = _adlibPatches; + + memset(_adlibPatches, 0, 128 * 30); + + for (int i = 0; i < 128; i++) { + byte instr[16]; + + ibk.read(instr, 16); + + ptr[0] = instr[0]; // Modulator Sound Characteristics + ptr[1] = instr[2]; // Modulator Scaling/Output Level + ptr[2] = ~instr[4]; // Modulator Attack/Decay + ptr[3] = ~instr[6]; // Modulator Sustain/Release + ptr[4] = instr[8]; // Modulator Wave Select + ptr[5] = instr[1]; // Carrier Sound Characteristics + ptr[6] = instr[3]; // Carrier Scaling/Output Level + ptr[7] = ~instr[5]; // Carrier Attack/Delay + ptr[8] = ~instr[7]; // Carrier Sustain/Release + ptr[9] = instr[9]; // Carrier Wave Select + ptr[10] = instr[10]; // Feedback/Connection + + // The remaining six bytes are reserved for future use + + ptr += 30; + } + } +} + +void MidiPlayer::unloadAdlibPatches() { + delete[] _adlibPatches; + _adlibPatches = NULL; +} + static const int simon1_gmf_size[] = { 8900, 12166, 2848, 3442, 4034, 4508, 7064, 9730, 6014, 4742, 3138, 6570, 5384, 8909, 6457, 16321, 2742, 8968, 4804, 8442, 7717, @@ -405,7 +466,7 @@ void MidiPlayer::loadSMF(Common::File *in, int song, bool sfx) { uint32 timerRate = _driver->getBaseTempo(); - if (!memcmp(p->data, "GMF\x1", 4)) { + if (isGMF) { // The GMF header // 3 BYTES: 'GMF' // 1 BYTE : Major version @@ -426,11 +487,9 @@ void MidiPlayer::loadSMF(Common::File *in, int song, bool sfx) { // It seems that 4 corresponds to our base tempo, so // this should be the right way to calculate it. timerRate = (4 * _driver->getBaseTempo()) / p->data[5]; - - // According to bug #1004919 calling setLoop() from - // within a lock causes a lockup, though I have no - // idea when this actually happens. - _loopTrack = (p->data[6] != 0); + p->loopTrack = (p->data[6] != 0); + } else { + p->loopTrack = _loopTrackDefault; } MidiParser *parser = MidiParser::createParser_SMF(); @@ -500,6 +559,8 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) { p->song_sizes[i] = size; } + p->loopTrack = _loopTrackDefault; + if (!sfx) { _currentTrack = 255; resetVolumeTable(); @@ -531,6 +592,7 @@ void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) { in->seek(pos, 0); p->data = (byte *)calloc(size, 1); in->read(p->data, size); + p->loopTrack = _loopTrackDefault; } else { error("Expected 'FORM' tag but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]); } @@ -575,6 +637,7 @@ void MidiPlayer::loadS1D(Common::File *in, bool sfx) { _currentTrack = 255; resetVolumeTable(); } + p->loopTrack = _loopTrackDefault; p->parser = parser; // That plugs the power cord into the wall } diff --git a/engines/agos/midi.h b/engines/agos/midi.h index 3efadddc2f..7e78bfef28 100644 --- a/engines/agos/midi.h +++ b/engines/agos/midi.h @@ -36,6 +36,7 @@ namespace AGOS { struct MusicInfo { MidiParser *parser; byte *data; + bool loopTrack; byte num_songs; // For Type 1 SMF resources byte *songs[16]; // For Type 1 SMF resources uint32 song_sizes[16]; // For Type 1 SMF resources @@ -46,6 +47,7 @@ struct MusicInfo { MusicInfo() { clear(); } void clear() { parser = 0; data = 0; num_songs = 0; + loopTrack = false; memset(songs, 0, sizeof(songs)); memset(song_sizes, 0, sizeof(song_sizes)); memset(channel, 0, sizeof(channel)); @@ -71,15 +73,19 @@ protected: // These are only used for music. byte _currentTrack; - bool _loopTrack; + bool _loopTrackDefault; byte _queuedTrack; bool _loopQueuedTrack; + byte *_adlibPatches; + protected: static void onTimer(void *data); void clearConstructs(); void clearConstructs(MusicInfo &info); void resetVolumeTable(); + void loadAdlibPatches(); + void unloadAdlibPatches(); public: bool _enable_sfx; diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index 6185653d42..d1d6f2b99d 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -383,7 +383,7 @@ bool AGOSEngine::loadRoomItems(uint16 room) { for (uint16 z = minNum; z <= maxNum; z++) { uint16 itemNum = z + 2; item = derefItem(itemNum); - item->parent = 0; + _itemArrayPtr[itemNum] = 0; uint16 num = (itemNum - _itemArrayInited); _roomStates[num].state = item->state; @@ -453,6 +453,7 @@ bool AGOSEngine::loadRoomItems(uint16 room) { item->classFlags = _roomStates[num].classFlags; SubRoom *subRoom = (SubRoom *)findChildOfType(item, kRoomType); subRoom->roomExitStates = _roomStates[num].roomExitStates; + } in.close(); diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 5d5e2d7b03..b968ae645c 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -1261,7 +1261,6 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo uint16 room = _currentRoom; _currentRoom = f->readUint16BE(); - if (_roomsListPtr) { byte *p = _roomsListPtr; if (room == _currentRoom) { @@ -1293,8 +1292,7 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo for (uint16 z = minNum; z <= maxNum; z++) { uint16 itemNum = z + 2; - Item *item = derefItem(itemNum); - item->parent = 0; + _itemArrayPtr[itemNum] = 0; } } } @@ -1318,6 +1316,9 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo uint parent = f->readUint16BE(); uint next = f->readUint16BE(); + if (getGameType() == GType_WW && getPlatform() == Common::kPlatformDOS && derefItem(item->parent) == NULL) + item->parent = 0; + parent_item = derefItem(parent); setItemParent(item, parent_item); |