CViewPort::CViewPort(int width, int height, TRect& bound, ILandscape* landscape): mWidth(width), mHeight(height), mHalfWidth(width / 2.0f), mHalfHeight(height / 2.0f), mLandscape(landscape), mMagnitude(0.0f) { // Calculate scale between display and viewport TDisplayMode displayMode; CLayerManager::instance()->getRenderLayer()->getDeviceDisplayMode(displayMode); CVector2D scale((float)displayMode.mWidth / mWidth, (float)displayMode.mHeight / mHeight); CLayerManager::instance()->getRenderLayer()->setSpriteScale(scale); // Set bound mBound.mX0 = bound.mX0; mBound.mY0 = bound.mY0; mBound.mX1 = bound.mX1; mBound.mY1 = bound.mY1; // By default view port position is (0, 0), so fix it for landscape fixPosition(); mNewPosition = mPosition; updateLeftTop(); }
void CViewPort::update() { mPosition = mNewPosition; fixPosition(); processShake(); updateLeftTop(); }
bool Actor::handleOrder(TrackOrder &order, EntityEvent event, const EntityEventParams ¶ms) { if(event == EntityEvent::init_order || event == EntityEvent::think) { order.m_time_for_update -= timeDelta(); const Entity *target = refEntity(order.m_target); if(!target) return false; if(order.m_time_for_update < 0.0f) { fixPosition(); int3 cur_pos = (int3)pos(); int3 target_pos; FBox target_box = target->boundingBox(); if(!world()->findClosestPos(target_pos, cur_pos, enclosingIBox(target_box), ref())) return failOrder(); order.m_path_pos = PathPos(); if(!world()->findPath(order.m_path, cur_pos, target_pos, ref())) return failOrder(); order.m_time_for_update = 0.25f; } if(distance(boundingBox(), target->boundingBox()) <= order.m_min_distance) return false; if(event == EntityEvent::init_order) { if(order.m_please_run && m_proto.simpleAnimId(Action::run, m_stance) == -1) order.m_please_run = 0; if(!animate(order.m_please_run? Action::run : Action::walk)) return failOrder(); } FollowPathResult result = order.needCancel()? FollowPathResult::finished : followPath(order.m_path, order.m_path_pos, order.m_please_run); if(result != FollowPathResult::moved) return false; } if(order.m_path.length(order.m_path_pos) > 1.0f) { if(event == EntityEvent::anim_finished && m_stance == Stance::crouch) { animate(m_action); } if(event == EntityEvent::step) { SurfaceId standing_surface = surfaceUnder(); playSound(m_proto.step_sounds[m_stance][standing_surface], pos()); } } return true; }
void Virus::move(Frame const &limits) { int minx = limits.getPX() + PADDING_SPAWN; int maxx = limits.getPX() + limits.getWidth() - PADDING_SPAWN; int miny = limits.getPY() + PADDING_SPAWN; int maxy = limits.getPY() + limits.getHeight() - PADDING_SPAWN; _position += _direction; fixPosition(minx, maxx, miny, maxy); if (_clock.GetElapsedTime() >= _freq) { changeDirection(); _clock.Reset(); } }
void SelectiveScroll::deaccelerateScrolling(float dt) { if (_dragging) { this->unschedule(schedule_selector(SelectiveScroll::deaccelerateScrolling)); return; } float newX, newY; Vec2 maxInset, minInset; _container->setPosition(_container->getPosition() + _scrollDistance); if (_bounceable) { maxInset = _maxInset; minInset = _minInset; } else { maxInset = this->maxContainerOffset(); minInset = this->minContainerOffset(); } newX = _container->getPosition().x; newY = _container->getPosition().y; _scrollDistance = _scrollDistance * SCROLL_DEACCEL_RATE; this->setContentOffset(Vec2(newX, newY)); if ((fabsf(_scrollDistance.x) <= SCROLL_DEACCEL_DIST && fabsf(_scrollDistance.y) <= SCROLL_DEACCEL_DIST) || newX >= maxInset.x || newX <= minInset.x) { this->unschedule(schedule_selector(SelectiveScroll::deaccelerateScrolling)); this->relocateContainer(true); fixPosition(); } }
bool KoToolDockMoveManager::check(int& x, int& y, int& w, int& h, bool change) { int w1 = QMIN(QMAX(minSize.width(), w), maxSize.width()); int h1 = QMIN(QMAX(minSize.height(), h), maxSize.height()); bool f1 = (w1-w)+(h1-h) == 0; if (change) { if (mirrorX) x += w - w1; w = w1; if (mirrorY) y += h - h1; h = h1; } int x0 = x; int y0 = y; int w0 = w; int h0 = h; if (isDoMove) emit fixPosition(x0,y0,w0,h0); else emit fixSize(x0,y0,w0,h0); bool f2 = (x0==x)&&(y0==y)&&(w0==w)&&(h0==h); if (change) { x = x0; y = y0; w = w0; h = h0; } return f1&&f2; }
/** * Adjust position of a sprite * This function adjusts the position of a sprite moving it until * certain criteria is matched. According to priority and control line * data, a sprite may not always appear at the location we specified. * This behavior is also known as the "Budin-Sonneveld effect". * * @param n view table entry number */ void AgiEngine::fixPosition(int16 screenObjNr) { ScreenObjEntry *screenObj = &_game.screenObjTable[screenObjNr]; fixPosition(screenObj); }
/** * Update position of objects * This function updates the position of all animated, updating view * table entries according to its motion type, step size, etc. The * new position must be valid according to the sprite positioning * rules, otherwise the previous position will be kept. */ void AgiEngine::updatePosition() { ScreenObjEntry *screenObj; int x, y, oldX, oldY, border; setVar(VM_VAR_BORDER_CODE, 0); setVar(VM_VAR_BORDER_TOUCH_EGO, 0); setVar(VM_VAR_BORDER_TOUCH_OBJECT, 0); for (screenObj = _game.screenObjTable; screenObj < &_game.screenObjTable[SCREENOBJECTS_MAX]; screenObj++) { if ((screenObj->flags & (fAnimated | fUpdate | fDrawn)) != (fAnimated | fUpdate | fDrawn)) { continue; } if (screenObj->stepTimeCount > 1) { screenObj->stepTimeCount--; continue; } screenObj->stepTimeCount = screenObj->stepTime; x = oldX = screenObj->xPos; y = oldY = screenObj->yPos; // If object has moved, update its position if (!(screenObj->flags & fUpdatePos)) { int dx[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 }; int dy[9] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 }; x += screenObj->stepSize * dx[screenObj->direction]; y += screenObj->stepSize * dy[screenObj->direction]; } // Now check if it touched the borders border = 0; // Check left/right borders if (getVersion() == 0x3086) { // KQ4 interpreter does a different comparison on x // The interpreter before (2.917) and after that (3.098) don't do them that way // This difference is required for at least Sarien bug #192 // KQ4: room 135, hen moves from the center of the screen to the left border, // but it doesn't disappear. if (x <= 0) { x = 0; border = 4; } } else { // regular comparison if (x < 0) { x = 0; border = 4; } } // } else if (v->entry == 0 && x == 0 && v->flags & fAdjEgoXY) { // should not be required // // Extra test to walk west clicking the mouse // x = 0; // border = 4; if (!border) { if (x + screenObj->xSize > SCRIPT_WIDTH) { x = SCRIPT_WIDTH - screenObj->xSize; border = 2; } } // Check top/bottom borders. if (y - screenObj->ySize < -1) { y = screenObj->ySize - 1; border = 1; } else if (y > SCRIPT_HEIGHT - 1) { y = SCRIPT_HEIGHT - 1; border = 3; } else if ((!(screenObj->flags & fIgnoreHorizon)) && y <= _game.horizon) { debugC(4, kDebugLevelSprites, "y = %d, horizon = %d", y, _game.horizon); y = _game.horizon + 1; border = 1; } // Test new position. rollback if test fails screenObj->xPos = x; screenObj->yPos = y; if (checkCollision(screenObj) || !checkPriority(screenObj)) { screenObj->xPos = oldX; screenObj->yPos = oldY; border = 0; fixPosition(screenObj->objectNr); } if (border) { if (isEgoView(screenObj)) { setVar(VM_VAR_BORDER_TOUCH_EGO, border); } else { setVar(VM_VAR_BORDER_CODE, screenObj->objectNr); setVar(VM_VAR_BORDER_TOUCH_OBJECT, border); } if (screenObj->motionType == kMotionMoveObj) { motionMoveObjStop(screenObj); } } screenObj->flags &= ~fUpdatePos; } }
/** * Update position of objects * This function updates the position of all animated, updating view * table entries according to its motion type, step size, etc. The * new position must be valid according to the sprite positioning * rules, otherwise the previous position will be kept. */ void AgiEngine::updatePosition() { VtEntry *v; int x, y, oldX, oldY, border; _game.vars[vBorderCode] = 0; _game.vars[vBorderTouchEgo] = 0; _game.vars[vBorderTouchObj] = 0; for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) { if ((v->flags & (ANIMATED | UPDATE | DRAWN)) != (ANIMATED | UPDATE | DRAWN)) { continue; } if (v->stepTimeCount != 0) { if (--v->stepTimeCount != 0) continue; } v->stepTimeCount = v->stepTime; x = oldX = v->xPos; y = oldY = v->yPos; // If object has moved, update its position if (~v->flags & UPDATE_POS) { int dx[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 }; int dy[9] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 }; x += v->stepSize * dx[v->direction]; y += v->stepSize * dy[v->direction]; } // Now check if it touched the borders border = 0; // Check left/right borders if (x < 0) { x = 0; border = 4; } else if (x <= 0 && getVersion() == 0x3086) { // KQ4 x = 0; // See Sarien bug #590462 border = 4; } else if (v->entry == 0 && x == 0 && v->flags & ADJ_EGO_XY) { // Extra test to walk west clicking the mouse x = 0; border = 4; } else if (x + v->xSize > _WIDTH) { x = _WIDTH - v->xSize; border = 2; } // Check top/bottom borders. if (y - v->ySize + 1 < 0) { y = v->ySize - 1; border = 1; } else if (y > _HEIGHT - 1) { y = _HEIGHT - 1; border = 3; } else if ((~v->flags & IGNORE_HORIZON) && y <= _game.horizon) { debugC(4, kDebugLevelSprites, "y = %d, horizon = %d", y, _game.horizon); y = _game.horizon + 1; border = 1; } // Test new position. rollback if test fails v->xPos = x; v->yPos = y; if (checkCollision(v) || !checkPriority(v)) { v->xPos = oldX; v->yPos = oldY; border = 0; fixPosition(v->entry); } if (border != 0) { if (isEgoView(v)) { _game.vars[vBorderTouchEgo] = border; } else { _game.vars[vBorderCode] = v->entry; _game.vars[vBorderTouchObj] = border; } if (v->motion == MOTION_MOVE_OBJ) { inDestination(v); } } v->flags &= ~UPDATE_POS; } }