bool AdResponseBox::loadFile(const char *filename) { char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename); if (buffer == nullptr) { _gameRef->LOG(0, "AdResponseBox::LoadFile failed for file '%s'", filename); return STATUS_FAILED; } bool ret; setFilename(filename); if (DID_FAIL(ret = loadBuffer(buffer, true))) { _gameRef->LOG(0, "Error parsing RESPONSE_BOX file '%s'", filename); } delete[] buffer; return ret; }
bool AdScaleLevel::loadFile(const char *filename) { byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); if (buffer == nullptr) { _gameRef->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename); return STATUS_FAILED; } bool ret; setFilename(filename); if (DID_FAIL(ret = loadBuffer(buffer, true))) { _gameRef->LOG(0, "Error parsing SCALE_LEVEL file '%s'", filename); } delete[] buffer; return ret; }
void BasePersistenceManager::getSaveStateDesc(int slot, SaveStateDescriptor &desc) { Common::String filename = getFilenameForSlot(slot); debugC(kWintermuteDebugSaveGame, "Trying to list savegame %s in slot %d", filename.c_str(), slot); if (DID_FAIL(readHeader(filename))) { debugC(kWintermuteDebugSaveGame, "getSavedDesc(%d) - Failed for %s", slot, filename.c_str()); return; } desc.setSaveSlot(slot); desc.setDescription(_savedDescription); desc.setDeletableFlag(true); desc.setWriteProtectedFlag(false); int thumbSize = 0; byte *thumbData = nullptr; if (_scummVMThumbSize > 0) { thumbSize = _scummVMThumbSize; thumbData = _scummVMThumbnailData; } else if (_thumbnailDataSize > 0) { thumbSize = _thumbnailDataSize; thumbData = _thumbnailData; } if (thumbSize > 0) { Common::MemoryReadStream thumbStream(thumbData, thumbSize, DisposeAfterUse::NO); Graphics::BitmapDecoder bmpDecoder; if (bmpDecoder.loadStream(thumbStream)) { const Graphics::Surface *bmpSurface = bmpDecoder.getSurface(); TransparentSurface *scaleableSurface = new TransparentSurface(*bmpSurface, false); Graphics::Surface *scaled = scaleableSurface->scale(kThumbnailWidth, kThumbnailHeight2); Graphics::Surface *thumb = scaled->convertTo(g_system->getOverlayFormat()); desc.setThumbnail(thumb); delete scaleableSurface; scaled->free(); delete scaled; } } desc.setSaveDate(_savedTimestamp.tm_year, _savedTimestamp.tm_mon, _savedTimestamp.tm_mday); desc.setSaveTime(_savedTimestamp.tm_hour, _savedTimestamp.tm_min); desc.setPlayTime(0); }
bool BasePersistenceManager::initLoad(const Common::String &filename) { if (DID_FAIL(readHeader(filename))) { cleanup(); return STATUS_FAILED; } _saving = false; if (_savedName == "" || scumm_stricmp(_savedName.c_str(), _gameRef->getName()) != 0) { debugC(kWintermuteDebugSaveGame, "ERROR: Saved game name doesn't match current game"); cleanup(); return STATUS_FAILED; } // if save is newer version than we are, fail if (_savedVerMajor > DCGF_VER_MAJOR || (_savedVerMajor == DCGF_VER_MAJOR && _savedVerMinor > DCGF_VER_MINOR) || (_savedVerMajor == DCGF_VER_MAJOR && _savedVerMinor == DCGF_VER_MINOR && _savedVerBuild > DCGF_VER_BUILD) ) { debugC(kWintermuteDebugSaveGame, "ERROR: Saved game version is newer than current game"); debugC(kWintermuteDebugSaveGame, "ERROR: Expected %d.%d.%d got %d.%d.%d", DCGF_VER_MAJOR, DCGF_VER_MINOR, DCGF_VER_BUILD, _savedVerMajor, _savedVerMinor, _savedVerBuild); cleanup(); return STATUS_FAILED; } // if save is older than the minimal version we support if (_savedVerMajor < SAVEGAME_VER_MAJOR || (_savedVerMajor == SAVEGAME_VER_MAJOR && _savedVerMinor < SAVEGAME_VER_MINOR) || (_savedVerMajor == SAVEGAME_VER_MAJOR && _savedVerMinor == SAVEGAME_VER_MINOR && _savedVerBuild < SAVEGAME_VER_BUILD) ) { debugC(kWintermuteDebugSaveGame, "ERROR: Saved game is too old and cannot be used by this version of game engine"); debugC(kWintermuteDebugSaveGame, "ERROR: Expected %d.%d.%d got %d.%d.%d", DCGF_VER_MAJOR, DCGF_VER_MINOR, DCGF_VER_BUILD, _savedVerMajor, _savedVerMinor, _savedVerBuild); cleanup(); return STATUS_FAILED; } return STATUS_OK; }
bool AdActor::mergeAnims(const char *animsFilename) { TOKEN_TABLE_START(commands) TOKEN_TABLE(ANIMATION) TOKEN_TABLE_END byte *fileBuffer = BaseFileManager::getEngineInstance()->readWholeFile(animsFilename); if (fileBuffer == nullptr) { _gameRef->LOG(0, "AdActor::MergeAnims failed for file '%s'", animsFilename); return STATUS_FAILED; } byte *buffer = fileBuffer; byte *params; int cmd; BaseParser parser; bool ret = STATUS_OK; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_ANIMATION: { AdSpriteSet *anim = new AdSpriteSet(_gameRef, this); if (!anim || DID_FAIL(anim->loadBuffer(params, false))) { cmd = PARSERR_GENERIC; ret = STATUS_FAILED; } else { _anims.add(anim); } } break; } } delete[] fileBuffer; return ret; }
bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint32 timerDelta) { if (!particle) { return STATUS_FAILED; } if (_sprites.size() == 0) { return STATUS_FAILED; } int posX = BaseUtils::randomInt(_posX, _posX + _width); int posY = BaseUtils::randomInt(_posY, _posY + _height); float posZ = BaseUtils::randomFloat(0.0f, 100.0f); float velocity; if (_velocityZBased) { velocity = _velocity1 + posZ * (_velocity2 - _velocity1) / 100; } else { velocity = BaseUtils::randomFloat(_velocity1, _velocity2); } float scale; if (_scaleZBased) { scale = _scale1 + posZ * (_scale2 - _scale1) / 100; } else { scale = BaseUtils::randomFloat(_scale1, _scale2); } int lifeTime; if (_lifeTimeZBased) { lifeTime = (int)(_lifeTime2 - posZ * (_lifeTime2 - _lifeTime1) / 100); } else { lifeTime = BaseUtils::randomInt(_lifeTime1, _lifeTime2); } float angle = BaseUtils::randomAngle(_angle1, _angle2); int spriteIndex = BaseUtils::randomInt(0, _sprites.size() - 1); float rotation = BaseUtils::randomAngle(_rotation1, _rotation2); float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2); float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2); if (!BasePlatform::isRectEmpty(&_border)) { int thicknessLeft = (int)(_borderThicknessLeft - (float)_borderThicknessLeft * posZ / 100.0f); int thicknessRight = (int)(_borderThicknessRight - (float)_borderThicknessRight * posZ / 100.0f); int thicknessTop = (int)(_borderThicknessTop - (float)_borderThicknessTop * posZ / 100.0f); int thicknessBottom = (int)(_borderThicknessBottom - (float)_borderThicknessBottom * posZ / 100.0f); particle->_border = _border; particle->_border.left += thicknessLeft; particle->_border.right -= thicknessRight; particle->_border.top += thicknessTop; particle->_border.bottom -= thicknessBottom; } Vector2 vecPos((float)posX, (float)posY); Vector2 vecVel(0, velocity); Matrix4 matRot; matRot.rotationZ(Common::deg2rad(BaseUtils::normalizeAngle(angle - 180))); matRot.transformVector2(vecVel); if (_alphaTimeBased) { particle->_alpha1 = _alpha1; particle->_alpha2 = _alpha2; } else { int alpha = BaseUtils::randomInt(_alpha1, _alpha2); particle->_alpha1 = alpha; particle->_alpha2 = alpha; } particle->_creationTime = currentTime; particle->_pos = vecPos; particle->_posZ = posZ; particle->_velocity = vecVel; particle->_scale = scale; particle->_lifeTime = lifeTime; particle->_rotation = rotation; particle->_angVelocity = angVelocity; particle->_growthRate = growthRate; particle->_exponentialGrowth = _exponentialGrowth; particle->_isDead = DID_FAIL(particle->setSprite(_sprites[spriteIndex])); particle->fadeIn(currentTime, _fadeInTime); if (particle->_isDead) { return STATUS_FAILED; } else { return STATUS_OK; } }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdResponseBox::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(RESPONSE_BOX) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(FONT_HOVER) TOKEN_TABLE(FONT) TOKEN_TABLE(AREA) TOKEN_TABLE(HORIZONTAL) TOKEN_TABLE(SPACING) TOKEN_TABLE(WINDOW) TOKEN_TABLE(CURSOR) TOKEN_TABLE(TEXT_ALIGN) TOKEN_TABLE(VERTICAL_ALIGN) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_RESPONSE_BOX) { _gameRef->LOG(0, "'RESPONSE_BOX' keyword expected."); return STATUS_FAILED; } buffer = params; } while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_WINDOW: delete _window; _window = new UIWindow(_gameRef); if (!_window || DID_FAIL(_window->loadBuffer(params, false))) { delete _window; _window = nullptr; cmd = PARSERR_GENERIC; } else if (_shieldWindow) { _shieldWindow->_parent = _window; } break; case TOKEN_FONT: if (_font) { _gameRef->_fontStorage->removeFont(_font); } _font = _gameRef->_fontStorage->addFont((char *)params); if (!_font) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_HOVER: if (_fontHover) { _gameRef->_fontStorage->removeFont(_fontHover); } _fontHover = _gameRef->_fontStorage->addFont((char *)params); if (!_fontHover) { cmd = PARSERR_GENERIC; } break; case TOKEN_AREA: parser.scanStr((char *)params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom); break; case TOKEN_HORIZONTAL: parser.scanStr((char *)params, "%b", &_horizontal); break; case TOKEN_TEXT_ALIGN: if (scumm_stricmp((char *)params, "center") == 0) { _align = TAL_CENTER; } else if (scumm_stricmp((char *)params, "right") == 0) { _align = TAL_RIGHT; } else { _align = TAL_LEFT; } break; case TOKEN_VERTICAL_ALIGN: if (scumm_stricmp((char *)params, "top") == 0) { _verticalAlign = VAL_TOP; } else if (scumm_stricmp((char *)params, "center") == 0) { _verticalAlign = VAL_CENTER; } else { _verticalAlign = VAL_BOTTOM; } break; case TOKEN_SPACING: parser.scanStr((char *)params, "%d", &_spacing); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = nullptr; cmd = PARSERR_GENERIC; } break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in RESPONSE_BOX definition"); return STATUS_FAILED; } if (_window) { for (uint32 i = 0; i < _window->_widgets.size(); i++) { if (!_window->_widgets[i]->_listenerObject) { _window->_widgets[i]->setListener(this, _window->_widgets[i], 0); } } } return STATUS_OK; }
int WintermuteEngine::init() { BaseEngine::createInstance(_targetName, _gameDescription->language); _game = new AdGame(_targetName); if (!_game) { return 1; } BaseEngine::instance().setGameRef(_game); BasePlatform::initialize(_game, 0, NULL); bool windowedMode = !ConfMan.getBool("fullscreen"); if (ConfMan.hasKey("debug_mode")) { if (ConfMan.getBool("debug_mode")) { _game->DEBUG_DebugEnable("./wme.log"); } } if (ConfMan.hasKey("show_fps")) { _game->_debugShowFPS = ConfMan.getBool("show_fps"); } else { _game->_debugShowFPS = false; } if (ConfMan.hasKey("disable_smartcache")) { _game->_smartCache = ConfMan.getBool("disable_smartcache"); } else { _game->_smartCache = true; } if (!_game->_smartCache) { _game->LOG(0, "Smart cache is DISABLED"); } // load general game settings _game->initialize1(); // set gameId, for savegame-naming: _game->setGameId(_targetName); if (DID_FAIL(_game->loadSettings("startup.settings"))) { _game->LOG(0, "Error loading game settings."); delete _game; _game = NULL; warning("Some of the essential files are missing. Please reinstall."); return 2; } _game->initialize2(); bool ret; // initialize the renderer ret = _game->_renderer->initRenderer(_game->_settingsResWidth, _game->_settingsResHeight, windowedMode); if (DID_FAIL(ret)) { _game->LOG(ret, "Error initializing renderer. Exiting."); delete _game; _game = NULL; return 3; } _game->initialize3(); // initialize sound manager (non-fatal if we fail) ret = _game->_soundMgr->initialize(); if (DID_FAIL(ret)) { _game->LOG(ret, "Sound is NOT available."); } // load game uint32 dataInitStart = g_system->getMillis(); if (DID_FAIL(_game->loadFile(_game->_settingsGameFile ? _game->_settingsGameFile : "default.game"))) { _game->LOG(ret, "Error loading game file. Exiting."); delete _game; _game = NULL; return false; } _game->_renderer->_ready = true; _game->_miniUpdateEnabled = true; _game->LOG(0, "Engine initialized in %d ms", g_system->getMillis() - dataInitStart); _game->LOG(0, ""); if (ConfMan.hasKey("save_slot")) { int slot = ConfMan.getInt("save_slot"); _game->loadGame(slot); } // all set, ready to go return 0; }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SetSprite ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SetSprite") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); bool setCurrent = false; if (_currentSprite && _currentSprite == _sprite) { setCurrent = true; } delete _sprite; _sprite = nullptr; if (val->isNULL()) { _sprite = nullptr; if (setCurrent) { _currentSprite = nullptr; } stack->pushBool(true); } else { const char *filename = val->getString(); BaseSprite *spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile(filename))) { script->runtimeError("SetSprite method failed for file '%s'", filename); stack->pushBool(false); } else { _sprite = spr; if (setCurrent) { _currentSprite = _sprite; } stack->pushBool(true); } } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSprite ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSprite") == 0) { stack->correctParams(0); if (!_sprite || !_sprite->getFilename()) { stack->pushNULL(); } else { stack->pushString(_sprite->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSpriteObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSpriteObject") == 0) { stack->correctParams(0); if (!_sprite) { stack->pushNULL(); } else { stack->pushNative(_sprite, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // AddTalkSprite ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "AddTalkSprite") == 0) { stack->correctParams(2); const char *filename = stack->pop()->getString(); bool ex = stack->pop()->getBool(); BaseSprite *spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile(filename))) { stack->pushBool(false); script->runtimeError("AddTalkSprite method failed for file '%s'", filename); } else { if (ex) { _talkSpritesEx.add(spr); } else { _talkSprites.add(spr); } stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RemoveTalkSprite ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RemoveTalkSprite") == 0) { stack->correctParams(2); const char *filename = stack->pop()->getString(); bool ex = stack->pop()->getBool(); bool setCurrent = false; bool setTemp2 = false; if (ex) { for (uint32 i = 0; i < _talkSpritesEx.size(); i++) { if (scumm_stricmp(_talkSpritesEx[i]->getFilename(), filename) == 0) { if (_currentSprite == _talkSpritesEx[i]) { setCurrent = true; } if (_tempSprite2 == _talkSpritesEx[i]) { setTemp2 = true; } delete _talkSpritesEx[i]; _talkSpritesEx.remove_at(i); break; } } } else { for (uint32 i = 0; i < _talkSprites.size(); i++) { if (scumm_stricmp(_talkSprites[i]->getFilename(), filename) == 0) { if (_currentSprite == _talkSprites[i]) { setCurrent = true; } if (_tempSprite2 == _talkSprites[i]) { setTemp2 = true; } delete _talkSprites[i]; _talkSprites.remove_at(i); break; } } } stack->pushBool(true); if (setCurrent) { _currentSprite = _sprite; } if (setTemp2) { _tempSprite2 = _sprite; } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetTalkSprite ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetTalkSprite") == 0) { stack->correctParams(2); const char *filename = stack->pop()->getString(); bool ex = stack->pop()->getBool(); bool setCurrent = false; bool setTemp2 = false; BaseSprite *spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile(filename))) { stack->pushBool(false); script->runtimeError("SetTalkSprite method failed for file '%s'", filename); } else { // delete current if (ex) { for (uint32 i = 0; i < _talkSpritesEx.size(); i++) { if (_talkSpritesEx[i] == _currentSprite) { setCurrent = true; } if (_talkSpritesEx[i] == _tempSprite2) { setTemp2 = true; } delete _talkSpritesEx[i]; } _talkSpritesEx.clear(); } else { for (uint32 i = 0; i < _talkSprites.size(); i++) { if (_talkSprites[i] == _currentSprite) { setCurrent = true; } if (_talkSprites[i] == _tempSprite2) { setTemp2 = true; } delete _talkSprites[i]; } _talkSprites.clear(); } // set new if (ex) { _talkSpritesEx.add(spr); } else { _talkSprites.add(spr); } stack->pushBool(true); if (setCurrent) { _currentSprite = spr; } if (setTemp2) { _tempSprite2 = spr; } } return STATUS_OK; } else { return AdObject::scCallMethod(script, stack, thisStack, name); } }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(INVENTORY_BOX) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(WINDOW) TOKEN_TABLE(EXCLUSIVE) TOKEN_TABLE(ALWAYS_VISIBLE) TOKEN_TABLE(AREA) TOKEN_TABLE(SPACING) TOKEN_TABLE(ITEM_WIDTH) TOKEN_TABLE(ITEM_HEIGHT) TOKEN_TABLE(SCROLL_BY) TOKEN_TABLE(NAME) TOKEN_TABLE(CAPTION) TOKEN_TABLE(HIDE_SELECTED) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd = 2; BaseParser parser; bool alwaysVisible = false; _exclusive = false; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_INVENTORY_BOX) { _gameRef->LOG(0, "'INVENTORY_BOX' keyword expected."); return STATUS_FAILED; } buffer = params; } while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_WINDOW: delete _window; _window = new UIWindow(_gameRef); if (!_window || DID_FAIL(_window->loadBuffer(params, false))) { delete _window; _window = nullptr; cmd = PARSERR_GENERIC; } else { _gameRef->registerObject(_window); } break; case TOKEN_AREA: parser.scanStr((char *)params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom); break; case TOKEN_EXCLUSIVE: parser.scanStr((char *)params, "%b", &_exclusive); break; case TOKEN_HIDE_SELECTED: parser.scanStr((char *)params, "%b", &_hideSelected); break; case TOKEN_ALWAYS_VISIBLE: parser.scanStr((char *)params, "%b", &alwaysVisible); break; case TOKEN_SPACING: parser.scanStr((char *)params, "%d", &_spacing); break; case TOKEN_ITEM_WIDTH: parser.scanStr((char *)params, "%d", &_itemWidth); break; case TOKEN_ITEM_HEIGHT: parser.scanStr((char *)params, "%d", &_itemHeight); break; case TOKEN_SCROLL_BY: parser.scanStr((char *)params, "%d", &_scrollBy); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in INVENTORY_BOX definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading INVENTORY_BOX definition"); return STATUS_FAILED; } if (_exclusive) { delete _closeButton; _closeButton = new UIButton(_gameRef); if (_closeButton) { _closeButton->setName("close"); _closeButton->setListener(this, _closeButton, 0); _closeButton->_parent = _window; } } _visible = alwaysVisible; if (_window) { for (uint32 i = 0; i < _window->_widgets.size(); i++) { if (!_window->_widgets[i]->_listenerObject) { _window->_widgets[i]->setListener(this, _window->_widgets[i], 0); } } } return STATUS_OK; }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool BaseObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SkipTo ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SkipTo") == 0) { stack->correctParams(2); _posX = stack->pop()->getInt(); _posY = stack->pop()->getInt(); afterMove(); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Caption ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Caption") == 0) { stack->correctParams(1); stack->pushString(getCaption(stack->pop()->getInt())); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetCursor") == 0) { stack->correctParams(1); if (DID_SUCCEED(setCursor(stack->pop()->getString()))) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RemoveCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RemoveCursor") == 0) { stack->correctParams(0); if (!_sharedCursors) { delete _cursor; _cursor = nullptr; } else { _cursor = nullptr; } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetCursor") == 0) { stack->correctParams(0); if (!_cursor || !_cursor->getFilename()) { stack->pushNULL(); } else { stack->pushString(_cursor->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetCursorObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetCursorObject") == 0) { stack->correctParams(0); if (!_cursor) { stack->pushNULL(); } else { stack->pushNative(_cursor, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // HasCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "HasCursor") == 0) { stack->correctParams(0); if (_cursor) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetCaption ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetCaption") == 0) { stack->correctParams(2); setCaption(stack->pop()->getString(), stack->pop()->getInt()); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // LoadSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "LoadSound") == 0) { stack->correctParams(1); const char *filename = stack->pop()->getString(); if (DID_SUCCEED(playSFX(filename, false, false))) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PlaySound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PlaySound") == 0) { stack->correctParams(3); const char *filename; bool looping; uint32 loopStart; ScValue *val1 = stack->pop(); ScValue *val2 = stack->pop(); ScValue *val3 = stack->pop(); if (val1->_type == VAL_BOOL) { filename = nullptr; looping = val1->getBool(); loopStart = val2->getInt(); } else { if (val1->isNULL()) { filename = nullptr; } else { filename = val1->getString(); } looping = val2->isNULL() ? false : val2->getBool(); loopStart = val3->getInt(); } if (DID_FAIL(playSFX(filename, looping, true, NULL, loopStart))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PlaySoundEvent ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PlaySoundEvent") == 0) { stack->correctParams(2); const char *filename; const char *eventName; ScValue *val1 = stack->pop(); ScValue *val2 = stack->pop(); if (val2->isNULL()) { filename = nullptr; eventName = val1->getString(); } else { filename = val1->getString(); eventName = val2->getString(); } if (DID_FAIL(playSFX(filename, false, true, eventName))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // StopSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StopSound") == 0) { stack->correctParams(0); if (DID_FAIL(stopSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PauseSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PauseSound") == 0) { stack->correctParams(0); if (DID_FAIL(pauseSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ResumeSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ResumeSound") == 0) { stack->correctParams(0); if (DID_FAIL(resumeSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // IsSoundPlaying ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "IsSoundPlaying") == 0) { stack->correctParams(0); if (_sFX && _sFX->isPlaying()) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetSoundPosition ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetSoundPosition") == 0) { stack->correctParams(1); uint32 time = stack->pop()->getInt(); if (DID_FAIL(setSFXTime(time))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSoundPosition ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSoundPosition") == 0) { stack->correctParams(0); if (!_sFX) { stack->pushInt(0); } else { stack->pushInt(_sFX->getPositionTime()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetSoundVolume ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetSoundVolume") == 0) { stack->correctParams(1); int volume = stack->pop()->getInt(); if (DID_FAIL(setSFXVolume(volume))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSoundVolume ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSoundVolume") == 0) { stack->correctParams(0); if (!_sFX) { stack->pushInt(_sFXVolume); } else { stack->pushInt(_sFX->getVolumePercent()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXNone ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXNone") == 0) { stack->correctParams(0); _sFXType = SFX_NONE; _sFXParam1 = 0; _sFXParam2 = 0; _sFXParam3 = 0; _sFXParam4 = 0; stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXEcho ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXEcho") == 0) { stack->correctParams(4); _sFXType = SFX_ECHO; _sFXParam1 = (float)stack->pop()->getFloat(0); // Wet/Dry Mix [%] (0-100) _sFXParam2 = (float)stack->pop()->getFloat(0); // Feedback [%] (0-100) _sFXParam3 = (float)stack->pop()->getFloat(333.0f); // Left Delay [ms] (1-2000) _sFXParam4 = (float)stack->pop()->getFloat(333.0f); // Right Delay [ms] (1-2000) stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXReverb ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXReverb") == 0) { stack->correctParams(4); _sFXType = SFX_REVERB; _sFXParam1 = (float)stack->pop()->getFloat(0); // In Gain [dB] (-96 - 0) _sFXParam2 = (float)stack->pop()->getFloat(0); // Reverb Mix [dB] (-96 - 0) _sFXParam3 = (float)stack->pop()->getFloat(1000.0f); // Reverb Time [ms] (0.001 - 3000) _sFXParam4 = (float)stack->pop()->getFloat(0.001f); // HighFreq RT Ratio (0.001 - 0.999) stack->pushNULL(); return STATUS_OK; } else { return BaseScriptHolder::scCallMethod(script, stack, thisStack, name); } }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool AdEntity::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // StopSound ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "StopSound") == 0 && _subtype == ENTITY_SOUND) { stack->correctParams(0); if (DID_FAIL(stopSFX(false))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PlayTheora ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PlayTheora") == 0) { stack->correctParams(4); const char *filename = stack->pop()->getString(); bool looping = stack->pop()->getBool(false); ScValue *valAlpha = stack->pop(); int startTime = stack->pop()->getInt(); delete _theora; _theora = new VideoTheoraPlayer(_gameRef); if (_theora && DID_SUCCEED(_theora->initialize(filename))) { if (!valAlpha->isNULL()) { _theora->setAlphaImage(valAlpha->getString()); } _theora->play(VID_PLAY_POS, 0, 0, false, false, looping, startTime, _scale >= 0.0f ? _scale : -1.0f, _sFXVolume); //if (_scale>=0) _theora->_playZoom = _scale; stack->pushBool(true); } else { script->runtimeError("Entity.PlayTheora - error playing video '%s'", filename); stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // StopTheora ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StopTheora") == 0) { stack->correctParams(0); if (_theora) { _theora->stop(); delete _theora; _theora = nullptr; stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // IsTheoraPlaying ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "IsTheoraPlaying") == 0) { stack->correctParams(0); if (_theora && _theora->isPlaying()) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PauseTheora ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PauseTheora") == 0) { stack->correctParams(0); if (_theora && _theora->isPlaying()) { _theora->pause(); stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ResumeTheora ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ResumeTheora") == 0) { stack->correctParams(0); if (_theora && _theora->isPaused()) { _theora->resume(); stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // IsTheoraPaused ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "IsTheoraPaused") == 0) { stack->correctParams(0); if (_theora && _theora->isPaused()) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // CreateRegion ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "CreateRegion") == 0) { stack->correctParams(0); if (!_region) { _region = new BaseRegion(_gameRef); _gameRef->registerObject(_region); } if (_region) { stack->pushNative(_region, true); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // DeleteRegion ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "DeleteRegion") == 0) { stack->correctParams(0); if (_region) { _gameRef->unregisterObject(_region); _region = nullptr; stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } else { return AdTalkHolder::scCallMethod(script, stack, thisStack, name); } }
int WintermuteEngine::init() { BaseEngine::createInstance(_targetName, _gameDescription->adDesc.gameId, _gameDescription->adDesc.language, _gameDescription->targetExecutable); _game = new AdGame(_targetName); if (!_game) { return 1; } BaseEngine::instance().setGameRef(_game); BasePlatform::initialize(this, _game, 0, nullptr); _game->initConfManSettings(); // load general game settings _game->initialize1(); // set gameId, for savegame-naming: _game->setGameTargetName(_targetName); if (DID_FAIL(_game->loadSettings("startup.settings"))) { _game->LOG(0, "Error loading game settings."); delete _game; _game = nullptr; warning("Some of the essential files are missing. Please reinstall."); return 2; } _game->initialize2(); bool ret = _game->initRenderer(); if (DID_FAIL(ret)) { _game->LOG(ret, "Error initializing renderer. Exiting."); delete _game; _game = nullptr; return 3; } _game->initialize3(); // initialize sound manager (non-fatal if we fail) ret = _game->_soundMgr->initialize(); if (DID_FAIL(ret)) { _game->LOG(ret, "Sound is NOT available."); } // load game uint32 dataInitStart = g_system->getMillis(); if (DID_FAIL(_game->loadGameSettingsFile())) { _game->LOG(ret, "Error loading game file. Exiting."); delete _game; _game = nullptr; return false; } _game->_renderer->_ready = true; _game->_miniUpdateEnabled = true; _game->LOG(0, "Engine initialized in %d ms", g_system->getMillis() - dataInitStart); _game->LOG(0, ""); if (ConfMan.hasKey("save_slot")) { int slot = ConfMan.getInt("save_slot"); _game->loadGame(slot); } _game->_scEngine->attachMonitor(_dbgController); // all set, ready to go return 0; }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool AdObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // PlayAnim / PlayAnimAsync ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "PlayAnim") == 0 || strcmp(name, "PlayAnimAsync") == 0) { stack->correctParams(1); if (DID_FAIL(playAnim(stack->pop()->getString()))) { stack->pushBool(false); } else { if (strcmp(name, "PlayAnimAsync") != 0) { script->waitFor(this); } stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Reset ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Reset") == 0) { stack->correctParams(0); reset(); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // IsTalking ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "IsTalking") == 0) { stack->correctParams(0); stack->pushBool(_state == STATE_TALKING); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // StopTalk / StopTalking ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StopTalk") == 0 || strcmp(name, "StopTalking") == 0) { stack->correctParams(0); if (_sentence) { _sentence->finish(); } if (_state == STATE_TALKING) { _state = _nextState; _nextState = STATE_READY; stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ForceTalkAnim ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ForceTalkAnim") == 0) { stack->correctParams(1); const char *animName = stack->pop()->getString(); delete[] _forcedTalkAnimName; _forcedTalkAnimName = new char[strlen(animName) + 1]; strcpy(_forcedTalkAnimName, animName); _forcedTalkAnimUsed = false; stack->pushBool(true); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Talk / TalkAsync ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Talk") == 0 || strcmp(name, "TalkAsync") == 0) { stack->correctParams(5); const char *text = stack->pop()->getString(); ScValue *soundVal = stack->pop(); int duration = stack->pop()->getInt(); ScValue *valStances = stack->pop(); const char *stances = valStances->isNULL() ? nullptr : valStances->getString(); int align = 0; ScValue *val = stack->pop(); if (val->isNULL()) { align = TAL_CENTER; } else { align = val->getInt(); } align = MIN(MAX(0, align), NUM_TEXT_ALIGN - 1); const char *sound = soundVal->isNULL() ? nullptr : soundVal->getString(); talk(text, sound, duration, stances, (TTextAlign)align); if (strcmp(name, "TalkAsync") != 0) { script->waitForExclusive(this); } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // StickToRegion ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StickToRegion") == 0) { stack->correctParams(1); AdLayer *main = ((AdGame *)_gameRef)->_scene->_mainLayer; bool regFound = false; uint32 i; ScValue *val = stack->pop(); if (val->isNULL() || !main) { _stickRegion = nullptr; regFound = true; } else if (val->isString()) { const char *regionName = val->getString(); for (i = 0; i < main->_nodes.size(); i++) { if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region->getName() && scumm_stricmp(main->_nodes[i]->_region->getName(), regionName) == 0) { _stickRegion = main->_nodes[i]->_region; regFound = true; break; } } } else if (val->isNative()) { BaseScriptable *obj = val->getNative(); for (i = 0; i < main->_nodes.size(); i++) { if (main->_nodes[i]->_type == OBJECT_REGION && main->_nodes[i]->_region == obj) { _stickRegion = main->_nodes[i]->_region; regFound = true; break; } } } if (!regFound) { _stickRegion = nullptr; } stack->pushBool(regFound); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetFont ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (val->isNULL()) { setFont(nullptr); } else { setFont(val->getString()); } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetFont ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetFont") == 0) { stack->correctParams(0); if (_font && _font->getFilename()) { stack->pushString(_font->getFilename()); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // TakeItem ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "TakeItem") == 0) { stack->correctParams(2); if (!_inventory) { _inventory = new AdInventory(_gameRef); ((AdGame *)_gameRef)->registerInventory(_inventory); } ScValue *val = stack->pop(); if (!val->isNULL()) { const char *itemName = val->getString(); val = stack->pop(); const char *insertAfter = val->isNULL() ? nullptr : val->getString(); if (DID_FAIL(_inventory->insertItem(itemName, insertAfter))) { script->runtimeError("Cannot add item '%s' to inventory", itemName); } else { // hide associated entities ((AdGame *)_gameRef)->_scene->handleItemAssociations(itemName, false); } } else { script->runtimeError("TakeItem: item name expected"); } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // DropItem ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "DropItem") == 0) { stack->correctParams(1); if (!_inventory) { _inventory = new AdInventory(_gameRef); ((AdGame *)_gameRef)->registerInventory(_inventory); } ScValue *val = stack->pop(); if (!val->isNULL()) { if (DID_FAIL(_inventory->removeItem(val->getString()))) { script->runtimeError("Cannot remove item '%s' from inventory", val->getString()); } else { // show associated entities ((AdGame *)_gameRef)->_scene->handleItemAssociations(val->getString(), true); } } else { script->runtimeError("DropItem: item name expected"); } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetItem ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetItem") == 0) { stack->correctParams(1); if (!_inventory) { _inventory = new AdInventory(_gameRef); ((AdGame *)_gameRef)->registerInventory(_inventory); } ScValue *val = stack->pop(); if (val->_type == VAL_STRING) { AdItem *item = ((AdGame *)_gameRef)->getItemByName(val->getString()); if (item) { stack->pushNative(item, true); } else { stack->pushNULL(); } } else if (val->isNULL() || val->getInt() < 0 || val->getInt() >= (int32)_inventory->_takenItems.size()) { stack->pushNULL(); } else { stack->pushNative(_inventory->_takenItems[val->getInt()], true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // HasItem ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "HasItem") == 0) { stack->correctParams(1); if (!_inventory) { _inventory = new AdInventory(_gameRef); ((AdGame *)_gameRef)->registerInventory(_inventory); } ScValue *val = stack->pop(); if (!val->isNULL()) { for (uint32 i = 0; i < _inventory->_takenItems.size(); i++) { if (val->getNative() == _inventory->_takenItems[i]) { stack->pushBool(true); return STATUS_OK; } else if (scumm_stricmp(val->getString(), _inventory->_takenItems[i]->getName()) == 0) { stack->pushBool(true); return STATUS_OK; } } } else { script->runtimeError("HasItem: item name expected"); } stack->pushBool(false); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // CreateParticleEmitter ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "CreateParticleEmitter") == 0) { stack->correctParams(3); bool followParent = stack->pop()->getBool(); int offsetX = stack->pop()->getInt(); int offsetY = stack->pop()->getInt(); PartEmitter *emitter = createParticleEmitter(followParent, offsetX, offsetY); if (emitter) { stack->pushNative(_partEmitter, true); } else { stack->pushNULL(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // DeleteParticleEmitter ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "DeleteParticleEmitter") == 0) { stack->correctParams(0); if (_partEmitter) { _gameRef->unregisterObject(_partEmitter); _partEmitter = nullptr; } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // AddAttachment ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "AddAttachment") == 0) { stack->correctParams(4); const char *filename = stack->pop()->getString(); bool preDisplay = stack->pop()->getBool(true); int offsetX = stack->pop()->getInt(); int offsetY = stack->pop()->getInt(); bool res; AdEntity *ent = new AdEntity(_gameRef); if (DID_FAIL(res = ent->loadFile(filename))) { delete ent; ent = nullptr; script->runtimeError("AddAttachment() failed loading entity '%s'", filename); stack->pushBool(false); } else { _gameRef->registerObject(ent); ent->_posX = offsetX; ent->_posY = offsetY; ent->_active = true; if (preDisplay) { _attachmentsPre.add(ent); } else { _attachmentsPost.add(ent); } stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RemoveAttachment ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RemoveAttachment") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); bool found = false; if (val->isNative()) { BaseScriptable *obj = val->getNative(); for (uint32 i = 0; i < _attachmentsPre.size(); i++) { if (_attachmentsPre[i] == obj) { found = true; _gameRef->unregisterObject(_attachmentsPre[i]); _attachmentsPre.remove_at(i); i--; } } for (uint32 i = 0; i < _attachmentsPost.size(); i++) { if (_attachmentsPost[i] == obj) { found = true; _gameRef->unregisterObject(_attachmentsPost[i]); _attachmentsPost.remove_at(i); i--; } } } else { const char *attachmentName = val->getString(); for (uint32 i = 0; i < _attachmentsPre.size(); i++) { if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) { found = true; _gameRef->unregisterObject(_attachmentsPre[i]); _attachmentsPre.remove_at(i); i--; } } for (uint32 i = 0; i < _attachmentsPost.size(); i++) { if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) { found = true; _gameRef->unregisterObject(_attachmentsPost[i]); _attachmentsPost.remove_at(i); i--; } } } stack->pushBool(found); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetAttachment ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetAttachment") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); AdObject *ret = nullptr; if (val->isInt()) { int index = val->getInt(); int currIndex = 0; for (uint32 i = 0; i < _attachmentsPre.size(); i++) { if (currIndex == index) { ret = _attachmentsPre[i]; } currIndex++; } for (uint32 i = 0; i < _attachmentsPost.size(); i++) { if (currIndex == index) { ret = _attachmentsPost[i]; } currIndex++; } } else { const char *attachmentName = val->getString(); for (uint32 i = 0; i < _attachmentsPre.size(); i++) { if (_attachmentsPre[i]->getName() && scumm_stricmp(_attachmentsPre[i]->getName(), attachmentName) == 0) { ret = _attachmentsPre[i]; break; } } if (!ret) { for (uint32 i = 0; i < _attachmentsPost.size(); i++) { if (_attachmentsPost[i]->getName() && scumm_stricmp(_attachmentsPost[i]->getName(), attachmentName) == 0) { ret = _attachmentsPre[i]; break; } } } } if (ret != nullptr) { stack->pushNative(ret, true); } else { stack->pushNULL(); } return STATUS_OK; } else { return BaseObject::scCallMethod(script, stack, thisStack, name); } }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool BaseGameSettings::loadSettings(const char *filename) { TOKEN_TABLE_START(commands) TOKEN_TABLE(SETTINGS) TOKEN_TABLE(GAME) TOKEN_TABLE(STRING_TABLE) TOKEN_TABLE(RESOLUTION) TOKEN_TABLE(REQUIRE_3D_ACCELERATION) TOKEN_TABLE(REQUIRE_SOUND) TOKEN_TABLE(HWTL_MODE) TOKEN_TABLE(ALLOW_WINDOWED_MODE) TOKEN_TABLE(ALLOW_ACCESSIBILITY_TAB) TOKEN_TABLE(ALLOW_ABOUT_TAB) TOKEN_TABLE(ALLOW_ADVANCED) TOKEN_TABLE(ALLOW_DESKTOP_RES) TOKEN_TABLE(REGISTRY_PATH) TOKEN_TABLE(RICH_SAVED_GAMES) TOKEN_TABLE(SAVED_GAME_EXT) TOKEN_TABLE(GUID) TOKEN_TABLE_END byte *origBuffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); if (origBuffer == nullptr) { BaseEngine::LOG(0, "BaseGame::LoadSettings failed for file '%s'", filename); return STATUS_FAILED; } bool ret = STATUS_OK; byte *buffer = origBuffer; byte *params; int cmd; BaseParser parser; if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_SETTINGS) { BaseEngine::LOG(0, "'SETTINGS' keyword expected in game settings file."); return STATUS_FAILED; } buffer = params; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_GAME: delete[] _gameFile; _gameFile = new char[strlen((char *)params) + 1]; if (_gameFile) { strcpy(_gameFile, (char *)params); } break; case TOKEN_STRING_TABLE: if (DID_FAIL(_stringTable->loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_RESOLUTION: parser.scanStr((char *)params, "%d,%d", &_resWidth, &_resHeight); break; case TOKEN_REQUIRE_3D_ACCELERATION: parser.scanStr((char *)params, "%b", &_requireAcceleration); break; case TOKEN_REQUIRE_SOUND: parser.scanStr((char *)params, "%b", &_requireSound); break; case TOKEN_HWTL_MODE: parser.scanStr((char *)params, "%d", &_TLMode); break; case TOKEN_ALLOW_WINDOWED_MODE: parser.scanStr((char *)params, "%b", &_allowWindowed); break; case TOKEN_ALLOW_DESKTOP_RES: parser.scanStr((char *)params, "%b", &_allowDesktopRes); break; case TOKEN_ALLOW_ADVANCED: parser.scanStr((char *)params, "%b", &_allowAdvanced); break; case TOKEN_ALLOW_ACCESSIBILITY_TAB: parser.scanStr((char *)params, "%b", &_allowAccessTab); break; case TOKEN_ALLOW_ABOUT_TAB: parser.scanStr((char *)params, "%b", &_allowAboutTab); break; case TOKEN_REGISTRY_PATH: //BaseEngine::instance().getRegistry()->setBasePath((char *)params); break; case TOKEN_RICH_SAVED_GAMES: parser.scanStr((char *)params, "%b", &_richSavedGames); break; case TOKEN_SAVED_GAME_EXT: _savedGameExt = (char *)params; break; case TOKEN_GUID: break; } } if (cmd == PARSERR_TOKENNOTFOUND) { BaseEngine::LOG(0, "Syntax error in game settings '%s'", filename); ret = STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { BaseEngine::LOG(0, "Error loading game settings '%s'", filename); ret = STATUS_FAILED; } _allowWindowed = true; // TODO: These two settings should probably be cleaned out altogether. _compressedSavegames = true; delete[] origBuffer; return ret; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool UIText::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(STATIC) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(DISABLED) TOKEN_TABLE(VISIBLE) TOKEN_TABLE(BACK) TOKEN_TABLE(IMAGE) TOKEN_TABLE(FONT) TOKEN_TABLE(TEXT_ALIGN) TOKEN_TABLE(VERTICAL_ALIGN) TOKEN_TABLE(TEXT) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(WIDTH) TOKEN_TABLE(HEIGHT) TOKEN_TABLE(CURSOR) TOKEN_TABLE(NAME) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(CAPTION) TOKEN_TABLE(PARENT_NOTIFY) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd = 2; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_STATIC) { _gameRef->LOG(0, "'STATIC' keyword expected."); return STATUS_FAILED; } buffer = params; } while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_BACK: delete _back; _back = new UITiledImage(_gameRef); if (!_back || DID_FAIL(_back->loadFile((char *)params))) { delete _back; _back = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE: delete _image; _image = new BaseSprite(_gameRef); if (!_image || DID_FAIL(_image->loadFile((char *)params))) { delete _image; _image = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_FONT: if (_font) { _gameRef->_fontStorage->removeFont(_font); } _font = _gameRef->_fontStorage->addFont((char *)params); if (!_font) { cmd = PARSERR_GENERIC; } break; case TOKEN_TEXT: setText((char *)params); _gameRef->expandStringByStringTable(&_text); break; case TOKEN_TEXT_ALIGN: if (scumm_stricmp((char *)params, "left") == 0) { _textAlign = TAL_LEFT; } else if (scumm_stricmp((char *)params, "right") == 0) { _textAlign = TAL_RIGHT; } else { _textAlign = TAL_CENTER; } break; case TOKEN_VERTICAL_ALIGN: if (scumm_stricmp((char *)params, "top") == 0) { _verticalAlign = VAL_TOP; } else if (scumm_stricmp((char *)params, "bottom") == 0) { _verticalAlign = VAL_BOTTOM; } else { _verticalAlign = VAL_CENTER; } break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_WIDTH: parser.scanStr((char *)params, "%d", &_width); break; case TOKEN_HEIGHT: parser.scanStr((char *)params, "%d", &_height); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_PARENT_NOTIFY: parser.scanStr((char *)params, "%b", &_parentNotify); break; case TOKEN_DISABLED: parser.scanStr((char *)params, "%b", &_disable); break; case TOKEN_VISIBLE: parser.scanStr((char *)params, "%b", &_visible); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in STATIC definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading STATIC definition"); return STATUS_FAILED; } correctSize(); return STATUS_OK; }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool UIButton::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SetDisabledFont ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SetDisabledFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (_fontDisable) { _gameRef->_fontStorage->removeFont(_fontDisable); } if (val->isNULL()) { _fontDisable = nullptr; stack->pushBool(true); } else { _fontDisable = _gameRef->_fontStorage->addFont(val->getString()); stack->pushBool(_fontDisable != nullptr); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetHoverFont ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetHoverFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (_fontHover) { _gameRef->_fontStorage->removeFont(_fontHover); } if (val->isNULL()) { _fontHover = nullptr; stack->pushBool(true); } else { _fontHover = _gameRef->_fontStorage->addFont(val->getString()); stack->pushBool(_fontHover != nullptr); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetPressedFont ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetPressedFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (_fontPress) { _gameRef->_fontStorage->removeFont(_fontPress); } if (val->isNULL()) { _fontPress = nullptr; stack->pushBool(true); } else { _fontPress = _gameRef->_fontStorage->addFont(val->getString()); stack->pushBool(_fontPress != nullptr); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetFocusedFont ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetFocusedFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (_fontFocus) { _gameRef->_fontStorage->removeFont(_fontFocus); } if (val->isNULL()) { _fontFocus = nullptr; stack->pushBool(true); } else { _fontFocus = _gameRef->_fontStorage->addFont(val->getString()); stack->pushBool(_fontFocus != nullptr); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetDisabledImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetDisabledImage") == 0) { stack->correctParams(1); delete _imageDisable; _imageDisable = new BaseSprite(_gameRef); const char *filename = stack->pop()->getString(); if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(filename))) { delete _imageDisable; _imageDisable = nullptr; stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetDisabledImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetDisabledImage") == 0) { stack->correctParams(0); if (!_imageDisable || !_imageDisable->getFilename()) { stack->pushNULL(); } else { stack->pushString(_imageDisable->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetDisabledImageObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetDisabledImageObject") == 0) { stack->correctParams(0); if (!_imageDisable) { stack->pushNULL(); } else { stack->pushNative(_imageDisable, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetHoverImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetHoverImage") == 0) { stack->correctParams(1); delete _imageHover; _imageHover = new BaseSprite(_gameRef); const char *filename = stack->pop()->getString(); if (!_imageHover || DID_FAIL(_imageHover->loadFile(filename))) { delete _imageHover; _imageHover = nullptr; stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetHoverImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetHoverImage") == 0) { stack->correctParams(0); if (!_imageHover || !_imageHover->getFilename()) { stack->pushNULL(); } else { stack->pushString(_imageHover->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetHoverImageObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetHoverImageObject") == 0) { stack->correctParams(0); if (!_imageHover) { stack->pushNULL(); } else { stack->pushNative(_imageHover, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetPressedImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetPressedImage") == 0) { stack->correctParams(1); delete _imagePress; _imagePress = new BaseSprite(_gameRef); const char *filename = stack->pop()->getString(); if (!_imagePress || DID_FAIL(_imagePress->loadFile(filename))) { delete _imagePress; _imagePress = nullptr; stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetPressedImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetPressedImage") == 0) { stack->correctParams(0); if (!_imagePress || !_imagePress->getFilename()) { stack->pushNULL(); } else { stack->pushString(_imagePress->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetPressedImageObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetPressedImageObject") == 0) { stack->correctParams(0); if (!_imagePress) { stack->pushNULL(); } else { stack->pushNative(_imagePress, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetFocusedImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetFocusedImage") == 0) { stack->correctParams(1); delete _imageFocus; _imageFocus = new BaseSprite(_gameRef); const char *filename = stack->pop()->getString(); if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(filename))) { delete _imageFocus; _imageFocus = nullptr; stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetFocusedImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetFocusedImage") == 0) { stack->correctParams(0); if (!_imageFocus || !_imageFocus->getFilename()) { stack->pushNULL(); } else { stack->pushString(_imageFocus->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetFocusedImageObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetFocusedImageObject") == 0) { stack->correctParams(0); if (!_imageFocus) { stack->pushNULL(); } else { stack->pushNative(_imageFocus, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Press ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Press") == 0) { stack->correctParams(0); if (_visible && !_disable) { _oneTimePress = true; _oneTimePressTime = g_system->getMillis(); } stack->pushNULL(); return STATUS_OK; } else { return UIObject::scCallMethod(script, stack, thisStack, name); } }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool UIButton::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(BUTTON) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(DISABLED) TOKEN_TABLE(VISIBLE) TOKEN_TABLE(FOCUSABLE) TOKEN_TABLE(BACK_HOVER) TOKEN_TABLE(BACK_PRESS) TOKEN_TABLE(BACK_DISABLE) TOKEN_TABLE(BACK_FOCUS) TOKEN_TABLE(BACK) TOKEN_TABLE(CENTER_IMAGE) TOKEN_TABLE(IMAGE_HOVER) TOKEN_TABLE(IMAGE_PRESS) TOKEN_TABLE(IMAGE_DISABLE) TOKEN_TABLE(IMAGE_FOCUS) TOKEN_TABLE(IMAGE) TOKEN_TABLE(FONT_HOVER) TOKEN_TABLE(FONT_PRESS) TOKEN_TABLE(FONT_DISABLE) TOKEN_TABLE(FONT_FOCUS) TOKEN_TABLE(FONT) TOKEN_TABLE(TEXT_ALIGN) TOKEN_TABLE(TEXT) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(WIDTH) TOKEN_TABLE(HEIGHT) TOKEN_TABLE(CURSOR) TOKEN_TABLE(NAME) TOKEN_TABLE(EVENTS) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(CAPTION) TOKEN_TABLE(PARENT_NOTIFY) TOKEN_TABLE(PRESSED) TOKEN_TABLE(PIXEL_PERFECT) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd = 2; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_BUTTON) { _gameRef->LOG(0, "'BUTTON' keyword expected."); return STATUS_FAILED; } buffer = params; } while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_BACK: delete _back; _back = new UITiledImage(_gameRef); if (!_back || DID_FAIL(_back->loadFile((char *)params))) { delete _back; _back = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_BACK_HOVER: delete _backHover; _backHover = new UITiledImage(_gameRef); if (!_backHover || DID_FAIL(_backHover->loadFile((char *)params))) { delete _backHover; _backHover = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_BACK_PRESS: delete _backPress; _backPress = new UITiledImage(_gameRef); if (!_backPress || DID_FAIL(_backPress->loadFile((char *)params))) { delete _backPress; _backPress = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_BACK_DISABLE: delete _backDisable; _backDisable = new UITiledImage(_gameRef); if (!_backDisable || DID_FAIL(_backDisable->loadFile((char *)params))) { delete _backDisable; _backDisable = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_BACK_FOCUS: delete _backFocus; _backFocus = new UITiledImage(_gameRef); if (!_backFocus || DID_FAIL(_backFocus->loadFile((char *)params))) { delete _backFocus; _backFocus = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE: delete _image; _image = new BaseSprite(_gameRef); if (!_image || DID_FAIL(_image->loadFile((char *)params))) { delete _image; _image = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE_HOVER: delete _imageHover; _imageHover = new BaseSprite(_gameRef); if (!_imageHover || DID_FAIL(_imageHover->loadFile((char *)params))) { delete _imageHover; _imageHover = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE_PRESS: delete _imagePress; _imagePress = new BaseSprite(_gameRef); if (!_imagePress || DID_FAIL(_imagePress->loadFile((char *)params))) { delete _imagePress; _imagePress = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE_DISABLE: delete _imageDisable; _imageDisable = new BaseSprite(_gameRef); if (!_imageDisable || DID_FAIL(_imageDisable->loadFile((char *)params))) { delete _imageDisable; _imageDisable = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE_FOCUS: delete _imageFocus; _imageFocus = new BaseSprite(_gameRef); if (!_imageFocus || DID_FAIL(_imageFocus->loadFile((char *)params))) { delete _imageFocus; _imageFocus = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_FONT: if (_font) { _gameRef->_fontStorage->removeFont(_font); } _font = _gameRef->_fontStorage->addFont((char *)params); if (!_font) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_HOVER: if (_fontHover) { _gameRef->_fontStorage->removeFont(_fontHover); } _fontHover = _gameRef->_fontStorage->addFont((char *)params); if (!_fontHover) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_PRESS: if (_fontPress) { _gameRef->_fontStorage->removeFont(_fontPress); } _fontPress = _gameRef->_fontStorage->addFont((char *)params); if (!_fontPress) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_DISABLE: if (_fontDisable) { _gameRef->_fontStorage->removeFont(_fontDisable); } _fontDisable = _gameRef->_fontStorage->addFont((char *)params); if (!_fontDisable) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_FOCUS: if (_fontFocus) { _gameRef->_fontStorage->removeFont(_fontFocus); } _fontFocus = _gameRef->_fontStorage->addFont((char *)params); if (!_fontFocus) { cmd = PARSERR_GENERIC; } break; case TOKEN_TEXT: setText((char *)params); _gameRef->_stringTable->expand(&_text); break; case TOKEN_TEXT_ALIGN: if (scumm_stricmp((char *)params, "left") == 0) { _align = TAL_LEFT; } else if (scumm_stricmp((char *)params, "right") == 0) { _align = TAL_RIGHT; } else { _align = TAL_CENTER; } break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_WIDTH: parser.scanStr((char *)params, "%d", &_width); break; case TOKEN_HEIGHT: parser.scanStr((char *)params, "%d", &_height); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_PARENT_NOTIFY: parser.scanStr((char *)params, "%b", &_parentNotify); break; case TOKEN_DISABLED: parser.scanStr((char *)params, "%b", &_disable); break; case TOKEN_VISIBLE: parser.scanStr((char *)params, "%b", &_visible); break; case TOKEN_FOCUSABLE: parser.scanStr((char *)params, "%b", &_canFocus); break; case TOKEN_CENTER_IMAGE: parser.scanStr((char *)params, "%b", &_centerImage); break; case TOKEN_PRESSED: parser.scanStr((char *)params, "%b", &_stayPressed); break; case TOKEN_PIXEL_PERFECT: parser.scanStr((char *)params, "%b", &_pixelPerfect); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in BUTTON definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading BUTTON definition"); return STATUS_FAILED; } correctSize(); return STATUS_OK; }
////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool UIObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SetFont ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SetFont") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); if (_font) { _gameRef->_fontStorage->removeFont(_font); } if (val->isNULL()) { _font = nullptr; stack->pushBool(true); } else { _font = _gameRef->_fontStorage->addFont(val->getString()); stack->pushBool(_font != nullptr); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetImage") == 0) { stack->correctParams(1); ScValue *val = stack->pop(); /* const char *filename = */ val->getString(); delete _image; _image = nullptr; if (val->isNULL()) { stack->pushBool(true); return STATUS_OK; } _image = new BaseSprite(_gameRef); if (!_image || DID_FAIL(_image->loadFile(val->getString()))) { delete _image; _image = nullptr; stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetImage ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetImage") == 0) { stack->correctParams(0); if (!_image || !_image->getFilename()) { stack->pushNULL(); } else { stack->pushString(_image->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetImageObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetImageObject") == 0) { stack->correctParams(0); if (!_image) { stack->pushNULL(); } else { stack->pushNative(_image, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Focus ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Focus") == 0) { stack->correctParams(0); focus(); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // MoveAfter / MoveBefore ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "MoveAfter") == 0 || strcmp(name, "MoveBefore") == 0) { stack->correctParams(1); if (_parent && _parent->_type == UI_WINDOW) { UIWindow *win = (UIWindow *)_parent; uint32 i; bool found = false; ScValue *val = stack->pop(); // find directly if (val->isNative()) { UIObject *widget = (UIObject *)val->getNative(); for (i = 0; i < win->_widgets.size(); i++) { if (win->_widgets[i] == widget) { found = true; break; } } } // find by name else { const char *findName = val->getString(); for (i = 0; i < win->_widgets.size(); i++) { if (scumm_stricmp(win->_widgets[i]->getName(), findName) == 0) { found = true; break; } } } if (found) { bool done = false; for (uint32 j = 0; j < win->_widgets.size(); j++) { if (win->_widgets[j] == this) { if (strcmp(name, "MoveAfter") == 0) { i++; } if (j >= i) { j++; } win->_widgets.insert_at(i, this); win->_widgets.remove_at(j); done = true; stack->pushBool(true); break; } } if (!done) { stack->pushBool(false); } } else { stack->pushBool(false); } } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // MoveToBottom ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "MoveToBottom") == 0) { stack->correctParams(0); if (_parent && _parent->_type == UI_WINDOW) { UIWindow *win = (UIWindow *)_parent; for (uint32 i = 0; i < win->_widgets.size(); i++) { if (win->_widgets[i] == this) { win->_widgets.remove_at(i); win->_widgets.insert_at(0, this); break; } } stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // MoveToTop ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "MoveToTop") == 0) { stack->correctParams(0); if (_parent && _parent->_type == UI_WINDOW) { UIWindow *win = (UIWindow *)_parent; for (uint32 i = 0; i < win->_widgets.size(); i++) { if (win->_widgets[i] == this) { win->_widgets.remove_at(i); win->_widgets.add(this); break; } } stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } else { return BaseObject::scCallMethod(script, stack, thisStack, name); } }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdTalkNode::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(ACTION) TOKEN_TABLE(SPRITESET_FILE) TOKEN_TABLE(SPRITESET) TOKEN_TABLE(SPRITE) TOKEN_TABLE(START_TIME) TOKEN_TABLE(END_TIME) TOKEN_TABLE(COMMENT) TOKEN_TABLE(PRECACHE) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ACTION) { _gameRef->LOG(0, "'ACTION' keyword expected."); return STATUS_FAILED; } buffer = params; } _endTime = 0; _playToEnd = false; _preCache = false; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_SPRITE: BaseUtils::setString(&_spriteFilename, (char *)params); break; case TOKEN_SPRITESET_FILE: BaseUtils::setString(&_spriteSetFilename, (char *)params); break; case TOKEN_SPRITESET: { delete _spriteSet; _spriteSet = new AdSpriteSet(_gameRef); if (!_spriteSet || DID_FAIL(_spriteSet->loadBuffer(params, false))) { delete _spriteSet; _spriteSet = nullptr; cmd = PARSERR_GENERIC; } } break; case TOKEN_START_TIME: parser.scanStr((char *)params, "%d", &_startTime); break; case TOKEN_END_TIME: parser.scanStr((char *)params, "%d", &_endTime); break; case TOKEN_PRECACHE: parser.scanStr((char *)params, "%b", &_preCache); break; case TOKEN_COMMENT: if (_gameRef->_editorMode) { BaseUtils::setString(&_comment, (char *)params); } break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in ACTION definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading ACTION definition"); return STATUS_FAILED; } if (_endTime == 0) { _playToEnd = true; } else { _playToEnd = false; } if (_preCache && _spriteFilename) { delete _sprite; _sprite = new BaseSprite(_gameRef); if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) { return STATUS_FAILED; } } if (_preCache && _spriteSetFilename) { delete _spriteSet; _spriteSet = new AdSpriteSet(_gameRef); if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) { return STATUS_FAILED; } } return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdRegion::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(REGION) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(NAME) TOKEN_TABLE(ACTIVE) TOKEN_TABLE(ZOOM) TOKEN_TABLE(SCALE) TOKEN_TABLE(BLOCKED) TOKEN_TABLE(DECORATION) TOKEN_TABLE(POINT) TOKEN_TABLE(ALPHA_COLOR) TOKEN_TABLE(ALPHA) TOKEN_TABLE(EDITOR_SELECTED_POINT) TOKEN_TABLE(EDITOR_SELECTED) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(CAPTION) TOKEN_TABLE(PROPERTY) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_REGION) { _gameRef->LOG(0, "'REGION' keyword expected."); return STATUS_FAILED; } buffer = params; } for (uint32 i = 0; i < _points.size(); i++) { delete _points[i]; } _points.clear(); int ar = 255, ag = 255, ab = 255, alpha = 255; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_ACTIVE: parser.scanStr((char *)params, "%b", &_active); break; case TOKEN_BLOCKED: parser.scanStr((char *)params, "%b", &_blocked); break; case TOKEN_DECORATION: parser.scanStr((char *)params, "%b", &_decoration); break; case TOKEN_ZOOM: case TOKEN_SCALE: { int j; parser.scanStr((char *)params, "%d", &j); _zoom = (float)j; } break; case TOKEN_POINT: { int x, y; parser.scanStr((char *)params, "%d,%d", &x, &y); _points.add(new BasePoint(x, y)); } break; case TOKEN_ALPHA_COLOR: parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab); break; case TOKEN_ALPHA: parser.scanStr((char *)params, "%d", &alpha); break; case TOKEN_EDITOR_SELECTED: parser.scanStr((char *)params, "%b", &_editorSelected); break; case TOKEN_EDITOR_SELECTED_POINT: parser.scanStr((char *)params, "%d", &_editorSelectedPoint); break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_PROPERTY: parseProperty(params, false); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in REGION definition"); return STATUS_FAILED; } createRegion(); _alpha = BYTETORGBA(ar, ag, ab, alpha); return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdEntity::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(ENTITY) TOKEN_TABLE(SPRITE) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(NAME) TOKEN_TABLE(SCALABLE) TOKEN_TABLE(REGISTRABLE) TOKEN_TABLE(INTERACTIVE) TOKEN_TABLE(SHADOWABLE) TOKEN_TABLE(COLORABLE) TOKEN_TABLE(ACTIVE) TOKEN_TABLE(EVENTS) TOKEN_TABLE(FONT) TOKEN_TABLE(TALK_SPECIAL) TOKEN_TABLE(TALK) TOKEN_TABLE(CURSOR) TOKEN_TABLE(REGION) TOKEN_TABLE(BLOCKED_REGION) TOKEN_TABLE(EDITOR_SELECTED) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(SOUND_START_TIME) TOKEN_TABLE(SOUND_VOLUME) TOKEN_TABLE(SOUND_PANNING) TOKEN_TABLE(SOUND) TOKEN_TABLE(SUBTYPE) TOKEN_TABLE(CAPTION) TOKEN_TABLE(PROPERTY) TOKEN_TABLE(WAYPOINTS) TOKEN_TABLE(IGNORE_ITEMS) TOKEN_TABLE(ROTABLE) TOKEN_TABLE(ROTATABLE) TOKEN_TABLE(ALPHA_COLOR) TOKEN_TABLE(SCALE) TOKEN_TABLE(RELATIVE_SCALE) TOKEN_TABLE(ALPHA) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE(ITEM) TOKEN_TABLE(WALK_TO_X) TOKEN_TABLE(WALK_TO_Y) TOKEN_TABLE(WALK_TO_DIR) TOKEN_TABLE(SAVE_STATE) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ENTITY) { _gameRef->LOG(0, "'ENTITY' keyword expected."); return STATUS_FAILED; } buffer = params; } AdGame *adGame = (AdGame *)_gameRef; BaseSprite *spr = nullptr; int ar = 0, ag = 0, ab = 0, alpha = 0; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_SPRITE: { delete _sprite; _sprite = nullptr; spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile((char *)params))) { cmd = PARSERR_GENERIC; } else { _sprite = spr; } } break; case TOKEN_TALK: { spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) { cmd = PARSERR_GENERIC; } else { _talkSprites.add(spr); } } break; case TOKEN_TALK_SPECIAL: { spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) { cmd = PARSERR_GENERIC; } else { _talkSpritesEx.add(spr); } } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_ITEM: setItem((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_FONT: setFont((char *)params); break; case TOKEN_SCALABLE: parser.scanStr((char *)params, "%b", &_zoomable); break; case TOKEN_SCALE: { int s; parser.scanStr((char *)params, "%d", &s); _scale = (float)s; } break; case TOKEN_RELATIVE_SCALE: { int s; parser.scanStr((char *)params, "%d", &s); _relativeScale = (float)s; } break; case TOKEN_ROTABLE: case TOKEN_ROTATABLE: parser.scanStr((char *)params, "%b", &_rotatable); break; case TOKEN_REGISTRABLE: case TOKEN_INTERACTIVE: parser.scanStr((char *)params, "%b", &_registrable); break; case TOKEN_SHADOWABLE: case TOKEN_COLORABLE: parser.scanStr((char *)params, "%b", &_shadowable); break; case TOKEN_ACTIVE: parser.scanStr((char *)params, "%b", &_active); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_EDITOR_SELECTED: parser.scanStr((char *)params, "%b", &_editorSelected); break; case TOKEN_REGION: { if (_region) { _gameRef->unregisterObject(_region); } _region = nullptr; BaseRegion *rgn = new BaseRegion(_gameRef); if (!rgn || DID_FAIL(rgn->loadBuffer(params, false))) { cmd = PARSERR_GENERIC; } else { _region = rgn; _gameRef->registerObject(_region); } } break; case TOKEN_BLOCKED_REGION: { delete _blockRegion; _blockRegion = nullptr; delete _currentBlockRegion; _currentBlockRegion = nullptr; BaseRegion *rgn = new BaseRegion(_gameRef); BaseRegion *crgn = new BaseRegion(_gameRef); if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) { delete _blockRegion; _blockRegion = nullptr; delete _currentBlockRegion; _currentBlockRegion = nullptr; cmd = PARSERR_GENERIC; } else { _blockRegion = rgn; _currentBlockRegion = crgn; _currentBlockRegion->mimic(_blockRegion); } } break; case TOKEN_WAYPOINTS: { delete _wptGroup; _wptGroup = nullptr; delete _currentWptGroup; _currentWptGroup = nullptr; AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef); AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef); if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) { delete _wptGroup; _wptGroup = nullptr; delete _currentWptGroup; _currentWptGroup = nullptr; cmd = PARSERR_GENERIC; } else { _wptGroup = wpt; _currentWptGroup = cwpt; _currentWptGroup->mimic(_wptGroup); } } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_SUBTYPE: { if (scumm_stricmp((char *)params, "sound") == 0) { delete _sprite; _sprite = nullptr; if (_gameRef->_editorMode) { spr = new BaseSprite(_gameRef, this); if (!spr || DID_FAIL(spr->loadFile("entity_sound.sprite"))) { cmd = PARSERR_GENERIC; } else { _sprite = spr; } } if (_gameRef->_editorMode) { _editorOnly = true; } _zoomable = false; _rotatable = false; _registrable = _gameRef->_editorMode; _shadowable = false; _subtype = ENTITY_SOUND; } } break; case TOKEN_SOUND: playSFX((char *)params, false, false); break; case TOKEN_SOUND_START_TIME: parser.scanStr((char *)params, "%d", &_sFXStart); break; case TOKEN_SOUND_VOLUME: parser.scanStr((char *)params, "%d", &_sFXVolume); break; case TOKEN_SOUND_PANNING: parser.scanStr((char *)params, "%b", &_autoSoundPanning); break; case TOKEN_SAVE_STATE: parser.scanStr((char *)params, "%b", &_saveState); break; case TOKEN_PROPERTY: parseProperty(params, false); break; case TOKEN_IGNORE_ITEMS: parser.scanStr((char *)params, "%b", &_ignoreItems); break; case TOKEN_ALPHA_COLOR: parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab); break; case TOKEN_ALPHA: parser.scanStr((char *)params, "%d", &alpha); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; case TOKEN_WALK_TO_X: parser.scanStr((char *)params, "%d", &_walkToX); break; case TOKEN_WALK_TO_Y: parser.scanStr((char *)params, "%d", &_walkToY); break; case TOKEN_WALK_TO_DIR: { int i; parser.scanStr((char *)params, "%d", &i); if (i < 0) { i = 0; } if (i >= NUM_DIRECTIONS) { i = DI_NONE; } _walkToDir = (TDirection)i; } break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in ENTITY definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading ENTITY definition"); if (spr) { delete spr; } return STATUS_FAILED; } if (_region && _sprite) { _gameRef->LOG(0, "Warning: Entity '%s' has both sprite and region.", getName()); } updatePosition(); if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) { ar = ag = ab = 255; } _alphaColor = BYTETORGBA(ar, ag, ab, alpha); _state = STATE_READY; if (_item && ((AdGame *)_gameRef)->isItemTaken(_item)) { _active = false; } return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdActor::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(ACTOR) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(NAME) TOKEN_TABLE(SCALABLE) TOKEN_TABLE(REGISTRABLE) TOKEN_TABLE(INTERACTIVE) TOKEN_TABLE(SHADOWABLE) TOKEN_TABLE(COLORABLE) TOKEN_TABLE(ACTIVE) TOKEN_TABLE(WALK) TOKEN_TABLE(STAND) TOKEN_TABLE(TALK_SPECIAL) TOKEN_TABLE(TALK) TOKEN_TABLE(TURN_LEFT) TOKEN_TABLE(TURN_RIGHT) TOKEN_TABLE(EVENTS) TOKEN_TABLE(FONT) TOKEN_TABLE(CURSOR) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(SOUND_VOLUME) TOKEN_TABLE(SOUND_PANNING) TOKEN_TABLE(CAPTION) TOKEN_TABLE(PROPERTY) TOKEN_TABLE(BLOCKED_REGION) TOKEN_TABLE(WAYPOINTS) TOKEN_TABLE(IGNORE_ITEMS) TOKEN_TABLE(ROTABLE) TOKEN_TABLE(ROTATABLE) TOKEN_TABLE(ALPHA_COLOR) TOKEN_TABLE(SCALE) TOKEN_TABLE(RELATIVE_SCALE) TOKEN_TABLE(ALPHA) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE(ANIMATION) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ACTOR) { _gameRef->LOG(0, "'ACTOR' keyword expected."); return STATUS_FAILED; } buffer = params; } AdGame *adGame = (AdGame *)_gameRef; AdSpriteSet *spr = nullptr; int ar = 0, ag = 0, ab = 0, alpha = 0; while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_FONT: setFont((char *)params); break; case TOKEN_SCALABLE: parser.scanStr((char *)params, "%b", &_zoomable); break; case TOKEN_ROTABLE: case TOKEN_ROTATABLE: parser.scanStr((char *)params, "%b", &_rotatable); break; case TOKEN_REGISTRABLE: case TOKEN_INTERACTIVE: parser.scanStr((char *)params, "%b", &_registrable); break; case TOKEN_SHADOWABLE: case TOKEN_COLORABLE: parser.scanStr((char *)params, "%b", &_shadowable); break; case TOKEN_ACTIVE: parser.scanStr((char *)params, "%b", &_active); break; case TOKEN_WALK: delete _walkSprite; _walkSprite = nullptr; spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texWalkLifeTime, CACHE_HALF))) { cmd = PARSERR_GENERIC; } else { _walkSprite = spr; } break; case TOKEN_TALK: spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) { cmd = PARSERR_GENERIC; } else { _talkSprites.add(spr); } break; case TOKEN_TALK_SPECIAL: spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texTalkLifeTime))) { cmd = PARSERR_GENERIC; } else { _talkSpritesEx.add(spr); } break; case TOKEN_STAND: delete _standSprite; _standSprite = nullptr; spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true, adGame->_texStandLifeTime))) { cmd = PARSERR_GENERIC; } else { _standSprite = spr; } break; case TOKEN_TURN_LEFT: delete _turnLeftSprite; _turnLeftSprite = nullptr; spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true))) { cmd = PARSERR_GENERIC; } else { _turnLeftSprite = spr; } break; case TOKEN_TURN_RIGHT: delete _turnRightSprite; _turnRightSprite = nullptr; spr = new AdSpriteSet(_gameRef, this); if (!spr || DID_FAIL(spr->loadBuffer(params, true))) { cmd = PARSERR_GENERIC; } else { _turnRightSprite = spr; } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = nullptr; cmd = PARSERR_GENERIC; } break; case TOKEN_SOUND_VOLUME: parser.scanStr((char *)params, "%d", &_sFXVolume); break; case TOKEN_SCALE: { int s; parser.scanStr((char *)params, "%d", &s); _scale = (float)s; } break; case TOKEN_RELATIVE_SCALE: { int s; parser.scanStr((char *)params, "%d", &s); _relativeScale = (float)s; } break; case TOKEN_SOUND_PANNING: parser.scanStr((char *)params, "%b", &_autoSoundPanning); break; case TOKEN_PROPERTY: parseProperty(params, false); break; case TOKEN_BLOCKED_REGION: { delete _blockRegion; delete _currentBlockRegion; _blockRegion = nullptr; _currentBlockRegion = nullptr; BaseRegion *rgn = new BaseRegion(_gameRef); BaseRegion *crgn = new BaseRegion(_gameRef); if (!rgn || !crgn || DID_FAIL(rgn->loadBuffer(params, false))) { delete _blockRegion; delete _currentBlockRegion; _blockRegion = nullptr; _currentBlockRegion = nullptr; cmd = PARSERR_GENERIC; } else { _blockRegion = rgn; _currentBlockRegion = crgn; _currentBlockRegion->mimic(_blockRegion); } } break; case TOKEN_WAYPOINTS: { delete _wptGroup; delete _currentWptGroup; _wptGroup = nullptr; _currentWptGroup = nullptr; AdWaypointGroup *wpt = new AdWaypointGroup(_gameRef); AdWaypointGroup *cwpt = new AdWaypointGroup(_gameRef); if (!wpt || !cwpt || DID_FAIL(wpt->loadBuffer(params, false))) { delete _wptGroup; delete _currentWptGroup; _wptGroup = nullptr; _currentWptGroup = nullptr; cmd = PARSERR_GENERIC; } else { _wptGroup = wpt; _currentWptGroup = cwpt; _currentWptGroup->mimic(_wptGroup); } } break; case TOKEN_IGNORE_ITEMS: parser.scanStr((char *)params, "%b", &_ignoreItems); break; case TOKEN_ALPHA_COLOR: parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab); break; case TOKEN_ALPHA: parser.scanStr((char *)params, "%d", &alpha); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; case TOKEN_ANIMATION: { AdSpriteSet *anim = new AdSpriteSet(_gameRef, this); if (!anim || DID_FAIL(anim->loadBuffer(params, false))) { cmd = PARSERR_GENERIC; } else { _anims.add(anim); } } break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in ACTOR definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { if (spr) { delete spr; } _gameRef->LOG(0, "Error loading ACTOR definition"); return STATUS_FAILED; } if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) { ar = ag = ab = 255; } _alphaColor = BYTETORGBA(ar, ag, ab, alpha); _state = _nextState = STATE_READY; return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool AdTalkDef::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(TALK) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(ACTION) TOKEN_TABLE(DEFAULT_SPRITESET_FILE) TOKEN_TABLE(DEFAULT_SPRITESET) TOKEN_TABLE(DEFAULT_SPRITE) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_TALK) { _gameRef->LOG(0, "'TALK' keyword expected."); return STATUS_FAILED; } buffer = params; } while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_ACTION: { AdTalkNode *node = new AdTalkNode(_gameRef); if (node && DID_SUCCEED(node->loadBuffer(params, false))) { _nodes.add(node); } else { delete node; node = nullptr; cmd = PARSERR_GENERIC; } } break; case TOKEN_DEFAULT_SPRITE: BaseUtils::setString(&_defaultSpriteFilename, (char *)params); break; case TOKEN_DEFAULT_SPRITESET_FILE: BaseUtils::setString(&_defaultSpriteSetFilename, (char *)params); break; case TOKEN_DEFAULT_SPRITESET: { delete _defaultSpriteSet; _defaultSpriteSet = new AdSpriteSet(_gameRef); if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadBuffer(params, false))) { delete _defaultSpriteSet; _defaultSpriteSet = nullptr; cmd = PARSERR_GENERIC; } } break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in TALK definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading TALK definition"); return STATUS_FAILED; } delete _defaultSprite; delete _defaultSpriteSet; _defaultSprite = nullptr; _defaultSpriteSet = nullptr; if (_defaultSpriteFilename) { _defaultSprite = new BaseSprite(_gameRef); if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) { return STATUS_FAILED; } } if (_defaultSpriteSetFilename) { _defaultSpriteSet = new AdSpriteSet(_gameRef); if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) { return STATUS_FAILED; } } return STATUS_OK; }
bool BasePersistenceManager::initSave(const char *desc) { if (!desc) { return STATUS_FAILED; } cleanup(); _saving = true; _saveStream = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES); if (_saveStream) { // get thumbnails if (!_gameRef->_cachedThumbnail) { _gameRef->_cachedThumbnail = new SaveThumbHelper(_gameRef); if (DID_FAIL(_gameRef->_cachedThumbnail->storeThumbnail(true))) { delete _gameRef->_cachedThumbnail; _gameRef->_cachedThumbnail = nullptr; } } uint32 magic = DCGF_MAGIC; putDWORD(magic); magic = SAVE_MAGIC_3; putDWORD(magic); byte verMajor, verMinor, extMajor, extMinor; _gameRef->getVersion(&verMajor, &verMinor, &extMajor, &extMinor); _saveStream->writeByte(verMajor); _saveStream->writeByte(verMinor); _saveStream->writeByte(extMajor); _saveStream->writeByte(extMinor); // new in ver 2 putDWORD((uint32)DCGF_VER_BUILD); putString(_gameRef->getName()); // thumbnail data size bool thumbnailOK = false; if (_gameRef->_cachedThumbnail) { if (_gameRef->_cachedThumbnail->_thumbnail) { Common::MemoryWriteStreamDynamic thumbStream(DisposeAfterUse::YES); if (_gameRef->_cachedThumbnail->_thumbnail->writeBMPToStream(&thumbStream)) { _saveStream->writeUint32LE(thumbStream.size()); _saveStream->write(thumbStream.getData(), thumbStream.size()); } else { _saveStream->writeUint32LE(0); } thumbnailOK = true; } } if (!thumbnailOK) { putDWORD(0); } thumbnailOK = false; // Again for the ScummVM-thumb: if (_gameRef->_cachedThumbnail) { if (_gameRef->_cachedThumbnail->_scummVMThumb) { Common::MemoryWriteStreamDynamic scummVMthumbStream(DisposeAfterUse::YES); if (_gameRef->_cachedThumbnail->_scummVMThumb->writeBMPToStream(&scummVMthumbStream)) { _saveStream->writeUint32LE(scummVMthumbStream.size()); _saveStream->write(scummVMthumbStream.getData(), scummVMthumbStream.size()); } else { _saveStream->writeUint32LE(0); } thumbnailOK = true; } } if (!thumbnailOK) { putDWORD(0); } // in any case, destroy the cached thumbnail once used delete _gameRef->_cachedThumbnail; _gameRef->_cachedThumbnail = nullptr; uint32 dataOffset = _offset + sizeof(uint32) + // data offset sizeof(uint32) + strlen(desc) + 1 + // description sizeof(uint32); // timestamp putDWORD(dataOffset); putString(desc); g_system->getTimeAndDate(_savedTimestamp); putTimeDate(_savedTimestamp); _savedPlayTime = g_system->getMillis(); _saveStream->writeUint32LE(_savedPlayTime); } return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool UIEntity::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(ENTITY_CONTAINER) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(DISABLED) TOKEN_TABLE(VISIBLE) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(NAME) TOKEN_TABLE(ENTITY) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE_END byte *params; int cmd = 2; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ENTITY_CONTAINER) { _gameRef->LOG(0, "'ENTITY_CONTAINER' keyword expected."); return STATUS_FAILED; } buffer = params; } while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_DISABLED: parser.scanStr((char *)params, "%b", &_disable); break; case TOKEN_VISIBLE: parser.scanStr((char *)params, "%b", &_visible); break; case TOKEN_ENTITY: if (DID_FAIL(setEntity((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in ENTITY_CONTAINER definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading ENTITY_CONTAINER definition"); return STATUS_FAILED; } correctSize(); if (_gameRef->_editorMode) { _width = 50; _height = 50; } return STATUS_OK; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool UIEdit::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(DISABLED) TOKEN_TABLE(VISIBLE) TOKEN_TABLE(BACK) TOKEN_TABLE(IMAGE) TOKEN_TABLE(FONT_SELECTED) TOKEN_TABLE(FONT) TOKEN_TABLE(TEXT) TOKEN_TABLE(X) TOKEN_TABLE(Y) TOKEN_TABLE(WIDTH) TOKEN_TABLE(HEIGHT) TOKEN_TABLE(CURSOR_BLINK_RATE) TOKEN_TABLE(CURSOR) TOKEN_TABLE(FRAME_WIDTH) TOKEN_TABLE(NAME) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(PARENT_NOTIFY) TOKEN_TABLE(MAX_LENGTH) TOKEN_TABLE(EDITOR_PROPERTY) TOKEN_TABLE(EDIT) TOKEN_TABLE(CAPTION) TOKEN_TABLE_END byte *params; int cmd = 2; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_EDIT) { _gameRef->LOG(0, "'EDIT' keyword expected."); return STATUS_FAILED; } buffer = params; } while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_BACK: delete _back; _back = new UITiledImage(_gameRef); if (!_back || DID_FAIL(_back->loadFile((char *)params))) { delete _back; _back = NULL; cmd = PARSERR_GENERIC; } break; case TOKEN_IMAGE: delete _image; _image = new BaseSprite(_gameRef); if (!_image || DID_FAIL(_image->loadFile((char *)params))) { delete _image; _image = NULL; cmd = PARSERR_GENERIC; } break; case TOKEN_FONT: if (_font) { _gameRef->_fontStorage->removeFont(_font); } _font = _gameRef->_fontStorage->addFont((char *)params); if (!_font) { cmd = PARSERR_GENERIC; } break; case TOKEN_FONT_SELECTED: if (_fontSelected) { _gameRef->_fontStorage->removeFont(_fontSelected); } _fontSelected = _gameRef->_fontStorage->addFont((char *)params); if (!_fontSelected) { cmd = PARSERR_GENERIC; } break; case TOKEN_TEXT: setText((char *)params); _gameRef->_stringTable->expand(&_text); break; case TOKEN_X: parser.scanStr((char *)params, "%d", &_posX); break; case TOKEN_Y: parser.scanStr((char *)params, "%d", &_posY); break; case TOKEN_WIDTH: parser.scanStr((char *)params, "%d", &_width); break; case TOKEN_HEIGHT: parser.scanStr((char *)params, "%d", &_height); break; case TOKEN_MAX_LENGTH: parser.scanStr((char *)params, "%d", &_maxLength); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_CURSOR: delete _cursor; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { delete _cursor; _cursor = NULL; cmd = PARSERR_GENERIC; } break; case TOKEN_CURSOR_BLINK_RATE: parser.scanStr((char *)params, "%d", &_cursorBlinkRate); break; case TOKEN_FRAME_WIDTH: parser.scanStr((char *)params, "%d", &_frameWidth); break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_PARENT_NOTIFY: parser.scanStr((char *)params, "%b", &_parentNotify); break; case TOKEN_DISABLED: parser.scanStr((char *)params, "%b", &_disable); break; case TOKEN_VISIBLE: parser.scanStr((char *)params, "%b", &_visible); break; case TOKEN_EDITOR_PROPERTY: parseEditorProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in EDIT definition"); return STATUS_FAILED; } if (cmd == PARSERR_GENERIC) { _gameRef->LOG(0, "Error loading EDIT definition"); return STATUS_FAILED; } correctSize(); return STATUS_OK; }
bool ScScript::executeInstruction() { bool ret = STATUS_OK; uint32 dw; const char *str = nullptr; //ScValue* op = new ScValue(_gameRef); _operand->cleanup(); ScValue *op1; ScValue *op2; uint32 inst = getDWORD(); switch (inst) { case II_DEF_VAR: _operand->setNULL(); dw = getDWORD(); if (_scopeStack->_sP < 0) { _globals->setProp(_symbols[dw], _operand); } else { _scopeStack->getTop()->setProp(_symbols[dw], _operand); } break; case II_DEF_GLOB_VAR: case II_DEF_CONST_VAR: { dw = getDWORD(); /* char *temp = _symbols[dw]; // TODO delete */ // only create global var if it doesn't exist if (!_engine->_globals->propExists(_symbols[dw])) { _operand->setNULL(); _engine->_globals->setProp(_symbols[dw], _operand, false, inst == II_DEF_CONST_VAR); } break; } case II_RET: if (_scopeStack->_sP >= 0 && _callStack->_sP >= 0) { _scopeStack->pop(); _iP = (uint32)_callStack->pop()->getInt(); } else { if (_thread) { _state = SCRIPT_THREAD_FINISHED; } else { if (_numEvents == 0 && _numMethods == 0) { _state = SCRIPT_FINISHED; } else { _state = SCRIPT_PERSISTENT; } } } break; case II_RET_EVENT: _state = SCRIPT_FINISHED; break; case II_CALL: dw = getDWORD(); _operand->setInt(_iP); _callStack->push(_operand); _iP = dw; break; case II_CALL_BY_EXP: { // push var // push string str = _stack->pop()->getString(); char *methodName = new char[strlen(str) + 1]; strcpy(methodName, str); ScValue *var = _stack->pop(); if (var->_type == VAL_VARIABLE_REF) { var = var->_valRef; } bool res = STATUS_FAILED; bool triedNative = false; // we are already calling this method, try native if (_thread && _methodThread && strcmp(methodName, _threadEvent) == 0 && var->_type == VAL_NATIVE && _owner == var->getNative()) { triedNative = true; res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName); } if (DID_FAIL(res)) { if (var->isNative() && var->getNative()->canHandleMethod(methodName)) { if (!_unbreakable) { _waitScript = var->getNative()->invokeMethodThread(methodName); if (!_waitScript) { _stack->correctParams(0); runtimeError("Error invoking method '%s'.", methodName); _stack->pushNULL(); } else { _state = SCRIPT_WAITING_SCRIPT; _waitScript->copyParameters(_stack); } } else { // can call methods in unbreakable mode _stack->correctParams(0); runtimeError("Cannot call method '%s'. Ignored.", methodName); _stack->pushNULL(); } delete[] methodName; break; } /* ScValue* val = var->getProp(MethodName); if (val) { dw = GetFuncPos(val->getString()); if (dw==0) { TExternalFunction* f = GetExternal(val->getString()); if (f) { ExternalCall(_stack, _thisStack, f); } else{ // not an internal nor external, try for native function _gameRef->ExternalCall(this, _stack, _thisStack, val->getString()); } } else{ _operand->setInt(_iP); _callStack->Push(_operand); _iP = dw; } } */ else { res = STATUS_FAILED; if (var->_type == VAL_NATIVE && !triedNative) { res = var->_valNative->scCallMethod(this, _stack, _thisStack, methodName); } if (DID_FAIL(res)) { _stack->correctParams(0); runtimeError("Call to undefined method '%s'. Ignored.", methodName); _stack->pushNULL(); } } } delete[] methodName; } break; case II_EXTERNAL_CALL: { uint32 symbolIndex = getDWORD(); TExternalFunction *f = getExternal(_symbols[symbolIndex]); if (f) { externalCall(_stack, _thisStack, f); } else { _gameRef->externalCall(this, _stack, _thisStack, _symbols[symbolIndex]); } break; } case II_SCOPE: _operand->setNULL(); _scopeStack->push(_operand); break; case II_CORRECT_STACK: dw = getDWORD(); // params expected _stack->correctParams(dw); break; case II_CREATE_OBJECT: _operand->setObject(); _stack->push(_operand); break; case II_POP_EMPTY: _stack->pop(); break; case II_PUSH_VAR: { ScValue *var = getVar(_symbols[getDWORD()]); if (false && /*var->_type==VAL_OBJECT ||*/ var->_type == VAL_NATIVE) { _operand->setReference(var); _stack->push(_operand); } else { _stack->push(var); } break; } case II_PUSH_VAR_REF: { ScValue *var = getVar(_symbols[getDWORD()]); _operand->setReference(var); _stack->push(_operand); break; } case II_POP_VAR: { char *varName = _symbols[getDWORD()]; ScValue *var = getVar(varName); if (var) { ScValue *val = _stack->pop(); if (!val) { runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum."); var->setNULL(); } else { if (val->getType() == VAL_VARIABLE_REF) { val = val->_valRef; } if (val->_type == VAL_NATIVE) { var->setValue(val); } else { var->copy(val); } } } break; } case II_PUSH_VAR_THIS: _stack->push(_thisStack->getTop()); break; case II_PUSH_INT: _stack->pushInt((int)getDWORD()); break; case II_PUSH_FLOAT: _stack->pushFloat(getFloat()); break; case II_PUSH_BOOL: _stack->pushBool(getDWORD() != 0); break; case II_PUSH_STRING: _stack->pushString(getString()); break; case II_PUSH_NULL: _stack->pushNULL(); break; case II_PUSH_THIS_FROM_STACK: _operand->setReference(_stack->getTop()); _thisStack->push(_operand); break; case II_PUSH_THIS: _operand->setReference(getVar(_symbols[getDWORD()])); _thisStack->push(_operand); break; case II_POP_THIS: _thisStack->pop(); break; case II_PUSH_BY_EXP: { str = _stack->pop()->getString(); ScValue *val = _stack->pop()->getProp(str); if (val) { _stack->push(val); } else { _stack->pushNULL(); } break; } case II_POP_BY_EXP: { str = _stack->pop()->getString(); ScValue *var = _stack->pop(); ScValue *val = _stack->pop(); if (val == nullptr) { runtimeError("Script stack corruption detected. Please report this script at WME bug reports forum."); var->setNULL(); } else { var->setProp(str, val); } break; } case II_PUSH_REG1: _stack->push(_reg1); break; case II_POP_REG1: _reg1->copy(_stack->pop()); break; case II_JMP: _iP = getDWORD(); break; case II_JMP_FALSE: { dw = getDWORD(); //if (!_stack->pop()->getBool()) _iP = dw; ScValue *val = _stack->pop(); if (!val) { runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?"); } else { if (!val->getBool()) { _iP = dw; } } break; } case II_ADD: op2 = _stack->pop(); op1 = _stack->pop(); if (op1->isNULL() || op2->isNULL()) { _operand->setNULL(); } else if (op1->getType() == VAL_STRING || op2->getType() == VAL_STRING) { char *tempStr = new char [strlen(op1->getString()) + strlen(op2->getString()) + 1]; strcpy(tempStr, op1->getString()); strcat(tempStr, op2->getString()); _operand->setString(tempStr); delete[] tempStr; } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) { _operand->setInt(op1->getInt() + op2->getInt()); } else { _operand->setFloat(op1->getFloat() + op2->getFloat()); } _stack->push(_operand); break; case II_SUB: op2 = _stack->pop(); op1 = _stack->pop(); if (op1->isNULL() || op2->isNULL()) { _operand->setNULL(); } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) { _operand->setInt(op1->getInt() - op2->getInt()); } else { _operand->setFloat(op1->getFloat() - op2->getFloat()); } _stack->push(_operand); break; case II_MUL: op2 = _stack->pop(); op1 = _stack->pop(); if (op1->isNULL() || op2->isNULL()) { _operand->setNULL(); } else if (op1->getType() == VAL_INT && op2->getType() == VAL_INT) { _operand->setInt(op1->getInt() * op2->getInt()); } else { _operand->setFloat(op1->getFloat() * op2->getFloat()); } _stack->push(_operand); break; case II_DIV: op2 = _stack->pop(); op1 = _stack->pop(); if (op2->getFloat() == 0.0f) { runtimeError("Division by zero."); } if (op1->isNULL() || op2->isNULL() || op2->getFloat() == 0.0f) { _operand->setNULL(); } else { _operand->setFloat(op1->getFloat() / op2->getFloat()); } _stack->push(_operand); break; case II_MODULO: op2 = _stack->pop(); op1 = _stack->pop(); if (op2->getInt() == 0) { runtimeError("Division by zero."); } if (op1->isNULL() || op2->isNULL() || op2->getInt() == 0) { _operand->setNULL(); } else { _operand->setInt(op1->getInt() % op2->getInt()); } _stack->push(_operand); break; case II_NOT: op1 = _stack->pop(); //if (op1->isNULL()) _operand->setNULL(); if (op1->isNULL()) { _operand->setBool(true); } else { _operand->setBool(!op1->getBool()); } _stack->push(_operand); break; case II_AND: op2 = _stack->pop(); op1 = _stack->pop(); if (op1 == nullptr || op2 == nullptr) { runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?"); _operand->setBool(false); } else { _operand->setBool(op1->getBool() && op2->getBool()); } _stack->push(_operand); break; case II_OR: op2 = _stack->pop(); op1 = _stack->pop(); if (op1 == nullptr || op2 == nullptr) { runtimeError("Script corruption detected. Did you use '=' instead of '==' for comparison?"); _operand->setBool(false); } else { _operand->setBool(op1->getBool() || op2->getBool()); } _stack->push(_operand); break; case II_CMP_EQ: op2 = _stack->pop(); op1 = _stack->pop(); /* if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(false); else if (op1->isNative() && op2->isNative()) { _operand->setBool(op1->getNative() == op2->getNative()); } else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING) { _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())==0); } else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() == op2->getFloat()); } else{ _operand->setBool(op1->getInt() == op2->getInt()); } */ _operand->setBool(ScValue::compare(op1, op2) == 0); _stack->push(_operand); break; case II_CMP_NE: op2 = _stack->pop(); op1 = _stack->pop(); /* if ((op1->isNULL() && !op2->isNULL()) || (!op1->isNULL() && op2->isNULL())) _operand->setBool(true); else if (op1->isNative() && op2->isNative()) { _operand->setBool(op1->getNative() != op2->getNative()); } else if (op1->getType()==VAL_STRING || op2->getType()==VAL_STRING) { _operand->setBool(scumm_stricmp(op1->getString(), op2->getString())!=0); } else if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() != op2->getFloat()); } else{ _operand->setBool(op1->getInt() != op2->getInt()); } */ _operand->setBool(ScValue::compare(op1, op2) != 0); _stack->push(_operand); break; case II_CMP_L: op2 = _stack->pop(); op1 = _stack->pop(); /* if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() < op2->getFloat()); } else _operand->setBool(op1->getInt() < op2->getInt()); */ _operand->setBool(ScValue::compare(op1, op2) < 0); _stack->push(_operand); break; case II_CMP_G: op2 = _stack->pop(); op1 = _stack->pop(); /* if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() > op2->getFloat()); } else _operand->setBool(op1->getInt() > op2->getInt()); */ _operand->setBool(ScValue::compare(op1, op2) > 0); _stack->push(_operand); break; case II_CMP_LE: op2 = _stack->pop(); op1 = _stack->pop(); /* if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() <= op2->getFloat()); } else _operand->setBool(op1->getInt() <= op2->getInt()); */ _operand->setBool(ScValue::compare(op1, op2) <= 0); _stack->push(_operand); break; case II_CMP_GE: op2 = _stack->pop(); op1 = _stack->pop(); /* if (op1->getType()==VAL_FLOAT && op2->getType()==VAL_FLOAT) { _operand->setBool(op1->getFloat() >= op2->getFloat()); } else _operand->setBool(op1->getInt() >= op2->getInt()); */ _operand->setBool(ScValue::compare(op1, op2) >= 0); _stack->push(_operand); break; case II_CMP_STRICT_EQ: op2 = _stack->pop(); op1 = _stack->pop(); //_operand->setBool(op1->getType()==op2->getType() && op1->getFloat()==op2->getFloat()); _operand->setBool(ScValue::compareStrict(op1, op2) == 0); _stack->push(_operand); break; case II_CMP_STRICT_NE: op2 = _stack->pop(); op1 = _stack->pop(); //_operand->setBool(op1->getType()!=op2->getType() || op1->getFloat()!=op2->getFloat()); _operand->setBool(ScValue::compareStrict(op1, op2) != 0); _stack->push(_operand); break; case II_DBG_LINE: { int newLine = getDWORD(); if (newLine != _currentLine) { _currentLine = newLine; } break; } default: _gameRef->LOG(0, "Fatal: Invalid instruction %d ('%s', line %d, IP:0x%x)\n", inst, _filename, _currentLine, _iP - sizeof(uint32)); _state = SCRIPT_FINISHED; ret = STATUS_FAILED; } // switch(instruction) //delete op; return ret; }
TOKEN_DEF_END ////////////////////////////////////////////////////////////////////////// bool BaseRegion::loadBuffer(byte *buffer, bool complete) { TOKEN_TABLE_START(commands) TOKEN_TABLE(REGION) TOKEN_TABLE(TEMPLATE) TOKEN_TABLE(NAME) TOKEN_TABLE(ACTIVE) TOKEN_TABLE(POINT) TOKEN_TABLE(CAPTION) TOKEN_TABLE(SCRIPT) TOKEN_TABLE(EDITOR_SELECTED_POINT) TOKEN_TABLE(PROPERTY) TOKEN_TABLE_END byte *params; int cmd; BaseParser parser; if (complete) { if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_REGION) { _gameRef->LOG(0, "'REGION' keyword expected."); return STATUS_FAILED; } buffer = params; } for (uint32 i = 0; i < _points.size(); i++) { delete _points[i]; } _points.clear(); while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { switch (cmd) { case TOKEN_TEMPLATE: if (DID_FAIL(loadFile((char *)params))) { cmd = PARSERR_GENERIC; } break; case TOKEN_NAME: setName((char *)params); break; case TOKEN_CAPTION: setCaption((char *)params); break; case TOKEN_ACTIVE: parser.scanStr((char *)params, "%b", &_active); break; case TOKEN_POINT: { int x, y; parser.scanStr((char *)params, "%d,%d", &x, &y); _points.add(new BasePoint(x, y)); } break; case TOKEN_SCRIPT: addScript((char *)params); break; case TOKEN_EDITOR_SELECTED_POINT: parser.scanStr((char *)params, "%d", &_editorSelectedPoint); break; case TOKEN_PROPERTY: parseProperty(params, false); break; } } if (cmd == PARSERR_TOKENNOTFOUND) { _gameRef->LOG(0, "Syntax error in REGION definition"); return STATUS_FAILED; } createRegion(); return STATUS_OK; }
int WintermuteEngine::init() { BaseEngine::createInstance(_targetName, _gameDescription->adDesc.gameId, _gameDescription->adDesc.language, _gameDescription->targetExecutable); // check dependencies for games with high resolution assets #if not defined(USE_PNG) || not defined(USE_JPEG) || not defined(USE_VORBIS) if (!(_gameDescription->adDesc.flags & GF_LOWSPEC_ASSETS)) { GUI::MessageDialog dialog("This game requires PNG, JPEG and Vorbis support."); dialog.runModal(); delete _game; _game = nullptr; return false; } #endif _game = new AdGame(_targetName); if (!_game) { return 1; } BaseEngine::instance().setGameRef(_game); BasePlatform::initialize(this, _game, 0, nullptr); _game->initConfManSettings(); // load general game settings _game->initialize1(); // set gameId, for savegame-naming: _game->setGameTargetName(_targetName); if (DID_FAIL(_game->loadSettings("startup.settings"))) { _game->LOG(0, "Error loading game settings."); delete _game; _game = nullptr; warning("Some of the essential files are missing. Please reinstall."); return 2; } _game->initialize2(); bool ret = _game->initRenderer(); if (DID_FAIL(ret)) { _game->LOG(ret, "Error initializing renderer. Exiting."); delete _game; _game = nullptr; return 3; } _game->initialize3(); // initialize sound manager (non-fatal if we fail) ret = _game->_soundMgr->initialize(); if (DID_FAIL(ret)) { _game->LOG(ret, "Sound is NOT available."); } // load game uint32 dataInitStart = g_system->getMillis(); if (DID_FAIL(_game->loadGameSettingsFile())) { _game->LOG(ret, "Error loading game file. Exiting."); delete _game; _game = nullptr; return false; } _game->_renderer->_ready = true; _game->_miniUpdateEnabled = true; _game->LOG(0, "Engine initialized in %d ms", g_system->getMillis() - dataInitStart); _game->LOG(0, ""); if (ConfMan.hasKey("save_slot")) { int slot = ConfMan.getInt("save_slot"); _game->loadGame(slot); } _game->_scEngine->attachMonitor(_dbgController); // all set, ready to go return 0; }