Sign in to follow this  
Xanas

Mouse movement for control producing irratic results

Recommended Posts

I know this is me somehow but I'm not sure how. Anyway, I'm a noob and here is what I'm doing. 1) I am "somewhat" using chromium (great little sdl/opengl/openal game) to learn some things. 2) I am trying to follow his code in order to work on a similar little program I'm making (I wouldn't dare to call it a game yet, may never be one). Anyhow, I am trying to use a mouse to control the movement of a little quad I have painted my little ship texture on that I made. It will move, but it always bounces back and I cannot for the life of me figure out why. All of my debugging attempts are making results that don't make sense to me... Here is an example from his code real quickly. Now mine isn't object oriented or anything like that (since I'm just trying to learn how to use the functions procedurally first, not making anything with that level of complexity) but you'll see how I've converted it.
void MainSDL::mouseMotion(SDL_Event *event)
{
	Global	*game = Global::getInstance();
	int xNow;
	int yNow;
	int xDiff;
	int yDiff;
	if(mouseToggle)
	{
		xNow = event->motion.x;
		yNow = event->motion.y;
		if(xNow == xMid && yNow == yMid)
		{
			// ignore
		}
		else
		{
			xDiff =  xNow - xLast;
			yDiff =  yNow - yLast;
			if(xDiff || yDiff)
			{
				game->hero->moveEvent(xDiff, yDiff);
				SDL_WarpMouse(xMid, yMid);
			}
		}
		xLast = xNow;
		yLast = yNow;
	}
}
xMid/yMid are defined as (pretty obviously) screenw/2 screenh/2 The warp mouse call pulls the mouse back to the middle of the screen, and the conditional filters out this by checking to see if xNow & yNow both equal the middle. If so it's filtered and ignored. I modified this conditional setup slightly but the conditional should still be perfectly valid.. Anyway here is what I have (xMove is used within the drawscene function to move the quad but it's really pretty basic and I don't think the error could be there). I'd appreciate any help at all with this. I'm sure it's something simple I'm overlooking but simple things aren't coming to me.. at all
int xNow;
  int yNow;
  int xDiff;
  int yDiff;
  int xLast;
  int yLast;
  int xMid;
  int yMid;
  int screenw = 1024;
  int screenh = 768;
  /* wait for events */
  while (!done)
  {
    /* handle the events in the queue */
    while (SDL_PollEvent(&event))
    {
      switch(event.type)
      {
      case SDL_ACTIVEEVENT:
        /* Something's happend with our focus
        * If we lost focus or we are iconified, we
        * shouldn't draw the screen
        */
        if (event.active.gain == 0)
          isActive = false;
        else
          isActive = true;
        break;
      case SDL_VIDEORESIZE:
        /* handle resize event */
        surface = SDL_SetVideoMode(event.resize.w,event.resize.h,32,videoFlags);
        if (!surface)
        {
          fprintf(stderr,"Could not get a surface after resize: %s\n",SDL_GetError());
          exit(1);
        }
        screenw = event.resize.w;
        screenh = event.resize.h;
        resizeWindow(event.resize.w,event.resize.h);
        break;
      case SDL_MOUSEMOTION:
        xNow = event.motion.x;
        yNow = event.motion.y;
        xMid = screenw/2;
        yMid = screenh/2;
        if(!(xNow == xMid && yNow == yMid))
        {
          xDiff = xNow-xLast;
          yDiff = yNow-yLast;
          if(xDiff || yDiff)
          {
            SDL_WarpMouse(xMid,yMid);
						xMove += xDiff * 0.01f;
						yMove += yDiff * 0.01f;
          }
          xLast = xNow;
          yLast = yNow;
					cout<<"xMove "<<xMove<<" yMove "<<yMove<<endl;
					cout<<"xDiff "<<xDiff<<" yDiff "<<yDiff<<endl;
					cout<<"xNow "<<xNow<<" yNow "<<yNow<<endl;
 					cout<<"xMid "<<xMid<<" yMid "<<yMid<<endl;
        }
        break;
      case SDL_KEYDOWN:
        /* handle key presses */
        handleKeyPress(&event.key.keysym);
        break;
      case SDL_QUIT:
        /* handle quit requests */
        done = true;
        break;
      default:
        break;
      }
    }
    /* draw the scene */
    if (isActive)
    {
      SDL_ShowCursor(0);
      drawGLScene();
    }
    else{ SDL_ShowCursor(1); }
  }
EDIT: I figured for interest sake I'd post some of the debug output which shows the direction of the problem
Quote:
xMove -4.84 yMove -0.57 xDiff -484 yDiff -57 xNow 28 yNow 327 xMid 512 yMid 384 xMove 0.18 yMove 0.04 xDiff 502 yDiff 61 xNow 530 yNow 388 xMid 512 yMid 384
It looks like it's attempting to bounce back to the position as SDL_WarpMouse tells it to, but that it's off by a bit when it's doing it.. But that doesn't make sense.. I have no idea what would cause such a thing. [Edited by - Xanas on May 16, 2006 9:38:38 PM]

Share this post


Link to post
Share on other sites
Well, something that differs between your code and his, is that when x and y are equal to mid, you ignore EVERYTHING, as in not updating your last x, y, not doing cout, etc...

Your if's last } should go after the } that closes the scope where the mouse is reset to the middle of the screen I guess.

Hope this helps

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You rock. Thanks for being my one response I don't know that I would have ever have found that. I just could not see that one difference. I thought my conditional was exactly the same and it was, but I wasn't paying enough attention to that.

And seeing that, it took me a few more minutes to really come to why (yeah I'm a moron and slow :) ) that was the problem.

When the mouse is reset back to position (lets say 0,0) the new motion is calculated from that position.

Lets say I move the moust first right to 1,0

Then I want to move the mouse up from there to 1,1

Well, based on my previous code the mouse itself was put back to 0,0, but rather than calculating the difference from this value I'm doing it from the previous 1,0 value. So when I try to move to 1, 1 instead I'm moving to 0, 1

This gave the impression of irratic movement (because my motions with the mouse are not nearly so precise as the numbers I'm giving here) when in reality it was pretty simple.

Quote:
Original post by xEricx
Well, something that differs between your code and his, is that when x and y are equal to mid, you ignore EVERYTHING, as in not updating your last x, y, not doing cout, etc...

Your if's last } should go after the } that closes the scope where the mouse is reset to the middle of the screen I guess.

Hope this helps


Share this post


Link to post
Share on other sites
that was obviously me above.. that's what i get for having firefox loaded in another x session and using konqueror instead on this one.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this