diff options
Diffstat (limited to 'engines/sky/logic.cpp')
-rw-r--r-- | engines/sky/logic.cpp | 362 |
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); |