diff options
Diffstat (limited to 'engines/kyra/script_lol.cpp')
-rw-r--r-- | engines/kyra/script_lol.cpp | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp new file mode 100644 index 0000000000..488ec54d14 --- /dev/null +++ b/engines/kyra/script_lol.cpp @@ -0,0 +1,450 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/lol.h" +#include "kyra/screen_lol.h" + +#include "common/endian.h" + +namespace Kyra { + +void LoLEngine::runInitScript(const char *filename, int func) { + EMCData scriptData; + EMCState scriptState; + memset(&scriptData, 0, sizeof(EMCData)); + _emc->load(filename, &scriptData, &_opcodes); + + _emc->init(&scriptState, &scriptData); + _emc->start(&scriptState, 0); + while (_emc->isValid(&scriptState)) + _emc->run(&scriptState); + + if (func) { + _emc->init(&scriptState, &scriptData); + _emc->start(&scriptState, func); + while (_emc->isValid(&scriptState)) + _emc->run(&scriptState); + } + + _emc->unload(&scriptData); +} + +void LoLEngine::runInfScript(const char *filename) { + _emc->load(filename, &_scriptData, &_opcodes); + runResidentScript(0x400, -1); +} + +void LoLEngine::runResidentScript(int func, int reg0) { + runResidentScriptCustom(func, reg0, -1, 0, 0, 0); +} + +void LoLEngine::runResidentScriptCustom(int func, int reg0, int reg1, int reg2, int reg3, int reg4) { + EMCState scriptState; + memset(&scriptState, 0, sizeof(EMCState)); + + if (!_scriptBoolSkipExec) { + _emc->init(&scriptState, &_scriptData); + _emc->start(&scriptState, func); + + scriptState.regs[0] = reg0; + scriptState.regs[1] = reg1; + scriptState.regs[2] = reg2; + scriptState.regs[3] = reg3; + scriptState.regs[4] = reg4; + scriptState.regs[5] = func; + scriptState.regs[6] = _unkScriptByte; + + while (_emc->isValid(&scriptState)) + _emc->run(&scriptState); + } + + checkScriptUnk(func); +} + +bool LoLEngine::checkScriptUnk(int func) { + if (_boolScriptFuncDone) + return true; + + for (int i = 0; i < 15; i++) { + if (_scriptExecutedFuncs[i] == func) { + _boolScriptFuncDone = true; + return true; + } + } + + if (_currentBlock == func){ + _boolScriptFuncDone = true; + return true; + } + + return false; +} + +int LoLEngine::o2_setGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + if (stackPos(1)) + _gameFlags[stackPos(0) >> 4] |= (1 << (stackPos(0) & 0x0f)); + else + _gameFlags[stackPos(0) >> 4] &= (~(1 << (stackPos(0) & 0x0f))); + + return 1; +} + +int LoLEngine::o2_testGameFlag(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_testGameFlag(%p) (%d)", (const void *)script, stackPos(0)); + if (!stackPos(0)) + return 0; + + if (_gameFlags[stackPos(0) >> 4] & (1 << (stackPos(0) & 0x0f))) + return 1; + + return 0; +} + +int LoLEngine::o2_loadLevelSupplemenaryFiles(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadLevelSupplemenaryFiles(%p) (%d)", (const void *)script, stackPos(0)); + loadLevelSupplemenaryFiles(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), (stackPos(5) == -1) ? 0 : stackPosString(5)); + return 1; +} + +int LoLEngine::o2_loadCmzFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadCmzFile(%p) (%d)", (const void *)script, stackPos(0)); + loadCmzFile(stackPosString(0)); + return 1; +} + +int LoLEngine::o2_loadMonsterShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadMonsterShapes(%p) (%d)", (const void *)script, stackPos(0)); + loadMonsterShapes(stackPosString(0), stackPos(1), stackPos(2)); + return 1; +} + +int LoLEngine::o2_allocItemPropertiesBuffer(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_allocItemPropertiesBuffer(%p) (%d)", (const void *)script, stackPos(0)); + delete []_itemProperties; + _itemProperties = new ItemProperty[stackPos(0)]; + return 1; +} + +int LoLEngine::o2_setItemProperty(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setItemProperty(%p) (%d)", (const void *)script, stackPos(0)); + ItemProperty *tmp = &_itemProperties[stackPos(0)]; + + tmp->nameStringId = stackPos(1); + tmp->shpIndex = stackPos(2); + tmp->unk5 = stackPos(3); + tmp->itemScriptFunc = stackPos(4); + tmp->unk8 = stackPos(5); + tmp->unk9 = stackPos(6); + tmp->unkA = stackPos(7); + tmp->flags = stackPos(8); + tmp->unkB = stackPos(9); + return 1; +} + +int LoLEngine::o2_makeItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_makeItem(%p) (%d)", (const void *)script, stackPos(0)); + return makeItem(stackPos(0), stackPos(1), stackPos(2)); +} + +int LoLEngine::o2_getItemPara(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_getItemPara(%p) (%d)", (const void *)script, stackPos(0)); + if(!stackPos(0)) + return 0; + + ItemInPlay *i = &_itemsInPlay[stackPos(0)]; + ItemProperty *p = &_itemProperties[i->itemPropertyIndex]; + + switch(stackPos(1)) { + case 0: + return i->cmzIndex; + case 1: + return i->unk7; + case 2: + return i->anonymous_4; + case 3: + return i->level; + case 4: + return i->itemPropertyIndex; + case 5: + return i->shpCurFrame_flg; + case 6: + return p->nameStringId; + case 7: + break; + case 8: + return p->shpIndex; + case 9: + return p->unk5; + case 10: + return p->itemScriptFunc; + case 11: + case 12: + case 13: + return p[stackPos(1)].unkB & 0x0f; + case 14: + return p->unkB; + case 15: + return i->shpCurFrame_flg & 0x1fff; + case 16: + return p->flags; + case 17: + return (p->unk9 << 8) | p->unk8; + default: + break; + } + + return -1; +} + +int LoLEngine::o2_getCharacterStat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_getCharacterStat(%p) (%d)", (const void *)script, stackPos(0)); + LoLCharacter *c = &_characters[stackPos(0)]; + int d = stackPos(2); + + switch(stackPos(1)) { + case 0: + return c->flags; + case 1: + return c->raceClassSex; + case 2: + case 3: + case 4: + default: + break; + case 5: + return c->hitPointsCur; + case 6: + return c->hitPointsMax; + case 7: + return c->magicPointsCur; + case 8: + return c->magicPointsMax; + case 9: + return c->field_37; + case 10: + return c->items[d]; + case 11: + return c->field_66[d] + c->field_69[d]; + case 12: + return c->field_27[d]; + case 13: + return (d & 0x80) ? c->field_25 : c->field_17[d]; + case 14: + return c->field_69[d]; + case 15: + return c->id; + } + + return 0; +} + +int LoLEngine::o2_setCharacterStat(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setCharacterStat(%p) (%d)", (const void *)script, stackPos(0)); + LoLCharacter *c = &_characters[stackPos(0)]; + int d = stackPos(2); + int e = stackPos(3); + + switch(stackPos(1)) { + case 0: + c->flags = e; + case 1: + c->raceClassSex = e & 0x0f; + case 2: + case 3: + case 4: + default: + break; + case 5: + //// TODO + break; + case 6: + c->hitPointsMax = e; + case 7: + //// TODO + break; + case 8: + c->magicPointsMax = e; + case 9: + c->field_37 = e; + case 10: + c->items[d] = 0; + case 11: + c->field_66[d] = e; + case 12: + c->field_27[d] = e; + case 13: + if (d & 0x80) + c->field_25 = e; + else + c->field_17[d] = e; + case 14: + c->field_69[d] = e; + } + + return 0; +} + +int LoLEngine::o2_loadLevelShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadLevelShapes(%p) (%d)", (const void *)script, stackPos(0)); + loadLevelShpDat(stackPosString(0), stackPosString(1), true); + return 1; +} + +int LoLEngine::o2_closeLevelShapeFile(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_closeLevelShapeFile(%p) (%d)", (const void *)script, stackPos(0)); + delete _lvlShpFileHandle; + _lvlShpFileHandle = 0; + return 1; +} + +int LoLEngine::o2_loadDoorShapes(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadDoorShapes(%p) (%d)", (const void *)script, stackPos(0)); + _screen->loadBitmap(stackPosString(0), 3, 3, 0); + const uint8 *p = _screen->getCPagePtr(2); + if (_doorShapes[0]) + delete []_doorShapes[0]; + _doorShapes[0] = _screen->makeShapeCopy(p, stackPos(1)); + if (_doorShapes[1]) + delete []_doorShapes[1]; + _doorShapes[1] = _screen->makeShapeCopy(p, stackPos(2)); + + for (int i = 0; i < 20; i++) { + _wllBuffer5[i + 3] |= 7; + int t = i % 5; + if (t == 4) + _wllBuffer5[i + 3] &= 0xf8; + if (t == 3) + _wllBuffer5[i + 3] &= 0xfd; + } + + if (stackPos(3)) { + for (int i = 3; i < 13; i++) + _wllBuffer5[i] &= 0xfd; + } + + if (stackPos(4)) { + for (int i = 13; i < 23; i++) + _wllBuffer5[i] &= 0xfd; + } + + return 1; +} + +int LoLEngine::o2_setGlobalVar(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setGlobalVar(%p) (%d)", (const void *)script, stackPos(0)); + //uint16 a = stackPos(1); + uint16 b = stackPos(2); + + switch (stackPos(0)) { + case 0: + _currentBlock = b; + setLF1(_unkCmzU1, _unkCmzU2, _currentBlock, 0x80, 0x80); + setLF2(_currentBlock); + break; + case 1: + _unkPara2 = b; + break; + case 2: + _currentLevel = b & 0xff; + break; + case 3: + break; + case 4: + _brightness = b & 0xff; + break; + case 5: + _credits = b; + break; + case 6: + //TODO + break; + case 7: + break; + case 8: + _charFlagUnk = b; + //TODO + break; + case 9: + _lampStatusUnk = b & 0xff; + break; + case 10: + _loadLevelFlag2 = b & 0xff; + //TODO + break; + case 11: + //TODO + break; + case 12: + //TODO + break; + default: + break; + } + + return 1; +} + +int LoLEngine::o2_mapShapeToBlock(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_mapShapeToBlock(%p) (%d)", (const void *)script, stackPos(0)); + return assignLevelShapes(stackPos(0)); +} + +int LoLEngine::o2_resetBlockShapeAssignment(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_resetBlockShapeAssignment(%p) (%d)", (const void *)script, stackPos(0)); + uint8 v = stackPos(0) & 0xff; + memset(_wllShapeMap + 3, v, 5); + memset(_wllShapeMap + 13, v, 5); + return 1; +} + +int LoLEngine::o2_setPaletteBrightness(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setPaletteBrightness(%p) (%d)", (const void *)script, stackPos(0)); + uint16 old = _brightness; + _brightness = stackPos(0); + if (stackPos(1) == 1) + _screen->setPaletteBrightness(_screen->_currentPalette, stackPos(0), _lampOilStatus); + return old; +} + +int LoLEngine::o2_assignCustomSfx(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_assignCustomSfx(%p) (%d)", (const void *)script, stackPos(0)); + const char *c = stackPosString(0); + int i = stackPos(1); + + if (!c || i > 250) + return 0; + + if (_ingameSoundIndex[i] == 0xffff) + return 0; + + strcpy(_ingameSoundList[_ingameSoundIndex[i]], c); + + return 0; +} + +} // end of namespace Kyra + + |