Page 1 sur 2

États souris et screen

Publié : ven. 25/sept./2015 9:29
par Joubarbe
Salut,

Bon, je tente le forum français, j'aurais peut-être davantage de réponses :)

Voilà mon problème : j'aimerais développer une application/jeu "cross-platform" utilisant DirectX/OpenGL. J'ai donc besoin d'un screen et de connaître tous les états de la souris. Mais je veux utiliser la souris hardware qui est plus réactive, préférable pour manipuler l'UI ou les jeux de style RTS (je crois d'ailleurs que c'est ainsi que font les pros : ils prennent la souris hardware et changent le curseur et ne font une souris software que pour les jeux de style FPS). De surcroît, avec la bibliothèque Mouse, j'ignore totalement comment modifier la sensibilité de la souris.

Le souci principal est de récupérer l'état "appuyé" de la souris. Aucun évènement PureBasic ne permet de le récupérer, donc j'utilise un truc hybride un peu bizarre :

Code : Tout sélectionner

  ExamineKeyboard() : ExamineMouse()
  
  ReleaseMouse(0)
  If MouseButton(#PB_MouseButton_Left)
    pushed = 1
  Else
    pushed = 0
  EndIf
  ReleaseMouse(1)
Et pour récupérer l'état "relâché" :

Code : Tout sélectionner

  Repeat
    
    event = WindowEvent()
    
    If event = #PB_Event_LeftClick
      Debug "released"
    EndIf
    
  Until event = 0
Ce qui donne, pour le code entier :

Code : Tout sélectionner

InitSprite() : InitKeyboard() : InitMouse()

OpenWindow(0, 0, 0, 1920, 1080, "")
OpenWindowedScreen(WindowID(0), 0, 0, 1920, 1080)

Repeat
  
  Repeat
    
    event = WindowEvent()
    
    If event = #PB_Event_LeftClick
      Debug "released"
    EndIf
    
  Until event = 0
  
  ExamineKeyboard() : ExamineMouse()
  
  ReleaseMouse(0)
  If MouseButton(#PB_MouseButton_Left)
    pushed = 1
  Else
    pushed = 0
  EndIf
  ReleaseMouse(1)
  
  If pushed
    Debug "pushed"
  EndIf
  
  ClearScreen(0)
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)
Et c'est là que les choses se corsent, car le #PB_Event_LeftClick n'est pas récupéré sur Linux. Et sur Windows, "pushed" n'est jamais égal à 1.

En d'autres termes : sur Linux, j'ai le "pushed" mais pas le "released" ; sur Windows, j'ai le "released" mais pas le "pushed".
Et sur Mac, j'ignore totalement le comportement, car je n'ai pas de Mac...

Cela fait un moment que je développe sous PB, mais jusque là, je n'utilisais que Windows, et le système d'events internes (avec l'API) me suffisait. Mais ça restait du bricolage, et j'aimerais bien savoir comment on gère correctement une souris ; le but étant d'avoir les états suivants : appuyé, relâché, relâché au même endroit, double cliqué ; ainsi que la gestion de la mollette. Mais pour le moment, la question, c'est de savoir comment récupérer l'état appuyé :)

Merci.

Re: États souris et screen

Publié : ven. 25/sept./2015 12:25
par G-Rom
tu récupère l’état dans un boolean et tu le traite avec des drapeaux ( keyflag )
là tu as pressed & released

Code : Tout sélectionner

InitSprite() : InitKeyboard() : InitMouse()

OpenWindow(0, 0, 0, 1920, 1080, "")
OpenWindowedScreen(WindowID(0), 0, 0, 1920, 1080)

pushed.a   = #False 
keyflag.a  = #False 


Repeat
  
  Repeat
    
    event = WindowEvent()
    
    
  Until event = 0
  
  ExamineKeyboard() : ExamineMouse()
  
  
  Button.a = MouseButton(#PB_MouseButton_Left)
  
 
  If Button And Not keyflag
    keyflag = #True
    Debug "Pressed"
  EndIf
  
  If Not Button And keyflag
    keyflag = #False
    Debug "Released"
  EndIf
 
    
  
  ClearScreen(0)
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)

Re: États souris et screen

Publié : ven. 25/sept./2015 12:31
par G-Rom
Avec le double click , portable & sans api :

Code : Tout sélectionner

InitSprite() : InitKeyboard() : InitMouse()

OpenWindow(0, 0, 0, 1920, 1080, "")
OpenWindowedScreen(WindowID(0), 0, 0, 1920, 1080)

pushed.a   = #False 
keyflag.a  = #False 

clickcount.l = 1
clickdelay.l = 0

Repeat
  
  Repeat
    
    event = WindowEvent()
    
    
  Until event = 0
  
  ExamineKeyboard() : ExamineMouse()
  
  
  Button.a = MouseButton(#PB_MouseButton_Left)
  
 
  If Button And Not keyflag
    keyflag = #True
    Debug "Pressed"
    
    If clickdelay > ElapsedMilliseconds()
      clickcount+1
      clickcount%2 + 1
    Else
      clickdelay = ElapsedMilliseconds()+250
      clickcount=0
    EndIf 
      
      
  EndIf
  
  If Not Button And keyflag
    keyflag = #False
     Debug "Released"
  EndIf
 
  If clickcount=2 ; double click
    Debug "double click"
    clickcount=0
  EndIf   
  
  
  ClearScreen(0)
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)

Re: États souris et screen

Publié : ven. 25/sept./2015 13:00
par crisot
Joubarbe a écrit :Salut,
Et c'est là que les choses se corsent, car le #PB_Event_LeftClick n'est pas récupéré sur Linux. Et sur Windows, "pushed" n'est jamais égal à 1.

En d'autres termes : sur Linux, j'ai le "pushed" mais pas le "released" ; sur Windows, j'ai le "released" mais pas le "pushed".
Et sur Mac, j'ignore totalement le comportement, car je n'ai pas de Mac...
Merci.
Je ne peux pas te dire ni pour Linux ni pour MacOs, en revanche, tu devrais avoir Pushed à 1 sous Windows, car MouseButton(#PB_MouseButton_Left) fonctionne parfaitement et permet de savoir si le button est pressé ou relaché. Il ne donne pas les clic ni les doubleclic mais bien l'état.

Le "problème" c'est les ReleaseMouse() encadrant, qui, oui, rendent le comportement de la souris très aléatoire.

Essayes sans ces ReleaseMouse tu verra que ton état MouseButton() est bon.

J'avais essayé ce genre de bricole pour avoir le curseur hardware qui ne disparait pas, malheureusement, sans succès. Maintenant les curseurs soft sont une catastrophe, il va falloir faire autrement...

Re: États souris et screen

Publié : ven. 25/sept./2015 13:17
par crisot

Code : Tout sélectionner

InitSprite() : InitKeyboard() : InitMouse()

OpenWindow(0, 0, 0, 1920, 1080, "")
OpenWindowedScreen(WindowID(0), 0, 0, 1920, 1080)
ShowCursor_(1)

Repeat
	Repeat
		event = WindowEvent()
	Until event = 0

	ExamineKeyboard() : ExamineMouse()

	pushed = MouseButton(#PB_MouseButton_Left)
  	If Not pushed=oldpushed
		If pushed=1 : Debug "pushed" : EndIf ; debuging
		If pushed=0 : Debug "released" : EndIf ; debuging
		oldpushed=pushed
	EndIf
  
	ClearScreen(0)
  
	FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)
Le ShowCursor() remplace avantageusement les ReleaseMouse() pour faire réapparaitre le cursor hardware.
Du coup MouseButton() fonctionne de nouveau et te retourne les états. Avec un système de "flag" comme le dit G-Rom ou d'ancien état, tu en déduit les état pushed et released facilement.

EDIT: Ah fuck it. J'avais pas percuté mais ShowCursor_() n'est pas multi-plateforme...

Re: États souris et screen

Publié : ven. 25/sept./2015 13:27
par G-Rom
pour Linux y a XDefineCursor :

Code : Tout sélectionner

 XDefineCursor(display, w, cursor)
	  Display *display;
	  Window w;
	  Cursor cursor;

  XUndefineCursor(display, w)
	  Display *display;
	  Window w;
Pour *Display y a

Code : Tout sélectionner

Display *XOpenDisplay(display_name)
Tu passes #NULL et tu as le moniteur courant
Pour Window , WindowID() dois faire l'affaire.

Re: États souris et screen

Publié : sam. 26/sept./2015 8:23
par Joubarbe
Oops, désolé, je n'avais pas reçu de notifications à vos réponses.

G-Rom : dans tes exemples, le problème est que le curseur n'apparaît pas. Les ReleaseMouse() sont justement faits pour que je puisse voir le curseur hardware. Mais oui, en effet, ce sont eux qui causent des problèmes. Sauf que sans eux, je me retrouve avec du curseur software.

Dans ton dernier message, tu donnes l'équivalent du ShowCursor_() sur Linux, semble-t-il. Sur la doc, je trouve : "Specifies the cursor that is to be displayed or .ZN None ."
Pas sûr de comprendre l'usage de tout ça. Est-ce que ce n'est pas que pour changer l'icône du curseur ? Que se passe-t-il s'il est déjà capturé par le screen ?

(Quoi qu'il en soit, merci à tous les deux pour ce début de réponse, ça fait longtemps que je cherche une réponse à tout ça :))

Re: États souris et screen

Publié : sam. 26/sept./2015 10:33
par blendman
Et sinon, si tu passes par un screen inséré dans un canvasgadget ?
Je sais que ça fonctionne sous windows, sous linux je ne suis plus certain, et mac non plus.

Code : Tout sélectionner

 If InitSprite() = 0
    MessageRequester("Erreur", "Impossible d'ouvrir l'écran & l'environnement nécessaire aux sprites !", 0)
    End
  EndIf
  
  If OpenWindow(0, 0, 0, 220, 160, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(0, 170, 135, 45, 20, "Quitter")
    
    If CanvasGadget(1,0,0,160,160)
    
    If OpenWindowedScreen(GadgetID(1), 0, 0, 160, 160)
      CreateSprite(0, 20, 20)
      If StartDrawing(SpriteOutput(0))
        Box(0, 0, 20, 20, RGB(255, 0, 155))
        Box(5, 5, 10, 10, RGB(155, 0, 255))
        StopDrawing()
      EndIf
    Else
      MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
      End
    EndIf
  EndIf
  
  EndIf
  
  direction = 2
  Repeat
    ; Il est très important de traiter tous les évènements restants dans la file d'attente à chaque tour
    ;
    Repeat
      Event = WindowEvent()
      
      Select Event 
        Case #PB_Event_Gadget
          Select EventGadget() 
            Case 0
              End
            Case 1
              mx = GetGadgetAttribute(1, #PB_Canvas_MouseX)
              my = GetGadgetAttribute(1, #PB_Canvas_MouseY)

              Select EventType()
                  
                Case #PB_EventType_LeftButtonDown
                  Debug "Left down"
                Case #PB_EventType_LeftButtonUp
                  Debug "Left up"
                  Case #PB_EventType_RightButtonDown 
                  Debug "Right down"
                Case #PB_EventType_RightButtonUp 
                  Debug "Right up"
                  
              EndSelect
                           
          EndSelect
        
        Case #PB_Event_CloseWindow
          End 
      EndSelect
    Until Event = 0
    
    If StartDrawing(ScreenOutput())
      DrawText(0,0,"Mouse : "+Str(mX)+"/"+Str(my))
      StopDrawing()
    EndIf
    
    FlipBuffers() 
    ClearScreen(RGB(0, 0, 0))    
    DisplaySprite(0, x, x)
    x + direction
    If x > 140 : direction = -2 : EndIf
    If x < 0   : direction =  2 : EndIf
    Delay(1)
  ForEver

Re: États souris et screen

Publié : sam. 26/sept./2015 11:03
par Joubarbe
@blendman : oui j'avais pensé à un truc du genre, mais ça ne fonctionne que sous Windows comme tu le soupçonnes.

En revanche, je me dis de plus en plus que pendant tout ce temps, mon cerveau s'est verrouillé sur l'idée de comment gérer la souris avec des évènements, alors que la question est peut-être bien plus simple, à savoir : comment avoir un ShowCursor_ crossplatform ? Je me demande si ça ne suffirait pas...

Re: États souris et screen

Publié : sam. 26/sept./2015 11:08
par G-Rom
Sous linux , la souris est completement buggé...
je crois me souvenir qu'il y a un exemple avec la SDL , regarde de ce coté & c'est portable ( en théorie )

Re: États souris et screen

Publié : sam. 26/sept./2015 13:07
par Joubarbe
@G-Rom : On est bien d'accord que lorsque tu parlais de XDefineCursor(), tu faisais référence à un équivalent de ShowCursor_ ? Si oui, j'apprécierais vraiment que tu me montres comment en faire usage. Si je pouvais faire apparaître le curseur sur toutes les plateformes, je pense que je m'en sortirais en utilisant la bibliothèque Mouse normalement.

Re: États souris et screen

Publié : sam. 26/sept./2015 13:43
par G-Rom
On est bien d'accord que lorsque tu parlais de XDefineCursor(), tu faisais référence à un équivalent de ShowCursor_ ?
Non, c'était des pistes d'apres un survol sur google.

Re: États souris et screen

Publié : sam. 26/sept./2015 20:23
par Joubarbe
Argh, mais il doit bien y avoir un équivalent de ShowCursor_ sous Linux non ? Quand tu dis que la souris est complètement buggée, moi je vois tous les jeux qui tournent très bien sur Linux ; il doit bien y avoir un truc :) Ou alors c'est PB qui est à la ramasse.

Re: États souris et screen

Publié : sam. 26/sept./2015 20:26
par G-Rom
La réponse est dans ta question.
La soluce, une lib tierce. sdl par exemple. dispo avec pb sous linux.

Re: États souris et screen

Publié : sam. 26/sept./2015 20:38
par Joubarbe
Justement, j'ai bien peur d'avoir à poser cette question idiote, mais... comment accède-t-on à SDL avec PB ? ... "sdl" dans l'option de compilation renvoie une erreur.