aboutsummaryrefslogtreecommitdiff
path: root/engines/saga
diff options
context:
space:
mode:
Diffstat (limited to 'engines/saga')
-rw-r--r--engines/saga/actor.cpp37
-rw-r--r--engines/saga/actor.h7
-rw-r--r--engines/saga/animation.cpp36
-rw-r--r--engines/saga/animation.h3
-rw-r--r--engines/saga/detection.cpp34
-rw-r--r--engines/saga/detection_tables.h1016
-rw-r--r--engines/saga/displayinfo.h2
-rw-r--r--engines/saga/events.cpp41
-rw-r--r--engines/saga/events.h3
-rw-r--r--engines/saga/font.cpp8
-rw-r--r--engines/saga/gfx.cpp10
-rw-r--r--engines/saga/ihnm_introproc.cpp146
-rw-r--r--engines/saga/image.cpp1
-rw-r--r--engines/saga/interface.cpp180
-rw-r--r--engines/saga/isomap.cpp2
-rw-r--r--engines/saga/ite_introproc.cpp1
-rw-r--r--engines/saga/list.h2
-rw-r--r--engines/saga/music.cpp160
-rw-r--r--engines/saga/music.h2
-rw-r--r--engines/saga/objectmap.cpp1
-rw-r--r--engines/saga/puzzle.h2
-rw-r--r--engines/saga/render.cpp1
-rw-r--r--engines/saga/rscfile.cpp230
-rw-r--r--engines/saga/rscfile.h2
-rw-r--r--engines/saga/saga.cpp6
-rw-r--r--engines/saga/saga.h5
-rw-r--r--engines/saga/sagaresnames.h34
-rw-r--r--engines/saga/saveload.cpp13
-rw-r--r--engines/saga/scene.cpp202
-rw-r--r--engines/saga/scene.h7
-rw-r--r--engines/saga/script.cpp4
-rw-r--r--engines/saga/script.h9
-rw-r--r--engines/saga/sfuncs.cpp182
-rw-r--r--engines/saga/sndres.cpp29
-rw-r--r--engines/saga/sound.cpp21
-rw-r--r--engines/saga/sprite.cpp14
36 files changed, 1297 insertions, 1156 deletions
diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp
index d7882a78fd..c2ecff4a1a 100644
--- a/engines/saga/actor.cpp
+++ b/engines/saga/actor.cpp
@@ -897,7 +897,9 @@ void Actor::updateActorsScene(int actorsEntrance) {
}
}
- assert(_protagonist);
+ // _protagonist can be null while loading a game from the command line
+ if (_protagonist == NULL)
+ return;
if ((actorsEntrance >= 0) && (_vm->_scene->_entryList.entryListCount > 0)) {
if (_vm->_scene->_entryList.entryListCount <= actorsEntrance) {
@@ -1605,7 +1607,9 @@ void Actor::handleActions(int msec, bool setup) {
if (actor->_lastZone)
stepZoneAction(actor, actor->_lastZone, true, false);
actor->_lastZone = hitZone;
- if (hitZone)
+ // WORKAROUND for graphics glitch in the rat caves. Don't do this step zone action in the rat caves
+ // (room 51) to avoid the glitch
+ if (hitZone && !(_vm->getGameType() == GType_ITE && _vm->_scene->currentSceneNumber() == 51))
stepZoneAction(actor, hitZone, false, false);
}
}
@@ -2127,7 +2131,10 @@ bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) {
if ((((actor->_currentAction >= kActionWalkToPoint) &&
(actor->_currentAction <= kActionWalkDir)) || (actor == _protagonist)) &&
!_vm->_scene->canWalk(pointFrom)) {
- for (i = 1; i < 8; i++) {
+
+ int max = _vm->getGameType() == GType_ITE ? 8 : 4;
+
+ for (i = 1; i < max; i++) {
pointAdd = pointFrom;
pointAdd.y += i;
if (_vm->_scene->canWalk(pointAdd)) {
@@ -2140,17 +2147,19 @@ bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) {
pointFrom = pointAdd;
break;
}
- pointAdd = pointFrom;
- pointAdd.x += i;
- if (_vm->_scene->canWalk(pointAdd)) {
- pointFrom = pointAdd;
- break;
- }
- pointAdd = pointFrom;
- pointAdd.x -= i;
- if (_vm->_scene->canWalk(pointAdd)) {
- pointFrom = pointAdd;
- break;
+ if (_vm->getGameType() == GType_ITE) {
+ pointAdd = pointFrom;
+ pointAdd.x += i;
+ if (_vm->_scene->canWalk(pointAdd)) {
+ pointFrom = pointAdd;
+ break;
+ }
+ pointAdd = pointFrom;
+ pointAdd.x -= i;
+ if (_vm->_scene->canWalk(pointAdd)) {
+ pointFrom = pointAdd;
+ break;
+ }
}
}
}
diff --git a/engines/saga/actor.h b/engines/saga/actor.h
index b9ec62337c..ef62661c6c 100644
--- a/engines/saga/actor.h
+++ b/engines/saga/actor.h
@@ -41,7 +41,7 @@ namespace Saga {
class HitZone;
-// #define ACTOR_DEBUG 1 //only for actor pathfinding debug!
+//#define ACTOR_DEBUG 1 //only for actor pathfinding debug!
#define ACTOR_BARRIERS_MAX 16
@@ -614,11 +614,6 @@ public:
void showActors(bool flag) { _showActors = flag; }
- /*
- uint16 _currentFrameIndex;
- void frameTest() {
- _currentFrameIndex++;
- }*/
protected:
friend class Script;
bool loadActorResources(ActorData *actor);
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index d29fc6ebe6..7b3bdcd665 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -24,6 +24,7 @@
*/
// Background animation management module
+
#include "saga/saga.h"
#include "saga/gfx.h"
@@ -94,7 +95,10 @@ void Anim::playCutaway(int cut, bool fade) {
startImmediately = true;
}
- _vm->_gfx->savePalette();
+ // WORKAROUND: The IHNM demo deals with chained cutaways in a different manner. Don't save
+ // the palette of cutaway 11 (the woman looking at the marble)
+ if (!(_vm->getGameId() == GID_IHNM_DEMO && cut == 11))
+ _vm->_gfx->savePalette();
if (fade) {
_vm->_gfx->getCurrentPal(saved_pal);
@@ -152,6 +156,12 @@ void Anim::playCutaway(int cut, bool fade) {
_vm->_gfx->setPalette(palette);
+ // WORKAROUND for a bug found in the original IHNM demo. The palette of cutaway 12 is incorrect (the incorrect
+ // palette can be seen in the original demo too, for a split second). Therefore, use the saved palette for this
+ // cutaway
+ if (_vm->getGameId() == GID_IHNM_DEMO && cut == 12)
+ _vm->_gfx->restorePalette();
+
free(buf);
free(resourceData);
@@ -307,7 +317,17 @@ void Anim::clearCutaway(void) {
}
_vm->_interface->restoreMode();
- _vm->_gfx->showCursor(true);
+
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149) {
+ // Don't show the mouse cursor in the non-interactive part of the IHNM demo
+ } else {
+ _vm->_gfx->showCursor(true);
+ }
+ } else {
+ // Enable the save reminder state after each cutaway for the IHNM demo
+ _vm->_interface->setSaveReminderState(true);
+ }
}
}
@@ -367,16 +387,6 @@ void Anim::load(uint16 animId, const byte *animResourceData, size_t animResource
fillFrameOffsets(anim);
- /* char s[200];
- sprintf(s, "d:\\anim%i",animId);
- long flen=anim->resourceLength;
- char *buf=(char*)anim->resourceData;
- FILE*f;
- f=fopen(s,"wb");
- for (long i = 0; i < flen; i++)
- fputc(buf[i],f);
- fclose(f);*/
-
// Set animation data
anim->currentFrame = 0;
anim->completed = 0;
@@ -642,7 +652,7 @@ void Anim::decodeFrame(AnimationData *anim, size_t frameOffset, byte *buf, size_
yStart = readS.readUint16BE();
else
yStart = readS.readByte();
- readS.readByte(); /* Skip pad byte */
+ readS.readByte(); // Skip pad byte
/*xPos = */readS.readUint16BE();
/*yPos = */readS.readUint16BE();
/*width = */readS.readUint16BE();
diff --git a/engines/saga/animation.h b/engines/saga/animation.h
index 89a1e77807..f8cf90425f 100644
--- a/engines/saga/animation.h
+++ b/engines/saga/animation.h
@@ -154,6 +154,7 @@ public:
}
return (_animations[animId] != NULL);
}
+ int cutawayResourceID(int cutaway) { return _cutawayList[cutaway].animResourceId; }
private:
void decodeFrame(AnimationData *anim, size_t frameOffset, byte *buf, size_t bufLength);
void fillFrameOffsets(AnimationData *anim);
@@ -208,4 +209,4 @@ private:
} // End of namespace Saga
-#endif /* ANIMATION_H_ */
+#endif // ANIMATION_H_
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 9b9a0ca872..c8918998f1 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -69,7 +69,19 @@ int SagaEngine::getFontsCount() const { return _gameDescription->fontsCount; }
int SagaEngine::getGameId() const { return _gameDescription->gameId; }
int SagaEngine::getGameType() const { return _gameDescription->gameType; }
-uint32 SagaEngine::getFeatures() const { return _gameDescription->features; }
+
+uint32 SagaEngine::getFeatures() const {
+ uint32 result = _gameDescription->features;
+
+ if (_gf_wyrmkeep)
+ result |= GF_WYRMKEEP;
+
+ if (_gf_compressed_sounds)
+ result |= GF_COMPRESSED_SOUNDS;
+
+ return result;
+}
+
Common::Language SagaEngine::getLanguage() const { return _gameDescription->desc.language; }
Common::Platform SagaEngine::getPlatform() const { return _gameDescription->desc.platform; }
int SagaEngine::getGameNumber() const { return _gameNumber; }
@@ -133,6 +145,26 @@ bool SagaEngine::initGame() {
_displayClip.right = getDisplayInfo().logicalWidth;
_displayClip.bottom = getDisplayInfo().logicalHeight;
+ if (Common::File::exists("graphics/credit3n.dlt")) {
+ _gf_wyrmkeep = true;
+ }
+
+ // If a compressed sound file is found in the game's directory, set the compressed flag to true
+ if (_gameDescription->gameType == GType_ITE) {
+ if (Common::File::exists("sounds.cmp") || Common::File::exists("soundsd.cmp") ||
+ Common::File::exists("voices.cmp") || Common::File::exists("voicesd.cmp") ||
+ Common::File::exists("inherit the earth voices.cmp")) {
+ _gf_compressed_sounds = true;
+ }
+ } else {
+ if (Common::File::exists("voicess.cmp") || Common::File::exists("voices1.cmp") ||
+ Common::File::exists("voices2.cmp") || Common::File::exists("voices3.cmp") ||
+ Common::File::exists("voices4.cmp") || Common::File::exists("voices5.cmp") ||
+ Common::File::exists("voices6.cmp") || Common::File::exists("voicesd.cmp")) {
+ _gf_compressed_sounds = true;
+ }
+ }
+
return _resource->createContexts();
}
diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h
index da06255a82..0d57adb87d 100644
--- a/engines/saga/detection_tables.h
+++ b/engines/saga/detection_tables.h
@@ -23,6 +23,8 @@
*
*/
+// Game detection information and MD5s
+
namespace Saga {
static const GameResourceDescription ITE_Resources = {
@@ -36,6 +38,7 @@ static const GameResourceDescription ITE_Resources = {
RID_ITE_MAIN_PANEL_SPRITES,
0, // Option panel sprites (IHNM only)
RID_ITE_DEFAULT_PORTRAITS,
+ 0, // Psychic profile background (IHNM only)
RID_ITE_MAIN_STRINGS,
RID_ITE_ACTOR_NAMES
};
@@ -51,6 +54,7 @@ static const GameResourceDescription ITEDemo_Resources = {
RID_ITEDEMO_MAIN_PANEL_SPRITES,
0, // Option panel sprites (IHNM only)
RID_ITEDEMO_DEFAULT_PORTRAITS,
+ 0, // Psychic profile background (IHNM only)
RID_ITEDEMO_MAIN_STRINGS,
RID_ITEDEMO_ACTOR_NAMES
};
@@ -61,15 +65,6 @@ static const GameFontDescription ITEDEMO_GameFonts[] = {
{1}
};
-static const GameSoundInfo ITEDEMO_GameSound = {
- kSoundVOC,
- -1,
- -1,
- false,
- false,
- true
-};
-
// Inherit the Earth - Wyrmkeep Win32 Demo version
static const GameFontDescription ITEWINDEMO_GameFonts[] = {
@@ -132,16 +127,6 @@ static const GameSoundInfo ITEMACDEMO_GameMusic = {
true
};
-// Inherit the Earth - Wyrmkeep Linux Demo version
-static const GameSoundInfo ITELINDEMO_GameMusic = {
- kSoundPCM,
- 11025,
- 16,
- true,
- false,
- true
-};
-
static const GameSoundInfo ITEMACCD_G_GameSound = {
kSoundMacPCM,
22050,
@@ -201,7 +186,8 @@ static const GameSoundInfo ITECD_GameSound = {
true
};
-static const GamePatchDescription ITEWinPatch1_Files[] = {
+// Patch files. Files not found will be ignored
+static const GamePatchDescription ITEPatch_Files[] = {
{ "cave.mid", GAME_RESOURCEFILE, 9, NULL},
{ "intro.mid", GAME_RESOURCEFILE, 10, NULL},
{ "fvillage.mid", GAME_RESOURCEFILE, 11, NULL},
@@ -235,31 +221,11 @@ static const GamePatchDescription ITEWinPatch1_Files[] = {
{ "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL},
{ "wyrm4.dlt", GAME_RESOURCEFILE, 1533, NULL},
{ "credit3n.dlt", GAME_RESOURCEFILE, 1796, NULL},
+ { "credit3m.dlt", GAME_RESOURCEFILE, 1796, NULL}, // Macintosh
{ "credit4n.dlt", GAME_RESOURCEFILE, 1797, NULL},
- { "p2_a.voc", GAME_VOICEFILE, 4, NULL}
-};
-
-static const GamePatchDescription ITEWinPatch2_Files[] = {
- { "cave.mid", GAME_RESOURCEFILE, 9, NULL},
- { "intro.mid", GAME_RESOURCEFILE, 10, NULL},
- { "fvillage.mid", GAME_RESOURCEFILE, 11, NULL},
- { "elkfanfare.mid", GAME_RESOURCEFILE, 19, NULL},
- { "bcexpl.mid", GAME_RESOURCEFILE, 20, NULL},
- { "boargtnt.mid", GAME_RESOURCEFILE, 21, NULL},
- { "explorea.mid", GAME_RESOURCEFILE, 23, NULL},
- { "sweet.mid", GAME_RESOURCEFILE, 32, NULL},
-
- { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL},
- { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL},
- { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL},
- { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL},
+ { "credit4m.dlt", GAME_RESOURCEFILE, 1797, NULL}, // Macintosh
+ { "p2_a.voc", GAME_VOICEFILE, 4, NULL},
{ "p2_a.iaf", GAME_VOICEFILE, 4, &ITECD_GameSound}
-/* boarhall.bbm
- elkenter.bbm
- ferrets.bbm
- ratdoor.bbm
- sanctuar.bbm
- tycho.bbm*/
};
static const GamePatchDescription ITEMacPatch_Files[] = {
@@ -273,16 +239,6 @@ static const GamePatchDescription ITEMacPatch_Files[] = {
{ "p2_a.iaf", GAME_VOICEFILE, 4, &ITEMACCD_GameSound}
};
-static const GamePatchDescription ITELinPatch_Files[] = {
- { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL},
- { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL},
- { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL},
- { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL},
- { "credit3n.dlt", GAME_RESOURCEFILE, 1796, NULL},
- { "credit4n.dlt", GAME_RESOURCEFILE, 1797, NULL},
- { "P2_A.iaf", GAME_VOICEFILE, 4, &ITECD_GameSound}
-};
-
// IHNM section
static const GameResourceDescription IHNM_Resources = {
@@ -296,10 +252,27 @@ static const GameResourceDescription IHNM_Resources = {
RID_IHNM_MAIN_PANEL_SPRITES,
RID_IHNM_OPTION_PANEL_SPRITES,
0, // Default portraits (ITE only)
+ RID_IHNM_PROFILE_BG,
RID_IHNM_MAIN_STRINGS,
0 // Actors strings (ITE only)
};
+static const GameResourceDescription IHNMDEMO_Resources = {
+ RID_IHNMDEMO_SCENE_LUT, // Scene lookup table RN
+ RID_IHNMDEMO_SCRIPT_LUT, // Script lookup table RN
+ RID_IHNMDEMO_MAIN_PANEL,
+ RID_IHNMDEMO_CONVERSE_PANEL,
+ RID_IHNMDEMO_OPTION_PANEL,
+ RID_IHNMDEMO_WARNING_PANEL,
+ RID_IHNMDEMO_MAIN_SPRITES,
+ RID_IHNMDEMO_MAIN_PANEL_SPRITES,
+ RID_IHNMDEMO_OPTION_PANEL_SPRITES,
+ 0, // Default portraits (ITE only)
+ RID_IHNMDEMO_PROFILE_BG,
+ RID_IHNMDEMO_MAIN_STRINGS,
+ 0 // Actors strings (ITE only)
+};
+
static const GameFontDescription IHNMDEMO_GameFonts[] = {
{2},
{3},
@@ -326,6 +299,14 @@ static const GameSoundInfo IHNM_GameSound = {
};
static const SAGAGameDescription gameDescriptions[] = {
+ // ITE Section ////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ // ITE Demos //////////////////////////////////////////////////////////////////////////////////////////////
+
+ // Note: This version is NOT supported yet
+ // Based on a very early version of the engine
+
// Inherit the earth - DOS Demo version
// sound unchecked
{
@@ -336,7 +317,7 @@ static const SAGAGameDescription gameDescriptions[] = {
{"ite.rsc", GAME_RESOURCEFILE, "986c79c4d2939dbe555576529fd37932", -1},
//{"ite.dmo", GAME_DEMOFILE}, "0b9a70eb4e120b6f00579b46c8cae29e"
{"scripts.rsc", GAME_SCRIPTFILE, "d5697dd3240a3ceaddaa986c47e1a2d7", -1},
- {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "c58e67c506af4ffa03fd0aac2079deb0", -1},
+ //{"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "c58e67c506af4ffa03fd0aac2079deb0", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -350,24 +331,25 @@ static const SAGAGameDescription gameDescriptions[] = {
&ITEDemo_Resources,
ARRAYSIZE(ITEDEMO_GameFonts),
ITEDEMO_GameFonts,
- &ITEDEMO_GameSound,
- &ITEDEMO_GameSound,
- NULL,
+ &ITEDISK_GameSound,
+ &ITEDISK_GameSound,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
0,
NULL,
},
- // Inherit the earth - MAC Demo version 2
+
+ // Inherit the earth - MAC Demo version
{
{
"ite",
"Demo 2",
{
- {"ited.rsc", GAME_RESOURCEFILE, "addfc9d82bc2fa1f4cab23743c652c08", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "fded5c59b8b7c5976229f960d21e6b0b", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "b3a831fbed337d1f1300fee1dd474f6c", -1},
- {"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
- {"musicd.rsc", GAME_MUSICFILE, "495bdde51fd9f4bea2b9c911091b1ab2", -1},
+ {"ited.rsc", GAME_RESOURCEFILE, "addfc9d82bc2fa1f4cab23743c652c08", 1865461},
+ {"scriptsd.rsc", GAME_SCRIPTFILE, "fded5c59b8b7c5976229f960d21e6b0b", 70083},
+ //{"soundsd.rsc", GAME_SOUNDFILE, "b3a831fbed337d1f1300fee1dd474f6c", -1},
+ //{"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
+ //{"musicd.rsc", GAME_MUSICFILE, "495bdde51fd9f4bea2b9c911091b1ab2", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -388,17 +370,21 @@ static const SAGAGameDescription gameDescriptions[] = {
ITEMacPatch_Files,
},
+
+ // Note: This version is NOT supported yet
+ // Exiting the faire leads to a crash
+
// Inherit the earth - MAC Demo version 1
{
{
"ite",
"Demo 1",
{
- {"ited.rsc", GAME_RESOURCEFILE, "addfc9d82bc2fa1f4cab23743c652c08", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "fded5c59b8b7c5976229f960d21e6b0b", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "b3a831fbed337d1f1300fee1dd474f6c", -1},
- {"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
- {"musicd.rsc", GAME_MUSICFILE, "1a91cd60169f367ecb6c6e058d899b2f", -1},
+ {"ited.rsc", GAME_RESOURCEFILE, "addfc9d82bc2fa1f4cab23743c652c08", 1131098},
+ {"scriptsd.rsc", GAME_SCRIPTFILE, "fded5c59b8b7c5976229f960d21e6b0b", 38613},
+ //{"soundsd.rsc", GAME_SOUNDFILE, "b3a831fbed337d1f1300fee1dd474f6c", -1},
+ //{"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
+ //{"musicd.rsc", GAME_MUSICFILE, "1a91cd60169f367ecb6c6e058d899b2f", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -419,142 +405,19 @@ static const SAGAGameDescription gameDescriptions[] = {
ITEMacPatch_Files,
},
- // Inherit the earth - MAC CD Guild version
- {
- {
- "ite",
- "CD",
- {
- {"ite resources.bin", GAME_RESOURCEFILE | GAME_MACBINARY, "0bd506aa887bfc7965f695c6bd28237d", -1},
- {"ite scripts.bin", GAME_SCRIPTFILE | GAME_MACBINARY, "af0d7a2588e09ad3ecbc5b474ea238bf", -1},
- {"ite sounds.bin", GAME_SOUNDFILE | GAME_MACBINARY, "441426c6bb2a517f65c7e49b57f7a345", -1},
- {"ite music.bin", GAME_MUSICFILE_GM | GAME_MACBINARY, "c1d20324b7cdf1650e67061b8a93251c", -1},
- {"ite voices.bin", GAME_VOICEFILE | GAME_MACBINARY, "dba92ae7d57e942250fe135609708369", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformMacintosh,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_MACCD_G,
- GF_BIG_ENDIAN_DATA | GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEWINDEMO_GameFonts),
- ITEWINDEMO_GameFonts,
- &ITEMACCD_G_GameSound,
- &ITEMACCD_G_GameSound,
- NULL,
- 0,
- NULL,
- },
- // Inherit the earth - MAC CD Wyrmkeep version
+ // Inherit the earth - Win32 Demo version 2/3, Linux Demo version
+ // Win32 Version 3 and Linux Demo version have digital music, Win32 version 2 has MIDI music
{
{
"ite",
- "Wyrmkeep CD",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "4f7fa11c5175980ed593392838523060", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "adf1f46c1d0589083996a7060c798ad0", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "95863b89a0916941f6c5e1789843ba14", -1},
- {"inherit the earth voices", GAME_VOICEFILE, "c14c4c995e7a0d3828e3812a494301b7", -1},
- {"music.rsc", GAME_MUSICFILE, "1a91cd60169f367ecb6c6e058d899b2f", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformMacintosh,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_MACCD,
- GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEWINDEMO_GameFonts),
- ITEWINDEMO_GameFonts,
- &ITEMACCD_GameSound,
- &ITEMACCD_GameSound,
- &ITEMACCD_GameMusic,
- ARRAYSIZE(ITEMacPatch_Files),
- ITEMacPatch_Files,
- },
-
- // Inherit the earth - MAC CD Wyrmkeep version (compressed sound)
- {
- {
- "ite",
- "Wyrmkeep CD",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "4f7fa11c5175980ed593392838523060", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "adf1f46c1d0589083996a7060c798ad0", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"inherit the earth voices.cmp",GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformMacintosh,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_MACCD,
- GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEWINDEMO_GameFonts),
- ITEWINDEMO_GameFonts,
- &ITEMACCD_GameSound,
- &ITEMACCD_GameSound,
- &ITEMACCD_GameMusic,
- ARRAYSIZE(ITEMacPatch_Files),
- ITEMacPatch_Files,
- },
-
- // Inherit the earth - Linux Demo version
- // Note: it should be before GID_ITE_WINDEMO2 version
- {
- {
- "ite",
- "Demo",
- {
- {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "95a6c148e22e99a8c243f2978223583c", 2026769},
- {"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
- {"musicd.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- Common::ADGF_DEMO
- },
- GType_ITE,
- GID_ITE_LINDEMO,
- GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEWINDEMO_GameFonts),
- ITEWINDEMO_GameFonts,
- &ITEWINDEMO2_GameVoice,
- &ITEWINDEMO2_GameSound,
- &ITELINDEMO_GameMusic,
- ARRAYSIZE(ITELinPatch_Files),
- ITELinPatch_Files,
- },
-
- // Inherit the earth - Win32 Demo version 3
- {
- {
- "ite",
- "Demo 3",
+ "Win Demo 2/3, Linux Demo",
{
- {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "95a6c148e22e99a8c243f2978223583c", 2005074},
- {"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
- {"musicd.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
+ {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", 1951395},
+ {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", 70051},
+ //{"soundsd.rsc", GAME_SOUNDFILE, "95a6c148e22e99a8c243f2978223583c", -1},
+ //{"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
+ //{"musicd.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -570,21 +433,25 @@ static const SAGAGameDescription gameDescriptions[] = {
ITEWINDEMO_GameFonts,
&ITEWINDEMO2_GameVoice,
&ITEWINDEMO2_GameSound,
- &ITELINDEMO_GameMusic,
- ARRAYSIZE(ITEWinPatch2_Files),
- ITEWinPatch2_Files,
+ &ITEMACCD_GameMusic,
+ ARRAYSIZE(ITEPatch_Files),
+ ITEPatch_Files,
},
- // Inherit the earth - Win32 Demo version 2
+
+ // Note: This version is NOT supported yet
+ // Exiting the faire leads to a crash
+
+ // Inherit the earth - Win32 Demo version 1
{
{
"ite",
- "Demo 2",
+ "Demo 1",
{
- {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "95a6c148e22e99a8c243f2978223583c", 2005074},
- {"voicesd.rsc", GAME_VOICEFILE, "e139d86bab2ee8ba3157337f894a92d4", -1},
+ {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", 1327323},
+ {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", 38613},
+ //{"soundsd.rsc", GAME_SOUNDFILE, "a741139dd7365a13f463cd896ff9969a", -1},
+ //{"voicesd.rsc", GAME_VOICEFILE, "0759eaf5b64ae19fd429920a70151ad3", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -592,86 +459,91 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::ADGF_DEMO
},
GType_ITE,
- GID_ITE_WINDEMO2,
- GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES,
+ GID_ITE_WINDEMO1,
+ GF_WYRMKEEP | GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
ARRAYSIZE(ITEWINDEMO_GameFonts),
ITEWINDEMO_GameFonts,
- &ITEWINDEMO2_GameVoice,
- &ITEWINDEMO2_GameSound,
- NULL,
- ARRAYSIZE(ITEWinPatch2_Files),
- ITEWinPatch2_Files,
+ &ITEWINDEMO1_GameSound,
+ &ITEWINDEMO1_GameSound,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
+ ARRAYSIZE(ITEPatch_Files),
+ ITEPatch_Files,
},
- // Inherit the earth - Win32 Demo version 1
+
+ // TODO: Add Amiga demos here (not supported yet)
+
+
+ // ITE Mac versions ///////////////////////////////////////////////////////////////////////////////////////
+
+ // Inherit the earth - MAC CD Guild version
{
{
"ite",
- "Demo 1",
+ "CD",
{
- {"ited.rsc", GAME_RESOURCEFILE, "3a450852cbf3c80773984d565647e6ac", -1},
- {"scriptsd.rsc", GAME_SCRIPTFILE, "3f12b67fa93e56e1a6be39d2921d80bb", -1},
- {"soundsd.rsc", GAME_SOUNDFILE, "a741139dd7365a13f463cd896ff9969a", -1},
- {"voicesd.rsc", GAME_VOICEFILE, "0759eaf5b64ae19fd429920a70151ad3", -1},
+ {"ite resources.bin", GAME_RESOURCEFILE | GAME_MACBINARY, "0bd506aa887bfc7965f695c6bd28237d", -1},
+ {"ite scripts.bin", GAME_SCRIPTFILE | GAME_MACBINARY, "af0d7a2588e09ad3ecbc5b474ea238bf", -1},
+ {"ite sounds.bin", GAME_SOUNDFILE | GAME_MACBINARY, "441426c6bb2a517f65c7e49b57f7a345", -1},
+ {"ite music.bin", GAME_MUSICFILE_GM | GAME_MACBINARY, "c1d20324b7cdf1650e67061b8a93251c", -1},
+ {"ite voices.bin", GAME_VOICEFILE | GAME_MACBINARY, "dba92ae7d57e942250fe135609708369", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
- Common::kPlatformWindows,
- Common::ADGF_DEMO
+ Common::kPlatformMacintosh,
+ Common::ADGF_NO_FLAGS
},
GType_ITE,
- GID_ITE_WINDEMO1,
- GF_WYRMKEEP | GF_CD_FX,
+ GID_ITE_MACCD_G,
+ GF_BIG_ENDIAN_DATA | GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
ARRAYSIZE(ITEWINDEMO_GameFonts),
ITEWINDEMO_GameFonts,
- &ITEWINDEMO1_GameSound,
- &ITEWINDEMO1_GameSound,
+ &ITEMACCD_G_GameSound,
+ &ITEMACCD_G_GameSound,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
+ 0,
NULL,
- ARRAYSIZE(ITEWinPatch1_Files),
- ITEWinPatch1_Files,
},
- // Inherit the earth - Wyrmkeep combined Windows/Mac/Linux CD
-
- // version is different from the other Wyrmkeep re-releases in that it does
- // not have any substitute files. Presumably the ite.rsc file has been
- // modified to include the Wyrmkeep changes. The resource files are little-
- // endian, except for the voice file which is big-endian.
+ // Inherit the earth - MAC CD Wyrmkeep version
{
{
"ite",
- "Multi-OS CD Version",
+ "Wyrmkeep CD",
{
- {"ite.rsc", GAME_RESOURCEFILE, "a6433e34b97b15e64fe8214651012db9", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"inherit the earth voices", GAME_VOICEFILE | GAME_SWAPENDIAN, "c14c4c995e7a0d3828e3812a494301b7", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
+ {"ite.rsc", GAME_RESOURCEFILE, "4f7fa11c5175980ed593392838523060", -1},
+ {"scripts.rsc", GAME_SCRIPTFILE, "adf1f46c1d0589083996a7060c798ad0", -1},
+ //{"sounds.rsc", GAME_SOUNDFILE, "95863b89a0916941f6c5e1789843ba14", -1},
+ //{"inherit the earth voices", GAME_VOICEFILE, "c14c4c995e7a0d3828e3812a494301b7", -1},
+ //{"music.rsc", GAME_MUSICFILE, "1a91cd60169f367ecb6c6e058d899b2f", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
- Common::kPlatformUnknown,
+ Common::kPlatformMacintosh,
Common::ADGF_NO_FLAGS
},
GType_ITE,
- GID_ITE_MULTICD,
- GF_WYRMKEEP | GF_CD_FX,
+ GID_ITE_MACCD,
+ GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
+ ARRAYSIZE(ITEWINDEMO_GameFonts),
+ ITEWINDEMO_GameFonts,
+ &ITEMACCD_GameSound,
&ITEMACCD_GameSound,
- &ITECD_GameSound,
&ITEMACCD_GameMusic,
- 0,
- NULL,
+ ARRAYSIZE(ITEMacPatch_Files),
+ ITEMacPatch_Files,
},
- // Inherit the earth - Wyrmkeep combined Windows/Mac/Linux CD (compressed sound)
+
+ // ITE PC CD versions //////////////////////////////////////////////////////////////////////////////////////
+
+ // Inherit the earth - Wyrmkeep combined Windows/Mac/Linux CD
// version is different from the other Wyrmkeep re-releases in that it does
// not have any substitute files. Presumably the ite.rsc file has been
@@ -684,9 +556,9 @@ static const SAGAGameDescription gameDescriptions[] = {
{
{"ite.rsc", GAME_RESOURCEFILE, "a6433e34b97b15e64fe8214651012db9", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"inherit the earth voices.cmp",GAME_VOICEFILE | GAME_SWAPENDIAN, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
+ //{"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
+ //{"inherit the earth voices", GAME_VOICEFILE | GAME_SWAPENDIAN, "c14c4c995e7a0d3828e3812a494301b7", -1},
+ //{"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -695,7 +567,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
GType_ITE,
GID_ITE_MULTICD,
- GF_WYRMKEEP | GF_CD_FX | GF_COMPRESSED_SOUNDS,
+ GF_WYRMKEEP | GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
ARRAYSIZE(ITECD_GameFonts),
@@ -707,138 +579,17 @@ static const SAGAGameDescription gameDescriptions[] = {
NULL,
},
- // Inherit the earth - Wyrmkeep Linux CD version
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_LINCD,
- GF_WYRMKEEP | GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- &ITEMACCD_GameMusic,
- ARRAYSIZE(ITELinPatch_Files),
- ITELinPatch_Files,
- },
-
- // Inherit the earth - Wyrmkeep Linux CD version (compressed sound)
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_LINCD,
- GF_WYRMKEEP | GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- &ITEMACCD_GameMusic,
- ARRAYSIZE(ITELinPatch_Files),
- ITELinPatch_Files,
- },
-
- // Inherit the earth - Wyrmkeep Windows CD version
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_WINCD,
- GF_WYRMKEEP | GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- ARRAYSIZE(ITEWinPatch1_Files),
- ITEWinPatch1_Files,
- },
-
- // Inherit the earth - Wyrmkeep Windows CD version (compressed sound)
+ // Inherit the earth - Windows/Linux/DOS CD version
{
{
"ite",
- "CD Version",
+ "Windows/Linux/DOS CD Version",
{
{"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_WINCD,
- GF_WYRMKEEP | GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- ARRAYSIZE(ITEWinPatch1_Files),
- ITEWinPatch1_Files,
- },
-
- // Inherit the earth - DOS CD version
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "50a0d2d7003c926a3832d503c8534e90", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
+ //{"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
+ //{"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
+ //{"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -846,7 +597,7 @@ static const SAGAGameDescription gameDescriptions[] = {
Common::ADGF_NO_FLAGS
},
GType_ITE,
- GID_ITE_CD_G,
+ GID_ITE_CD,
GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
@@ -854,12 +605,12 @@ static const SAGAGameDescription gameDescriptions[] = {
ITECD_GameFonts,
&ITECD_GameSound,
&ITECD_GameSound,
- NULL,
- 0,
- NULL,
+ &ITEMACCD_GameMusic,
+ ARRAYSIZE(ITEPatch_Files),
+ ITEPatch_Files,
},
- // Inherit the earth - DOS CD version (compressed sound)
+ // Inherit the earth - DOS CD version
{
{
"ite",
@@ -867,8 +618,8 @@ static const SAGAGameDescription gameDescriptions[] = {
{
{"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "50a0d2d7003c926a3832d503c8534e90", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
+ //{"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
+ //{"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -877,37 +628,6 @@ static const SAGAGameDescription gameDescriptions[] = {
},
GType_ITE,
GID_ITE_CD_G,
- GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- 0,
- NULL,
- },
-
- // Inherit the earth - DOS CD version with digital music
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "50a0d2d7003c926a3832d503c8534e90", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD_G2,
GF_CD_FX,
ITE_DEFAULT_SCENE,
&ITE_Resources,
@@ -915,40 +635,9 @@ static const SAGAGameDescription gameDescriptions[] = {
ITECD_GameFonts,
&ITECD_GameSound,
&ITECD_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
- },
-
- // Inherit the earth - DOS CD version with digital music (compressed sound)
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "50a0d2d7003c926a3832d503c8534e90", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD_G2,
- GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
+ ARRAYSIZE(ITEPatch_Files),
+ ITEPatch_Files,
},
// Inherit the earth - DOS CD German version
@@ -960,8 +649,8 @@ static const SAGAGameDescription gameDescriptions[] = {
{
{"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "2fbad5d10b9b60a3415dc4aebbb11718", -1},
+ //{"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
+ //{"voices.rsc", GAME_VOICEFILE, "2fbad5d10b9b60a3415dc4aebbb11718", -1},
{ NULL, 0, NULL, 0}
},
Common::DE_DEU,
@@ -977,163 +666,13 @@ static const SAGAGameDescription gameDescriptions[] = {
ITECD_GameFonts,
&ITECD_GameSound,
&ITECD_GameSound,
- NULL,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
0,
NULL,
},
- // Inherit the earth - DOS CD German version (compressed sound)
- // reported by mld. Bestsellergamers cover disk
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD_DE,
- GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- 0,
- NULL,
- },
- // Inherit the earth - DOS CD German version with digital music
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "2fbad5d10b9b60a3415dc4aebbb11718", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD_DE2,
- GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
- },
-
- // Inherit the earth - DOS CD German version with digital music (compressed sound)
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD_DE2,
- GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
- },
-
- // Inherit the earth - CD version
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.rsc", GAME_SOUNDFILE, "e2ccb61c325d6d1ead3be0e731fe29fe", -1},
- {"voices.rsc", GAME_VOICEFILE, "41bb6b95d792dde5196bdb78740895a6", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD,
- GF_CD_FX,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- 0,
- NULL,
- },
-
- // Inherit the earth - CD version (compressed sound)
- {
- {
- "ite",
- "CD Version",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "a891405405edefc69c9d6c420c868b84", -1},
- {"sounds.cmp", GAME_SOUNDFILE, NULL, -1},
- {"voices.cmp", GAME_VOICEFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_CD,
- GF_CD_FX | GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITECD_GameFonts),
- ITECD_GameFonts,
- &ITECD_GameSound,
- &ITECD_GameSound,
- NULL,
- 0,
- NULL,
- },
+ // ITE floppy versions ////////////////////////////////////////////////////////////////////////////////////
// Inherit the earth - German Floppy version
{
@@ -1143,36 +682,7 @@ static const SAGAGameDescription gameDescriptions[] = {
{
{"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "0c9113e630f97ef0996b8c3114badb08", -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_DE,
- 0,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- NULL,
- 0,
- NULL,
- },
-
- // Inherit the earth - German Floppy version (compressed sound)
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.cmp", GAME_SOUNDFILE | GAME_VOICEFILE, NULL, -1},
+ //{"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "0c9113e630f97ef0996b8c3114badb08", -1},
{ NULL, 0, NULL, 0}
},
Common::DE_DEU,
@@ -1181,74 +691,14 @@ static const SAGAGameDescription gameDescriptions[] = {
},
GType_ITE,
GID_ITE_DISK_DE,
- GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- NULL,
- 0,
- NULL,
- },
-
- // Inherit the earth - German Floppy version with digital music
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "0c9113e630f97ef0996b8c3114badb08", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_DE2,
- 0,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- &ITEMACCD_GameMusic,
0,
- NULL,
- },
-
- // Inherit the earth - German Floppy version with digital music (compressed sound)
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "869fc23c8f38f575979ec67152914fee", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.cmp", GAME_SOUNDFILE | GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_DE2,
- GF_COMPRESSED_SOUNDS,
ITE_DEFAULT_SCENE,
&ITE_Resources,
ARRAYSIZE(ITEDISK_GameFonts),
ITEDISK_GameFonts,
&ITEDISK_GameSound,
&ITEDISK_GameSound,
- &ITEMACCD_GameMusic,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
0,
NULL,
},
@@ -1261,7 +711,7 @@ static const SAGAGameDescription gameDescriptions[] = {
{
{"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
{"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "c46e4392fcd2e89bc91e5567db33b62d", -1},
+ //{"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "c46e4392fcd2e89bc91e5567db33b62d", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -1277,99 +727,18 @@ static const SAGAGameDescription gameDescriptions[] = {
ITEDISK_GameFonts,
&ITEDISK_GameSound,
&ITEDISK_GameSound,
- NULL,
- 0,
- NULL,
+ &ITEMACCD_GameMusic, // note: this version did not originally have digital music
+ ARRAYSIZE(ITEPatch_Files),
+ ITEPatch_Files,
},
- // Inherit the earth - Disk version (compressed sound)
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.cmp", GAME_SOUNDFILE | GAME_VOICEFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_G,
- GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- NULL,
- 0,
- NULL,
- },
- // Inherit the earth - Disk version with digital music
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE, "c46e4392fcd2e89bc91e5567db33b62d", -1},
- {"music.rsc", GAME_MUSICFILE, "d6454756517f042f01210458abe8edd4", -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_G2,
- 0,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
- },
+ // ITE Amiga versions /////////////////////////////////////////////////////////////////////////////////////
- // Inherit the earth - Disk version with digital music (compressed sound)
- {
- {
- "ite",
- "Floppy",
- {
- {"ite.rsc", GAME_RESOURCEFILE, "8f4315a9bb10ec839253108a032c8b54", -1},
- {"scripts.rsc", GAME_SCRIPTFILE, "516f7330f8410057b834424ea719d1ef", -1},
- {"voices.cmp", GAME_SOUNDFILE | GAME_VOICEFILE, NULL, -1},
- {"music.cmp", GAME_MUSICFILE, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
- },
- GType_ITE,
- GID_ITE_DISK_G2,
- GF_COMPRESSED_SOUNDS,
- ITE_DEFAULT_SCENE,
- &ITE_Resources,
- ARRAYSIZE(ITEDISK_GameFonts),
- ITEDISK_GameFonts,
- &ITEDISK_GameSound,
- &ITEDISK_GameSound,
- &ITEMACCD_GameMusic,
- 0,
- NULL,
- },
+ // TODO: Add the Amiga versions here (not supported yet)
+
+
+ // IHNM Section ///////////////////////////////////////////////////////////////////////////////////////////
// I Have No Mouth And I Must Scream - Demo version
{
@@ -1377,10 +746,11 @@ static const SAGAGameDescription gameDescriptions[] = {
"ihnm",
"Demo",
{
+ {"music.res", GAME_MUSICFILE_FM, "0439083e3dfdc51b486071d45872ae52", -1},
{"scream.res", GAME_RESOURCEFILE, "46bbdc65d164ba7e89836a0935eec8e6", -1},
{"scripts.res", GAME_SCRIPTFILE, "9626bda8978094ff9b29198bc1ed5f9a", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicesd.res", GAME_VOICEFILE, "3bbc16a8f741dbb511da506c660a0b54", -1},
+ //{"voicesd.res", GAME_VOICEFILE, "3bbc16a8f741dbb511da506c660a0b54", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -1390,8 +760,8 @@ static const SAGAGameDescription gameDescriptions[] = {
GType_IHNM,
GID_IHNM_DEMO,
0,
- 0,
- &IHNM_Resources,
+ IHNMDEMO_DEFAULT_SCENE,
+ &IHNMDEMO_Resources,
ARRAYSIZE(IHNMDEMO_GameFonts),
IHNMDEMO_GameFonts,
&IHNM_GameSound,
@@ -1413,13 +783,13 @@ static const SAGAGameDescription gameDescriptions[] = {
{"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE, "58b79e61594779513c7f2d35509fa89e", -1},
{"scripts.res", GAME_SCRIPTFILE, "be38bbc5a26be809dbf39f13befebd01", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicess.res", GAME_VOICEFILE, "54b1f2013a075338ceb0e258d97808bd", -1}, //order of voice bank file is important
- {"voices1.res", GAME_VOICEFILE, "fc6440b38025f4b2cc3ff55c3da5c3eb", -1},
- {"voices2.res", GAME_VOICEFILE, "b37f10fd1696ade7d58704ccaaebceeb", -1},
- {"voices3.res", GAME_VOICEFILE, "3bbc16a8f741dbb511da506c660a0b54", -1},
- {"voices4.res", GAME_VOICEFILE, "ebfa160122d2247a676ca39920e5d481", -1},
- {"voices5.res", GAME_VOICEFILE, "1f501ce4b72392bdd1d9ec38f6eec6da", -1},
- {"voices6.res", GAME_VOICEFILE, "f580ed7568c7d6ef34e934ba20adf834", -1},
+ //{"voicess.res", GAME_VOICEFILE, "54b1f2013a075338ceb0e258d97808bd", -1}, //order of voice bank file is important
+ //{"voices1.res", GAME_VOICEFILE, "fc6440b38025f4b2cc3ff55c3da5c3eb", -1},
+ //{"voices2.res", GAME_VOICEFILE, "b37f10fd1696ade7d58704ccaaebceeb", -1},
+ //{"voices3.res", GAME_VOICEFILE, "3bbc16a8f741dbb511da506c660a0b54", -1},
+ //{"voices4.res", GAME_VOICEFILE, "ebfa160122d2247a676ca39920e5d481", -1},
+ //{"voices5.res", GAME_VOICEFILE, "1f501ce4b72392bdd1d9ec38f6eec6da", -1},
+ //{"voices6.res", GAME_VOICEFILE, "f580ed7568c7d6ef34e934ba20adf834", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -1454,12 +824,12 @@ static const SAGAGameDescription gameDescriptions[] = {
{"scripts.res", GAME_SCRIPTFILE, "32aa01a89937520fe0ea513950117292", -1},
{"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE, "58b79e61594779513c7f2d35509fa89e", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicess.res", GAME_VOICEFILE, "8b09a196a52627cacb4eab13bfe0b2c3", -1}, //order of voice bank file is important
- {"voices1.res", GAME_VOICEFILE, "424971e1e2373187c3f5734fe36071a2", -1},
- {"voices2.res", GAME_VOICEFILE, "c270e0980782af43641a86e4a14e2a32", -1},
- {"voices3.res", GAME_VOICEFILE, "49e42befea883fd101ec3d0f5d0647b9", -1},
- {"voices5.res", GAME_VOICEFILE, "c477443c52a0aa56e686ebd8d051e4ab", -1},
- {"voices6.res", GAME_VOICEFILE, "2b9aea838f74b4eecfb29a8f205a2bd4", -1},
+ //{"voicess.res", GAME_VOICEFILE, "8b09a196a52627cacb4eab13bfe0b2c3", -1}, //order of voice bank file is important
+ //{"voices1.res", GAME_VOICEFILE, "424971e1e2373187c3f5734fe36071a2", -1},
+ //{"voices2.res", GAME_VOICEFILE, "c270e0980782af43641a86e4a14e2a32", -1},
+ //{"voices3.res", GAME_VOICEFILE, "49e42befea883fd101ec3d0f5d0647b9", -1},
+ //{"voices5.res", GAME_VOICEFILE, "c477443c52a0aa56e686ebd8d051e4ab", -1},
+ //{"voices6.res", GAME_VOICEFILE, "2b9aea838f74b4eecfb29a8f205a2bd4", -1},
{ NULL, 0, NULL, 0}
},
Common::DE_DEU,
@@ -1492,13 +862,13 @@ static const SAGAGameDescription gameDescriptions[] = {
{"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE, "58b79e61594779513c7f2d35509fa89e", -1},
{"scripts.res", GAME_SCRIPTFILE, "be38bbc5a26be809dbf39f13befebd01", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicess.res", GAME_VOICEFILE, "d869de9883c8faea7f687217a9ec7057", -1}, //order of voice bank file is important
- {"voices1.res", GAME_VOICEFILE, "dc6a34e3d1668730ea46815a92c7847f", -1},
- {"voices2.res", GAME_VOICEFILE, "dc6a5fa7a4cdc2ca5a6fd924e969986c", -1},
- {"voices3.res", GAME_VOICEFILE, "dc6a5fa7a4cdc2ca5a6fd924e969986c", -1},
- {"voices4.res", GAME_VOICEFILE, "0f87400b804232a58dd22e404420cc45", -1},
- {"voices5.res", GAME_VOICEFILE, "172668cfc5d8c305cb5b1a9b4d995fc0", -1},
- {"voices6.res", GAME_VOICEFILE, "96c9bda9a5f41d6bc232ed7bf6d371d9", -1},
+ //{"voicess.res", GAME_VOICEFILE, "d869de9883c8faea7f687217a9ec7057", -1}, //order of voice bank file is important
+ //{"voices1.res", GAME_VOICEFILE, "dc6a34e3d1668730ea46815a92c7847f", -1},
+ //{"voices2.res", GAME_VOICEFILE, "dc6a5fa7a4cdc2ca5a6fd924e969986c", -1},
+ //{"voices3.res", GAME_VOICEFILE, "dc6a5fa7a4cdc2ca5a6fd924e969986c", -1},
+ //{"voices4.res", GAME_VOICEFILE, "0f87400b804232a58dd22e404420cc45", -1},
+ //{"voices5.res", GAME_VOICEFILE, "172668cfc5d8c305cb5b1a9b4d995fc0", -1},
+ //{"voices6.res", GAME_VOICEFILE, "96c9bda9a5f41d6bc232ed7bf6d371d9", -1},
{ NULL, 0, NULL, 0}
},
Common::ES_ESP,
@@ -1531,13 +901,13 @@ static const SAGAGameDescription gameDescriptions[] = {
{"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE, "58b79e61594779513c7f2d35509fa89e", -1},
{"scripts.res", GAME_SCRIPTFILE, "be38bbc5a26be809dbf39f13befebd01", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicess.res", GAME_VOICEFILE, "9df7cd3b18ddaa16b5291b3432567036", -1}, //order of voice bank file is important
- {"voices1.res", GAME_VOICEFILE, "d6100d2dc3b2b9f2e1ad247f613dce9b", -1},
- {"voices2.res", GAME_VOICEFILE, "84f6f48ecc2832841ea6417a9a379430", -1},
- {"voices3.res", GAME_VOICEFILE, "ebb9501283047f27a0f54e27b3c8ba1e", -1},
- {"voices4.res", GAME_VOICEFILE, "4c145da5fa6d1306162a7ca8ce5a4f2e", -1},
- {"voices5.res", GAME_VOICEFILE, "871a559644281917677eca4af1b05620", -1},
- {"voices6.res", GAME_VOICEFILE, "211be5c24f066d69a2f6cfa953acfba6", -1},
+ //{"voicess.res", GAME_VOICEFILE, "9df7cd3b18ddaa16b5291b3432567036", -1}, //order of voice bank file is important
+ //{"voices1.res", GAME_VOICEFILE, "d6100d2dc3b2b9f2e1ad247f613dce9b", -1},
+ //{"voices2.res", GAME_VOICEFILE, "84f6f48ecc2832841ea6417a9a379430", -1},
+ //{"voices3.res", GAME_VOICEFILE, "ebb9501283047f27a0f54e27b3c8ba1e", -1},
+ //{"voices4.res", GAME_VOICEFILE, "4c145da5fa6d1306162a7ca8ce5a4f2e", -1},
+ //{"voices5.res", GAME_VOICEFILE, "871a559644281917677eca4af1b05620", -1},
+ //{"voices6.res", GAME_VOICEFILE, "211be5c24f066d69a2f6cfa953acfba6", -1},
{ NULL, 0, NULL, 0}
},
Common::RU_RUS,
@@ -1570,12 +940,12 @@ static const SAGAGameDescription gameDescriptions[] = {
{"scripts.res", GAME_SCRIPTFILE, "32aa01a89937520fe0ea513950117292", -1},
{"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE, "58b79e61594779513c7f2d35509fa89e", -1},
{"sfx.res", GAME_SOUNDFILE, "1c610d543f32ec8b525e3f652536f269", -1},
- {"voicess.res", GAME_VOICEFILE, "b8642e943bbebf89cef2f48b31cb4305", -1}, //order of voice bank file is important
- {"voices1.res", GAME_VOICEFILE, "424971e1e2373187c3f5734fe36071a2", -1},
- {"voices2.res", GAME_VOICEFILE, "c2d93a35d2c2def9c3d6d242576c794b", -1},
- {"voices3.res", GAME_VOICEFILE, "49e42befea883fd101ec3d0f5d0647b9", -1},
- {"voices5.res", GAME_VOICEFILE, "f4c415de7c03de86b73f9a12b8bd632f", -1},
- {"voices6.res", GAME_VOICEFILE, "3fc5358a5d8eee43bdfab2740276572e", -1},
+ //{"voicess.res", GAME_VOICEFILE, "b8642e943bbebf89cef2f48b31cb4305", -1}, //order of voice bank file is important
+ //{"voices1.res", GAME_VOICEFILE, "424971e1e2373187c3f5734fe36071a2", -1},
+ //{"voices2.res", GAME_VOICEFILE, "c2d93a35d2c2def9c3d6d242576c794b", -1},
+ //{"voices3.res", GAME_VOICEFILE, "49e42befea883fd101ec3d0f5d0647b9", -1},
+ //{"voices5.res", GAME_VOICEFILE, "f4c415de7c03de86b73f9a12b8bd632f", -1},
+ //{"voices6.res", GAME_VOICEFILE, "3fc5358a5d8eee43bdfab2740276572e", -1},
{ NULL, 0, NULL, 0}
},
Common::FR_FRA,
diff --git a/engines/saga/displayinfo.h b/engines/saga/displayinfo.h
index 83bc536959..74bbcc4343 100644
--- a/engines/saga/displayinfo.h
+++ b/engines/saga/displayinfo.h
@@ -23,6 +23,8 @@
*
*/
+// Interface widget display information
+
#ifndef SAGA_DISPLAYINFO_H
#define SAGA_DISPLAYINFO_H
diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp
index b93c6017c7..80e6b58595 100644
--- a/engines/saga/events.cpp
+++ b/engines/saga/events.cpp
@@ -35,6 +35,7 @@
#include "saga/palanim.h"
#include "saga/render.h"
#include "saga/sndres.h"
+#include "saga/rscfile.h"
#include "saga/music.h"
#include "saga/actor.h"
@@ -344,6 +345,39 @@ int Events::handleOneShot(Event *event) {
_vm->_actor->showActors(true);
}
break;
+ case kPsychicProfileBgEvent:
+ {
+ ResourceContext *context = _vm->_resource->getContext(GAME_RESOURCEFILE);
+
+ byte *resourceData;
+ size_t resourceDataLength;
+
+ _vm->_resource->loadResource(context, _vm->getResourceDescription()->psychicProfileResourceId, resourceData, resourceDataLength);
+
+ byte *buf;
+ size_t buflen;
+ int width;
+ int height;
+
+ _vm->decodeBGImage(resourceData, resourceDataLength, &buf, &buflen, &width, &height);
+
+ const PalEntry *palette = (const PalEntry *)_vm->getImagePal(resourceData, resourceDataLength);
+
+ Surface *bgSurface = _vm->_render->getBackGroundSurface();
+ const Rect profileRect(width, height);
+
+ bgSurface->blit(profileRect, buf);
+ _vm->_frameCount++;
+
+ _vm->_gfx->setPalette(palette);
+
+ free(buf);
+ free(resourceData);
+
+ // Draw the scene. It won't be drawn by Render::drawScene(), as the RF_PLACARD is set
+ _vm->_scene->draw();
+ }
+ break;
case kAnimEvent:
switch (event->op) {
case kEventPlay:
@@ -460,12 +494,13 @@ int Events::handleOneShot(Event *event) {
_vm->_gfx->showCursor(false);
break;
case kEventSetNormalCursor:
- // in ITE there is just one cursor
- if (_vm->getGameType() == GType_IHNM)
+ // in ITE and IHNM demo there is just one cursor
+ if (_vm->getGameType() == GType_IHNM && _vm->getGameId() != GID_IHNM_DEMO)
_vm->_gfx->setCursor(kCursorNormal);
break;
case kEventSetBusyCursor:
- if (_vm->getGameType() == GType_IHNM)
+ // in ITE and IHNM demo there is just one cursor
+ if (_vm->getGameType() == GType_IHNM && _vm->getGameId() != GID_IHNM_DEMO)
_vm->_gfx->setCursor(kCursorBusy);
break;
default:
diff --git a/engines/saga/events.h b/engines/saga/events.h
index d0af1fe916..2486525751 100644
--- a/engines/saga/events.h
+++ b/engines/saga/events.h
@@ -60,7 +60,8 @@ enum EventCodes {
kScriptEvent,
kCursorEvent,
kGraphicsEvent,
- kCutawayEvent
+ kCutawayEvent,
+ kPsychicProfileBgEvent
};
enum EventOps {
diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp
index ece48512df..71cd6b0eef 100644
--- a/engines/saga/font.cpp
+++ b/engines/saga/font.cpp
@@ -24,6 +24,7 @@
*/
// Font management and font drawing module
+
#include "saga/saga.h"
#include "saga/gfx.h"
#include "saga/rscfile.h"
@@ -331,7 +332,7 @@ void Font::outFont(const FontStyle &drawFont, Surface *ds, const char *text, siz
// Check if character is defined
if ((drawFont.fontCharEntry[c_code].index == 0) && (c_code != FONT_FIRSTCHAR)) {
#if FONT_SHOWUNDEFINED
- if (c_code == FONT_CH_SPACE) {
+ if (c_code == FONT_CH_SPACE || c_code == 9) {
textPoint.x += drawFont.fontCharEntry[c_code].tracking;
continue;
}
@@ -629,7 +630,8 @@ void Font::textDrawRect(FontId fontId, Surface *ds, const char *text, const Comm
Font::FontId Font::knownFont2FontIdx(KnownFont font) {
FontId fontId = kSmallFont;
- if (_vm->getGameType() == GType_ITE) {
+ // The demo version of IHNM has 3 font types (like ITE), not 6 (like the full version of IHNM)
+ if (_vm->getGameType() == GType_ITE || _vm->getGameId() == GID_IHNM_DEMO) {
switch (font)
{
case (kKnownFontSmall):
@@ -652,7 +654,7 @@ Font::FontId Font::knownFont2FontIdx(KnownFont font) {
fontId = _vm->_font->valid(kBigFont) ? kBigFont : kMediumFont;
break;
}
- } else if (_vm->getGameType() == GType_IHNM) {
+ } else if (_vm->getGameType() == GType_IHNM && _vm->getGameId() != GID_IHNM_DEMO) {
switch (font)
{
case (kKnownFontSmall):
diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp
index a9c6801714..56ffe04c96 100644
--- a/engines/saga/gfx.cpp
+++ b/engines/saga/gfx.cpp
@@ -130,10 +130,7 @@ void Surface::drawPolyLine(const Point *points, int count, int color) {
}
}
-/**
-* Dissolve one image with another.
-* If flags if set to 1, do zero masking.
-*/
+// Dissolve one image with another. If flags is set to 1, do zero masking.
void Surface::transitionDissolve(const byte *sourceBuffer, const Common::Rect &sourceRect, int flags, double percent) {
#define XOR_MASK 0xB400;
int pixelcount = w * h;
@@ -431,7 +428,10 @@ void Gfx::setCursor(CursorType cursorType) {
switch (cursorType) {
case kCursorBusy:
- resourceId = RID_IHNM_HOURGLASS_CURSOR;
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ resourceId = RID_IHNM_HOURGLASS_CURSOR;
+ else
+ resourceId = (uint32)-1;
break;
default:
resourceId = (uint32)-1;
diff --git a/engines/saga/ihnm_introproc.cpp b/engines/saga/ihnm_introproc.cpp
index e122082322..631da37e82 100644
--- a/engines/saga/ihnm_introproc.cpp
+++ b/engines/saga/ihnm_introproc.cpp
@@ -31,6 +31,7 @@
#include "saga/animation.h"
#include "saga/events.h"
#include "saga/interface.h"
+#include "saga/rscfile.h"
#include "saga/sndres.h"
#include "saga/music.h"
@@ -39,7 +40,7 @@
namespace Saga {
SceneResourceData IHNM_IntroMovie1RL[] = {
- {30, 2, 0, 0, false} ,
+ {30, 2, 0, 0, false},
{31, 14, 0, 0, false}
};
@@ -50,7 +51,7 @@ SceneDescription IHNM_IntroMovie1Desc = {
};
SceneResourceData IHNM_IntroMovie2RL[] = {
- {32, 2, 0, 0, false} ,
+ {32, 2, 0, 0, false},
{33, 14, 0, 0, false}
};
@@ -82,28 +83,100 @@ SceneDescription IHNM_IntroMovie4Desc = {
ARRAYSIZE(IHNM_IntroMovie4RL)
};
+// Demo
+SceneResourceData IHNMDEMO_IntroMovie1RL[] = {
+ {19, 2, 0, 0, false} // this scene doesn't have an animation
+};
+
+SceneDescription IHNMDEMO_IntroMovie1Desc = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ IHNMDEMO_IntroMovie1RL,
+ ARRAYSIZE(IHNMDEMO_IntroMovie1RL)
+};
+
+SceneResourceData IHNMDEMO_IntroMovie2RL[] = {
+ {22, 2, 0, 0, false},
+ {23, 14, 0, 0, false}
+};
+
+SceneDescription IHNMDEMO_IntroMovie2Desc = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ IHNMDEMO_IntroMovie2RL,
+ ARRAYSIZE(IHNMDEMO_IntroMovie2RL)
+};
+
LoadSceneParams IHNM_IntroList[] = {
{0, kLoadByDescription, &IHNM_IntroMovie1Desc, Scene::SC_IHNMIntroMovieProc1, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
{0, kLoadByDescription, &IHNM_IntroMovie2Desc, Scene::SC_IHNMIntroMovieProc2, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
{0, kLoadByDescription, &IHNM_IntroMovie3Desc, Scene::SC_IHNMIntroMovieProc3, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
};
+LoadSceneParams IHNMDEMO_IntroList[] = {
+ {0, kLoadByDescription, &IHNMDEMO_IntroMovie1Desc, Scene::SC_IHNMIntroMovieProc1, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
+ {0, kLoadByDescription, &IHNMDEMO_IntroMovie2Desc, Scene::SC_IHNMIntroMovieProc3, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
+};
+
+// IHNM cutaway intro resource IDs
+#define RID_IHNM_INTRO_CUTAWAYS 39
+#define RID_IHNMDEMO_INTRO_CUTAWAYS 25
+
int Scene::IHNMStartProc() {
size_t n_introscenes;
size_t i;
LoadSceneParams firstScene;
+ /*
+ // Test code - uses loadCutawayList to load the intro cutaways, like the original
+
+ ResourceContext *resourceContext;
+ //ResourceContext *soundContext;
+ byte *resourcePointer;
+ size_t resourceLength;
+
+ resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE);
+ if (resourceContext == NULL) {
+ error("Scene::IHNMStartProc() resource context not found");
+ }
+
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ _vm->_resource->loadResource(resourceContext, RID_IHNM_INTRO_CUTAWAYS, resourcePointer, resourceLength);
+ else
+ _vm->_resource->loadResource(resourceContext, RID_IHNMDEMO_INTRO_CUTAWAYS, resourcePointer, resourceLength);
+
+ if (resourceLength == 0) {
+ error("Scene::IHNMStartProc() Can't load cutaway list");
+ }
+
+ // Load the cutaways for the title screens
+ _vm->_anim->loadCutawayList(resourcePointer, resourceLength);
+
+ // Note that the resource ID needed is the returned ID minus one
+ printf("%i\n", _vm->_anim->cutawayResourceID(0));
+ printf("%i\n", _vm->_anim->cutawayResourceID(1));
+ printf("%i\n", _vm->_anim->cutawayResourceID(2));
+ */
+
// The original used the "play video" mechanism for the first part of
// the intro. We just use that panel mode.
_vm->_anim->setCutAwayMode(kPanelVideo);
_vm->_interface->setMode(kPanelVideo);
- n_introscenes = ARRAYSIZE(IHNM_IntroList);
-
- for (i = 0; i < n_introscenes; i++) {
- _vm->_scene->queueScene(&IHNM_IntroList[i]);
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ n_introscenes = ARRAYSIZE(IHNM_IntroList);
+ else
+ n_introscenes = ARRAYSIZE(IHNMDEMO_IntroList);
+
+ // Queue the company and title videos
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ for (i = 0; i < n_introscenes; i++) {
+ _vm->_scene->queueScene(&IHNM_IntroList[i]);
+ }
+ } else {
+ for (i = 0; i < n_introscenes; i++) {
+ _vm->_scene->queueScene(&IHNMDEMO_IntroList[i]);
+ }
}
firstScene.loadFlag = kLoadBySceneNumber;
@@ -140,16 +213,40 @@ int Scene::IHNMIntroMovieProc1(int param) {
q_event = _vm->_events->queue(&event);
- _vm->_anim->setFrameTime(0, IHNM_INTRO_FRAMETIME);
- _vm->_anim->setFlag(0, ANIM_FLAG_ENDSCENE);
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ _vm->_anim->setFrameTime(0, IHNM_INTRO_FRAMETIME);
+ _vm->_anim->setFlag(0, ANIM_FLAG_ENDSCENE);
- event.type = kEvTOneshot;
- event.code = kAnimEvent;
- event.op = kEventPlay;
- event.param = 0;
- event.time = 0;
+ event.type = kEvTOneshot;
+ event.code = kAnimEvent;
+ event.op = kEventPlay;
+ event.param = 0;
+ event.time = 0;
+
+ q_event = _vm->_events->chain(q_event, &event);
+ } else {
+ // Start playing the intro music for the demo version
+ event.type = kEvTOneshot;
+ event.code = kMusicEvent;
+ event.param = 1;
+ event.param2 = MUSIC_NORMAL;
+ event.op = kEventPlay;
+ event.time = 0;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ // The IHNM demo doesn't have an animation at the
+ // Cyberdreans logo screen
+
+ // Queue end of scene after a while
+ event.type = kEvTOneshot;
+ event.code = kSceneEvent;
+ event.op = kEventEnd;
+ event.time = 8000;
+
+ q_event = _vm->_events->chain(q_event, &event);
+ }
- q_event = _vm->_events->chain(q_event, &event);
break;
default:
break;
@@ -273,14 +370,16 @@ int Scene::IHNMIntroMovieProc3(int param) {
// In the GM file, this music also appears as tracks 7, 13, 19,
// 25 and 31, but only track 1 sounds right with the FM music.
- event.type = kEvTOneshot;
- event.code = kMusicEvent;
- event.param = 1;
- event.param2 = MUSIC_NORMAL;
- event.op = kEventPlay;
- event.time = 0;
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ event.type = kEvTOneshot;
+ event.code = kMusicEvent;
+ event.param = 1;
+ event.param2 = MUSIC_NORMAL;
+ event.op = kEventPlay;
+ event.time = 0;
- q_event = _vm->_events->chain(q_event, &event);
+ q_event = _vm->_events->chain(q_event, &event);
+ }
// Background for intro scene is the first frame of the intro
// animation; display it but don't set palette
@@ -317,7 +416,10 @@ int Scene::IHNMIntroMovieProc3(int param) {
event.type = kEvTOneshot;
event.code = kSceneEvent;
event.op = kEventEnd;
- event.time = _vm->_music->hasAdlib() ? IHNM_TITLE_TIME_FM : IHNM_TITLE_TIME_GM;
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ event.time = _vm->_music->hasAdlib() ? IHNM_TITLE_TIME_FM : IHNM_TITLE_TIME_GM;
+ else
+ event.time = 12000;
q_event = _vm->_events->chain(q_event, &event);
break;
diff --git a/engines/saga/image.cpp b/engines/saga/image.cpp
index f76258c565..9f72036634 100644
--- a/engines/saga/image.cpp
+++ b/engines/saga/image.cpp
@@ -24,6 +24,7 @@
*/
// SAGA Image resource management routines
+
#include "saga/saga.h"
#include "saga/stream.h"
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index 55b2b0a996..8cfd993391 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -337,13 +337,23 @@ int Interface::activate() {
_vm->_script->_skipSpeeches = false;
_vm->_actor->_protagonist->_targetObject = ID_NOTHING;
unlockMode();
- if (_panelMode == kPanelMain || _panelMode == kPanelChapterSelection){
+ if (_panelMode == kPanelMain || _panelMode == kPanelChapterSelection) {
+ _saveReminderState = 1;
+ } else if (_panelMode == kPanelNull && _vm->getGameId() == GID_IHNM_DEMO) {
_saveReminderState = 1;
}
draw();
}
- _vm->_gfx->showCursor(true);
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ _vm->_gfx->showCursor(true);
+ } else {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149) {
+ // Don't show the mouse cursor in the non-interactive part of the IHNM demo
+ } else {
+ _vm->_gfx->showCursor(true);
+ }
+ }
return SUCCESS;
}
@@ -359,18 +369,18 @@ int Interface::deactivate() {
}
void Interface::rememberMode() {
- assert (_savedMode == -1);
+ debug(1, "rememberMode(%d)", _savedMode);
_savedMode = _panelMode;
-
- debug(1, "rememberMode(%d)", _savedMode);
}
void Interface::restoreMode(bool draw_) {
- assert (_savedMode != -1);
-
debug(1, "restoreMode(%d)", _savedMode);
+ // If _savedMode is -1 by a race condition, set it to kPanelMain
+ if (_savedMode == -1)
+ _savedMode = kPanelMain;
+
_panelMode = _savedMode;
_savedMode = -1;
@@ -386,10 +396,23 @@ void Interface::setMode(int mode) {
_saveReminderState = 1; //TODO: blinking timeout
} else if (mode == kPanelChapterSelection) {
_saveReminderState = 1;
+ } else if (mode == kPanelNull) {
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ _inMainMode = true;
+ _saveReminderState = 1;
+ if ((_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149) ||
+ _vm->_scene->currentSceneNumber() == 0 || _vm->_scene->currentSceneNumber() == -1)
+ _vm->_gfx->showCursor(false);
+ }
+ } else if (mode == kPanelOption) {
+ // Show the cursor in the IHNM demo
+ if (_vm->getGameId() == GID_IHNM_DEMO)
+ _vm->_gfx->showCursor(true);
} else {
if (mode == kPanelConverse) {
_inMainMode = false;
}
+
_saveReminderState = 0;
}
@@ -440,12 +463,18 @@ void Interface::setMode(int mode) {
_vm->_render->setFlag(RF_DEMO_SUBST);
break;
case kPanelProtect:
- _protectPanel.currentButton = NULL;
- _textInputMaxWidth = _protectEdit->width - 10;
- _textInput = true;
- _textInputString[0] = 0;
- _textInputStringLength = 0;
- _textInputPos = _textInputStringLength + 1;
+ if (_vm->getGameType() == GType_ITE) {
+ // This is used as the copy protection panel in ITE
+ _protectPanel.currentButton = NULL;
+ _textInputMaxWidth = _protectEdit->width - 10;
+ _textInput = true;
+ _textInputString[0] = 0;
+ _textInputStringLength = 0;
+ _textInputPos = _textInputStringLength + 1;
+ } else {
+ // In the IHNM demo, this panel mode is set by the scripts
+ // to flip through the pages of the help system
+ }
break;
}
@@ -476,6 +505,11 @@ bool Interface::processAscii(uint16 ascii) {
}
return true;
}
+
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ _vm->_scene->showIHNMDemoSpecialScreen();
+ }
break;
case kPanelCutaway:
if (ascii == 27) { // Esc
@@ -484,6 +518,11 @@ bool Interface::processAscii(uint16 ascii) {
_vm->_scene->cutawaySkip();
return true;
}
+
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ _vm->_scene->showIHNMDemoSpecialScreen();
+ }
break;
case kPanelVideo:
if (ascii == 27) { // Esc
@@ -494,6 +533,12 @@ bool Interface::processAscii(uint16 ascii) {
_vm->_actor->abortAllSpeeches();
}
_vm->_scene->cutawaySkip();
+ return true;
+ }
+
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ _vm->_scene->showIHNMDemoSpecialScreen();
}
break;
case kPanelOption:
@@ -632,18 +677,35 @@ bool Interface::processAscii(uint16 ascii) {
keyBossExit();
break;
case kPanelProtect:
- if (_textInput && processTextInput(ascii)) {
- return true;
- }
+ if (_vm->getGameType() == GType_ITE) {
+ if (_textInput && processTextInput(ascii)) {
+ return true;
+ }
- if (ascii == 27 || ascii == 13) { // Esc or Enter
- _vm->_script->wakeUpThreads(kWaitTypeRequest);
- _vm->_interface->setMode(kPanelMain);
-
- _protectHash = 0;
+ if (ascii == 27 || ascii == 13) { // Esc or Enter
+ _vm->_script->wakeUpThreads(kWaitTypeRequest);
+ _vm->_interface->setMode(kPanelMain);
+
+ _protectHash = 0;
- for (char *p = _textInputString; *p; p++)
- _protectHash = (_protectHash << 1) + toupper(*p);
+ for (char *p = _textInputString; *p; p++)
+ _protectHash = (_protectHash << 1) + toupper(*p);
+ }
+ } else {
+ // In the IHNM demo, this panel mode is set by the scripts
+ // to flip through the pages of the help system
+ }
+ break;
+ case kPanelPlacard:
+ if (_vm->getGameType() == GType_IHNM) {
+ // Any keypress here returns the user back to the game
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ _vm->_scene->clearPsychicProfile();
+ } else {
+ setMode(kPanelConverse);
+ _vm->_scene->_textList.clear();
+ _vm->_script->wakeUpThreads(kWaitTypeDelay);
+ }
}
break;
}
@@ -656,6 +718,10 @@ void Interface::setStatusText(const char *text, int statusColor) {
if (_vm->getGameType() == GType_IHNM && _vm->_scene->currentChapterNumber() == 8)
return;
+ // Disable the status text in the introduction of the IHNM demo
+ if (_vm->getGameId() == GID_IHNM_DEMO && _vm->_scene->currentSceneNumber() == 0)
+ return;
+
assert(text != NULL);
assert(strlen(text) < STATUS_TEXT_LEN);
@@ -719,7 +785,8 @@ void Interface::draw() {
drawStatusBar();
- if (_panelMode == kPanelMain || _panelMode == kPanelMap) {
+ if (_panelMode == kPanelMain || _panelMode == kPanelMap ||
+ (_panelMode == kPanelNull && _vm->getGameId() == GID_IHNM_DEMO)) {
_mainPanel.getRect(rect);
backBuffer->blit(rect, _mainPanel.image);
@@ -745,7 +812,8 @@ void Interface::draw() {
}
if (_panelMode == kPanelMain || _panelMode == kPanelConverse ||
- _lockedMode == kPanelMain || _lockedMode == kPanelConverse) {
+ _lockedMode == kPanelMain || _lockedMode == kPanelConverse ||
+ (_panelMode == kPanelNull && _vm->getGameId() == GID_IHNM_DEMO)) {
leftPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().leftPortraitXOffset;
leftPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().leftPortraitYOffset;
_vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _defPortraits, _leftPortrait, leftPortraitPoint, 256);
@@ -1467,10 +1535,20 @@ void Interface::setOption(PanelButton *panelButton) {
switch (panelButton->id) {
case kTextContinuePlaying:
ConfMan.flushToDisk();
- if (!(_vm->getGameType() == GType_IHNM && _vm->_scene->currentChapterNumber() == 8))
+ if (_vm->getGameType() == GType_ITE) {
setMode(kPanelMain);
- else
- setMode(kPanelChapterSelection);
+ } else {
+ if (_vm->_scene->currentChapterNumber() == 8) {
+ setMode(kPanelChapterSelection);
+ } else if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ setMode(kPanelNull);
+ else
+ setMode(kPanelMain);
+ } else {
+ setMode(kPanelMain);
+ }
+ }
break;
case kTextQuitGame:
setMode(kPanelQuit);
@@ -1486,6 +1564,12 @@ void Interface::setOption(PanelButton *panelButton) {
}
break;
case kTextSave:
+ // Disallow saving in the non-interactive part of the IHNM demo
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ return;
+ }
+
if (!_vm->isSaveListFull() && (_optionSaveFileTitleNumber == 0)) {
_textInputString[0] = 0;
} else {
@@ -1536,7 +1620,12 @@ void Interface::update(const Point& mousePoint, int updateFlag) {
_vm->_actor->abortSpeech();
if (_vm->_scene->isInIntro() || _fadeMode == kFadeOut || !_active) {
- return;
+ // When opening the psychic profile, or the options screen in the non-interactive part of the IHNM demo,
+ // the interface is locked (_active is false)
+ // Don't return in those cases, so that mouse actions can be processed
+ if (!(_vm->getGameType() == GType_IHNM && _panelMode == kPanelPlacard && (updateFlag & UPDATE_MOUSECLICK)) &&
+ !(_vm->getGameId() == GID_IHNM_DEMO && (_panelMode == kPanelOption || _panelMode == kPanelQuit)))
+ return;
}
if (_statusTextInput) {
@@ -1682,6 +1771,27 @@ void Interface::update(const Point& mousePoint, int updateFlag) {
// No mouse interaction
break;
+ case kPanelPlacard:
+ if (_vm->getGameType() == GType_IHNM) {
+ // Any mouse click here returns the user back to the game
+ if (updateFlag & UPDATE_MOUSECLICK) {
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ _vm->_scene->clearPsychicProfile();
+ } else {
+ setMode(kPanelConverse);
+ _vm->_scene->_textList.clear();
+ _vm->_script->wakeUpThreads(kWaitTypeDelay);
+ }
+ }
+ }
+ break;
+
+ case kPanelNull:
+ if (_vm->getGameId() == GID_IHNM_DEMO && (updateFlag & UPDATE_MOUSECLICK)) {
+ if (_vm->_scene->currentSceneNumber() >= 144 && _vm->_scene->currentSceneNumber() <= 149)
+ _vm->_scene->showIHNMDemoSpecialScreen();
+ }
+ break;
}
_lastMousePoint = mousePoint;
@@ -2016,10 +2126,10 @@ void Interface::drawButtonBox(Surface *ds, const Rect& rect, ButtonKind kind, bo
((byte *)ds->getBasePtr(x, ye))[0] = cornerColor;
((byte *)ds->getBasePtr(xe, y))[0] = cornerColor;
((byte *)ds->getBasePtr(xe, ye))[0] = cornerColor;
- ds->hLine(x + 1, y, x + 1 + w - 2, frameColor);
- ds->hLine(x + 1, ye, x + 1 + w - 2, frameColor);
- ds->vLine(x, y + 1, y + 1 + h - 2, frameColor);
- ds->vLine(xe, y + 1, y + 1 + h - 2, frameColor);
+ ds->hLine(x + 1, y, x + w - 2, frameColor);
+ ds->hLine(x + 1, ye, x + w - 2, frameColor);
+ ds->vLine(x, y + 1, y + h - 2, frameColor);
+ ds->vLine(xe, y + 1, y + h - 2, frameColor);
x++;
y++;
@@ -2029,7 +2139,7 @@ void Interface::drawButtonBox(Surface *ds, const Rect& rect, ButtonKind kind, bo
h -= 2;
ds->vLine(x, y, y + h - 1, odl);
ds->hLine(x, ye, x + w - 1, odl);
- ds->vLine(xe, y, y + h - 1, our);
+ ds->vLine(xe, y, y + h - 2, our);
ds->hLine(x + 1, y, x + 1 + w - 2, our);
x++;
@@ -2042,7 +2152,7 @@ void Interface::drawButtonBox(Surface *ds, const Rect& rect, ButtonKind kind, bo
((byte *)ds->getBasePtr(xe, ye))[0] = fillColor;
ds->vLine(x, y + 1, y + 1 + h - 2, idl);
ds->hLine(x + 1, ye, x + 1 + w - 2, idl);
- ds->vLine(xe, y, y + h - 1, iur);
+ ds->vLine(xe, y, y + h - 2, iur);
ds->hLine(x + 1, y, x + 1 + w - 2, iur);
x++; y++;
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index 124242204b..4f635c6e3b 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -24,6 +24,7 @@
*/
// Isometric level module
+
#include "saga/saga.h"
#include "saga/gfx.h"
@@ -1609,6 +1610,7 @@ void IsoMap::findTilePath(ActorData* actor, const Location &start, const Locatio
/* if (i > 64) {
i = 64;
}*/
+
actor->_walkStepsCount = i;
if (i) {
actor->setTileDirectionsSize(i, false);
diff --git a/engines/saga/ite_introproc.cpp b/engines/saga/ite_introproc.cpp
index ec4d07c069..1664969644 100644
--- a/engines/saga/ite_introproc.cpp
+++ b/engines/saga/ite_introproc.cpp
@@ -23,7 +23,6 @@
*
*/
-
// Intro sequence scene procedures
#include "saga/saga.h"
diff --git a/engines/saga/list.h b/engines/saga/list.h
index 28159475c3..1363155f43 100644
--- a/engines/saga/list.h
+++ b/engines/saga/list.h
@@ -23,6 +23,8 @@
*
*/
+// List functions
+
#ifndef SAGA_LIST_H
#define SAGA_LIST_H
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 71b6964530..04e79c174d 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -22,6 +22,9 @@
* $Id$
*
*/
+
+// MIDI and digital music class
+
#include "saga/saga.h"
#include "saga/rscfile.h"
@@ -38,14 +41,12 @@ namespace Saga {
#define BUFFER_SIZE 4096
-// I haven't decided yet if it's a good idea to make looping part of the audio
-// stream class, or if I should use a "wrapper" class, like I did for Broken
-// Sword 2, to make it easier to add support for compressed music... but I'll
-// worry about that later.
-
-class RAWInputStream : public Audio::AudioStream {
+class DigitalMusicInputStream : public Audio::AudioStream {
private:
+ Audio::AudioStream *_compressedStream;
ResourceContext *_context;
+ ResourceData * resourceData;
+ GameSoundTypes soundType;
Common::File *_file;
uint32 _filePos;
uint32 _startPos;
@@ -56,6 +57,7 @@ private:
const int16 *_bufferEnd;
const int16 *_pos;
const GameSoundInfo *_musicInfo;
+ Common::MemoryReadStream *_memoryStream;
void refill();
bool eosIntern() const {
@@ -63,7 +65,10 @@ private:
}
public:
- RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart);
+ DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart);
+ ~DigitalMusicInputStream();
+
+ void createCompressedStream();
int readBuffer(int16 *buffer, const int numSamples);
@@ -72,17 +77,36 @@ public:
int getRate() const { return _musicInfo->frequency; }
};
-RAWInputStream::RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart)
+DigitalMusicInputStream::DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart)
: _context(context), _finished(false), _looping(looping), _bufferEnd(_buf + BUFFER_SIZE) {
- ResourceData * resourceData;
+ byte compressedHeader[10];
resourceData = vm->_resource->getResourceData(context, resourceId);
_file = context->getFile(resourceData);
_musicInfo = vm->getMusicInfo();
if (_musicInfo == NULL) {
- error("RAWInputStream() wrong musicInfo");
+ error("DigitalMusicInputStream() wrong musicInfo");
+ }
+
+ _compressedStream = NULL;
+
+ if (Common::File::exists("music.cmp")) {
+ // Read compressed header to determine compression type
+ _file->seek((long)resourceData->offset, SEEK_SET);
+ _file->read(compressedHeader, 9);
+
+ if (compressedHeader[0] == char(0)) {
+ soundType = kSoundMP3;
+ } else if (compressedHeader[0] == char(1)) {
+ soundType = kSoundOGG;
+ } else if (compressedHeader[0] == char(2)) {
+ soundType = kSoundFLAC;
+ }
+
+ createCompressedStream();
+ resourceData->offset += 9; // Skip compressed header
}
// Determine the end position
@@ -96,22 +120,59 @@ RAWInputStream::RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32
refill();
}
-int RAWInputStream::readBuffer(int16 *buffer, const int numSamples) {
+DigitalMusicInputStream::~DigitalMusicInputStream() {
+ delete _compressedStream;
+}
+
+void DigitalMusicInputStream::createCompressedStream() {
+ uint numLoops = _looping ? 0 : 1;
+ _memoryStream = _file->readStream(resourceData->size);
+
+ switch (soundType) {
+#ifdef USE_MAD
+ case kSoundMP3:
+ debug(1, "Playing MP3 compressed digital music");
+ _compressedStream = Audio::makeMP3Stream(_memoryStream, true, 0, 0, numLoops);
+ break;
+#endif
+#ifdef USE_VORBIS
+ case kSoundOGG:
+ debug(1, "Playing OGG compressed digital music");
+ _compressedStream = Audio::makeVorbisStream(_memoryStream, true, 0, 0, numLoops);
+ break;
+#endif
+#ifdef USE_FLAC
+ case kSoundFLAC:
+ debug(1, "Playing FLAC compressed digital music");
+ _compressedStream = Audio::makeFlacStream(_memoryStream, true, 0, 0, numLoops);
+ break;
+#endif
+ default:
+ // Unknown compression
+ error("Trying to play a compressed digital music, but the compression is not known");
+ break;
+ }
+}
+
+int DigitalMusicInputStream::readBuffer(int16 *buffer, const int numSamples) {
+ if (_compressedStream != NULL)
+ return _compressedStream->readBuffer(buffer, numSamples);
+
int samples = 0;
while (samples < numSamples && !eosIntern()) {
- const int len = MIN(numSamples - samples, (int) (_bufferEnd - _pos));
+ int len = 0;
+ len = MIN(numSamples - samples, (int) (_bufferEnd - _pos));
memcpy(buffer, _pos, len * 2);
buffer += len;
_pos += len;
samples += len;
- if (_pos >= _bufferEnd) {
+ if (_pos >= _bufferEnd)
refill();
- }
}
return samples;
}
-void RAWInputStream::refill() {
+void DigitalMusicInputStream::refill() {
if (_finished)
return;
@@ -282,7 +343,7 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enable
xmidiParser = MidiParser::createParser_XMIDI();
smfParser = MidiParser::createParser_SMF();
- _musicContext = _vm->_resource->getContext(GAME_MUSICFILE);
+ _digitalMusicContext = _vm->_resource->getContext(GAME_MUSICFILE);
_songTableLen = 0;
_songTable = 0;
@@ -373,6 +434,10 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
_player->stopMusic();
_mixer->stopHandle(_musicHandle);
+ if (!_vm->_musicVolume) {
+ return;
+ }
+
int realTrackNumber;
if (_vm->getGameType() == GType_ITE) {
@@ -405,7 +470,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
if (_vm->getGameType() == GType_ITE) {
if (resourceId >= 9 && resourceId <= 34) {
- if (_musicContext != NULL) {
+ if (_digitalMusicContext != NULL) {
//TODO: check resource size
loopStart = 0;
// fix ITE sunstatm score
@@ -413,61 +478,8 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
loopStart = 4 * 18727;
}
- if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS)) {
- // uncompressed digital music
- audioStream = new RAWInputStream(_vm, _musicContext, resourceId - 9, flags == MUSIC_LOOP, loopStart);
- } else {
- // compressed digital music
- ResourceData * musicResourceData;
- Common::File *_file;
- byte compressedHeader[10];
- GameSoundTypes soundType;
-
- musicResourceData = _vm->_resource->getResourceData(_musicContext, resourceId - 9);
- _file = _musicContext->getFile(musicResourceData);
-
- if (_vm->getMusicInfo() == NULL) {
- error("RAWInputStream() wrong musicInfo");
- }
-
- _file->seek((long)musicResourceData->offset, SEEK_SET);
-
- _file->read(compressedHeader, 9);
-
- if (compressedHeader[0] == char(0)) {
- soundType = kSoundMP3;
- } else if (compressedHeader[0] == char(1)) {
- soundType = kSoundOGG;
- } else if (compressedHeader[0] == char(2)) {
- soundType = kSoundFLAC;
- }
-
- switch (soundType) {
-#ifdef USE_MAD
- case kSoundMP3:
- debug(1, "Playing MP3 compressed digital music");
- audioStream = Audio::makeMP3Stream(_file, musicResourceData->size);
- break;
-#endif
-#ifdef USE_VORBIS
- case kSoundOGG:
- debug(1, "Playing OGG compressed digital music");
- audioStream = Audio::makeVorbisStream(_file, musicResourceData->size);
- break;
-#endif
-#ifdef USE_FLAC
- case kSoundFLAC:
- debug(1, "Playing FLAC compressed digital music");
- audioStream = Audio::makeFlacStream(_file, musicResourceData->size);
- break;
-#endif
- default:
- // Unknown compression
- error("Trying to play a compressed digital music, but the compression is not known");
- break;
- }
-
- }
+ // digital music
+ audioStream = new DigitalMusicInputStream(_vm, _digitalMusicContext, resourceId - 9, flags == MUSIC_LOOP, loopStart);
}
}
}
@@ -512,8 +524,10 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
// Oddly enough, the intro music (song 1) is very
// different in the two files. I have no idea why.
+ // Note that the IHNM demo has only got one music file
+ // (music.rsc). It is assumed that it contains FM music
- if (hasAdlib()) {
+ if (hasAdlib() || _vm->getGameId() == GID_IHNM_DEMO) {
context = _vm->_resource->getContext(GAME_MUSICFILE_FM);
} else {
context = _vm->_resource->getContext(GAME_MUSICFILE_GM);
diff --git a/engines/saga/music.h b/engines/saga/music.h
index 96d8608bcd..b038a25a11 100644
--- a/engines/saga/music.h
+++ b/engines/saga/music.h
@@ -137,7 +137,7 @@ private:
int _currentVolume;
int _currentVolumePercent;
- ResourceContext *_musicContext;
+ ResourceContext *_digitalMusicContext;
MidiParser *xmidiParser;
MidiParser *smfParser;
diff --git a/engines/saga/objectmap.cpp b/engines/saga/objectmap.cpp
index 52f2e89be7..9e633a6709 100644
--- a/engines/saga/objectmap.cpp
+++ b/engines/saga/objectmap.cpp
@@ -28,6 +28,7 @@
// Polygon Hit Test code ( HitTestPoly() ) adapted from code (C) Eric Haines
// appearing in Graphics Gems IV, "Point in Polygon Strategies."
// p. 24-46, code: p. 34-45
+
#include "saga/saga.h"
#include "saga/gfx.h"
diff --git a/engines/saga/puzzle.h b/engines/saga/puzzle.h
index 92bf73e2a0..3713cbaab7 100644
--- a/engines/saga/puzzle.h
+++ b/engines/saga/puzzle.h
@@ -23,6 +23,8 @@
*
*/
+// ITE puzzle scene
+
#ifndef SAGA_PUZZLE_H
#define SAGA_PUZZLE_H
diff --git a/engines/saga/render.cpp b/engines/saga/render.cpp
index 16536f762e..930476b4e2 100644
--- a/engines/saga/render.cpp
+++ b/engines/saga/render.cpp
@@ -24,6 +24,7 @@
*/
// Main rendering loop
+
#include "saga/saga.h"
#include "saga/actor.h"
diff --git a/engines/saga/rscfile.cpp b/engines/saga/rscfile.cpp
index 33e8a7d603..4d3ff1e47c 100644
--- a/engines/saga/rscfile.cpp
+++ b/engines/saga/rscfile.cpp
@@ -24,6 +24,7 @@
*/
// RSC Resource file management module
+
#include "saga/saga.h"
#include "saga/actor.h"
@@ -329,6 +330,7 @@ bool Resource::loadContext(ResourceContext *context) {
if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {
resourceData->offset = 0;
resourceData->size = resourceData->patchData->_patchFile->size();
+ resourceData->patchData->_patchFile->close();
} else {
delete resourceData->patchData;
resourceData->patchData = NULL;
@@ -343,18 +345,188 @@ bool Resource::loadContext(ResourceContext *context) {
bool Resource::createContexts() {
int i;
ResourceContext *context;
+ char musicFileName[256];
+ char soundFileName[256];
+ char voicesFileName[256];
+ int soundFileIndex = 0;
+ int voicesFileIndex = 0;
+ bool digitalMusic = false;
+ bool soundFileInArray = false;
+ bool voicesFileInArray = false;
+ bool multipleVoices = false;
+ bool censoredVersion = false;
+ uint16 voiceFileType = GAME_VOICEFILE;
_contextsCount = 0;
- for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++)
+ for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {
_contextsCount++;
+ if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE)
+ soundFileInArray = true;
+ if (_vm->getFilesDescriptions()[i].fileType == GAME_VOICEFILE)
+ voicesFileInArray = true;
+ }
+
+ if (!soundFileInArray) {
+ if (_vm->getGameType() == GType_ITE) {
+ // If the sound file is not specified in the detector table, add it here
+ if (Common::File::exists("sounds.rsc") || Common::File::exists("sounds.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "sounds.cmp");
+ else
+ sprintf(soundFileName, "sounds.rsc");
+ } else if (Common::File::exists("soundsd.rsc") || Common::File::exists("soundsd.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "soundsd.cmp");
+ else
+ sprintf(soundFileName, "soundsd.rsc");
+ } else {
+ // No sound file found, don't add any file to the array
+ soundFileInArray = true;
+ // ITE floppy versions have both voices and sounds in voices.rsc
+ voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE;
+ }
+ } else {
+ // If the sound file is not specified in the detector table, add it here
+ if (Common::File::exists("sfx.res") || Common::File::exists("sfx.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "sfx.cmp");
+ else
+ sprintf(soundFileName, "sfx.res");
+ } else {
+ // No sound file found, don't add any file to the array
+ soundFileInArray = true;
+ }
+ }
+ }
+
+ if (!voicesFileInArray) {
+ if (_vm->getGameType() == GType_ITE) {
+ // If the voices file is not specified in the detector table, add it here
+ if (Common::File::exists("voices.rsc") || Common::File::exists("voices.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voices.cmp");
+ else
+ sprintf(voicesFileName, "voices.rsc");
+ } else if (Common::File::exists("voicesd.rsc") || Common::File::exists("voicesd.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicesd.cmp");
+ else
+ sprintf(voicesFileName, "voicesd.rsc");
+ } else if (Common::File::exists("inherit the earth voices") ||
+ Common::File::exists("inherit the earth voices.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "inherit the earth voices.cmp");
+ else
+ sprintf(voicesFileName, "inherit the earth voices");
+ // The resources in the Wyrmkeep combined Windows/Mac/Linux CD version are little endian, but
+ // the voice file is big endian. If we got such a version with mixed files, mark this voice file
+ // as big endian
+ if (!_vm->isBigEndian())
+ voiceFileType = GAME_VOICEFILE | GAME_SWAPENDIAN; // This file is big endian
+ } else {
+ // No voice file found, don't add any file to the array
+ voicesFileInArray = true;
+ }
+ } else {
+ // If the voices file is not specified in the detector table, add it here
+ if (Common::File::exists("voicess.res") || Common::File::exists("voicess.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ // IHNM has multiple voice files
+ multipleVoices = true;
+ // Note: it is assumed that the voices are always last in the list
+ if (Common::File::exists("voices4.res") || Common::File::exists("voices4.cmp")) {
+ _contextsCount += 6; // voices1-voices6
+ } else {
+ // The German and French versions of IHNM don't have Nimdok's chapter, therefore the voices file
+ // for that chapter is missing
+ _contextsCount += 5; // voices1-voices3, voices4-voices5
+ censoredVersion = true;
+ }
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicess.cmp");
+ else
+ sprintf(voicesFileName, "voicess.res");
+ } else if (Common::File::exists("voicesd.res") || Common::File::exists("voicesd.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicesd.cmp");
+ else
+ sprintf(voicesFileName, "voicesd.res");
+ } else {
+ // No voice file found, don't add any file to the array
+ voicesFileInArray = true;
+ }
+ }
+ }
+
+ if (_vm->getGameType() == GType_ITE) {
+ // Check for digital music in ITE
+ if (Common::File::exists("music.rsc") || Common::File::exists("music.cmp")) {
+ _contextsCount++;
+ digitalMusic = true;
+ if (Common::File::exists("music.cmp"))
+ sprintf(musicFileName, "music.cmp");
+ else
+ sprintf(musicFileName, "music.rsc");
+ } else if (Common::File::exists("musicd.rsc") || Common::File::exists("musicd.cmp")) {
+ _contextsCount++;
+ digitalMusic = true;
+ if (Common::File::exists("musicd.cmp"))
+ sprintf(musicFileName, "musicd.cmp");
+ else
+ sprintf(musicFileName, "musicd.rsc");
+ } else {
+ digitalMusic = false;
+ }
+ }
_contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));
for (i = 0; i < _contextsCount; i++) {
context = &_contexts[i];
context->file = new Common::File();
- context->fileName = _vm->getFilesDescriptions()[i].fileName;
- context->fileType = _vm->getFilesDescriptions()[i].fileType;
+
+ // For ITE, add the digital music file and sfx file information here
+ if (_vm->getGameType() == GType_ITE && digitalMusic && i == _contextsCount - 1) {
+ context->fileName = musicFileName;
+ context->fileType = GAME_MUSICFILE;
+ } else if (!soundFileInArray && i == soundFileIndex) {
+ context->fileName = soundFileName;
+ context->fileType = GAME_SOUNDFILE;
+ } else if (!voicesFileInArray && i == voicesFileIndex) {
+ context->fileName = voicesFileName;
+ // can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN
+ context->fileType = voiceFileType;
+ } else {
+ if (!(!voicesFileInArray && multipleVoices && (i > voicesFileIndex))) {
+ context->fileName = _vm->getFilesDescriptions()[i].fileName;
+ context->fileType = _vm->getFilesDescriptions()[i].fileType;
+ } else {
+ int token = (censoredVersion && (i - voicesFileIndex >= 4)) ? 1 : 0; // censored versions don't have voice4
+
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voices%i.cmp", i - voicesFileIndex + token);
+ else
+ sprintf(voicesFileName, "voices%i.res", i - voicesFileIndex + token);
+
+ context->fileName = voicesFileName;
+ context->fileType = GAME_VOICEFILE;
+ }
+ }
context->serial = 0;
// IHNM has serveral different voice files, so we need to allow
@@ -434,13 +606,20 @@ void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&r
if (file->read(resourceBuffer, resourceSize) != resourceSize) {
error("Resource::loadResource() failed to read");
}
+ if (resourceData->patchData != NULL)
+ file->close();
}
static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 };
+static int metaResourceTableDemo[] = { 0, 0, 0, 0, 0, 0, 0, 285, 0 };
void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
- if (chapter < 0)
- chapter = 8;
+ if (chapter < 0) {
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ chapter = 8;
+ else
+ chapter = 7;
+ }
// TODO
//if (module.voiceLUT)
@@ -465,8 +644,13 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
byte *resourcePointer;
size_t resourceLength;
- _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter],
- resourcePointer, resourceLength);
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter],
+ resourcePointer, resourceLength);
+ } else {
+ _vm->_resource->loadResource(resourceContext, metaResourceTableDemo[chapter],
+ resourcePointer, resourceLength);
+ }
if (resourceLength == 0) {
error("Resource::loadGlobalResources wrong metaResource");
@@ -555,22 +739,27 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
_vm->_anim->loadCutawayList(resourcePointer, resourceLength);
- _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
+ if (_metaResource.songTableID > 0) {
+ _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources Can't load songs list for current track");
- }
+ if (resourceLength == 0) {
+ error("Resource::loadGlobalResources Can't load songs list for current track");
+ }
- free(_vm->_music->_songTable);
-
- _vm->_music->_songTableLen = resourceLength / 4;
- _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen);
+ free(_vm->_music->_songTable);
+
+ _vm->_music->_songTableLen = resourceLength / 4;
+ _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen);
- MemoryReadStream songS(resourcePointer, resourceLength);
+ MemoryReadStream songS(resourcePointer, resourceLength);
- for (i = 0; i < _vm->_music->_songTableLen; i++)
- _vm->_music->_songTable[i] = songS.readSint32LE();
- free(resourcePointer);
+ for (i = 0; i < _vm->_music->_songTableLen; i++)
+ _vm->_music->_songTable[i] = songS.readSint32LE();
+ free(resourcePointer);
+ } else {
+ // The IHNM demo has a fixed music track and doesn't load a song table
+ _vm->_music->play(3, MUSIC_LOOP);
+ }
int voiceLUTResourceID = 0;
@@ -602,6 +791,9 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
voiceLUTResourceID = 28;
break;
case 7:
+ // IHNM demo
+ _vm->_sndRes->setVoiceBank(0);
+ voiceLUTResourceID = 17;
break;
case 8:
_vm->_sndRes->setVoiceBank(0);
diff --git a/engines/saga/rscfile.h b/engines/saga/rscfile.h
index f8b6ddc3be..2df3b2eb7c 100644
--- a/engines/saga/rscfile.h
+++ b/engines/saga/rscfile.h
@@ -83,6 +83,8 @@ struct ResourceContext {
Common::File *getFile(ResourceData *resourceData) const {
if (resourceData->patchData != NULL) {
+ if (!resourceData->patchData->_patchFile->isOpen())
+ resourceData->patchData->_patchFile->open(resourceData->patchData->_patchDescription->fileName);
return resourceData->patchData->_patchFile;
} else {
return file;
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 99462c5583..76731c201a 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -107,7 +107,6 @@ SagaEngine::SagaEngine(OSystem *syst)
// Mac CD Wyrmkeep
Common::File::addDefaultDirectory(_gameDataPath + "patch/");
-
// Setup mixer
if (!_mixer->isReady()) {
warning("Sound initialization failed.");
@@ -150,6 +149,8 @@ int SagaEngine::init() {
_subtitlesEnabled = ConfMan.getBool("subtitles");
_readingSpeed = getTalkspeed();
_copyProtection = ConfMan.getBool("copy_protection");
+ _gf_wyrmkeep = false;
+ _gf_compressed_sounds = false;
if (_readingSpeed > 3)
_readingSpeed = 0;
@@ -454,6 +455,9 @@ ColorId SagaEngine::KnownColor2ColorId(KnownColor knownColor) {
colorId = kITEColorTransBlack;
break;
+ case (kKnownColorBrightWhite):
+ colorId = kITEColorBrightWhite;
+ break;
case (kKnownColorBlack):
colorId = kIHNMColorBlack;
break;
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index 844a738418..43952fe564 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -301,6 +301,7 @@ struct GameResourceDescription {
uint32 mainPanelSpritesResourceId;
uint32 optionPanelSpritesResourceId;
uint32 defaultPortraitsResourceId;
+ uint32 psychicProfileResourceId;
uint32 mainStringsResourceId;
uint32 actorsStringsResourceId;
};
@@ -527,6 +528,8 @@ public:
int _readingSpeed;
bool _copyProtection;
+ bool _gf_wyrmkeep;
+ bool _gf_compressed_sounds;
SndRes *_sndRes;
Sound *_sound;
@@ -548,7 +551,7 @@ public:
Resource *_resource;
- /** Random number generator */
+ // Random number generator
Common::RandomSource _rnd;
private:
diff --git a/engines/saga/sagaresnames.h b/engines/saga/sagaresnames.h
index 94f97635c1..761ac1ab68 100644
--- a/engines/saga/sagaresnames.h
+++ b/engines/saga/sagaresnames.h
@@ -45,8 +45,9 @@ namespace Saga {
#define RID_IHNMDEMO_SCENE_LUT 286
#define RID_IHNMDEMO_SCRIPT_LUT 18
+#define RID_IHNMDEMO_SFX_LUT 222
-//obj names
+// Object names
#define ITE_OBJ_MAP 14
#define ITE_OBJ_MAGIC_HAT 0
@@ -54,10 +55,10 @@ namespace Saga {
#define RID_IHNM_DEFAULT_PALETTE 1
-//actor names
+// Actor names
#define ITE_ACTOR_PUZZLE 176
-// SCENES
+// Scenes
#define ITE_SCENE_INV -1
#define ITE_SCENE_PUZZLE 26
#define ITE_SCENE_LODGE 21
@@ -67,13 +68,14 @@ namespace Saga {
#define IHNM_DEFAULT_SCENE 151
#define ITEDEMO_DEFAULT_SCENE 68
+#define IHNMDEMO_DEFAULT_SCENE 144
-// FONTS
+// Fonts
#define RID_MEDIUM_FONT 0
#define RID_BIG_FONT 1
#define RID_SMALL_FONT 2
-// INTERFACE IMAGES
+// Interface images
#define RID_ITE_MAIN_PANEL 3
#define RID_ITE_CONVERSE_PANEL 4
#define RID_ITE_OPTION_PANEL 5
@@ -99,7 +101,7 @@ namespace Saga {
#define RID_IHNM_MAIN_PANEL 9
#define RID_IHNM_CONVERSE_PANEL 10
#define RID_IHNM_HOURGLASS_CURSOR 11
-#define RID_IHNM_MAIN_SPRITES 12 // TODO: verify this
+#define RID_IHNM_MAIN_SPRITES 12
#define RID_IHNM_MAIN_PANEL_SPRITES 12
#define RID_IHNM_ARROW_SPRITES 13
#define RID_IHNM_SAVEREMINDER_SPRITES 14
@@ -110,6 +112,20 @@ namespace Saga {
#define RID_IHNM_PROFILE_BG 20
#define RID_IHNM_MAIN_STRINGS 21
+#define RID_IHNMDEMO_MAIN_PANEL 5
+#define RID_IHNMDEMO_CONVERSE_PANEL 6
+#define RID_IHNMDEMO_HOURGLASS_CURSOR 6 // Does not exist in the demo
+#define RID_IHNMDEMO_MAIN_SPRITES 7
+#define RID_IHNMDEMO_MAIN_PANEL_SPRITES 7
+#define RID_IHNMDEMO_ARROW_SPRITES 8
+#define RID_IHNMDEMO_SAVEREMINDER_SPRITES 9
+#define RID_IHNMDEMO_OPTION_PANEL 10
+#define RID_IHNMDEMO_OPTION_PANEL_SPRITES 11
+#define RID_IHNMDEMO_WARNING_PANEL 12
+#define RID_IHNMDEMO_BOSS_SCREEN 13 // Does not exist in the demo
+#define RID_IHNMDEMO_PROFILE_BG 15
+#define RID_IHNMDEMO_MAIN_STRINGS 16
+
// Puzzle portraits
#define RID_ITE_SAKKA_APPRAISING 6
#define RID_ITE_SAKKA_DENIAL 7
@@ -151,7 +167,7 @@ namespace Saga {
#define RID_ITE_INTRO_IMG_3 1561
#define RID_ITE_INTRO_IMG_4 1565
-// ITE_VOICES
+// ITE voices
#define RID_CAVE_VOICE_0 0
#define RID_CAVE_VOICE_1 1
#define RID_CAVE_VOICE_2 2
@@ -177,7 +193,7 @@ namespace Saga {
#define RID_BOAR_VOICE_006 245
#define RID_BOAR_VOICE_007 246
-// MUSIC
+// Music
#define MUSIC_1 9
#define MUSIC_2 10
#define MUSIC_SUNSPOT 26
@@ -185,7 +201,7 @@ namespace Saga {
// TODO: If the sound effects are numbered sequentially, we don't really need
// these constants. But for now they might be useful for debugging.
-// SOUND EFFECTS
+// Sound effects
#define FX_DOOR_OPEN 14
#define FX_DOOR_CLOSE 15
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index bb3164a79c..77d7816963 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -172,14 +172,6 @@ void SagaEngine::fillSaveList() {
}
i++;
}
-/* 4debug
- for (i = 0; i < 14; i++) {
- sprintf(_saveFiles[i].name,"test%i", i);
- _saveFiles[i].slotNumber = i;
- }
- _saveFilesCount = 14;
- _saveFilesMaxCount = 14;
- */
}
@@ -294,7 +286,10 @@ void SagaEngine::load(const char *fileName) {
_scene->setCurrentMusicTrack(in->readSint32LE());
_scene->setCurrentMusicRepeat(in->readSint32LE());
_music->stop();
- _music->play(_music->_songTable[_scene->getCurrentMusicTrack()], _scene->getCurrentMusicRepeat() ? MUSIC_LOOP : MUSIC_NORMAL);
+ if (getGameId() != GID_IHNM_DEMO)
+ _music->play(_music->_songTable[_scene->getCurrentMusicTrack()], _scene->getCurrentMusicRepeat() ? MUSIC_LOOP : MUSIC_NORMAL);
+ else
+ _music->play(3, MUSIC_LOOP);
}
// Inset scene
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index 362b212b14..c49fe546ee 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -570,8 +570,6 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {
_chapterPointsChanged = false;
- _vm->_actor->showActors(false);
-
if ((_vm->getGameType() == GType_IHNM) && (loadSceneParams->chapter != NO_CHAPTER_CHANGE)) {
if (loadSceneParams->loadFlag != kLoadBySceneNumber) {
error("loadScene wrong usage");
@@ -581,7 +579,16 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {
_vm->_interface->setLeftPortrait(0);
_vm->_anim->freeCutawayList();
- _vm->_script->freeModules();
+ // FIXME: Freed script modules are not reloaded correctly when changing chapters.
+ // This is apparent when returning back to the character selection screen,
+ // where the scene script module is loaded incorrectly
+ // Don't free them for now, but free them on game exit, like ITE.
+ // This has no impact on the game itself (other than increased memory usage),
+ // as each chapter uses a different module slot
+ // TODO: Find out why the script modules are not loaded correctly when
+ // changing chapters and uncomment this again
+ //_vm->_script->freeModules();
+
// deleteAllScenes();
// installSomeAlarm()
@@ -591,10 +598,14 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {
_vm->_interface->addToInventory(IHNM_OBJ_PROFILE);
_vm->_interface->activate();
- if (loadSceneParams->chapter == 8 || loadSceneParams->chapter == -1)
- _vm->_interface->setMode(kPanelChapterSelection);
- else
+ if (loadSceneParams->chapter == 8 || loadSceneParams->chapter == -1) {
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ _vm->_interface->setMode(kPanelChapterSelection);
+ else
+ _vm->_interface->setMode(kPanelNull);
+ } else {
_vm->_interface->setMode(kPanelMain);
+ }
_inGame = true;
@@ -640,6 +651,15 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {
debug(3, "Loading scene number %d:", _sceneNumber);
+ if (_vm->getGameId() == GID_IHNM_DEMO && _sceneNumber == 144) {
+ // WORKAROUND for the non-interactive part of the IHNM demo: When restarting the
+ // non-interactive demo, opcode sfMainMode is incorrectly called. Therefore, if the
+ // starting scene of the non-interactive demo is loaded (scene 144), set panel to null
+ // and lock the user interface
+ _vm->_interface->deactivate();
+ _vm->_interface->setMode(kPanelNull);
+ }
+
// Load scene descriptor and resource list resources
if (_loadDescription) {
debug(3, "Loading scene resource %i", _sceneResourceId);
@@ -1282,4 +1302,174 @@ void Scene::loadSceneEntryList(const byte* resourcePointer, size_t resourceLengt
}
}
+void Scene::clearPlacard() {
+ static PalEntry cur_pal[PAL_ENTRIES];
+ PalEntry *pal;
+ Event event;
+ Event *q_event;
+
+ _vm->_interface->restoreMode();
+
+ _vm->_gfx->getCurrentPal(cur_pal);
+
+ event.type = kEvTImmediate;
+ event.code = kPalEvent;
+ event.op = kEventPalToBlack;
+ event.time = 0;
+ event.duration = kNormalFadeDuration;
+ event.data = cur_pal;
+
+ q_event = _vm->_events->queue(&event);
+
+ event.type = kEvTOneshot;
+ event.code = kGraphicsEvent;
+ event.op = kEventClearFlag;
+ event.param = RF_PLACARD;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kTextEvent;
+ event.op = kEventRemove;
+ event.data = _vm->_script->getPlacardTextEntry();
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ _vm->_scene->getBGPal(pal);
+
+ event.type = kEvTImmediate;
+ event.code = kPalEvent;
+ event.op = kEventBlackToPal;
+ event.time = 0;
+ event.duration = kNormalFadeDuration;
+ event.data = pal;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kCursorEvent;
+ event.op = kEventShow;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kScriptEvent;
+ event.op = kEventThreadWake;
+ event.param = kWaitTypePlacard;
+
+ q_event = _vm->_events->chain(q_event, &event);
+}
+
+void Scene::showPsychicProfile(const char *text) {
+ int textHeight;
+ static PalEntry cur_pal[PAL_ENTRIES];
+ PalEntry *pal;
+ TextListEntry textEntry;
+ Event event;
+ Event *q_event;
+
+ if (_vm->_interface->getMode() == kPanelPlacard)
+ return;
+
+ _vm->_interface->rememberMode();
+ _vm->_interface->setMode(kPanelPlacard);
+ _vm->_gfx->savePalette();
+
+ event.type = kEvTOneshot;
+ event.code = kCursorEvent;
+ event.op = kEventHide;
+
+ q_event = _vm->_events->queue(&event);
+
+ _vm->_gfx->getCurrentPal(cur_pal);
+
+ event.type = kEvTImmediate;
+ event.code = kPalEvent;
+ event.op = kEventPalToBlack;
+ event.time = 0;
+ event.duration = kNormalFadeDuration;
+ event.data = cur_pal;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kInterfaceEvent;
+ event.op = kEventClearStatus;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kGraphicsEvent;
+ event.op = kEventSetFlag;
+ event.param = RF_PLACARD;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ // Set the background and palette for the psychic profile
+ event.type = kEvTOneshot;
+ event.code = kPsychicProfileBgEvent;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ _vm->_scene->_textList.clear();
+
+ if (text != NULL) {
+ textHeight = _vm->_font->getHeight(kKnownFontVerb, text, 226, kFontCentered);
+
+ textEntry.knownColor = kKnownColorBlack;
+ textEntry.useRect = true;
+ textEntry.rect.left = 245;
+ textEntry.rect.setHeight(210 + 76);
+ textEntry.rect.setWidth(226);
+ textEntry.rect.top = 210 - textHeight;
+ textEntry.font = kKnownFontVerb;
+ textEntry.flags = (FontEffectFlags)(kFontCentered);
+ textEntry.text = text;
+
+ TextListEntry *_psychicProfileTextEntry = _vm->_scene->_textList.addEntry(textEntry);
+
+ event.type = kEvTOneshot;
+ event.code = kTextEvent;
+ event.op = kEventDisplay;
+ event.data = _psychicProfileTextEntry;
+
+ q_event = _vm->_events->chain(q_event, &event);
+ }
+
+ _vm->_scene->getBGPal(pal);
+
+ event.type = kEvTImmediate;
+ event.code = kPalEvent;
+ event.op = kEventBlackToPal;
+ event.time = 0;
+ event.duration = kNormalFadeDuration;
+ event.data = pal;
+
+ q_event = _vm->_events->chain(q_event, &event);
+
+ event.type = kEvTOneshot;
+ event.code = kScriptEvent;
+ event.op = kEventThreadWake;
+ event.param = kWaitTypePlacard;
+
+ q_event = _vm->_events->chain(q_event, &event);
+}
+
+void Scene::clearPsychicProfile() {
+ if (_vm->_interface->getMode() == kPanelPlacard || _vm->getGameId() == GID_IHNM_DEMO) {
+ _vm->_scene->clearPlacard();
+ _vm->_scene->_textList.clear();
+ _vm->_actor->showActors(false);
+ _vm->_gfx->restorePalette();
+ _vm->_scene->restoreScene();
+ _vm->_interface->activate();
+ }
+}
+
+void Scene::showIHNMDemoSpecialScreen() {
+ _vm->_gfx->showCursor(true);
+ _vm->_interface->clearInventory();
+ _vm->_scene->changeScene(150, 0, kTransitionFade);
+}
+
} // End of namespace Saga
diff --git a/engines/saga/scene.h b/engines/saga/scene.h
index 5fa4569949..da97bddff5 100644
--- a/engines/saga/scene.h
+++ b/engines/saga/scene.h
@@ -340,6 +340,11 @@ class Scene {
return _vm->getDisplayInfo().sceneHeight;
}
+ void clearPlacard();
+ void showPsychicProfile(const char *text);
+ void clearPsychicProfile();
+ void showIHNMDemoSpecialScreen();
+
private:
void loadScene(LoadSceneParams *loadSceneParams);
void loadSceneDescriptor(uint32 resourceId);
@@ -392,13 +397,11 @@ class Scene {
static int SC_IHNMIntroMovieProc1(int param, void *refCon);
static int SC_IHNMIntroMovieProc2(int param, void *refCon);
static int SC_IHNMIntroMovieProc3(int param, void *refCon);
- static int SC_IHNMHateProc(int param, void *refCon);
private:
int IHNMIntroMovieProc1(int param);
int IHNMIntroMovieProc2(int param);
int IHNMIntroMovieProc3(int param);
- int IHNMHateProc(int param);
public:
static int SC_ITEIntroAnimProc(int param, void *refCon);
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index 262d63c51f..82fcb352c0 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -750,6 +750,10 @@ void Script::whichObject(const Point& mousePoint) {
_leftButtonVerb = _currentVerb;
newRightButtonVerb = getVerbType(kVerbNone);
+ // _protagonist can be null while loading a game from the command line
+ if (_vm->_actor->_protagonist == NULL)
+ return;
+
if (_vm->_actor->_protagonist->_currentAction != kActionWalkDir) {
if (_vm->_scene->getHeight() >= mousePoint.y) {
newObjectId = _vm->_actor->hitTest(mousePoint, true);
diff --git a/engines/saga/script.h b/engines/saga/script.h
index 5adfb6181a..5e5e702132 100644
--- a/engines/saga/script.h
+++ b/engines/saga/script.h
@@ -380,6 +380,7 @@ public:
setPointerVerb();
}
int getVerbType(VerbTypes verbType);
+ TextListEntry *getPlacardTextEntry() { return _placardTextEntry; }
private:
// When reading or writing data to the common buffer, we have to use a
@@ -443,6 +444,7 @@ private:
int _stickyVerb;
int _leftButtonVerb;
int _rightButtonVerb;
+ int _ihnmDemoCurrentY;
public:
uint16 _pendingObject[2];
@@ -590,11 +592,12 @@ private:
void sfScriptStartVideo(SCRIPTFUNC_PARAMS);
void sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS);
void sfScriptEndVideo(SCRIPTFUNC_PARAMS);
- void sf87(SCRIPTFUNC_PARAMS);
- void sf88(SCRIPTFUNC_PARAMS);
- void sf89(SCRIPTFUNC_PARAMS);
+ void sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS);
+ void sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS);
+ void sfShowIHNMDemoHelpPage(SCRIPTFUNC_PARAMS);
void sfGetPoints(SCRIPTFUNC_PARAMS);
void sfSetGlobalFlag(SCRIPTFUNC_PARAMS);
+ void sf92(SCRIPTFUNC_PARAMS);
void sfClearGlobalFlag(SCRIPTFUNC_PARAMS);
void sfTestGlobalFlag(SCRIPTFUNC_PARAMS);
void sfSetPoints(SCRIPTFUNC_PARAMS);
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index 4954188a6e..c0e44584df 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -40,6 +40,7 @@
#include "saga/render.h"
#include "saga/sound.h"
#include "saga/sndres.h"
+#include "saga/rscfile.h"
#include "saga/script.h"
#include "saga/objectmap.h"
@@ -224,12 +225,12 @@ static const ScriptFunctionDescription IHNMscriptFunctionsList[IHNM_SCRIPT_FUNCT
OPCODE(sfScriptReturnFromVideo),
OPCODE(sfScriptEndVideo),
OPCODE(sfSetActorZ),
- OPCODE(sf87),
- OPCODE(sf88),
- OPCODE(sf89),
+ OPCODE(sfShowIHNMDemoHelpBg),
+ OPCODE(sfAddIHNMDemoHelpTextLine),
+ OPCODE(sfShowIHNMDemoHelpPage),
OPCODE(sfVstopFX),
OPCODE(sfVstopLoopedFX),
- OPCODE(sfNull),
+ OPCODE(sf92), // only used in the demo version of IHNM
OPCODE(sfDemoIsInteractive),
OPCODE(sfVsetTrack),
OPCODE(sfGetPoints),
@@ -277,7 +278,16 @@ void Script::sfTakeObject(SCRIPTFUNC_PARAMS) {
obj = _vm->_actor->getObj(objectId);
if (obj->_sceneNumber != ITE_SCENE_INV) {
obj->_sceneNumber = ITE_SCENE_INV;
- //4debug for (int j=0;j<17;j++)
+
+ // WORKAROUND for two incorrect object sprites in the IHNM demo
+ // (the mirror and the icon in Ted's part). Set them correctly here
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ if (obj->_spriteListResourceId == 4 && objectId == 16408)
+ obj->_spriteListResourceId = 24;
+ if (obj->_spriteListResourceId == 3 && objectId == 16409)
+ obj->_spriteListResourceId = 25;
+ }
+
_vm->_interface->addToInventory(objectId);
}
}
@@ -562,16 +572,19 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {
}
if (_vm->getGameType() == GType_IHNM) {
+ // WORKAROUND for the briefly appearing actors at the beginning of each chapter
+ // This will stop the actors being drawn in those specific scenes until the scene background has been drawn
+ if ((_vm->_scene->currentChapterNumber() == 1 && _vm->_scene->currentSceneNumber() == 6) ||
+ (_vm->_scene->currentChapterNumber() == 2 && _vm->_scene->currentSceneNumber() == 31) ||
+ (_vm->_scene->currentChapterNumber() == 3 && _vm->_scene->currentSceneNumber() == 58) ||
+ (_vm->_scene->currentChapterNumber() == 4 && _vm->_scene->currentSceneNumber() == 68) ||
+ (_vm->_scene->currentChapterNumber() == 5 && _vm->_scene->currentSceneNumber() == 91) ||
+ (_vm->_scene->currentChapterNumber() == 7 && _vm->_scene->currentSceneNumber() == 145))
+ _vm->_actor->showActors(false); // Stop showing actors before the background is drawn
+
// Since it doesn't look like the IHNM scripts remove the
- // cutaway after the intro, this is probably the best place to
- // to it.
- Event event;
- event.type = kEvTImmediate;
- event.code = kCutawayEvent;
- event.op = kEventClear;
- event.time = 0;
- event.duration = 0;
- _vm->_events->queue(&event);
+ // cutaway after the intro, this is probably the best place to do it
+ _vm->_anim->clearCutaway();
}
// It is possible to leave scene when converse panel is on,
@@ -868,10 +881,16 @@ void Script::sfDropObject(SCRIPTFUNC_PARAMS) {
_vm->_scene->currentSceneNumber() == 59 && obj->_id == 16385)
obj->_sceneNumber = -1;
- if (_vm->getGameType() == GType_IHNM)
- obj->_spriteListResourceId = spriteId;
- else
+ if (_vm->getGameType() == GType_IHNM) {
+ if (_vm->getGameId() != GID_IHNM_DEMO) {
+ obj->_spriteListResourceId = spriteId;
+ } else {
+ // Don't update the object's _spriteListResourceId in the IHNM demo, as this function is
+ // called incorrectly there (with spriteId == 0, which resets the object sprites)
+ }
+ } else {
obj->_spriteListResourceId = OBJ_SPRITE_BASE + spriteId;
+ }
obj->_location.x = x;
obj->_location.y = y;
@@ -1296,11 +1315,6 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
Event event;
Event *q_event;
- if (_vm->getGameType() == GType_IHNM) {
- warning("Psychic profile is not implemented");
- return;
- }
-
thread->wait(kWaitTypePlacard);
_vm->_interface->rememberMode();
@@ -1397,72 +1411,24 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
// Script function #49 (0x31)
void Script::sfPlacardOff(SCRIPTFUNC_PARAMS) {
- static PalEntry cur_pal[PAL_ENTRIES];
- PalEntry *pal;
- Event event;
- Event *q_event;
-
thread->wait(kWaitTypePlacard);
- _vm->_interface->restoreMode();
-
- _vm->_gfx->getCurrentPal(cur_pal);
-
- event.type = kEvTImmediate;
- event.code = kPalEvent;
- event.op = kEventPalToBlack;
- event.time = 0;
- event.duration = kNormalFadeDuration;
- event.data = cur_pal;
-
- q_event = _vm->_events->queue(&event);
-
- event.type = kEvTOneshot;
- event.code = kGraphicsEvent;
- event.op = kEventClearFlag;
- event.param = RF_PLACARD;
-
- q_event = _vm->_events->chain(q_event, &event);
-
- event.type = kEvTOneshot;
- event.code = kTextEvent;
- event.op = kEventRemove;
- event.data = _placardTextEntry;
-
- q_event = _vm->_events->chain(q_event, &event);
-
- _vm->_scene->getBGPal(pal);
-
- event.type = kEvTImmediate;
- event.code = kPalEvent;
- event.op = kEventBlackToPal;
- event.time = 0;
- event.duration = kNormalFadeDuration;
- event.data = pal;
-
- q_event = _vm->_events->chain(q_event, &event);
-
- event.type = kEvTOneshot;
- event.code = kCursorEvent;
- event.op = kEventShow;
-
- q_event = _vm->_events->chain(q_event, &event);
-
- event.type = kEvTOneshot;
- event.code = kScriptEvent;
- event.op = kEventThreadWake;
- event.param = kWaitTypePlacard;
-
- q_event = _vm->_events->chain(q_event, &event);
-
+ _vm->_scene->clearPlacard();
}
void Script::sfPsychicProfile(SCRIPTFUNC_PARAMS) {
- SF_stub("sfPsychicProfile", thread, nArgs);
+ thread->wait(kWaitTypePlacard);
+
+ int stringId = thread->pop();
+ _vm->_scene->showPsychicProfile(thread->_strings->getString(stringId));
}
void Script::sfPsychicProfileOff(SCRIPTFUNC_PARAMS) {
- SF_stub("sfPsychicProfileOff", thread, nArgs);
+ thread->wait(kWaitTypePlacard);
+
+ // This is called a while after the psychic profile is
+ // opened, to close it automatically
+ _vm->_scene->clearPsychicProfile();
}
// Script function #50 (0x32)
@@ -1695,7 +1661,7 @@ void Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
int16 param = thread->pop() + 9;
if (param >= 9 && param <= 34) {
- _vm->_music->setVolume(-1, 1);
+ _vm->_music->setVolume(_vm->_musicVolume == 10 ? -1 : _vm->_musicVolume * 25, 1);
_vm->_music->play(param);
} else {
_vm->_music->stop();
@@ -1712,7 +1678,7 @@ void Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
if (param1 >= _vm->_music->_songTableLen) {
warning("sfPlayMusic: Wrong song number (%d > %d)", param1, _vm->_music->_songTableLen - 1);
} else {
- _vm->_music->setVolume(-1, 1);
+ _vm->_music->setVolume(_vm->_musicVolume == 10 ? -1 : _vm->_musicVolume * 25, 1);
_vm->_music->play(_vm->_music->_songTable[param1], param2 ? MUSIC_LOOP : MUSIC_NORMAL);
if (!_vm->_scene->haveChapterPointsChanged()) {
_vm->_scene->setCurrentMusicTrack(param1);
@@ -2032,16 +1998,49 @@ void Script::sfScriptEndVideo(SCRIPTFUNC_PARAMS) {
_vm->_anim->endVideo();
}
-void Script::sf87(SCRIPTFUNC_PARAMS) {
- SF_stub("sf87", thread, nArgs);
+void Script::sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS) {
+ _ihnmDemoCurrentY = 0;
+ _vm->_scene->_textList.clear();
+ _vm->_interface->setMode(kPanelConverse);
+ _vm->_scene->showPsychicProfile(NULL);
}
-void Script::sf88(SCRIPTFUNC_PARAMS) {
- SF_stub("sf88", thread, nArgs);
+void Script::sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS) {
+ int stringId, textHeight;
+ TextListEntry textEntry;
+ Event event;
+
+ stringId = thread->pop();
+
+ textHeight = _vm->_font->getHeight(kKnownFontVerb, thread->_strings->getString(stringId), 226, kFontCentered);
+
+ textEntry.knownColor = kKnownColorBlack;
+ textEntry.useRect = true;
+ textEntry.rect.left = 245;
+ textEntry.rect.setHeight(210 + 76);
+ textEntry.rect.setWidth(226);
+ textEntry.rect.top = 76 + _ihnmDemoCurrentY;
+ textEntry.font = kKnownFontVerb;
+ textEntry.flags = (FontEffectFlags)(kFontCentered);
+ textEntry.text = thread->_strings->getString(stringId);
+
+ TextListEntry *_psychicProfileTextEntry = _vm->_scene->_textList.addEntry(textEntry);
+
+ event.type = kEvTOneshot;
+ event.code = kTextEvent;
+ event.op = kEventDisplay;
+ event.data = _psychicProfileTextEntry;
+
+ _vm->_events->queue(&event);
+
+ _ihnmDemoCurrentY += 10;
}
-void Script::sf89(SCRIPTFUNC_PARAMS) {
- SF_stub("sf89", thread, nArgs);
+void Script::sfShowIHNMDemoHelpPage(SCRIPTFUNC_PARAMS) {
+ // Note: The IHNM demo changes panel mode to 8 (kPanelProtect in ITE)
+ // when changing pages
+ _vm->_interface->setMode(kPanelPlacard);
+ _ihnmDemoCurrentY = 0;
}
void Script::sfVstopFX(SCRIPTFUNC_PARAMS) {
@@ -2052,6 +2051,11 @@ void Script::sfVstopLoopedFX(SCRIPTFUNC_PARAMS) {
_vm->_sound->stopSound();
}
+void Script::sf92(SCRIPTFUNC_PARAMS) {
+ SF_stub("sf92", thread, nArgs);
+ // This opcode is empty in the full version of IHNM, but it's not empty in the demo
+}
+
void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) {
thread->_returnValue = 0;
}
@@ -2144,7 +2148,7 @@ void Script::sfQueueMusic(SCRIPTFUNC_PARAMS) {
if (param1 >= _vm->_music->_songTableLen) {
warning("sfQueueMusic: Wrong song number (%d > %d)", param1, _vm->_music->_songTableLen - 1);
} else {
- _vm->_music->setVolume(-1, 1);
+ _vm->_music->setVolume(_vm->_musicVolume == 10 ? -1 : _vm->_musicVolume * 25, 1);
event.type = kEvTOneshot;
event.code = kMusicEvent;
event.param = _vm->_music->_songTable[param1];
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index ceb1ebf630..edbdebabab 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -44,7 +44,7 @@
namespace Saga {
SndRes::SndRes(SagaEngine *vm) : _vm(vm) {
- /* Load sound module resource file contexts */
+ // Load sound module resource file contexts
_sfxContext = _vm->_resource->getContext(GAME_SOUNDFILE);
if (_sfxContext == NULL) {
error("SndRes::SndRes resource context not found");
@@ -68,8 +68,13 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm) {
byte *resourcePointer;
size_t resourceLength;
- _vm->_resource->loadResource(resourceContext, RID_IHNM_SFX_LUT,
- resourcePointer, resourceLength);
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ _vm->_resource->loadResource(resourceContext, RID_IHNMDEMO_SFX_LUT,
+ resourcePointer, resourceLength);
+ } else {
+ _vm->_resource->loadResource(resourceContext, RID_IHNM_SFX_LUT,
+ resourcePointer, resourceLength);
+ }
if (resourceLength == 0) {
error("Sndres::SndRes can't read SfxIDs table");
@@ -169,7 +174,6 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
MemoryReadStream readS(soundResource, soundResourceLength);
resourceType = soundInfo->resourceType;
- buffer.isBigEndian = soundInfo->isBigEndian;
if (soundResourceLength >= 8) {
if (!memcmp(soundResource, "Creative", 8)) {
@@ -178,7 +182,17 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
resourceType = kSoundWAV;
}
- if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) {
+ bool uncompressedSound = false;
+ // If a patch file exists for sound resource 4 (used in ITE intro), don't treat this sound as compressed
+ if (_vm->getGameType() == GType_ITE && resourceId == 4 &&
+ (Common::File::exists("sound/p2_a.iaf") || Common::File::exists("sound/p2_a.voc")))
+ uncompressedSound = true;
+
+ // FIXME: Currently, the SFX.RES file in IHNM cannot be compressed
+ if (_vm->getGameType() == GType_IHNM && (context->fileType & GAME_SOUNDFILE))
+ uncompressedSound = true;
+
+ if ((_vm->getFeatures() & GF_COMPRESSED_SOUNDS) && !uncompressedSound) {
if (soundResource[0] == char(0)) {
resourceType = kSoundMP3;
} else if (soundResource[0] == char(1)) {
@@ -190,6 +204,9 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
}
+ buffer.isBigEndian = soundInfo->isBigEndian;
+ buffer.soundType = resourceType;
+ buffer.originalSize = 0;
switch (resourceType) {
case kSoundPCM:
@@ -319,7 +336,7 @@ int SndRes::getVoiceLength(uint32 resourceId) {
return -1;
}
- if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS))
+ if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS) || buffer.originalSize == 0)
msDouble = (double)buffer.size;
else
msDouble = (double)buffer.originalSize;
diff --git a/engines/saga/sound.cpp b/engines/saga/sound.cpp
index 6c2516c8a3..621b3ed310 100644
--- a/engines/saga/sound.cpp
+++ b/engines/saga/sound.cpp
@@ -83,31 +83,40 @@ void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int
if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS)) {
_mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
} else {
- buffer.soundFile->seek((long)buffer.fileOffset, SEEK_SET);
Audio::AudioStream *stream = NULL;
+ Common::MemoryReadStream *tmp = NULL;
switch (buffer.soundType) {
#ifdef USE_MAD
case kSoundMP3:
debug(1, "Playing MP3 compressed sound");
- stream = Audio::makeMP3Stream(buffer.soundFile, buffer.size);
+ buffer.soundFile->seek((long)buffer.fileOffset, SEEK_SET);
+ tmp = buffer.soundFile->readStream(buffer.size);
+ assert(tmp);
+ stream = Audio::makeMP3Stream(tmp, true);
break;
#endif
#ifdef USE_VORBIS
case kSoundOGG:
debug(1, "Playing OGG compressed sound");
- stream = Audio::makeVorbisStream(buffer.soundFile, buffer.size);
+ buffer.soundFile->seek((long)buffer.fileOffset, SEEK_SET);
+ tmp = buffer.soundFile->readStream(buffer.size);
+ assert(tmp);
+ stream = Audio::makeVorbisStream(tmp, true);
break;
#endif
#ifdef USE_FLAC
case kSoundFLAC:
debug(1, "Playing FLAC compressed sound");
- stream = Audio::makeFlacStream(buffer.soundFile, buffer.size);
+ buffer.soundFile->seek((long)buffer.fileOffset, SEEK_SET);
+ tmp = buffer.soundFile->readStream(buffer.size);
+ assert(tmp);
+ stream = Audio::makeFlacStream(tmp, true);
break;
#endif
default:
- // Unknown compression
- error("Trying to play a compressed sound, but the compression is not known");
+ // No compression, play it as raw sound
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume);
break;
}
diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp
index 607e7d0a0b..ac911e5a9c 100644
--- a/engines/saga/sprite.cpp
+++ b/engines/saga/sprite.cpp
@@ -24,6 +24,7 @@
*/
// Sprite management module
+
#include "saga/saga.h"
#include "saga/gfx.h"
@@ -57,8 +58,13 @@ Sprite::Sprite(SagaEngine *vm) : _vm(vm) {
loadList(_vm->getResourceDescription()->mainSpritesResourceId, _mainSprites);
_arrowSprites = _saveReminderSprites = _inventorySprites = _mainSprites;
} else {
- loadList(RID_IHNM_ARROW_SPRITES, _arrowSprites);
- loadList(RID_IHNM_SAVEREMINDER_SPRITES, _saveReminderSprites);
+ if (_vm->getGameId() == GID_IHNM_DEMO) {
+ loadList(RID_IHNMDEMO_ARROW_SPRITES, _arrowSprites);
+ loadList(RID_IHNMDEMO_SAVEREMINDER_SPRITES, _saveReminderSprites);
+ } else {
+ loadList(RID_IHNM_ARROW_SPRITES, _arrowSprites);
+ loadList(RID_IHNM_SAVEREMINDER_SPRITES, _saveReminderSprites);
+ }
}
}
@@ -113,7 +119,9 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
offset = readS.readUint16();
if (offset >= spriteListLength) {
- error("Sprite::loadList offset exceed");
+ // ITE Mac demos throw this warning
+ warning("Sprite::loadList offset exceeded");
+ return;
}
spritePointer = spriteListData;