- Split the IHNM script functions into a different file
- Added two new defines, ENABLE_IHNM and ENABLE_SAGA2 (enabled by default), which can be used to remove the parts of the SAGA engine which are specific to IHNM and SAGA 2 games. Hopefully, this will reduce the size of the engine even more for platforms with little memory (e.g. the Nintendo DS) svn-id: r35672
This commit is contained in:
parent
a09a7678f4
commit
d5b6996c45
29 changed files with 656 additions and 430 deletions
|
@ -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"
|
||||
|
@ -262,6 +262,9 @@
|
|||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sndres.cpp">
|
||||
</File>
|
||||
|
|
|
@ -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"
|
||||
|
@ -276,6 +276,9 @@
|
|||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sndres.cpp">
|
||||
</File>
|
||||
|
|
|
@ -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"
|
||||
|
@ -378,6 +378,10 @@
|
|||
RelativePath="..\..\engines\saga\sfuncs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sndres.cpp"
|
||||
>
|
||||
|
|
|
@ -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"
|
||||
|
@ -379,6 +379,10 @@
|
|||
RelativePath="..\..\engines\saga\sfuncs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sfuncs_ihnm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engines\saga\sndres.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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 //////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,12 +625,18 @@ 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;
|
||||
|
||||
if (thread->_flags & kTFlagAsleep)
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,116 +134,6 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
|
448
engines/saga/sfuncs_ihnm.cpp
Normal file
448
engines/saga/sfuncs_ihnm.cpp
Normal file
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue