Clash when using SDL_ShowCursor() and SDL_WarpMouse()

I’ve written a multi-player game where each person can choose to use the
mouse or keyboard.

The mouse pointer is hidden when it’s a keyboard player’s go and it’s also
important that the game returns the mouse pointer to its last position when
there are multiple mouse players.

The problem I have is that when my application redisplays the mouse pointer
using SDL_ShowCursor( SDL_ENABLE ) and then moves it using SDL_WarpMouse()
the pointer moves but the physical pointer isn’t redrawn.

The following example program demonstrates the issue well. The mouse
pointer is hidden and when it reappears it seems to be in the same place,
but if you ‘twitch’ the mouse slightly it jumps to its real position.

This is an issue in both Linux (1.2.0) and Windows (1.0.8), for both
full-screen and window when using the normal pointer. SDL seems to lock
and flush the events, but doesn’t work. I’d have to hack in a delay to
make it work, and I really don’t want to do that.

Help!

Ta.

  • Deth. -
    (P.S. Why does ‘gcc -Wconversion’ generate warnings with/without cast?)

====== Makefile ======

CC=gcc
CFLAGS=-Wall -O2 -pipe

SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)

default: test

test: test.c
$(CC) test.c $(CFLAGS) $(SDL_CFLAGS) $(SDL_LDFLAGS) -o test

====== test.c ======

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

#define SYSTEM_ERROR 2

/* Main processing. */

int main( int argc, char *argv[] )
{
static SDL_Surface *Screen;

/* Access the SDL library.  */
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
    fprintf( stderr, "Unable to initialise SDL library,\n\t%s",
             SDL_GetError() );
    return SYSTEM_ERROR;
}

/* Ensure that SDL is closed when the program ends.  */
if ( atexit( SDL_Quit ) )
{
    perror( "atexit" );
    fprintf( stderr, "Failed to register graphics shutdown handler." );
}

/* Open the graphics display.  */
Screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, SDL_SWSURFACE );
if ( Screen == NULL )
{
    fprintf( stderr, "Unable to set video mode,\n\t%s", SDL_GetError() );
    return SYSTEM_ERROR;
}

/* Wait for 5 seconds.  */
SDL_Delay( 5000 );

/* Hide the mouse pointer.  */
(void) SDL_ShowCursor( SDL_DISABLE );

/* Wait for 5 seconds.  */
SDL_Delay( 5000 );

/* Redisplay mouse pointer and then move it to the centre of the screen.  */
(void) SDL_ShowCursor( SDL_ENABLE );
SDL_WarpMouse( (Uint16) SCREEN_WIDTH / 2, (Uint16) SCREEN_HEIGHT / 2 );

/* Wait for 5 seconds.  */
SDL_Delay( 5000 );

/* Return successfully.  */
return 0;

}

“Lee Haywood” wrote in message
news:986919498 at ksl.uk

I’ve written a multi-player game where each person can choose to use the
mouse or keyboard.

The mouse pointer is hidden when it’s a keyboard player’s go and it’s also
important that the game returns the mouse pointer to its last position
when
there are multiple mouse players.

The problem I have is that when my application redisplays the mouse
pointer
using SDL_ShowCursor( SDL_ENABLE ) and then moves it using SDL_WarpMouse()
the pointer moves but the physical pointer isn’t redrawn.

So why don’t you warp first and then call ‘SDL_ShowCursor’?–
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor

I have seen this before (in Tux Typing) and I solved it by handling the mouse
cursor via a surface (this actually solves a lot of problems, many dealing
with laptop screen refreshes [or lack thereof :wink: ] and not just this one).

While I have seen this problem before, I could not get get the bug to work
with the example code you sent.On Tuesday 10 April 2001 16:44, you wrote:

The problem I have is that when my application redisplays the mouse pointer
using SDL_ShowCursor( SDL_ENABLE ) and then moves it using SDL_WarpMouse()
the pointer moves but the physical pointer isn’t redrawn.

The following example program demonstrates the issue well. The mouse
pointer is hidden and when it reappears it seems to be in the same place,
but if you ‘twitch’ the mouse slightly it jumps to its real position.

This is an issue in both Linux (1.2.0) and Windows (1.0.8), for both
full-screen and window when using the normal pointer. SDL seems to lock
and flush the events, but doesn’t work. I’d have to hack in a delay to
make it work, and I really don’t want to do that.


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

“Rainer Deyke” wrote:

So why don’t you warp first and then call ‘SDL_ShowCursor’?

Erm, because I hadn’t thought of doing that.

It’s still a bug, but this workaround works very well - in the test program
at least. It’s a little harder in the actual application because the 2
actions aren’t processed in the same place, but I’ll hack it in.

Thanks.

  • Deth -