Beispiel #1
0
void BossGun::update(float frametime, int orientation, float x, float y, Input * input, LevelController * lc, float destX, float destY, bool shouldShoot) {
    playerX = x;
    playerY = y;
    adjacent = destX - x;
    opposite = destY - y;
    angle = atan((opposite / adjacent));
    spriteData.angle = angle;
    if (adjacent < 0) { // Facing back
        setX(x);
        setY(y + 80);
        flipHorizontal(true);
    } else {
        setX(x + 50);
        setY(y + 80);
        flipHorizontal(false);
    }
    angle = atan((destY - getY()) / (destX - getX()));
    // Fire bullet
    if (shouldShoot) { // Cause AI calls this
        Projectile* p = shoot(lc, frametime);
        if (p != nullptr)
            p->setOwner(Projectile::NPC);
    } else {
        cooldownCurrent -= frametime;
    }
    Entity::update(frametime);
}
Beispiel #2
0
//ernest stamp of approval do not change or famiry dry
void Bullet::fire(Entity* entity)
{
	if (entity->getIdentity() == 'e'){
		if (enemyFireTimer <= 0)                       // if ready to fire
		{
			velocity.x = entity->getKillDirX() * 50;// properly initiliaze
			if (velocity.x < 0)
			{
				faceRight = false;
				flipHorizontal(!faceRight);
			}
			else
			{
				faceRight = true;
				flipHorizontal(!faceRight);
			}
			if (velocity.x < 0)
			{
				//velocity.x *= -1;
				spriteData.x = entity->getCenterX() - entity->getWidth();
			}
			else
				spriteData.x = entity->getCenterX();
			velocity.y = entity->getKillDirY() * 50; //f*****g directions
			//spriteData.x = entity->getCenterX();
			spriteData.y = entity->getCenterY() - 50;
			visible = true;                         // make torpedo visible
			active = true;                          // enable collisions
			enemyFireTimer = bulletNS::ENEMY_FIRE_DELAY;      // delay firing
		}
	}
	else{

		if (fireTimer <= 0)                       // if ready to fire
		{
			velocity.x = 200;
			faceRight = entity->getDirection();
			flipHorizontal(!faceRight);
			if (!entity->getDirection())
			{
				velocity.x *= -1;
				spriteData.x = entity->getCenterX() - entity->getWidth();
			}
			else
				spriteData.x = entity->getCenterX();
			velocity.y = 0;
			//spriteData.x = entity->getCenterX();
			spriteData.y = entity->getCenterY() - 50;
			visible = true;                         // make torpedo visible
			active = true;                          // enable collisions
			fireTimer = bulletNS::FIRE_DELAY;      // delay firing
		}
	}
}
void RenderObject::fhTo(bool fh)
{
	if ((fh && !_fh) || (!fh && _fh))
	{
		flipHorizontal();
	}
}
Beispiel #4
0
/* Process a frame
 */
void Frame::processFrame( long int run_id )
{

	for (int i=0;i<_nImages;i++) {
		cvConvertImage(_grab_img[i],_tmp_img[i],0);
		cvCopyImage( _rotated_img[i], _copy_img[i] );
		rotateCW(_tmp_img[i],_rotated_img[i]);

		// resize and convert from 4-channel to 3-channel
		// (Ladybug outputs 4-channel images by default)
		cvResize(_rotated_img[i],_display_img[i]);
		cvConvertImage(_tmp_img[i],_grayscale_img[i],CV_RGB2GRAY);

		// save the image for debug
		if ( run_id > 0 ) {
			LOG(LEVEL_INFO, "saving image in %d_%d.bmp", run_id, i );
			char filename[256];
			sprintf( filename, "synthetic/%d_%d.bmp", run_id, i );
			cvSaveImage( filename, _tmp_img[i] );
		}
	}

	flipHorizontal(_display_img[5],temp_img); // flip image horizontally
	cvConvertImage(temp_img,_flipped_img,1); // flip image vertically
}
Beispiel #5
0
//=============================================================================
// update
// typically called once per frame
// frameTime is used to regulate the speed of movement and animation
//=============================================================================
void Bowser::update(float frameTime)
{
	Entity::update(frameTime);

	//leftOfWall_ = false;
	//rightOfWall_ = false;

	if (spriteData.state == ATTACKING)
	{
		spinAttack(frameTime);
	}

	if (spriteData.state != DEAD)
	{
		gravity(frameTime);
		if (spriteData.direction == RIGHT)
		{
			flipHorizontal(false);
		}
		else
		{
			flipHorizontal(true);
		}
		bowserIdle.update(frameTime);
	}
	else if (spriteData.state == FIRE_BREATH)
	{
		bowserFireBreath.update(frameTime);
		if (bowserFireBreath.getAnimationComplete())
		{
			spriteData.state = STANDING;
			bowserIdle.update(frameTime);
		}
	}
	else
	{
		if (bowserDying.getAnimationComplete())
		{
			visible = false;
		}
		bowserDying.update(frameTime);
	}
}
Beispiel #6
0
static __inline__ void flip_fun(int flip, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    int horiz = (flip & 1) != 0;
    int vert = (flip & 2) != 0;
    if (horiz && vert){
        int arr_len = dstWidth * dstHeight * sizeof(char) * 4;
        char* temp = (char *) malloc(arr_len);
        flipHorizontal(source, srcWidth, srcHeight, temp, dstWidth, dstHeight);
        flipVertical(temp, dstWidth, dstHeight, destination, dstWidth, dstHeight);
        free(temp);
        return;
    }
    if (horiz){
        flipHorizontal(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
        return;
    }
    if (vert){
        flipVertical(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
        return;
    }
}
Beispiel #7
0
void Boxer::animate(float frameTime) {
	if(input->isKeyDown(VK_RIGHT) || input->isKeyDown(VK_LEFT)){
		isWalking = false;
	}
	else{
		isWalking = true;
	}
	if (isAttacking) {
		setFrameDelay(0.05);
		setFrames(12, 23);
		if (currentFrame == endFrame) isAttacking = false;
		else return;
	}
	if (isWalking) {
		setFrameDelay(0.1);
		setFrames(6, 11);
		flipHorizontal(!facingRight);
	} else {
		setFrameDelay(0.075);
		setFrames(0, 5);
		flipHorizontal(!facingRight);
	}
}
Beispiel #8
0
void saveScreenShot(int w, int h, int premult, const char* name)
{
	unsigned char* image = (unsigned char*)malloc(w*h*4);
	if (image == NULL)
		return;
	glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image);
	if (premult)
		unpremultiplyAlpha(image, w, h, w*4);
	else
		setAlpha(image, w, h, w*4, 255);
	flipHorizontal(image, w, h, w*4);
 	stbi_write_png(name, w, h, 4, image, w*4);
 	free(image);
}
void fireball::set(int x, int y, Direction dirc)
{
	if (dirc == RIGHT)
	{
		setX(x + marioNS::WALKING_IMAGE_WIDTH / 2);
		setY(y);
	}
	else
	{
		setX(x - marioNS::WALKING_IMAGE_WIDTH);
		setY(y);
		setVelocity(-getVelocity());
		flipHorizontal(true);
	}
}
Beispiel #10
0
void SchoolFish::onUpdate(float dt)
{
	BBGE_PROF(SchoolFish_onUpdate);
	/*
	Quad::onUpdate(dt);
	return;
	*/

	/*
	if (dsq->continuity.form == FORM_BEAST)
		this->activationType = ACT_CLICK;
	else
		this->activationType = ACT_NONE;
	*/


	/*
	if (burstDelay == 0)
	{
		maxSpeedLerp = 2;
		Vector v = getNormal();
		vel = 0;
		v *= -5000;
		vel += v;
		//float t = (100 + rand()%100)/100.0;
		float t = 2;
		maxSpeedLerp.interpolateTo(1, t);
		burstDelay = 10;// + (rand()%100)/100.0;
		//rotateToVec(v, 0, 90);
		//rotation.interpolateTo(0, 1);

		if (v.x > 0 && !isfh())
		{
			flipHorizontal();
			flipDelay = 0.5;
		}
		if (v.x < 0 && isfh())
		{
			flipHorizontal();
			flipDelay = 0.5;
		}
	}
	else
	*/

	{
		burstDelay -= dt;
		if (burstDelay < 0)
		{
			burstDelay = 0;
		}
	}

	if (stickToNaijasHead && alpha.x < 0.1)
		stickToNaijasHead = false;

	if (this->layer < LR_ENTITIES)
	{
		//debugLog("background fish!");
		/*
		setDamageTarget(DT_AVATAR_SHOCK, false);
		setDamageTarget(DT_AVATAR_BITE, false);
		setDamageTarget(DT_AVATAR_VOMIT, false);
		setDamageTarget(DT_AVATAR_ENERGYBLAST, false);
		*/
		setEntityType(ET_NEUTRAL);
		collideRadius = 0;
	}

	if (getState() == STATE_DEAD)
	{
		FlockEntity::onUpdate(dt);
		respawnTimer -= dt;
		if (!(dsq->game->avatar->position - this->position).isLength2DIn(2000))
		{
			if (respawnTimer < 0)
			{
				respawnTimer = 0;
				perform(STATE_IDLE);
			}
		}
	}
	else
	{
		/*
		if (layer == LR_ENTITIES || layer == LR_ENTITIES2)
		{
			rippleTimer -= dt;
			if (rippleTimer < 0)
			{
				if (core->afterEffectManager)
					core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),position,0.04,0.06,15,0.2f));
				rippleTimer = 0.5;
			}
		}
		*/

		FlockEntity::onUpdate(dt);

		if (dsq->game->isValidTarget(this, 0))
			dsq->game->handleShotCollisions(this);


		/*
		soundDelay -= dt;
		if (soundDelay <= 0)
		{
			//sound(swimSound, 1000 + rand()%100);
			soundDelay = 4+(rand()%50)/100.0;
		}
		*/
		/*
	1.    if distance_to(closest_boid) <= too_close then set direction away from closest_boid
	2.    speed_of_neighbors := average(speed(x), for all x where distance_to(x) <= neighborhood_size)
			direction_of_neighbors := avg(direction(x), for all x where distance_to(x) <= neighborhood_size)
			if speed < speed_of_neighbors then increase speed
			if speed > speed_of_neighbors then decrease speed
			turn towards direction_of_neighbors
	3.    position_of_neighbors := avg(position(x), for all x where distance_to(x) <= neighborhood_size)
			turn towards position_of_neighbors
		*/


		float seperation = 1;
		float alignment = 0;
		float cohesion = 0.75;
		/*
		FlockPiece flock;
		getFlockInRange(160, &flock);
		*/
		// if flock in 160 ?
		if (true)
		{
			VectorSet newDirection;

			if (avoidTime>0)
			{
				avoidTime -= dt;
				if (avoidTime<0)
					avoidTime=0;
			}

			Vector dir = getFlockHeading();

			Vector accumulator;


			applyCohesion(accumulator);
			applyAlignment(accumulator, dir);
			// alignment
			applySeparation(accumulator);
			applyAvoidance(accumulator);
			updateVelocity(accumulator);

			/*
			if (dsq->game->isValidTarget(this, 0))
				doSpellAvoidance(dt, 96, dodgeAbility);
			*/


			Vector lastPosition = position;
			Vector newPosition = position + (vel*velocityScale*dt) + vel2*dt;
			position = newPosition;

			if (dsq->game->isObstructed(position))
			{
				position = lastPosition;
				/*
				position = Vector(newPosition.x, lastPosition.y);
				if (dsq->game->isObstructed(position))
				{
					position = Vector(lastPosition.x, newPosition.y);
					if (dsq->game->isObstructed(position))
					{
						position = lastPosition;
					}
				}
				*/
			}

			//updateCurrents(dt);
			updateVel2(dt);


			/*
			if (flipDelay > 0)
			{
				flipDelay -= dt;
				if (flipDelay < 0)
				{
					flipDelay = 0;
				}
			}
			*/

			flipDelay = 0;

			//dir.normalize2D();
			if (flipDelay <= 0)
			{
				const float amt = 0;
				/*

				if (fabs(dir.x) > fabs(dir.y))
				{
					if (dir.x > amt && !isfh())
					{
						flipHorizontal();
						flipDelay = 0.5;
					}
					if (dir.x < -amt && isfh())
					{
						flipHorizontal();
						flipDelay = 0.5;
					}
				}
				*/
				if (vel.x > amt && !isfh())
				{
					flipHorizontal();
				}
				if (vel.x < -amt && isfh())
				{
					flipHorizontal();
				}
			}


			//rotateToVec(accumulator, 5, 90);

			float angle = atan(dir.y/dir.x);
			angle = ((angle*180)/3.14);

			if (angle > 45)
				angle = 45;
			if (angle < -45)
				angle = -45;
			

			rotation = Vector(0,0,angle);

			//rotation.interpolateTo(Vector(0, 0, angle), 0);
		}

	}
}
Beispiel #11
0
FITSViewer::FITSViewer (QWidget *parent)
        : KXmlGuiWindow (parent)
{
#ifdef Q_OS_OSX
    if(Options::independentWindowFITS())
         setWindowFlags(Qt::Window);
     else{
        setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
        connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(changeAlwaysOnTop(Qt::ApplicationState)));
     }
#endif

    fitsTab   = new QTabWidget(this);
    undoGroup = new QUndoGroup(this);

    fitsID = 0;
    debayerDialog= NULL;
    markStars = false;

    lastURL = QUrl(QDir::homePath());

    fitsTab->setTabsClosable(true);

    setWindowIcon(QIcon::fromTheme("kstars_fitsviewer", QIcon(":/icons/breeze/default/kstars_fitsviewer.svg")));

    setCentralWidget(fitsTab);

    connect(fitsTab, SIGNAL(currentChanged(int)), this, SLOT(tabFocusUpdated(int)));
    connect(fitsTab, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));

    //These two connections will enable or disable the scope button if a scope is available or not.
    //Of course this is also dependent on the presence of WCS data in the image.

    #ifdef HAVE_INDI
    connect(INDIListener::Instance(), SIGNAL(newTelescope(ISD::GDInterface *)), this, SLOT(updateWCSFunctions()));
    connect(INDIListener::Instance(), SIGNAL(deviceRemoved(ISD::GDInterface *)), this, SLOT(updateWCSFunctions()));
    #endif

    led.setColor(Qt::green);

    fitsPosition.setAlignment(Qt::AlignCenter);
    fitsValue.setAlignment(Qt::AlignCenter);

    //fitsPosition.setFixedWidth(100);
    //fitsValue.setFixedWidth(100);
    fitsWCS.setVisible(false);

    statusBar()->insertPermanentWidget(FITS_WCS, &fitsWCS);
    statusBar()->insertPermanentWidget(FITS_VALUE, &fitsValue);
    statusBar()->insertPermanentWidget(FITS_POSITION, &fitsPosition);
    statusBar()->insertPermanentWidget(FITS_ZOOM, &fitsZoom);
    statusBar()->insertPermanentWidget(FITS_RESOLUTION, &fitsResolution);
    statusBar()->insertPermanentWidget(FITS_LED, &led);

    QAction *action;

    action = actionCollection()->addAction("rotate_right", this, SLOT(rotateCW()));
    action->setText(i18n("Rotate Right"));
    action->setIcon(QIcon::fromTheme("object-rotate-right", QIcon(":/icons/breeze/default/object-rotate-right.svg")));

    action = actionCollection()->addAction("rotate_left", this, SLOT(rotateCCW()));
    action->setText(i18n("Rotate Left"));
    action->setIcon(QIcon::fromTheme("object-rotate-left", QIcon(":/icons/breeze/default/object-rotate-left.svg")));

    action = actionCollection()->addAction("flip_horizontal", this, SLOT(flipHorizontal()));
    action->setText(i18n("Flip Horizontal"));
    action->setIcon(QIcon::fromTheme("object-flip-horizontal", QIcon(":/icons/breeze/default/object-flip-horizontal.svg")));

    action = actionCollection()->addAction("flip_vertical", this, SLOT(flipVertical()));
    action->setText(i18n("Flip Vertical"));
    action->setIcon(QIcon::fromTheme("object-flip-vertical", QIcon(":/icons/breeze/default/object-flip-vertical.svg")));

    action = actionCollection()->addAction("image_histogram");
    action->setText(i18n("Histogram"));
    connect(action, SIGNAL(triggered(bool)), SLOT (histoFITS()));
    actionCollection()->setDefaultShortcut(action, QKeySequence::Replace);

    action->setIcon(QIcon(":/icons/histogram.png"));

    action = KStandardAction::open(this,   SLOT(openFile()),   actionCollection());
    action->setIcon(QIcon::fromTheme("document-open", QIcon(":/icons/breeze/default/document-open.svg")));
    
    saveFileAction    = KStandardAction::save(this,   SLOT(saveFile()),   actionCollection());
    saveFileAction->setIcon(QIcon::fromTheme("document-save", QIcon(":/icons/breeze/default/document-save.svg")));

    action=saveFileAsAction  = KStandardAction::saveAs(this, SLOT(saveFileAs()), actionCollection());
    saveFileAsAction->setIcon(QIcon::fromTheme("document-save_as", QIcon(":/icons/breeze/default/document-save-as.svg")));

    action = actionCollection()->addAction("fits_header");
    actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::CTRL+Qt::Key_H));
    action->setIcon(QIcon::fromTheme("document-properties", QIcon(":/icons/breeze/default/document-properties.svg")));
    action->setText(i18n( "FITS Header"));
    connect(action, SIGNAL(triggered(bool) ), SLOT(headerFITS()));

    action = actionCollection()->addAction("fits_debayer");
    actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::CTRL+Qt::Key_D));
    action->setIcon(QIcon::fromTheme("view-preview", QIcon(":/icons/breeze/default/view-preview.svg")));
    action->setText(i18n( "Debayer..."));
    connect(action, SIGNAL(triggered(bool) ), SLOT(debayerFITS()));

    action = actionCollection()->addAction("image_stretch");
    action->setText(i18n("Auto stretch"));
    connect(action, SIGNAL(triggered(bool)), SLOT (stretchFITS()));
    actionCollection()->setDefaultShortcut(action, QKeySequence::SelectAll);
    action->setIcon(QIcon::fromTheme("transform-move", QIcon(":/icons/breeze/default/transform-move.svg")));

    action = KStandardAction::close(this,  SLOT(close()),  actionCollection());
    action->setIcon(QIcon::fromTheme("window-close", QIcon(":/icons/breeze/default/window-close.svg")));
    
    action = KStandardAction::copy(this,   SLOT(copyFITS()),   actionCollection());
    action->setIcon(QIcon::fromTheme("edit-copy", QIcon(":/icons/breeze/default/edit-copy.svg")));
    
    action=KStandardAction::zoomIn(this,     SLOT(ZoomIn()),      actionCollection());
    action->setIcon(QIcon::fromTheme("zoom-in", QIcon(":/icons/breeze/default/zoom-in.svg")));
    
    action=KStandardAction::zoomOut(this,    SLOT(ZoomOut()),     actionCollection());
    action->setIcon(QIcon::fromTheme("zoom-out", QIcon(":/icons/breeze/default/zoom-out.svg")));
    
    action=KStandardAction::actualSize(this, SLOT(ZoomDefault()), actionCollection());
    action->setIcon(QIcon::fromTheme("zoom-fit-best", QIcon(":/icons/breeze/default/zoom-fit-best.svg")));

    QAction *kundo = KStandardAction::undo(undoGroup, SLOT(undo()), actionCollection());
    kundo->setIcon(QIcon::fromTheme("edit-undo", QIcon(":/icons/breeze/default/edit-undo.svg")));
    
    QAction *kredo = KStandardAction::redo(undoGroup, SLOT(redo()), actionCollection());
    kredo->setIcon(QIcon::fromTheme("edit-redo", QIcon(":/icons/breeze/default/edit-redo.svg")));

    connect(undoGroup, SIGNAL(canUndoChanged(bool)), kundo, SLOT(setEnabled(bool)));
    connect(undoGroup, SIGNAL(canRedoChanged(bool)), kredo, SLOT(setEnabled(bool)));

    action = actionCollection()->addAction("image_stats");
    action->setIcon(QIcon::fromTheme("view-statistics", QIcon(":/icons/breeze/default/view-statistics.svg")));
    action->setText(i18n( "Statistics"));
    connect(action, SIGNAL(triggered(bool)), SLOT(statFITS()));

    action = actionCollection()->addAction("view_crosshair");
    action->setIcon(QIcon::fromTheme("crosshairs", QIcon(":/icons/breeze/default/crosshairs.svg")));
    action->setText(i18n( "Show Cross Hairs"));
    action->setCheckable(true);
    connect(action, SIGNAL(triggered(bool)), SLOT(toggleCrossHair()));

    action = actionCollection()->addAction("view_pixel_grid");
    action->setIcon(QIcon::fromTheme("map-flat", QIcon(":/icons/breeze/default/map-flat.svg")));
    action->setText(i18n( "Show Pixel Gridlines"));
    action->setCheckable(true);
    connect(action, SIGNAL(triggered(bool)), SLOT(togglePixelGrid()));

    action = actionCollection()->addAction("view_eq_grid");
    action->setIcon(QIcon::fromTheme("kstars_grid", QIcon(":/icons/breeze/default/kstars_grid.svg")));
    action->setText(i18n( "Show Equatorial Gridlines"));
    action->setCheckable(true);
    action->setDisabled(true);
    connect(action, SIGNAL(triggered(bool)), SLOT(toggleEQGrid()));

    action = actionCollection()->addAction("view_objects");
    action->setIcon(QIcon::fromTheme("help-hint", QIcon(":/icons/breeze/default/help-hint.svg")));
    action->setText(i18n( "Show Objects in Image"));
    action->setCheckable(true);
    action->setDisabled(true);
    connect(action, SIGNAL(triggered(bool)), SLOT(toggleObjects()));

    action = actionCollection()->addAction("center_telescope");
    action->setIcon(QIcon(":/icons/center_telescope.svg"));
    action->setText(i18n( "Center Telescope\n*No Telescopes Detected*"));
    action->setDisabled(true);
    action->setCheckable(true);
    connect(action, SIGNAL(triggered(bool)), SLOT(centerTelescope()));

    action = actionCollection()->addAction("view_zoom_fit");
    action->setIcon(QIcon::fromTheme("zoom-fit-width", QIcon(":/icons/breeze/default/zoom-fit-width.svg")));
    action->setText(i18n( "Zoom To Fit"));
    connect(action, SIGNAL(triggered(bool)), SLOT(ZoomToFit()));

    action = actionCollection()->addAction("mark_stars");
    action->setText(i18n( "Mark Stars"));
    connect(action, SIGNAL(triggered(bool)), SLOT(toggleStars()));

    QSignalMapper *filterMapper = new QSignalMapper(this);

    int filterCounter=1;

    foreach(QString filter, FITSViewer::filterTypes)
    {

        action = actionCollection()->addAction(QString("filter%1").arg(filterCounter));
        action->setText(i18n(filter.toUtf8().constData()));
        filterMapper->setMapping(action, filterCounter++);
        connect(action, SIGNAL(triggered()), filterMapper, SLOT(map()));


    }
Beispiel #12
0
void NPC::calcVelocity(float frameTime)
{
    float angle, xLength, yLength, tempX, tempY;
    static int xSign = 1;
    static int ySign = 1;
    xLength = moseyEndX-moseyStartX;
    yLength = moseyEndY-moseyStartY;

    static float timeTillPause = pauseInterval;
    static float timeTillMosey = pauseTime;

    if(speaking) {
        // prevent movement while speaking
        setVelocity(VECTOR2(0.0,0.0));
        return;
    }

    if(timeTillPause > 0.0)
        timeTillPause -= frameTime;
    else if(timeTillMosey > 0.0) {
        // NPC should be paused
        setVelocity(VECTOR2(0.0,0.0));
        timeTillMosey -= frameTime;
        return;
    }
    else {
        timeTillPause = pauseInterval;
        timeTillMosey = pauseTime;
    }
    // if he is not paused, continue on to mosey...
    // if vector is negative, it's moving left
    if(xLength < 0) {
        setFrames(2,3);
        flipHorizontal(true);
        // if the NPC is further left than the endpoint, swap endpoint and startpoint
        if(spriteData.x < moseyEndX) {
            tempX = moseyStartX;
            moseyStartX = moseyEndX;
            moseyEndX = tempX;
        }
    } else if(xLength > 0) { // if movement is positive, check for x > endpoint, then swap
        setFrames(2,3);
        flipHorizontal(false);
        if(spriteData.x > moseyEndX) {
            tempX = moseyStartX;
            moseyStartX = moseyEndX;
            moseyEndX = tempX;
        }
    }

    // if vector is negative, he's moving up
    if(yLength < 0) {
        setFrames(4,5);
        // if the NPC is higher than that the endpoint, swap endpoint and startpoint
        if(spriteData.y < moseyEndY) {
            tempY = moseyStartY;
            moseyStartY = moseyEndY;
            moseyEndY = tempY;
            setCurrentFrame(0);
        }
    } else if(yLength > 0) {
        setFrames(0,1);
        if(spriteData.y > moseyEndY) {
            tempY = moseyStartY;
            moseyStartY = moseyEndY;
            moseyEndY = tempY;
            setCurrentFrame(4);

        }
    }
    if(xLength == 0.0) {
        if(yLength < 0)
            angle = -(float)PI/2; // prevent divide by 0 when xLength is 0. atan(inf) = -PI/2
        if(yLength > 0)
            angle = (float)PI/2;
    } else if(xLength < 0)
        angle = atan(yLength/xLength)+((float)PI); // rotate by 180 degrees
    else
        angle = atan(yLength/xLength);
    setVelocity(VECTOR2(npcNS::MOVE_SPEED*cos(angle)*xSign, npcNS::MOVE_SPEED*sin(angle)*ySign));
}
/**
 * Method:    rotate90CCWAndFlipHorizontal
 */
void rotate90CCWAndFlipHorizontal(uint32* sourceBuffer, uint32* targetBuffer, int width, int height) {
    uint32* aux = (uint32*)malloc(width*height*sizeof(uint32));
    rotate90CCW(sourceBuffer, aux, width, height);
    flipHorizontal(aux, targetBuffer, height, width);
    free(aux);
}
/**
 * Method:    DecodeAndConvert
 */
JNIEXPORT jintArray JNICALL Java_com_orangelabs_rcs_core_ims_protocol_rtp_codec_video_h264_decoder_NativeH264Decoder_DecodeAndConvert
  (JNIEnv *env, jclass clazz, jbyteArray h264Frame, int rotateOrientation, jintArray dimensions) {
    pthread_mutex_lock(&iMutex);

    int32 size = 0;
    int32 status;
    jintArray decoded;

    // Check if decoder is initialized
    if(!decoderInitialized) {
        decoded = (env)->NewIntArray(0);
        pthread_mutex_unlock(&iMutex);
        iStatus = FAIL_NOT_INITIALIZED;
        return decoded;
    }

    // Copy jbyteArray to uint8*
    jint len = env->GetArrayLength(h264Frame);
    jbyte data[len];
    env->GetByteArrayRegion(h264Frame, 0, len, data);
    uint8* aInputBuf = (uint8*)malloc(len);
    memcpy(aInputBuf, (uint8*)data, len);
    size = len;

    // Get type of NAL
    u_int8_t type = aInputBuf[0] & 0x1f;
    iStatus = FAIL;
    switch (type) {
        case 7: // SPS
            if ((status = decoder->DecodeSPS(aInputBuf, size)) != AVCDEC_SUCCESS) {
                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed decode SPS: %ld", status);
                decoded = (env)->NewIntArray(0);
                pthread_mutex_unlock(&iMutex);
                iStatus = FAIL_TO_DECODE_SPS;
                return decoded;
            }
            iStatus = SPS_DECODED;
            decoded = (env)->NewIntArray(0);
            __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Receive SPS");
            break;

        case 8: // PPS
            if ((status = decoder->DecodePPS(aInputBuf, size)) != AVCDEC_SUCCESS) {
                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to decode PPS: %ld", status);
                decoded = (env)->NewIntArray(0);
                pthread_mutex_unlock(&iMutex);
                iStatus = FAIL_TO_DECODE_PPS;
                return decoded;
            }
            iStatus = PPS_DECODED;
            decoded = (env)->NewIntArray(0);
            __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Receive PPS");
            break;

        case 5: // IDR slice
        case 1: // non-IDR slice
            // Decode the buffer
            status = decoder->DecodeAVCSlice(aInputBuf, &size);
            if (status > AVCDEC_FAIL) {
                iStatus = SUCCESS;
                AVCFrameIO outVid;
                int indexFrame;
                int releaseFrame;
                if (!decoder->GetDecOutput(&indexFrame, &releaseFrame, &outVid)) {
                    decoded = (env)->NewIntArray(0);
                    pthread_mutex_unlock(&iMutex);
                    iStatus = FAIL_TO_GET_OUTPUT;
                    return decoded;
                }

                // Set width and height
                uint32* resultDimensions= (uint32*) malloc(2*sizeof(uint32));
                if (resultDimensions == NULL) {
                    decoded = (env)->NewIntArray(0);
                    pthread_mutex_unlock(&iMutex);
                    iStatus = FAIL_TO_CREATE_DIMENSIONS;
                    return decoded;
                }
                resultDimensions[0] = outVid.pitch;
                resultDimensions[1] = outVid.height;

                if(aOutBuffer == NULL) {
                    aOutBuffer = (uint8*)malloc(resultDimensions[0]*resultDimensions[1]*3/2);
                }
                decoded = (env)->NewIntArray(resultDimensions[0]*resultDimensions[1]);

                // Copy result to YUV array
                memcpy(aOutBuffer, outVid.YCbCr[0], resultDimensions[0] * resultDimensions[1]);
                memcpy(aOutBuffer + (resultDimensions[0] * resultDimensions[1]), outVid.YCbCr[1], (resultDimensions[0] * resultDimensions[1]) / 4);
                memcpy(aOutBuffer + (resultDimensions[0] * resultDimensions[1]) + ((resultDimensions[0] * resultDimensions[1]) / 4), outVid.YCbCr[2], (resultDimensions[0] * resultDimensions[1]) / 4);

                // Create the output buffer
                uint32* resultBuffer = (uint32*) malloc(resultDimensions[0] * resultDimensions[1] * sizeof(uint32));
                if (resultBuffer == NULL) {
                    decoded = (env)->NewIntArray(0);
                    pthread_mutex_unlock(&iMutex);
                    iStatus = FAIL_TO_CREATE_OUTPUT;
                    return decoded;
                }

                // Convert to RGB
                convert(resultDimensions[0], resultDimensions[1], aOutBuffer, resultBuffer);

                // Frame rotation
                bool freeResultBuffer = true;
                VideoEncoderRotateOrientation videoEncoderRotateOrientation = (VideoEncoderRotateOrientation) rotateOrientation;
                if (videoEncoderRotateOrientation != NONE) {
                    // Alloc rotated frame buffer
                    rotatedFrame = (uint32*)malloc(outVid.pitch*outVid.height*sizeof(uint32));
                    switch (videoEncoderRotateOrientation) {
                        case ROTATE_90_CW:
                            rotate90CW(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case ROTATE_180:
                            rotate180(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case ROTATE_90_CCW:
                            rotate90CCW(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case FLIP_HORIZONTAL:
                            flipHorizontal(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case ROTATE_90_CW_FLIP_HORIZONTAL:
                            rotate90CWAndFlipHorizontal(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case ROTATE_180_FLIP_HORIZONTAL:
                            rotate180AndFlipHorizontal(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                        case ROTATE_90_CCW_FLIP_HORIZONTAL:
                            rotate90CCWAndFlipHorizontal(resultBuffer, rotatedFrame, outVid.pitch, outVid.height);
                            break;
                    }

                    // Free original frame
                    free(resultBuffer);

                    // Update aOutBuffer variable with the rotated data
                    resultBuffer = rotatedFrame;

                    // Do not free result buffer because its the rotated frame buffer
                    freeResultBuffer = false;

                    if (videoEncoderRotateOrientation != ROTATE_180
                            && videoEncoderRotateOrientation != ROTATE_180_FLIP_HORIZONTAL
                            && videoEncoderRotateOrientation != FLIP_HORIZONTAL) {
                        // Switch width and height values
                        resultDimensions[0] = outVid.height; // width
                        resultDimensions[1] = outVid.pitch; // height
                    } else {
                        resultDimensions[0] = outVid.pitch; // width
                        resultDimensions[1] = outVid.height; // height
                    }
                }

                // Return Bitmap Dimensions
                (env)->SetIntArrayRegion(dimensions, 0, 2, (const jint*)resultDimensions);
                free(resultDimensions);

                // Return Bitmap image
                (env)->SetIntArrayRegion(decoded, 0, outVid.pitch*outVid.height, (const jint*)resultBuffer);
                if (freeResultBuffer) {
                    free(resultBuffer);
                    resultBuffer = NULL;
                }
                if (rotatedFrame != NULL) {
                    free(rotatedFrame);
                    rotatedFrame = NULL;
                }
            } else {
                __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Decoder error %ld", status);
                decoded = (env)->NewIntArray(0);
                pthread_mutex_unlock(&iMutex);
                iStatus = FAIL_TO_DECODE_AVC;
                return decoded;
            }
            break;
    }
    free(aInputBuf);
    pthread_mutex_unlock(&iMutex);
    return decoded;
}