aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/prince/script.cpp174
-rw-r--r--engines/prince/script.h1
2 files changed, 141 insertions, 34 deletions
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index d5284034e2..ed96e34dd5 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -572,7 +572,7 @@ void Interpreter::O_INITROOM() {
void Interpreter::O_SETSAMPLE() {
uint16 sampleId = readScriptFlagValue();
int32 sampleNameOffset = readScript<uint32>();
- const char * sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4);
+ const char *sampleName = _script->getString(_currentInstruction + sampleNameOffset - 4);
debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName);
_vm->loadSample(sampleId, sampleName);
}
@@ -838,6 +838,7 @@ void Interpreter::O_SETSTRING() {
debugInterpreter("GetVaria %s", _string);
}
else if (offset < 2000) {
+ //dialogDat -> dialogData
uint32 of = READ_LE_UINT32(_vm->_talkTxt + offset * 4);
const char *txt = (const char *)&_vm->_talkTxt[of];
_string = &_vm->_talkTxt[of];
@@ -1204,30 +1205,24 @@ void Interpreter::O_LOADPATH() {
void Interpreter::O_GETCHAR() {
Flags::Id flagId = readScriptFlagId();
-
_flags->setFlagValue(flagId, *_string);
-
- debugInterpreter(
- "O_GETCHAR %04X (%s) %02x",
- flagId,
- Flags::getFlagName(flagId),
- _flags->getFlagValue(flagId));
-
- ++_string;
+ debugInterpreter("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags->getFlagValue(flagId));
+ _string++;
}
void Interpreter::O_SETDFLAG() {
- uint16 flag = readScript<uint16>();
- int32 offset = readScript<uint32>();
- debugInterpreter("O_SETDFLAG flag %d, offset %04x", flag, offset);
- // run this through debugger looks strange
- // it looks like this one store two 16 bit value in one go
+ Flags::Id flagId = readScriptFlagId();
+ int32 address = readScript<uint32>();
+ debugInterpreter("O_SETDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction + address - 4);
+ _flags->setFlagValue((Flags::Id)(flagId), _currentInstruction + address - 4);
}
void Interpreter::O_CALLDFLAG() {
- uint16 flag = readScript<uint16>();
- debugInterpreter("O_CALLDFLAG flag %d", flag);
- // it seems that some flags are 32 bit long
+ Flags::Id flagId = readScriptFlagId();
+ _stack[_stacktop] = _currentInstruction;
+ _stacktop++;
+ _currentInstruction = _flags->getFlagValue(flagId);
+ debugInterpreter("O_CALLDFLAG 0x%04X (%s) = 0x%04X", flagId, Flags::getFlagName(flagId), _currentInstruction);
}
void Interpreter::O_PRINTAT() {
@@ -1290,25 +1285,134 @@ void Interpreter::O_CHANGEHEROSET() {
void Interpreter::O_ADDSTRING() {
uint16 value = readScriptFlagValue();
debugInterpreter("O_ADDSTRING value %d", value);
- // _string += value
+ _string += value;
}
void Interpreter::O_SUBSTRING() {
uint16 value = readScriptFlagValue();
debugInterpreter("O_SUBSTRING value %d", value);
- // _string -= value
+ _string -= value;
+}
+
+int Interpreter::checkSeq(byte *string) {
+ int freeHSlotIncrease = 0;
+ byte c;
+ while (1) {
+ c = string[0];
+ string++;
+ if (c < 0xF0) {
+ //not_spec
+ freeHSlotIncrease++;
+ while (1) {
+ c = string[0];
+ if (c == 0) {
+ break;
+ }
+ string++;
+ }
+ string++;
+ continue;
+ }
+ if (c == 0xFF) {
+ break;
+ }
+ if (c == 0xFE) {
+ continue; // pause
+ }
+ string++;
+ }
+ return freeHSlotIncrease;
}
void Interpreter::O_INITDIALOG() {
debugInterpreter("O_INITDIALOG");
- for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) {
- _vm->_dialogBoxList[i].clear();
- }
- _vm->_dialogBoxList.clear();
+ if (_string[0] == 255) {
+ byte *stringESI = _string;
+ byte *stringEBP = _string;
+ stringESI++;
+ int32 adressOfFirstSequence = *stringESI; // eax
+ stringESI += 2;
+ _string = stringEBP + adressOfFirstSequence;
+
+ // like this?
+ for (uint i = 0; i < _vm->_dialogBoxList.size(); i++) {
+ _vm->_dialogBoxList[i].clear();
+ }
+ _vm->_dialogBoxList.clear();
+
+ // to global
+ byte *dialogBoxAddr[32]; // adresses of dialog windows
+ byte *dialogOptAddr[32]; // adresses of dialog options
+ int dialogOptLines[4 * 32]; // numbers of initial dialog lines
- // cut string to dialogs
- // cut dialogs to nr and lines
- // push them to dialogBoxList
+ for (int i = 0; i < 32; i++) {
+ dialogBoxAddr[i] = 0;
+ dialogOptAddr[i] = 0;
+ }
+
+ for (int i = 0; i < 4 * 32; i++) {
+ dialogOptLines[i] = 0;
+ }
+
+ //loop_1
+ int16 c;
+ byte *eax;
+ int edi = 0;
+ while (1) {
+ c = (int)READ_UINT16(stringESI);
+ stringESI += 2;
+ if (c == -1) {
+ break;
+ }
+ if (c != 0) {
+ eax = stringEBP + c;
+ }
+ dialogBoxAddr[edi] = eax;
+ edi++;
+ }
+ //box_done:
+ edi = 0;
+ while (1) {
+ c = (int)READ_UINT16(stringESI);
+ stringESI += 2;
+ if (c == -1) {
+ break;
+ }
+ if (c != 0) {
+ eax = stringEBP + c;
+ }
+ dialogOptAddr[edi] = eax;
+ edi++;
+ }
+ //opt_done
+ int freeASlot = 0;
+ int freeBSlot = 0;
+ _flags->setFlagValue(Flags::VOICE_A_LINE, 0);
+ _flags->setFlagValue(Flags::VOICE_B_LINE, 0); // bx in original?
+
+ int freeHSlot = 0;
+ //check
+ for (int i = 31; i >= 0; i--) {
+ if (dialogOptAddr[i] != 0) {
+ // or i++ before break here?
+ debug("%s", (char *)dialogOptAddr[i]);
+ freeHSlot = i;
+ _flags->setFlagValue(Flags::VOICE_H_LINE, i);
+ break;
+ }
+ }
+
+ freeHSlot += checkSeq(_string);
+
+ for (int i = 0; i < 32; i++) {
+ dialogOptLines[i * 4] = freeHSlot;
+ dialogOptLines[i * 4 + 1] = freeHSlot;
+ dialogOptLines[i * 4 + 2] = freeHSlot;
+ if (dialogOptAddr[i]) {
+ freeHSlot += checkSeq(dialogOptAddr[i]);
+ }
+ }
+ }
}
void Interpreter::O_ENABLEDIALOGOPT() {
@@ -1324,13 +1428,15 @@ void Interpreter::O_DISABLEDIALOGOPT() {
void Interpreter::O_SHOWDIALOGBOX() {
uint16 box = readScriptFlagValue();
debugInterpreter("O_SHOWDIALOGBOX box %d", box);
- _vm->createDialogBox(_vm->_dialogBoxList[box]);
- int dialogLines = _vm->_dialogBoxList[box].size();
- _flags->setFlagValue(Flags::DIALINES, dialogLines);
- if (dialogLines != 0) {
- _vm->changeCursor(1);
- _vm->runDialog(_vm->_dialogBoxList[box]);
- _vm->changeCursor(0);
+ if (box < _vm->_dialogBoxList.size()) {
+ _vm->createDialogBox(_vm->_dialogBoxList[box]);
+ int dialogLines = _vm->_dialogBoxList[box].size();
+ _flags->setFlagValue(Flags::DIALINES, dialogLines);
+ if (dialogLines != 0) {
+ _vm->changeCursor(1);
+ _vm->runDialog(_vm->_dialogBoxList[box]);
+ _vm->changeCursor(0);
+ }
}
}
diff --git a/engines/prince/script.h b/engines/prince/script.h
index d550ebc9bf..ddb68087f4 100644
--- a/engines/prince/script.h
+++ b/engines/prince/script.h
@@ -218,6 +218,7 @@ private:
uint16 readScriptFlagValue();
Flags::Id readScriptFlagId();
+ int checkSeq(byte *string);
// instantiation not needed here
template <typename T> T readScript();