// Load a value according to the operation void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) { int16 dimCount; uint16 temp; int16 temp2; int16 offset; int16 dim; byte *arrDescPtr; int32 prevPrevVal; int32 prevVal; int32 curVal; switch (operation) { case OP_ARRAY_INT8: case OP_ARRAY_INT32: case OP_ARRAY_INT16: case OP_ARRAY_STR: *stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; temp = _vm->_game->_script->readInt16(); dimCount = _vm->_game->_script->readByte(); arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos(); _vm->_game->_script->skip(dimCount); offset = 0; for (dim = 0; dim < dimCount; dim++) { temp2 = parseValExpr(OP_END_MARKER); offset = offset * arrDescPtr[dim] + temp2; } if (operation == OP_ARRAY_INT8) *stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset); else if (operation == OP_ARRAY_INT32) *stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4); else if (operation == OP_ARRAY_INT16) *stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2); else if (operation == OP_ARRAY_STR) { *stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8( varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), kInterVar); if (_vm->_game->_script->peekByte() == 13) { _vm->_game->_script->skip(1); temp2 = parseValExpr(OP_END_MARKER); *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2); } } break; case OP_LOAD_VAR_INT16: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 2); break; case OP_LOAD_VAR_INT8: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readUint16()); break; case OP_LOAD_IMM_INT32: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = _vm->_game->_script->readInt32(); break; case OP_LOAD_IMM_INT16: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = _vm->_game->_script->readInt16(); break; case OP_LOAD_IMM_INT8: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = _vm->_game->_script->readInt8(); break; case OP_LOAD_IMM_STR: *stackFrame.opers = OP_LOAD_IMM_STR; *stackFrame.values = encodePtr((byte *)_vm->_game->_script->readString(), kExecPtr); break; case OP_LOAD_VAR_INT32: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readUint16() * 4); break; case OP_LOAD_VAR_INT32_AS_INT16: *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 4); break; case OP_LOAD_VAR_STR: *stackFrame.opers = OP_LOAD_IMM_STR; temp = _vm->_game->_script->readUint16() * 4; *stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar); if (_vm->_game->_script->peekByte() == 13) { _vm->_game->_script->skip(1); temp += parseValExpr(OP_END_MARKER); *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = READ_VARO_UINT8(varBase + temp); } break; case OP_FUNC: operation = _vm->_game->_script->readByte(); parseExpr(OP_END_EXPR, 0); switch (operation) { case FUNC_SQRT1: case FUNC_SQRT2: case FUNC_SQRT3: curVal = 1; prevVal = 1; do { prevPrevVal = prevVal; prevVal = curVal; curVal = (curVal + _resultInt / curVal) / 2; } while ((curVal != prevVal) && (curVal != prevPrevVal)); _resultInt = curVal; break; case FUNC_SQR: _resultInt = _resultInt * _resultInt; break; case FUNC_ABS: if (_resultInt < 0) _resultInt = -_resultInt; break; case FUNC_RAND: _resultInt = _vm->_util->getRandom(_resultInt); break; } *stackFrame.opers = OP_LOAD_IMM_INT16; *stackFrame.values = _resultInt; break; } }
void Map_v2::loadMapObjects(const char *avjFile) { uint8 wayPointsCount; uint16 var; int16 id; int16 mapWidth, mapHeight; int16 tmp; byte *variables; uint32 tmpPos; uint32 passPos; var = _vm->_game->_script->readVarIndex(); variables = _vm->_inter->_variables->getAddressOff8(var); id = _vm->_game->_script->readInt16(); if (((uint16) id) >= 65520) { switch ((uint16) id) { case 65530: for (int i = 0; i < _mapWidth * _mapHeight; i++) _passMap[i] -= READ_VARO_UINT8(var + i); break; case 65531: for (int i = 0; i < _mapWidth * _mapHeight; i++) _passMap[i] += READ_VARO_UINT8(var + i); break; case 65532: for (int i = 0; i < _mapWidth * _mapHeight; i++) WRITE_VARO_UINT8(var + i, 0x00); break; case 65533: { int index = READ_VARO_UINT16(var); // _vm->_mult->_objects[index].field_6E = 0; // _vm->_mult->_objects[index].field_6A = variables; warning("Map_v2::loadMapObjects(): ID == 65533 (%d)", index); break; } case 65534: _tilesWidth = READ_VARO_UINT8(var); _tilesHeight = READ_VARO_UINT8(var + 1); _mapWidth = READ_VARO_UINT8(var + 2); _mapHeight = READ_VARO_UINT8(var + 3); _mapUnknownBool = READ_VARO_UINT8(var + 4) ? true : false; if (_mapUnknownBool) warning("Map_v2::loadMapObjects(): _mapUnknownBool == true"); break; case 65535: _passMap = (int8 *)_vm->_inter->_variables->getAddressOff8(var); break; default: warning("Map_v2::loadMapObjects(): ID == %d", (uint16) id); break; } return; } Resource *resource = _vm->_game->_resources->getResource(id); if (!resource) return; Common::SeekableReadStream &mapData = *resource->stream(); _mapVersion = mapData.readByte(); if (_mapVersion == 4) { _screenWidth = 640; _screenHeight = 400; } else if (_mapVersion == 3) { _passWidth = 65; _screenWidth = 640; _screenHeight = 200; } else { _passWidth = 40; _screenWidth = 320; _screenHeight = 200; } _wayPointCount = mapData.readByte(); _tilesWidth = mapData.readSint16LE(); _tilesHeight = mapData.readSint16LE(); _bigTiles = !(_tilesHeight & 0xFF00); _tilesHeight &= 0xFF; if (_mapVersion == 4) { _screenWidth = mapData.readSint16LE(); _screenHeight = mapData.readSint16LE(); } _mapWidth = _screenWidth / _tilesWidth; _mapHeight = _screenHeight / _tilesHeight; passPos = mapData.pos(); mapData.skip(_mapWidth * _mapHeight); if (resource->getData()[0] == 1) wayPointsCount = _wayPointCount = 40; else wayPointsCount = _wayPointCount == 0 ? 1 : _wayPointCount; delete[] _wayPoints; _wayPoints = new WayPoint[wayPointsCount]; for (int i = 0; i < _wayPointCount; i++) { _wayPoints[i].x = mapData.readSByte(); _wayPoints[i].y = mapData.readSByte(); _wayPoints[i].notWalkable = mapData.readSByte(); } if (_mapVersion == 4) { _mapWidth = VAR(17); _passWidth = _mapWidth; } // In the original asm, this writes byte-wise into the variables-array tmpPos = mapData.pos(); mapData.seek(passPos); if ((variables != 0) && (variables != _vm->_inter->_variables->getAddressOff8(0))) { _passMap = (int8 *)variables; mapHeight = _screenHeight / _tilesHeight; mapWidth = _screenWidth / _tilesWidth; for (int i = 0; i < mapHeight; i++) { for (int j = 0; j < mapWidth; j++) setPass(j, i, mapData.readSByte()); _vm->_inter->_variables->getAddressOff8(var + i * _passWidth); } } mapData.seek(tmpPos); tmp = mapData.readSint16LE(); mapData.skip(tmp * 14); tmp = mapData.readSint16LE(); mapData.skip(tmp * 14 + 28); tmp = mapData.readSint16LE(); mapData.skip(tmp * 14); _vm->_goblin->_gobsCount = tmp; for (int i = 0; i < _vm->_goblin->_gobsCount; i++) loadGoblinStates(mapData, i); _vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16(); for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); delete resource; }