diff options
author | Florian Kagerer | 2009-05-17 15:02:34 +0000 |
---|---|---|
committer | Florian Kagerer | 2009-05-17 15:02:34 +0000 |
commit | b3a50b99fcc2663198f5cf6559eaaa0826d8faa6 (patch) | |
tree | 8dc8ddf54ee3de5b99550a73ec0e5c29ae08e003 /engines | |
parent | 2f798b088fab7cb191ec08ce6ca76126c849690a (diff) | |
download | scummvm-rg350-b3a50b99fcc2663198f5cf6559eaaa0826d8faa6.tar.gz scummvm-rg350-b3a50b99fcc2663198f5cf6559eaaa0826d8faa6.tar.bz2 scummvm-rg350-b3a50b99fcc2663198f5cf6559eaaa0826d8faa6.zip |
LOL: - some opcodes for the swamp
- fix last commit (which broke TIM scripts)
svn-id: r40654
Diffstat (limited to 'engines')
-rw-r--r-- | engines/kyra/lol.cpp | 11 | ||||
-rw-r--r-- | engines/kyra/lol.h | 15 | ||||
-rw-r--r-- | engines/kyra/script.h | 4 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 115 | ||||
-rw-r--r-- | engines/kyra/sound_towns.cpp | 37 |
5 files changed, 145 insertions, 37 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 920a79a3cb..49d2831fe6 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -235,6 +235,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _compassTimer = 0; _timer3Para = 0; + _scriptCharacterCycle = 0; _partyDeathFlag = -1; } @@ -3167,19 +3168,19 @@ int LoLEngine::removeCharacterItem(int charNum, int itemFlags) { return 0; } -bool LoLEngine::paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw) { +int LoLEngine::paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw) { if (!(_characters[charNum].flags & 1) || (_characters[charNum].flags & immunityFlags)) return 0; if ((int)_rnd.getRandomNumberRng(1, 100) > hitChance) return 0; - int r = false; + int r = 0; if (typeFlag == 0x40) { _characters[charNum].flags |= 0x40; setCharacterUpdateEvent(charNum, 3, 3600, 1); - r = true; + r = 1; // check for bezel ring } else if (typeFlag == 0x80 && !itemEquipped(charNum, 225)) { @@ -3187,12 +3188,12 @@ bool LoLEngine::paralyzePoisonCharacter(int charNum, int typeFlag, int immunityF setCharacterUpdateEvent(charNum, 4, 10, 1); if (characterSays(0x4021, _characters[charNum].id, true)) _txt->printMessage(6, getLangString(0x4021), _characters[charNum].name); - r = true; + r = 1; } else if (typeFlag == 0x1000) { _characters[charNum].flags |= 0x1000; setCharacterUpdateEvent(charNum, 7, 120, 1); - r = true; + r = 1; } if (r && redraw) diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 5bb5d02a7d..8a1a63ab56 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -614,6 +614,7 @@ private: int olol_getGlobalVar(EMCState *script); int olol_setGlobalVar(EMCState *script); int olol_triggerDoorSwitch(EMCState *script); + int olol_checkEquippedItemScriptFlags(EMCState *script); int olol_setDoorState(EMCState *script); int olol_updateBlockAnimations(EMCState *script); int olol_mapShapeToBlock(EMCState *script); @@ -661,7 +662,7 @@ private: int olol_playMusicTrack(EMCState *script); int olol_countBlockItems(EMCState *script); int olol_characterSkillTest(EMCState *script); - int olol_countActiveMonsters(EMCState *script); + int olol_countAllMonsters(EMCState *script); int olol_stopCharacterSpeech(EMCState *script); int olol_setPaletteBrightness(EMCState *script); int olol_calcInflictableDamage(EMCState *script); @@ -675,13 +676,15 @@ private: int olol_checkInventoryFull(EMCState *script); int olol_objectLeavesLevel(EMCState *script); int olol_addSpellToScroll(EMCState *script); + int olol_playDialogueText(EMCState *script); int olol_playDialogueTalkText(EMCState *script); int olol_checkMonsterTypeHostility(EMCState *script); int olol_setNextFunc(EMCState *script); int olol_dummy1(EMCState *script); int olol_suspendMonster(EMCState *script); - int olol_triggerEventOnMouseButtonRelease(EMCState *script); + int olol_triggerEventOnMouseButtonClick(EMCState *script); int olol_printWindowText(EMCState *script); + int olol_countSpecificMonsters(EMCState *script); int olol_updateBlockAnimations2(EMCState *script); int olol_checkPartyForItemType(EMCState *script); int olol_setUnkDoorVar(EMCState *script); @@ -693,14 +696,19 @@ private: int olol_initDialogueSequence(EMCState *script); int olol_restoreAfterDialogueSequence(EMCState *script); int olol_setSpecialSceneButtons(EMCState *script); + int olol_restoreButtonsAfterSpecialScene(EMCState *script); int olol_prepareSpecialScene(EMCState *script); int olol_restoreAfterSpecialScene(EMCState *script); int olol_assignCustomSfx(EMCState *script); + int olol_checkBlockForMonster(EMCState *script); int olol_transformRegion(EMCState *script); int olol_calcCoordinatesAddDirectionOffset(EMCState *script); int olol_resetPortraitsAndDisableSysTimer(EMCState *script); int olol_enableSysTimer(EMCState *script); int olol_checkNeedSceneRestore(EMCState *script); + int olol_getNextActiveCharacter(EMCState *script); + int olol_paralyzePoisonCharacter(EMCState *script); + int olol_drawCharPortrait(EMCState *script); int olol_castSpell(EMCState *script); int olol_pitDrop(EMCState *script); int olol_paletteFlash(EMCState *script); @@ -833,6 +841,7 @@ private: int _loadLevelFlag; int _hasTempDataFlags; int _unkCharNum; + uint16 _scriptCharacterCycle; int _charStatsTemp[5]; const LoLCharacter *_charDefaults; @@ -1294,7 +1303,7 @@ private: void applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage); void applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int deathFlag, int skill, int damage); int removeCharacterItem(int charNum, int itemFlags); - bool paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw); + int paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw); void paralyzePoisonAllCharacters(int typeFlag, int immunityFlags, int hitChance); void stunCharacter(int charNum); void level11specialUnk(); diff --git a/engines/kyra/script.h b/engines/kyra/script.h index 65631488af..187dc5fdec 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -84,8 +84,10 @@ public: // Both lead to some problems in our IFF parser, either reading after the end // of file or producing a "Chunk overread" error message. To work around this // we need to adjust the size field properly. - if (_typeId == MKID_BE('EMC2') || _typeId == MKID_BE('AVFS')) + if (_typeId == MKID_BE('EMC2')) _formChunk.size -= 8; + else if (_typeId == MKID_BE('AVFS')) + _formChunk.size = input.size() - 8; } }; diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 957aedf47c..4dca1e9bf0 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -750,6 +750,20 @@ int LoLEngine::olol_triggerDoorSwitch(EMCState *script) { return 1; } +int LoLEngine::olol_checkEquippedItemScriptFlags(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkEquippedItemScriptFlags(%p)", (const void *)script); + for (int i = 0; i < 4; i++) { + if (!(_characters[i].flags & 1)) + continue; + for (int ii = 0; ii < 4; ii++) { + uint8 f = _itemProperties[_itemsInPlay[_characters[i].items[ii]].itemPropertyIndex].itemScriptFunc; + if (f == 0 || f == 2) + return 1; + } + } + return 0; +} + int LoLEngine::olol_setDoorState(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setDoorState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (stackPos(1)) @@ -1349,8 +1363,8 @@ int LoLEngine::olol_characterSkillTest(EMCState *script){ return (_rnd.getRandomNumberRng(1, 100) > m) ? -1 : c; } -int LoLEngine::olol_countActiveMonsters(EMCState *script){ - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countActiveMonsters(%p)", (const void *)script); +int LoLEngine::olol_countAllMonsters(EMCState *script){ + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countAllMonsters(%p)", (const void *)script); int res = 0; for (int i = 0; i < 30; i++) { @@ -1510,6 +1524,12 @@ int LoLEngine::olol_addSpellToScroll(EMCState *script) { return 1; } +int LoLEngine::olol_playDialogueText(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playDialogueText(%p) (%d)", (const void *)script, stackPos(0)); + _txt->printDialogueText(3, getLangString(stackPos(0)), script, 0, 1); + return 1; +} + int LoLEngine::olol_playDialogueTalkText(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playDialogueTalkText(%p) (%d)", (const void *)script, stackPos(0)); int track = stackPos(0); @@ -1551,8 +1571,8 @@ int LoLEngine::olol_suspendMonster(EMCState *script) { return 1; } -int LoLEngine::olol_triggerEventOnMouseButtonRelease(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_triggerEventOnMouseButtonRelease(%p) (%d)", (const void *)script, stackPos(0)); +int LoLEngine::olol_triggerEventOnMouseButtonClick(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_triggerEventOnMouseButtonClick(%p) (%d)", (const void *)script, stackPos(0)); gui_notifyButtonListChanged(); snd_characterSpeaking(); @@ -1585,6 +1605,23 @@ int LoLEngine::olol_printWindowText(EMCState *script) { return 1; } +int LoLEngine::olol_countSpecificMonsters(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_countSpecificMonsters(%p) (%d, ...)", (const void *)script, stackPos(0)); + uint16 types = 0; + int res = 0; + int cnt = 0; + + while (stackPos(cnt) != -1) + types |= (1 << stackPos(cnt++)); + + for (int i = 0; i < 30; i++) { + if (((1 << _monsters[i].type) & types) && _monsters[i].mode < 14) + res++; + } + + return res; +} + int LoLEngine::olol_updateBlockAnimations2(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_updateBlockAnimations2(%p) (%d, %d, %d, %d, ...)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int numFrames = stackPos(3); @@ -1707,6 +1744,12 @@ int LoLEngine::olol_setSpecialSceneButtons(EMCState *script) { return 1; } +int LoLEngine::olol_restoreButtonsAfterSpecialScene(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreButtonsAfterSpecialScene(%p)", (const void *)script); + gui_specialSceneRestoreButtons(); + return 1; +} + int LoLEngine::olol_prepareSpecialScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_prepareSpecialScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); prepareSpecialScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); @@ -1735,6 +1778,20 @@ int LoLEngine::olol_assignCustomSfx(EMCState *script) { return 0; } +int LoLEngine::olol_checkBlockForMonster(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkBlockForMonster(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + uint16 block = stackPos(0); + uint16 id = stackPos(1) | 0x8000; + + uint16 o = _levelBlockProperties[block].assignedObjects; + while (o & 0x8000) { + if (id == 0xffff || id == o) + return o & 0x7fff; + o = findObject(o)->nextAssignedObject; + } + return -1; +} + int LoLEngine::olol_transformRegion(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_transformRegion(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); transformRegion(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); @@ -1767,6 +1824,36 @@ int LoLEngine::olol_checkNeedSceneRestore(EMCState *script) { return _needSceneRestore; } +int LoLEngine::olol_getNextActiveCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getNextActiveCharacter(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(0)) + _scriptCharacterCycle = 0; + else + _scriptCharacterCycle++; + + while (_scriptCharacterCycle < 4) { + if (_characters[_scriptCharacterCycle].flags & 1) + return _scriptCharacterCycle; + _scriptCharacterCycle++; + } + return -1; +} + +int LoLEngine::olol_paralyzePoisonCharacter(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_paralyzePoisonCharacter(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); + return paralyzePoisonCharacter(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); +} + +int LoLEngine::olol_drawCharPortrait(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drawCharPortrait(%p) (%d)", (const void *)script, stackPos(0)); + int charNum = stackPos(0); + if (charNum == -1) + gui_drawAllCharPortraitsWithStats(); + else + gui_drawCharPortraitWithStats(charNum); + return 1; +} + int LoLEngine::olol_castSpell(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_castSpell(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); return castSpell(stackPos(0), stackPos(1), stackPos(2)); @@ -2200,7 +2287,7 @@ void LoLEngine::setupOpcodeTable() { // 0x30 Opcode(olol_setGlobalVar); Opcode(olol_triggerDoorSwitch); - OpcodeUnImpl(); + Opcode(olol_checkEquippedItemScriptFlags); Opcode(olol_setDoorState); // 0x34 @@ -2282,7 +2369,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_characterSkillTest); // 0x68 - Opcode(olol_countActiveMonsters); + Opcode(olol_countAllMonsters); OpcodeUnImpl(); Opcode(olol_stopCharacterSpeech); Opcode(olol_setPaletteBrightness); @@ -2307,7 +2394,7 @@ void LoLEngine::setupOpcodeTable() { // 0x78 Opcode(olol_addSpellToScroll); - OpcodeUnImpl(); + Opcode(olol_playDialogueText); Opcode(olol_playDialogueTalkText); Opcode(olol_checkMonsterTypeHostility); @@ -2319,9 +2406,9 @@ void LoLEngine::setupOpcodeTable() { // 0x80 OpcodeUnImpl(); - Opcode(olol_triggerEventOnMouseButtonRelease); + Opcode(olol_triggerEventOnMouseButtonClick); Opcode(olol_printWindowText); - OpcodeUnImpl(); + Opcode(olol_countSpecificMonsters); // 0x84 Opcode(olol_updateBlockAnimations2); @@ -2339,7 +2426,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_initDialogueSequence); Opcode(olol_restoreAfterDialogueSequence); Opcode(olol_setSpecialSceneButtons); - OpcodeUnImpl(); + Opcode(olol_restoreButtonsAfterSpecialScene); // 0x90 OpcodeUnImpl(); @@ -2351,7 +2438,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_assignCustomSfx); OpcodeUnImpl(); OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_checkBlockForMonster); // 0x98 Opcode(olol_transformRegion); @@ -2361,9 +2448,9 @@ void LoLEngine::setupOpcodeTable() { // 0x9C Opcode(olol_checkNeedSceneRestore); - OpcodeUnImpl(); - OpcodeUnImpl(); - OpcodeUnImpl(); + Opcode(olol_getNextActiveCharacter); + Opcode(olol_paralyzePoisonCharacter); + Opcode(olol_drawCharPortrait); // 0xA0 OpcodeUnImpl(); diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 9f15d94518..05dee7f9e3 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -1235,11 +1235,16 @@ void TownsPC98_OpnOperator::generateOutput(int32 phasebuf, int32 *feed, int32 &o case s_ready: return; case s_attacking: - nextState = s_decaying; - targetTime = (1 << fs_a.shift) - 1; targetLevel = 0; - levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; - break; + nextState = s_decaying; + if ((_specifiedAttackRate << 1) + _keyScale2 < 64) { + targetTime = (1 << fs_a.shift) - 1; + levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; + break; + } else { + _currentLevel = targetLevel; + _state = nextState; + } case s_decaying: targetTime = (1 << fs_d.shift) - 1; nextState = s_sustaining; @@ -1485,7 +1490,7 @@ private: class TownsPC98_OpnSquareSineSource { public: - TownsPC98_OpnSquareSineSource(const uint32 timerbase, const uint8 levelOutModifier); + TownsPC98_OpnSquareSineSource(const uint32 timerbase); ~TownsPC98_OpnSquareSineSource(); void init(const int *rsTable, const int *rseTable); @@ -1516,7 +1521,6 @@ private: int32 *_tleTable; const uint32 _tickLength; - const uint8 _levelOutModifier; uint32 _timer; struct Channel { @@ -2554,8 +2558,8 @@ bool TownsPC98_OpnChannelPCM::control_ff_endOfTrack(uint8 para) { } } -TownsPC98_OpnSquareSineSource::TownsPC98_OpnSquareSineSource(const uint32 timerbase, const uint8 levelOutModifier) : _tlTable(0), - _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _levelOutModifier(levelOutModifier), _ready(0), _reg(0), _rand(1), _outN(1), +TownsPC98_OpnSquareSineSource::TownsPC98_OpnSquareSineSource(const uint32 timerbase) : _tlTable(0), + _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _ready(0), _reg(0), _rand(1), _outN(1), _nTick(0), _evpUpdateCnt(0), _evpTimer(0x1f), _pReslt(0x1f), _attack(0), _cont(false), _evpUpdate(true), _timer(0), _noiseGenerator(0), _chanEnable(0) { @@ -2715,7 +2719,7 @@ void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) { finOut += _tlTable[_channels[ii].out ? (_channels[ii].vol & 0x0f) : 0]; } - finOut >>= _levelOutModifier; + finOut /= 3; buffer[i << 1] += finOut; buffer[(i << 1) + 1] += finOut; } @@ -2969,7 +2973,7 @@ bool TownsPC98_OpnCore::init() { } if (_numSSG) { - _ssg = new TownsPC98_OpnSquareSineSource(_timerbase, _numChan / 3); + _ssg = new TownsPC98_OpnSquareSineSource(_timerbase); _ssg->init(&_ssgTables[0], &_ssgTables[16]); } @@ -3232,16 +3236,21 @@ int inline TownsPC98_OpnCore::readBuffer(int16 *buffer, const int numSamples) { void TownsPC98_OpnCore::generateTables() { delete[] _oprRates; _oprRates = new uint8[128]; + + WRITE_BE_UINT32(_oprRates + 32, _numChan == 6 ? 0x90900000 : 0x00081018); + WRITE_BE_UINT32(_oprRates + 36, _numChan == 6 ? 0x00001010 : 0x00081018); memset(_oprRates, 0x90, 32); - uint8 *dst = (uint8*) _oprRates + 32; + memset(_oprRates + 96, 0x80, 32); + uint8 *dst = (uint8*) _oprRates + 40; + for (int i = 0; i < 40; i += 4) + WRITE_BE_UINT32(dst + i, 0x00081018); for (int i = 0; i < 48; i += 4) WRITE_BE_UINT32(dst + i, 0x00081018); - dst += 48; + dst += 40; for (uint8 i = 0; i < 16; i ++) { uint8 v = (i < 12) ? i : 12; *dst++ = ((4 + v) << 3); } - memset(dst, 0x80, 32); delete[] _oprRateshift; _oprRateshift = new uint8[128]; @@ -3382,7 +3391,7 @@ void TownsPC98_OpnCore::nextTick(int32 *buffer, uint32 bufferSize) { break; }; - int32 finOut = ((output << 2) / ((_numChan + _numSSG - 3) / 3)); + int32 finOut = (output << 2) / ((_numChan + _numSSG - 3) / 3); if (_chanInternal[i].enableLeft) *leftSample += finOut; |