[v4] Gros bug ecran et changer d'utilisateur

Archive.
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Plantage application au changement d'utilisateur

Message par Thyphoon »

sylvain38 a écrit :J'ai la version 4 et j'ai le même genre de probléme.
Au changement d'utilisateur ou ecran de veille, l'application plante au retour !!!!
Pas de nouvelle de Fred a propos de ce bug génant ?
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message par Dräc »

Je pense rencontrer un problème connexe :

Mon programme utilise la bibliothèque 2D et 3D.
Si j’exécute mon programme et que je le laisse ainsi pour faire autre chose sur l’ordinateur, il peut arriver que la fenêtre soit gelée lorsque j’y retourne car le programme ne répond plus !

Si je le laisse à nouveau pour y revenir plus tard, le programme peut avoir retrouvé son état de fonctionnement nominal.

Cette situation est très ennuyante car elle touche à la fiabilité des exe générés.

Comme Fred parle de « Va falloir que je trouve autre chose pour preserver les sprites, j'ai plus d'idees pour l'instant. », je me demande si cela n’est pas lié.

J’espère en tout les cas que mon observation lui donnera quelques pistes et je suis dispo si questions/tests…
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Cette remarque de Fred date d'un an, Thyphoon, et le sujet vient de remonter, peut-être que de nouvelles idées ont germées depuis (il faut savoir rester patient et positif, même si je reste dubitatif à ce sujet :lol:).

Une lecture du code de langages open source qui préservent les sprites correctement pourrait-elle apporter quelques nouvelles pistes ou PureBasic est-il trop avancé pour modifier franchement la gestion de ses sprites sans tout refaire (auquel cas le language est dans la mouise) ?
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Where are you Fred ? We can see you on the English forum but not at all on the French one, snif your cliens are so sad.
Fred
Site Admin
Messages : 2652
Inscription : mer. 21/janv./2004 11:03

Message par Fred »

Malheureusement, je n'ai pas de solution miracle à ce probleme. Une des solution peut etre de tester IsScreenActive() et de recreer l'écran/recharger les sprites quand il redevient actif.
barnierchristophe
Messages : 64
Inscription : lun. 07/févr./2005 11:18

ça fout les jetons votre truc

Message par barnierchristophe »

Il va falloir payer???
Anonyme

Message par Anonyme »

Pour mon p'tit Moteur3D en opengl, je n'ai aucun problème, je change de session puis je reviens , l'écran est toujours là, c'est peut être du à directx.

Gratteur, essaye d'utilisé le subsystem opengl. moi j'ai déjà essayer sans succès...
D'ailleurs, Fred, les sprites/3D, les opération de dessin (les plots, les ligne)
utilise quoi comme api? directX? car avec le subsytem gl impossible de faire un startdrawing(windowoutput()) par exemple, ca plante avec un invalid acces memory. impossible donc d'afficher un sprite...
j'ai réussi quand meme à ecrire du texte avec text() mais le texte clignote.

@++
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Tester IsScreenActive() et tout décharger/recharger n'est pas du tout une solution pour les gros projets ou petits ordinateurs. A la limite recharger les ressources est envisageable lorsque quelque chose en mode plein écran s'ouvre ou lorsqu'on rentre dans une session.

J'ai du mal à croire que Windobe ne revoit pas de message dans ces cas la.

Cpl.Bator, tu as raison, c'est sans doute une solution mais je n'ai pas trop l'envie et le temps de passer à OpenGl pour la 2D (ni pour la 3D qui est soumise au même bug).

Fred, comme ta réponse est très clair (ça n'a pas du être facile à accepter et c'est vraiment dommage pour le purebasic mais merci de l'avoir écrit noir sur blanc), je ne vais pas insister plus sur ce sujet.

Voila.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Voilà ce que je fais

Code : Tout sélectionner

If IsScreenActive()=0 ;if user is switching to desktop
	ReleaseMouse(1)
	Repeat
		FlipBuffers(1) ;without flip, we can't know that our screen is active
	Until IsScreenActive()<>0
	CloseScreen() ;I prefer to close our screen and recreate, coz I don't trust pb and directx
	Gosub SCREEN_INIT
	Gosub LOADING ;sprites have to be reloaded as closing screen has freed them
	Gosub REDRAW_LEVEL
	Gosub VAR_INIT
	ReleaseMouse(0)
Else
	ReleaseMouse(0)
EndIf
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

C'est presque bien pour de petits programmes qui n'ont pas de besoin de tonnes de manipulations après la création des sprites, sinon on peut toujours les sauvegarder dans un fichier temporaire pour les recharger mais ça prend trop de temps, de place et l'opération est trop fréquente en mode fenêtré.

J'utilise une méthode similaire (avec des procédure parceque les goto hors asm c'est quand même sale ou vieux jeu) pour lancer des rendus plein écran pour les éditeurs de cartes par exemple.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Tiens, voilà la méthode "officielle". http://www.drunkenhyena.com/cgi-bin/vie ... st_Devices
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Cette méthode ne résoud pas ce bug sous PureBasic, l'écran plante quand même (ou waitwindowevent() parfois quand il y a une callback).

Après des heures de recherche dans tous les sens et 1 an et demi de frustration j'ai enfin trouvé une solution simple, rapide et efficasse à ce bug qui pourrit les logiciels et les jeux ! Et je vous jure que ça fait du bien !

Bon j'ai un rendez-vous dans 10 minutes, pas le temps d'en dire plus. De toute façon, depuis le temps et puisque ça interesse si peu de monde, on n'est plus à quelques jours...

A plus tard !
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Bon, le principe est simple, même si c'est du bricolage (vive l'api window) on utilise un hDC qui est dégradé et qui plante en même temps que l'écran mais qui a au moins le mérite de ne pas faire bugger l'application (comme GetDC_()) :

Code : Tout sélectionner

verifDC = GetDC_(0)
Et on utilise une fonction rapide pour vérifier, comme GetPixel_() qui rend la couleur d'un pixel de l'image dans le DC et -1 sinon.

Code : Tout sélectionner

GetPixel_(verifDC, 0, 0)
Donc si GetPixel_(verifDC, 0, 0) = -1 alors les ressources ont planté, on peut mettre le programme en attente et on doit les recharger le moment venue.

Plus besoin de tout fermer dès que IsScreenActuve() = 0 (et dans ce cas on peut par exemple juste sauvegarder les ressources à recharger si besoin) pour éviter le plantage.

Code : Tout sélectionner

; Eviter que l'écran ne plante ou que les sprites se dégradent
; Tuto réalisé par Gratteur

Procedure Init() ; Initialisation et ouverture de la fenetre principale
  Global verifDC
  op = #PB_Window_ScreenCentered|#PB_Window_SystemMenu
  OpenWindow(0, 0, 0, 300, 200, "Test", op)
  InitSprite()
EndProcedure

Procedure Quitter() ; Fermeture du programme
  ReleaseDC_(0, verifDC)
  End
EndProcedure

Procedure OuvrirEcran() ; Ouverture de l'écran et des sprites
  OpenWindowedScreen(WindowID(0), 0, 0, 300, 200, 0, 0, 0)
  CreateSprite(0, 200, 100)
  StartDrawing(SpriteOutput(0))
    Box(0, 0, 200, 100, RGB(0, 255, 0))
  StopDrawing()
  verifDC = GetDC_(0) ; On ouvre un DC sur le bureau
EndProcedure

Procedure FermerEcran() ; Fermeture de l'écran
  CloseScreen()
EndProcedure

Procedure Main()
  Repeat
    If GetPixel_(verifDC, 0, 0) = -1 
      ; Dans ce cas DC est planté (on est en plein écran ou la session est en attente)
      FermerEcran() ; On ferme l'écran
      Repeat
        ReleaseDC_(0, verifDC) ; On libère le DC
        verifDC = GetDC_(WindowID(0)) ; On ouvre un DC sur la fenêtre cette fois (car une autre application peut etre en plein écran)
        Delay(10)
      Until GetPixel_(verifDC, 0, 0) <> -1
      ReleaseDC_(0, verifDC) ; On libère le DC
      OuvrirEcran() ; On ouvre l'écran et on recharge les sprites
    EndIf
    ; On affiche les sprites
    DisplayRGBFilter(0, 0, 300, 200, 0, 0, 255)
    DisplaySprite(0, 50, 50)
    FlipBuffers()
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndProcedure

Init()
OuvrirEcran()
Main()
Quitter()

; Si vous avez des sprites qui ont été modifiés, alors quand IsScreenActive() = 0
; il faut sauvegarder dans un fichier temporaire les sprites à conserver.
; Ensuite dès que IsScreenActive() <> 0, soit on utilise la méthode ci-dessus si 
; GetPixel_(verifDC, 0, 0) = -1, soit on efface les fichiers temporaires pour récupérer 
; la place qu'ils prennent sur le disque dur (on peut aussi les effacer plus tard)
Voila, on peut enfin faire des applications correctes avec un écran ! 8)
De rien.

(On peut sans doute utiliser un DC plus petit) mais je vous livre ça en expresse en espérant que quelqu'un partagera ma joie et mon soulagement :D. Yep ! Des remarques ?
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Gratteur a écrit :(On peut sans doute utiliser un DC plus petit) mais je vous livre ça en expresse en espérant que quelqu'un partagera ma joie et mon soulagement :D. Yep ! Des remarques ?
oui , je suis content de voir un homme heureux :P


[EDIT]
Perso ça ne me traumatisait pas ce problème mais c'est sympa de partager ton astuce avec nous.
Gratteur
Messages : 147
Inscription : ven. 22/avr./2005 23:02

Message par Gratteur »

Un peu que je suis content oui, c'était le dernier obstacle qui m'empêchait de faire des applications propres, entre temps j'ai commencé à étudier d'autres languages moins amusants et j'enviseagais de tout recommencer en c++.

Mais c'est du passé maintenant. Du coup je vais bientôt vous parler à nouveau de mon projet. Youpie !

Pour résumer le cas général en mode fenêtré avec écran vous faites ça :

Code : Tout sélectionner

Global verifDC = GetDC_(0)

Procedure VerifDC()
  If GetPixel_(verifDC, 0, 0) = -1
    ReleaseDC_(0, verifDC)
    CloseScreen()
    Repeat
      ReleaseDC_(0, verifDC)
      verifDC = GetDC_(WindowID(0))
      WindowEvent()
      Delay(10)
    Until GetPixel_(verifDC, 0, 0) <> -1
    ReleaseDC_(0, verifDC)
    verifDC = GetDC_(0)
    ;ouvrir l'écran
    ;charger les sprites
  EndIf
EndProcedure

Repeat
    ev = WaitWindowEvent() ; ou WindowEvent() + un Delay() ou vous voulez
    VerifDC()
    ; votre code
Until ev = #PB_Event_CloseWindow
ReleaseDC_(0, verifDC)
Répondre