diff options
author | Eugene Sandulenko | 2005-08-07 00:00:43 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2005-08-07 00:00:43 +0000 |
commit | 215a94ae30082e396ab6179e26ab6e182602f8a7 (patch) | |
tree | 6404c4d54735610814ca9238b7d38372a0b36a19 | |
parent | 5956747e2e9d38defe5684a67992dfc6dba58cf4 (diff) | |
download | scummvm-rg350-215a94ae30082e396ab6179e26ab6e182602f8a7.tar.gz scummvm-rg350-215a94ae30082e396ab6179e26ab6e182602f8a7.tar.bz2 scummvm-rg350-215a94ae30082e396ab6179e26ab6e182602f8a7.zip |
WIP on metaResources. Most resources are load. Now we start correct
scene. But there are following problems:
o Inclomplete support for actors speech, so opSpeak is skipped
o For some weird reason actors do not appear at all. Actually code seems to
be trying to read only protagonist frames
o It crashes on reading sprites due to wrong input
svn-id: r18624
-rw-r--r-- | saga/actor.cpp | 121 | ||||
-rw-r--r-- | saga/actor.h | 7 | ||||
-rw-r--r-- | saga/ihnm_introproc.cpp | 2 | ||||
-rw-r--r-- | saga/interface.h | 4 | ||||
-rw-r--r-- | saga/itedata.cpp | 71 | ||||
-rw-r--r-- | saga/itedata.h | 7 | ||||
-rw-r--r-- | saga/resnames.h | 1 | ||||
-rw-r--r-- | saga/rscfile.cpp | 85 | ||||
-rw-r--r-- | saga/rscfile.h | 9 | ||||
-rw-r--r-- | saga/scene.cpp | 15 | ||||
-rw-r--r-- | saga/script.h | 1 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 117 | ||||
-rw-r--r-- | saga/sndres.cpp | 43 | ||||
-rw-r--r-- | saga/sndres.h | 9 | ||||
-rw-r--r-- | saga/sprite.cpp | 3 | ||||
-rw-r--r-- | saga/sthread.cpp | 7 |
16 files changed, 368 insertions, 134 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp index d1da219a80..c44ac5d970 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -184,6 +184,9 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) { _debugPointsAlloced = _debugPointsCount = 0; #endif + _protagStates = 0; + _protagStatesCount = 0; + _pathNodeList = _newPathNodeList = NULL; _pathList = NULL; _pathDirectionList = NULL; @@ -390,8 +393,9 @@ void Actor::loadList(int actorsEntrance, int actorCount, int actorsResourceID, i _vm->_resource->loadResource(_actorContext, actorsResourceID, actorListData, actorListLength); + _actorsCount = actorCount; + MemoryReadStream actorS(actorListData, actorListLength); - _actorsCount = actorListLength / ACTOR_INHM_SIZE; _actors = (ActorData **)malloc(_actorsCount * sizeof(*_actors)); for (i = 0; i < _actorsCount; i++) { @@ -442,6 +446,8 @@ void Actor::loadList(int actorsEntrance, int actorCount, int actorsResourceID, i } free(actorListData); + _actors[actorsEntrance]->flags |= kProtagonist | kExtended; + for (i = 0; i < _actorsCount; i++) { actor = _actors[i]; if (actor->flags & kExtended) { @@ -451,7 +457,93 @@ void Actor::loadList(int actorsEntrance, int actorCount, int actorsResourceID, i } } } -//TODO: protagonist stuff + + _centerActor = _protagonist = _actors[actorsEntrance]; + _protagState = 0; + + if (protagStatesResourceID) { + free(_protagStates); + + _protagStates = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * protagStatesCount); + + byte *resourcePointer; + size_t resourceLength; + + _vm->_resource->loadResource(_actorContext, protagStatesResourceID, + resourcePointer, resourceLength); + + + MemoryReadStream statesS(resourcePointer, resourceLength); + + for (i = 0; i < protagStatesCount; i++) { + for (int j = 0; j < ACTOR_DIRECTIONS_COUNT; j++) { + _protagStates[i].directions[j].frameIndex = statesS.readUint16LE(); + _protagStates[i].directions[j].frameCount = statesS.readUint16LE(); + } + } + free(resourcePointer); + + _protagonist->frames = &_protagStates[_protagState]; + } + + _protagStatesCount = protagStatesCount; +} + +void Actor::freeObjList() { + int i; + ObjectData *object; + for (i = 0; i < _objsCount; i++) { + object = _objs[i]; + delete object; + } + free(_objs); + _objs = NULL; + _objsCount = 0; +} + +void Actor::loadObjList(int objectCount, int objectsResourceID) { + int i; + ObjectData *object; + byte* objectListData; + size_t objectListLength; + freeObjList(); + + _vm->_resource->loadResource(_actorContext, objectsResourceID, objectListData, objectListLength); + + _objsCount = objectCount; + + MemoryReadStream objectS(objectListData, objectListLength); + + _objs = (ObjectData **)malloc(_objsCount * sizeof(*_objs)); + for (i = 0; i < _objsCount; i++) { + object = _objs[i] = new ObjectData(); + object->id = objectIndexToId(kGameObjectObject, i); + object->index = i; + debug(9, "init object id=%d index=%d", object->id, object->index); + objectS.readUint32LE(); //next displayed + objectS.readByte(); //type + object->flags = objectS.readByte(); + object->nameIndex = objectS.readUint16LE(); + object->sceneNumber = objectS.readUint32LE(); + object->location.fromStream(objectS); + object->screenPosition.x = objectS.readUint16LE(); + object->screenPosition.y = objectS.readUint16LE(); + object->screenScale = objectS.readUint16LE(); + object->screenDepth = objectS.readUint16LE(); + objectS.readUint32LE(); // object->frameListResourceId + object->spriteListResourceId = objectS.readUint32LE(); + object->scriptEntrypointNumber = objectS.readUint32LE(); + objectS.readByte(); + objectS.readByte(); + objectS.readByte(); + objectS.readByte(); + objectS.readUint16LE(); //LEFT + objectS.readUint16LE(); //RIGHT + objectS.readUint16LE(); //TOP + objectS.readUint16LE(); //BOTTOM + object->interactBits = objectS.readUint16LE(); + } + free(objectListData); } void Actor::takeExit(uint16 actorId, const HitZone *hitZone) { @@ -624,6 +716,9 @@ bool Actor::validFollowerLocation(const Location &location) { void Actor::setProtagState(int state) { _protagState = state; + + if (_vm->getGameType() == GType_IHNM) + _protagonist->frames = &_protagStates[state]; } void Actor::updateActorsScene(int actorsEntrance) { @@ -635,11 +730,6 @@ void Actor::updateActorsScene(int actorsEntrance) { Point delta; const SceneEntry *sceneEntry; - if (_vm->getGameType() == GType_IHNM) { - warning("Actors aren't implemented for IHNM yet"); - return; - } - if (_vm->_scene->currentSceneNumber() == 0) { error("Actor::updateActorsScene _vm->_scene->currentSceneNumber() == 0"); } @@ -768,7 +858,7 @@ ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) { error("Actor::getActorFrameRange Wrong actorId 0x%X", actorId); if (frameType >= actor->framesCount) - error("Actor::getActorFrameRange Wrong frameType 0x%X actorId 0x%X", frameType, actorId); + error("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->framesCount, actorId); if ((actor->facingDirection < kDirUp) || (actor->facingDirection > kDirUpLeft)) error("Actor::getActorFrameRange Wrong direction 0x%X actorId 0x%X", actor->facingDirection, actorId); @@ -933,6 +1023,11 @@ void Actor::handleActions(int msec, bool setup) { /* if (actor->index == 2) debug(9, "Action: %d Flags: %x", actor->currentAction, actor->flags);*/ + if (_vm->getGameType() == GType_IHNM) { + if (actor->spriteList.spriteCount == 0) + continue; + } + switch (actor->currentAction) { case kActionWait: if (!setup && (actor->flags & kFollower)) { @@ -1868,11 +1963,6 @@ void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount, int i; int16 dist; - if (_vm->getGameType() == GType_IHNM) { - warning("Actors aren't implemented for IHNM yet"); - return; - } - actor = getActor(actorId); calcScreenPosition(actor); for (i = 0; i < stringsCount; i++) { @@ -1926,11 +2016,6 @@ void Actor::nonActorSpeech(const Common::Rect &box, const char **strings, int st void Actor::simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId) { int i; - if (_vm->getGameType() == GType_IHNM) { - warning("Actors aren't implemented for IHNM yet"); - return; - } - for (i = 0; i < actorIdsCount; i++) { ActorData *actor; diff --git a/saga/actor.h b/saga/actor.h index 3ff06709fd..b8c325bf00 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -342,6 +342,7 @@ public: Location partialTarget; int32 walkFrameSequence; +public: void saveState(Common::OutSaveFile *out) { int i = 0; CommonObjectData::saveState(out); @@ -582,6 +583,8 @@ public: void freeList(); void loadList(int actorsEntrance, int actorCount, int actorsResourceID, int protagStatesCount, int protagStatesResourceID); + void freeObjList(); + void loadObjList(int objectCount, int objectsResourceID); private: bool loadActorResources(ActorData *actor); @@ -643,12 +646,16 @@ public: ActorData *_centerActor; ActorData *_protagonist; int _handleActionDiv; + protected: SpeechData _activeSpeech; int _protagState; bool _dragonHunt; private: + ActorFrameSequence *_protagStates; + int _protagStatesCount; + //path stuff struct PathNode { Point point; diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp index 7d162e09a1..89837d9bf2 100644 --- a/saga/ihnm_introproc.cpp +++ b/saga/ihnm_introproc.cpp @@ -99,7 +99,7 @@ int Scene::IHNMStartProc() { } firstScene.loadFlag = kLoadBySceneNumber; - firstScene.sceneDescriptor = _vm->getStartSceneNumber(); + firstScene.sceneDescriptor = -1; firstScene.sceneDescription = NULL; firstScene.sceneSkipTarget = true; firstScene.sceneProc = NULL; diff --git a/saga/interface.h b/saga/interface.h index 96b3057247..b8f1945135 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -375,6 +375,9 @@ private: } } +public: + SpriteList _defPortraits; + private: SagaEngine *_vm; @@ -385,7 +388,6 @@ private: InterfacePanel _conversePanel; PanelButton *_converseUpButton; PanelButton *_converseDownButton; - SpriteList _defPortraits; SpriteList _scenePortraits; PanelButton *_verbTypeToPanelButton[kVerbTypesMax]; InterfacePanel _optionPanel; diff --git a/saga/itedata.cpp b/saga/itedata.cpp index 73515483dc..95dce36a6d 100644 --- a/saga/itedata.cpp +++ b/saga/itedata.cpp @@ -24,6 +24,8 @@ // Actor and Object data tables #include "saga/saga.h" #include "saga/itedata.h" +#include "saga/resnames.h" +#include "saga/sndres.h" namespace Saga { @@ -264,4 +266,73 @@ ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT] = { { 54, 281, 620, 352, 0, 80, 46, 0 } // Orb of Storms in Dam Lab }; +FxTable ITE_SfxTable[ITE_SFXCOUNT] = { + { FX_DOOR_OPEN, 127 }, + { FX_DOOR_CLOSE, 127 }, + { FX_RUSH_WATER, 63 }, // Floppy volume: 127 + { FX_RUSH_WATER, 26 }, // Floppy volume: 40 + { FX_CRICKET, 64 }, + { FX_PORTICULLIS, 84 }, // Floppy volume: 127 + { FX_CLOCK_1, 64 }, + { FX_CLOCK_2, 64 }, + { FX_DAM_MACHINE, 64 }, + { FX_DAM_MACHINE, 40 }, + { FX_HUM1, 64 }, + { FX_HUM2, 64 }, + { FX_HUM3, 64 }, + { FX_HUM4, 64 }, + { FX_WATER_LOOP_S, 32 }, // Floppy volume: 64 + { FX_SURF, 42 }, // Floppy volume: 127 + { FX_SURF, 32 }, // Floppy volume: 64 + { FX_FIRELOOP, 64 }, // Floppy volume: 96 + { FX_SCRAPING, 84 }, // Floppy volume: 127 + { FX_BEE_SWARM, 64 }, // Floppy volume: 96 + { FX_BEE_SWARM, 26 }, // Floppy volume: 40 + { FX_SQUEAKBOARD, 64 }, + { FX_KNOCK, 127 }, + { FX_COINS, 32 }, // Floppy volume: 48 + { FX_STORM, 84 }, // Floppy volume: 127 + { FX_DOOR_CLOSE_2, 84 }, // Floppy volume: 127 + { FX_ARCWELD, 84 }, // Floppy volume: 127 + { FX_RETRACT_ORB, 127 }, + { FX_DRAGON, 127 }, + { FX_SNORES, 127 }, + { FX_SPLASH, 127 }, + { FX_LOBBY_DOOR, 127 }, + { FX_CHIRP_LOOP, 26 }, // Floppy volume: 40 + { FX_DOOR_CREAK, 96 }, + { FX_SPOON_DIG, 64 }, + { FX_CROW, 96 }, + { FX_COLDWIND, 42 }, // Floppy volume: 64 + { FX_TOOL_SND_1, 96 }, + { FX_TOOL_SND_2, 127 }, + { FX_TOOL_SND_3, 64 }, + { FX_DOOR_METAL, 96 }, + { FX_WATER_LOOP_S, 32 }, + { FX_WATER_LOOP_L, 32 }, // Floppy volume: 64 + { FX_DOOR_OPEN_2, 127 }, + { FX_JAIL_DOOR, 64 }, + { FX_KILN_FIRE, 53 }, // Floppy volume: 80 + + // Only in the CD version + { FX_CROWD_01, 64 }, + { FX_CROWD_02, 64 }, + { FX_CROWD_03, 64 }, + { FX_CROWD_04, 64 }, + { FX_CROWD_05, 64 }, + { FX_CROWD_06, 64 }, + { FX_CROWD_07, 64 }, + { FX_CROWD_08, 64 }, + { FX_CROWD_09, 64 }, + { FX_CROWD_10, 64 }, + { FX_CROWD_11, 64 }, + { FX_CROWD_12, 64 }, + { FX_CROWD_13, 64 }, + { FX_CROWD_14, 64 }, + { FX_CROWD_15, 64 }, + { FX_CROWD_16, 64 }, + { FX_CROWD_17, 64 } +}; + + } // End of namespace Saga diff --git a/saga/itedata.h b/saga/itedata.h index 299cc365db..fb1f929241 100644 --- a/saga/itedata.h +++ b/saga/itedata.h @@ -76,9 +76,16 @@ struct ObjectTableData { uint16 interactBits; }; +struct FxTable { + int res; + int vol; +}; + #define ITE_OBJECTCOUNT 39 +#define ITE_SFXCOUNT 63 extern ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT]; +extern FxTable ITE_SfxTable[ITE_SFXCOUNT]; } // End of namespace Saga diff --git a/saga/resnames.h b/saga/resnames.h index 500fb0a82d..ca1ae7af72 100644 --- a/saga/resnames.h +++ b/saga/resnames.h @@ -36,6 +36,7 @@ namespace Saga { #define RID_IHNM_SCENE_LUT 1272 #define RID_IHNM_SCRIPT_LUT 29 +#define RID_IHNM_SFX_LUT 265 #define RID_IHNMDEMO_SCENE_LUT 286 #define RID_IHNMDEMO_SCRIPT_LUT 18 diff --git a/saga/rscfile.cpp b/saga/rscfile.cpp index 5625f51b03..dadcd15b4f 100644 --- a/saga/rscfile.cpp +++ b/saga/rscfile.cpp @@ -25,7 +25,9 @@ #include "saga/saga.h" #include "saga/actor.h" +#include "saga/interface.h" #include "saga/rscfile.h" +#include "saga/sndres.h" #include "saga/stream.h" namespace Saga { @@ -432,7 +434,7 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) { //if (module.voiceLUT) // free module.voiceLUT; - // TODO: close chapeter context, or rather reassign it in our case + // TODO: close chapter context, or rather reassign it in our case ResourceContext *resourceContext; @@ -448,16 +450,17 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) { resourcePointer, resourceLength); if (resourceLength == 0) { - error("Resource::loadGlobalResources wrong resource"); + error("Resource::loadGlobalResources wrong metaResource"); } + MemoryReadStream metaS(resourcePointer, resourceLength); _metaResource.sceneIndex = metaS.readSint16LE(); - _metaResource.obectCount = metaS.readSint16LE(); + _metaResource.objectCount = metaS.readSint16LE(); _metaResource.field_4 = metaS.readSint32LE(); _metaResource.field_8 = metaS.readSint32LE(); _metaResource.mainSpritesID = metaS.readSint32LE(); - _metaResource.objectResourceID = metaS.readSint32LE(); + _metaResource.objectsResourceID = metaS.readSint32LE(); _metaResource.actorCount = metaS.readSint16LE(); _metaResource.field_16 = metaS.readSint32LE(); _metaResource.actorsResourceID = metaS.readSint32LE(); @@ -477,6 +480,80 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) { _vm->_actor->_protagonist->sceneNumber = _metaResource.sceneIndex; + // TODO: field_16 + + if (chapter >= _vm->_sndRes->_fxTableIDsLen) { + error("Chapter ID exceeds fxTableIDs length"); + } + + debug(0, "Going to read %d of %d", chapter, _vm->_sndRes->_fxTableIDs[chapter]); + _vm->_resource->loadResource(resourceContext, _vm->_sndRes->_fxTableIDs[chapter], + resourcePointer, resourceLength); + + if (resourceLength == 0) { + error("Resource::loadGlobalResources Can't load sound effects for current track"); + } + + free(_vm->_sndRes->_fxTable); + + _vm->_sndRes->_fxTableLen = resourceLength / 4; + _vm->_sndRes->_fxTable = (FxTable *)malloc(sizeof(FxTable) * _vm->_sndRes->_fxTableLen); + + MemoryReadStream fxS(resourcePointer, resourceLength); + + for (int i = 0; i < _vm->_sndRes->_fxTableLen; i++) { + _vm->_sndRes->_fxTable[i].res = fxS.readSint16LE(); + _vm->_sndRes->_fxTable[i].vol = fxS.readSint16LE(); + } + + _vm->_interface->_defPortraits.freeMem(); + _vm->_sprite->loadList(_metaResource.protagFaceSpritesID, _vm->_interface->_defPortraits); + + // TODO: field_4 + + // TODO: field_8 + + _vm->_sprite->_mainSprites.freeMem(); + _vm->_sprite->loadList(_metaResource.mainSpritesID, _vm->_sprite->_mainSprites); + + _vm->_actor->loadObjList(_metaResource.objectCount, _metaResource.objectsResourceID); + + // TODO: cutawayList + + // TODO: songTable + + switch (chapter) { + case 1: + // chapterRes = "voices1.res" + // hackVoiceTableListID = 23 + break; + case 2: + // chapterRes = "voices2.res" + // hackVoiceTableListID = 24 + break; + case 3: + // chapterRes = "voices3.res" + // hackVoiceTableListID = 25 + break; + case 4: + // chapterRes = "voices4.res" + // hackVoiceTableListID = 26 + break; + case 5: + // chapterRes = "voices5.res" + // hackVoiceTableListID = 27 + break; + case 6: + // chapterRes = "voices6.res" + // hackVoiceTableListID = 28 + break; + case 7: + break; + case 8: + // chapterRes = "voicess.res" + // hackVoiceTableListID = 22 + break; + } } diff --git a/saga/rscfile.h b/saga/rscfile.h index 217e4b33d4..d096184ba6 100644 --- a/saga/rscfile.h +++ b/saga/rscfile.h @@ -91,11 +91,11 @@ struct ResourceContext { struct MetaResource { int16 sceneIndex; - int16 obectCount; + int16 objectCount; int32 field_4; int32 field_8; int32 mainSpritesID; - int32 objectResourceID; + int32 objectsResourceID; int16 actorCount; int32 field_16; int32 actorsResourceID; @@ -148,7 +148,8 @@ public: ResourceData *getResourceData(ResourceContext *context, uint32 resourceId) const { if (!validResourceId(context, resourceId)) { - error("Resource::getResourceData() wrong resourceId %d", resourceId); + warning("Resource::getResourceData() wrong resourceId %d", resourceId); + assert(0); } return &context->table[resourceId]; } @@ -162,6 +163,8 @@ private: bool loadMacContext(ResourceContext *context); bool loadSagaContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize); + +public: MetaResource _metaResource; }; diff --git a/saga/scene.cpp b/saga/scene.cpp index 23570bb5f7..a131eff7e7 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -418,7 +418,10 @@ static struct SceneSubstitutes { }; void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionType transitionType, int chapter) { - // This is used for latter demos where all places on world map except + + debug(5, "Scene::changeScene(%d, %d, %d, %d)", sceneNumber, actorsEntrance, transitionType, chapter); + + // This is used for latter ITE demos where all places on world map except // Tent Faire are substituted with LBM picture and short description if (_vm->getFeatures() & GF_SCENE_SUBSTITUTES) { for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++) { @@ -627,13 +630,19 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { return; } } -// + if (_sceneLoaded) { error("Scene::loadScene(): Error, a scene is already loaded"); } _loadDescription = true; + if (_vm->getGameType() == GType_IHNM) { + if (loadSceneParams->loadFlag == kLoadBySceneNumber) // When will we get rid of it? + if (loadSceneParams->sceneDescriptor <= 0) + loadSceneParams->sceneDescriptor = _vm->_resource->_metaResource.sceneIndex; + } + switch (loadSceneParams->loadFlag) { case kLoadByResourceId: _sceneNumber = 0; // original assign zero for loaded by resource id @@ -655,7 +664,7 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { break; } - debug(3, "Loading scene number %u:", _sceneNumber); + debug(3, "Loading scene number %d:", _sceneNumber); // Load scene descriptor and resource list resources if (_loadDescription) { diff --git a/saga/script.h b/saga/script.h index a0c00521d1..2ff86c7194 100644 --- a/saga/script.h +++ b/saga/script.h @@ -549,6 +549,7 @@ private: void sfDebugShowData(SCRIPTFUNC_PARAMS); void SF_stub(SCRIPTFUNC_PARAMS); void sfNull(SCRIPTFUNC_PARAMS); + void sfWaitFramesEsc(SCRIPTFUNC_PARAMS); void sfPsychicProfile(SCRIPTFUNC_PARAMS); void sfPsychicProfileOff(SCRIPTFUNC_PARAMS); }; diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index a8d9eee34c..2bbc00d20f 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -237,7 +237,7 @@ static const ScriptFunctionDescription IHNMscriptFunctionsList[IHNM_SCRIPT_FUNCT OPCODE(SF_stub), OPCODE(SF_stub), OPCODE(sfDebugShowData), - OPCODE(SF_stub), + OPCODE(sfWaitFramesEsc), OPCODE(SF_stub), OPCODE(SF_stub) }; @@ -1098,11 +1098,6 @@ void Script::sfPlaceActor(SCRIPTFUNC_PARAMS) { debug(1, "sfPlaceActor(id = %d, x=%d, y=%d, dir=%d, frameType=%d, frameOffset=%d)", actorId, actorLocation.x, actorLocation.y, actorDirection, frameType, frameOffset); - if (_vm->getGameType() == GType_IHNM) { - warning("Actors aren't implemented for IHNM yet"); - return; - } - actor = _vm->_actor->getActor(actorId); actor->location.x = actorLocation.x; actor->location.y = actorLocation.y; @@ -1728,95 +1723,16 @@ void Script::sfEnableEscape(SCRIPTFUNC_PARAMS) { } } -static struct { - int res; - int vol; -} sfxTable[] = { - { FX_DOOR_OPEN, 127 }, - { FX_DOOR_CLOSE, 127 }, - { FX_RUSH_WATER, 63 }, // Floppy volume: 127 - { FX_RUSH_WATER, 26 }, // Floppy volume: 40 - { FX_CRICKET, 64 }, - { FX_PORTICULLIS, 84 }, // Floppy volume: 127 - { FX_CLOCK_1, 64 }, - { FX_CLOCK_2, 64 }, - { FX_DAM_MACHINE, 64 }, - { FX_DAM_MACHINE, 40 }, - { FX_HUM1, 64 }, - { FX_HUM2, 64 }, - { FX_HUM3, 64 }, - { FX_HUM4, 64 }, - { FX_WATER_LOOP_S, 32 }, // Floppy volume: 64 - { FX_SURF, 42 }, // Floppy volume: 127 - { FX_SURF, 32 }, // Floppy volume: 64 - { FX_FIRELOOP, 64 }, // Floppy volume: 96 - { FX_SCRAPING, 84 }, // Floppy volume: 127 - { FX_BEE_SWARM, 64 }, // Floppy volume: 96 - { FX_BEE_SWARM, 26 }, // Floppy volume: 40 - { FX_SQUEAKBOARD, 64 }, - { FX_KNOCK, 127 }, - { FX_COINS, 32 }, // Floppy volume: 48 - { FX_STORM, 84 }, // Floppy volume: 127 - { FX_DOOR_CLOSE_2, 84 }, // Floppy volume: 127 - { FX_ARCWELD, 84 }, // Floppy volume: 127 - { FX_RETRACT_ORB, 127 }, - { FX_DRAGON, 127 }, - { FX_SNORES, 127 }, - { FX_SPLASH, 127 }, - { FX_LOBBY_DOOR, 127 }, - { FX_CHIRP_LOOP, 26 }, // Floppy volume: 40 - { FX_DOOR_CREAK, 96 }, - { FX_SPOON_DIG, 64 }, - { FX_CROW, 96 }, - { FX_COLDWIND, 42 }, // Floppy volume: 64 - { FX_TOOL_SND_1, 96 }, - { FX_TOOL_SND_2, 127 }, - { FX_TOOL_SND_3, 64 }, - { FX_DOOR_METAL, 96 }, - { FX_WATER_LOOP_S, 32 }, - { FX_WATER_LOOP_L, 32 }, // Floppy volume: 64 - { FX_DOOR_OPEN_2, 127 }, - { FX_JAIL_DOOR, 64 }, - { FX_KILN_FIRE, 53 }, // Floppy volume: 80 - - // Only in the CD version - { FX_CROWD_01, 64 }, - { FX_CROWD_02, 64 }, - { FX_CROWD_03, 64 }, - { FX_CROWD_04, 64 }, - { FX_CROWD_05, 64 }, - { FX_CROWD_06, 64 }, - { FX_CROWD_07, 64 }, - { FX_CROWD_08, 64 }, - { FX_CROWD_09, 64 }, - { FX_CROWD_10, 64 }, - { FX_CROWD_11, 64 }, - { FX_CROWD_12, 64 }, - { FX_CROWD_13, 64 }, - { FX_CROWD_14, 64 }, - { FX_CROWD_15, 64 }, - { FX_CROWD_16, 64 }, - { FX_CROWD_17, 64 } -}; - // Script function #70 (0x46) void Script::sfPlaySound(SCRIPTFUNC_PARAMS) { int16 param = thread->pop(); int res; - if (_vm->getGameType() == GType_IHNM) { - int16 param2 = thread->pop(); - - // Here sfxTable comes from Resource #265 - debug(0, "STUB: sfPlaySound(%d, %d)", param, param2); - return; - } - - if (param >= 0 && param < ARRAYSIZE(sfxTable)) { - res = sfxTable[param].res; + if (param >= 0 && param < _vm->_sndRes->_fxTableLen) { + res = _vm->_sndRes->_fxTable[param].res; if (_vm->getFeatures() & GF_CD_FX) res -= 14; - _vm->_sndRes->playSound(res, sfxTable[param].vol, false); + _vm->_sndRes->playSound(res, _vm->_sndRes->_fxTable[param].vol, false); } else { _vm->_sound->stopSound(); } @@ -1827,20 +1743,12 @@ void Script::sfPlayLoopedSound(SCRIPTFUNC_PARAMS) { int16 param = thread->pop(); int res; - if (_vm->getGameType() == GType_IHNM) { - int16 param2 = thread->pop(); - - // Here sfxTable comes from Resource #265 - debug(0, "STUB: sfPlayLoopedSound(%d, %d)", param, param2); - return; - } - - if (param >= 0 && param < ARRAYSIZE(sfxTable)) { - res = sfxTable[param].res; + if (param >= 0 && param < _vm->_sndRes->_fxTableLen) { + res = _vm->_sndRes->_fxTable[param].res; if (_vm->getFeatures() & GF_CD_FX) res -= 14; - _vm->_sndRes->playSound(res, sfxTable[param].vol, true); + _vm->_sndRes->playSound(res, _vm->_sndRes->_fxTable[param].vol, true); } else { _vm->_sound->stopSound(); } @@ -1977,10 +1885,11 @@ void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) { } void Script::sfVsetTrack(SCRIPTFUNC_PARAMS) { - for (int i = 0; i < nArgs; i++) - thread->pop(); + int16 chapter = thread->pop(); + int16 sceneNumber = thread->pop(); + int16 actorsEntrance = thread->pop(); - debug(0, "STUB: sfVsetTrack(), %d args", nArgs); + _vm->_scene->changeScene(sceneNumber, actorsEntrance, kTransitionFade, chapter); } void Script::sfDebugShowData(SCRIPTFUNC_PARAMS) { @@ -1992,6 +1901,10 @@ void Script::sfDebugShowData(SCRIPTFUNC_PARAMS) { _vm->_interface->setStatusText(buf); } +void Script::sfWaitFramesEsc(SCRIPTFUNC_PARAMS) { + thread->_returnValue = 0; +} + void Script::sfNull(SCRIPTFUNC_PARAMS) { for (int i = 0; i < nArgs; i++) thread->pop(); diff --git a/saga/sndres.cpp b/saga/sndres.cpp index f93c595d90..a4e21551b3 100644 --- a/saga/sndres.cpp +++ b/saga/sndres.cpp @@ -25,6 +25,8 @@ #include "saga/saga.h" +#include "saga/itedata.h" +#include "saga/resnames.h" #include "saga/rscfile.h" #include "saga/sndres.h" #include "saga/sound.h" @@ -49,6 +51,47 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm) { _voiceSerial = -1; setVoiceBank(0); + + if (_vm->getGameType() == GType_ITE) { + _fxTable = ITE_SfxTable; + _fxTableLen = ITE_SFXCOUNT; + } else { + ResourceContext *resourceContext; + + resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE); + if (resourceContext == NULL) { + error("Resource::loadGlobalResources() resource context not found"); + } + + byte *resourcePointer; + size_t resourceLength; + + _vm->_resource->loadResource(resourceContext, RID_IHNM_SFX_LUT, + resourcePointer, resourceLength); + + if (resourceLength == 0) { + error("Sndres::SndRes can't read SfxIDs table"); + } + + _fxTableIDsLen = resourceLength / 2; + _fxTableIDs = (int16 *)malloc(_fxTableIDsLen * sizeof(int16)); + + MemoryReadStream metaS(resourcePointer, resourceLength); + for (int i = 0; i < _fxTableIDsLen; i++) + _fxTableIDs[i] = metaS.readSint16LE(); + + free(resourcePointer); + + _fxTable = 0; + _fxTableLen = 0; + } +} + +SndRes::~SndRes() { + if (_vm->getGameType() == GType_IHNM) { + free(_fxTable); + free(_fxTableIDs); + } } void SndRes::setVoiceBank(int serial) diff --git a/saga/sndres.h b/saga/sndres.h index 0a7c3c129c..b4b985979d 100644 --- a/saga/sndres.h +++ b/saga/sndres.h @@ -26,6 +26,7 @@ #ifndef SAGA_SNDRES_H_ #define SAGA_SNDRES_H_ +#include "saga/itedata.h" #include "saga/sound.h" namespace Saga { @@ -34,12 +35,20 @@ class SndRes { public: SndRes(SagaEngine *vm); + ~SndRes(); int loadSound(uint32 resourceId); void playSound(uint32 resourceId, int volume, bool loop); void playVoice(uint32 resourceId); int getVoiceLength(uint32 resourceId); void setVoiceBank(int serial); + + FxTable *_fxTable; + int _fxTableLen; + + int16 *_fxTableIDs; + int _fxTableIDsLen; + private: bool load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader); bool loadVocSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer); diff --git a/saga/sprite.cpp b/saga/sprite.cpp index 6a4b94c441..fb74d85967 100644 --- a/saga/sprite.cpp +++ b/saga/sprite.cpp @@ -51,7 +51,8 @@ Sprite::Sprite(SagaEngine *vm) : _vm(vm) { memoryError("Sprite::Sprite"); } - loadList(_vm->getResourceDescription()->mainSpritesResourceId, _mainSprites); + if (_vm->getGameType() == GType_ITE) + loadList(_vm->getResourceDescription()->mainSpritesResourceId, _mainSprites); } Sprite::~Sprite(void) { diff --git a/saga/sthread.cpp b/saga/sthread.cpp index a52578b554..5816c6c49f 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -338,7 +338,7 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { error("Script::runThread() Invalid script function number (%d)", functionNumber); } - debug(8, "Calling 0x%X %s argCount=%i", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName, argumentsCount); + debug(8, "Calling #%d %s argCount=%i", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName, argumentsCount); scriptFunction = _scriptFunctionsList[functionNumber].scriptFunction; checkStackTopIndex = thread->_stackTopIndex + argumentsCount; disContinue = false; @@ -611,6 +611,11 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { int16 first; const char *strings[ACTOR_SPEECH_STRING_MAX]; + if (_vm->getGameType() == GType_IHNM) { + warning("STUB: opSpeak"); + break; + } + if (_vm->_actor->isSpeaking()) { thread->wait(kWaitTypeSpeech); return false; |