États souris et screen

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

États souris et screen

Message 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.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message 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)
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message 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)
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: États souris et screen

Message 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...
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: États souris et screen

Message 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...
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message 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.
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

Re: États souris et screen

Message 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 :))
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: États souris et screen

Message 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
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

Re: États souris et screen

Message 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...
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message 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 )
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

Re: États souris et screen

Message 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.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message 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.
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

Re: États souris et screen

Message 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.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: États souris et screen

Message par G-Rom »

La réponse est dans ta question.
La soluce, une lib tierce. sdl par exemple. dispo avec pb sous linux.
Joubarbe
Messages : 93
Inscription : sam. 01/juil./2006 16:40

Re: États souris et screen

Message 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.
Répondre