void Fontinfo::clear() { if (is_vertical) SetXY(area_x-size()-pitch_x, 0); else if (is_bidirect) SetXY(area_x, 0); else SetXY(0, 0); indent = 0; style = default_encoding; font_size_mod = 0; }
/** * This method is used to set the projection x/y. The Set forces an attempted * calculation of the corresponding latitude/longitude position. This may or * may not be successful and a status is returned as such. * * @param x X coordinate of the projection in units that are the same as the * radii in the label * * @param y Y coordinate of the projection in units that are the same as the * radii in the label * * @return bool */ bool SimpleCylindrical::SetCoordinate(const double x, const double y) { // Save the coordinate SetXY(x, y); // Compute latitude and make sure it is not above 90 m_latitude = GetY() / m_equatorialRadius; if ((fabs(m_latitude) - HALFPI) > DBL_EPSILON) { m_good = false; return m_good; } // Compute longitude m_longitude = m_centerLongitude + GetX() / m_equatorialRadius; // Convert to degrees m_latitude *= 180.0 / PI; m_longitude *= 180.0 / PI; // Cleanup the longitude if (m_longitudeDirection == PositiveWest) m_longitude *= -1.0; // Do these if the projection is circular // m_longitude = To360Domain (m_longitude); // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude); m_good = true; return m_good; }
///knock player back. used in collisions void Player::KnockBack() { if (Alive()) { SetXY(_lastX, _lastY); } }
/// Print a label void AddLabel(const wxString& texte) { // We are in a new page, then we must add a page if ((m_xCount == 0) && (m_yCount == 0)) { AddPage(); } double posX = m_marginLeft+(m_xCount*(m_width+m_xSpace)); double posY = m_marginTop+(m_yCount*(m_height+m_ySpace)); SetXY(posX+3, posY+3); MultiCell(m_width, m_lineHeight, texte); m_yCount++; if (m_yCount == m_yNumber) { // End of column reached, we start a new one m_xCount++; m_yCount = 0; } if (m_xCount == m_xNumber) { // Page full, we start a new one m_xCount = 0; m_yCount = 0; } }
void Actor::ScaleTo( const RectI &rect, StretchType st ) { // width and height of rectangle float rect_width = (float) rect.GetWidth(); float rect_height = (float) rect.GetHeight(); if( rect_width < 0 ) SetRotationY( 180 ); if( rect_height < 0 ) SetRotationX( 180 ); // center of the rectangle float rect_cx = rect.left + rect_width/2; float rect_cy = rect.top + rect_height/2; // zoom fActor needed to scale the Actor to fill the rectangle float fNewZoomX = fabsf(rect_width / m_size.x); float fNewZoomY = fabsf(rect_height / m_size.y); float fNewZoom = 0.f; switch( st ) { case cover: fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomX : fNewZoomY; // use larger zoom break; case fit_inside: fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomY : fNewZoomX; // use smaller zoom break; } SetXY( rect_cx, rect_cy ); SetZoom( fNewZoom ); }
void Sprite::ScaleToClipped( float fWidth, float fHeight ) { m_fRememberedClipWidth = fWidth; m_fRememberedClipHeight = fHeight; if( !m_pTexture ) return; float fScaleFudgePercent = 0.15f; // scale up to this amount in one dimension to avoid clipping. // save the original X and Y. We're going to restore them later. float fOriginalX = GetX(); float fOriginalY = GetY(); if( fWidth != -1 && fHeight != -1 ) { // this is probably a background graphic or something not intended to be a CroppedSprite Sprite::StopUsingCustomCoords(); // first find the correct zoom Sprite::ScaleToCover( RectF(0, 0, fWidth, fHeight) ); // find which dimension is larger bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01; if( bXDimNeedsToBeCropped ) // crop X { float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth(); fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 ); float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; // generate a rectangle with new texture coordinates RectF fCustomImageRect( fPercentageToCutOffEachSide, 0, 1 - fPercentageToCutOffEachSide, 1 ); SetCustomImageRect( fCustomImageRect ); } else // crop Y { float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight(); fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 ); float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; // generate a rectangle with new texture coordinates RectF fCustomImageRect( 0, fPercentageToCutOffEachSide, 1, 1 - fPercentageToCutOffEachSide ); SetCustomImageRect( fCustomImageRect ); } m_size = RageVector2( fWidth, fHeight ); SetZoom( 1 ); } // restore original XY SetXY( fOriginalX, fOriginalY ); }
///knocks bad guy back. used for collisions. void BadGuy::KnockBack() { if (Alive()) { SetXY(_lastX, _lastY); } }
/***********************显示函数****************************/ void LcdShow(unchar x,unchar y,unchar *str) { SetXY(x,y); while(*str!='\0') { LCDWriteDate(*str); str++; } }
/** * This method is used to set the projection x/y. The Set forces an attempted * calculation of the corresponding latitude/longitude position. This may or * may not be successful and a status is returned as such. * * @param x X coordinate of the projection in units that are the same as the * radii in the label * * @param y Y coordinate of the projection in units that are the same as the * radii in the label * * @return bool */ bool LunarAzimuthalEqualArea::SetCoordinate(const double x, const double y) { // Save the coordinate SetXY(x, y); double RP = sqrt((x * x) + (y * y)); double lat, lon; if (y == 0.0 && x == 0.0) { lat = 0.0; lon = 0.0; return true; } double radius = m_equatorialRadius; double D = atan2(y, x); double test = RP / radius; if (abs(test) > 1.0) { return false; } double EPSILON = 0.0000000001; double PFAC = (HALFPI + m_maxLibration) / HALFPI; double E = PFAC * asin(RP / radius); lat = HALFPI - (acos(sin(D) * sin(E))); if (abs(HALFPI - abs(lat)) <= EPSILON) { lon = 0.0; } else { test = sin(E) * cos(D) / sin(HALFPI - lat); if (test > 1.0) test = 1.0; else if (test < -1.0) test = -1.0; lon = asin(test); } if (E >= HALFPI) { if (lon <= 0.0) lon = -PI - lon; else lon = PI - lon; } // Convert to degrees m_latitude = lat * 180.0 / Isis::PI; m_longitude = lon * 180.0 / Isis::PI; // Cleanup the latitude if (IsPlanetocentric()) m_latitude = ToPlanetocentric(m_latitude); m_good = true; return m_good; }
void Cluster::Shoot(const Point2i & pos, Double strength, Double angle) { SetCollisionModel(true, true, false ); // a bit hackish... // we do need to collide with objects, but if we allow for this, the clusters // will explode on spawn (because of colliding with each other) StartTimeout(); Camera::GetInstance()->FollowObject(this); ResetConstants(); SetXY( pos ); SetSpeed(strength, angle); }
///Moves bad guy towards it's target void BadGuy::Move(int targetX, int targetY) { if (Alive()) { _lastX = X; _lastY = Y; int deltaX = 0, deltaY = 0; if (rand() % 50 == 0) { if (rand() % 2 == 0){ deltaX += rand() % _stepDistance + 5; deltaY += rand() % _stepDistance + 5; } else { deltaX -= rand() % _stepDistance + 5; deltaY -= rand() % _stepDistance + 5; } } else { if (targetX < X) { deltaX -= _stepDistance; Direction = LEFT; } if (targetX > X) { deltaX += _stepDistance; Direction = RIGHT; } if (targetY < Y) { deltaY -= _stepDistance; Direction = UP; } if (targetY > Y) { deltaY += _stepDistance; Direction = DOWN; } } SetXY(X + deltaX, Y + deltaY); } }
void MouseInput::OnMsg(UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_LBUTTONDOWN: { lButtonState = BUTTON_DOWN; SetXY(lParam); } break; case WM_LBUTTONUP: { lButtonState = BUTTON_UP; SetXY(lParam); } break; case WM_LBUTTONDBLCLK: { lButtonState = BUTTON_DOUBLECLICK; SetXY(lParam); } break; case WM_RBUTTONDOWN: { rButtonState = BUTTON_DOWN; SetXY(lParam); } break; case WM_RBUTTONUP: { rButtonState = BUTTON_UP; SetXY(lParam); } break; case WM_RBUTTONDBLCLK: { rButtonState = BUTTON_DOUBLECLICK; SetXY(lParam); } case WM_MOUSEMOVE: { SetXY(lParam); SetMoveState(MOVE_MOVING); } break; } }
void Actor::StretchTo( const RectF &r ) { // width and height of rectangle float width = r.GetWidth(); float height = r.GetHeight(); // center of the rectangle float cx = r.left + width/2.0f; float cy = r.top + height/2.0f; // zoom fActor needed to scale the Actor to fill the rectangle float fNewZoomX = width / m_size.x; float fNewZoomY = height / m_size.y; SetXY( cx, cy ); SetZoomX( fNewZoomX ); SetZoomY( fNewZoomY ); }
void Player::MoveToScreen(Directions direction) { if (Alive()) { //set direction Direction = direction; //set player movement int newX = 0, newY = 0; if (direction == RIGHT) { printf("moving player screen right\n"); MapXLocation++; newX = _stepDistance * 2; newY = Y; } else if (direction == LEFT) { printf("moving player screen left\n"); MapXLocation--; newX = PLAYFIELD_WIDTH - _stepDistance * 2; newY = Y; } else if (direction == DOWN) { printf("moving player screen down\n"); MapYLocation++; newX = X; newY = _stepDistance * 2; } else if (direction == UP) { printf("moving player screen up\n"); MapYLocation--; newX = X; newY = PLAYFIELD_HEIGHT - _stepDistance * 2; } _lastX = newX; _lastY = newY; //move player SetXY(newX, newY); } }
/** * This method is used to set the projection x/y. The Set forces an attempted * calculation of the corresponding latitude/longitude position. This may or * may not be successful and a status is returned as such. * * @param x X coordinate of the projection in units that are the same as the * radii in the label * * @param y Y coordinate of the projection in units that are the same as the * radii in the label * * @return bool */ bool Sinusoidal::SetCoordinate(const double x, const double y) { // Save the coordinate SetXY(x, y); // Compute latitude and make sure it is not above 90 m_latitude = GetY() / m_equatorialRadius; if (fabs(m_latitude) > HALFPI) { if (fabs(HALFPI - fabs(m_latitude)) > DBL_EPSILON) { m_good = false; return m_good; } else if (m_latitude < 0.0) { m_latitude = -HALFPI; } else { m_latitude = HALFPI; } } // Compute longitude double coslat = cos(m_latitude); if (coslat <= DBL_EPSILON) { m_longitude = m_centerLongitude; } else { m_longitude = m_centerLongitude + GetX() / (m_equatorialRadius * coslat); } // Convert to degrees m_latitude *= 180.0 / PI; m_longitude *= 180.0 / PI; // Cleanup the longitude if (m_longitudeDirection == PositiveWest) m_longitude *= -1.0; // These need to be done for circular type projections // m_longitude = To360Domain (m_longitude); // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude); // Our double precision is not good once we pass a certain magnitude of // longitude. Prevent failures down the road by failing now. m_good = (fabs(m_longitude) < 1E10); return m_good; }
/// Shared sprite constructor commands void Sprite::setUpSprite(int x, int y) { _dstRect = new SDL_Rect(); SetXY(x,y); //set transparency if (NULL != _sprite) { if (SDL_SetColorKey(_sprite, SDL_SRCCOLORKEY, SDL_MapRGB(_sprite->format, 255, 0, 255)) != 0) { printf("Sprite setUpSprite: Unable to set transparency: %s\n", SDL_GetError()); SpriteError = true; } } else { SpriteError = true; } }
void Player::Move(Directions direction) { if (Alive()) { _lastX = X; _lastY = Y; //set direction Direction = direction; //set player movement int deltaX = 0, deltaY = 0; if (direction == RIGHT) deltaX += _stepDistance; else if (direction == LEFT) deltaX -= _stepDistance; else if (direction == DOWN) deltaY += _stepDistance; else if (direction == UP) deltaY -= _stepDistance; //move player SetXY(X + deltaX, Y + deltaY); } }
/* Create Camera at ( x, y ) */ Camera::Camera( double x, double y ) : _x( 0.0 ), _y( 0.0 ), _w( 0.0 ), _h( 0.0 ), _left( 0.0 ), _right( 0.0 ), _top( 0.0 ), _bottom( 0.0 ), _rect( SDL_Rect() ), _cache_half_screen_w( (double)( SCREEN_W/SCALE )/2.0 ), _cache_half_screen_h( (double)( SCREEN_H/SCALE )/2.0 ) { _w = _cache_half_screen_w; _h = _cache_half_screen_h; /* Move Camera to ( x, y ) */ SetXY( x, y ); };
BodyMemberParticle::BodyMemberParticle(Sprite& spr, const Point2i& position) : Particle("body_member_particle") , angle_rad(0) { SetCollisionModel(true, false, false); m_time_left_to_live = 100; // Bug #17408: make sure there's an available surface for the sprite spr.RefreshSurface(); image = new Sprite(spr.GetSurface()); image->EnableCaches(false, 0); // Some generic particle code requires it to be flipped ASSERT(image->GetWidth() && image->GetHeight()); SetXY(position); SetSize(image->GetSize()); SetOnTop(true); MSG_DEBUG("random.get", "BodyMemberParticle::BodyMemberParticle(...) speed vector length"); Double speed_vector_length = (Double)RandomSync().GetInt(10, 15); MSG_DEBUG("random.get", "BodyMemberParticle::BodyMemberParticle(...) speed vector angle"); Double speed_vector_angle = - RandomSync().GetDouble(0, 3); SetSpeed(speed_vector_length, speed_vector_angle); }
void Enemy::Create(CreateInfo obj){ SetXY(obj.x,obj.y); SetAngle(obj.angle); SetSpeed(obj.speed); SetVxVyFromSpeedAngle(); SetImage(obj.image); _bulletImg = obj.bulletImage; SetHP(obj.hp); _hitW = obj.hitW; _hitH = obj.hitH; SetShotWait(0); _angleShotB4 = 0; _shotCnt = 0; _BornFunc = obj.BornFunc; _ShotFunc = obj.ShotFunc; _MoveFunc = obj.MoveFunc; _DeadFunc = obj.DeadFunc; SetDrawExp(1.0); SetDrawParam(255); SetDeletable(false); //敵が画面外から侵入することを想定し、最初は画面外にあっても消さない SetRotateWhenDraw(obj.rotateWhenDraw); SetBorn(); }
void CluzookaCluster::Shoot(const Point2i & start_pos, Double strength, Double angle, uint recurse_times) { m_recursion_depth = recurse_times; #else void CluzookaCluster::Shoot(const Point2i & start_pos, Double strength, Double angle) { #endif Camera::GetInstance()->FollowObject(this); ResetConstants(); SetCollisionModel(true, true, false ); // a bit hackish... // we do need to collide with objects, but if we allow for this, the clusters // will explode on spawn (because of colliding with each other) SetXY(start_pos); SetSpeed(strength, angle); explode_with_timeout = true; StartTimeout(); m_time_before_spawn = 750; // make time a bit random to unsychronize particles m_time_before_spawn += RandomSync().GetDouble(-300, 100); }
bool PhysicalObj::PutOutOfGround(Double direction, Double max_distance) { if (IsOutsideWorld(Point2i(0, 0))) return false; if (IsInVacuum(Point2i(0, 0), false)) return true; Double dx = cos(direction); Double dy = sin(direction); // (dx,dy) is a normal vector (cos^2+sin^2==1) Double step=1; while (step<max_distance && !IsInVacuum(Point2i(dx * step, dy * step), false)) step+=1.0; if (step<max_distance) SetXY(Point2i(dx*step + GetX(), dy*step + GetY())); else return false; //Can't put the object out of the ground return true; }
void Sprite::ScaleToClipped( float fWidth, float fHeight ) { m_fRememberedClipWidth = fWidth; m_fRememberedClipHeight = fHeight; if( !m_pTexture ) return; int iSourceWidth = m_pTexture->GetSourceWidth(); int iSourceHeight = m_pTexture->GetSourceHeight(); // save the original X&Y. We're going to resore them later. float fOriginalX = GetX(); float fOriginalY = GetY(); if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite { float fCustomImageCoords[8] = { 0.02f, 0.78f, // top left 0.22f, 0.98f, // bottom left 0.98f, 0.22f, // bottom right 0.78f, 0.02f, // top right }; Sprite::SetCustomImageCoords( fCustomImageCoords ); if( fWidth != -1 && fHeight != -1) m_size = RageVector2( fWidth, fHeight ); else { /* If no crop size is set, then we're only being used to crop diagonal * banners so they look like regular ones. We don't actually care about * the size of the image, only that it has an aspect ratio of 4:1. */ m_size = RageVector2(256, 64); } SetZoom( 1 ); } else if( m_pTexture->GetID().filename.find( "(was rotated)" ) != m_pTexture->GetID().filename.npos && fWidth != -1 && fHeight != -1 ) { /* Dumb hack. Normally, we crop all sprites except for diagonal banners, * which are stretched. Low-res versions of banners need to do the same * thing as their full resolution counterpart, so the crossfade looks right. * However, low-res diagonal banners are un-rotated, to save space. BannerCache * drops the above text into the "filename" (which is otherwise unused for * these banners) to tell us this. */ Sprite::StopUsingCustomCoords(); m_size = RageVector2( fWidth, fHeight ); SetZoom( 1 ); } else if( fWidth != -1 && fHeight != -1 ) { // this is probably a background graphic or something not intended to be a CroppedSprite Sprite::StopUsingCustomCoords(); // first find the correct zoom Sprite::ScaleToCover( RectF(0,0,fWidth,fHeight) ); // find which dimension is larger bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01; if( bXDimNeedsToBeCropped ) // crop X { float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth(); float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; // generate a rectangle with new texture coordinates RectF fCustomImageRect( fPercentageToCutOffEachSide, 0, 1 - fPercentageToCutOffEachSide, 1 ); SetCustomImageRect( fCustomImageRect ); } else // crop Y { float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight(); float fPercentageToCutOffEachSide = fPercentageToCutOff / 2; // generate a rectangle with new texture coordinates RectF fCustomImageRect( 0, fPercentageToCutOffEachSide, 1, 1 - fPercentageToCutOffEachSide ); SetCustomImageRect( fCustomImageRect ); } m_size = RageVector2( fWidth, fHeight ); SetZoom( 1 ); } // restore original XY SetXY( fOriginalX, fOriginalY ); }
/** * This method is used to set the projection x/y. The Set forces an attempted * calculation of the corresponding latitude/longitude position. This may or * may not be successful and a status is returned as such. * * @param x X coordinate of the projection in units that are the same as the * radii in the label * * @param y Y coordinate of the projection in units that are the same as the * radii in the label * * @return bool */ bool PointPerspective::SetCoordinate(const double x, const double y) { // Save the coordinate SetXY(x, y); // Declare instance variables and calculate rho double rho, rp, con, com, z, sinz, cosz; const double epsilon = 1.0e-10; rho = sqrt(GetX() * GetX() + GetY() * GetY()); rp = rho / m_equatorialRadius; con = m_P - 1.0; com = m_P + 1.0; // Error calculating rho - should be less than equatorial radius if (rp > (sqrt(con / com))) { m_good = false; return m_good; } // Calculate the latitude and longitude m_longitude = m_centerLongitude; if (fabs(rho) <= epsilon) { m_latitude = m_centerLatitude; } else { if (rp <= epsilon) { sinz = 0.0; } else { sinz = (m_P - sqrt(1.0 - rp * rp * com / con)) / (con / rp + rp / con); } z = asin(sinz); sinz = sin(z); cosz = cos(z); con = cosz * m_sinph0 + GetY() * sinz * m_cosph0 / rho; if (con > 1.0) con = 1.0; if (con < -1.0) con = -1.0; m_latitude = asin(con); con = fabs(m_centerLatitude) - HALFPI; if (fabs(con) <= epsilon) { if (m_centerLatitude >= 0.0) { m_longitude += atan2(GetX(), -GetY()); } else { m_longitude += atan2(-GetX(), GetY()); } } else { con = cosz - m_sinph0 * sin(m_latitude); if ((fabs(con) >= epsilon) || (fabs(GetX()) >= epsilon)) { m_longitude += atan2(GetX() * sinz * m_cosph0, con * rho); } } } // Convert to degrees m_latitude *= 180.0 / PI; m_longitude *= 180.0 / PI; // Cleanup the longitude if (m_longitudeDirection == PositiveWest) m_longitude *= -1.0; // These need to be done for circular type projections m_longitude = To360Domain(m_longitude); if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude); // Cleanup the latitude if (IsPlanetocentric()) m_latitude = ToPlanetocentric(m_latitude); m_good = true; return m_good; }
// Move to a point with collision test collision_t PhysicalObj::NotifyMove(Point2d oldPos, Point2d newPos) { if (IsGhost()) return NO_COLLISION; Point2d contactPos; Double contactAngle; Point2d pos, offset; PhysicalObj* collided_obj = NULL; collision_t collision = NO_COLLISION; // Convert meters to pixels. oldPos *= PIXEL_PER_METER; newPos *= PIXEL_PER_METER; // Compute distance between old and new position. Double lg = oldPos.SquareDistance(newPos); MSG_DEBUG("physic.move", "%s moves (%s, %s) -> (%s, %s), square distance: %s", GetName().c_str(), Double2str(oldPos.x).c_str(), Double2str(oldPos.y).c_str(), Double2str(newPos.x).c_str(), Double2str(newPos.y).c_str(), Double2str(lg).c_str()); if (!lg.IsNotZero()) return NO_COLLISION; // Compute increments to move the object step by step from the old // to the new position. lg = sqrt(lg); offset = (newPos - oldPos) / lg; // First iteration position. pos = oldPos + offset; if (!m_collides_with_ground || IsInWater()) { MSG_DEBUG("physic.move", "%s moves (%s, %s) -> (%s, %s), collides ground:%d, water:%d", GetName().c_str(), Double2str(oldPos.x).c_str(), Double2str(oldPos.y).c_str(), Double2str(newPos.x).c_str(), Double2str(newPos.y).c_str(), m_collides_with_ground, IsInWater()); SetXY(newPos); return NO_COLLISION; } do { Point2i tmpPos(uround(pos.x), uround(pos.y)); // Check if we exit the GetWorld(). If so, we stop moving and return. if (IsOutsideWorldXY(tmpPos)) { if (!GetWorld().IsOpen()) { tmpPos.x = InRange_Long(tmpPos.x, 0, GetWorld().GetWidth() - GetWidth() - 1); tmpPos.y = InRange_Long(tmpPos.y, 0, GetWorld().GetHeight() - GetHeight() - 1); MSG_DEBUG("physic.state", "%s - DeplaceTestCollision touche un bord : %d, %d", GetName().c_str(), tmpPos.x, tmpPos.y); collision = COLLISION_ON_GROUND; break; } SetXY(pos); MSG_DEBUG("physic.move", "%s moves (%f, %f) -> (%f, %f) : OUTSIDE WORLD", GetName().c_str(), oldPos.x.tofloat(), oldPos.y.tofloat(), newPos.x.tofloat(), newPos.y.tofloat()); return NO_COLLISION; } // Test if we collide... collided_obj = CollidedObjectXY(tmpPos); if (collided_obj) { if (!m_go_through_objects || m_last_collided_object != collided_obj) { MSG_DEBUG("physic.state", "%s collide on %s", GetName().c_str(), collided_obj->GetName().c_str()); if (m_go_through_objects) { SignalObjectCollision(GetSpeed(), collided_obj, collided_obj->GetSpeed()); collision = NO_COLLISION; } else { collision = COLLISION_ON_OBJECT; } m_last_collided_object = collided_obj; } else { collided_obj = NULL; collision = NO_COLLISION; } } else if (!IsInVacuumXY(tmpPos, false)) { collision = COLLISION_ON_GROUND; m_last_collided_object = NULL; } if (collision != NO_COLLISION) { // Nothing more to do! MSG_DEBUG("physic.state", "%s - Collision at %d,%d : on %s", GetName().c_str(), tmpPos.x, tmpPos.y, collision == COLLISION_ON_GROUND ? "ground" : "an object"); // Set the object position to the current position. SetXY(Point2d(pos.x - offset.x, pos.y - offset.y)); break; } // Next motion step pos += offset; lg -= ONE; } while (ZERO < lg); Point2d speed_before_collision = GetSpeed(); Point2d speed_collided_obj; if (collided_obj) { speed_collided_obj = collided_obj->GetSpeed(); } ContactPointAngleOnGround(pos, contactPos, contactAngle); Collide(collision, collided_obj, pos); // =================================== // it's time to signal object(s) about collision! // WARNING: the following calls can send Action(s) over the network (cf bug #11232) // Be sure to keep it isolated here // =================================== ActiveTeam().AccessWeapon().NotifyMove(!!collision); switch (collision) { case NO_COLLISION: // Nothing more to do! break; case COLLISION_ON_GROUND: SignalGroundCollision(speed_before_collision, contactAngle); break; case COLLISION_ON_OBJECT: SignalObjectCollision(speed_before_collision, collided_obj, speed_collided_obj); collided_obj->SignalObjectCollision(speed_collided_obj, this, speed_before_collision); break; } // =================================== return collision; }
//////////////////////////////////////////////////////////////////////////// // Drawing operations // bool CGammaBlitter::FillRect(const stm_blitter_operation_t &op, const stm_rect_t &dst) { DEBUGF2(2, ("%s @ %p: colour %.8lx l/r/t/b: %lu/%lu/%lu/%lu\n", __PRETTY_FUNCTION__, this, op.ulColour, dst.left, dst.right, dst.top, dst.bottom)); if ((dst.left != dst.right) && (dst.top != dst.bottom)) { GAMMA_BLIT_NODE blitNode = {0}; if (op.ulFlags & ~STGGAL_VALID_DRAW_OPS) { DEBUGF2(1, ("CGammaBlitter::FillRect() operation flags not handled 0x%lx\n",op.ulFlags)); return false; } if(!SetBufferType(op.dstSurface,&(blitNode.BLT_TTY))) { DEBUGF2(1, ("CGammaBlitter::FillRect() invalid destination type\n")); return false; } blitNode.BLT_TBA = op.dstSurface.ulMemory; SetXY(dst.left, dst.top, &(blitNode.BLT_TXY)); blitNode.BLT_S1XY = blitNode.BLT_TXY; blitNode.BLT_S1SZ = (((dst.bottom - dst.top) & 0x0FFF) << 16) | ((dst.right - dst.left) & 0x0FFF); if (op.ulFlags == STM_BLITTER_FLAGS_NONE && (op.colourFormat == op.dstSurface.format)) { // Solid Fill DEBUGF2(2, ("CGammaBlitter::FillRect() fast direct fill\n")); blitNode.BLT_S1TY = blitNode.BLT_TTY & ~BLIT_TY_BIG_ENDIAN; blitNode.BLT_S1CF = op.ulColour; blitNode.BLT_INS = BLIT_INS_SRC1_MODE_DIRECT_FILL; } else { stm_blitter_surface_t tmpSurf = {{0}}; tmpSurf.format = op.colourFormat; // Operations that require the destination in SRC1 e.g. blending and colourkeying DEBUGF2(2, ("CGammaBlitter::FillRect() complex fill\n")); if(!SetBufferType(tmpSurf,&(blitNode.BLT_S2TY))) { DEBUGF2(1, ("CGammaBlitter::FillRect() invalid source colour format\n")); return false; } blitNode.BLT_S2TY |= BLIT_TY_COLOR_EXPAND_MSB; blitNode.BLT_S2XY = blitNode.BLT_TXY; blitNode.BLT_S2SZ = blitNode.BLT_S1SZ; blitNode.BLT_S2CF = op.ulColour; blitNode.BLT_S1TY = blitNode.BLT_TTY | BLIT_TY_COLOR_EXPAND_MSB; blitNode.BLT_S1BA = blitNode.BLT_TBA; blitNode.BLT_INS = BLIT_INS_SRC1_MODE_DISABLED | BLIT_INS_SRC2_MODE_COLOR_FILL; blitNode.BLT_ACK = BLIT_ACK_BYPASSSOURCE2; if(!ColourKey(&blitNode, op)) return false; BlendOperation(&blitNode, op); SetPlaneMask (op, blitNode.BLT_INS, blitNode.BLT_PMK); YUVRGBConversions(&blitNode); } QueueBlitOperation(blitNode); DEBUGF2(2, ("CGammaBlitter::FillRect() completed.\n")); } return true; }
//////////////////////////////////////////////////////////////////////////// // Blitting (Copy) operations // bool CGammaBlitter::CopyRect(const stm_blitter_operation_t &op, const stm_rect_t &dst, const stm_point_t &src) { DEBUGF2(2, ("%s @ %p: src x/y: %lu/%lu dst l/r/t/b: %lu/%lu/%lu/%lu\n", __PRETTY_FUNCTION__, this, src.x, src.y, dst.left, dst.right, dst.top, dst.bottom)); if ((dst.left != dst.right) && (dst.top != dst.bottom)) { GAMMA_BLIT_NODE blitNode = {0}; // Set the fill mode blitNode.BLT_INS = BLIT_INS_SRC1_MODE_DIRECT_COPY; // Set source type if(!SetBufferType(op.srcSurface,&(blitNode.BLT_S1TY))) { DEBUGF2(1, ("CGammaBlitter::CopyRect() invalid source type\n")); return false; } // Set target type if(!SetBufferType(op.dstSurface,&(blitNode.BLT_TTY))) { DEBUGF2(1, ("CGammaBlitter::CopyRect() invalid destination type\n")); return false; } // Work out copy direction bool copyDirReversed = false; if(op.srcSurface.ulMemory == op.dstSurface.ulMemory) { copyDirReversed = (dst.top > src.y) || ((dst.top == src.y) && (dst.left > src.x)); } if (!copyDirReversed) { SetXY(src.x, src.y, &(blitNode.BLT_S1XY)); SetXY(dst.left, dst.top, &(blitNode.BLT_TXY)); } else { blitNode.BLT_S1TY |= BLIT_TY_COPYDIR_BOTTOMRIGHT; blitNode.BLT_TTY |= BLIT_TY_COPYDIR_BOTTOMRIGHT; SetXY(src.x + dst.right - (dst.left + 1), src.y + dst.bottom - (dst.top + 1), &(blitNode.BLT_S1XY)); SetXY(dst.right - 1, dst.bottom - 1, &(blitNode.BLT_TXY)); } // Set the source base address blitNode.BLT_S1BA = op.srcSurface.ulMemory; // Set the target base address blitNode.BLT_TBA = op.dstSurface.ulMemory; // Set the window dimensions blitNode.BLT_S1SZ = (((dst.bottom - dst.top) & 0x0FFF) << 16) | ((dst.right - dst.left) & 0x0FFF); QueueBlitOperation(blitNode); DEBUGF2(2, ("CGammaBlitter::CopyRect() completed.\n")); } return true; }
XY(T fX, T fY) { SetXY(fX,fY); }
bool CGammaBlitter::CopyRectComplex(const stm_blitter_operation_t &op, const stm_rect_t &dst, const stm_rect_t &src) { stm_point_t SrcPoint; SrcPoint.x = src.left; SrcPoint.y = src.top; DEBUGF2(2, ("%s @ %p: flags: %.8lx src l/r/t/b: %lu/%lu/%lu/%lu -> dst l/r/t/b: %lu/%lu/%lu/%lu\n", __PRETTY_FUNCTION__, this, op.ulFlags, src.left, src.right, src.top, src.bottom, dst.left, dst.right, dst.top, dst.bottom)); if (op.ulFlags & ~STGGAL_VALID_COPY_OPS) { #ifndef __TDT__ DEBUGF2(1, "%s 1\n", __PRETTY_FUNCTION__); #endif return false; } GAMMA_BLIT_NODE blitNode = {0}; blitNode.BLT_ACK = BLIT_ACK_BYPASSSOURCE2; blitNode.BLT_INS = BLIT_INS_SRC1_MODE_DISABLED | BLIT_INS_SRC2_MODE_MEMORY; if (op.ulFlags & STM_BLITTER_FLAGS_FLICKERFILTER) { blitNode.BLT_INS |= (BLIT_INS_ENABLE_FLICKERFILTER | BLIT_INS_ENABLE_2DRESCALE); blitNode.BLT_FF0 = stm_flicker_filter_coeffs[0]; blitNode.BLT_FF1 = stm_flicker_filter_coeffs[1]; blitNode.BLT_FF2 = stm_flicker_filter_coeffs[2]; blitNode.BLT_FF3 = stm_flicker_filter_coeffs[3]; blitNode.BLT_RZC |= (BLIT_RZC_FF_MODE_ADAPTIVE | BLIT_RZC_2DHF_MODE_RESIZE_ONLY | BLIT_RZC_2DVF_MODE_RESIZE_ONLY); blitNode.BLT_RSF = 0x04000400; // 1:1 scaling by default } if (((src.bottom - src.top) != (dst.bottom - dst.top)) || ((src.right - src.left) != (dst.right - dst.left))) { /* * Note that the resize filter setup may override the default 1:1 resize * configuration set by the flicker filter; this is fine. */ ULONG ulScaleh=0; ULONG ulScalew=0; ulScaleh = ((src.bottom - src.top)<<10) / (dst.bottom - dst.top); ulScalew = ((src.right - src.left)<<10) / (dst.right - dst.left); if(ulScaleh > (32<<10) || ulScalew > (32<<10)) { #ifndef __TDT__ DEBUGF2(1, "%s 2\n", __PRETTY_FUNCTION__); #endif return false; } if(ulScaleh == 0 || ulScalew == 0) { #ifndef __TDT__ DEBUGF2(1, "%s 3\n", __PRETTY_FUNCTION__); #endif return false; } /* * Fail/fallback to software for >2x downscale. * This avoid an apparent hardware bug in all chips containing the * gamma blitter. This is under further investigation. */ #ifndef __TDT__ // this bug never occurred to me with ufs910 if(ulScalew > (2<<10)) { #ifndef __TDT__ DEBUGF2(1, "%s 4\n", __PRETTY_FUNCTION__); #endif return false; } #endif DEBUGF2(2, ("CGammaBlitter::CopyRectComplex() Scaleh = 0x%08lx Scalew = 0x%08lx.\n",ulScaleh,ulScalew)); int filterIndex; if((filterIndex = ChooseBlitter5x8FilterCoeffs((int)ulScalew)) < 0) { DEBUGF2(1, ("Error: No horizontal resize filter found.\n")); blitNode.BLT_RZC |= BLIT_RZC_2DHF_MODE_RESIZE_ONLY; blitNode.BLT_HFP = 0; } else { blitNode.BLT_RZC |= BLIT_RZC_2DHF_MODE_FILTER_BOTH; blitNode.BLT_HFP = m_5x8FilterTables.ulPhysical + filterIndex*STM_BLIT_FILTER_TABLE_SIZE; } if((filterIndex = ChooseBlitter5x8FilterCoeffs((int)ulScaleh)) < 0) { DEBUGF2(1, ("Error: No vertical resize filter found.\n")); blitNode.BLT_RZC |= BLIT_RZC_2DVF_MODE_RESIZE_ONLY; blitNode.BLT_VFP = 0; } else { blitNode.BLT_RZC |= BLIT_RZC_2DVF_MODE_FILTER_BOTH; blitNode.BLT_VFP = m_5x8FilterTables.ulPhysical + filterIndex*STM_BLIT_FILTER_TABLE_SIZE; } blitNode.BLT_INS |= BLIT_INS_ENABLE_2DRESCALE; blitNode.BLT_RSF = (ulScaleh << 16) | (ulScalew & 0x0000FFFF); } // Set source 2 type if(!SetBufferType(op.srcSurface,&(blitNode.BLT_S2TY))) { DEBUGF2(1, ("CGammaBlitter::CopyRectComplex() invalid source2 type\n")); return false; } blitNode.BLT_S2TY |= BLIT_TY_COLOR_EXPAND_MSB; // Set target type if(!SetBufferType(op.dstSurface,&(blitNode.BLT_TTY))) { DEBUGF2(1, ("CGammaBlitter::CopyRectComplex() invalid destination type\n")); return false; } // Work out copy direction bool copyDirReversed = false; if(op.srcSurface.ulMemory == op.dstSurface.ulMemory) { copyDirReversed = (dst.top > src.top) || ((dst.top == src.top) && (dst.left > src.left)); } if (!copyDirReversed) { SetXY(src.left, src.top, &(blitNode.BLT_S2XY)); SetXY(dst.left, dst.top, &(blitNode.BLT_TXY)); } else { blitNode.BLT_S2TY |= BLIT_TY_COPYDIR_BOTTOMRIGHT; blitNode.BLT_TTY |= BLIT_TY_COPYDIR_BOTTOMRIGHT; SetXY(src.right - 1, src.bottom - 1, &(blitNode.BLT_S2XY)); SetXY(dst.right - 1, dst.bottom - 1, &(blitNode.BLT_TXY)); } // Set the source 2 base address and size blitNode.BLT_S2BA = op.srcSurface.ulMemory; blitNode.BLT_S2SZ = (((src.bottom - src.top) & 0x0FFF) << 16) | ((src.right - src.left) & 0x0FFF); // Set the target base address blitNode.BLT_TBA = op.dstSurface.ulMemory; /* * Setup SRC1 even if we are not blending or destination colour * keying. Why? Because turning off SRC1 completely crashes the blitter. * The suspicion is that the ALU is still trying to pull data from the * SRC1 path even when SRC1 is disabled in BLT_INS and when the ALU * operation is BYPASSSOURCE2. As SRC1 isn't generating data the whole * thing deadlocks. Thankfully it only seems to be necessary * to set SRC1 up as a solid colour fill, not actually to read memory. */ blitNode.BLT_S1BA = blitNode.BLT_TBA; /* * Note: do not be tempted to copy BLT_S2TY into BLT_S1TY here, * the two surfaces may be different colour formats. SRC1 is the same * type as the destination in this case. */ blitNode.BLT_S1TY = blitNode.BLT_TTY | BLIT_TY_COLOR_EXPAND_MSB; blitNode.BLT_S1XY = blitNode.BLT_TXY; blitNode.BLT_S1SZ = (((dst.bottom - dst.top) & 0x0FFF) << 16) | ((dst.right - dst.left) & 0x0FFF); /* * We set the CLUT operation after the source 2 type (which the CLUT operates * on) in order to determine if we are doing a colour lookup or an RGB * LUT correction (e.g. for display gamma). */ if(op.ulFlags & STM_BLITTER_FLAGS_CLUT_ENABLE) { blitNode.BLT_CML = op.ulCLUT; SetCLUTOperation((blitNode.BLT_S2TY & BLIT_COLOR_FORM_TYPE_MASK), blitNode.BLT_INS, blitNode.BLT_CCO); DEBUGF2(2, ("CGammaBlitter::CopyRectComplex() CLUT type = %#08lx cco = %#08lx cml = %#08lx\n",(blitNode.BLT_S2TY & BLIT_COLOR_FORM_TYPE_MASK), blitNode.BLT_CCO, blitNode.BLT_CML)); } if(!ColourKey(&blitNode, op)) { #ifndef __TDT__ DEBUGF2(1, "%s 5\n", __PRETTY_FUNCTION__); #endif return false; } BlendOperation (&blitNode, op); SetPlaneMask (op, blitNode.BLT_INS, blitNode.BLT_PMK); /* * Rather like the clut this looks at the src2 and target type setup * to determine what colour space conversions are required. */ YUVRGBConversions(&blitNode); DEBUGBLITNODE(&blitNode); QueueBlitOperation(blitNode); DEBUGF2(2, ("CGammaBlitter::CopyRectComplex() completed.\n")); return true; }
/** * This method is used to set the projection x/y. The Set forces an attempted * calculation of the corresponding latitude/longitude position. This may or * may not be successful and a status is returned as such. * * @param x X coordinate of the projection in units that are the same as the * radii in the label * * @param y Y coordinate of the projection in units that are the same as the * radii in the label * * @return bool */ bool TransverseMercator::SetCoordinate(const double x, const double y) { // Save the coordinate SetXY(x,y); // Declare & Initialize variables double f,g,h,temp,con,phi,dphi,sinphi,cosphi,tanphi; double c,cs,t,ts,n,rp,d,ds; const double epsilon = 1.0e-10; // Sphere Conversion if (p_sph) { f = exp(GetX() / (p_equatorialRadius * p_scalefactor)); g = 0.5 * (f - 1.0 / f); temp = p_centerLatitude + GetY() / (p_equatorialRadius * p_scalefactor); h = cos(temp); con = sqrt((1.0 - h * h) / (1.0 + g * g)); if (con > 1.0) con = 1.0; if (con < -1.0) con = -1.0; p_latitude = asin(con); if (temp < 0.0 ) p_latitude = -p_latitude; p_longitude = p_centerLongitude; if (g != 0.0 || h != 0.0) { p_longitude = atan2(g,h) + p_centerLongitude; } } // Ellipsoid Conversion else if (!p_sph) { con = (p_ml0 + GetY() / p_scalefactor) / p_equatorialRadius; phi = con; for (int i = 1; i < 7; i++) { dphi = ((con + p_e1 * sin(2.0 * phi) - p_e2 * sin(4.0 * phi) + p_e3 * sin(6.0 * phi)) / p_e0) - phi; phi += dphi; if (fabs(dphi) <= epsilon) break; } // Didn't converge if (fabs(dphi) > epsilon) { p_good = false; return p_good; } if (fabs(phi) >= Isis::HALFPI) { if (GetY() >= 0.0) p_latitude = fabs(Isis::HALFPI); if (GetY() < 0.0) p_latitude = - fabs(Isis::HALFPI); p_longitude = p_centerLongitude; } else { sinphi = sin(phi); cosphi = cos(phi); tanphi = tan(phi); c = p_esp * cosphi * cosphi; cs = c * c; t = tanphi * tanphi; ts = t * t; con = 1.0 - p_eccsq * sinphi * sinphi; n = p_equatorialRadius / sqrt(con); rp = n * (1.0 - p_eccsq) / con; d = GetX() / (n * p_scalefactor); ds = d * d; p_latitude = phi - (n * tanphi * ds / rp) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * p_esp - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * p_esp - 3.0 * cs))); // Latitude cannot be greater than + or - halfpi radians (or 90 degrees) if (fabs(p_latitude) > Isis::HALFPI) { p_good = false; return p_good; } p_longitude = p_centerLongitude + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * p_esp + 24.0 * ts))) / cosphi); } } // Convert to Degrees p_latitude *= 180.0 / Isis::PI; p_longitude *= 180.0 / Isis::PI; // Cleanup the longitude if (p_longitudeDirection == PositiveWest) p_longitude *= -1.0; // These need to be done for circular type projections p_longitude = To360Domain (p_longitude); if (p_longitudeDomain == 180) p_longitude = To180Domain(p_longitude); // Cleanup the latitude if (IsPlanetocentric()) p_latitude = ToPlanetocentric(p_latitude); p_good = true; return p_good; }