aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2014-07-20 21:19:20 +0300
committerFilippos Karapetis2014-07-20 21:19:20 +0300
commite88d6265d8ea3d1133661073a5484e0ed372458e (patch)
treefd3616d8909f9dad93190ca4e680ae2271cdd641
parent0d926f9aaf81b18fdac290efb5dffeca09533cae (diff)
downloadscummvm-rg350-e88d6265d8ea3d1133661073a5484e0ed372458e.tar.gz
scummvm-rg350-e88d6265d8ea3d1133661073a5484e0ed372458e.tar.bz2
scummvm-rg350-e88d6265d8ea3d1133661073a5484e0ed372458e.zip
SAGA: Add support for MIDI music in SAGA2 games
-rw-r--r--engines/saga/interface.cpp5
-rw-r--r--engines/saga/introproc_saga2.cpp6
-rw-r--r--engines/saga/music.cpp12
-rw-r--r--engines/saga/resource.h16
-rw-r--r--engines/saga/resource_hrs.cpp45
5 files changed, 63 insertions, 21 deletions
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 680b2274f5..44581f26fc 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -710,6 +710,11 @@ bool Interface::processAscii(Common::KeyState keystate) {
}
void Interface::setStatusText(const char *text, int statusColor) {
+ if (_vm->getGameId() == GID_FTA2 || _vm->getGameId() == GID_DINO) {
+ warning("setStatusText not implemented for SAGA2");
+ return;
+ }
+
if (_vm->getGameId() == GID_IHNM) {
// Don't show the status text for the IHNM chapter selection screens (chapter 8), or
// scene 0 (IHNM demo introduction)
diff --git a/engines/saga/introproc_saga2.cpp b/engines/saga/introproc_saga2.cpp
index 710236b0c4..0b773b03f0 100644
--- a/engines/saga/introproc_saga2.cpp
+++ b/engines/saga/introproc_saga2.cpp
@@ -43,9 +43,6 @@ int Scene::DinoStartProc() {
playMovie("testvid.smk");
- // HACK: Forcibly quit here
- _vm->quitGame();
-
return SUCCESS;
}
@@ -55,9 +52,6 @@ int Scene::FTA2StartProc() {
playMovie("trimark.smk");
playMovie("intro.smk");
- // HACK: Forcibly quit here
- _vm->quitGame();
-
return SUCCESS;
}
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 6e36f51dee..d20882ca26 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -147,7 +147,7 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
if (!_musicContext) {
if (_vm->getGameId() == GID_ITE) {
_musicContext = _vm->_resource->getContext(GAME_RESOURCEFILE);
- } else {
+ } else if (_vm->getGameId() == GID_IHNM) {
// I've listened to music from both the FM and the GM
// file, and I've tentatively reached the conclusion
// that they are both General MIDI. My guess is that
@@ -173,6 +173,8 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
// Note that the IHNM demo has only got one music file
// (music.rsc). It is assumed that it contains FM music
_musicContext = _vm->_resource->getContext(GAME_MUSICFILE_FM);
+ } else if (_vm->getGameId() == GID_DINO || _vm->getGameId() == GID_FTA2) {
+ _musicContext = _vm->_resource->getContext(GAME_SOUNDFILE);
}
}
@@ -255,14 +257,18 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
_mixer->stopHandle(_musicHandle);
_player->stop();
- int realTrackNumber;
+ int realTrackNumber = 0;
if (_vm->getGameId() == GID_ITE) {
if (flags == MUSIC_NORMAL && (resourceId == 13 || resourceId == 19))
flags = MUSIC_LOOP;
realTrackNumber = resourceId - 8;
- } else {
+ } else if (_vm->getGameId() == GID_IHNM) {
+ realTrackNumber = resourceId + 1;
+ } else if (_vm->getGameId() == GID_DINO || _vm->getGameId() == GID_FTA2) {
realTrackNumber = resourceId + 1;
+ uint32 musicTrackTag = MKTAG('X','M','I', (byte)(resourceId + 1));
+ resourceId = _musicContext->getEntryNum(musicTrackTag);
}
// Try to open standalone digital track
diff --git a/engines/saga/resource.h b/engines/saga/resource.h
index 252e92c967..2a1aaf3103 100644
--- a/engines/saga/resource.h
+++ b/engines/saga/resource.h
@@ -60,12 +60,13 @@ struct PatchData {
struct ResourceData {
uint32 id; // SAGA2
+ uint32 category; // SAGA2
size_t offset;
size_t size;
PatchData *patchData;
ResourceData() :
- id(0), offset(0), size(0), patchData(NULL) {
+ id(0), category(0), offset(0), size(0), patchData(NULL) {
}
~ResourceData() {
@@ -130,10 +131,15 @@ public:
// SAGA 2
int32 getEntryNum(uint32 id) {
int32 num = 0;
+ uint32 miloCategory = MKTAG('M', 'I', 'L', 'O');
+
for (ResourceDataArray::const_iterator i = _table.begin(); i != _table.end(); ++i) {
- if (i->id == id) {
+ //uint32 c = i->category;
+ //debug("%c%c%c%c, offset: %d, size: %d", (c >> 24), (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF, i->offset, i->size);
+ // Ignore low quality music resources (MILO)
+ if (i->id == id && i->category != miloCategory)
return num;
- }
+
num++;
}
return -1;
@@ -282,6 +288,10 @@ protected:
return loadResV2(contextSize);
}
bool loadResV2(uint32 contextSize);
+
+ void readCategory(ResourceData &element);
+ void readEntry(ResourceData &element);
+ uint32 getCategory(uint32 resourceOffset);
};
class Resource_HRS : public Resource {
diff --git a/engines/saga/resource_hrs.cpp b/engines/saga/resource_hrs.cpp
index 09da9cf0bb..ba58830269 100644
--- a/engines/saga/resource_hrs.cpp
+++ b/engines/saga/resource_hrs.cpp
@@ -39,13 +39,35 @@
namespace Saga {
-void readElement(Common::File &file, Saga::ResourceData &element) {
- element.id = file.readUint32BE();
- element.offset = file.readUint32LE();
- element.size = file.readUint32LE();
+void ResourceContext_HRS::readCategory(ResourceData &element) {
+ element.id = _file.readUint32BE();
+ element.offset = _file.readUint32LE();
+ element.size = _file.readUint32LE();
+ element.category = 0;
+ debug(3, "Category: id %u, offset %u, size %u", element.id, (uint)element.offset, (uint)element.size);
+}
+
+void ResourceContext_HRS::readEntry(ResourceData &element) {
+ element.id = _file.readUint32BE();
+ element.offset = _file.readUint32LE();
+ element.size = _file.readUint32LE();
+ element.category = getCategory(_file.pos());
debug(3, "Entry: id %u, offset %u, size %u", element.id, (uint)element.offset, (uint)element.size);
}
+uint32 ResourceContext_HRS::getCategory(uint32 resourceOffset) {
+ for (int i = _categories.size() - 1; i >= 0; --i) {
+ if (resourceOffset >= _categories[i].offset)
+ return _categories[i].id;
+ }
+
+ error("Unknown category for offset %d", resourceOffset);
+}
+
+static bool categorySortHelper(const ResourceData &r1, const ResourceData &r2) {
+ return r1.offset < r2.offset;
+}
+
bool ResourceContext_HRS::loadResV2(uint32 contextSize) {
ResourceData origin;
uint32 firstEntryOffset;
@@ -56,7 +78,7 @@ bool ResourceContext_HRS::loadResV2(uint32 contextSize) {
debug(3, "Context %s =====", _fileName);
_file.seek(0, SEEK_SET);
- readElement(_file, origin);
+ readCategory(origin);
// Check if the file is valid
if (origin.id != MKTAG('H','R','E','S')) { // header
@@ -74,18 +96,23 @@ bool ResourceContext_HRS::loadResV2(uint32 contextSize) {
// Read categories
count = origin.size / resourceSize;
- debug(3, "Categories: %d =====", count);
+ debug(3, "File: %s, categories: %d =====", _file.getName(), count);
for (i = 0; i < count; i++) {
- readElement(_file, _categories[i]);
+ readCategory(_categories[i]);
+ //uint32 id = _categories[i].id;
+ //debug("%i: %c%c%c%c, offset: %d, size: %d", i, (id >> 24), (id >> 16) & 0xFF, (id >> 8) & 0xFF, id & 0xFF, _categories[i].offset, _categories[i].size);
}
+ Common::sort(_categories.begin(), _categories.end(), categorySortHelper);
+
_file.seek(firstEntryOffset, SEEK_SET);
// Read table entries
count = tableSize / resourceSize;
- debug(3, "Entries: %d =====", count);
+ debug(3, "File: %s, entries: %d =====", _file.getName(), count);
for (i = 0; i < count; i++) {
- readElement(_file, _table[i]);
+ readEntry(_table[i]);
+ //debug("%i: offset: %d, size: %d", i, _table[i].offset, _table[i].size);
}
return true;
}