diff options
Diffstat (limited to 'engines/gob/inter_v1.cpp')
-rw-r--r-- | engines/gob/inter_v1.cpp | 2956 |
1 files changed, 1590 insertions, 1366 deletions
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 045fa9007b..f6081a8fb2 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -23,22 +23,26 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "common/file.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/inter.h" +#include "gob/global.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/parse.h" -#include "gob/game.h" +#include "gob/dataio.h" +#include "gob/music.h" +#include "gob/cdrom.h" #include "gob/draw.h" -#include "gob/mult.h" +#include "gob/game.h" #include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/music.h" +#include "gob/inter.h" #include "gob/map.h" +#include "gob/mult.h" #include "gob/palanim.h" -#include "gob/anim.h" +#include "gob/parse.h" +#include "gob/scenery.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -122,12 +126,12 @@ Inter_v1::Inter_v1(GobEngine *vm) : Inter(vm) { setupOpcodes(); } -void Inter_v1::setupOpcodes(void) { +void Inter_v1::setupOpcodes() { static const OpcodeDrawEntryV1 opcodesDraw[256] = { /* 00 */ OPCODE(o1_loadMult), OPCODE(o1_playMult), - OPCODE(o1_freeMult), + OPCODE(o1_freeMultKeys), {NULL, ""}, /* 04 */ {NULL, ""}, @@ -151,11 +155,11 @@ void Inter_v1::setupOpcodes(void) { {NULL, ""}, /* 14 */ OPCODE(o1_initMult), - OPCODE(o1_multFreeMult), + OPCODE(o1_freeMult), OPCODE(o1_animate), - OPCODE(o1_multLoadMult), + OPCODE(o1_loadMultObject), /* 18 */ - OPCODE(o1_storeParams), + OPCODE(o1_getAnimLayerInfo), OPCODE(o1_getObjAnimSize), OPCODE(o1_loadStatic), OPCODE(o1_freeStatic), @@ -450,15 +454,15 @@ void Inter_v1::setupOpcodes(void) { /* 00 */ OPCODE(o1_callSub), OPCODE(o1_callSub), - OPCODE(o1_drawPrintText), + OPCODE(o1_printTotText), OPCODE(o1_loadCursor), /* 04 */ {NULL, ""}, - OPCODE(o1_call), + OPCODE(o1_switch), OPCODE(o1_repeatUntil), OPCODE(o1_whileDo), /* 08 */ - OPCODE(o1_callBool), + OPCODE(o1_if), OPCODE(o1_evaluateStore), OPCODE(o1_loadSpriteToPos), {NULL, ""}, @@ -642,12 +646,13 @@ void Inter_v1::setupOpcodes(void) { }; _opcodesDrawV1 = opcodesDraw; - _opcodesFuncV1 = opcodesFunc; // EGroupe + _opcodesFuncV1 = opcodesFunc; _opcodesGoblinV1 = opcodesGoblin; } void Inter_v1::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; @@ -657,8 +662,9 @@ void Inter_v1::executeDrawOpcode(byte i) { (this->*op) (); } -bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); +bool Inter_v1::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -670,12 +676,13 @@ bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, if (op == NULL) warning("unimplemented opcodeFunc: %d.%d", i, j); else - return (this->*op) (cmdCount, counter, retFlag); + return (this->*op) (params); return false; } -void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); +void Inter_v1::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcV1 op = NULL; @@ -692,7 +699,7 @@ void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Go _vm->_global->_inter_execPtr += cmd * 2; } else - (this->*op) (extraData, retVarPtr, objDesc); + (this->*op) (params); } const char *Inter_v1::getOpcodeDrawDesc(byte i) { @@ -714,7 +721,6 @@ const char *Inter_v1::getOpcodeGoblinDesc(int i) { } void Inter_v1::checkSwitchTable(char **ppExec) { - int i; int16 len; int32 value; bool found; @@ -727,7 +733,7 @@ void Inter_v1::checkSwitchTable(char **ppExec) { len = (int8) *_vm->_global->_inter_execPtr++; while (len != -5) { - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { evalExpr(0); if (_terminate) @@ -742,7 +748,8 @@ void Inter_v1::checkSwitchTable(char **ppExec) { if (found) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; found = false; len = (int8) *_vm->_global->_inter_execPtr++; } @@ -754,150 +761,33 @@ void Inter_v1::checkSwitchTable(char **ppExec) { if (notFound) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; -} - -bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); - _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); - if (_vm->_global->_useMouse != 0) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - return false; -} - -bool Inter_v1::o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) { - char *savedPos; - int16 token; - int16 result; - int16 varOff; - - savedPos = _vm->_global->_inter_execPtr; - varOff = _vm->_parse->parseVarIndex(); - token = evalExpr(&result); - switch (savedPos[0]) { - case 23: - case 26: - WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); - break; - - case 25: - case 28: - if (token == 20) - WRITE_VARO_UINT8(varOff, result); - else - WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); - break; - - } - return false; -} - -bool Inter_v1::o1_capturePush(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 left; - int16 top; - int16 width; - int16 height; - - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); - _vm->_game->capturePush(left, top, width, height); - (*_vm->_scenery->_pCaptureCounter)++; - return false; -} - -bool Inter_v1::o1_capturePop(char &cmdCount, int16 &counter, int16 &retFlag) { - if (*_vm->_scenery->_pCaptureCounter != 0) { - (*_vm->_scenery->_pCaptureCounter)--; - _vm->_game->capturePop(1); - } - return false; -} - -bool Inter_v1::o1_printText(char &cmdCount, int16 &counter, int16 &retFlag) { - char buf[60]; - int16 i; - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); - _vm->_draw->_destSurface = 21; - _vm->_draw->_textToPrint = buf; - _vm->_draw->_transparency = 0; - - if (_vm->_draw->_backColor >= 16) { - _vm->_draw->_backColor = 0; - _vm->_draw->_transparency = 1; - } - - do { - for (i = 0; *_vm->_global->_inter_execPtr != '.' && (byte)*_vm->_global->_inter_execPtr != 200; - i++, _vm->_global->_inter_execPtr++) { - buf[i] = *_vm->_global->_inter_execPtr; - } - - if ((byte)*_vm->_global->_inter_execPtr != 200) { - _vm->_global->_inter_execPtr++; - switch (*_vm->_global->_inter_execPtr) { - case 23: - case 26: - sprintf(buf + i, "%d", VAR_OFFSET(_vm->_parse->parseVarIndex())); - break; - - case 25: - case 28: - sprintf(buf + i, "%s", GET_VARO_STR(_vm->_parse->parseVarIndex())); - break; - } - _vm->_global->_inter_execPtr++; - } else { - buf[i] = 0; - } - _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while ((byte)*_vm->_global->_inter_execPtr != 200); - _vm->_global->_inter_execPtr++; - - return false; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } -bool Inter_v1::o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) { - _animPalDir[0] = load16(); - _animPalLowIndex[0] = _vm->_parse->parseValExpr(); - _animPalHighIndex[0] = _vm->_parse->parseValExpr(); - return false; +void Inter_v1::o1_loadMult() { + _vm->_mult->loadMult(load16()); } -void Inter_v1::o1_loadMult(void) { - int16 resId; - - resId = load16(); - _vm->_mult->loadMult(resId); -} - -void Inter_v1::o1_playMult(void) { +void Inter_v1::o1_playMult() { int16 checkEscape; checkEscape = load16(); _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); } -void Inter_v1::o1_freeMult(void) { - load16(); // unused +void Inter_v1::o1_freeMultKeys() { + load16(); _vm->_mult->freeMultKeys(); } -void Inter_v1::o1_initCursor(void) { +void Inter_v1::o1_initCursor() { int16 width; int16 height; int16 count; - int16 i; - _vm->_draw->_cursorXDeltaVar = _vm->_parse->parseVarIndex(); - _vm->_draw->_cursorYDeltaVar = _vm->_parse->parseVarIndex(); + _vm->_draw->_cursorHotspotXVar = _vm->_parse->parseVarIndex() / 4; + _vm->_draw->_cursorHotspotYVar = _vm->_parse->parseVarIndex() / 4; width = load16(); if (width < 16) @@ -907,16 +797,19 @@ void Inter_v1::o1_initCursor(void) { if (height < 16) height = 16; + _vm->_draw->adjustCoords(0, &width, &height); + count = load16(); if (count < 2) count = 2; - if (width != _vm->_draw->_cursorWidth || height != _vm->_draw->_cursorHeight || - _vm->_draw->_cursorSprites->width != width * count) { + if ((width != _vm->_draw->_cursorWidth) || + (height != _vm->_draw->_cursorHeight) || + (_vm->_draw->_cursorSprites->getWidth() != (width * count))) { - _vm->_video->freeSurfDesc(_vm->_draw->_cursorSprites); - _vm->_draw->_spritesArray[23] = 0; - _vm->_video->freeSurfDesc(_vm->_draw->_scummvmCursor); + _vm->_draw->freeSprite(23); + _vm->_draw->_cursorSprites = 0; + _vm->_draw->_cursorSpritesBack = 0; _vm->_draw->_scummvmCursor = 0; _vm->_draw->_cursorWidth = width; @@ -930,15 +823,17 @@ void Inter_v1::o1_initCursor(void) { if (count > 0x80) count -= 0x80; - _vm->_draw->_cursorSprites = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth * count, - _vm->_draw->_cursorHeight, 2); - _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + _vm->_draw->initSpriteSurf(23, _vm->_draw->_cursorWidth * count, + _vm->_draw->_cursorHeight, 2); + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; _vm->_draw->_scummvmCursor = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth, - _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); - for (i = 0; i < 40; i++) { + _vm->_video->initSurfDesc(_vm->_global->_videoMode, + _vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, + SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { _vm->_draw->_cursorAnimLow[i] = -1; _vm->_draw->_cursorAnimDelays[i] = 0; _vm->_draw->_cursorAnimHigh[i] = 0; @@ -947,7 +842,7 @@ void Inter_v1::o1_initCursor(void) { } } -void Inter_v1::o1_initCursorAnim(void) { +void Inter_v1::o1_initCursorAnim() { int16 ind; _vm->_draw->_showCursor = 3; @@ -957,7 +852,7 @@ void Inter_v1::o1_initCursorAnim(void) { _vm->_draw->_cursorAnimDelays[ind] = load16(); } -void Inter_v1::o1_clearCursorAnim(void) { +void Inter_v1::o1_clearCursorAnim() { int16 ind; _vm->_draw->_showCursor = 0; @@ -967,672 +862,19 @@ void Inter_v1::o1_clearCursorAnim(void) { _vm->_draw->_cursorAnimDelays[ind] = 0; } -bool Inter_v1::o1_drawOperations(char &cmdCount, int16 &counter, int16 &retFlag) { - byte cmd; - - cmd = *_vm->_global->_inter_execPtr++; - - executeDrawOpcode(cmd); - - return false; -} - -bool Inter_v1::o1_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 freeVar; - int16 maxFreeVar; - - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); - - // HACK - WRITE_VAR_OFFSET(freeVar, 1000000); - WRITE_VAR_OFFSET(maxFreeVar, 1000000); - return false; -} - -bool Inter_v1::o1_manageDataFile(char &cmdCount, int16 &counter, int16 &retFlag) { - evalExpr(0); - - if (_vm->_global->_inter_resStr[0] != 0) - _vm->_dataio->openDataFile(_vm->_global->_inter_resStr); - else - _vm->_dataio->closeDataFile(); - return false; -} - -bool Inter_v1::o1_writeData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 offset; - int16 handle; - int16 size; - int16 dataVar; - int16 retSize; - - // FIXME: This code tries to write to a file. But this is not portable - // as datafiles might not be writeable. So we should determine when - // precisely this function is used, and see if we can either change it - // to a no-op, or use the SaveFileManager instead. If we use savefiles, - // then corresponding read etc. file calls would have to be adapted, too. - - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr, Common::File::kFileWriteMode); - - if (handle < 0) - return false; - - if (offset < 0) { - _vm->_dataio->seekData(handle, -offset - 1, 2); - } else { - _vm->_dataio->seekData(handle, offset, 0); - } - - retSize = _vm->_dataio->file_getHandle(handle)->write(_vm->_global->_inter_variables + dataVar, size); - - if (retSize == size) - WRITE_VAR(1, 0); - - _vm->_dataio->closeData(handle); - return false; -} - -bool Inter_v1::o1_checkData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 handle; - int16 varOff; - - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - - WRITE_VAR_OFFSET(varOff, handle); - if (handle >= 0) - _vm->_dataio->closeData(handle); - else - warning("File \"%s\" not found", _vm->_global->_inter_resStr); - return false; -} - -bool Inter_v1::o1_readData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 retSize; - int16 size; - int16 dataVar; - int16 offset; - int16 handle; - char buf[4]; - - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - if (handle >= 0) { - _vm->_draw->animateCursor(4); - if (offset < 0) - _vm->_dataio->seekData(handle, -offset - 1, 2); - else - _vm->_dataio->seekData(handle, offset, 0); - - if (((dataVar >> 2) == 59) && (size == 4)) { - retSize = _vm->_dataio->readData(handle, buf, 4); - WRITE_VAR(59, READ_LE_UINT32(buf)); - } else - retSize = _vm->_dataio->readData(handle, _vm->_global->_inter_variables + dataVar, size); - _vm->_dataio->closeData(handle); - - if (retSize == size) - WRITE_VAR(1, 0); - } - - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); - return false; -} - -bool Inter_v1::o1_loadFont(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - evalExpr(0); - index = load16(); - - if (_vm->_draw->_fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->_fonts[index]); - - _vm->_draw->animateCursor(4); - if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); - - _vm->_draw->_fonts[index] = _vm->_util->loadFont(_vm->_global->_inter_resStr); - - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); - return false; -} - -bool Inter_v1::o1_freeFont(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - index = load16(); - if (_vm->_draw->_fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->_fonts[index]); - - _vm->_draw->_fonts[index] = 0; - return false; -} - -bool Inter_v1::o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 var; - - var = _vm->_parse->parseVarIndex(); - _vm->_util->prepareStr(GET_VARO_STR(var)); - _vm->_global->writeVarSizeStr(var, strlen(GET_VARO_STR(var))); - return false; -} - -bool Inter_v1::o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 pos; - int16 strVar; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - pos = _vm->_parse->parseValExpr(); - _vm->_util->insertStr(_vm->_global->_inter_resStr, GET_VARO_STR(strVar), pos); - _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); - return false; -} - -bool Inter_v1::o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 var; - int16 pos; - int16 size; - - var = _vm->_parse->parseVarIndex(); - pos = _vm->_parse->parseValExpr(); - size = _vm->_parse->parseValExpr(); - _vm->_util->cutFromStr(GET_VARO_STR(var), pos, size); - return false; -} - -bool Inter_v1::o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 strVar; - int16 resVar; - int16 pos; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - resVar = _vm->_parse->parseVarIndex(); - - char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr); - pos = res ? (res - (GET_VARO_STR(strVar))) : -1; - WRITE_VAR_OFFSET(resVar, pos); - return false; -} - -bool Inter_v1::o1_setFrameRate(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); - return false; -} - -bool Inter_v1::o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 len; - int16 var; - - var = _vm->_parse->parseVarIndex(); - len = strlen(GET_VARO_STR(var)); - var = _vm->_parse->parseVarIndex(); - - WRITE_VAR_OFFSET(var, len); - return false; -} - -bool Inter_v1::o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag) { - char str[20]; - int16 strVar; - int16 destVar; - int32 res; - - strVar = _vm->_parse->parseVarIndex(); - strcpy(str, GET_VARO_STR(strVar)); - res = atol(str); - - destVar = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(destVar, res); - return false; -} - -bool Inter_v1::o1_invalidate(char &cmdCount, int16 &counter, int16 &retFlag) { - warning("invalidate: 'bugged' function"); - _vm->_draw->_destSurface = load16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_INVALIDATE); - return false; -} - -bool Inter_v1::o1_loadSpriteContent(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_spriteLeft = load16(); - _vm->_draw->_destSurface = load16(); - _vm->_draw->_transparency = load16(); - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); - return false; -} - -bool Inter_v1::o1_copySprite(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_sourceSurface = load16(); - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_spriteLeft = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_transparency = load16(); - _vm->_draw->spriteOperation(DRAW_BLITSURF); - return false; -} - -bool Inter_v1::o1_putPixel(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_PUTPIXEL); - return false; -} - -bool Inter_v1::o1_fillRect(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_FILLRECT); - return false; -} - -bool Inter_v1::o1_drawLine(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_DRAWLINE); - return false; -} - -bool Inter_v1::o1_createSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - int16 height; - int16 width; - int16 flag; - - index = load16(); - width = load16(); - height = load16(); - - flag = load16(); - if (flag == 1) -// _vm->_draw->_spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 2); - _vm->_draw->initSpriteSurf(index, _vm->_global->_videoMode, width, height, 2); - else -// _vm->_draw->_spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 0); - _vm->_draw->initSpriteSurf(index, _vm->_global->_videoMode, width, height, 0); - - _vm->_video->clearSurf(_vm->_draw->_spritesArray[index]); - return false; -} - -bool Inter_v1::o1_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - index = load16(); - if (_vm->_draw->_spritesArray[index] == 0) - return false; - - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[index]); - _vm->_draw->_spritesArray[index] = 0; - return false; -} - -bool Inter_v1::o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag) { - static int16 composition[50]; - int16 i; - int16 dataVar; - int16 freqVal; - - dataVar = _vm->_parse->parseVarIndex(); - freqVal = _vm->_parse->parseValExpr(); - for (i = 0; i < 50; i++) - composition[i] = (int16)VAR_OFFSET(dataVar + i * 4); - - _vm->_snd->playComposition(composition, freqVal); - return false; -} - -bool Inter_v1::o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - _vm->_snd->stopSound(_vm->_parse->parseValExpr()); - _soundEndTimeKey = 0; - return false; -} - -bool Inter_v1::o1_playSound(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 frequency; - int16 freq2; - int16 repCount; - int16 index; - - index = _vm->_parse->parseValExpr(); - repCount = _vm->_parse->parseValExpr(); - frequency = _vm->_parse->parseValExpr(); - - _vm->_snd->stopSound(0); - _soundEndTimeKey = 0; - if (_vm->_game->_soundSamples[index] == 0) - return false; - - if (repCount < 0) { - if (_vm->_global->_soundFlags < 2) - return false; - - repCount = -repCount; - _soundEndTimeKey = _vm->_util->getTimeKey(); - - if (frequency == 0) { - freq2 = _vm->_game->_soundSamples[index]->frequency; - } else { - freq2 = frequency; - } - _soundStopVal = - (10 * (_vm->_game->_soundSamples[index]->size / 2)) / freq2; - _soundEndTimeKey += - ((_vm->_game->_soundSamples[index]->size * repCount - - _vm->_game->_soundSamples[index]->size / 2) * 1000) / freq2; - } - _vm->_snd->playSample(_vm->_game->_soundSamples[index], repCount, frequency); - return false; -} - -bool Inter_v1::o1_loadCursor(char &cmdCount, int16 &counter, int16 &retFlag) { - Game::TotResItem *itemPtr; - int16 width; - int16 height; - int32 offset; - char *dataBuf; - int16 id; - int8 index; - - id = load16(); - index = *_vm->_global->_inter_execPtr++; - itemPtr = &_vm->_game->_totResourceTable->items[id]; - offset = itemPtr->offset; - - if (offset >= 0) { - dataBuf = - _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + - szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + offset; - } else { - dataBuf = _vm->_game->_imFileData + (int32)READ_LE_UINT32(&((int32 *)_vm->_game->_imFileData)[-offset - 1]); - } - - width = itemPtr->width; - height = itemPtr->height; - - _vm->_video->fillRect(_vm->_draw->_cursorSprites, index * _vm->_draw->_cursorWidth, 0, - index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, - _vm->_draw->_cursorHeight - 1, 0); - - _vm->_video->drawPackedSprite((byte*)dataBuf, width, height, - index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); - _vm->_draw->_cursorAnimLow[index] = 0; - - return false; -} - -bool Inter_v1::o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_spriteLeft = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_transparency = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_destSurface = (_vm->_global->_inter_execPtr[0] / 2) - 1; - - if (_vm->_draw->_destSurface < 0) - _vm->_draw->_destSurface = 101; - _vm->_draw->_transparency &= 1; - _vm->_global->_inter_execPtr += 2; - - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); - - return false; -} - -bool Inter_v1::o1_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { - char buf[20]; - int8 size; - int16 i; - - if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { - _vm->_global->_inter_execPtr++; - evalExpr(0); - strcpy(buf, _vm->_global->_inter_resStr); - } else { - size = *_vm->_global->_inter_execPtr++; - for (i = 0; i < size; i++) - buf[i] = *_vm->_global->_inter_execPtr++; - - buf[size] = 0; - } - - strcat(buf, ".tot"); - _terminate = true; - strcpy(_vm->_game->_totToLoad, buf); - - return false; -} - -bool Inter_v1::o1_keyFunc(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 flag; - int16 key; - uint32 now; - static uint32 lastCalled = 0; - - flag = load16(); - animPalette(); - _vm->_draw->blitInvalidated(); - - now = _vm->_util->getTimeKey(); - if (!_noBusyWait) - if ((now - lastCalled) <= 20) - _vm->_util->longDelay(1); - lastCalled = now; - _noBusyWait = false; - - if (flag != 0) { - - if (flag != 1) { - if (flag != 2) { - _vm->_snd->speakerOnUpdate(flag); - if (flag < 20) { - _vm->_util->delay(flag); - _noBusyWait = true; - } - else - _vm->_util->longDelay(flag); - return false; - } - - key = 0; - - if (_vm->_global->_pressedKeys[0x48]) - key |= 1; - - if (_vm->_global->_pressedKeys[0x50]) - key |= 2; - - if (_vm->_global->_pressedKeys[0x4d]) - key |= 4; - - if (_vm->_global->_pressedKeys[0x4b]) - key |= 8; - - if (_vm->_global->_pressedKeys[0x1c]) - key |= 0x10; - - if (_vm->_global->_pressedKeys[0x39]) - key |= 0x20; - - if (_vm->_global->_pressedKeys[1]) - key |= 0x40; - - if (_vm->_global->_pressedKeys[0x1d]) - key |= 0x80; - - if (_vm->_global->_pressedKeys[0x2a]) - key |= 0x100; - - if (_vm->_global->_pressedKeys[0x36]) - key |= 0x200; - - if (_vm->_global->_pressedKeys[0x38]) - key |= 0x400; - - if (_vm->_global->_pressedKeys[0x3b]) - key |= 0x800; - - if (_vm->_global->_pressedKeys[0x3c]) - key |= 0x1000; - - if (_vm->_global->_pressedKeys[0x3d]) - key |= 0x2000; - - if (_vm->_global->_pressedKeys[0x3e]) - key |= 0x4000; - - WRITE_VAR(0, key); - _vm->_util->waitKey(); - return false; - } - key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); - - storeKey(key); - return false; - } else { - _vm->_draw->_showCursor &= ~2; - _vm->_util->longDelay(1); - key = _vm->_game->checkCollisions(0, 0, 0, 0); - storeKey(key); - - if (flag == 1) - return false; - - _vm->_util->waitKey(); - } - return false; -} - -bool Inter_v1::o1_repeatUntil(char &cmdCount, int16 &counter, int16 &retFlag) { - char *blockPtr; - int16 size; - char flag; - - _nestLevel[0]++; - blockPtr = _vm->_global->_inter_execPtr; - - do { - _vm->_global->_inter_execPtr = blockPtr; - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - funcBlock(1); - _vm->_global->_inter_execPtr = blockPtr + size + 1; - flag = evalBoolResult(); - } while (flag == 0 && !_breakFlag && !_terminate && !_vm->_quitRequested); - - _nestLevel[0]--; - - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } - return false; -} - -bool Inter_v1::o1_whileDo(char &cmdCount, int16 &counter, int16 &retFlag) { - char *blockPtr; - char *savedIP; - char flag; - int16 size; - - _nestLevel[0]++; - do { - savedIP = _vm->_global->_inter_execPtr; - flag = evalBoolResult(); - - if (_terminate) - return false; - - blockPtr = _vm->_global->_inter_execPtr; - - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - if (flag != 0) { - funcBlock(1); - _vm->_global->_inter_execPtr = savedIP; - } else { - _vm->_global->_inter_execPtr += size; - } - - if (_breakFlag || _terminate || _vm->_quitRequested) { - _vm->_global->_inter_execPtr = blockPtr; - _vm->_global->_inter_execPtr += size; - break; - } - } while (flag != 0); - - _nestLevel[0]--; - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } - return false; -} - -void Inter_v1::o1_setRenderFlags(void) { +void Inter_v1::o1_setRenderFlags() { _vm->_draw->_renderFlags = _vm->_parse->parseValExpr(); } -void Inter_v1::o1_loadAnim(void) { +void Inter_v1::o1_loadAnim() { _vm->_scenery->loadAnim(0); } -void Inter_v1::o1_freeAnim(void) { +void Inter_v1::o1_freeAnim() { _vm->_scenery->freeAnim(-1); } -void Inter_v1::o1_updateAnim(void) { +void Inter_v1::o1_updateAnim() { int16 deltaX; int16 deltaY; int16 flags; @@ -1646,43 +888,59 @@ void Inter_v1::o1_updateAnim(void) { evalExpr(&layer); evalExpr(&frame); flags = load16(); - _vm->_scenery->updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1); + _vm->_scenery->updateAnim(layer, frame, animation, flags, + deltaX, deltaY, 1); } -void Inter_v1::o1_initMult(void) { +void Inter_v1::o1_initMult() { int16 oldAnimHeight; int16 oldAnimWidth; int16 oldObjCount; - int16 i; int16 posXVar; int16 posYVar; int16 animDataVar; - oldAnimWidth = _vm->_anim->_areaWidth; - oldAnimHeight = _vm->_anim->_areaHeight; + oldAnimWidth = _vm->_mult->_animWidth; + oldAnimHeight = _vm->_mult->_animHeight; oldObjCount = _vm->_mult->_objCount; - _vm->_anim->_areaLeft = load16(); - _vm->_anim->_areaTop = load16(); - _vm->_anim->_areaWidth = load16(); - _vm->_anim->_areaHeight = load16(); + _vm->_mult->_animLeft = load16(); + _vm->_mult->_animTop = load16(); + _vm->_mult->_animWidth = load16(); + _vm->_mult->_animHeight = load16(); _vm->_mult->_objCount = load16(); posXVar = _vm->_parse->parseVarIndex(); posYVar = _vm->_parse->parseVarIndex(); animDataVar = _vm->_parse->parseVarIndex(); + if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { + warning("Initializing new objects without having " + "cleaned up the old ones at first"); + delete[] _vm->_mult->_objects; + delete[] _vm->_mult->_renderData; + _vm->_mult->_objects = 0; + _vm->_mult->_renderObjs = 0; + } + if (_vm->_mult->_objects == 0) { _vm->_mult->_renderData = new int16[_vm->_mult->_objCount * 9]; - memset(_vm->_mult->_renderData, 0, _vm->_mult->_objCount * 9 * sizeof(int16)); + memset(_vm->_mult->_renderData, 0, + _vm->_mult->_objCount * 9 * sizeof(int16)); _vm->_mult->_objects = new Mult::Mult_Object[_vm->_mult->_objCount]; - memset(_vm->_mult->_objects, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); + memset(_vm->_mult->_objects, 0, + _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); + + for (int i = 0; i < _vm->_mult->_objCount; i++) { + _vm->_mult->_objects[i].pPosX = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posXVar / 4) * 4); + _vm->_mult->_objects[i].pPosY = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posYVar / 4) * 4); - for (i = 0; i < _vm->_mult->_objCount; i++) { - _vm->_mult->_objects[i].pPosX = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posXVar / 4) * 4); - _vm->_mult->_objects[i].pPosY = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posYVar / 4) * 4); _vm->_mult->_objects[i].pAnimData = - (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + animDataVar + - i * 4 * _vm->_global->_inter_animDataSize); + (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + + animDataVar + i * 4 * _vm->_global->_inter_animDataSize); _vm->_mult->_objects[i].pAnimData->isStatic = 1; _vm->_mult->_objects[i].tick = 0; @@ -1691,77 +949,112 @@ void Inter_v1::o1_initMult(void) { _vm->_mult->_objects[i].lastTop = -1; _vm->_mult->_objects[i].lastBottom = -1; } - } else if (oldObjCount != _vm->_mult->_objCount) { - error("o1_initMult: Object count changed, but storage didn't (old count = %d, new count = %d)", - oldObjCount, _vm->_mult->_objCount); } - if (_vm->_anim->_animSurf != 0 && - (oldAnimWidth != _vm->_anim->_areaWidth - || oldAnimHeight != _vm->_anim->_areaHeight)) { - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; + if (_vm->_mult->_animSurf && + ((oldAnimWidth != _vm->_mult->_animWidth) || + (oldAnimHeight != _vm->_mult->_animHeight))) { + _vm->_draw->freeSprite(22); + _vm->_mult->_animSurf = 0; } - if (_vm->_anim->_animSurf == 0) { - _vm->_anim->_animSurf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, - _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0); - _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf; + if (!_vm->_mult->_animSurf) { + _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, + _vm->_mult->_animHeight, 0); + _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; } - _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, - _vm->_anim->_areaLeft, _vm->_anim->_areaTop, - _vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1, - _vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1, 0, 0, 0); + _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_mult->_animSurf, + _vm->_mult->_animLeft, _vm->_mult->_animTop, + _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1, + _vm->_mult->_animTop + _vm->_mult->_animHeight - 1, 0, 0, 0); debugC(4, kDebugGraphics, "o1_initMult: x = %d, y = %d, w = %d, h = %d", - _vm->_anim->_areaLeft, _vm->_anim->_areaTop, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight); - debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, animation data size = %d", _vm->_mult->_objCount, _vm->_global->_inter_animDataSize); + _vm->_mult->_animLeft, _vm->_mult->_animTop, + _vm->_mult->_animWidth, _vm->_mult->_animHeight); + debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, " + "animation data size = %d", _vm->_mult->_objCount, + _vm->_global->_inter_animDataSize); } -void Inter_v1::o1_multFreeMult(void) { +void Inter_v1::o1_freeMult() { _vm->_mult->freeMult(); } -void Inter_v1::o1_animate(void) { +void Inter_v1::o1_animate() { _vm->_mult->animate(); } -void Inter_v1::o1_multLoadMult(void) { - loadMult(); +void Inter_v1::o1_loadMultObject() { + int16 val; + int16 objIndex; + char *multData; + + evalExpr(&objIndex); + evalExpr(&val); + *_vm->_mult->_objects[objIndex].pPosX = val; + evalExpr(&val); + *_vm->_mult->_objects[objIndex].pPosY = val; + + debugC(4, kDebugGameFlow, "Loading mult object %d", objIndex); + + multData = (char *) _vm->_mult->_objects[objIndex].pAnimData; + for (int i = 0; i < 11; i++) { + if (READ_LE_UINT16(_vm->_global->_inter_execPtr) != 99) { + evalExpr(&val); + multData[i] = val; + } else + _vm->_global->_inter_execPtr++; + } } -void Inter_v1::o1_storeParams(void) { - _vm->_scenery->interStoreParams(); +void Inter_v1::o1_getAnimLayerInfo() { + int16 anim; + int16 layer; + int16 varDX, varDY; + int16 varUnk0; + int16 varFrames; + + evalExpr(&anim); + evalExpr(&layer); + + varDX = _vm->_parse->parseVarIndex(); + varDY = _vm->_parse->parseVarIndex(); + varUnk0 = _vm->_parse->parseVarIndex(); + varFrames = _vm->_parse->parseVarIndex(); + + _vm->_scenery->writeAnimLayerInfo(anim, layer, + varDX, varDY, varUnk0, varFrames); } -void Inter_v1::o1_getObjAnimSize(void) { - Mult::Mult_AnimData *pAnimData; +void Inter_v1::o1_getObjAnimSize() { int16 objIndex; evalExpr(&objIndex); - pAnimData = _vm->_mult->_objects[objIndex].pAnimData; - if (pAnimData->isStatic == 0) { - _vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, - pAnimData->animation, 0, *(_vm->_mult->_objects[objIndex].pPosX), + + Mult::Mult_AnimData &animData = *(_vm->_mult->_objects[objIndex].pAnimData); + if (animData.isStatic == 0) + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 0, *(_vm->_mult->_objects[objIndex].pPosX), *(_vm->_mult->_objects[objIndex].pPosY), 0); - } + + _vm->_scenery->_toRedrawLeft = MAX(_vm->_scenery->_toRedrawLeft, (int16) 0); + _vm->_scenery->_toRedrawTop = MAX(_vm->_scenery->_toRedrawTop, (int16) 0); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawLeft); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawTop); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawRight); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawBottom); } -void Inter_v1::o1_loadStatic(void) { +void Inter_v1::o1_loadStatic() { _vm->_scenery->loadStatic(0); } -void Inter_v1::o1_freeStatic(void) { +void Inter_v1::o1_freeStatic() { _vm->_scenery->freeStatic(-1); } -void Inter_v1::o1_renderStatic(void) { +void Inter_v1::o1_renderStatic() { int16 layer; int16 index; @@ -1770,12 +1063,12 @@ void Inter_v1::o1_renderStatic(void) { _vm->_scenery->renderStatic(index, layer); } -void Inter_v1::o1_loadCurLayer(void) { +void Inter_v1::o1_loadCurLayer() { evalExpr(&_vm->_scenery->_curStatic); evalExpr(&_vm->_scenery->_curStaticLayer); } -void Inter_v1::o1_playCDTrack(void) { +void Inter_v1::o1_playCDTrack() { evalExpr(0); if (_vm->_platform == Common::kPlatformMacintosh) { if (_vm->_adlib) @@ -1785,7 +1078,7 @@ void Inter_v1::o1_playCDTrack(void) { _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); } -void Inter_v1::o1_getCDTrackPos(void) { +void Inter_v1::o1_getCDTrackPos() { // Used in gob1 CD // Some scripts busy-wait while calling this opcode. @@ -1800,7 +1093,7 @@ void Inter_v1::o1_getCDTrackPos(void) { WRITE_VAR(5, pos); } -void Inter_v1::o1_stopCD(void) { +void Inter_v1::o1_stopCD() { if (_vm->_platform == Common::kPlatformMacintosh) { if (_vm->_adlib) _vm->_adlib->stopPlay(); @@ -1809,7 +1102,7 @@ void Inter_v1::o1_stopCD(void) { _vm->_cdrom->stopPlaying(); } -void Inter_v1::o1_loadFontToSprite(void) { +void Inter_v1::o1_loadFontToSprite() { int16 i = load16(); _vm->_draw->_fontToSprite[i].sprite = load16(); _vm->_draw->_fontToSprite[i].base = load16(); @@ -1817,7 +1110,7 @@ void Inter_v1::o1_loadFontToSprite(void) { _vm->_draw->_fontToSprite[i].height = load16(); } -void Inter_v1::o1_freeFontToSprite(void) { +void Inter_v1::o1_freeFontToSprite() { int16 i = load16(); _vm->_draw->_fontToSprite[i].sprite = -1; _vm->_draw->_fontToSprite[i].base = -1; @@ -1825,14 +1118,15 @@ void Inter_v1::o1_freeFontToSprite(void) { _vm->_draw->_fontToSprite[i].height = -1; } -bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { char *storedIP; uint32 offset; storedIP = _vm->_global->_inter_execPtr; offset = READ_LE_UINT16(_vm->_global->_inter_execPtr); - debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", _vm->_game->_curTotFile, offset); + debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", + _vm->_game->_curTotFile, offset); // Skipping the copy protection screen in Gobliiins if (!_vm->_copyProtection && (_vm->_features & GF_GOB1) && (offset == 3905) @@ -1849,9 +1143,9 @@ bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } - _vm->_global->_inter_execPtr = (char *)_vm->_game->_totFileData + offset; + _vm->_global->_inter_execPtr = (char *) _vm->_game->_totFileData + offset; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; callSub(2); @@ -1860,19 +1154,56 @@ bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } -bool Inter_v1::o1_drawPrintText(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->printText(); +bool Inter_v1::o1_printTotText(OpFuncParams ¶ms) { + _vm->_draw->printTotText(load16()); + return false; +} + +bool Inter_v1::o1_loadCursor(OpFuncParams ¶ms) { + Game::TotResItem *itemPtr; + int16 width, height; + char *dataBuf; + int32 offset; + int16 id; + int8 index; + + id = load16(); + index = *_vm->_global->_inter_execPtr++; + itemPtr = &_vm->_game->_totResourceTable->items[id]; + offset = itemPtr->offset; + + if (offset < 0) { + offset = (-offset - 1) * 4; + dataBuf = _vm->_game->_imFileData + + (int32) READ_LE_UINT32(_vm->_game->_imFileData + offset); + } else + dataBuf = _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + + szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + + offset; + + width = itemPtr->width; + height = itemPtr->height; + + _vm->_video->fillRect(_vm->_draw->_cursorSprites, + index * _vm->_draw->_cursorWidth, 0, + index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, + _vm->_draw->_cursorHeight - 1, 0); + + _vm->_video->drawPackedSprite((byte*) dataBuf, width, height, + index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); + _vm->_draw->_cursorAnimLow[index] = 0; + return false; } -bool Inter_v1::o1_call(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_switch(OpFuncParams ¶ms) { char *callAddr; checkSwitchTable(&callAddr); char *storedIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr = callAddr; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; funcBlock(0); @@ -1881,210 +1212,669 @@ bool Inter_v1::o1_call(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } -bool Inter_v1::o1_callBool(char &cmdCount, int16 &counter, int16 &retFlag) { - byte cmd; - bool boolRes = evalBoolResult() != 0; +bool Inter_v1::o1_repeatUntil(OpFuncParams ¶ms) { + char *blockPtr; + int16 size; + bool flag; + + _nestLevel[0]++; + blockPtr = _vm->_global->_inter_execPtr; + + do { + _vm->_global->_inter_execPtr = blockPtr; + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + funcBlock(1); + _vm->_global->_inter_execPtr = blockPtr + size + 1; + flag = evalBoolResult(); + } while (!flag && !_break && !_terminate && !_vm->_quitRequested); + + _nestLevel[0]--; + + if (*_breakFromLevel > -1) { + _break = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_v1::o1_whileDo(OpFuncParams ¶ms) { + char *blockPtr; + char *savedIP; + bool flag; + int16 size; + + _nestLevel[0]++; + do { + savedIP = _vm->_global->_inter_execPtr; + flag = evalBoolResult(); + + if (_terminate) + return false; + + blockPtr = _vm->_global->_inter_execPtr; + + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + if (flag) { + funcBlock(1); + _vm->_global->_inter_execPtr = savedIP; + } else + _vm->_global->_inter_execPtr += size; + + if (_break || _terminate || _vm->_quitRequested) { + _vm->_global->_inter_execPtr = blockPtr; + _vm->_global->_inter_execPtr += size; + break; + } + } while (flag); - if (boolRes != 0) { - if (counter == cmdCount - && retFlag == 2) + _nestLevel[0]--; + if (*_breakFromLevel > -1) { + _break = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_v1::o1_if(OpFuncParams ¶ms) { + byte cmd; + bool boolRes; + + boolRes = evalBoolResult(); + if (boolRes) { + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; char *storedIP = _vm->_global->_inter_execPtr; funcBlock(0); _vm->_global->_inter_execPtr = storedIP; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - debugC(5, kDebugGameFlow, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + debugC(5, kDebugGameFlow, "cmd = %d", + (int16) *_vm->_global->_inter_execPtr); + + cmd = (byte) (*_vm->_global->_inter_execPtr) >> 4; _vm->_global->_inter_execPtr++; if (cmd != 12) return false; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } else { - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + debugC(5, kDebugGameFlow, "cmd = %d", + (int16) *_vm->_global->_inter_execPtr); - debugC(5, kDebugGameFlow, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + cmd = (byte) (*_vm->_global->_inter_execPtr) >> 4; _vm->_global->_inter_execPtr++; if (cmd != 12) return false; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; char *storedIP = _vm->_global->_inter_execPtr; funcBlock(0); _vm->_global->_inter_execPtr = storedIP; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } return false; } -bool Inter_v1::o1_palLoad(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 i; - int16 ind1; - int16 ind2; - byte cmd; +bool Inter_v1::o1_evaluateStore(OpFuncParams ¶ms) { + char *savedPos; + int16 token; + int16 result; + int16 varOff; + + savedPos = _vm->_global->_inter_execPtr; + varOff = _vm->_parse->parseVarIndex(); + token = evalExpr(&result); + switch (savedPos[0]) { + case 23: + case 26: + WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); + break; + + case 25: + case 28: + if (token == 20) + WRITE_VARO_UINT8(varOff, result); + else + WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); + break; + + } + return false; +} + +bool Inter_v1::o1_loadSpriteToPos(OpFuncParams ¶ms) { + _vm->_draw->_spriteLeft = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_transparency = *_vm->_global->_inter_execPtr & 1; + _vm->_draw->_destSurface = (*_vm->_global->_inter_execPtr >> 1) - 1; + if (_vm->_draw->_destSurface < 0) + _vm->_draw->_destSurface = 101; + + _vm->_global->_inter_execPtr += 2; + + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + + return false; +} + +bool Inter_v1::o1_printText(OpFuncParams ¶ms) { + char buf[60]; + int i; + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_backColor = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); + _vm->_draw->_destSurface = 21; + _vm->_draw->_textToPrint = buf; + _vm->_draw->_transparency = 0; + + if (_vm->_draw->_backColor >= 16) { + _vm->_draw->_backColor = 0; + _vm->_draw->_transparency = 1; + } + + do { + for (i = 0; (*_vm->_global->_inter_execPtr != '.') && + ((byte) *_vm->_global->_inter_execPtr != 200); + i++, _vm->_global->_inter_execPtr++) { + buf[i] = *_vm->_global->_inter_execPtr; + } + + if ((byte) *_vm->_global->_inter_execPtr != 200) { + _vm->_global->_inter_execPtr++; + switch (*_vm->_global->_inter_execPtr) { + case 23: + case 26: + sprintf(buf + i, "%d", + VAR_OFFSET(_vm->_parse->parseVarIndex())); + break; + + case 25: + case 28: + sprintf(buf + i, "%s", + GET_VARO_STR(_vm->_parse->parseVarIndex())); + break; + } + _vm->_global->_inter_execPtr++; + } else + buf[i] = 0; + + _vm->_draw->spriteOperation(DRAW_PRINTTEXT); + } while ((byte) *_vm->_global->_inter_execPtr != 200); + + _vm->_global->_inter_execPtr++; + + return false; +} + +bool Inter_v1::o1_loadTot(OpFuncParams ¶ms) { + char buf[20]; + int8 size; + + if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { + _vm->_global->_inter_execPtr++; + evalExpr(0); + strcpy(buf, _vm->_global->_inter_resStr); + } else { + size = *_vm->_global->_inter_execPtr++; + for (int i = 0; i < size; i++) + buf[i] = *_vm->_global->_inter_execPtr++; + + buf[size] = 0; + } + + strcat(buf, ".tot"); + if (_terminate != 2) + _terminate = 1; + strcpy(_vm->_game->_totToLoad, buf); + + return false; +} + +bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { + int index1, index2; char *palPtr; + byte cmd; cmd = *_vm->_global->_inter_execPtr++; - _vm->_draw->_applyPal = 0; - if (cmd & 0x80) - cmd &= 0x7f; - else - _vm->_draw->_applyPal = 1; + switch (cmd & 0x7F) { + case 48: + if ((_vm->_global->_fakeVideoMode < 0x32) || + (_vm->_global->_fakeVideoMode > 0x63)) { + _vm->_global->_inter_execPtr += 48; + return false; + } + break; + + case 49: + if ((_vm->_global->_fakeVideoMode != 5) && + (_vm->_global->_fakeVideoMode != 7)) { + _vm->_global->_inter_execPtr += 18; + return false; + } + break; + + case 50: + if (_vm->_global->_colorCount == 256) { + _vm->_global->_inter_execPtr += 16; + return false; + } + break; + + case 51: + if (_vm->_global->_fakeVideoMode < 0x64) { + _vm->_global->_inter_execPtr += 2; + return false; + } + break; + + case 52: + if (_vm->_global->_colorCount == 256) { + _vm->_global->_inter_execPtr += 48; + return false; + } + break; + + case 53: + if (_vm->_global->_colorCount != 256) { + _vm->_global->_inter_execPtr += 2; + return false; + } + break; + + case 54: + if (_vm->_global->_fakeVideoMode < 0x13) { + return false; + } + break; + + case 61: + if (_vm->_global->_fakeVideoMode < 0x13) { + *_vm->_global->_inter_execPtr += 4; + return false; + } + break; + } + + if ((cmd & 0x7F) == 0x30) { + _vm->_global->_inter_execPtr += 48; + return false; + } + + _vm->_draw->_applyPal = !(cmd & 0x80); + cmd &= 0x7F; if (cmd == 49) { - warning("o1_palLoad: cmd == 49 is not supported"); - //var_B = 1; - for (i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { + bool allZero = true; + + for (int i = 2; i < 18; i++) { + if (_vm->_global->_inter_execPtr[i] != 0) { + allZero = false; + break; + } + } + if (!allZero) { + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + _vm->_draw->_noInvalidated57 = true; + _vm->_global->_inter_execPtr += 18; + return false; + } + _vm->_draw->_noInvalidated57 = false; + + for (int i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { if (i < 2) { - if (_vm->_draw->_applyPal == 0) + if (!_vm->_draw->_applyPal) continue; _vm->_draw->_unusedPalette1[i] = *_vm->_global->_inter_execPtr; continue; } - //if (*inter_execPtr != 0) - // var_B = 0; - ind1 = *_vm->_global->_inter_execPtr >> 4; - ind2 = (*_vm->_global->_inter_execPtr & 0xf); + index1 = *_vm->_global->_inter_execPtr >> 4; + index2 = (*_vm->_global->_inter_execPtr & 0xF); _vm->_draw->_unusedPalette1[i] = - ((_vm->_draw->_palLoadData1[ind1] + _vm->_draw->_palLoadData2[ind2]) << 8) + - (_vm->_draw->_palLoadData2[ind1] + _vm->_draw->_palLoadData1[ind2]); + ((_vm->_draw->_palLoadData1[index1] + + _vm->_draw->_palLoadData2[index2]) << 8) + + (_vm->_draw->_palLoadData2[index1] + + _vm->_draw->_palLoadData1[index2]); } _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + return false; } switch (cmd) { - case 52: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { - _vm->_draw->_vgaSmallPalette[i].red = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_vgaSmallPalette[i].green = _vm->_global->_inter_execPtr[1]; - _vm->_draw->_vgaSmallPalette[i].blue = _vm->_global->_inter_execPtr[2]; - } - break; - case 50: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) + for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) _vm->_draw->_unusedPalette2[i] = *_vm->_global->_inter_execPtr; break; + case 52: + for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { + _vm->_draw->_vgaPalette[i].red = _vm->_global->_inter_execPtr[0]; + _vm->_draw->_vgaPalette[i].green = _vm->_global->_inter_execPtr[1]; + _vm->_draw->_vgaPalette[i].blue = _vm->_global->_inter_execPtr[2]; + } + break; + case 53: palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); - memcpy((char *)_vm->_draw->_vgaPalette, palPtr, 768); + memcpy((char *) _vm->_draw->_vgaPalette, palPtr, 768); break; case 54: - memset((char *)_vm->_draw->_vgaPalette, 0, 768); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + break; + + case 61: + index1 = *_vm->_global->_inter_execPtr++; + index2 = (*_vm->_global->_inter_execPtr++ - index1 + 1) * 3; + palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); + memcpy((char *) _vm->_draw->_vgaPalette + index1 * 3, + palPtr + index1 * 3, index2); + + if (_vm->_draw->_applyPal) { + _vm->_draw->_applyPal = false; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + return false; + } break; } + if (!_vm->_draw->_applyPal) { _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; - if (_vm->_global->_videoMode != 0x13) - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaSmallPalette; - else - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaPalette; + if (_vm->_global->_videoMode < 0x13) { + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + return false; + } + if ((_vm->_global->_videoMode < 0x32) || + (_vm->_global->_videoMode >= 0x64)) { + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + return false; + } + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + } + + return false; +} + +bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { + static uint32 lastCalled = 0; + int16 cmd; + int16 key; + uint32 now; + + cmd = load16(); + animPalette(); + _vm->_draw->blitInvalidated(); + + now = _vm->_util->getTimeKey(); + if (!_noBusyWait) + if ((now - lastCalled) <= 20) + _vm->_util->longDelay(1); + lastCalled = now; + _noBusyWait = false; + + switch (cmd) { + case 0: + _vm->_draw->_showCursor &= ~2; + _vm->_util->longDelay(1); + key = _vm->_game->checkCollisions(0, 0, 0, 0); + storeKey(key); + + _vm->_util->clearKeyBuf(); + break; + + case 1: + key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); + storeKey(key); + break; + + case 2: + key = 0; + + if (_vm->_global->_pressedKeys[0x48]) + key |= 1; + + if (_vm->_global->_pressedKeys[0x50]) + key |= 2; - _vm->_palanim->fade((Video::PalDesc *) _vm->_global->_pPaletteDesc, 0, 0); + if (_vm->_global->_pressedKeys[0x4D]) + key |= 4; + + if (_vm->_global->_pressedKeys[0x4B]) + key |= 8; + + if (_vm->_global->_pressedKeys[0x1C]) + key |= 0x10; + + if (_vm->_global->_pressedKeys[0x39]) + key |= 0x20; + + if (_vm->_global->_pressedKeys[1]) + key |= 0x40; + + if (_vm->_global->_pressedKeys[0x1D]) + key |= 0x80; + + if (_vm->_global->_pressedKeys[0x2A]) + key |= 0x100; + + if (_vm->_global->_pressedKeys[0x36]) + key |= 0x200; + + if (_vm->_global->_pressedKeys[0x38]) + key |= 0x400; + + if (_vm->_global->_pressedKeys[0x3B]) + key |= 0x800; + + if (_vm->_global->_pressedKeys[0x3C]) + key |= 0x1000; + + if (_vm->_global->_pressedKeys[0x3D]) + key |= 0x2000; + + if (_vm->_global->_pressedKeys[0x3E]) + key |= 0x4000; + + WRITE_VAR(0, key); + _vm->_util->clearKeyBuf(); + break; + + default: + _vm->_snd->speakerOnUpdate(cmd); + if (cmd < 20) { + _vm->_util->delay(cmd); + _noBusyWait = true; + } else + _vm->_util->longDelay(cmd); + break; + } + + return false; +} + +bool Inter_v1::o1_capturePush(OpFuncParams ¶ms) { + int16 left, top; + int16 width, height; + + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + _vm->_game->capturePush(left, top, width, height); + (*_vm->_scenery->_pCaptureCounter)++; + return false; +} + +bool Inter_v1::o1_capturePop(OpFuncParams ¶ms) { + if (*_vm->_scenery->_pCaptureCounter != 0) { + (*_vm->_scenery->_pCaptureCounter)--; + _vm->_game->capturePop(1); } return false; } -bool Inter_v1::o1_setcmdCount(char &cmdCount, int16 &counter, int16 &retFlag) { - cmdCount = *_vm->_global->_inter_execPtr++; - counter = 0; +bool Inter_v1::o1_animPalInit(OpFuncParams ¶ms) { + _animPalDir[0] = load16(); + _animPalLowIndex[0] = _vm->_parse->parseValExpr(); + _animPalHighIndex[0] = _vm->_parse->parseValExpr(); return false; } -bool Inter_v1::o1_return(char &cmdCount, int16 &counter, int16 &retFlag) { - if (retFlag != 2) - _breakFlag = true; +bool Inter_v1::o1_drawOperations(OpFuncParams ¶ms) { + byte cmd; + + cmd = *_vm->_global->_inter_execPtr++; + + executeDrawOpcode(cmd); + + return false; +} + +bool Inter_v1::o1_setcmdCount(OpFuncParams ¶ms) { + params.cmdCount = *_vm->_global->_inter_execPtr++; + params.counter = 0; + return false; +} + +bool Inter_v1::o1_return(OpFuncParams ¶ms) { + if (params.retFlag != 2) + _break = true; _vm->_global->_inter_execPtr = 0; return false; } -bool Inter_v1::o1_renewTimeInVars(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_renewTimeInVars(OpFuncParams ¶ms) { renewTimeInVars(); return false; } -bool Inter_v1::o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_speakerOn(OpFuncParams ¶ms) { _vm->_snd->speakerOn(_vm->_parse->parseValExpr(), -1); return false; } -bool Inter_v1::o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_speakerOff(OpFuncParams ¶ms) { _vm->_snd->speakerOff(); return false; } -bool Inter_v1::o1_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 cmd; - int16 extraData = 0; - Goblin::Gob_Object *objDesc = NULL; - int32 *retVarPtr; +bool Inter_v1::o1_putPixel(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_PUTPIXEL); + return false; +} + +bool Inter_v1::o1_goblinFunc(OpFuncParams ¶ms) { + OpGobParams gobParams; bool objDescSet = false; + int16 cmd; - retVarPtr = (int32 *)VAR_ADDRESS(59); + gobParams.extraData = 0; + gobParams.objDesc = 0; + gobParams.retVarPtr = (int32 *) VAR_ADDRESS(59); cmd = load16(); _vm->_global->_inter_execPtr += 2; - if (cmd > 0 && cmd < 17) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; + if ((cmd > 0) && (cmd < 17)) { objDescSet = true; - extraData = load16(); + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; + gobParams.extraData = load16(); } - if (cmd > 90 && cmd < 107) { - extraData = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; + if ((cmd > 90) && (cmd < 107)) { objDescSet = true; - extraData = load16(); + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; + gobParams.extraData = load16(); cmd -= 90; } - if (cmd > 110 && cmd < 128) { - extraData = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; + if ((cmd > 110) && (cmd < 128)) { objDescSet = true; + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; cmd -= 90; - } else if (cmd > 20 && cmd < 38) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; + } else if ((cmd > 20) && (cmd < 38)) { objDescSet = true; + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; } /* - NB: The original gobliiins engine did not initialize the objDesc - variable, so we manually check if objDesc is properly set before + NB: The original gobliiins engine did not initialize the gobParams.objDesc + variable, so we manually check if gobParams.objDesc is properly set before checking if it is zero. If it was not set, we do not return. This fixes a crash in the EGA version if the life bar is depleted, because interFunc is called multiple times with cmd == 39. Bug #1324814 */ - if (cmd < 40 && objDescSet && objDesc == 0) + if ((cmd < 40) && objDescSet && !gobParams.objDesc) return false; - executeGoblinOpcode(cmd, extraData, retVarPtr, objDesc); + executeGoblinOpcode(cmd, gobParams); + + return false; +} + +bool Inter_v1::o1_createSprite(OpFuncParams ¶ms) { + int16 index; + int16 width, height; + int16 flag; + + index = load16(); + width = load16(); + height = load16(); + + flag = load16(); + _vm->_draw->initSpriteSurf(index, width, height, flag ? 2 : 0); return false; } -bool Inter_v1::o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag) { - if (retFlag == 1) { - _breakFlag = true; +bool Inter_v1::o1_freeSprite(OpFuncParams ¶ms) { + _vm->_draw->freeSprite(load16()); + return false; +} + +bool Inter_v1::o1_returnTo(OpFuncParams ¶ms) { + if (params.retFlag == 1) { + _break = true; _vm->_global->_inter_execPtr = 0; return true; } @@ -2093,33 +1883,282 @@ bool Inter_v1::o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag) { return false; *_breakFromLevel = *_nestLevel; - _breakFlag = true; + _break = true; _vm->_global->_inter_execPtr = 0; return true; } -bool Inter_v1::o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_loadSpriteContent(OpFuncParams ¶ms) { + _vm->_draw->_spriteLeft = load16(); + _vm->_draw->_destSurface = load16(); + _vm->_draw->_transparency = load16(); + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + return false; +} + +bool Inter_v1::o1_copySprite(OpFuncParams ¶ms) { + _vm->_draw->_sourceSurface = load16(); + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_spriteLeft = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_transparency = load16(); + _vm->_draw->spriteOperation(DRAW_BLITSURF); + return false; +} + +bool Inter_v1::o1_fillRect(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_backColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_FILLRECT); + return false; +} + +bool Inter_v1::o1_drawLine(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_DRAWLINE); + return false; +} + +bool Inter_v1::o1_strToLong(OpFuncParams ¶ms) { + char str[20]; + int16 strVar; + int16 destVar; + int32 res; + + strVar = _vm->_parse->parseVarIndex(); + strcpy(str, GET_VARO_STR(strVar)); + res = atol(str); + + destVar = _vm->_parse->parseVarIndex(); + WRITE_VAR_OFFSET(destVar, res); + return false; +} + +bool Inter_v1::o1_invalidate(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_INVALIDATE); + return false; +} + +bool Inter_v1::o1_setBackDelta(OpFuncParams ¶ms) { _vm->_draw->_backDeltaX = _vm->_parse->parseValExpr(); _vm->_draw->_backDeltaY = _vm->_parse->parseValExpr(); return false; } -bool Inter_v1::o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { + int16 frequency; + int16 freq2; + int16 repCount; + int16 index; + int16 endRep; + + index = _vm->_parse->parseValExpr(); + repCount = _vm->_parse->parseValExpr(); + frequency = _vm->_parse->parseValExpr(); + + SoundDesc &sample = _vm->_game->_soundSamples[index]; + + _soundEndTimeKey = 0; + if (sample.empty()) + return false; + + if (repCount < 0) { + if (_vm->_global->_soundFlags < 2) + return false; + + repCount = -repCount; + _soundEndTimeKey = _vm->_util->getTimeKey(); + + freq2 = frequency ? frequency : sample._frequency; + endRep = MAX(repCount - 1, 1); + + _soundStopVal = sample.calcFadeOutLength(freq2); + _soundEndTimeKey += sample.calcLength(endRep, freq2, true); + } + + if (sample.getType() == SOUND_ADL) { + if (_vm->_adlib) { + _vm->_adlib->load(sample.getData(), sample.size(), index); + _vm->_adlib->setRepeating(repCount - 1); + _vm->_adlib->startPlay(); + } + } else { + _vm->_snd->stopSound(0); + _vm->_snd->playSample(sample, repCount - 1, frequency); + } + + return false; +} + +bool Inter_v1::o1_stopSound(OpFuncParams ¶ms) { + if (_vm->_adlib) + _vm->_adlib->stopPlay(); + _vm->_snd->stopSound(_vm->_parse->parseValExpr()); + + _soundEndTimeKey = 0; + return false; +} + +bool Inter_v1::o1_loadSound(OpFuncParams ¶ms) { loadSound(-1); return false; } -bool Inter_v1::o1_freeSoundSlot(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_freeSoundSlot(OpFuncParams ¶ms) { _vm->_game->freeSoundSlot(-1); return false; } -bool Inter_v1::o1_waitEndPlay(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_waitEndPlay(OpFuncParams ¶ms) { _vm->_snd->waitEndPlay(); return false; } -bool Inter_v1::o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_playComposition(OpFuncParams ¶ms) { + int16 composition[50]; + int16 dataVar; + int16 freqVal; + + dataVar = _vm->_parse->parseVarIndex(); + freqVal = _vm->_parse->parseValExpr(); + for (int i = 0; i < 50; i++) + composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); + + _vm->_snd->playComposition(composition, freqVal); + return false; +} + +bool Inter_v1::o1_getFreeMem(OpFuncParams ¶ms) { + int16 freeVar; + int16 maxFreeVar; + + freeVar = _vm->_parse->parseVarIndex(); + maxFreeVar = _vm->_parse->parseVarIndex(); + + // HACK + WRITE_VAR_OFFSET(freeVar, 1000000); + WRITE_VAR_OFFSET(maxFreeVar, 1000000); + return false; +} + +bool Inter_v1::o1_checkData(OpFuncParams ¶ms) { + int16 handle; + int16 varOff; + + evalExpr(0); + varOff = _vm->_parse->parseVarIndex(); + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + + WRITE_VAR_OFFSET(varOff, handle); + if (handle >= 0) + _vm->_dataIO->closeData(handle); + else + warning("File \"%s\" not found", _vm->_global->_inter_resStr); + return false; +} + +bool Inter_v1::o1_prepareStr(OpFuncParams ¶ms) { + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + _vm->_util->prepareStr(GET_VARO_STR(strVar)); + _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); + return false; +} + +bool Inter_v1::o1_insertStr(OpFuncParams ¶ms) { + int16 pos; + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + pos = _vm->_parse->parseValExpr(); + _vm->_util->insertStr(_vm->_global->_inter_resStr, GET_VARO_STR(strVar), pos); + _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); + return false; +} + +bool Inter_v1::o1_cutStr(OpFuncParams ¶ms) { + int16 strVar; + int16 pos; + int16 size; + + strVar = _vm->_parse->parseVarIndex(); + pos = _vm->_parse->parseValExpr(); + size = _vm->_parse->parseValExpr(); + _vm->_util->cutFromStr(GET_VARO_STR(strVar), pos, size); + return false; +} + +bool Inter_v1::o1_strstr(OpFuncParams ¶ms) { + int16 strVar; + int16 resVar; + int16 pos; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + resVar = _vm->_parse->parseVarIndex(); + + char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr); + pos = res ? (res - (GET_VARO_STR(strVar))) : -1; + WRITE_VAR_OFFSET(resVar, pos); + return false; +} + +bool Inter_v1::o1_istrlen(OpFuncParams ¶ms) { + int16 len; + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + len = strlen(GET_VARO_STR(strVar)); + strVar = _vm->_parse->parseVarIndex(); + + WRITE_VAR_OFFSET(strVar, len); + return false; +} + +bool Inter_v1::o1_setMousePos(OpFuncParams ¶ms) { + _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); + _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); + if (_vm->_global->_useMouse != 0) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, + _vm->_global->_inter_mouseY); + return false; +} + +bool Inter_v1::o1_setFrameRate(OpFuncParams ¶ms) { + _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); + return false; +} + +bool Inter_v1::o1_animatePalette(OpFuncParams ¶ms) { _vm->_draw->blitInvalidated(); _vm->_util->waitEndFrame(); animPalette(); @@ -2128,174 +2167,279 @@ bool Inter_v1::o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag) return false; } -bool Inter_v1::o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_animateCursor(OpFuncParams ¶ms) { _vm->_draw->animateCursor(1); return false; } -bool Inter_v1::o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_blitCursor(OpFuncParams ¶ms) { _vm->_draw->blitCursor(); return false; } -void Inter_v1::o1_setState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->state = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemStateVarPtr = extraData; +bool Inter_v1::o1_loadFont(OpFuncParams ¶ms) { + int16 index; + + evalExpr(0); + index = load16(); + + if (_vm->_draw->_fonts[index]) + _vm->_util->freeFont(_vm->_draw->_fonts[index]); + + _vm->_draw->animateCursor(4); + if (_vm->_game->_extHandle >= 0) + _vm->_dataIO->closeData(_vm->_game->_extHandle); + + _vm->_draw->_fonts[index] = + _vm->_util->loadFont(_vm->_global->_inter_resStr); + + if (_vm->_game->_extHandle >= 0) + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); + return false; +} + +bool Inter_v1::o1_freeFont(OpFuncParams ¶ms) { + int16 index; + + index = load16(); + if (_vm->_draw->_fonts[index]) + _vm->_util->freeFont(_vm->_draw->_fonts[index]); + + _vm->_draw->_fonts[index] = 0; + return false; +} + +bool Inter_v1::o1_readData(OpFuncParams ¶ms) { + int16 retSize; + int16 size; + int16 dataVar; + int16 offset; + int16 handle; + char buf[4]; + + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + if (_vm->_game->_extHandle >= 0) + _vm->_dataIO->closeData(_vm->_game->_extHandle); + + WRITE_VAR(1, 1); + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + if (handle >= 0) { + _vm->_draw->animateCursor(4); + if (offset < 0) + _vm->_dataIO->seekData(handle, -offset - 1, 2); + else + _vm->_dataIO->seekData(handle, offset, 0); + + if (((dataVar >> 2) == 59) && (size == 4)) { + retSize = _vm->_dataIO->readData(handle, buf, 4); + WRITE_VAR(59, READ_LE_UINT32(buf)); + } else + retSize = _vm->_dataIO->readData(handle, + _vm->_global->_inter_variables + dataVar, size); + + _vm->_dataIO->closeData(handle); + + if (retSize == size) + WRITE_VAR(1, 0); + } + + if (_vm->_game->_extHandle >= 0) + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); + return false; +} + +bool Inter_v1::o1_writeData(OpFuncParams ¶ms) { + int16 offset; + int16 size; + int16 dataVar; + + // This writes into a file. It's not portable and isn't needed anyway + // (Gobliiins 1 doesn't use save file), so we just warn should it be + // called regardless. + + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); + WRITE_VAR(1, 0); + + return false; } -void Inter_v1::o1_setCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->curFrame = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemFrameVarPtr = extraData; +bool Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { + evalExpr(0); + + if (_vm->_global->_inter_resStr[0] != 0) + _vm->_dataIO->openDataFile(_vm->_global->_inter_resStr); + else + _vm->_dataIO->closeDataFile(); + return false; } -void Inter_v1::o1_setNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->nextState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemNextStateVarPtr = extraData; +void Inter_v1::o1_setState(OpGobParams ¶ms) { + params.objDesc->state = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemStateVarPtr = params.extraData; } -void Inter_v1::o1_setMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->multState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemMultStateVarPtr = extraData; +void Inter_v1::o1_setCurFrame(OpGobParams ¶ms) { + params.objDesc->curFrame = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemFrameVarPtr = params.extraData; } -void Inter_v1::o1_setOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->order = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemOrderVarPtr = extraData; +void Inter_v1::o1_setNextState(OpGobParams ¶ms) { + params.objDesc->nextState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemNextStateVarPtr = params.extraData; } -void Inter_v1::o1_setActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->actionStartState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemActStartStVarPtr = extraData; +void Inter_v1::o1_setMultState(OpGobParams ¶ms) { + params.objDesc->multState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemMultStateVarPtr = params.extraData; } -void Inter_v1::o1_setCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->curLookDir = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemLookDirVarPtr = extraData; +void Inter_v1::o1_setOrder(OpGobParams ¶ms) { + params.objDesc->order = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemOrderVarPtr = params.extraData; } -void Inter_v1::o1_setType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->type = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemTypeVarPtr = extraData; +void Inter_v1::o1_setActionStartState(OpGobParams ¶ms) { + params.objDesc->actionStartState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemActStartStVarPtr = params.extraData; +} - if (extraData == 0) - objDesc->toRedraw = 1; +void Inter_v1::o1_setCurLookDir(OpGobParams ¶ms) { + params.objDesc->curLookDir = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemLookDirVarPtr = params.extraData; } -void Inter_v1::o1_setNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->noTick = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemNoTickVarPtr = extraData; +void Inter_v1::o1_setType(OpGobParams ¶ms) { + params.objDesc->type = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemTypeVarPtr = params.extraData; + + if (params.extraData == 0) + params.objDesc->toRedraw = 1; } -void Inter_v1::o1_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->pickable = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemPickableVarPtr = extraData; +void Inter_v1::o1_setNoTick(OpGobParams ¶ms) { + params.objDesc->noTick = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemNoTickVarPtr = params.extraData; } -void Inter_v1::o1_setXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->xPos = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemScrXVarPtr = extraData; +void Inter_v1::o1_setPickable(OpGobParams ¶ms) { + params.objDesc->pickable = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemPickableVarPtr = params.extraData; } -void Inter_v1::o1_setYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->yPos = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemScrYVarPtr = extraData; +void Inter_v1::o1_setXPos(OpGobParams ¶ms) { + params.objDesc->xPos = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemScrXVarPtr = params.extraData; } -void Inter_v1::o1_setDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->doAnim = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemDoAnimVarPtr = extraData; +void Inter_v1::o1_setYPos(OpGobParams ¶ms) { + params.objDesc->yPos = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemScrYVarPtr = params.extraData; } -void Inter_v1::o1_setRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->relaxTime = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemRelaxVarPtr = extraData; +void Inter_v1::o1_setDoAnim(OpGobParams ¶ms) { + params.objDesc->doAnim = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemDoAnimVarPtr = params.extraData; } -void Inter_v1::o1_setMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->maxTick = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemMaxTickVarPtr = extraData; +void Inter_v1::o1_setRelaxTime(OpGobParams ¶ms) { + params.objDesc->relaxTime = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemRelaxVarPtr = params.extraData; } -void Inter_v1::o1_getState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->state; +void Inter_v1::o1_setMaxTick(OpGobParams ¶ms) { + params.objDesc->maxTick = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemMaxTickVarPtr = params.extraData; } -void Inter_v1::o1_getCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->curFrame; +void Inter_v1::o1_getState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->state; } -void Inter_v1::o1_getNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->nextState; +void Inter_v1::o1_getCurFrame(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->curFrame; } -void Inter_v1::o1_getMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->multState; +void Inter_v1::o1_getNextState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->nextState; } -void Inter_v1::o1_getOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->order; +void Inter_v1::o1_getMultState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->multState; } -void Inter_v1::o1_getActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->actionStartState; +void Inter_v1::o1_getOrder(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->order; } -void Inter_v1::o1_getCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->curLookDir; +void Inter_v1::o1_getActionStartState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->actionStartState; } -void Inter_v1::o1_getType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->type; +void Inter_v1::o1_getCurLookDir(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->curLookDir; } -void Inter_v1::o1_getNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->noTick; +void Inter_v1::o1_getType(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->type; } -void Inter_v1::o1_getPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->pickable; +void Inter_v1::o1_getNoTick(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->noTick; } -void Inter_v1::o1_getObjMaxFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->getObjMaxFrame(objDesc); +void Inter_v1::o1_getPickable(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->pickable; } -void Inter_v1::o1_getXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->xPos; +void Inter_v1::o1_getObjMaxFrame(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->getObjMaxFrame(params.objDesc); } -void Inter_v1::o1_getYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->yPos; +void Inter_v1::o1_getXPos(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->xPos; } -void Inter_v1::o1_getDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->doAnim; +void Inter_v1::o1_getYPos(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->yPos; } -void Inter_v1::o1_getRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->relaxTime; +void Inter_v1::o1_getDoAnim(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->doAnim; } -void Inter_v1::o1_getMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->maxTick; +void Inter_v1::o1_getRelaxTime(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->relaxTime; } -void Inter_v1::o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getMaxTick(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->maxTick; +} + +void Inter_v1::o1_manipulateMap(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 item = load16(); @@ -2303,17 +2447,17 @@ void Inter_v1::o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ manipulateMap(xPos, yPos, item); } -void Inter_v1::o1_getItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getItem(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) - *retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) >> 8; + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) + *params.retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) >> 8; else - *retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; + *params.retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; } -void Inter_v1::o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_manipulateMapIndirect(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 item = load16(); @@ -2325,27 +2469,27 @@ void Inter_v1::o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Gobl manipulateMap(xPos, yPos, item); } -void Inter_v1::o1_getItemIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getItemIndirect(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); xPos = VAR(xPos); yPos = VAR(yPos); - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) - *retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) >> 8; + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) + *params.retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) >> 8; else - *retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; + *params.retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; } -void Inter_v1::o1_setPassMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setPassMap(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 val = load16(); _vm->_map->setPass(xPos, yPos, val); } -void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinPosH(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); @@ -2354,28 +2498,27 @@ void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ _vm->_goblin->_gobPositions[item].x = xPos * 2; _vm->_goblin->_gobPositions[item].y = yPos * 2; - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = 21; + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = 21; - _vm->_goblin->nextLayer(objDesc); + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (_vm->_goblin->_gobPositions[item].y * 6 + 6) - (_vm->_scenery->_toRedrawBottom - - _vm->_scenery->_animTop); - objDesc->xPos = - _vm->_goblin->_gobPositions[item].x * 12 - (_vm->_scenery->_toRedrawLeft - - _vm->_scenery->_animLeft); + params.objDesc->yPos = (_vm->_goblin->_gobPositions[item].y * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = + _vm->_goblin->_gobPositions[item].x * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - objDesc->curFrame = 0; - objDesc->state = 21; + params.objDesc->curFrame = 0; + params.objDesc->state = 21; if (_vm->_goblin->_currentGoblin == item) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 18; @@ -2384,60 +2527,60 @@ void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ } } -void Inter_v1::o1_getGoblinPosXH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosXH(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].x >> 1; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].x >> 1; } -void Inter_v1::o1_getGoblinPosYH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosYH(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].y >> 1; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].y >> 1; } -void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinMultState(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); int16 yPos = load16(); - objDesc = _vm->_goblin->_goblins[item]; + params.objDesc = _vm->_goblin->_goblins[item]; if (yPos == 0) { - objDesc->multState = xPos; - objDesc->nextState = xPos; - _vm->_goblin->nextLayer(objDesc); + params.objDesc->multState = xPos; + params.objDesc->nextState = xPos; + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; - *_vm->_goblin->_curGobStateVarPtr = objDesc->state; - *_vm->_goblin->_curGobNextStateVarPtr = objDesc->nextState; - *_vm->_goblin->_curGobMultStateVarPtr = objDesc->multState; + *_vm->_goblin->_curGobStateVarPtr = params.objDesc->state; + *_vm->_goblin->_curGobNextStateVarPtr = params.objDesc->nextState; + *_vm->_goblin->_curGobMultStateVarPtr = params.objDesc->multState; *_vm->_goblin->_curGobMaxFrameVarPtr = - _vm->_goblin->getObjMaxFrame(objDesc); + _vm->_goblin->getObjMaxFrame(params.objDesc); _vm->_goblin->_noPick = 1; return; } - objDesc->multState = 21; - objDesc->nextState = 21; - objDesc->state = 21; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + params.objDesc->multState = 21; + params.objDesc->nextState = 21; + params.objDesc->state = 21; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); - objDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + params.objDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); _vm->_goblin->_gobPositions[item].x = xPos; _vm->_goblin->_pressedMapX = xPos; @@ -2447,8 +2590,8 @@ void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin: _vm->_goblin->_pressedMapY = yPos; _vm->_map->_curGoblinY = yPos; - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 21; *_vm->_goblin->_curGobNextStateVarPtr = 21; @@ -2456,7 +2599,30 @@ void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin: _vm->_goblin->_noPick = 0; } -void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinUnk14(OpGobParams ¶ms) { + int16 item = load16(); + int16 val = load16(); + params.objDesc = _vm->_goblin->_objects[item]; + params.objDesc->unk14 = val; +} + +void Inter_v1::o1_setItemIdInPocket(OpGobParams ¶ms) { + _vm->_goblin->_itemIdInPocket = load16(); +} + +void Inter_v1::o1_setItemIndInPocket(OpGobParams ¶ms) { + _vm->_goblin->_itemIndInPocket = load16(); +} + +void Inter_v1::o1_getItemIdInPocket(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->_itemIdInPocket; +} + +void Inter_v1::o1_getItemIndInPocket(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->_itemIndInPocket; +} + +void Inter_v1::o1_setGoblinPos(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); @@ -2465,26 +2631,26 @@ void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_O _vm->_goblin->_gobPositions[item].x = xPos; _vm->_goblin->_gobPositions[item].y = yPos; - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = 21; - _vm->_goblin->nextLayer(objDesc); + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = 21; + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); - objDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + params.objDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - objDesc->curFrame = 0; - objDesc->state = 21; + params.objDesc->curFrame = 0; + params.objDesc->state = 21; if (_vm->_goblin->_currentGoblin == item) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 18; @@ -2493,170 +2659,151 @@ void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_O } } -void Inter_v1::o1_setGoblinState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinState(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 state = load16(); - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = state; + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = state; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; if (item == _vm->_goblin->_currentGoblin) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; - *_vm->_goblin->_curGobStateVarPtr = objDesc->state; - *_vm->_goblin->_curGobMultStateVarPtr = objDesc->multState; + *_vm->_goblin->_curGobStateVarPtr = params.objDesc->state; + *_vm->_goblin->_curGobMultStateVarPtr = params.objDesc->multState; } } -void Inter_v1::o1_setGoblinStateRedraw(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinStateRedraw(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 state = load16(); - objDesc = _vm->_goblin->_objects[item]; + params.objDesc = _vm->_goblin->_objects[item]; + + params.objDesc->nextState = state; - objDesc->nextState = state; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; - objDesc->toRedraw = 1; - objDesc->type = 0; - if (objDesc == _vm->_goblin->_actDestItemDesc) { - *_vm->_goblin->_destItemScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_destItemScrYVarPtr = objDesc->yPos; + params.objDesc->toRedraw = 1; + params.objDesc->type = 0; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) { + *_vm->_goblin->_destItemScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_destItemScrYVarPtr = params.objDesc->yPos; - *_vm->_goblin->_destItemStateVarPtr = objDesc->state; + *_vm->_goblin->_destItemStateVarPtr = params.objDesc->state; *_vm->_goblin->_destItemNextStateVarPtr = -1; *_vm->_goblin->_destItemMultStateVarPtr = -1; *_vm->_goblin->_destItemFrameVarPtr = 0; } } -void Inter_v1::o1_setGoblinUnk14(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - int16 item = load16(); - int16 val = load16(); - objDesc = _vm->_goblin->_objects[item]; - objDesc->unk14 = val; -} - -void Inter_v1::o1_setItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->_itemIdInPocket = load16(); -} - -void Inter_v1::o1_setItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->_itemIndInPocket = load16(); -} - -void Inter_v1::o1_getItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->_itemIdInPocket; -} - -void Inter_v1::o1_getItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->_itemIndInPocket; -} +void Inter_v1::o1_decRelaxTime(OpGobParams ¶ms) { + params.extraData = load16(); + params.objDesc = _vm->_goblin->_objects[params.extraData]; -void Inter_v1::o1_setItemPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); - int16 val = load16(); - - _vm->_map->_itemPoses[item].x = xPos; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = val; -} - -void Inter_v1::o1_decRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; - - objDesc->relaxTime--; - if (objDesc->relaxTime < 0 && - _vm->_goblin->getObjMaxFrame(objDesc) == objDesc->curFrame) { - objDesc->relaxTime = _vm->_util->getRandom(100) + 50; - objDesc->curFrame = 0; - objDesc->toRedraw = 1; + params.objDesc->relaxTime--; + if ((params.objDesc->relaxTime < 0) && + (_vm->_goblin->getObjMaxFrame(params.objDesc) == + params.objDesc->curFrame)) { + params.objDesc->relaxTime = _vm->_util->getRandom(100) + 50; + params.objDesc->curFrame = 0; + params.objDesc->toRedraw = 1; } } -void Inter_v1::o1_getGoblinPosX(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosX(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].x; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].x; } -void Inter_v1::o1_getGoblinPosY(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosY(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].y; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].y; } -void Inter_v1::o1_clearPathExistence(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_clearPathExistence(OpGobParams ¶ms) { _vm->_goblin->_pathExistence = 0; } -void Inter_v1::o1_setGoblinVisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - _vm->_goblin->_goblins[extraData]->visible = 1; +void Inter_v1::o1_setGoblinVisible(OpGobParams ¶ms) { + params.extraData = load16(); + _vm->_goblin->_goblins[params.extraData]->visible = 1; } -void Inter_v1::o1_setGoblinInvisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - _vm->_goblin->_goblins[extraData]->visible = 0; +void Inter_v1::o1_setGoblinInvisible(OpGobParams ¶ms) { + params.extraData = load16(); + _vm->_goblin->_goblins[params.extraData]->visible = 0; } -void Inter_v1::o1_getObjectIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_getObjectIntersect(OpGobParams ¶ms) { + params.extraData = load16(); int16 item = load16(); - objDesc = _vm->_goblin->_objects[extraData]; - if (_vm->_goblin->objIntersected(objDesc, _vm->_goblin->_goblins[item]) != 0) - *retVarPtr = 1; + params.objDesc = _vm->_goblin->_objects[params.extraData]; + if (_vm->_goblin->objIntersected(params.objDesc, + _vm->_goblin->_goblins[item])) + *params.retVarPtr = 1; else - *retVarPtr = 0; + *params.retVarPtr = 0; } -void Inter_v1::o1_getGoblinIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_getGoblinIntersect(OpGobParams ¶ms) { + params.extraData = load16(); int16 item = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; - if (_vm->_goblin->objIntersected(objDesc, _vm->_goblin->_goblins[item]) != 0) - *retVarPtr = 1; + params.objDesc = _vm->_goblin->_goblins[params.extraData]; + if (_vm->_goblin->objIntersected(params.objDesc, + _vm->_goblin->_goblins[item])) + *params.retVarPtr = 1; else - *retVarPtr = 0; + *params.retVarPtr = 0; +} + +void Inter_v1::o1_setItemPos(OpGobParams ¶ms) { + int16 item = load16(); + int16 xPos = load16(); + int16 yPos = load16(); + int16 val = load16(); + + _vm->_map->_itemPoses[item].x = xPos; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = val; } -void Inter_v1::o1_loadObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_loadObjects(OpGobParams ¶ms) { + params.extraData = load16(); if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); + _vm->_dataIO->closeData(_vm->_game->_extHandle); - _vm->_goblin->loadObjects((char *)VAR_ADDRESS(extraData)); - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); + _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData)); + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); } -void Inter_v1::o1_freeObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_freeObjects(OpGobParams ¶ms) { _vm->_goblin->freeAllObjects(); } -void Inter_v1::o1_animateObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_animateObjects(OpGobParams ¶ms) { _vm->_goblin->animateObjects(); } -void Inter_v1::o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_drawObjects(OpGobParams ¶ms) { _vm->_goblin->drawObjects(); if (_vm->_platform == Common::kPlatformMacintosh) { @@ -2666,72 +2813,74 @@ void Inter_v1::o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Ob _vm->_cdrom->playBgMusic(); } -void Inter_v1::o1_loadMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_loadMap(OpGobParams ¶ms) { _vm->_map->loadMapsInitGobs(); } -void Inter_v1::o1_moveGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_moveGoblin(OpGobParams ¶ms) { int16 item; - extraData = load16(); + params.extraData = load16(); int16 xPos = load16(); - if ((uint16)VAR(xPos) == 0) { + if ((uint16) VAR(xPos) == 0) { item = - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 1, - (uint16)VAR(extraData)); + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 1, (uint16) VAR(params.extraData)); } else { item = - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 1, 3); + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 1, 3); } if (item != 0) _vm->_goblin->switchGoblin(item); } -void Inter_v1::o1_switchGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_switchGoblin(OpGobParams ¶ms) { _vm->_goblin->switchGoblin(0); } -void Inter_v1::o1_loadGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_loadGoblin(OpGobParams ¶ms) { _vm->_goblin->loadGobDataFromVars(); } -void Inter_v1::o1_writeTreatItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_writeTreatItem(OpGobParams ¶ms) { + params.extraData = load16(); int16 cmd = load16(); int16 xPos = load16(); - if ((uint16)VAR(xPos) == 0) { - WRITE_VAR(cmd, _vm->_goblin->treatItem((uint16)VAR(extraData))); + if ((uint16) VAR(xPos) == 0) { + WRITE_VAR(cmd, _vm->_goblin->treatItem((uint16) VAR(params.extraData))); return; } WRITE_VAR(cmd, _vm->_goblin->treatItem(3)); } -void Inter_v1::o1_moveGoblin0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 0, 0); +void Inter_v1::o1_moveGoblin0(OpGobParams ¶ms) { + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 0, 0); } -void Inter_v1::o1_setGoblinTarget(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - if (VAR(extraData) != 0) +void Inter_v1::o1_setGoblinTarget(OpGobParams ¶ms) { + params.extraData = load16(); + if (VAR(params.extraData) != 0) _vm->_goblin->_goesAtTarget = 1; else _vm->_goblin->_goesAtTarget = 0; } -void Inter_v1::o1_setGoblinObjectsPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - extraData = VAR(extraData); - _vm->_goblin->_objects[10]->xPos = extraData; +void Inter_v1::o1_setGoblinObjectsPos(OpGobParams ¶ms) { + params.extraData = load16(); + params.extraData = VAR(params.extraData); + _vm->_goblin->_objects[10]->xPos = params.extraData; - extraData = load16(); - extraData = VAR(extraData); - _vm->_goblin->_objects[10]->yPos = extraData; + params.extraData = load16(); + params.extraData = VAR(params.extraData); + _vm->_goblin->_objects[10]->yPos = params.extraData; } -void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_initGoblin(OpGobParams ¶ms) { Goblin::Gob_Object *gobDesc = _vm->_goblin->_goblins[0]; int16 xPos; int16 yPos; @@ -2761,8 +2910,8 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj _vm->_goblin->_readyToAct = 0; } - if (gobDesc->state != 10 && _vm->_goblin->_itemIndInPocket != -1 && - _vm->_goblin->getObjMaxFrame(gobDesc) == gobDesc->curFrame) { + if ((gobDesc->state != 10) && (_vm->_goblin->_itemIndInPocket != -1) && + (_vm->_goblin->getObjMaxFrame(gobDesc) == gobDesc->curFrame)) { gobDesc->stateMach = gobDesc->realStateMach; xPos = _vm->_goblin->_gobPositions[0].x; @@ -2774,11 +2923,10 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj _vm->_scenery->updateAnim(layer, 0, gobDesc->animation, 0, gobDesc->xPos, gobDesc->yPos, 0); - gobDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - - _vm->_scenery->_animTop); - gobDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + gobDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + gobDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); } if (gobDesc->state != 10) @@ -2790,28 +2938,28 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj if (gobDesc->curFrame != 10) return; - objDesc = _vm->_goblin->_objects[_vm->_goblin->_itemIndInPocket]; - objDesc->type = 0; - objDesc->toRedraw = 1; - objDesc->curFrame = 0; + params.objDesc = _vm->_goblin->_objects[_vm->_goblin->_itemIndInPocket]; + params.objDesc->type = 0; + params.objDesc->toRedraw = 1; + params.objDesc->curFrame = 0; - objDesc->order = gobDesc->order; - objDesc->animation = - objDesc->stateMach[objDesc->state][0]->animation; + params.objDesc->order = gobDesc->order; + params.objDesc->animation = + params.objDesc->stateMach[params.objDesc->state][0]->animation; - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos += - (_vm->_goblin->_gobPositions[0].y * 6 + 5) - _vm->_scenery->_toRedrawBottom; + params.objDesc->yPos += (_vm->_goblin->_gobPositions[0].y * 6 + 5) - + _vm->_scenery->_toRedrawBottom; if (gobDesc->curLookDir == 4) { - objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + 14 + params.objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + 14 - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; } else { - objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + params.objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; } @@ -2821,8 +2969,10 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj } int16 Inter_v1::loadSound(int16 slot) { - char *dataPtr; + byte *dataPtr; int16 id; + uint32 dataSize; + SoundSource source; if (slot == -1) slot = _vm->_parse->parseValExpr(); @@ -2834,74 +2984,25 @@ int16 Inter_v1::loadSound(int16 slot) { } if (id >= 30000) { - dataPtr = _vm->_game->loadExtData(id, 0, 0); - _vm->_game->_soundFromExt[slot] = 1; - } else { - dataPtr = _vm->_game->loadTotResource(id); - _vm->_game->_soundFromExt[slot] = 0; - } - - _vm->_game->loadSound(slot, dataPtr); - return 0; -} - -void Inter_v1::loadMult(void) { - int16 val; - int16 objIndex; - int16 i; - char *lmultData; + source = SOUND_EXT; - debugC(4, kDebugGameFlow, "Inter_v1::loadMult(): Loading..."); + dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); + } else { + int16 totSize; - evalExpr(&objIndex); - evalExpr(&val); - *_vm->_mult->_objects[objIndex].pPosX = val; - evalExpr(&val); - *_vm->_mult->_objects[objIndex].pPosY = val; + source = SOUND_TOT; - lmultData = (char *)_vm->_mult->_objects[objIndex].pAnimData; - for (i = 0; i < 11; i++) { - if ((char)READ_LE_UINT16(_vm->_global->_inter_execPtr) == (char)99) { - evalExpr(&val); - lmultData[i] = val; - } else { - _vm->_global->_inter_execPtr++; - } + dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize); + dataSize = (uint32) ((int32) totSize); } -} - -void Inter_v1::storeKey(int16 key) { - WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); - - storeMouse(); - WRITE_VAR(1, _vm->_snd->_playingSound); - - if (key == 0x4800) - key = 0x0B; - else if (key == 0x5000) - key = 0x0A; - else if (key == 0x4D00) - key = 0x09; - else if (key == 0x4B00) - key = 0x08; - else if (key == 0x011B) - key = 0x1B; - else if ((key & 0xFF) != 0) - key &= 0xFF; - - WRITE_VAR(0, key); - if (key != 0) - _vm->_util->waitKey(); -} - -void Inter_v1::storeMouse(void) { - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _vm->_game->_mouseButtons); + if (dataPtr) + _vm->_game->_soundSamples[slot].load(SOUND_SND, source, + dataPtr, dataSize); + return 0; } -void Inter_v1::animPalette(void) { +void Inter_v1::animPalette() { int16 i; Video::Color col; @@ -2929,4 +3030,127 @@ void Inter_v1::animPalette(void) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } +void Inter_v1::manipulateMap(int16 xPos, int16 yPos, int16 item) { + for (int y = 0; y < _vm->_map->_mapHeight; y++) { + for (int x = 0; x < _vm->_map->_mapWidth; x++) { + if ((_vm->_map->_itemsMap[y][x] & 0xFF) == item) + _vm->_map->_itemsMap[y][x] &= 0xFF00; + else if (((_vm->_map->_itemsMap[y][x] & 0xFF00) >> 8) == item) + _vm->_map->_itemsMap[y][x] &= 0xFF; + } + } + + if (xPos < _vm->_map->_mapWidth - 1) { + if (yPos > 0) { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos + 1] = + (_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos + 1] = + (_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF) + (item << 8); + } + } else { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF) + (item << 8); + } + } + } else { + if (yPos > 0) { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF) + (item << 8); + } + } else { + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + } + } + } + + if ((item < 0) || (item >= 20)) + return; + + if ((xPos > 1) && (_vm->_map->getPass(xPos - 2, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos - 2; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 4; + return; + } + + if ((xPos < _vm->_map->_mapWidth - 2) && + (_vm->_map->getPass(xPos + 2, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos + 2; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 0; + return; + } + + if ((xPos < _vm->_map->_mapWidth - 1) && + (_vm->_map->getPass(xPos + 1, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos + 1; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 0; + return; + } + + if ((xPos > 0) && (_vm->_map->getPass(xPos - 1, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos - 1; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 4; + return; + } +} + } // End of namespace Gob |