aboutsummaryrefslogtreecommitdiff
path: root/engines/sky/logic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sky/logic.cpp')
-rw-r--r--engines/sky/logic.cpp362
1 files changed, 183 insertions, 179 deletions
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index a69ba793f2..e92e768272 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -382,8 +382,8 @@ void Logic::mainAnim() {
}
};
- uint16 animId = *(uint16*)_skyCompact->getCompactElem(_compact, C_ANIM_UP + _compact->megaSet + dir * 4);
- uint16 *animList = (uint16*)_skyCompact->fetchCpt(animId);
+ uint16 animId = *(uint16 *)_skyCompact->getCompactElem(_compact, C_ANIM_UP + _compact->megaSet + dir * 4);
+ uint16 *animList = (uint16 *)_skyCompact->fetchCpt(animId);
uint16 arAnimIndex = _compact->arAnimIndex;
if (!animList[arAnimIndex / 2]) {
@@ -400,7 +400,7 @@ void Logic::mainAnim() {
}
void Logic::arTurn() {
- uint16 *turnData = (uint16*)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
+ uint16 *turnData = (uint16 *)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
_compact->frame = *turnData++;
_compact->turnProgPos++;
@@ -453,7 +453,7 @@ void Logic::anim() {
}
void Logic::turn() {
- uint16 *turnData = (uint16*)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
+ uint16 *turnData = (uint16 *)_skyCompact->fetchCpt(_compact->turnProgId) + _compact->turnProgPos;
if (*turnData) {
_compact->frame = *turnData;
_compact->turnProgPos++;
@@ -1232,201 +1232,205 @@ uint16 Logic::mouseScript(uint32 scrNum, Compact *scriptComp) {
* @return 0 if script finished. Else offset where to continue.
*/
uint16 Logic::script(uint16 scriptNo, uint16 offset) {
-script:
- /// process a script
- /// low level interface to interpreter
+ do {
+ bool restartScript = false;
- uint16 moduleNo = scriptNo >> 12;
- uint16 *scriptData = _moduleList[moduleNo]; // get module address
+ /// process a script
+ /// low level interface to interpreter
- if (!scriptData) { // We need to load the script module
- _moduleList[moduleNo] = _skyDisk->loadScriptFile(moduleNo + F_MODULE_0);
- scriptData = _moduleList[moduleNo]; // module has been loaded
- }
+ uint16 moduleNo = scriptNo >> 12;
+ uint16 *scriptData = _moduleList[moduleNo]; // get module address
- uint16 *moduleStart = scriptData;
+ if (!scriptData) { // We need to load the script module
+ _moduleList[moduleNo] = _skyDisk->loadScriptFile(moduleNo + F_MODULE_0);
+ scriptData = _moduleList[moduleNo]; // module has been loaded
+ }
- debug(3, "Doing Script: %d:%d:%x", moduleNo, scriptNo & 0xFFF, offset ? (offset - moduleStart[scriptNo & 0xFFF]) : 0);
+ uint16 *moduleStart = scriptData;
- // WORKAROUND for bug #3149412: "Invalid Mode when giving shades to travel agent"
- // Using the dark glasses on Trevor (travel agent) multiple times in succession would
- // wreck the trevor compact's mode, as the script in question doesn't account for using
- // this item at this point in the game (you will only have it here if you play the game
- // in an unusual way) and thus would loop indefinitely / never drop out.
- // To prevent this, we trigger the generic response by pretending we're using an item
- // which the script /does/ handle.
- if (scriptNo == TREVOR_SPEECH && _scriptVariables[OBJECT_HELD] == IDO_SHADES)
- _scriptVariables[OBJECT_HELD] = IDO_GLASS;
+ debug(3, "Doing Script: %d:%d:%x", moduleNo, scriptNo & 0xFFF, offset ? (offset - moduleStart[scriptNo & 0xFFF]) : 0);
+ // WORKAROUND for bug #3149412: "Invalid Mode when giving shades to travel agent"
+ // Using the dark glasses on Trevor (travel agent) multiple times in succession would
+ // wreck the trevor compact's mode, as the script in question doesn't account for using
+ // this item at this point in the game (you will only have it here if you play the game
+ // in an unusual way) and thus would loop indefinitely / never drop out.
+ // To prevent this, we trigger the generic response by pretending we're using an item
+ // which the script /does/ handle.
+ if (scriptNo == TREVOR_SPEECH && _scriptVariables[OBJECT_HELD] == IDO_SHADES)
+ _scriptVariables[OBJECT_HELD] = IDO_GLASS;
- // Check whether we have an offset or what
- if (offset)
- scriptData = moduleStart + offset;
- else
- scriptData += scriptData[scriptNo & 0x0FFF];
- uint32 a = 0, b = 0, c = 0;
- uint16 command, s;
-
- for (;;) {
- command = *scriptData++; // get a command
- Debug::script(command, scriptData);
-
- switch (command) {
- case 0: // push_variable
- push( _scriptVariables[*scriptData++ / 4] );
- break;
- case 1: // less_than
- a = pop();
- b = pop();
- if (a > b)
- push(1);
- else
- push(0);
- break;
- case 2: // push_number
- push(*scriptData++);
- break;
- case 3: // not_equal
- a = pop();
- b = pop();
- if (a != b)
- push(1);
- else
- push(0);
- break;
- case 4: // if_and
- a = pop();
- b = pop();
- if (a && b)
- push(1);
- else
- push(0);
- break;
- case 5: // skip_zero
- s = *scriptData++;
-
- a = pop();
- if (!a)
- scriptData += s / 2;
- break;
- case 6: // pop_var
- b = _scriptVariables[*scriptData++ / 4] = pop();
- break;
- case 7: // minus
- a = pop();
- b = pop();
- push(b-a);
- break;
- case 8: // plus
- a = pop();
- b = pop();
- push(b+a);
- break;
- case 9: // skip_always
- s = *scriptData++;
- scriptData += s / 2;
- break;
- case 10: // if_or
- a = pop();
- b = pop();
- if (a || b)
- push(1);
- else
- push(0);
- break;
- case 11: // call_mcode
- {
- a = *scriptData++;
- assert(a <= 3);
- // No, I did not forget the "break"s
- switch (a) {
- case 3:
- c = pop();
- case 2:
- b = pop();
- case 1:
- a = pop();
- }
-
- uint16 mcode = *scriptData++ / 4; // get mcode number
- Debug::mcode(mcode, a, b, c);
+ // Check whether we have an offset or what
+ if (offset)
+ scriptData = moduleStart + offset;
+ else
+ scriptData += scriptData[scriptNo & 0x0FFF];
- Compact *saveCpt = _compact;
- bool ret = (this->*_mcodeTable[mcode]) (a, b, c);
- _compact = saveCpt;
+ uint32 a = 0, b = 0, c = 0;
+ uint16 command, s;
- if (!ret)
- return (scriptData - moduleStart);
- }
- break;
- case 12: // more_than
- a = pop();
- b = pop();
- if (a < b)
- push(1);
- else
- push(0);
- break;
- case 14: // switch
- c = s = *scriptData++; // get number of cases
+ while(!restartScript) {
+ command = *scriptData++; // get a command
+ Debug::script(command, scriptData);
- a = pop(); // and value to switch on
+ switch (command) {
+ case 0: // push_variable
+ push( _scriptVariables[*scriptData++ / 4] );
+ break;
+ case 1: // less_than
+ a = pop();
+ b = pop();
+ if (a > b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 2: // push_number
+ push(*scriptData++);
+ break;
+ case 3: // not_equal
+ a = pop();
+ b = pop();
+ if (a != b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 4: // if_and
+ a = pop();
+ b = pop();
+ if (a && b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 5: // skip_zero
+ s = *scriptData++;
- do {
- if (a == *scriptData) {
- scriptData += scriptData[1] / 2;
- scriptData++;
- break;
+ a = pop();
+ if (!a)
+ scriptData += s / 2;
+ break;
+ case 6: // pop_var
+ b = _scriptVariables[*scriptData++ / 4] = pop();
+ break;
+ case 7: // minus
+ a = pop();
+ b = pop();
+ push(b-a);
+ break;
+ case 8: // plus
+ a = pop();
+ b = pop();
+ push(b+a);
+ break;
+ case 9: // skip_always
+ s = *scriptData++;
+ scriptData += s / 2;
+ break;
+ case 10: // if_or
+ a = pop();
+ b = pop();
+ if (a || b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 11: // call_mcode
+ {
+ a = *scriptData++;
+ assert(a <= 3);
+ // No, I did not forget the "break"s
+ switch (a) {
+ case 3:
+ c = pop();
+ case 2:
+ b = pop();
+ case 1:
+ a = pop();
+ }
+
+ uint16 mcode = *scriptData++ / 4; // get mcode number
+ Debug::mcode(mcode, a, b, c);
+
+ Compact *saveCpt = _compact;
+ bool ret = (this->*_mcodeTable[mcode]) (a, b, c);
+ _compact = saveCpt;
+
+ if (!ret)
+ return (scriptData - moduleStart);
}
- scriptData += 2;
- } while (--s);
-
- if (s == 0)
- scriptData += *scriptData / 2; // use the default
- break;
- case 15: // push_offset
- push( *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) );
- break;
- case 16: // pop_offset
- // pop a value into a compact
- *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) = (uint16)pop();
- break;
- case 17: // is_equal
- a = pop();
- b = pop();
- if (a == b)
- push(1);
- else
- push(0);
- break;
- case 18: { // skip_nz
- int16 t = *scriptData++;
+ break;
+ case 12: // more_than
+ a = pop();
+ b = pop();
+ if (a < b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 14: // switch
+ c = s = *scriptData++; // get number of cases
+
+ a = pop(); // and value to switch on
+
+ do {
+ if (a == *scriptData) {
+ scriptData += scriptData[1] / 2;
+ scriptData++;
+ break;
+ }
+ scriptData += 2;
+ } while (--s);
+
+ if (s == 0)
+ scriptData += *scriptData / 2; // use the default
+ break;
+ case 15: // push_offset
+ push( *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) );
+ break;
+ case 16: // pop_offset
+ // pop a value into a compact
+ *(uint16 *)_skyCompact->getCompactElem(_compact, *scriptData++) = (uint16)pop();
+ break;
+ case 17: // is_equal
a = pop();
- if (a)
- scriptData += t / 2;
+ b = pop();
+ if (a == b)
+ push(1);
+ else
+ push(0);
+ break;
+ case 18: { // skip_nz
+ int16 t = *scriptData++;
+ a = pop();
+ if (a)
+ scriptData += t / 2;
+ break;
+ }
+ case 13:
+ case 19: // script_exit
+ return 0;
+ case 20: // restart_script
+ offset = 0;
+ restartScript = true;
break;
+ default:
+ error("Unknown script command: %d", command);
}
- case 13:
- case 19: // script_exit
- return 0;
- case 20: // restart_script
- offset = 0;
- goto script;
- default:
- error("Unknown script command: %d", command);
}
- }
+ } while (true);
}
bool Logic::fnCacheChip(uint32 a, uint32 b, uint32 c) {
_skySound->fnStopFx();
- _skyDisk->fnCacheChip((uint16*)_skyCompact->fetchCpt((uint16)a));
+ _skyDisk->fnCacheChip((uint16 *)_skyCompact->fetchCpt((uint16)a));
return true;
}
bool Logic::fnCacheFast(uint32 a, uint32 b, uint32 c) {
- _skyDisk->fnCacheFast((uint16*)_skyCompact->fetchCpt((uint16)a));
+ _skyDisk->fnCacheFast((uint16 *)_skyCompact->fetchCpt((uint16)a));
return true;
}
@@ -1573,7 +1577,7 @@ bool Logic::fnGetTo(uint32 targetPlaceId, uint32 mode, uint32 c) {
warning("can't find _compact's getToTable. Place compact is NULL");
return false;
}
- uint16 *getToTable = (uint16*)_skyCompact->fetchCpt(cpt->getToTableId);
+ uint16 *getToTable = (uint16 *)_skyCompact->fetchCpt(cpt->getToTableId);
if (!getToTable) {
warning("Place compact's getToTable is NULL");
return false;
@@ -1592,7 +1596,7 @@ bool Logic::fnGetTo(uint32 targetPlaceId, uint32 mode, uint32 c) {
bool Logic::fnSetToStand(uint32 a, uint32 b, uint32 c) {
_compact->mood = 1; // high level stood still
- _compact->grafixProgId = *(uint16*)_skyCompact->getCompactElem(_compact, C_STAND_UP + _compact->megaSet + _compact->dir * 4);
+ _compact->grafixProgId = *(uint16 *)_skyCompact->getCompactElem(_compact, C_STAND_UP + _compact->megaSet + _compact->dir * 4);
_compact->grafixProgPos = 0;
uint16 *standList = _skyCompact->getGrafixPtr(_compact);
@@ -2154,8 +2158,8 @@ bool Logic::fnSetMegaSet(uint32 mega, uint32 setNo, uint32 c) {
bool Logic::fnMoveItems(uint32 listNo, uint32 screenNo, uint32 c) {
// Move a list of id's to another screen
- uint16 *p = (uint16*)_skyCompact->fetchCpt(CPT_MOVE_LIST);
- p = (uint16*)_skyCompact->fetchCpt(p[listNo]);
+ uint16 *p = (uint16 *)_skyCompact->fetchCpt(CPT_MOVE_LIST);
+ p = (uint16 *)_skyCompact->fetchCpt(p[listNo]);
for (int i = 0; i < 2; i++) {
if (!*p)
return true;
@@ -2524,7 +2528,7 @@ void Logic::stdSpeak(Compact *target, uint32 textNum, uint32 animNum, uint32 bas
animNum += target->megaSet / NEXT_MEGA_SET;
animNum &= 0xFF;
- uint16 *talkTable = (uint16*)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST);
+ uint16 *talkTable = (uint16 *)_skyCompact->fetchCpt(CPT_TALK_TABLE_LIST);
target->grafixProgId = talkTable[animNum];
target->grafixProgPos = 0;
uint16 *animPtr = _skyCompact->getGrafixPtr(target);