diff options
-rw-r--r-- | engines/gob/game.cpp | 748 | ||||
-rw-r--r-- | engines/gob/game.h | 16 | ||||
-rw-r--r-- | engines/gob/game_v1.cpp | 744 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 939 | ||||
-rw-r--r-- | engines/gob/inter.cpp | 12 | ||||
-rw-r--r-- | engines/gob/inter.h | 3 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 19 | ||||
-rw-r--r-- | engines/gob/mult.h | 13 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 70 |
9 files changed, 1675 insertions, 889 deletions
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 646b390fc1..d34004729f 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -250,65 +250,6 @@ void Game::freeCollision(int16 id) { } } -int16 Game::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { - Collision *ptr; - int16 i; - - if (resId != 0) - *resId = 0; - - *resIndex = 0; - - ptr = _collisionAreas; - for (i = 0; ptr->left != -1; ptr++, i++) { - if (all) { - if ((ptr->flags & 0xf) > 1) - continue; - - if ((ptr->flags & 0xff00) != 0) - continue; - - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) - continue; - - if (resId != 0) - *resId = ptr->id; - - *resIndex = i; - return ptr->key; - } else { - if ((ptr->flags & 0xff00) != 0) - continue; - - if ((ptr->flags & 0xf) != 1 && (ptr->flags & 0xf) != 2) - continue; - - if ((ptr->flags & 0xf0) >> 4 != _mouseButtons - 1 - && (ptr->flags & 0xf0) >> 4 != 2) - continue; - - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) - continue; - - if (resId != 0) - *resId = ptr->id; - *resIndex = i; - return ptr->key; - } - } - - if (_mouseButtons != 1 && all == 0) - return 0x11b; - - return 0; -} - void Game::capturePush(int16 left, int16 top, int16 width, int16 height) { int16 right; @@ -654,169 +595,6 @@ int16 Game::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 b } } -int16 Game::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * inpDesc) { - Collision *collArea; - int16 descInd; - int16 key; - int16 found = -1; - int16 i; - - descInd = 0; - for (i = 0; i < 250; i++) { - collArea = &_collisionAreas[i]; - - if (collArea->left == -1) - continue; - - if ((collArea->id & 0x8000) == 0) - continue; - - if ((collArea->flags & 0x0f) < 3) - continue; - - if ((collArea->flags & 0x0f) > 10) - continue; - - strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key); - - _vm->_draw->_destSpriteX = collArea->left; - _vm->_draw->_destSpriteY = collArea->top; - _vm->_draw->_spriteRight = collArea->right - collArea->left + 1; - _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1; - - _vm->_draw->_destSurface = 21; - - _vm->_draw->_backColor = inpDesc[descInd].backColor; - _vm->_draw->_frontColor = inpDesc[descInd].frontColor; - _vm->_draw->_textToPrint = _tempStr; - _vm->_draw->_transparency = 1; - _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex; - _vm->_draw->spriteOperation(DRAW_FILLRECT); - _vm->_draw->_destSpriteY += - ((collArea->bottom - collArea->top + 1) - 8) / 2; - - _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - descInd++; - } - - for (i = 0; i < 40; i++) { - WRITE_VAR_OFFSET(i * 4 + 0x44, 0); - } - - while (1) { - descInd = 0; - - for (i = 0; i < 250; i++) { - collArea = &_collisionAreas[i]; - - if (collArea->left == -1) - continue; - - if ((collArea->id & 0x8000) == 0) - continue; - - if ((collArea->flags & 0x0f) < 3) - continue; - - if ((collArea->flags & 0x0f) > 10) - continue; - - if (descInd == *pCurPos) { - found = i; - break; - } - - descInd++; - } - - assert(found != -1); - - collArea = &_collisionAreas[found]; - - key = inputArea(collArea->left, collArea->top, - collArea->right - collArea->left + 1, - collArea->bottom - collArea->top + 1, - inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor, - _vm->_global->_inter_variables + collArea->key, - inpDesc[*pCurPos].fontIndex, collArea->flags, &time); - - if (_vm->_inter->_terminate) - return 0; - - switch (key) { - case 0: - if (_activeCollResId == 0) - return 0; - - if ((_collisionAreas[_activeCollIndex]. - flags & 0x0f) < 3) - return 0; - - if ((_collisionAreas[_activeCollIndex]. - flags & 0x0f) > 10) - return 0; - - *pCurPos = 0; - for (i = 0; i < 250; i++) { - collArea = &_collisionAreas[i]; - - if (collArea->left == -1) - continue; - - if ((collArea->id & 0x8000) == 0) - continue; - - if ((collArea->flags & 0x0f) < 3) - continue; - - if ((collArea->flags & 0x0f) > 10) - continue; - - if (i == _activeCollIndex) - break; - - pCurPos[0]++; - } - break; - - case 0x3b00: - case 0x3c00: - case 0x3d00: - case 0x3e00: - case 0x3f00: - case 0x4000: - case 0x4100: - case 0x4200: - case 0x4300: - case 0x4400: - return key; - - case 0x1c0d: - - if (index == 1) - return key; - - if (*pCurPos == index - 1) { - *pCurPos = 0; - break; - } - - pCurPos[0]++; - break; - - case 0x5000: - if (index - 1 > *pCurPos) - pCurPos[0]++; - break; - - case 0x4800: - if (*pCurPos > 0) - pCurPos[0]--; - break; - } - } -} - int16 Game::adjustKey(int16 key) { if (key <= 0x60 || key >= 0x7b) return key; @@ -824,522 +602,6 @@ int16 Game::adjustKey(int16 key) { return key - 0x20; } -void Game::collisionsBlock(void) { - InputDesc descArray[20]; - int16 array[250]; - char count; - int16 collResId; - char *startIP; - int16 curCmd; - int16 cmd; - int16 cmdHigh; - int16 key; - int16 flags; - int16 left; - int16 top; - int16 width; - int16 height; - int16 var_22; - int16 index; - int16 curEditIndex; - int16 deltaTime; - int16 descIndex2; - int16 stackPos2; - int16 descIndex; - int16 timeVal; - char *str; - int16 savedCollStackSize; - int16 i; - int16 counter; - int16 var_24; - int16 var_26; - int16 _collStackPos; - Collision *collPtr; - int16 timeKey; - char *savedIP; - - if (_shouldPushColls) - pushCollisions(1); - - collResId = -1; - _vm->_global->_inter_execPtr++; - count = *_vm->_global->_inter_execPtr++; - _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * (byte)_vm->_global->_inter_execPtr[1]; - descIndex2 = (byte)_vm->_global->_inter_execPtr[2]; - stackPos2 = (byte)_vm->_global->_inter_execPtr[3]; - descIndex = (byte)_vm->_global->_inter_execPtr[4]; - - if (stackPos2 != 0 || descIndex != 0) - deltaTime /= 100; - - timeVal = deltaTime; - _vm->_global->_inter_execPtr += 6; - - startIP = _vm->_global->_inter_execPtr; - WRITE_VAR(16, 0); - var_22 = 0; - index = 0; - curEditIndex = 0; - - for (curCmd = 0; curCmd < count; curCmd++) { - array[curCmd] = 0; - cmd = *_vm->_global->_inter_execPtr++; - - if ((cmd & 0x40) != 0) { - cmd -= 0x40; - cmdHigh = (byte)*_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr++; - cmdHigh <<= 8; - } else { - cmdHigh = 0; - } - - if ((cmd & 0x80) != 0) { - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); - } else { - left = _vm->_inter->load16(); - top = _vm->_inter->load16(); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); - } - cmd &= 0x7f; - - debugC(1, DEBUG_COLLISIONS, "collisionsBlock(%d)", cmd); - - switch (cmd) { - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - - _vm->_util->waitKey(); - var_22 = 1; - key = _vm->_parse->parseVarIndex(); - descArray[index].fontIndex = _vm->_inter->load16(); - descArray[index].backColor = *_vm->_global->_inter_execPtr++; - descArray[index].frontColor = *_vm->_global->_inter_execPtr++; - - if (cmd < 5 || cmd > 8) { - descArray[index].ptr = 0; - } else { - descArray[index].ptr = _vm->_global->_inter_execPtr + 2; - _vm->_global->_inter_execPtr += _vm->_inter->load16(); - } - - if (left == -1) - break; - - if ((cmd & 1) == 0) { - addNewCollision(curCmd + 0x8000, left, - top, - left + - width * - _vm->_draw->_fonts[descArray[index].fontIndex]-> - itemWidth - 1, top + height - 1, cmd, key, - 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - } else { - addNewCollision(curCmd + 0x8000, left, - top, - left + - width * - _vm->_draw->_fonts[descArray[index].fontIndex]-> - itemWidth - 1, top + height - 1, cmd, key, - 0, 0); - } - index++; - break; - - case 21: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; - - addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, - (flags << 4) + cmdHigh + 2, key, - _vm->_global->_inter_execPtr - (char *)_totFileData, 0); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - break; - - case 20: - collResId = curCmd; - // Fall through to case 2 - - case 2: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; - - addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, - (flags << 4) + cmdHigh + 2, key, 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - break; - - case 0: - _vm->_global->_inter_execPtr += 6; - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - key = curCmd + 0xA000; - - addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, - cmd + cmdHigh, key, - startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - break; - - case 1: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; - - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - if (key == 0) - key = curCmd + 0xa000; - - addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, - (flags << 4) + cmd + cmdHigh, key, - startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); - break; - } - } - - _forceHandleMouse = 0; - _vm->_util->waitKey(); - - do { - if (var_22 != 0) { - key = - multiEdit(deltaTime, index, &curEditIndex, - descArray); - - if (key == 0x1c0d) { - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - if ((_collisionAreas[i].flags & 1) != 0) - continue; - - if ((_collisionAreas[i].flags & 0x0f) <= 2) - continue; - - collResId = _collisionAreas[i].id; - _activeCollResId = collResId; - collResId &= 0x7fff; - _activeCollIndex = i; - break; - } - break; - } - } else { - key = - checkCollisions(_handleMouse, -deltaTime, - &_activeCollResId, &_activeCollIndex); - } - - if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff && - (key >> 8) > 1 && (key >> 8) < 12) { - key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00); - } - - if (_activeCollResId == 0) { - if (key != 0) { - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i]. - id & 0x8000) == 0) - continue; - - if (_collisionAreas[i].key == key - || _collisionAreas[i].key == - 0x7fff) { - - _activeCollResId = - _collisionAreas[i].id; - _activeCollIndex = i; - break; - } - } - - if (_activeCollResId == 0) { - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - if ((_collisionAreas[i].key & 0xff00) != 0) - continue; - - if (_collisionAreas[i].key == 0) - continue; - - if (adjustKey(key & 0xff) == adjustKey(_collisionAreas[i].key) || _collisionAreas[i].key == 0x7fff) { - _activeCollResId = _collisionAreas[i].id; - _activeCollIndex = i; - break; - } - } - } - } else { - - if (deltaTime != 0 && VAR(16) == 0) { - if (stackPos2 != 0) { - _collStackPos = 0; - collPtr = _collisionAreas; - - for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { - if ((collPtr->id & 0x8000) == 0) - continue; - - _collStackPos++; - if (_collStackPos != stackPos2) - continue; - - _activeCollResId = collPtr->id; - _activeCollIndex = i; - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _mouseButtons); - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); - - if (collPtr->funcLeave != 0) { - timeKey = _vm->_util->getTimeKey(); - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + collPtr->funcLeave; - _shouldPushColls = 1; - savedCollStackSize = _collStackSize; - _vm->_inter->funcBlock(0); - - if (savedCollStackSize != _collStackSize) - popCollisions(); - - _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; - deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey); - - if (deltaTime < 2) - deltaTime = 2; - } - - if (VAR(16) == 0) - _activeCollResId = 0; - break; - } - } else { - if (descIndex != 0) { - counter = 0; - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - counter++; - if (counter != descIndex) - continue; - - _activeCollResId = _collisionAreas[i].id; - _activeCollIndex = i; - break; - } - } else { - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - _activeCollResId = _collisionAreas[i].id; - _activeCollIndex = i; - break; - } - } - } - } else { - if (descIndex2 != 0) { - counter = 0; - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - counter++; - if (counter != descIndex2) - continue; - - _activeCollResId = _collisionAreas[i].id; - _activeCollIndex = i; - break; - } - } - } - } - } - - if (_activeCollResId == 0) - continue; - - if (_collisionAreas[_activeCollIndex].funcLeave != 0) - continue; - - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _mouseButtons); - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); - - if (_collisionAreas[_activeCollIndex].funcEnter != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[_activeCollIndex]. - funcEnter; - - _shouldPushColls = 1; - - _collStackPos = _collStackSize; - _vm->_inter->funcBlock(0); - if (_collStackPos != _collStackSize) - popCollisions(); - _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; - } - - WRITE_VAR(16, 0); - _activeCollResId = 0; - } - while (_activeCollResId == 0 && !_vm->_inter->_terminate && !_vm->_quitRequested); - - if (((uint16)_activeCollResId & ~0x8000) == collResId) { - _collStackPos = 0; - var_24 = 0; - var_26 = 1; - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) - continue; - - if ((_collisionAreas[i].id & 0x8000) == 0) - continue; - - if ((_collisionAreas[i].flags & 0x0f) < 3) - continue; - - if ((_collisionAreas[i].flags & 0x0f) > 10) - continue; - - if ((_collisionAreas[i].flags & 0x0f) > 8) { - char *ptr; - strcpy(_tempStr, - _vm->_global->_inter_variables + _collisionAreas[i].key); - while ((ptr = strchr(_tempStr, ' ')) != 0) { - _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1); - ptr = strchr(_tempStr, ' '); - } - strcpy(_vm->_global->_inter_variables + _collisionAreas[i].key, _tempStr); - } - - if ((_collisionAreas[i].flags & 0x0f) >= 5 && - (_collisionAreas[i].flags & 0x0f) <= 8) { - str = descArray[var_24].ptr; - - strcpy(_tempStr, _vm->_global->_inter_variables + _collisionAreas[i].key); - - if ((_collisionAreas[i].flags & 0x0f) < 7) - _vm->_util->prepareStr(_tempStr); - - int16 pos = 0; - do { - strcpy(_collStr, str); - pos += strlen(str) + 1; - - str += strlen(str) + 1; - - if ((_collisionAreas[i].flags & 0x0f) < 7) - _vm->_util->prepareStr(_collStr); - - if (strcmp(_tempStr, _collStr) == 0) { - VAR(17)++; - WRITE_VAR(17 + var_26, 1); - break; - } - } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos); - _collStackPos++; - } else { - VAR(17 + var_26) = 2; - } - var_24++; - var_26++; - } - - if (_collStackPos != (int16)VAR(17)) - WRITE_VAR(17, 0); - else - WRITE_VAR(17, 1); - } - - savedIP = 0; - if (!_vm->_inter->_terminate) { - savedIP = (char *)_totFileData + - _collisionAreas[_activeCollIndex].funcLeave; - - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _mouseButtons); - - if (VAR(16) == 0) { - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); - } - } - - for (curCmd = 0; curCmd < count; curCmd++) { - freeCollision(curCmd + 0x8000); - } - _vm->_global->_inter_execPtr = savedIP; -} - void Game::loadTotFile(char *path) { int16 handle; @@ -1408,7 +670,7 @@ void Game::loadImFile(void) { void Game::start(void) { _collisionAreas = new Collision[250]; prepareStart(); - playTot(0); + playTot(-2); delete[] _collisionAreas; @@ -1634,7 +896,7 @@ void Game::setCollisions(void) { top = _vm->_parse->parseValExpr(); width = _vm->_parse->parseValExpr(); height = _vm->_parse->parseValExpr(); - if ((_vm->_draw->_renderFlags != 8) && (left != -1)) { + if ((_vm->_draw->_renderFlags & 8) && (left != -1)) { left += _vm->_draw->_backDeltaX; top += _vm->_draw->_backDeltaY; } @@ -1680,12 +942,12 @@ void Game::collAreaSub(int16 index, int8 enter) { collId = _collisionAreas[index].id & 0xF000; - if ((collId == 0xA000) || (collId == 0x9000)) + if ((collId != 0xA000) && (collId != 0x9000)) WRITE_VAR(17, collId); else if (enter == 0) - WRITE_VAR(17, -(collId & 0x0FFF)); + WRITE_VAR(17, _collisionAreas[index].id & 0x0FFF); else - WRITE_VAR(17, collId & 0x0FFF); + WRITE_VAR(17, -(_collisionAreas[index].id & 0x0FFF)); if (enter != 0) { if (_collisionAreas[index].funcEnter != 0) diff --git a/engines/gob/game.h b/engines/gob/game.h index 9ffc1b103d..ff4d133800 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -195,10 +195,7 @@ public: void loadSound(int16 slot, char *dataPtr); int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor, int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime); - int16 multiEdit(int16 time, int16 index, int16 *pCurPos, - InputDesc * inpDesc); int16 adjustKey(int16 key); - void collisionsBlock(void); void loadTotFile(char *path); void loadExtTable(void); void loadImFile(void); @@ -224,6 +221,9 @@ public: virtual void clearCollisions(void) = 0; virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave) = 0; + virtual void collisionsBlock(void) = 0; + virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, + InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0; virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, char handleMouse) = 0; virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, @@ -269,7 +269,6 @@ protected: GobEngine *_vm; - int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); void setCollisions(void); void collSub(int16 offset); void collAreaSub(int16 index, int8 enter); @@ -277,6 +276,7 @@ protected: virtual void pushCollisions(char all) = 0; virtual void popCollisions(void) = 0; + virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex) = 0; }; class Game_v1 : public Game { @@ -285,6 +285,9 @@ public: virtual void clearCollisions(void); virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + virtual void collisionsBlock(void); + virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, + InputDesc *inpDesc, int16 *collResId, int16 *collIndex); virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, char handleMouse); virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, @@ -297,6 +300,7 @@ public: protected: virtual void pushCollisions(char all); virtual void popCollisions(void); + virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); }; class Game_v2 : public Game_v1 { @@ -305,6 +309,9 @@ public: virtual void clearCollisions(void); virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + virtual void collisionsBlock(void); + virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, + InputDesc *inpDesc, int16 *collResId, int16 *collIndex); virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, char handleMouse); virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, @@ -325,6 +332,7 @@ protected: virtual void pushCollisions(char all); virtual void popCollisions(void); + virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); }; } // End of namespace Gob diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index 3bbb59a873..053061f2ba 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -59,6 +59,9 @@ void Game_v1::playTot(int16 skipPlay) { char *savedIP; int16 i; + if (skipPlay < 0) + skipPlay = 0; + oldNestLevel = _vm->_inter->_nestLevel; oldBreakFrom = _vm->_inter->_breakFromLevel; oldCaptureCounter = _vm->_scenery->_pCaptureCounter; @@ -83,7 +86,7 @@ void Game_v1::playTot(int16 skipPlay) { else _vm->_cdrom->stopPlaying(); _vm->_draw->animateCursor(4); - _vm->_inter->initControlVars(); + _vm->_inter->initControlVars(1); _vm->_mult->initAll(); _vm->_mult->zeroMultData(); @@ -627,4 +630,743 @@ void Game_v1::prepareStart(void) { _startTimeKey = _vm->_util->getTimeKey(); } +void Game_v1::collisionsBlock(void) { + InputDesc descArray[20]; + int16 array[250]; + char count; + int16 collResId; + char *startIP; + int16 curCmd; + int16 cmd; + int16 cmdHigh; + int16 key; + int16 flags; + int16 left; + int16 top; + int16 width; + int16 height; + int16 var_22; + int16 index; + int16 curEditIndex; + int16 deltaTime; + int16 descIndex2; + int16 stackPos2; + int16 descIndex; + int16 timeVal; + char *str; + int16 savedCollStackSize; + int16 i; + int16 counter; + int16 var_24; + int16 var_26; + int16 _collStackPos; + Collision *collPtr; + int16 timeKey; + char *savedIP; + + if (_shouldPushColls) + pushCollisions(1); + + collResId = -1; + _vm->_global->_inter_execPtr++; + count = *_vm->_global->_inter_execPtr++; + _handleMouse = _vm->_global->_inter_execPtr[0]; + deltaTime = 1000 * (byte)_vm->_global->_inter_execPtr[1]; + descIndex2 = (byte)_vm->_global->_inter_execPtr[2]; + stackPos2 = (byte)_vm->_global->_inter_execPtr[3]; + descIndex = (byte)_vm->_global->_inter_execPtr[4]; + + if (stackPos2 != 0 || descIndex != 0) + deltaTime /= 100; + + timeVal = deltaTime; + _vm->_global->_inter_execPtr += 6; + + startIP = _vm->_global->_inter_execPtr; + WRITE_VAR(16, 0); + var_22 = 0; + index = 0; + curEditIndex = 0; + + for (curCmd = 0; curCmd < count; curCmd++) { + array[curCmd] = 0; + cmd = *_vm->_global->_inter_execPtr++; + + if ((cmd & 0x40) != 0) { + cmd -= 0x40; + cmdHigh = (byte)*_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr++; + cmdHigh <<= 8; + } else { + cmdHigh = 0; + } + + if ((cmd & 0x80) != 0) { + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + } else { + left = _vm->_inter->load16(); + top = _vm->_inter->load16(); + width = _vm->_inter->load16(); + height = _vm->_inter->load16(); + } + cmd &= 0x7f; + + debugC(1, DEBUG_COLLISIONS, "collisionsBlock(%d)", cmd); + + switch (cmd) { + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + + _vm->_util->waitKey(); + var_22 = 1; + key = _vm->_parse->parseVarIndex(); + descArray[index].fontIndex = _vm->_inter->load16(); + descArray[index].backColor = *_vm->_global->_inter_execPtr++; + descArray[index].frontColor = *_vm->_global->_inter_execPtr++; + + if (cmd < 5 || cmd > 8) { + descArray[index].ptr = 0; + } else { + descArray[index].ptr = _vm->_global->_inter_execPtr + 2; + _vm->_global->_inter_execPtr += _vm->_inter->load16(); + } + + if (left == -1) + break; + + if ((cmd & 1) == 0) { + addNewCollision(curCmd + 0x8000, left, + top, + left + + width * + _vm->_draw->_fonts[descArray[index].fontIndex]-> + itemWidth - 1, top + height - 1, cmd, key, + 0, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + } else { + addNewCollision(curCmd + 0x8000, left, + top, + left + + width * + _vm->_draw->_fonts[descArray[index].fontIndex]-> + itemWidth - 1, top + height - 1, cmd, key, + 0, 0); + } + index++; + break; + + case 21: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16() & 3; + + addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, + top + height - 1, + (flags << 4) + cmdHigh + 2, key, + _vm->_global->_inter_execPtr - (char *)_totFileData, 0); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + + case 20: + collResId = curCmd; + // Fall through to case 2 + + case 2: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16() & 3; + + addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, + top + height - 1, + (flags << 4) + cmdHigh + 2, key, 0, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + + case 0: + _vm->_global->_inter_execPtr += 6; + startIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + key = curCmd + 0xA000; + + addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, + top + height - 1, + cmd + cmdHigh, key, + startIP - (char *)_totFileData, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + + case 1: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16() & 3; + + startIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + if (key == 0) + key = curCmd + 0xa000; + + addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, + top + height - 1, + (flags << 4) + cmd + cmdHigh, key, + startIP - (char *)_totFileData, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + } + } + + _forceHandleMouse = 0; + _vm->_util->waitKey(); + + do { + if (var_22 != 0) { + key = + multiEdit(deltaTime, index, &curEditIndex, + descArray, 0, 0); + + if (key == 0x1c0d) { + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + if ((_collisionAreas[i].flags & 1) != 0) + continue; + + if ((_collisionAreas[i].flags & 0x0f) <= 2) + continue; + + collResId = _collisionAreas[i].id; + _activeCollResId = collResId; + collResId &= 0x7fff; + _activeCollIndex = i; + break; + } + break; + } + } else { + key = + checkCollisions(_handleMouse, -deltaTime, + &_activeCollResId, &_activeCollIndex); + } + + if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff && + (key >> 8) > 1 && (key >> 8) < 12) { + key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00); + } + + if (_activeCollResId == 0) { + if (key != 0) { + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i]. + id & 0x8000) == 0) + continue; + + if (_collisionAreas[i].key == key + || _collisionAreas[i].key == + 0x7fff) { + + _activeCollResId = + _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + + if (_activeCollResId == 0) { + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + if ((_collisionAreas[i].key & 0xff00) != 0) + continue; + + if (_collisionAreas[i].key == 0) + continue; + + if (adjustKey(key & 0xff) == adjustKey(_collisionAreas[i].key) || _collisionAreas[i].key == 0x7fff) { + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + } + } else { + + if (deltaTime != 0 && VAR(16) == 0) { + if (stackPos2 != 0) { + _collStackPos = 0; + collPtr = _collisionAreas; + + for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { + if ((collPtr->id & 0x8000) == 0) + continue; + + _collStackPos++; + if (_collStackPos != stackPos2) + continue; + + _activeCollResId = collPtr->id; + _activeCollIndex = i; + WRITE_VAR(2, _vm->_global->_inter_mouseX); + WRITE_VAR(3, _vm->_global->_inter_mouseY); + WRITE_VAR(4, _mouseButtons); + WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); + + if (collPtr->funcLeave != 0) { + timeKey = _vm->_util->getTimeKey(); + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + collPtr->funcLeave; + _shouldPushColls = 1; + savedCollStackSize = _collStackSize; + _vm->_inter->funcBlock(0); + + if (savedCollStackSize != _collStackSize) + popCollisions(); + + _shouldPushColls = 0; + _vm->_global->_inter_execPtr = savedIP; + deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey); + + if (deltaTime < 2) + deltaTime = 2; + } + + if (VAR(16) == 0) + _activeCollResId = 0; + break; + } + } else { + if (descIndex != 0) { + counter = 0; + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + counter++; + if (counter != descIndex) + continue; + + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } else { + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + } + } else { + if (descIndex2 != 0) { + counter = 0; + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + counter++; + if (counter != descIndex2) + continue; + + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + } + } + } + + if (_activeCollResId == 0) + continue; + + if (_collisionAreas[_activeCollIndex].funcLeave != 0) + continue; + + WRITE_VAR(2, _vm->_global->_inter_mouseX); + WRITE_VAR(3, _vm->_global->_inter_mouseY); + WRITE_VAR(4, _mouseButtons); + WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); + + if (_collisionAreas[_activeCollIndex].funcEnter != 0) { + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_totFileData + + _collisionAreas[_activeCollIndex]. + funcEnter; + + _shouldPushColls = 1; + + _collStackPos = _collStackSize; + _vm->_inter->funcBlock(0); + if (_collStackPos != _collStackSize) + popCollisions(); + _shouldPushColls = 0; + _vm->_global->_inter_execPtr = savedIP; + } + + WRITE_VAR(16, 0); + _activeCollResId = 0; + } + while (_activeCollResId == 0 && !_vm->_inter->_terminate && !_vm->_quitRequested); + + if (((uint16)_activeCollResId & ~0x8000) == collResId) { + _collStackPos = 0; + var_24 = 0; + var_26 = 1; + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0x8000) == 0) + continue; + + if ((_collisionAreas[i].flags & 0x0f) < 3) + continue; + + if ((_collisionAreas[i].flags & 0x0f) > 10) + continue; + + if ((_collisionAreas[i].flags & 0x0f) > 8) { + char *ptr; + strcpy(_tempStr, + _vm->_global->_inter_variables + _collisionAreas[i].key); + while ((ptr = strchr(_tempStr, ' ')) != 0) { + _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1); + ptr = strchr(_tempStr, ' '); + } + strcpy(_vm->_global->_inter_variables + _collisionAreas[i].key, _tempStr); + } + + if ((_collisionAreas[i].flags & 0x0f) >= 5 && + (_collisionAreas[i].flags & 0x0f) <= 8) { + str = descArray[var_24].ptr; + + strcpy(_tempStr, _vm->_global->_inter_variables + _collisionAreas[i].key); + + if ((_collisionAreas[i].flags & 0x0f) < 7) + _vm->_util->prepareStr(_tempStr); + + int16 pos = 0; + do { + strcpy(_collStr, str); + pos += strlen(str) + 1; + + str += strlen(str) + 1; + + if ((_collisionAreas[i].flags & 0x0f) < 7) + _vm->_util->prepareStr(_collStr); + + if (strcmp(_tempStr, _collStr) == 0) { + VAR(17)++; + WRITE_VAR(17 + var_26, 1); + break; + } + } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos); + _collStackPos++; + } else { + VAR(17 + var_26) = 2; + } + var_24++; + var_26++; + } + + if (_collStackPos != (int16)VAR(17)) + WRITE_VAR(17, 0); + else + WRITE_VAR(17, 1); + } + + savedIP = 0; + if (!_vm->_inter->_terminate) { + savedIP = (char *)_totFileData + + _collisionAreas[_activeCollIndex].funcLeave; + + WRITE_VAR(2, _vm->_global->_inter_mouseX); + WRITE_VAR(3, _vm->_global->_inter_mouseY); + WRITE_VAR(4, _mouseButtons); + + if (VAR(16) == 0) { + WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); + } + } + + for (curCmd = 0; curCmd < count; curCmd++) { + freeCollision(curCmd + 0x8000); + } + _vm->_global->_inter_execPtr = savedIP; +} + +int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * inpDesc, + int16 *collResId, int16 *collIndex) { + Collision *collArea; + int16 descInd; + int16 key; + int16 found = -1; + int16 i; + + descInd = 0; + for (i = 0; i < 250; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0x8000) == 0) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key); + + _vm->_draw->_destSpriteX = collArea->left; + _vm->_draw->_destSpriteY = collArea->top; + _vm->_draw->_spriteRight = collArea->right - collArea->left + 1; + _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1; + + _vm->_draw->_destSurface = 21; + + _vm->_draw->_backColor = inpDesc[descInd].backColor; + _vm->_draw->_frontColor = inpDesc[descInd].frontColor; + _vm->_draw->_textToPrint = _tempStr; + _vm->_draw->_transparency = 1; + _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex; + _vm->_draw->spriteOperation(DRAW_FILLRECT); + _vm->_draw->_destSpriteY += + ((collArea->bottom - collArea->top + 1) - 8) / 2; + + _vm->_draw->spriteOperation(DRAW_PRINTTEXT); + descInd++; + } + + for (i = 0; i < 40; i++) { + WRITE_VAR_OFFSET(i * 4 + 0x44, 0); + } + + while (1) { + descInd = 0; + + for (i = 0; i < 250; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0x8000) == 0) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + if (descInd == *pCurPos) { + found = i; + break; + } + + descInd++; + } + + assert(found != -1); + + collArea = &_collisionAreas[found]; + + key = inputArea(collArea->left, collArea->top, + collArea->right - collArea->left + 1, + collArea->bottom - collArea->top + 1, + inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor, + _vm->_global->_inter_variables + collArea->key, + inpDesc[*pCurPos].fontIndex, collArea->flags, &time); + + if (_vm->_inter->_terminate) + return 0; + + switch (key) { + case 0: + if (_activeCollResId == 0) + return 0; + + if ((_collisionAreas[_activeCollIndex]. + flags & 0x0f) < 3) + return 0; + + if ((_collisionAreas[_activeCollIndex]. + flags & 0x0f) > 10) + return 0; + + *pCurPos = 0; + for (i = 0; i < 250; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0x8000) == 0) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + if (i == _activeCollIndex) + break; + + pCurPos[0]++; + } + break; + + case 0x3b00: + case 0x3c00: + case 0x3d00: + case 0x3e00: + case 0x3f00: + case 0x4000: + case 0x4100: + case 0x4200: + case 0x4300: + case 0x4400: + return key; + + case 0x1c0d: + + if (index == 1) + return key; + + if (*pCurPos == index - 1) { + *pCurPos = 0; + break; + } + + pCurPos[0]++; + break; + + case 0x5000: + if (index - 1 > *pCurPos) + pCurPos[0]++; + break; + + case 0x4800: + if (*pCurPos > 0) + pCurPos[0]--; + break; + } + } +} + +int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { + Collision *ptr; + int16 i; + + if (resId != 0) + *resId = 0; + + *resIndex = 0; + + ptr = _collisionAreas; + for (i = 0; ptr->left != -1; ptr++, i++) { + if (all) { + if ((ptr->flags & 0xf) > 1) + continue; + + if ((ptr->flags & 0xff00) != 0) + continue; + + if (_vm->_global->_inter_mouseX < ptr->left + || _vm->_global->_inter_mouseX > ptr->right + || _vm->_global->_inter_mouseY < ptr->top + || _vm->_global->_inter_mouseY > ptr->bottom) + continue; + + if (resId != 0) + *resId = ptr->id; + + *resIndex = i; + return ptr->key; + } else { + if ((ptr->flags & 0xff00) != 0) + continue; + + if ((ptr->flags & 0xf) != 1 && (ptr->flags & 0xf) != 2) + continue; + + if ((ptr->flags & 0xf0) >> 4 != _mouseButtons - 1 + && (ptr->flags & 0xf0) >> 4 != 2) + continue; + + if (_vm->_global->_inter_mouseX < ptr->left + || _vm->_global->_inter_mouseX > ptr->right + || _vm->_global->_inter_mouseY < ptr->top + || _vm->_global->_inter_mouseY > ptr->bottom) + continue; + + if (resId != 0) + *resId = ptr->id; + *resIndex = i; + return ptr->key; + } + } + + if (_mouseButtons != 1 && all == 0) + return 0x11b; + + return 0; +} + } // End of namespace Gob diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 025c86b73a..ab14eec6de 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -68,30 +68,35 @@ void Game_v2::playTot(int16 skipPlay) { _vm->_scenery->_pCaptureCounter = &_captureCounter; strcpy(savedTotName, _curTotFile); - if (skipPlay == 0) { + if (skipPlay <= 0) { while (!_vm->_quitRequested) { - for (i = 0; i < 4; i++) { - _vm->_draw->_fontToSprite[i].sprite = -1; - _vm->_draw->_fontToSprite[i].base = -1; - _vm->_draw->_fontToSprite[i].width = -1; - _vm->_draw->_fontToSprite[i].height = -1; - } - + _vm->_draw->animateCursor(4); if (_vm->_features & GF_MAC) _vm->_music->stopPlay(); else _vm->_cdrom->stopPlaying(); - _vm->_draw->animateCursor(4); - _vm->_inter->initControlVars(); - _vm->_mult->initAll(); - _vm->_mult->zeroMultData(); - for (i = 0; i < 20; i++) - _vm->_draw->_spritesArray[i] = 0; + if (skipPlay != -1) { + _vm->_inter->initControlVars(1); + + for (i = 0; i < 4; i++) { + _vm->_draw->_fontToSprite[i].sprite = -1; + _vm->_draw->_fontToSprite[i].base = -1; + _vm->_draw->_fontToSprite[i].width = -1; + _vm->_draw->_fontToSprite[i].height = -1; + } + + _vm->_mult->initAll(); + _vm->_mult->zeroMultData(); - _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; - _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; - _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites; + for (i = 0; i < 20; i++) + _vm->_draw->_spritesArray[i] = 0; + + _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; + _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; + _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites; + } else + _vm->_inter->initControlVars(0); for (i = 0; i < 20; i++) _soundSamples[i] = 0; @@ -113,6 +118,9 @@ void Game_v2::playTot(int16 skipPlay) { break; } + if (skipPlay == -2) + skipPlay = 0; + strcpy(_curImaFile, _curTotFile); strcpy(_curExtFile, _curTotFile); @@ -226,20 +234,25 @@ void Game_v2::playTot(int16 skipPlay) { for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) capturePop(0); - _vm->_mult->checkFreeMult(); - _vm->_mult->freeAll(); +/* _vm->_mult->checkFreeMult(); + _vm->_mult->freeAll();*/ - for (i = 0; i < 20; i++) { - if (_vm->_draw->_spritesArray[i] != 0) - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); - _vm->_draw->_spritesArray[i] = 0; - } - _vm->_snd->stopSound(0); + if (skipPlay != -1) { + _vm->_goblin->freeObjects(); - for (i = 0; i < 60; i++) - if ((_soundTypes[i] & 8) == 0) - freeSoundSlot(i); + for (i = 0; i < 20; i++) { + if (_vm->_draw->_spritesArray[i] != 0) + _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); + _vm->_draw->_spritesArray[i] = 0; + } + _vm->_snd->stopSound(0); + for (i = 0; i < 60; i++) + if ((_soundTypes[i] & 8) == 0) + freeSoundSlot(i); + } + + closeImd(); if (_totToLoad[0] == 0) break; @@ -277,7 +290,7 @@ void Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int1 debugC(5, DEBUG_COLLISIONS, "flags = %x, key = %x", flags, key); debugC(5, DEBUG_COLLISIONS, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); - for (i = 0; i < 250; i++) { + for (i = 0; i < 150; i++) { if ((_collisionAreas[i].left != -1) && (_collisionAreas[i].id != id)) continue; @@ -365,8 +378,8 @@ int16 Game_v2::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char h else _vm->_mult->_frameStart = 0; - _vm->_mult->playMult(_vm->_mult->_frameStart + VAR(57), _vm->_mult->_frameStart + VAR(57), 1, - handleMouse); + _vm->_mult->playMult(_vm->_mult->_frameStart + VAR(57), + _vm->_mult->_frameStart + VAR(57), 1, handleMouse); } if (_vm->_inter->_soundEndTimeKey != 0 @@ -405,11 +418,8 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, resIndex = 0; - if (_vm->_draw->_cursorIndex == -1 && handleMouse != 0 - && _lastCollKey == 0) { - _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); + if ((_vm->_draw->_cursorIndex == -1) && (handleMouse != 0) && (_lastCollKey == 0)) { + _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); if ((_lastCollKey != 0) && (_lastCollId & 0x8000)) collAreaSub(_lastCollAreaIndex, 1); @@ -427,31 +437,12 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } if (_vm->_draw->_noInvalidated == 0) { - if (handleMouse) + if (handleMouse != 0) _vm->_draw->animateCursor(-1); else _vm->_draw->blitInvalidated(); } - // NOTE: the original asm does the below checkKeys call - // _before_ this check. However, that can cause keypresses to get lost - // since there's a return statement in this check. - // Additionally, I added a 'deltaTime == -1' check there, since - // when this function is called with deltaTime == -1 in inputArea, - // and the return value is then discarded. - if (deltaTime < 0) { - uint32 curtime = _vm->_util->getTimeKey(); - if (deltaTime == -1 || curtime + deltaTime > timeKey) { - if (pResId != 0) - *pResId = 0; - - if (pResIndex != 0) - *pResIndex = 0; - - return 0; - } - } - key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse); @@ -534,14 +525,14 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } } - if (handleMouse == 0 && _mouseButtons != 0) { + if ((handleMouse == 0) && (_mouseButtons != 0)) { _vm->_util->waitMouseRelease(0); key = 3; } if (key != 0) { - if (handleMouse == 1) + if (handleMouse & 1) _vm->_draw->blitCursor(); if (pResId != 0) @@ -560,75 +551,72 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, if (handleMouse != 0) { if (_mouseButtons != 0) { - oldIndex = 0; - - _vm->_draw->animateCursor(2); - if (deltaTime <= 0) { - if (handleMouse == 1) - _vm->_util->waitMouseRelease(1); - } else if (deltaTime > 0) { + if (deltaTime > 0) { + _vm->_draw->animateCursor(2); _vm->_util->delay(deltaTime); - } - + } else if (handleMouse & 1) + _vm->_util->waitMouseRelease(1); _vm->_draw->animateCursor(-1); + if (pResId != 0) *pResId = 0; key = checkMousePoint(0, pResId, &resIndex); - if (pResIndex != 0) *pResIndex = resIndex; - if (key != 0 || (pResId != 0 && *pResId != 0)) { - if (handleMouse == 1 && (deltaTime <= 0 - || _mouseButtons == 0)) + if ((key != 0) || ((pResId != 0) && (*pResId != 0))) { + if ((handleMouse & 1) && ((deltaTime <= 0) || (_mouseButtons == 0))) _vm->_draw->blitCursor(); - if ((_lastCollKey != 0) && (key = _lastCollKey)) - collAreaSub(_lastCollAreaIndex, 0); + if ((_lastCollKey != 0) && (key != _lastCollKey)) + collAreaSub(_lastCollAreaIndex, 0); _lastCollKey = 0; return key; } if (handleMouse & 4) - return key; + return 0; if (_lastCollKey != 0) collAreaSub(_lastCollAreaIndex, 0); - _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); - - if (_lastCollKey != 0) + _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); + if ((_lastCollKey != 0) && (_lastCollId & 0x8000)) collAreaSub(_lastCollAreaIndex, 1); + } else if ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) || + (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { - // loc_189D3 - if (handleMouse != 0 && - (_vm->_global->_inter_mouseX != _vm->_draw->_cursorX - || _vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { - oldIndex = _lastCollAreaIndex; - oldId = _lastCollId; - - key = - checkMousePoint(1, - &_lastCollId, - &_lastCollAreaIndex); + oldIndex = _lastCollAreaIndex; + oldId = _lastCollId; + key = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); - if (key != _lastCollKey) { - if (_lastCollKey != 0) - collAreaSub(_lastCollAreaIndex, 0); + if (key != _lastCollKey) { + if ((_lastCollKey != 0) && (oldId & 0x8000)) + collAreaSub(oldIndex, 0); - _lastCollKey = key; + _lastCollKey = key; - if (_lastCollKey != 0) - collAreaSub(_lastCollAreaIndex, 1); - } + if ((key != 0) && (_lastCollId & 0x8000)) + collAreaSub(_lastCollAreaIndex, 1); } } } + if ((deltaTime < 0) && (key == 0) && (_mouseButtons == 0)) { + uint32 curtime = _vm->_util->getTimeKey(); + if ((curtime + deltaTime) > timeKey) { + if (pResId != 0) + *pResId = 0; + + if (pResIndex != 0) + *pResIndex = 0; + + return 0; + } + } + if (handleMouse != 0) _vm->_draw->animateCursor(-1); @@ -685,4 +673,761 @@ void Game_v2::prepareStart(void) { _startTimeKey = _vm->_util->getTimeKey(); } +void Game_v2::collisionsBlock(void) { + InputDesc descArray[20]; + int16 array[250]; + char count; + int16 collResId; + char *startIP; + int16 curCmd; + int16 cmd; + int16 cmdHigh; + int16 key; + int16 flags; + int16 left; + int16 top; + int16 width; + int16 height; + int16 var_1C; + int16 index; + int16 curEditIndex; + int16 deltaTime; + int16 stackPos2; + int16 descIndex; + int16 timeVal; + int16 offsetIP; + char *str; + int16 i; + int16 counter; + int16 var_24; + int16 var_26; + int16 _collStackPos; + Collision *collPtr; + Collision *collArea; + int16 timeKey; + char *savedIP; + + if (_shouldPushColls) + pushCollisions(0); + + collArea = _collisionAreas; + while (collArea->left != -1) + collArea++; + + _shouldPushColls = 0; + collResId = -1; + + _vm->_global->_inter_execPtr++; + count = *_vm->_global->_inter_execPtr++; + + _handleMouse = _vm->_global->_inter_execPtr[0]; + deltaTime = 1000 * (byte)_vm->_global->_inter_execPtr[1]; + stackPos2 = (byte)_vm->_global->_inter_execPtr[3]; + descIndex = (byte)_vm->_global->_inter_execPtr[4]; + + if ((stackPos2 != 0) || (descIndex != 0)) + deltaTime /= 100; + + timeVal = deltaTime; + _vm->_global->_inter_execPtr += 6; + + startIP = _vm->_global->_inter_execPtr; + WRITE_VAR(16, 0); + + var_1C = 0; + index = 0; + curEditIndex = 0; + + for (curCmd = 0; curCmd < count; curCmd++) { + array[curCmd] = 0; + cmd = *_vm->_global->_inter_execPtr++; + + if ((cmd & 0x40) != 0) { + cmd -= 0x40; + cmdHigh = (byte)*_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr++; + cmdHigh <<= 8; + } else + cmdHigh = 0; + + if ((cmd & 0x80) != 0) { + offsetIP = _vm->_global->_inter_execPtr - (char *) _totFileData; + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + } else { + offsetIP = 0; + left = _vm->_inter->load16(); + top = _vm->_inter->load16(); + width = _vm->_inter->load16(); + height = _vm->_inter->load16(); + } + + if ((_vm->_draw->_renderFlags & 8) && (left != -1)) { + left += _vm->_draw->_backDeltaX; + top += _vm->_draw->_backDeltaY; + } + + if (left != -1) { + _vm->_draw->adjustCoords(0, &left, &top); + if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) { + if (_vm->_draw->_word_2E8E2 != 2) + height &= 0xFFFE; + _vm->_draw->adjustCoords(0, 0, &width); + } else + _vm->_draw->adjustCoords(0, &height, &width); + } + + cmd &= 0x7f; + debugC(1, DEBUG_COLLISIONS, "collisionsBlock(%d)", cmd); + + switch(cmd) { + case 0: + _vm->_global->_inter_execPtr += 6; + startIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + key = curCmd + 0xA000; + + addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + cmd + cmdHigh, key, startIP - (char *)_totFileData, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + + if (key <= 150) + _collisionAreas[key].field_12 = offsetIP; + break; + + case 1: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16(); + + startIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + if (key == 0) + key = curCmd + 0xa000; + + addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + (flags << 4) + cmd + cmdHigh, key, startIP - (char *)_totFileData, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + + if (key <= 150) + _collisionAreas[key].field_12 = offsetIP; + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + _vm->_util->waitKey(); + var_1C = 1; + key = _vm->_parse->parseVarIndex(); + descArray[index].fontIndex = _vm->_inter->load16(); + descArray[index].backColor = *_vm->_global->_inter_execPtr++; + descArray[index].frontColor = *_vm->_global->_inter_execPtr++; + + if ((cmd >= 5) && (cmd <= 8)) { + descArray[index].ptr = _vm->_global->_inter_execPtr + 2; + _vm->_global->_inter_execPtr += _vm->_inter->load16();; + } else + descArray[index].ptr = 0; + + if (left == -1) { + if ((cmd & 1) == 0) { + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + } + break; + } + + if ((cmd & 1) == 0) { + addNewCollision(curCmd + 0x8000, left, top, + left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, + top + height - 1, cmd, key, 0, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + } else + addNewCollision(curCmd + 0x8000, left, top, + left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, + top + height - 1, cmd, key, 0, 0); + + index++; + break; + + case 11: + _vm->_global->_inter_execPtr += 6; + for (i = 0; i < 150; i++) { + if ((_collisionAreas[i].id & 0xF000) == 0xE000) { + _collisionAreas[i].id &= 0xBFFF; + _collisionAreas[i].funcEnter = _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcLeave = _vm->_global->_inter_execPtr - (char *) _totFileData; + } + } + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + + case 12: + _vm->_global->_inter_execPtr += 6; + for (i = 0; i < 150; i++) { + if ((_collisionAreas[i].id & 0xF000) == 0xD000) { + _collisionAreas[i].id &= 0xBFFF; + _collisionAreas[i].funcEnter = _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcLeave = _vm->_global->_inter_execPtr - (char *) _totFileData; + } + } + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + break; + + case 20: + collResId = curCmd; + // Fall through to case 2 + + case 2: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16(); + + addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + (flags << 4) + cmdHigh + 2, key, 0, + _vm->_global->_inter_execPtr - (char *)_totFileData); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + + if (key <= 150) + _collisionAreas[key].field_12 = offsetIP; + break; + + case 21: + key = _vm->_inter->load16(); + array[curCmd] = _vm->_inter->load16(); + flags = _vm->_inter->load16() & 3; + + addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + (flags << 4) + cmdHigh + 2, key, + _vm->_global->_inter_execPtr - (char *)_totFileData, 0); + + _vm->_global->_inter_execPtr += 2; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + + if (key <= 150) + _collisionAreas[key].field_12 = offsetIP; + break; + } + } + + _forceHandleMouse = 0; + _vm->_util->waitKey(); + + do { + if (var_1C != 0) { + key = multiEdit(deltaTime, index, &curEditIndex, descArray, + &_activeCollResId, &_activeCollIndex); + + WRITE_VAR(55, curEditIndex); + if (key == 0x1c0d) { + for (i = 0; i < 150; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0xC000) != 0x8000) + continue; + + if ((_collisionAreas[i].flags & 1) != 0) + continue; + + if ((_collisionAreas[i].flags & 0x0f) <= 2) + continue; + + _activeCollResId = _collisionAreas[i].id; + collResId = _collisionAreas[i].id & 0x7fff; + _activeCollIndex = i; + break; + } + break; + } + } else + key = checkCollisions(_handleMouse, -deltaTime, &_activeCollResId, &_activeCollIndex); + + if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff && + (key >> 8) > 1 && (key >> 8) < 12) { + key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00); + } + + if (_activeCollResId == 0) { + if (key != 0) { + for (i = 0; i < 150; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0xC000) != 0x8000) + continue; + + if ((_collisionAreas[i].key == key) || (_collisionAreas[i].key == 0x7fff)) { + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + + if (_activeCollResId == 0) { + for (i = 0; i < 150; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0xC000) != 0x8000) + continue; + + if ((_collisionAreas[i].key & 0xff00) != 0) + continue; + + if (_collisionAreas[i].key == 0) + continue; + + if ((adjustKey(key & 0xff) == adjustKey(_collisionAreas[i].key)) || + (_collisionAreas[i].key == 0x7fff)) { + _activeCollResId = _collisionAreas[i].id; + _activeCollIndex = i; + break; + } + } + } + } else if (deltaTime != 0) { + if (stackPos2 != 0) { + _collStackPos = 0; + collPtr = _collisionAreas; + + for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { + if ((collPtr->id & 0xF000) != 0x8000) + continue; + + _collStackPos++; + if (_collStackPos != stackPos2) + continue; + + _activeCollResId = collPtr->id; + _activeCollIndex = i; + _vm->_inter->storeMouse(); + if (VAR(16) != 0) + break; + + if ((_activeCollResId & 0xF000) == 0x8000) + WRITE_VAR(16, array[_activeCollResId & 0xFFF]); + else + WRITE_VAR(16, _activeCollResId & 0xFFF); + + if (collPtr->funcLeave != 0) { + timeKey = _vm->_util->getTimeKey(); + collSub(collPtr->funcLeave); + _vm->_inter->animPalette(); + + deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey); + + if (deltaTime < 2) + deltaTime = 2; + } + + if (VAR(16) == 0) + _activeCollResId = 0; + break; + } + } else { + if (descIndex != 0) { + + counter = 0; + for (i = 0, collPtr = collArea; collPtr->left != -1; i++, collPtr++) { + if ((collPtr->id & 0xF000) == 0x8000) + if (++counter == descIndex) { + _activeCollResId = collPtr->id; + _activeCollIndex = i; + break; + } + } + + } else { + + for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { + if ((collPtr->id & 0xF000) == 0x8000) { + _activeCollResId = collPtr->id; + _activeCollIndex = i; + break; + } + } + if ((_lastCollKey != 0) && (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) + collSub(_collisionAreas[_lastCollAreaIndex].funcLeave); + _lastCollKey = 0; + } + + } + } + } + + if ((_activeCollResId == 0) || (_collisionAreas[_activeCollIndex].funcLeave != 0)) + continue; + + _vm->_inter->storeMouse(); + if ((_activeCollResId & 0xF000) == 0x8000) + WRITE_VAR(16, array[_activeCollResId & 0xFFF]); + else + WRITE_VAR(16, _activeCollResId & 0xFFF); + + if (_collisionAreas[_activeCollIndex].funcEnter != 0) + collSub(_collisionAreas[_activeCollIndex].funcEnter); + + WRITE_VAR(16, 0); + _activeCollResId = 0; + } + while (_activeCollResId == 0 && !_vm->_inter->_terminate && !_vm->_quitRequested); + + if ((_activeCollResId & 0xFFF) == collResId) { + _collStackPos = 0; + var_24 = 0; + var_26 = 1; + for (i = 0; i < 150; i++) { + if (_collisionAreas[i].left == -1) + continue; + + if ((_collisionAreas[i].id & 0xC000) == 0x8000) + continue; + + if ((_collisionAreas[i].flags & 0x0f) < 3) + continue; + + if ((_collisionAreas[i].flags & 0x0f) > 10) + continue; + + if ((_collisionAreas[i].flags & 0x0f) > 8) { + char *ptr; + strcpy(_tempStr, + _vm->_global->_inter_variables + _collisionAreas[i].key); + while ((ptr = strchr(_tempStr, ' ')) != 0) { + _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1); + ptr = strchr(_tempStr, ' '); + } + strcpy(_vm->_global->_inter_variables + _collisionAreas[i].key, _tempStr); + if (_vm->_language == 2) { // loc_16080 + warning("GOB2 Stub! Game_v2::collisionsBlock(), language == 2"); + } + } + + if ((_collisionAreas[i].flags & 0x0f) >= 5 && + (_collisionAreas[i].flags & 0x0f) <= 8) { + str = descArray[var_24].ptr; + + strcpy(_tempStr, _vm->_global->_inter_variables + _collisionAreas[i].key); + + if ((_collisionAreas[i].flags & 0x0f) < 7) + _vm->_util->prepareStr(_tempStr); + + int16 pos = 0; + do { + strcpy(_collStr, str); + pos += strlen(str) + 1; + + str += strlen(str) + 1; + + if ((_collisionAreas[i].flags & 0x0f) < 7) + _vm->_util->prepareStr(_collStr); + + if (strcmp(_tempStr, _collStr) == 0) { + VAR(17)++; + WRITE_VAR(17 + var_26, 1); + break; + } + } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos); + _collStackPos++; + } else { + VAR(17 + var_26) = 2; + } + var_24++; + var_26++; + } + + if (_collStackPos != (int16)VAR(17)) + WRITE_VAR(17, 0); + else + WRITE_VAR(17, 1); + } + + if (_handleMouse == 1) + _vm->_draw->blitCursor(); + + savedIP = 0; + if (!_vm->_inter->_terminate) { + savedIP = (char *)_totFileData + _collisionAreas[_activeCollIndex].funcLeave; + + _vm->_inter->storeMouse(); + if ((_activeCollResId & 0xF000) == 0x8000) + WRITE_VAR(16, array[_activeCollResId & 0xFFF]); + else + WRITE_VAR(16, _activeCollResId & 0xFFF); + } + + for (curCmd = 0; curCmd < count; curCmd++) + freeCollision(curCmd + 0x8000); + + for (i = 0; i < 150; i++) { + if (((_collisionAreas[i].id & 0xF000) == 0xA000) || + ((_collisionAreas[i].id & 0xF000) == 0x9000)) + _collisionAreas[i].id |= 0x4000; + } + + _vm->_global->_inter_execPtr = savedIP; +} + +int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * inpDesc, + int16 *collResId, int16 *collIndex) { + Collision *collArea; + int16 descInd; + int16 key; + int16 found = -1; + int16 i; + void *fontExtraBak; + int16 w2E8E2Bak; + + descInd = 0; + for (i = 0; i < 150; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0xC000) == 0x8000) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key); + + _vm->_draw->_destSpriteX = collArea->left; + _vm->_draw->_destSpriteY = collArea->top; + _vm->_draw->_spriteRight = collArea->right - collArea->left + 1; + _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1; + + _vm->_draw->_destSurface = 21; + + _vm->_draw->_backColor = inpDesc[descInd].backColor; + _vm->_draw->_frontColor = inpDesc[descInd].frontColor; + _vm->_draw->_textToPrint = _tempStr; + _vm->_draw->_transparency = 1; + _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex; + + fontExtraBak = _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData; + w2E8E2Bak = _vm->_draw->_word_2E8E2; + _vm->_draw->_word_2E8E2 = 2; + _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0; + + _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10); + + _vm->_draw->_destSpriteY += ((collArea->bottom - collArea->top + 1) - + _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2; + + _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10); + + _vm->_draw->_word_2E8E2 = w2E8E2Bak; + _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = fontExtraBak; + + descInd++; + } + + for (i = 0; i < 40; i++) { + WRITE_VAR_OFFSET(i * 4 + 0x44, 0); + } + + while (1) { + descInd = 0; + + for (i = 0; i < 150; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0xC000) == 0x8000) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + if (descInd == *pCurPos) { + found = i; + break; + } + + descInd++; + } + + assert(found != -1); + + collArea = &_collisionAreas[found]; + + key = inputArea(collArea->left, collArea->top, + collArea->right - collArea->left + 1, + collArea->bottom - collArea->top + 1, + inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor, + _vm->_global->_inter_variables + collArea->key, + inpDesc[*pCurPos].fontIndex, collArea->flags, &time); + + if (_vm->_inter->_terminate) + return 0; + + switch (key) { + case 0: + if (*collResId == 0) + return 0; + + if ((_collisionAreas[*collIndex].flags & 0x0f) < 3) + return 0; + + if ((_collisionAreas[*collIndex].flags & 0x0f) > 10) + return 0; + + *pCurPos = 0; + for (i = 0; i < 150; i++) { + collArea = &_collisionAreas[i]; + + if (collArea->left == -1) + continue; + + if ((collArea->id & 0xC000) == 0x8000) + continue; + + if ((collArea->flags & 0x0f) < 3) + continue; + + if ((collArea->flags & 0x0f) > 10) + continue; + + if (i == *collIndex) + break; + + pCurPos[0]++; + } + break; + + case 0x3b00: + case 0x3c00: + case 0x3d00: + case 0x3e00: + case 0x3f00: + case 0x4000: + case 0x4100: + case 0x4200: + case 0x4300: + case 0x4400: + return key; + + case 0x1c0d: + + if (index == 1) + return key; + + if (*pCurPos == index - 1) { + *pCurPos = 0; + break; + } + + pCurPos[0]++; + break; + + case 0x5000: + if (index - 1 > *pCurPos) + pCurPos[0]++; + break; + + case 0x4800: + if (*pCurPos > 0) + pCurPos[0]--; + break; + } + } +} + +int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { + Collision *ptr; + int16 i; + + if (resId != 0) + *resId = 0; + + *resIndex = 0; + + ptr = _collisionAreas; + for (i = 0; ptr->left != -1; ptr++, i++) { + if (ptr->id & 0x4000) + continue; + + if (all) { + if ((ptr->flags & 0xf) > 1) + continue; + + if ((ptr->flags & 0xf00) != 0) + continue; + + if (_vm->_global->_inter_mouseX < ptr->left + || _vm->_global->_inter_mouseX > ptr->right + || _vm->_global->_inter_mouseY < ptr->top + || _vm->_global->_inter_mouseY > ptr->bottom) + continue; + + if (resId != 0) + *resId = ptr->id; + + *resIndex = i; + return ptr->key; + } else { + if ((ptr->flags & 0xf00) != 0) + continue; + + if ((ptr->flags & 0xf) < 1) + continue; + + if ((ptr->flags & 0xf0) >> 4 != _mouseButtons - 1 + && (ptr->flags & 0xf0) >> 4 != 2) + continue; + + if (_vm->_global->_inter_mouseX < ptr->left + || _vm->_global->_inter_mouseX > ptr->right + || _vm->_global->_inter_mouseY < ptr->top + || _vm->_global->_inter_mouseY > ptr->bottom) + continue; + + if (resId != 0) + *resId = ptr->id; + *resIndex = i; + if (((ptr->flags & 0xf) == 1) || ((ptr->flags & 0xf) == 2)) + return ptr->key; + return 0; + } + } + + if (_mouseButtons != 1 && all == 0) + return 0x11b; + + return 0; +} + } // End of namespace Gob diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index b5f3d9bfa4..1f18c30d43 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -279,7 +279,9 @@ void Inter::callSub(int16 retFlag) { _terminate = true; } -void Inter::initControlVars(void) { +void Inter::initControlVars(char full) { + int i; + *_nestLevel = 0; *_breakFromLevel = -1; @@ -287,8 +289,12 @@ void Inter::initControlVars(void) { _breakFlag = false; _terminate = false; - _animPalDir[0] = 0; - _soundEndTimeKey = 0; + + if (full == 1) { + for (i = 0; i < 8; i++) + _animPalDir[i] = 0; + _soundEndTimeKey = 0; + } } void Inter::renewTimeInVars(void) { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 1a4cba9d78..7a365a5544 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -57,7 +57,7 @@ public: void storeKey(int16 key); void checkSwitchTable(char **ppExec); void callSub(int16 retFlag); - void initControlVars(void); + void initControlVars(char full); void renewTimeInVars(void); void manipulateMap(int16 xPos, int16 yPos, int16 item); virtual int16 loadSound(int16 slot) = 0; @@ -317,6 +317,7 @@ protected: void o2_stub0x80(void); void o2_stub0x82(void); void o2_stub0x85(void); + bool o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_createSprite(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag); diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 2e14691537..5a692e9aaf 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -526,7 +526,7 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o1_waitEndPlay), OPCODE(o1_playComposition), OPCODE(o1_getFreeMem), - OPCODE(o1_checkData), + OPCODE(o2_checkData), /* 40 */ {NULL, ""}, OPCODE(o1_prepareStr), @@ -1180,6 +1180,23 @@ void Inter_v2::loadMult(void) { } } +bool Inter_v2::o2_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); + WRITE_VAR(16, (uint32) _vm->_dataio->getDataSize(_vm->_global->_inter_resStr)); + } else + WRITE_VAR(16, (uint32) -1); + return false; +} + bool Inter_v2::o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) { _vm->_snd->stopSound(_vm->_parse->parseValExpr()); _soundEndTimeKey = 0; diff --git a/engines/gob/mult.h b/engines/gob/mult.h index cec716d321..c5e252cd40 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -310,7 +310,10 @@ public: int16 animIndices[10]; int16 animLoaded[10]; int16 animKeysFrames[4]; - int16 someKeysFrames[4]; + int16 animKeysStartFrames[4]; + int16 animKeysStopFrames[4]; + int16 animKeysIndices[4][4]; + int8 animDirection; int16 textKeysCount; Mult_TextKey *textKeys; @@ -323,13 +326,11 @@ public: int16 frameRate; Video::Color fadePal[5][16]; - int16 field_124[4][4]; // Not sure here either - int16 palAnimIndices[4]; // Not sure here either + int16 field_124[4][4]; + int16 palAnimIndices[4]; // Not sure here + // TODO: Use this one instead of _frameStart int16 frameStart; - int8 field_156; - int16 field_157[4]; - int16 field_15F[4][4]; int16 field_17F[4][4]; int16 someKeysCount[4]; diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index e425b4fe9a..ff5ee59757 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -45,6 +45,7 @@ Mult_v2::Mult_v2(GobEngine *vm) : Mult_v1(vm) { _renderData2 = 0; _multData2 = 0; + _frameStart = 0; // Temporarily to sync _frameStart and _multData2->frameStart for (i = 0; i < 8; i++) _multDatas[i] = 0; } @@ -76,6 +77,7 @@ void Mult_v2::loadMult(int16 resId) { index = (resId & 0x8000) ? *_vm->_global->_inter_execPtr++ : 0; _multData2 = new Mult_Data; + _frameStart = 0; // Temporarily to sync _frameStart and _multData2->frameStart memset(_multData2, 0, sizeof(Mult_Data)); _multDatas[index] = _multData2; @@ -90,6 +92,7 @@ void Mult_v2::loadMult(int16 resId) { _multData2->sndSlotsCount = 0; _multData2->frameStart = 0; + _frameStart = 0; extData = _vm->_game->loadExtData(resId, 0, 0); Common::MemoryReadStream data((byte *) extData, 4294967295U); @@ -137,7 +140,7 @@ void Mult_v2::loadMult(int16 resId) { _multData2->someKeysIndices[i] = -1; for (j = 0; j < 4; j++) { - _multData2->field_15F[i][j] = 0; + _multData2->animKeysIndices[i][j] = 0; _multData2->field_17F[i][j] = 0; } @@ -242,7 +245,7 @@ void Mult_v2::loadMult(int16 resId) { if (_vm->_game->_totFileData[0x29] >= 51) { size = data.readSint16LE(); _multData2->somepointer10 = new char[size * 20]; -// data.read(_multData2->somepointer09 /*???*/, size * 20); + // According to the original asm, these bytes are written into _multData2->somepointer09! data.read(_multData2->somepointer10, size * 20); size = _vm->_inter->load16(); if (size > 0) { @@ -277,6 +280,7 @@ void Mult_v2::setMultData(uint16 multindex) { debugC(4, DEBUG_GAMEFLOW, "Switching to mult %d", multindex); _multData2 = _multDatas[multindex]; + _frameStart = _multData2->frameStart; // Temporarily to sync _frameStart and _multData2->frameStart } void Mult_v2::multSub(uint16 multindex) { @@ -295,6 +299,7 @@ void Mult_v2::multSub(uint16 multindex) { debugC(4, DEBUG_GAMEFLOW, "Sub mult %d", multindex); _multData2 = _multDatas[multindex]; + _frameStart = _multData2->frameStart; // Temporarily to sync _frameStart and _multData2->frameStart if (_multData2 == 0) { _vm->_parse->parseValExpr(); @@ -315,9 +320,9 @@ void Mult_v2::multSub(uint16 multindex) { if (flags & 0x400) { flags = 0x400; - _multData2->field_156 = -1; + _multData2->animDirection = -1; } else { - _multData2->field_156 = 1; + _multData2->animDirection = 1; flags &= 0x7F; } @@ -327,7 +332,7 @@ void Mult_v2::multSub(uint16 multindex) { } expr = _vm->_parse->parseValExpr(); _multData2->animKeysFrames[index] = expr; - _multData2->someKeysFrames[index] = expr; + _multData2->animKeysStartFrames[index] = expr; WRITE_VAR(18 + index, expr); if (expr == -1) { @@ -337,22 +342,22 @@ void Mult_v2::multSub(uint16 multindex) { _objects[_multData2->field_124[index][i]].pAnimData->animType = _objects[_multData2->field_124[index][i]].pAnimData->field_17; } else { - if (_multData2->field_156 == 1) { - _multData2->field_157[index] = 32000; + if (_multData2->animDirection == 1) { + _multData2->animKeysStopFrames[index] = 32000; for (i = 0; i < _multData2->textKeysCount; i++) { textFrame = _multData2->textKeys[i].frame; - if ((textFrame > _multData2->someKeysFrames[index]) && - (textFrame < _multData2->field_157[index])) { - _multData2->field_157[index] = textFrame; + if ((textFrame > _multData2->animKeysStartFrames[index]) && + (textFrame < _multData2->animKeysStopFrames[index])) { + _multData2->animKeysStopFrames[index] = textFrame; } } } else { - _multData2->field_157[index] = 0; + _multData2->animKeysStopFrames[index] = 0; for (i = 0; i < _multData2->textKeysCount; i++) { textFrame = _multData2->textKeys[i].frame; - if ((textFrame < _multData2->someKeysFrames[index]) && - (textFrame > _multData2->field_157[index])) { - _multData2->field_157[index] = textFrame; + if ((textFrame < _multData2->animKeysStartFrames[index]) && + (textFrame > _multData2->animKeysStopFrames[index])) { + _multData2->animKeysStopFrames[index] = textFrame; } } } @@ -365,27 +370,27 @@ void Mult_v2::multSub(uint16 multindex) { } for (i = 0; i < 4; i++) { - _multData2->field_15F[index][i] = 0; + _multData2->animKeysIndices[index][i] = 0; for (j = 0; j < _multData2->animKeysCount[i]; j++) { - if (_multData2->animKeys[i][j].frame >= _multData2->someKeysFrames[index]) - _multData2->field_15F[index][i] = j; + if (_multData2->animKeys[i][j].frame == _multData2->animKeysStartFrames[index]) + _multData2->animKeysIndices[index][i] = j; } } - if (_multData2->field_156 == -1) { // loc_60CF + if (_multData2->animDirection == -1) { // loc_60CF warning("Mult_v2::multSub(), someKeys and someKeysIndices"); } for (i = 0; i < 4; i++) { _multData2->field_17F[index][i] = 0; for (j = 0; j < _multData2->someKeysCount[i]; j++) { - if (_multData2->field_156 == 1) { - if (_multData2->someKeys[i][j].frame >= _multData2->someKeysFrames[index]) { + if (_multData2->animDirection == 1) { + if (_multData2->someKeys[i][j].frame >= _multData2->animKeysStartFrames[index]) { _multData2->field_17F[index][i] = j; break; } } else { - if (_multData2->someKeys[i][j].frame >= _multData2->field_157[index]) { + if (_multData2->someKeys[i][j].frame >= _multData2->animKeysStopFrames[index]) { _multData2->field_17F[index][i] = j; break; } @@ -431,8 +436,6 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, delete[] _objects; if (_orderArray) delete[] _orderArray; -/* if (_renderData) - delete[] _renderData;*/ if (_renderData2) delete[] _renderData2; @@ -441,8 +444,6 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, _orderArray = new int8[_objCount]; memset(_orderArray, 0, _objCount * sizeof(int8)); -/* _renderData = new int16[9 * _objCount]; - memset(_renderData, 0, _objCount * 9 * sizeof(int16));*/ _renderData2 = new Mult_Object*[_objCount]; memset(_renderData2, 0, _objCount * sizeof(Mult_Object*)); @@ -580,7 +581,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, WRITE_VAR(57, (uint32)-1); } else { - WRITE_VAR(57, _frame - 1 - _frameStart); + WRITE_VAR(57, _frame - 1 - _multData2->frameStart); } } @@ -696,6 +697,7 @@ void Mult_v2::drawText(char *pStop, char *pStopNoClear) { *pStop = 0; } else if (cmd == 1) { *pStopNoClear = 1; + _multData2->frameStart = 0; _frameStart = 0; } else if (cmd == 3) { *pStop = 0; @@ -900,14 +902,14 @@ void Mult_v2::sub_62DD(int16 index) { for (i = 0; i < 4; i++) { if (_multData2->field_124[index][i] != -1) { - for (j = _multData2->field_15F[index][i]; j < _multData2->animKeysCount[i]; j++) { + for (j = _multData2->animKeysIndices[index][i]; j < _multData2->animKeysCount[i]; j++) { if ((i >= 4) || (j >= _multData2->animKeysCount[i])) continue; animKey = &_multData2->animKeys[i][j]; if (animKey->frame == frame) { animObj = &_objects[_multData2->field_124[index][i]]; if (animKey->layer > -1) { - _multData2->field_15F[index][i] = j; + _multData2->animKeysIndices[index][i] = j; (*animObj->pPosX) = animKey->posX; (*animObj->pPosY) = animKey->posY; animObj->pAnimData->frame = 0; @@ -947,9 +949,9 @@ void Mult_v2::sub_62DD(int16 index) { _multData2->someKeysIndices[1] = -1; _multData2->someKeysIndices[2] = -1; _multData2->someKeysIndices[3] = -1; - if ((_multData2->field_156 == 1) || (someKey2->field_2 == 1)) + if ((_multData2->animDirection == 1) || (someKey2->field_2 == 1)) _multData2->someKeysIndices[i] = j; - else if (_multData2->field_157[index] == frame) + else if (_multData2->animKeysStopFrames[index] == frame) _multData2->someKeysIndices[i] = -1; else _multData2->someKeysIndices[i] = j - 1; @@ -962,7 +964,7 @@ void Mult_v2::sub_62DD(int16 index) { if (_multData2->someKeysIndices[i] != -1) { /* int arg3 = frame - _multData2->someKeys[i][_multData2->someKeysIndices[i]].field_0; - int arg2 = _multData2->field_156; + int arg2 = _multData2->animDirection; if ((arg2 != 1) && (--arg3 > 0)) arg3 = 0; int arg1 = _multData2->someKeys[i][_multData2->someKeysIndices[i]]; @@ -976,7 +978,7 @@ void Mult_v2::sub_62DD(int16 index) { doSoundAnim(0, frame); WRITE_VAR(22, frame); - if (_multData2->field_157[index] == frame) { + if (_multData2->animKeysStopFrames[index] == frame) { _multData2->someKeysIndices[0] = -1; _multData2->someKeysIndices[1] = -1; _multData2->someKeysIndices[2] = -1; @@ -986,7 +988,7 @@ void Mult_v2::sub_62DD(int16 index) { if ((_multData2->field_124[index][i] != -1) && (_multData2->field_124[index][i] != 1024)) _objects[_multData2->field_124[index][i]].pAnimData->animType = _objects[_multData2->field_124[index][i]].pAnimData->field_17; - } else if(_multData2->field_156 == 1) + } else if(_multData2->animDirection == 1) frame++; else frame--; @@ -1004,6 +1006,7 @@ void Mult_v2::sub_6A35(void) { for (i = 0; i < 8; i++) if (_multDatas[i] != 0) { _multData2 = _multDatas[i]; + _frameStart = _multData2->frameStart; // Temporarily to sync _frameStart and _multData2->frameStart for (j = 0; j < 4; j++) sub_62DD(j); } @@ -1404,6 +1407,7 @@ void Mult_v2::freeMultKeys(void) { delete _multData2; _multData2 = 0; + _frameStart = 0; // Temporarily to sync _frameStart and _multData2->frameStart } } // End of namespace Gob |