aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/detection_tables.h26
-rw-r--r--engines/agos/gfx.cpp2
-rw-r--r--engines/agos/input.cpp10
-rw-r--r--engines/agos/midi.cpp89
-rw-r--r--engines/agos/midi.h8
-rw-r--r--engines/agos/rooms.cpp3
-rw-r--r--engines/agos/saveload.cpp7
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);