I've been playing alot with this stuff but didn't have time to post earlier.
I came to your same conclusion, that using ShowCursor_() is the only way to fix it.
But then I found out another problem.
Seems like putting the ExamineMouse() in a thread gives many more problems than it solves. This is actually the only working (and easy to implement) solution I've found for the mouse sensitivity problem, but it basically breaks the fullscreen mode.
Not only it breaks the mouse pointer hiding, but (and this is even more important), it breaks IsScreenActive(), but only if your screen is fullscreen, while it seems to be working fine in windowedscreen mode.
To check this, I have modified Dobro's great solution to the alt-tab problem of the fullscreen mode:
Code: Select all
; Purebasic 4.41
;By Dobro
; exemple de l'utilisation de IsScreenActive()
; quittez le pseudo jeux avec Alt+TAB
; on retourne dans le jeux d'un clique sur la fenetre en barre des taches
#threadedmouse=1 ;set to 0 to disable mousethread(), 1 to enable it
InitSprite ()
InitMouse ()
InitKeyboard ()
Enumeration
#sprite
EndEnumeration
Structure sprite
x.i
y.i
pas_x.i
pas_y.i
EndStructure
Dim sprite.sprite(1)
ExamineDesktops ()
x_screen= DesktopWidth (0) ; je recup la rez de l'ecran
y_screen= DesktopHeight (0)
flag=0
CompilerIf #threadedmouse=1
firstrun=1
Global mousex.i,mousey.i
Procedure mousethread(flag.i)
Static quit.i
If flag
Repeat
ExamineMouse()
mousex=MouseX()
mousey=MouseY()
Delay(1)
Until quit
quit=#False
Else
If Not flag
quit=#True
While quit
Delay(1)
Wend
EndIf
EndIf
EndProcedure
CompilerEndIf
debut: ; le label qui permet le retour dans le jeux !!
OpenScreen (x_screen, y_screen, 32, "Fullscreen + ALT-TAB démo" )
ReleaseMouse (0)
CompilerIf #threadedmouse=1
If firstrun=1
CreateThread(@mousethread(),#True)
firstrun=0
EndIf
CompilerEndIf
CreateSprite ( #sprite , 64, 64)
StartDrawing ( SpriteOutput ( #sprite ))
Box (0,0,64,64, RGB (255,13,40))
StopDrawing ()
;********* initialisation du sprite **********
If flag=0 ; le joueur n'est jamais sorti du jeu , s'il est sorti on ne fais pas ce bloc de code !!
sprite(1)\x=x_screen/2 ; on place le sprite au centre
sprite(1)\y=y_screen/2 ; on place le sprite au centre
sprite(1)\pas_x=2 ; on donne une vitesse de deplacement a notre sprite
sprite(1)\pas_y=2 ; on donne une vitesse de deplacement a notre sprite
EndIf
Repeat
ExamineKeyboard () ; ne sert que pour quitter le prg avec la touche esc
; ************* gere le deplacement du sprite ***************
sprite(1)\x=sprite(1)\x+sprite(1)\pas_x
sprite(1)\y=sprite(1)\y+sprite(1)\pas_y
; ----------------------------------------------------------------------------
If sprite(1)\x+64>=x_screen:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
If sprite(1)\y+64>=y_screen:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
; ----------------------------------------------------------------------------
If sprite(1)\x<=0:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
If sprite(1)\y<=0:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
; *******************************************************
; ********** affichage du sprite *********************
DisplayTransparentSprite ( #sprite , sprite(1)\x, sprite(1)\y)
FlipBuffers ()
ClearScreen (0)
; *************** attention toute l'astuce est la !! *******************
If IsScreenActive () = 0 ; le joueur a quitter le jeu (Alt-tab)
ReleaseMouse (1) ; je libere la souris ... inutile ici mais bon
flag=1 ; on note que l'utilisateur est sorti du jeux
CloseScreen () ; on ferme l'ecran
; ******* la ruse de guerre !! ****************************
OpenWindow (1,1,1,1,1, "toto le jeu " , #PB_Window_Minimize ) ; j'ouvre une fenetre que je minimise en bar des taches
Repeat :Event= WaitWindowEvent (2): Until Event= #PB_Event_ActivateWindow ; j'attend qu'on clique sur la fenetre
CloseWindow (1) ; je ferme la fenetre
Goto debut ; je retourne dans le jeux sans réinitialiser les variables de déplacement (on reprends ou on en etait! !!! )
EndIf
Until KeyboardPushed ( #PB_Key_Escape ) ; là , on veux vraiment quitter le jeux LOL
End
In the example above, activating the mousethread will break IsScreenActive() as it will not report any status change in that case.
In my game I'm trying to support both windowedscreen and fullscreen modes, and that code works fine when in windowedscreen, but not in fullscreen mode.
What's worse, is another problem I found. After some compiles of my code, both the windowedscreen and fullscreen modes gets broken so much that they either shows a black screen and nothing else (the debugger reports no error but Stop doesn't work anymore), or the debugger (and the executable) quits by themselves without reporting anything wrong when you alt-tab.
The only solution is to reboot the system, but then the problem reappears again after some compiles.
What's weird, is that this problem also affects executables I compiled (and tested to be working fine) days or weeks ago (but that contains the same mousethread() handling), but ALT-TAB still works fine on executables which doesn't use that thread.
Even compiling a game or 2D example which uses alt-tab works in this state, as long as you don't use the mousethread(). It's like something in memory gets corrupted, but only affects programs made with that same thread (which should be recreated anew everytime you run another executable I think, but it's like in this case the system keeps using the same one).
I have tried debugging the mousethread() address and it looks like it's always the same unless you restart PB, in which case it changes but the game is still broken.
I'm not sure if it happens also in that example above, but you can try recompiling it for some times (10 or more), until alttabbing out doesn't work anymore (the window in the taskbar will no longer show "toto le jeu" but will have the screen name, "Fullscreen + ALT-TAB démo"). What I am sure of is that when my game doesn't work anymore, that example doesn't work aswell, and the only way to fix it is to compile without the mousethread().
I wonder if not quitting the thread manually (with mousethread(#false)) might be the culprit, I'll check it myself but I need to reboot before, but anyway shouldn't the thread be closed by PB itself at End?
This stuff is really weird, and all of these problems took me more time than coding the game itself :/