aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
Diffstat (limited to 'saga')
-rw-r--r--saga/game.cpp6
-rw-r--r--saga/interface.cpp3
-rw-r--r--saga/script.h21
-rw-r--r--saga/sfuncs.cpp255
-rw-r--r--saga/sthread.cpp3
5 files changed, 244 insertions, 44 deletions
diff --git a/saga/game.cpp b/saga/game.cpp
index 304df7c276..f3281df625 100644
--- a/saga/game.cpp
+++ b/saga/game.cpp
@@ -430,9 +430,9 @@ static GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all
0,0, // save reminder w&h
0,0, // save reminder sprite numbers
- 147, // verb text color
- 15, // verb text shadow color
- 96, // verb text active color
+ 253, // verb text color
+ 15, // verb text shadow color FIXME
+ 252, // verb text active color
5, 4, // left portrait x, y offset
-1, -1, // right portrait x, y offset
diff --git a/saga/interface.cpp b/saga/interface.cpp
index 47d1d69a71..3f7df23ef4 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -263,6 +263,9 @@ void Interface::setMode(int mode) {
switch (_panelMode) {
case kPanelMain:
+ if (_vm->getGameType() == GType_IHNM)
+ warning("FIXME: Implement IHNM differences from ExecuteInvontoryPanel");
+
_mainPanel.currentButton = NULL;
break;
case kPanelConverse:
diff --git a/saga/script.h b/saga/script.h
index 844f917f46..d5f2ce1bb0 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -39,14 +39,9 @@ namespace Saga {
#define SCRIPT_TBLENTRY_LEN 4
#define SCRIPT_MAX 5000
-#define SCRIPTLIST_HDR 12
-#define SCRIPT_STRINGLIMIT 255
-#define TAB " "
-#define S_ERROR_PREFIX "SError: "
-#define S_WARN_PREFIX "SWarning: "
-
-#define SCRIPT_FUNCTION_MAX 104
+#define ITE_SCRIPT_FUNCTION_MAX 78
+#define IHNM_SCRIPT_FUNCTION_MAX 105
#define DEFAULT_THREAD_STACK_SIZE 256
enum AddressTypes {
@@ -527,8 +522,20 @@ private:
void sfProtectResult(SCRIPTFUNC_PARAMS);
void sfRand(SCRIPTFUNC_PARAMS);
void sfFadeMusic(SCRIPTFUNC_PARAMS);
+ void sfScriptStartCutAway(SCRIPTFUNC_PARAMS);
+ void sfReturnFromCutAway(SCRIPTFUNC_PARAMS);
+ void sfEndCutAway(SCRIPTFUNC_PARAMS);
+ void sfGetMouseClicks(SCRIPTFUNC_PARAMS);
+ void sfResetMouseClicks(SCRIPTFUNC_PARAMS);
+ void sfWaitFrames(SCRIPTFUNC_PARAMS);
+ void sfScriptFade(SCRIPTFUNC_PARAMS);
void sfPlayVoice(SCRIPTFUNC_PARAMS);
+ void sfVstopFX(SCRIPTFUNC_PARAMS);
+ void sfVstopLoopedFX(SCRIPTFUNC_PARAMS);
+ void sfDemoIsInteractive(SCRIPTFUNC_PARAMS);
+ void sfDebugShowData(SCRIPTFUNC_PARAMS);
void SF_stub(SCRIPTFUNC_PARAMS);
+ void sfNull(SCRIPTFUNC_PARAMS);
};
} // End of namespace Saga
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index a7ecb88d1f..ff23dd5692 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -53,7 +53,7 @@ namespace Saga {
#define OPCODE(x) {&Script::x, #x}
void Script::setupScriptFuncList(void) {
- static const ScriptFunctionDescription scriptFunctionsList[SCRIPT_FUNCTION_MAX] = {
+ static const ScriptFunctionDescription ITEscriptFunctionsList[ITE_SCRIPT_FUNCTION_MAX] = {
OPCODE(sfPutString),
OPCODE(sfWait),
OPCODE(sfTakeObject),
@@ -131,23 +131,104 @@ void Script::setupScriptFuncList(void) {
OPCODE(sfProtectResult),
OPCODE(sfRand),
OPCODE(sfFadeMusic),
- OPCODE(sfPlayVoice),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
- OPCODE(SF_stub),
+ 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(sfNull),
+ 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(SF_cycleColors),
+ 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(sfPlacard),
+ OPCODE(sfPlacardOff),
+ 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(SF_stub),
OPCODE(SF_stub),
+ OPCODE(sfScriptStartCutAway),
+ OPCODE(sfReturnFromCutAway),
+ OPCODE(sfEndCutAway),
+ OPCODE(sfGetMouseClicks),
+ OPCODE(sfResetMouseClicks),
+ OPCODE(sfWaitFrames),
+ OPCODE(sfScriptFade),
OPCODE(SF_stub),
OPCODE(SF_stub),
OPCODE(SF_stub),
+ OPCODE(sfSetActorZ),
OPCODE(SF_stub),
OPCODE(SF_stub),
+ OPCODE(sfVstopFX),
+ OPCODE(sfVstopLoopedFX),
OPCODE(SF_stub),
+ OPCODE(sfNull),
+ OPCODE(sfDemoIsInteractive),
OPCODE(SF_stub),
OPCODE(SF_stub),
OPCODE(SF_stub),
@@ -155,11 +236,15 @@ void Script::setupScriptFuncList(void) {
OPCODE(SF_stub),
OPCODE(SF_stub),
OPCODE(SF_stub),
+ OPCODE(sfDebugShowData),
OPCODE(SF_stub),
OPCODE(SF_stub),
OPCODE(SF_stub)
};
- _scriptFunctionsList = scriptFunctionsList;
+ if (_vm->getGameType() == GType_IHNM)
+ _scriptFunctionsList = IHNMscriptFunctionsList;
+ else
+ _scriptFunctionsList = ITEscriptFunctionsList;
}
// Script function #0 (0x00)
@@ -225,7 +310,9 @@ void Script::sfMainMode(SCRIPTFUNC_PARAMS) {
showVerb();
_vm->_interface->activate();
_vm->_interface->setMode(kPanelMain);
- setPointerVerb();
+
+ if (_vm->getGameType() == GType_ITE)
+ setPointerVerb();
}
// Script function #6 (0x06) blocking
@@ -513,6 +600,9 @@ void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) {
return;
}
+ if (_vm->getGameType() == GType_IHNM)
+ warning("FIXME: implement sfScriptGotoScene differences for IHNM");
+
// It is possible to leave scene when converse panel is on,
// particulalrly it may happen at Moneychanger tent. This
// prevent this from happening.
@@ -578,7 +668,11 @@ void Script::sfGetObjImage(SCRIPTFUNC_PARAMS) {
objectId = thread->pop();
obj = _vm->_actor->getObj(objectId);
- thread->_returnValue = obj->spriteListResourceId - OBJ_SPRITE_BASE;
+
+ if (_vm->getGameType() == GType_IHNM)
+ thread->_returnValue = obj->spriteListResourceId;
+ else
+ thread->_returnValue = obj->spriteListResourceId - OBJ_SPRITE_BASE;
}
// Script function #20 (0x14)
@@ -784,7 +878,12 @@ void Script::sfDropObject(SCRIPTFUNC_PARAMS) {
}
obj->sceneNumber = _vm->_scene->currentSceneNumber();
- obj->spriteListResourceId = OBJ_SPRITE_BASE + spriteId;
+
+ if (_vm->getGameType() == GType_IHNM)
+ obj->spriteListResourceId = spriteId;
+ else
+ obj->spriteListResourceId = OBJ_SPRITE_BASE + spriteId;
+
obj->location.x = x;
obj->location.y = y;
}
@@ -824,6 +923,10 @@ void Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
actor1->flags |= kProtagonist;
_vm->_actor->_protagonist = _vm->_actor->_centerActor = actor1;
}
+
+ // Here non-protagonist ID gets saved in variable
+ if (_vm->getGameType() == GType_IHNM)
+ warning("sfSwapActors: incomplete implementation");
}
// Script function #35 (0x23)
@@ -852,9 +955,13 @@ void Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
string = thread->_strings->getString(stringId);
if (thread->_voiceLUT->voices) {
- sampleResourceId = thread->_voiceLUT->voices[stringId];
- if (sampleResourceId <= 0 || sampleResourceId > 4000)
+ if (_vm->getGameType() == GType_IHNM && stringId >= 338) {
sampleResourceId = -1;
+ } else {
+ sampleResourceId = thread->_voiceLUT->voices[stringId];
+ if (sampleResourceId <= 0 || sampleResourceId > 4000)
+ sampleResourceId = -1;
+ }
}
_vm->_actor->simulSpeech(string, actorsIds, actorsCount, 0, sampleResourceId);
@@ -1197,7 +1304,12 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
PalEntry *pal;
EVENT event;
EVENT *q_event;
-
+
+ if (_vm->getGameType() == GType_IHNM) {
+ warning("Psychic profile is not implemented");
+ return;
+ }
+
thread->wait(kWaitTypePlacard);
_vm->_interface->rememberMode();
@@ -1743,11 +1855,18 @@ void Script::sfPlaySound(SCRIPTFUNC_PARAMS) {
int16 param = thread->pop();
int res;
+ if (_vm->getGameType() == GType_IHNM) {
+ int16 param2 = thread->pop();
+
+ // Here sfxTable comes from Resource #265
+ debug(0, "STUB: sfPlaySound(%d, %d)", param, param2);
+ return;
+ }
+
if (param >= 0 && param < ARRAYSIZE(sfxTable)) {
res = sfxTable[param].res;
if (_vm->getFeatures() & GF_CD_FX)
res -= 14;
-
_vm->_sndRes->playSound(res, sfxTable[param].vol, false);
} else {
_vm->_sound->stopSound();
@@ -1759,6 +1878,14 @@ void Script::sfPlayLoopedSound(SCRIPTFUNC_PARAMS) {
int16 param = thread->pop();
int res;
+ if (_vm->getGameType() == GType_IHNM) {
+ int16 param2 = thread->pop();
+
+ // Here sfxTable comes from Resource #265
+ debug(0, "STUB: sfPlayLoopedSound(%d, %d)", param, param2);
+ return;
+ }
+
if (param >= 0 && param < ARRAYSIZE(sfxTable)) {
res = sfxTable[param].res;
if (_vm->getFeatures() & GF_CD_FX)
@@ -1798,21 +1925,8 @@ void Script::sfProtectResult(SCRIPTFUNC_PARAMS) {
void Script::sfRand(SCRIPTFUNC_PARAMS) {
int16 param;
- if (_vm->getGameType() == GType_IHNM) {
- // I don't know what this function does in IHNM, but apparently
- // it can take three parameters.
-
- debug(0, "STUB: sfRand()");
-
- for (int i = 0; i < nArgs; i++) {
- thread->pop();
- }
-
- thread->_returnValue = 0;
- } else {
- param = thread->pop();
- thread->_returnValue = _vm->_rnd.getRandomNumber(param - 1);
- }
+ param = thread->pop();
+ thread->_returnValue = _vm->_rnd.getRandomNumber(param - 1);
}
// Script function #76 (0x4c)
@@ -1852,6 +1966,81 @@ void Script::finishDialog(int replyID, int flags, int bitOffset) {
wakeUpThreads(kWaitTypeDialogBegin);
}
+void Script::sfScriptStartCutAway(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfScriptStartCutAway(), %d args", nArgs);
+}
+
+void Script::sfReturnFromCutAway(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfReturnFromCutAway(), %d args", nArgs);
+}
+
+void Script::sfEndCutAway(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfEndCutAway(), %d args", nArgs);
+}
+
+void Script::sfGetMouseClicks(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfGetMouseClicks(), %d args", nArgs);
+}
+
+void Script::sfResetMouseClicks(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfResetMouseClicks(), %d args", nArgs);
+}
+
+void Script::sfWaitFrames(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfWaitFrames(), %d args", nArgs);
+}
+
+void Script::sfScriptFade(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+
+ debug(0, "STUB: sfScriptFade(), %d args", nArgs);
+}
+
+void Script::sfVstopFX(SCRIPTFUNC_PARAMS) {
+ _vm->_sound->stopSound();
+}
+
+void Script::sfVstopLoopedFX(SCRIPTFUNC_PARAMS) {
+ _vm->_sound->stopSound();
+}
+
+void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) {
+ thread->_returnValue = 0;
+}
+
+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::sfNull(SCRIPTFUNC_PARAMS) {
+ for (int i = 0; i < nArgs; i++)
+ thread->pop();
+}
+
void Script::SF_stub(SCRIPTFUNC_PARAMS) {
for (int i = 0; i < nArgs; i++)
thread->pop();
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index c5f1f74a3a..209c6ebb6f 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -317,7 +317,8 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) {
CASEOP(opCcallV)
argumentsCount = scriptS.readByte();
functionNumber = scriptS.readUint16LE();
- if (functionNumber >= SCRIPT_FUNCTION_MAX) {
+ if (functionNumber >= (_vm->getGameType() == GType_IHNM) ?
+ IHNM_SCRIPT_FUNCTION_MAX : ITE_SCRIPT_FUNCTION_MAX) {
error("Script::runThread() Invalid script function number (%d)", functionNumber);
}