diff options
29 files changed, 656 insertions, 430 deletions
diff --git a/dists/msvc7/saga.vcproj b/dists/msvc7/saga.vcproj index af984f24d1..0542622602 100644 --- a/dists/msvc7/saga.vcproj +++ b/dists/msvc7/saga.vcproj @@ -22,7 +22,7 @@  				Optimization="0"  				InlineFunctionExpansion="0"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;_DEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				MinimalRebuild="TRUE"  				ExceptionHandling="TRUE"  				BasicRuntimeChecks="3" @@ -71,7 +71,7 @@  				FavorSizeOrSpeed="2"  				OmitFramePointers="TRUE"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;NDEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				StringPooling="TRUE"  				ExceptionHandling="TRUE"  				RuntimeLibrary="0" @@ -263,6 +263,9 @@  			RelativePath="..\..\engines\saga\sfuncs.cpp">  		</File>  		<File +			RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp"> +		</File> +		<File  			RelativePath="..\..\engines\saga\sndres.cpp">  		</File>  		<File diff --git a/dists/msvc71/saga.vcproj b/dists/msvc71/saga.vcproj index ce94390696..8834988797 100644 --- a/dists/msvc71/saga.vcproj +++ b/dists/msvc71/saga.vcproj @@ -22,7 +22,7 @@  				Optimization="0"  				InlineFunctionExpansion="0"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;_DEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				MinimalRebuild="TRUE"  				ExceptionHandling="TRUE"  				BasicRuntimeChecks="3" @@ -77,7 +77,7 @@  				FavorSizeOrSpeed="2"  				OmitFramePointers="TRUE"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;NDEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				StringPooling="TRUE"  				ExceptionHandling="TRUE"  				RuntimeLibrary="0" @@ -277,6 +277,9 @@  			RelativePath="..\..\engines\saga\sfuncs.cpp">  		</File>  		<File +			RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp"> +		</File> +		<File  			RelativePath="..\..\engines\saga\sndres.cpp">  		</File>  		<File diff --git a/dists/msvc8/saga.vcproj b/dists/msvc8/saga.vcproj index 1b9c8cbf28..4b035f1809 100644 --- a/dists/msvc8/saga.vcproj +++ b/dists/msvc8/saga.vcproj @@ -43,7 +43,7 @@  				Optimization="0"  				InlineFunctionExpansion="0"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;_DEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				MinimalRebuild="true"  				ExceptionHandling="1"  				BasicRuntimeChecks="3" @@ -120,7 +120,7 @@  				FavorSizeOrSpeed="2"  				OmitFramePointers="true"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;NDEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				StringPooling="true"  				ExceptionHandling="1"  				RuntimeLibrary="0" @@ -379,6 +379,10 @@  			>  		</File>  		<File +			RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp" +			> +		</File> +		<File  			RelativePath="..\..\engines\saga\sndres.cpp"  			>  		</File> diff --git a/dists/msvc9/saga.vcproj b/dists/msvc9/saga.vcproj index 6740a36970..cfe354a985 100644 --- a/dists/msvc9/saga.vcproj +++ b/dists/msvc9/saga.vcproj @@ -44,7 +44,7 @@  				Optimization="0"  				InlineFunctionExpansion="0"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;_DEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				MinimalRebuild="true"  				ExceptionHandling="1"  				BasicRuntimeChecks="3" @@ -121,7 +121,7 @@  				FavorSizeOrSpeed="2"  				OmitFramePointers="true"  				AdditionalIncludeDirectories="../../;../../engines" -				PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" +				PreprocessorDefinitions="WIN32;NDEBUG;ENABLE_IHNM;ENABLE_SAGA2;USE_ZLIB;USE_MAD;USE_VORBIS"  				StringPooling="true"  				ExceptionHandling="1"  				RuntimeLibrary="0" @@ -380,6 +380,10 @@  			>  		</File>  		<File +			RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp" +			> +		</File> +		<File  			RelativePath="..\..\engines\saga\sndres.cpp"  			>  		</File> diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp index ffd725b9da..8b61a9a849 100644 --- a/engines/saga/actor.cpp +++ b/engines/saga/actor.cpp @@ -51,6 +51,7 @@ static int commonObjectCompare(const CommonObjectDataPointer& obj1, const Common  	return 1;  } +#ifdef ENABLE_IHNM  static int commonObjectCompareIHNM(const CommonObjectDataPointer& obj1, const CommonObjectDataPointer& obj2) {  	int p1 = obj1->_location.y;  	int p2 = obj2->_location.y; @@ -60,6 +61,7 @@ static int commonObjectCompareIHNM(const CommonObjectDataPointer& obj1, const Co  		return -1;  	return 1;  } +#endif  static int tileCommonObjectCompare(const CommonObjectDataPointer& obj1, const CommonObjectDataPointer& obj2) {  	int p1 = -obj1->_location.u() - obj1->_location.v() - obj1->_location.z; @@ -182,6 +184,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {  			obj->_location.z = ITE_ObjectTable[i].z;  		}  	} else { +#ifdef ENABLE_IHNM  		// TODO. This is causing problems for SYMBIAN os as it doesn't like a static class here  		ActorData dummyActor; @@ -189,6 +192,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {  		dummyActor._walkStepsPoints = NULL;  		_protagonist = &dummyActor; +#endif  	}  	_dragonHunt = true; @@ -612,6 +616,7 @@ ActorData *Actor::getActor(uint16 actorId) {  void Actor::setProtagState(int state) {  	_protagState = state; +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		if (!_protagonist->_shareFrames)  			free(_protagonist->_frames); @@ -620,6 +625,8 @@ void Actor::setProtagState(int state) {  		_protagonist->_framesCount = _protagStates[state]._framesCount;  		_protagonist->_shareFrames = true;  	} +#endif +  }  int Actor::getFrameType(ActorFrameTypes frameType) { @@ -643,8 +650,8 @@ int Actor::getFrameType(ActorFrameTypes frameType) {  		case kFrameLook:  			return kFrameITELook;  		} -	} -	else { +#ifdef ENABLE_IHNM +	} else if (_vm->getGameId() == GID_IHNM) {  		switch (frameType) {  		case kFrameStand:  			return kFrameIHNMStand; @@ -662,6 +669,7 @@ int Actor::getFrameType(ActorFrameTypes frameType) {  			error("Actor::getFrameType() unknown frame type %d", frameType);  			return kFrameIHNMStand;  		} +#endif  	}  	error("Actor::getFrameType() unknown frame type %d", frameType);  } @@ -689,6 +697,7 @@ ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) {  		return &actor->_frames[frameType].directions[fourDirection];  	} +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		// It is normal for some actors to have no frames for a given frameType  		// These are mainly actors with no frames at all (e.g. narrators or immovable actors) @@ -703,6 +712,8 @@ ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) {  		fourDirection = actorDirectionsLUT[actor->_facingDirection];  		return &actor->_frames[frameType].directions[fourDirection];  	} +#endif +  	return NULL;  } @@ -875,10 +886,12 @@ bool Actor::calcScreenPosition(CommonObjectData *commonObjectData) {  		if (middle <= beginSlope) {  			commonObjectData->_screenScale = 256; +#ifdef ENABLE_IHNM  		} else if (_vm->getGameId() == GID_IHNM && (objectTypeId(commonObjectData->_id) & kGameObjectObject)) {  			commonObjectData->_screenScale = 256;  		} else if (_vm->getGameId() == GID_IHNM && (commonObjectData->_flags & kNoScale)) {  			commonObjectData->_screenScale = 256; +#endif  		} else if (middle >= endSlope) {  			commonObjectData->_screenScale = 1;  		} else { @@ -951,15 +964,17 @@ void Actor::createDrawOrderList() {  	int i;  	ActorData *actor;  	ObjectData *obj; -	CommonObjectOrderList::CompareFunction compareFunction; +	CommonObjectOrderList::CompareFunction compareFunction = 0;  	if (_vm->_scene->getFlags() & kSceneFlagISO) {  		compareFunction = &tileCommonObjectCompare;  	} else {  		if (_vm->getGameId() == GID_ITE)  			compareFunction = &commonObjectCompare; -		else +#ifdef ENABLE_IHNM +		else if (_vm->getGameId() == GID_IHNM)  			compareFunction = &commonObjectCompareIHNM; +#endif  	}  	_drawOrderList.clear(); diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index 2d0e1f6378..0d298bf96a 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -55,9 +55,13 @@ Anim::Anim(SagaEngine *vm) : _vm(vm) {  Anim::~Anim(void) {  	reset(); +#ifdef ENABLE_IHNM  	freeCutawayList(); +#endif  } +#ifdef ENABLE_IHNM +  void Anim::loadCutawayList(const byte *resourcePointer, size_t resourceLength) {  	free(_cutawayList);  	_cutawayListLength = resourceLength / 8; @@ -391,6 +395,8 @@ void Anim::returnFromVideo(void) {  	returnFromCutaway();  } +#endif +  void Anim::load(uint16 animId, const byte *animResourceData, size_t animResourceLength) {  	AnimationData *anim;  	uint16 temp; @@ -935,6 +941,7 @@ void Anim::animInfo() {  	}  } +#ifdef ENABLE_IHNM  void Anim::cutawayInfo() {  	uint16 i; @@ -946,6 +953,7 @@ void Anim::cutawayInfo() {  			_cutawayList[i].cycles, _cutawayList[i].frameRate);  	}  } +#endif  void Anim::resumeAll() {  	// Restore the animations diff --git a/engines/saga/console.cpp b/engines/saga/console.cpp index 47b2484547..c76e50d477 100644 --- a/engines/saga/console.cpp +++ b/engines/saga/console.cpp @@ -104,15 +104,19 @@ bool Console::cmdAnimInfo(int argc, const char **argv) {  }  bool Console::cmdCutawayInfo(int argc, const char **argv) { +#ifdef ENABLE_IHNM  	_vm->_anim->cutawayInfo(); +#endif  	return true;  }  bool Console::cmdPlayCutaway(int argc, const char **argv) { +#ifdef ENABLE_IHNM  	if (argc != 2)  		DebugPrintf("Usage: %s <Cutaway number>\n", argv[0]);  	else  		_vm->_anim->playCutaway(atoi(argv[1]), false); +#endif  	return true;  } diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index 53540186d6..ab0af56cf5 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -321,15 +321,17 @@ const GameDisplayInfo &SagaEngine::getDisplayInfo() {  	switch (_gameDescription->gameId) {  		case GID_ITE:  			return ITE_DisplayInfo; +#ifdef ENABLE_IHNM  		case GID_IHNM:  			return IHNM_DisplayInfo; +#endif  		case GID_DINO: -			return IHNM_DisplayInfo;	// TODO +			return FTA2_DisplayInfo;	// TODO  		case GID_FTA2:  			return FTA2_DisplayInfo;  		default:  			error("getDisplayInfo: Unknown game ID"); -			return IHNM_DisplayInfo;	// unreachable +			return ITE_DisplayInfo;		// unreachable  	}  } diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h index 2381f59681..8dcc729f96 100644 --- a/engines/saga/detection_tables.h +++ b/engines/saga/detection_tables.h @@ -626,7 +626,7 @@ static const SAGAGameDescription gameDescriptions[] = {  	// TODO: Add the Amiga versions here (not supported yet) - +#ifdef ENABLE_IHNM  	// IHNM Section ///////////////////////////////////////////////////////////////////////////////////////////  	// I Have No Mouth And I Must Scream - Demo version @@ -833,6 +833,7 @@ static const SAGAGameDescription gameDescriptions[] = {  		NULL,  		NULL,  	}, +#endif  	// Dinotopia Section ////////////////////////////////////////////////////////////////////////////////////// diff --git a/engines/saga/displayinfo.h b/engines/saga/displayinfo.h index 30c509a59d..7c426409ba 100644 --- a/engines/saga/displayinfo.h +++ b/engines/saga/displayinfo.h @@ -361,7 +361,7 @@ static PanelButton IHNM_SavePanelButtons[] = {  	{kPanelButtonSaveText, -1,30, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0},  }; - +#ifdef ENABLE_IHNM  static const GameDisplayInfo IHNM_DisplayInfo = {  	640, 480,	// logical width&height @@ -427,7 +427,7 @@ static const GameDisplayInfo IHNM_DisplayInfo = {  	ARRAYSIZE(IHNM_SavePanelButtons),  	IHNM_SavePanelButtons  }; - +#endif  // TODO: Fill in missing bits, currently contains IHNM_DisplayInfo  static const GameDisplayInfo FTA2_DisplayInfo = { diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp index 9d862dcad1..0a3b7fe21b 100644 --- a/engines/saga/events.cpp +++ b/engines/saga/events.cpp @@ -155,9 +155,11 @@ int Events::handleContinuous(Event *event) {  		case kEventPalToBlack:  			_vm->_gfx->palToBlack((PalEntry *)event->data, event_pc);  			break; +#ifdef ENABLE_IHNM  		case kEventPalFade:  			_vm->_gfx->palFade((PalEntry *)event->data, event->param, event->param2, event->param3, event->param4, event_pc);  			break; +#endif  		default:  			break;  		} @@ -240,9 +242,11 @@ int Events::handleImmediate(Event *event) {  		case kEventPalToBlack:  			_vm->_gfx->palToBlack((PalEntry *)event->data, event_pc);  			break; +#ifdef ENABLE_IHNM  		case kEventPalFade:  			_vm->_gfx->palFade((PalEntry *)event->data, event->param, event->param2, event->param3, event->param4, event_pc);  			break; +#endif  		default:  			break;  		} @@ -338,6 +342,7 @@ int Events::handleOneShot(Event *event) {  				if (event->param == kEvPSetPalette) {  					PalEntry *palPointer; +#ifdef ENABLE_IHNM  					if (_vm->getGameId() == GID_IHNM) {  						if (_vm->_spiritualBarometer > 255)  							_vm->_gfx->setPaletteColor(kIHNMColorPortrait, 0xff, 0xff, 0xff); @@ -347,6 +352,7 @@ int Events::handleOneShot(Event *event) {  								_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.green / 256,  								_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.blue / 256);  					} +#endif  					_vm->_scene->getBGPal(palPointer);  					_vm->_gfx->setPalette(palPointer); @@ -539,6 +545,7 @@ int Events::handleOneShot(Event *event) {  		default:  			break;  		} +#ifdef ENABLE_IHNM  	case kCutawayEvent:  		switch (event->op) {  		case kEventClear: @@ -550,6 +557,7 @@ int Events::handleOneShot(Event *event) {  		default:  			break;  		} +#endif  	case kActorEvent:  		switch (event->op) {  		case kEventMove: diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp index 5ea7124184..ab73f07968 100644 --- a/engines/saga/font.cpp +++ b/engines/saga/font.cpp @@ -681,6 +681,7 @@ Font::FontId Font::knownFont2FontIdx(KnownFont font) {  			fontId = _vm->_font->valid(kBigFont) ? kBigFont : kMediumFont;  			break;  		} +#ifdef ENABLE_IHNM  	} else if (_vm->getGameId() == GID_IHNM && !(_vm->getFeatures() & GF_IHNM_DEMO)) {  		switch (font) {  		case (kKnownFontSmall): @@ -703,6 +704,7 @@ Font::FontId Font::knownFont2FontIdx(KnownFont font) {  			fontId = kMediumFont; // unchecked  			break;  		} +#endif  	}  	return fontId;  } diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp index b548753c88..9c1b50b8d9 100644 --- a/engines/saga/gfx.cpp +++ b/engines/saga/gfx.cpp @@ -398,6 +398,8 @@ void Gfx::blackToPal(PalEntry *srcPal, double percent) {  	_system->setPalette(_currentPal, 0, PAL_ENTRIES);  } +#ifdef ENABLE_IHNM +  // Used in IHNM only  void Gfx::palFade(PalEntry *srcPal, int16 from, int16 to, int16 start, int16 numColors, double percent) {  	int i; @@ -464,6 +466,8 @@ void Gfx::palFade(PalEntry *srcPal, int16 from, int16 to, int16 start, int16 num  	_system->setPalette(_currentPal, 0, PAL_ENTRIES);  } +#endif +  void Gfx::showCursor(bool state) {  	// Don't show the mouse cursor in the non-interactive part of the IHNM demo  	if (_vm->_scene->isNonInteractiveIHNMDemoPart()) diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp index 166eb97d55..4aa8f6ae27 100644 --- a/engines/saga/interface.cpp +++ b/engines/saga/interface.cpp @@ -180,6 +180,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm) {  		_optionPanel.sprites.spriteCount = 0;  	} +#ifdef ENABLE_IHNM  	// Quit panel  	if (_vm->getGameId() == GID_IHNM) {  		_quitPanel.buttons = _vm->getDisplayInfo().quitPanelButtons; @@ -212,6 +213,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm) {  			&_loadPanel.imageLength, &_loadPanel.imageWidth, &_loadPanel.imageHeight);  		free(resource);  	} +#endif  	// Main panel sprites  	_vm->_sprite->loadList(_vm->getResourceDescription()->mainPanelSpritesResourceId, _mainPanel.sprites); @@ -703,6 +705,7 @@ bool Interface::processAscii(Common::KeyState keystate) {  		}  		break;  	case kPanelPlacard: +#ifdef ENABLE_IHNM  		if (_vm->getGameId() == GID_IHNM) {  			// Any keypress here returns the user back to the game  			if (!(_vm->getFeatures() & GF_IHNM_DEMO)) { @@ -713,6 +716,7 @@ bool Interface::processAscii(Common::KeyState keystate) {  				_vm->_script->wakeUpThreads(kWaitTypeDelay);  			}  		} +#endif  		break;  	}  	return false; @@ -1055,9 +1059,11 @@ void Interface::setQuit(PanelButton *panelButton) {  			setMode(kPanelOption);  			break;  		case kTextQuit: +#ifdef ENABLE_IHNM  			if (_vm->getFeatures() & GF_IHNM_DEMO)  				_vm->_scene->creditsScene();	// display sales info for IHNM demo  			else +#endif  				_vm->quitGame();  			break;  	} @@ -1822,6 +1828,7 @@ void Interface::update(const Point& mousePoint, int updateFlag) {  		break;  	case kPanelPlacard: +#ifdef ENABLE_IHNM  		if (_vm->getGameId() == GID_IHNM) {  			// Any mouse click here returns the user back to the game  			if (updateFlag & UPDATE_MOUSECLICK) { @@ -1834,6 +1841,7 @@ void Interface::update(const Point& mousePoint, int updateFlag) {  				}  			}  		} +#endif  		break;  	case kPanelNull: diff --git a/engines/saga/introproc_fta2.cpp b/engines/saga/introproc_fta2.cpp index 4e9541d0b9..fe1079e45b 100644 --- a/engines/saga/introproc_fta2.cpp +++ b/engines/saga/introproc_fta2.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_SAGA2 +  // "Faery Tale Adventure II: Halls of the Dead" Intro sequence scene procedures  #include "saga/saga.h" @@ -209,3 +211,5 @@ int Scene::FTA2EndProc(FTA2Endings whichEnding) {  }  } // End of namespace Saga + +#endif
\ No newline at end of file diff --git a/engines/saga/introproc_ihnm.cpp b/engines/saga/introproc_ihnm.cpp index 0b4ef6eb6a..a8970ffd6f 100644 --- a/engines/saga/introproc_ihnm.cpp +++ b/engines/saga/introproc_ihnm.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_IHNM +  // "I Have No Mouth" Intro sequence scene procedures  #include "saga/saga.h" @@ -290,3 +292,5 @@ bool Scene::playLoopingTitle(int title, int seconds) {  }  } // End of namespace Saga + +#endif diff --git a/engines/saga/module.mk b/engines/saga/module.mk index 24ebc40a4e..0c9c219621 100644 --- a/engines/saga/module.mk +++ b/engines/saga/module.mk @@ -14,9 +14,7 @@ MODULE_OBJS := \  	image.o \  	input.o \  	interface.o \ -	introproc_ihnm.o \  	introproc_ite.o \ -	introproc_fta2.o \  	isomap.o \  	itedata.o \  	music.o \ @@ -25,8 +23,6 @@ MODULE_OBJS := \  	puzzle.o \  	render.o \  	resource.o \ -	resource_hrs.o \ -	resource_res.o \  	resource_rsc.o \  	saga.o \  	saveload.o \ @@ -38,6 +34,19 @@ MODULE_OBJS := \  	sprite.o \  	sthread.o +ifdef ENABLE_IHNM +MODULE_OBJS += \ +	introproc_ihnm.o \ +	resource_res.o \ +	sfuncs_ihnm.o +endif + +ifdef ENABLE_SAGA2 +MODULE_OBJS += \ +	introproc_fta2.o \ +	resource_hrs.o +endif +  # This module can be built as a plugin  ifeq ($(ENABLE_SAGA), DYNAMIC_PLUGIN)  PLUGIN := 1 diff --git a/engines/saga/resource.h b/engines/saga/resource.h index 3519116682..90afee78d9 100644 --- a/engines/saga/resource.h +++ b/engines/saga/resource.h @@ -183,6 +183,7 @@ private:  	}  }; +#ifdef ENABLE_IHNM  // IHNM  class Resource_RES : public Resource {  public: @@ -197,7 +198,9 @@ private:  	}  	MetaResource _metaResource;  }; +#endif +#ifdef ENABLE_SAGA2  // DINO, FTA2  class Resource_HRS : public Resource {  public: @@ -215,6 +218,7 @@ private:  	}  	bool loadResContext_v2(ResourceContext *context, uint32 contextSize);  }; +#endif  } // End of namespace Saga diff --git a/engines/saga/resource_hrs.cpp b/engines/saga/resource_hrs.cpp index cc59f7ccc9..e06d03c604 100644 --- a/engines/saga/resource_hrs.cpp +++ b/engines/saga/resource_hrs.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_SAGA2 +  // HRS Resource file management module (SAGA 2, used in DINO and FTA2)  #include "saga/saga.h" @@ -102,3 +104,5 @@ bool Resource_HRS::loadResContext_v2(ResourceContext *context, uint32 contextSiz  }  } // End of namespace Saga + +#endif diff --git a/engines/saga/resource_res.cpp b/engines/saga/resource_res.cpp index 282eac3fc1..ca3c2a7ae0 100644 --- a/engines/saga/resource_res.cpp +++ b/engines/saga/resource_res.cpp @@ -39,6 +39,8 @@  namespace Saga { +#ifdef ENABLE_IHNM +  static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 };  static int metaResourceTableDemo[] = { 0, 0, 0, 0, 0, 0, 0, 285, 0 }; @@ -213,5 +215,6 @@ void Resource_RES::loadGlobalResources(int chapter, int actorsEntrance) {  	_vm->_spiritualBarometer = 0;  	_vm->_scene->setChapterNumber(chapter);  } +#endif  } // End of namespace Saga diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index 7f9fd6870c..4781ef79ab 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -167,13 +167,17 @@ Common::Error SagaEngine::init() {  		case GID_ITE:  			_resource = new Resource_RSC(this);  			break; +#ifdef ENABLE_IHNM  		case GID_IHNM:  			_resource = new Resource_RES(this);  			break; +#endif +#ifdef ENABLE_SAGA2  		case GID_DINO:  		case GID_FTA2:  			_resource = new Resource_HRS(this);  			break; +#endif  	}  	// Detect game and open resource files @@ -513,6 +517,7 @@ ColorId SagaEngine::KnownColor2ColorId(KnownColor knownColor) {  		default:  			error("SagaEngine::KnownColor2ColorId unknown color %i", knownColor);  		} +#ifdef ENABLE_IHNM  	} else if (getGameId() == GID_IHNM) {  		// The default colors in the Spanish version of IHNM are shifted by one  		// Fixes bug #1848016 - "IHNM: Wrong Subtitles Color (Spanish)" @@ -544,6 +549,7 @@ ColorId SagaEngine::KnownColor2ColorId(KnownColor knownColor) {  		default:  			error("SagaEngine::KnownColor2ColorId unknown color %i", knownColor);  		} +#endif  	}  	return colorId;  } diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp index 5aa0a1fc6e..94237d6d0b 100644 --- a/engines/saga/saveload.cpp +++ b/engines/saga/saveload.cpp @@ -199,6 +199,7 @@ void SagaEngine::save(const char *fileName, const char *saveName) {  	// Surrounding scene  	out->writeSint32LE(_scene->getOutsetSceneNumber()); +#ifdef ENABLE_IHNM  	if (getGameId() == GID_IHNM) {  		out->writeSint32LE(_scene->currentChapterNumber());  		// Protagonist @@ -206,15 +207,17 @@ void SagaEngine::save(const char *fileName, const char *saveName) {  		out->writeSint32LE(_scene->getCurrentMusicTrack());  		out->writeSint32LE(_scene->getCurrentMusicRepeat());  	} - +#endif  	// Inset scene  	out->writeSint32LE(_scene->currentSceneNumber()); +#ifdef ENABLE_IHNM  	if (getGameId() == GID_IHNM) {  		out->writeUint32LE(_globalFlags);  		for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++)  			out->writeSint16LE(_ethicsPoints[i]);  	} +#endif  	_interface->saveState(out); @@ -288,6 +291,7 @@ void SagaEngine::load(const char *fileName) {  	// Surrounding scene  	sceneNumber = in->readSint32LE(); +#ifdef ENABLE_IHNM  	if (getGameId() == GID_IHNM) {  		int currentChapter = _scene->currentChapterNumber();  		_scene->setChapterNumber(in->readSint32LE()); @@ -305,15 +309,18 @@ void SagaEngine::load(const char *fileName) {  			_music->play(3, MUSIC_LOOP);  		}  	} +#endif  	// Inset scene  	insetSceneNumber = in->readSint32LE(); +#ifdef ENABLE_IHNM  	if (getGameId() == GID_IHNM) {  		_globalFlags = in->readUint32LE();  		for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++)  			_ethicsPoints[i] = in->readSint16LE();  	} +#endif  	_interface->loadState(in); @@ -334,6 +341,7 @@ void SagaEngine::load(const char *fileName) {  	if (getGameId() == GID_ITE)  		_isoMap->setMapPosition(mapx, mapy); +#ifdef ENABLE_IHNM  	// Protagonist swapping  	if (getGameId() == GID_IHNM) {  		if (_scene->currentProtag() != 0 && _scene->currentChapterNumber() != 6) { @@ -355,6 +363,7 @@ void SagaEngine::load(const char *fileName) {  			_scene->setProtag(actor1->_id);  		}  	} +#endif  	_scene->clearSceneQueue();  	_scene->changeScene(sceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade); diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp index 40d0ddcc90..b5b9aaa2ea 100644 --- a/engines/saga/scene.cpp +++ b/engines/saga/scene.cpp @@ -82,6 +82,7 @@ SAGA_UNKNOWN,  	SAGA_PALETTE  }; +#ifdef ENABLE_IHNM  static SAGAResourceTypes IHNMSceneResourceTypes[28] = {  	SAGA_ACTOR,  SAGA_UNKNOWN, @@ -112,6 +113,7 @@ SAGA_UNKNOWN,  	SAGA_FACES,  	SAGA_PALETTE  }; +#endif  const char *SAGAResourceTypesString[] = {  	"SAGA_UNKNOWN", @@ -238,12 +240,14 @@ Scene::~Scene() {  }  void Scene::getResourceTypes(SAGAResourceTypes *&types, int &typesCount) { -	if (_vm->getGameId() == GID_IHNM) { -		typesCount = ARRAYSIZE(IHNMSceneResourceTypes); -		types = IHNMSceneResourceTypes; -	} else { +	if (_vm->getGameId() == GID_ITE) {  		typesCount = ARRAYSIZE(ITESceneResourceTypes);  		types = ITESceneResourceTypes; +#ifdef ENABLE_IHNM +	} else if (_vm->getGameId() == GID_IHNM) { +		typesCount = ARRAYSIZE(IHNMSceneResourceTypes); +		types = IHNMSceneResourceTypes; +#endif  	}  } @@ -286,15 +290,19 @@ void Scene::startScene() {  	case GID_ITE:  		ITEStartProc();  		break; +#ifdef ENABLE_IHNM  	case GID_IHNM:  		IHNMStartProc();  		break; +#endif +#ifdef ENABLE_SAGA2  	case GID_DINO:  		// TODO  		break;  	case GID_FTA2:  		FTA2StartProc();  		break; +#endif  	default:  		error("Scene::start(): Error: Can't start game... gametype not supported");  		break; @@ -314,6 +322,8 @@ void Scene::startScene() {  	loadScene(sceneQueue);  } +#ifdef ENABLE_IHNM +  void Scene::creditsScene() {  	// End the last game ending scene  	_vm->_scene->endScene(); @@ -339,6 +349,8 @@ void Scene::creditsScene() {  	return;  } +#endif +  void Scene::nextScene() {  	SceneQueueList::iterator queueIterator;  	LoadSceneParams *sceneQueue; @@ -619,6 +631,7 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {  	_chapterPointsChanged = false; +#ifdef ENABLE_IHNM  	if ((_vm->getGameId() == GID_IHNM) && (loadSceneParams->chapter != NO_CHAPTER_CHANGE)) {  		if (loadSceneParams->loadFlag != kLoadBySceneNumber) {  			error("loadScene wrong usage"); @@ -657,6 +670,7 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {  			return;  		}  	} +#endif  	if (_sceneLoaded) {  		error("Scene::loadScene(): Error, a scene is already loaded"); @@ -664,11 +678,13 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {  	_loadDescription = true; +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		if (loadSceneParams->loadFlag == kLoadBySceneNumber) // When will we get rid of it?  			if (loadSceneParams->sceneDescriptor <= 0)  				loadSceneParams->sceneDescriptor = _vm->_resource->getMetaResource()->sceneIndex;  	} +#endif  	switch (loadSceneParams->loadFlag) {  	case kLoadByResourceId: @@ -1365,6 +1381,7 @@ void Scene::clearPlacard() {  	event.duration = 0;  	q_event = _vm->_events->chain(q_event, &event); +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		// set mode to main  		event.type = kEvTImmediate; @@ -1375,6 +1392,7 @@ void Scene::clearPlacard() {  		event.duration = 0;  		q_event = _vm->_events->chain(q_event, &event);  	} +#endif  	// Display scene background, but stay with black palette  	event.type = kEvTImmediate; diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp index 62c7c3e368..a39f2ddb3d 100644 --- a/engines/saga/script.cpp +++ b/engines/saga/script.cpp @@ -163,7 +163,19 @@ Script::Script(SagaEngine *vm) : _vm(vm) {  	free(stringsPointer);  	setupScriptOpcodeList(); -	setupScriptFuncList(); + +	// Setup script functions +	switch (_vm->getGameId()) { +		case GID_ITE: +			setupITEScriptFuncList(); +			break; +#ifdef ENABLE_IHNM +		case GID_IHNM: +			setupIHNMScriptFuncList(); +			break; +#endif +		// TODO: FTA2 and DINO +	}  }  // Shut down script module gracefully; free all allocated module resources @@ -566,12 +578,18 @@ void Script::opCcall(SCRIPTOP_PARAMS) {  	if (stopParsing)  		return; -	if (scriptFunction == &Saga::Script::sfScriptGotoScene || -		scriptFunction == &Saga::Script::sfVsetTrack) { +	if (scriptFunction == &Saga::Script::sfScriptGotoScene) {  		stopParsing = true; // cause abortAllThreads called and _this_ thread destroyed  		return;  	} +#ifdef ENABLE_IHNM +	if (scriptFunction == &Saga::Script::sfVsetTrack) { +		stopParsing = true; +		return;		// cause abortAllThreads called and _this_ thread destroyed +	} +#endif +  	thread->_stackTopIndex = checkStackTopIndex;  	thread->push(thread->_returnValue);		// return value @@ -607,11 +625,17 @@ void Script::opCcallV(SCRIPTOP_PARAMS) {  	if (stopParsing)  		return; -	if (scriptFunction == &Saga::Script::sfScriptGotoScene || -		scriptFunction == &Saga::Script::sfVsetTrack) { +	if (scriptFunction == &Saga::Script::sfScriptGotoScene) { +		stopParsing = true; +		return;		// cause abortAllThreads called and _this_ thread destroyed +	} + +#ifdef ENABLE_IHNM +	if (scriptFunction == &Saga::Script::sfVsetTrack) {  		stopParsing = true;  		return;		// cause abortAllThreads called and _this_ thread destroyed  	} +#endif  	thread->_stackTopIndex = checkStackTopIndex; @@ -1556,6 +1580,7 @@ void Script::playfieldClick(const Point& mousePoint, bool leftButton) {  		}  	} +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		if ((_pendingVerb == getVerbType(kVerbWalkTo)) || @@ -1607,6 +1632,7 @@ void Script::playfieldClick(const Point& mousePoint, bool leftButton) {  			}  		}  	} +#endif  } diff --git a/engines/saga/script.h b/engines/saga/script.h index 9785ef9a77..608891bb8a 100644 --- a/engines/saga/script.h +++ b/engines/saga/script.h @@ -275,6 +275,7 @@ typedef SortedList<ScriptThread> ScriptThreadList;  #define SCRIPTOP_PARAMS ScriptThread *thread, MemoryReadStream *scriptS, bool &stopParsing, bool &breakOut  #define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs, bool &disContinue +#define OPCODE(x) {&Script::x, #x}  class Script {  public: @@ -498,7 +499,8 @@ private:  	};  	const ScriptFunctionDescription *_scriptFunctionsList; -	void setupScriptFuncList(); +	void setupITEScriptFuncList(); +	void setupIHNMScriptFuncList();  	void sfPutString(SCRIPTFUNC_PARAMS);  	void sfWait(SCRIPTFUNC_PARAMS); @@ -613,7 +615,7 @@ private:  	void sfQueueMusic(SCRIPTFUNC_PARAMS);  	void sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS); -	void SF_stub(const char *name, ScriptThread *thread, int nArgs); +	void sfStub(const char *name, ScriptThread *thread, int nArgs);  };  } // End of namespace Saga diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp index 9c93687a48..8467c9f9ed 100644 --- a/engines/saga/sfuncs.cpp +++ b/engines/saga/sfuncs.cpp @@ -52,9 +52,7 @@  namespace Saga { -#define OPCODE(x) {&Script::x, #x} - -void Script::setupScriptFuncList() { +void Script::setupITEScriptFuncList() {  	static const ScriptFunctionDescription ITEScriptFunctionsList[ITE_SCRIPT_FUNCTION_MAX] = {  		OPCODE(sfPutString),  		OPCODE(sfWait), @@ -136,117 +134,7 @@ void Script::setupScriptFuncList() {  		OPCODE(sfPlayVoice)  	}; -static const ScriptFunctionDescription IHNMScriptFunctionsList[IHNM_SCRIPT_FUNCTION_MAX] = { -		OPCODE(sfNull), -		OPCODE(sfWait), -		OPCODE(sfTakeObject), -		OPCODE(sfIsCarried), -		OPCODE(sfStatusBar), -		OPCODE(sfMainMode), -		OPCODE(sfScriptWalkTo), -		OPCODE(sfScriptDoAction), -		OPCODE(sfSetActorFacing), -		OPCODE(sfStartBgdAnim), -		OPCODE(sfStopBgdAnim), -		OPCODE(sfLockUser), -		OPCODE(sfPreDialog), -		OPCODE(sfKillActorThreads), -		OPCODE(sfFaceTowards), -		OPCODE(sfSetFollower), -		OPCODE(sfScriptGotoScene), -		OPCODE(sfSetObjImage), -		OPCODE(sfSetObjName), -		OPCODE(sfGetObjImage), -		OPCODE(sfGetNumber), -		OPCODE(sfScriptOpenDoor), -		OPCODE(sfScriptCloseDoor), -		OPCODE(sfSetBgdAnimSpeed), -		OPCODE(sfCycleColors), -		OPCODE(sfDoCenterActor), -		OPCODE(sfStartBgdAnimSpeed), -		OPCODE(sfScriptWalkToAsync), -		OPCODE(sfEnableZone), -		OPCODE(sfSetActorState), -		OPCODE(sfScriptMoveTo), -		OPCODE(sfSceneEq), -		OPCODE(sfDropObject), -		OPCODE(sfFinishBgdAnim), -		OPCODE(sfSwapActors), -		OPCODE(sfSimulSpeech), -		OPCODE(sfScriptWalk), -		OPCODE(sfCycleFrames), -		OPCODE(sfSetFrame), -		OPCODE(sfSetPortrait), -		OPCODE(sfSetProtagPortrait), -		OPCODE(sfChainBgdAnim), -		OPCODE(sfScriptSpecialWalk), -		OPCODE(sfPlaceActor), -		OPCODE(sfCheckUserInterrupt), -		OPCODE(sfScriptWalkRelative), -		OPCODE(sfScriptMoveRelative), -		OPCODE(sfSimulSpeech2), -		OPCODE(sfPsychicProfile), -		OPCODE(sfPsychicProfileOff), -		OPCODE(sfSetProtagState), -		OPCODE(sfResumeBgdAnim), -		OPCODE(sfThrowActor), -		OPCODE(sfWaitWalk), -		OPCODE(sfScriptSceneID), -		OPCODE(sfChangeActorScene), -		OPCODE(sfScriptClimb), -		OPCODE(sfSetDoorState), -		OPCODE(sfSetActorZ), -		OPCODE(sfScriptText), -		OPCODE(sfGetActorX), -		OPCODE(sfGetActorY), -		OPCODE(sfEraseDelta), -		OPCODE(sfPlayMusic), -		OPCODE(sfNull), -		OPCODE(sfEnableEscape), -		OPCODE(sfPlaySound), -		OPCODE(sfPlayLoopedSound), -		OPCODE(sfGetDeltaFrame), -		OPCODE(sfNull), -		OPCODE(sfNull), -		OPCODE(sfRand), -		OPCODE(sfFadeMusic), -		OPCODE(sfNull), -		OPCODE(sfSetChapterPoints), -		OPCODE(sfSetPortraitBgColor), -		OPCODE(sfScriptStartCutAway), -		OPCODE(sfReturnFromCutAway), -		OPCODE(sfEndCutAway), -		OPCODE(sfGetMouseClicks), -		OPCODE(sfResetMouseClicks), -		OPCODE(sfWaitFrames), -		OPCODE(sfScriptFade), -		OPCODE(sfScriptStartVideo), -		OPCODE(sfScriptReturnFromVideo), -		OPCODE(sfScriptEndVideo), -		OPCODE(sfSetActorZ), -		OPCODE(sfShowIHNMDemoHelpBg), -		OPCODE(sfAddIHNMDemoHelpTextLine), -		OPCODE(sfShowIHNMDemoHelpPage), -		OPCODE(sfVstopFX), -		OPCODE(sfVstopLoopedFX), -		OPCODE(sfDemoSetInteractive),	// only used in the demo version of IHNM -		OPCODE(sfDemoIsInteractive), -		OPCODE(sfVsetTrack), -		OPCODE(sfGetPoints), -		OPCODE(sfSetGlobalFlag), -		OPCODE(sfClearGlobalFlag), -		OPCODE(sfTestGlobalFlag), -		OPCODE(sfSetPoints), -		OPCODE(sfSetSpeechBox), -		OPCODE(sfDebugShowData), -		OPCODE(sfWaitFramesEsc), -		OPCODE(sfQueueMusic), -		OPCODE(sfDisableAbortSpeeches) -	}; -	if (_vm->getGameId() == GID_IHNM) -		_scriptFunctionsList = IHNMScriptFunctionsList; -	else -		_scriptFunctionsList = ITEScriptFunctionsList; +	_scriptFunctionsList = ITEScriptFunctionsList;  }  // Script function #0 (0x00) @@ -550,19 +438,23 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {  	int16 sceneNumber = thread->pop();  	int16 entrance = thread->pop(); +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		_vm->_gfx->setCursor(kCursorBusy);  	} +#endif  	if (_vm->getGameId() == GID_ITE && sceneNumber < 0) {  		_vm->quitGame();  		return;  	} +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM && sceneNumber == 0) {  		_vm->_scene->creditsScene();  		return;  	} +#endif  	// It is possible to leave scene when converse panel is on,  	// particulalrly it may happen at Moneychanger tent. This @@ -590,6 +482,7 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {  	_currentObject[0] = _currentObject[1] = ID_NOTHING;  	showVerb();	// calls setStatusText("") +#ifdef ENABLE_IHNM  	if (_vm->getGameId() == GID_IHNM) {  		// There are some cutaways which are not removed by game scripts, like the cutaway  		// after the intro of IHNM or the cutaway at the end of Ellen's part in the IHNM demo. @@ -597,6 +490,8 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {  		_vm->_anim->clearCutaway();  		_vm->_gfx->setCursor(kCursorNormal);  	} +#endif +  }  // Script function #17 (0x11) @@ -689,7 +584,7 @@ void Script::sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS) {  // Script function #24 (0x18)  void Script::sfCycleColors(SCRIPTFUNC_PARAMS) { -	SF_stub("sfCycleColors", thread, nArgs); +	sfStub("sfCycleColors", thread, nArgs);  	error("Please, report this to sev");  } @@ -1640,13 +1535,13 @@ void Script::sfPlayVoice(SCRIPTFUNC_PARAMS) {  void Script::finishDialog(int strID, int replyID, int flags, int bitOffset) {  	byte *addr; -	const char *str;  	if (_conversingThread) {  		_vm->_interface->setMode(kPanelNull); +#ifdef ENABLE_IHNM  		if (_vm->getGameId() == GID_IHNM) { -			str = _conversingThread->_strings->getString(strID); +			const char *str = _conversingThread->_strings->getString(strID);  			if (*str != '[') {  				int sampleResourceId = -1;  				sampleResourceId = _conversingThread->_voiceLUT->voices[strID]; @@ -1656,6 +1551,7 @@ void Script::finishDialog(int strID, int replyID, int flags, int bitOffset) {  				_vm->_actor->actorSpeech(_vm->_actor->_protagonist->_id, &str, 1, sampleResourceId, 0);  			}  		} +#endif  		_conversingThread->_flags &= ~kTFlagWaiting; @@ -1671,291 +1567,12 @@ void Script::finishDialog(int strID, int replyID, int flags, int bitOffset) {  	wakeUpThreads(kWaitTypeDialogBegin);  } -void Script::sfSetChapterPoints(SCRIPTFUNC_PARAMS) { -	int chapter = _vm->_scene->currentChapterNumber(); -	_vm->_ethicsPoints[chapter] = thread->pop(); -	int16 barometer = thread->pop(); -	static PalEntry cur_pal[PAL_ENTRIES]; - -	_vm->_spiritualBarometer = _vm->_ethicsPoints[chapter] * 256 / barometer; -	_vm->_scene->setChapterPointsChanged(true);		// don't save this music when saving in IHNM - -	if (_vm->_spiritualBarometer > 255) -		_vm->_gfx->setPaletteColor(kIHNMColorPortrait, 0xff, 0xff, 0xff); -	else -		_vm->_gfx->setPaletteColor(kIHNMColorPortrait, -			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.red / 256, -			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.green / 256, -			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.blue / 256); - -	_vm->_gfx->getCurrentPal(cur_pal); -	_vm->_gfx->setPalette(cur_pal); -} - -void Script::sfSetPortraitBgColor(SCRIPTFUNC_PARAMS) { -	int16 red = thread->pop(); -	int16 green = thread->pop(); -	int16 blue = thread->pop(); - -	_vm->_interface->setPortraitBgColor(red, green, blue); -} - -void Script::sfScriptStartCutAway(SCRIPTFUNC_PARAMS) { -	int16 cut = thread->pop(); -	thread->pop();		// Not used -	int16 fade = thread->pop(); - -	_vm->_anim->setCutAwayMode(kPanelCutaway); -	_vm->_anim->playCutaway(cut, fade != 0); -} - -void Script::sfReturnFromCutAway(SCRIPTFUNC_PARAMS) { -	_vm->_anim->returnFromCutaway(); -	thread->wait(kWaitTypeWakeUp); -} - -void Script::sfEndCutAway(SCRIPTFUNC_PARAMS) { -	_vm->_anim->endCutaway(); -} - -void Script::sfGetMouseClicks(SCRIPTFUNC_PARAMS) { -	thread->_returnValue = _vm->getMouseClickCount(); -} - -void Script::sfResetMouseClicks(SCRIPTFUNC_PARAMS) { -	_vm->resetMouseClickCount(); -} - -// Used in IHNM only -// Param1: frames -void Script::sfWaitFrames(SCRIPTFUNC_PARAMS) { -	int16 frames = thread->pop(); - -	if (!_skipSpeeches) -		thread->waitFrames(_vm->_frameCount + frames); -} - -void Script::sfScriptFade(SCRIPTFUNC_PARAMS) { -	int16 firstPalEntry = thread->pop(); -	int16 lastPalEntry = thread->pop(); -	int16 startingBrightness = thread->pop(); -	int16 endingBrightness = thread->pop(); -	Event event; -	static PalEntry cur_pal[PAL_ENTRIES]; - -	_vm->_gfx->getCurrentPal(cur_pal); -	event.type = kEvTImmediate; -	event.code = kPalEvent; -	event.op = kEventPalFade; -	event.time = 0; -	event.duration = kNormalFadeDuration; -	event.data = cur_pal; -	event.param = startingBrightness; -	event.param2 = endingBrightness; -	event.param3 = firstPalEntry; -	event.param4 = lastPalEntry - firstPalEntry + 1; -	_vm->_events->queue(&event); -} - -void Script::sfScriptStartVideo(SCRIPTFUNC_PARAMS) { -	int16 vid = thread->pop(); -	int16 fade = thread->pop(); - -	_vm->_anim->setCutAwayMode(kPanelVideo); -	_vm->_anim->startVideo(vid, fade != 0); -} - -void Script::sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS) { -	_vm->_anim->returnFromVideo(); -} - -void Script::sfScriptEndVideo(SCRIPTFUNC_PARAMS) { -	_vm->_anim->endVideo(); -} - -void Script::sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS) { -	_ihnmDemoCurrentY = 0; -	_vm->_scene->_textList.clear(); -	_vm->_interface->setMode(kPanelConverse); -	_vm->_scene->showPsychicProfile(NULL); -} - -void Script::sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS) { -	int stringId = thread->pop(); -	TextListEntry textEntry; -	Event event; - -	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 += _vm->_font->getHeight(kKnownFontVerb, thread->_strings->getString(stringId), 226, kFontCentered); -} - -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) { -	_vm->_sound->stopSound(); -} - -void Script::sfVstopLoopedFX(SCRIPTFUNC_PARAMS) { -	_vm->_sound->stopSound(); -} - -void Script::sfDemoSetInteractive(SCRIPTFUNC_PARAMS) { -	if (thread->pop() == 0) { -		_vm->_interface->deactivate(); -		_vm->_interface->setMode(kPanelNull); -	} - -	// Note: the original also sets an appropriate flag here, but we don't, -	// as we don't use it -} - -void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) { -	thread->_returnValue = 0; -} - -void Script::sfVsetTrack(SCRIPTFUNC_PARAMS) { -	int16 chapter = thread->pop(); -	int16 sceneNumber = thread->pop(); -	int16 actorsEntrance = thread->pop(); - -	debug(2, "sfVsetTrrack(%d, %d, %d)", chapter, sceneNumber, actorsEntrance); - -	_vm->_scene->changeScene(sceneNumber, actorsEntrance, kTransitionFade, chapter); -} - -void Script::sfGetPoints(SCRIPTFUNC_PARAMS) { -	int16 index = thread->pop(); - -	if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) -		thread->_returnValue = _vm->_ethicsPoints[index]; -	else -		thread->_returnValue = 0; -} - -void Script::sfSetGlobalFlag(SCRIPTFUNC_PARAMS) { -	int16 flag = thread->pop(); - -	if (flag >= 0 && flag < 32) -		_vm->_globalFlags |= (1 << flag); -} - -void Script::sfClearGlobalFlag(SCRIPTFUNC_PARAMS) { -	int16 flag = thread->pop(); - -	if (flag >= 0 && flag < 32) -		_vm->_globalFlags &= ~(1 << flag); -} - -void Script::sfTestGlobalFlag(SCRIPTFUNC_PARAMS) { -	int16 flag = thread->pop(); - -	if (flag >= 0 && flag < 32 && _vm->_globalFlags & (1 << flag)) -		thread->_returnValue = 1; -	else -		thread->_returnValue = 0; -} - -void Script::sfSetPoints(SCRIPTFUNC_PARAMS) { -	int16 index = thread->pop(); -	int16 points = thread->pop(); - -	if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) -		_vm->_ethicsPoints[index] = points; -} - -void Script::sfSetSpeechBox(SCRIPTFUNC_PARAMS) { -	int16 param1 = thread->pop(); -	int16 param2 = thread->pop(); -	int16 param3 = thread->pop(); -	int16 param4 = thread->pop(); - -	_vm->_actor->_speechBoxScript.left = param1; -	_vm->_actor->_speechBoxScript.top = param2; -	_vm->_actor->_speechBoxScript.setWidth(param3 - param1); -	_vm->_actor->_speechBoxScript.setHeight(param4 - param2); -} - -void Script::sfDebugShowData(SCRIPTFUNC_PARAMS) { -	int16 param = thread->pop(); -	char buf[50]; - -	snprintf(buf, 50, "Reached breakpoint %d", param); - -	_vm->_interface->setStatusText(buf); -} - -void Script::sfWaitFramesEsc(SCRIPTFUNC_PARAMS) { -	thread->_returnValue = _vm->_framesEsc; -} - -void Script::sfQueueMusic(SCRIPTFUNC_PARAMS) { -	int16 param1 = thread->pop(); -	int16 param2 = thread->pop(); -	Event event; - -	if (param1 < 0) { -		_vm->_music->stop(); -		return; -	} - -	if (param1 >= _vm->_music->_songTableLen) { -		warning("sfQueueMusic: Wrong song number (%d > %d)", param1, _vm->_music->_songTableLen - 1); -	} else { -		_vm->_music->setVolume(_vm->_musicVolume, 1); -		event.type = kEvTOneshot; -		event.code = kMusicEvent; -		event.param = _vm->_music->_songTable[param1]; -		event.param2 = param2 ? MUSIC_LOOP : MUSIC_NORMAL; -		event.op = kEventPlay; -		event.time = _vm->ticksToMSec(500);		// I find the delay in the original to be too long, so I've set it to -												// wait for half the time, which sounds better when chapter points -												// change -												// FIXME: If this is too short for other cases apart from chapter -												// point change, set it back to 1000 -		_vm->_events->queue(&event); - -		if (!_vm->_scene->haveChapterPointsChanged()) { -			_vm->_scene->setCurrentMusicTrack(param1); -			_vm->_scene->setCurrentMusicRepeat(param2); -		} else { -			// Don't save this music track when saving in IHNM -			_vm->_scene->setChapterPointsChanged(false); -		} -	} -} - -void Script::sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS) { -	_vm->_interface->disableAbortSpeeches(thread->pop() != 0); -} -  void Script::sfNull(SCRIPTFUNC_PARAMS) {  	for (int i = 0; i < nArgs; i++)  		thread->pop();  } -void Script::SF_stub(const char *name, ScriptThread *thread, int nArgs) { +void Script::sfStub(const char *name, ScriptThread *thread, int nArgs) {  	char buf[256], buf1[100];  	snprintf(buf, 256, "STUB: %s(", name); diff --git a/engines/saga/sfuncs_ihnm.cpp b/engines/saga/sfuncs_ihnm.cpp new file mode 100644 index 0000000000..0f648e2cbd --- /dev/null +++ b/engines/saga/sfuncs_ihnm.cpp @@ -0,0 +1,448 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifdef ENABLE_IHNM + +// Scripting module script function component + +#include "saga/saga.h" + +#include "saga/gfx.h" +#include "saga/actor.h" +#include "saga/animation.h" +#include "saga/console.h" +#include "saga/events.h" +#include "saga/font.h" +#include "saga/interface.h" +#include "saga/music.h" +#include "saga/itedata.h" +#include "saga/puzzle.h" +#include "saga/render.h" +#include "saga/sound.h" +#include "saga/sndres.h" +#include "saga/resource.h" + +#include "saga/script.h" +#include "saga/objectmap.h" + +#include "saga/scene.h" +#include "saga/isomap.h" + +#include "common/config-manager.h" + +namespace Saga { + +void Script::setupIHNMScriptFuncList() { +	static const ScriptFunctionDescription IHNMScriptFunctionsList[IHNM_SCRIPT_FUNCTION_MAX] = { +		OPCODE(sfNull), +		OPCODE(sfWait), +		OPCODE(sfTakeObject), +		OPCODE(sfIsCarried), +		OPCODE(sfStatusBar), +		OPCODE(sfMainMode), +		OPCODE(sfScriptWalkTo), +		OPCODE(sfScriptDoAction), +		OPCODE(sfSetActorFacing), +		OPCODE(sfStartBgdAnim), +		OPCODE(sfStopBgdAnim), +		OPCODE(sfLockUser), +		OPCODE(sfPreDialog), +		OPCODE(sfKillActorThreads), +		OPCODE(sfFaceTowards), +		OPCODE(sfSetFollower), +		OPCODE(sfScriptGotoScene), +		OPCODE(sfSetObjImage), +		OPCODE(sfSetObjName), +		OPCODE(sfGetObjImage), +		OPCODE(sfGetNumber), +		OPCODE(sfScriptOpenDoor), +		OPCODE(sfScriptCloseDoor), +		OPCODE(sfSetBgdAnimSpeed), +		OPCODE(sfCycleColors), +		OPCODE(sfDoCenterActor), +		OPCODE(sfStartBgdAnimSpeed), +		OPCODE(sfScriptWalkToAsync), +		OPCODE(sfEnableZone), +		OPCODE(sfSetActorState), +		OPCODE(sfScriptMoveTo), +		OPCODE(sfSceneEq), +		OPCODE(sfDropObject), +		OPCODE(sfFinishBgdAnim), +		OPCODE(sfSwapActors), +		OPCODE(sfSimulSpeech), +		OPCODE(sfScriptWalk), +		OPCODE(sfCycleFrames), +		OPCODE(sfSetFrame), +		OPCODE(sfSetPortrait), +		OPCODE(sfSetProtagPortrait), +		OPCODE(sfChainBgdAnim), +		OPCODE(sfScriptSpecialWalk), +		OPCODE(sfPlaceActor), +		OPCODE(sfCheckUserInterrupt), +		OPCODE(sfScriptWalkRelative), +		OPCODE(sfScriptMoveRelative), +		OPCODE(sfSimulSpeech2), +		OPCODE(sfPsychicProfile), +		OPCODE(sfPsychicProfileOff), +		OPCODE(sfSetProtagState), +		OPCODE(sfResumeBgdAnim), +		OPCODE(sfThrowActor), +		OPCODE(sfWaitWalk), +		OPCODE(sfScriptSceneID), +		OPCODE(sfChangeActorScene), +		OPCODE(sfScriptClimb), +		OPCODE(sfSetDoorState), +		OPCODE(sfSetActorZ), +		OPCODE(sfScriptText), +		OPCODE(sfGetActorX), +		OPCODE(sfGetActorY), +		OPCODE(sfEraseDelta), +		OPCODE(sfPlayMusic), +		OPCODE(sfNull), +		OPCODE(sfEnableEscape), +		OPCODE(sfPlaySound), +		OPCODE(sfPlayLoopedSound), +		OPCODE(sfGetDeltaFrame), +		OPCODE(sfNull), +		OPCODE(sfNull), +		OPCODE(sfRand), +		OPCODE(sfFadeMusic), +		OPCODE(sfNull), +		OPCODE(sfSetChapterPoints), +		OPCODE(sfSetPortraitBgColor), +		OPCODE(sfScriptStartCutAway), +		OPCODE(sfReturnFromCutAway), +		OPCODE(sfEndCutAway), +		OPCODE(sfGetMouseClicks), +		OPCODE(sfResetMouseClicks), +		OPCODE(sfWaitFrames), +		OPCODE(sfScriptFade), +		OPCODE(sfScriptStartVideo), +		OPCODE(sfScriptReturnFromVideo), +		OPCODE(sfScriptEndVideo), +		OPCODE(sfSetActorZ), +		OPCODE(sfShowIHNMDemoHelpBg), +		OPCODE(sfAddIHNMDemoHelpTextLine), +		OPCODE(sfShowIHNMDemoHelpPage), +		OPCODE(sfVstopFX), +		OPCODE(sfVstopLoopedFX), +		OPCODE(sfDemoSetInteractive),	// only used in the demo version of IHNM +		OPCODE(sfDemoIsInteractive), +		OPCODE(sfVsetTrack), +		OPCODE(sfGetPoints), +		OPCODE(sfSetGlobalFlag), +		OPCODE(sfClearGlobalFlag), +		OPCODE(sfTestGlobalFlag), +		OPCODE(sfSetPoints), +		OPCODE(sfSetSpeechBox), +		OPCODE(sfDebugShowData), +		OPCODE(sfWaitFramesEsc), +		OPCODE(sfQueueMusic), +		OPCODE(sfDisableAbortSpeeches) +	}; + +	_scriptFunctionsList = IHNMScriptFunctionsList; +} + +void Script::sfSetChapterPoints(SCRIPTFUNC_PARAMS) { +	int chapter = _vm->_scene->currentChapterNumber(); +	_vm->_ethicsPoints[chapter] = thread->pop(); +	int16 barometer = thread->pop(); +	static PalEntry cur_pal[PAL_ENTRIES]; + +	_vm->_spiritualBarometer = _vm->_ethicsPoints[chapter] * 256 / barometer; +	_vm->_scene->setChapterPointsChanged(true);		// don't save this music when saving in IHNM + +	if (_vm->_spiritualBarometer > 255) +		_vm->_gfx->setPaletteColor(kIHNMColorPortrait, 0xff, 0xff, 0xff); +	else +		_vm->_gfx->setPaletteColor(kIHNMColorPortrait, +			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.red / 256, +			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.green / 256, +			_vm->_spiritualBarometer * _vm->_interface->_portraitBgColor.blue / 256); + +	_vm->_gfx->getCurrentPal(cur_pal); +	_vm->_gfx->setPalette(cur_pal); +} + +void Script::sfSetPortraitBgColor(SCRIPTFUNC_PARAMS) { +	int16 red = thread->pop(); +	int16 green = thread->pop(); +	int16 blue = thread->pop(); + +	_vm->_interface->setPortraitBgColor(red, green, blue); +} + +void Script::sfScriptStartCutAway(SCRIPTFUNC_PARAMS) { +	int16 cut = thread->pop(); +	thread->pop();		// Not used +	int16 fade = thread->pop(); + +	_vm->_anim->setCutAwayMode(kPanelCutaway); +	_vm->_anim->playCutaway(cut, fade != 0); +} + +void Script::sfReturnFromCutAway(SCRIPTFUNC_PARAMS) { +	_vm->_anim->returnFromCutaway(); +	thread->wait(kWaitTypeWakeUp); +} + +void Script::sfEndCutAway(SCRIPTFUNC_PARAMS) { +	_vm->_anim->endCutaway(); +} + +void Script::sfGetMouseClicks(SCRIPTFUNC_PARAMS) { +	thread->_returnValue = _vm->getMouseClickCount(); +} + +void Script::sfResetMouseClicks(SCRIPTFUNC_PARAMS) { +	_vm->resetMouseClickCount(); +} + +void Script::sfWaitFrames(SCRIPTFUNC_PARAMS) { +	int16 frames = thread->pop(); + +	if (!_skipSpeeches) +		thread->waitFrames(_vm->_frameCount + frames); +} + +void Script::sfScriptFade(SCRIPTFUNC_PARAMS) { +	int16 firstPalEntry = thread->pop(); +	int16 lastPalEntry = thread->pop(); +	int16 startingBrightness = thread->pop(); +	int16 endingBrightness = thread->pop(); +	Event event; +	static PalEntry cur_pal[PAL_ENTRIES]; + +	_vm->_gfx->getCurrentPal(cur_pal); +	event.type = kEvTImmediate; +	event.code = kPalEvent; +	event.op = kEventPalFade; +	event.time = 0; +	event.duration = kNormalFadeDuration; +	event.data = cur_pal; +	event.param = startingBrightness; +	event.param2 = endingBrightness; +	event.param3 = firstPalEntry; +	event.param4 = lastPalEntry - firstPalEntry + 1; +	_vm->_events->queue(&event); +} + +void Script::sfScriptStartVideo(SCRIPTFUNC_PARAMS) { +	int16 vid = thread->pop(); +	int16 fade = thread->pop(); + +	_vm->_anim->setCutAwayMode(kPanelVideo); +	_vm->_anim->startVideo(vid, fade != 0); +} + +void Script::sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS) { +	_vm->_anim->returnFromVideo(); +} + +void Script::sfScriptEndVideo(SCRIPTFUNC_PARAMS) { +	_vm->_anim->endVideo(); +} + +void Script::sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS) { +	_ihnmDemoCurrentY = 0; +	_vm->_scene->_textList.clear(); +	_vm->_interface->setMode(kPanelConverse); +	_vm->_scene->showPsychicProfile(NULL); +} + +void Script::sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS) { +	int stringId = thread->pop(); +	TextListEntry textEntry; +	Event event; + +	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 += _vm->_font->getHeight(kKnownFontVerb, thread->_strings->getString(stringId), 226, kFontCentered); +} + +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) { +	_vm->_sound->stopSound(); +} + +void Script::sfVstopLoopedFX(SCRIPTFUNC_PARAMS) { +	_vm->_sound->stopSound(); +} + +void Script::sfDemoSetInteractive(SCRIPTFUNC_PARAMS) { +	if (thread->pop() == 0) { +		_vm->_interface->deactivate(); +		_vm->_interface->setMode(kPanelNull); +	} + +	// Note: the original also sets an appropriate flag here, but we don't, +	// as we don't use it +} + +void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) { +	thread->_returnValue = 0; +} + +void Script::sfVsetTrack(SCRIPTFUNC_PARAMS) { +	int16 chapter = thread->pop(); +	int16 sceneNumber = thread->pop(); +	int16 actorsEntrance = thread->pop(); + +	debug(2, "sfVsetTrrack(%d, %d, %d)", chapter, sceneNumber, actorsEntrance); + +	_vm->_scene->changeScene(sceneNumber, actorsEntrance, kTransitionFade, chapter); +} + +void Script::sfGetPoints(SCRIPTFUNC_PARAMS) { +	int16 index = thread->pop(); + +	if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) +		thread->_returnValue = _vm->_ethicsPoints[index]; +	else +		thread->_returnValue = 0; +} + +void Script::sfSetGlobalFlag(SCRIPTFUNC_PARAMS) { +	int16 flag = thread->pop(); + +	if (flag >= 0 && flag < 32) +		_vm->_globalFlags |= (1 << flag); +} + +void Script::sfClearGlobalFlag(SCRIPTFUNC_PARAMS) { +	int16 flag = thread->pop(); + +	if (flag >= 0 && flag < 32) +		_vm->_globalFlags &= ~(1 << flag); +} + +void Script::sfTestGlobalFlag(SCRIPTFUNC_PARAMS) { +	int16 flag = thread->pop(); + +	if (flag >= 0 && flag < 32 && _vm->_globalFlags & (1 << flag)) +		thread->_returnValue = 1; +	else +		thread->_returnValue = 0; +} + +void Script::sfSetPoints(SCRIPTFUNC_PARAMS) { +	int16 index = thread->pop(); +	int16 points = thread->pop(); + +	if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) +		_vm->_ethicsPoints[index] = points; +} + +void Script::sfSetSpeechBox(SCRIPTFUNC_PARAMS) { +	int16 param1 = thread->pop(); +	int16 param2 = thread->pop(); +	int16 param3 = thread->pop(); +	int16 param4 = thread->pop(); + +	_vm->_actor->_speechBoxScript.left = param1; +	_vm->_actor->_speechBoxScript.top = param2; +	_vm->_actor->_speechBoxScript.setWidth(param3 - param1); +	_vm->_actor->_speechBoxScript.setHeight(param4 - param2); +} + +void Script::sfDebugShowData(SCRIPTFUNC_PARAMS) { +	int16 param = thread->pop(); +	char buf[50]; + +	snprintf(buf, 50, "Reached breakpoint %d", param); + +	_vm->_interface->setStatusText(buf); +} + +void Script::sfWaitFramesEsc(SCRIPTFUNC_PARAMS) { +	thread->_returnValue = _vm->_framesEsc; +} + +void Script::sfQueueMusic(SCRIPTFUNC_PARAMS) { +	int16 param1 = thread->pop(); +	int16 param2 = thread->pop(); +	Event event; + +	if (param1 < 0) { +		_vm->_music->stop(); +		return; +	} + +	if (param1 >= _vm->_music->_songTableLen) { +		warning("sfQueueMusic: Wrong song number (%d > %d)", param1, _vm->_music->_songTableLen - 1); +	} else { +		_vm->_music->setVolume(_vm->_musicVolume, 1); +		event.type = kEvTOneshot; +		event.code = kMusicEvent; +		event.param = _vm->_music->_songTable[param1]; +		event.param2 = param2 ? MUSIC_LOOP : MUSIC_NORMAL; +		event.op = kEventPlay; +		event.time = _vm->ticksToMSec(500);		// I find the delay in the original to be too long, so I've set it to +												// wait for half the time, which sounds better when chapter points +												// change +												// FIXME: If this is too short for other cases apart from chapter +												// point change, set it back to 1000 +		_vm->_events->queue(&event); + +		if (!_vm->_scene->haveChapterPointsChanged()) { +			_vm->_scene->setCurrentMusicTrack(param1); +			_vm->_scene->setCurrentMusicRepeat(param2); +		} else { +			// Don't save this music track when saving in IHNM +			_vm->_scene->setChapterPointsChanged(false); +		} +	} +} + +void Script::sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS) { +	_vm->_interface->disableAbortSpeeches(thread->pop() != 0); +} + +} // End of namespace Saga + +#endif diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp index 03e93a54e2..4b11a8612c 100644 --- a/engines/saga/sndres.cpp +++ b/engines/saga/sndres.cpp @@ -60,6 +60,7 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm) {  	if (_vm->getGameId() == GID_ITE) {  		_fxTable = ITE_SfxTable;  		_fxTableLen = ITE_SFXCOUNT; +#ifdef ENABLE_IHNM  	} else if (_vm->getGameId() == GID_IHNM) {  		ResourceContext *resourceContext; @@ -94,6 +95,7 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm) {  		_fxTable = 0;  		_fxTableLen = 0; +#endif  	} else if (_vm->getGameId() == GID_DINO) {  		// TODO  	} else if (_vm->getGameId() == GID_FTA2) { diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp index c246a8fafb..89e64d1a35 100644 --- a/engines/saga/sprite.cpp +++ b/engines/saga/sprite.cpp @@ -61,6 +61,7 @@ Sprite::Sprite(SagaEngine *vm) : _vm(vm) {  	if (_vm->getGameId() == GID_ITE) {  		loadList(_vm->getResourceDescription()->mainSpritesResourceId, _mainSprites);  		_arrowSprites = _saveReminderSprites = _inventorySprites = _mainSprites; +#ifdef ENABLE_IHNM  	} else if (_vm->getGameId() == GID_IHNM) {  		if (_vm->getFeatures() & GF_IHNM_DEMO) {  			loadList(RID_IHNMDEMO_ARROW_SPRITES, _arrowSprites); @@ -69,6 +70,7 @@ Sprite::Sprite(SagaEngine *vm) : _vm(vm) {  			loadList(RID_IHNM_ARROW_SPRITES, _arrowSprites);  			loadList(RID_IHNM_SAVEREMINDER_SPRITES, _saveReminderSprites);  		} +#endif  	} else {  		error("Sprite: unknown game type");  	} @@ -167,6 +169,7 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {  			memoryError("Sprite::loadList");  		} +#ifdef ENABLE_IHNM  		// IHNM sprites are upside-down, for reasons which i can only  		// assume are perverse. To simplify things, flip them now. Not  		// at drawing time. @@ -181,6 +184,7 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {  				dst += spriteInfo->width;  			}  		} else +#endif  			memcpy(spriteInfo->decodedBuffer, _decodeBuf, outputLength);  	}  | 
