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;
}
Exemple #2
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;
  }
Exemple #3
0
///knock player back. used in collisions
void Player::KnockBack()
{
    if (Alive())
    {
        SetXY(_lastX, _lastY);
    }
}
Exemple #4
0
  /// 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;
    }
  }
Exemple #5
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 );
}
Exemple #6
0
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 );
}
Exemple #7
0
///knocks bad guy back. used for collisions.
void BadGuy::KnockBack()
{
    if (Alive())
    {
        SetXY(_lastX, _lastY);
    }

}
Exemple #8
0
/***********************显示函数****************************/
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;
  }
Exemple #10
0
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);
}
Exemple #11
0
///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;
	}
}
Exemple #13
0
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 );
}
Exemple #14
0
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);
    }
}
Exemple #15
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 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;
  }
Exemple #16
0
/// 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;
    }

}
Exemple #17
0
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);
    }
}
Exemple #18
0
/*
	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 );
};
Exemple #19
0
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);
}
Exemple #20
0
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();
}
Exemple #21
0
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);
}
Exemple #22
0
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;
}
Exemple #23
0
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 );
}
Exemple #24
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 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;
  }
Exemple #25
0
// 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;
}
Exemple #26
0
////////////////////////////////////////////////////////////////////////////
// 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;
}
Exemple #27
0
////////////////////////////////////////////////////////////////////////////
// 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);
 }
Exemple #29
0
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;
}
Exemple #30
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 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;
  }