Partage
  • Partager sur Facebook
  • Partager sur Twitter

Programme en C avec SDL et DevC++ qui plante !

    17 février 2017 à 16:49:22

    Je désalloue bien toutes les surfaces mais tout à la fin du programme avec SDL_FreeSurface (...) ; Et pendant l’exécution de la boucle je ne désalloue rien puisque mon programme en a besoin. Ou alors j'ai pas bien compris un truc...

    Ça n’a rien à voir avec les surfaces. C’est un problème d’évènements. L’analogie de @Fvirtman devrait t’aider à bien comprendre le truc.

    Je sais pas s'il faut le placer à un autre endroit du programme aussi ? dans tous les boucles for ?

    Tu dois gérer tes évènements quand il le faut. De manière générale, si tu ne récupères pas les évènements à n’importe quel moment de ton programme comment peux-tu savoir que l’on décide par exemple de le quitter.

    • Partager sur Facebook
    • Partager sur Twitter
    Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
      17 février 2017 à 17:25:07

      @Fvirtman a parlé de surfaces aussi :
      [...] Si c'est le cas, c'est que tu ne désalloues pas toutes les surfaces que tu alloues. Et ça dans une boucle.
      Et l'analogie je l'ai bien comprise. Ce que j'avais moins compris était sur à quel moment le programme stocke ces events. En gros il faut faire quoi pour que le facteur passe? ^^ Et il faut faire quoi pour vider la boîte aux lettres. Mais je pense que j'ai compris là.


      De manière générale, si tu ne récupères pas les évènements à n’importe quel moment de ton programme comment peux-tu savoir que l’on décide par exemple de le quitter.
      Enfaite ma boucle recommence tous les 30ms (C'est géré avec SDL_GetTicks et SDL_Delay), du coup c'est assez court pour savoir quel touche on appuie à quel moment du programme.

      • Partager sur Facebook
      • Partager sur Twitter
        17 février 2017 à 20:50:32

        Ce que j'avais moins compris était sur à quel moment le programme stocke ces events. En gros il faut faire quoi pour que le facteur passe?

        Le programme stocke un évènement dès qu’un évènement a lieu, c’est automatique.

        Et il faut faire quoi pour vider la boîte aux lettres.

        Pour vider la boîte, il faut utiliser les fonctions de la SDL qui lisent les évènements.

        Tiens regarde ici, la section « Une file d’évènements » est celle qui t’intéressera le plus ici,mais tu peux lire le reste également.

        • Partager sur Facebook
        • Partager sur Twitter
        Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
          17 février 2017 à 23:26:04

          En gros le programme stocke les évènement quand il utilise SDL. (oui, et dès qu'un évènement arrive)

          Je viens de réussir à installer SDL 2 et je me rends compte que la moitié des commandes sont différents de SDL 1.2. :waw:
          Du coup je capitule et je veux bien envoyer mon code à quelqu'un.  Par contre niveau convention c'est pas très comme il le faudrait. Et j'utilise même des variables globales. ^^
          • Partager sur Facebook
          • Partager sur Twitter
            17 février 2017 à 23:35:57

            Je viens de réussir à installer SDL 2 et je me rends compte que la moitié des commandes sont différents de SDL 1.2.

            C’est pas si différent de ça (ça prend beaucoup moins d’une semaine pour faire la transition). Il y a même un guide de migration sur le site de la SDL (et la traduction en français sur developpez). En gros c’est ça.

            • La fenêtre n’est plus une surface mais un SDL_Window (c’est beaucoup mieux comme ça, on peut gérer du multi-fenêtrage, etc.).
            • On n’utilise quasiment plus les surfaces qui sont remplacées par des textures (mieux aussi, permet redimensionnement à la volée, etc.).

            Sinon, les évènements c’est en gros la même chose et il y a des ajouts intéressants.

            • Partager sur Facebook
            • Partager sur Twitter
            Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
              17 février 2017 à 23:48:53

              Oui, je viens de découvrir ce guide. Et il y a pleins de trucs en plus qui sont intéressants, mais si au final j'ai le même problème j'aurais perdu beaucoup de temps...
              Quelqu'un est motivé.. eu non, quelqu'un veut avoir l'honneur (voila) de vérifier mon code ? :)
              • Partager sur Facebook
              • Partager sur Twitter
                20 février 2017 à 0:00:59

                Bon, là je me suis finalement pris le temps pour tout convertir en SDL 2. (il y a 200 lignes de plus)
                Après avoir corrigé la centaine de trucs qui allaient pas, le programme s'est enfin compilé dans erreur sans warning. Je le lance et là, l'écran clignote, ça s'affiche repart se re-affiche puis ouvre une fenêtre console et y affiche le texte suivant :
                "Process exited after 16.96 seconds with return value 3221225477"

                Ça pourrait être quoi ? Ça se trouve c'est ce qui m'a fait buger mon ancien programme en SDL 1.2, mais sans message comme ici...
                • Partager sur Facebook
                • Partager sur Twitter
                  20 février 2017 à 0:25:46

                  Bon, là je me suis finalement pris le temps pour tout convertir en SDL 2. (il y a 200 lignes de plus)

                  Ça me paraît bizarre ça. T’as fait les fonctions qui vont bien, ton code est bien factorisé ?

                  Ça pourrait être quoi ? Ça se trouve c'est ce qui m'a fait buger mon ancien programme en SDL 1.2, mais sans message comme ici...

                  Peut-être un accès à une zone mémoire qui ne t’appartient pas. Compile avec des options de compilation si ce n’est pas déjà le cas. -Wall au minimum, -Wextra aussi et d’autres sont très utiles. Et pour savoir ce qui se passe pendant l’exécution de ton programme, utilise un débogueur.

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
                    20 février 2017 à 1:43:11

                    T’as fait les fonctions qui vont bien, ton code est bien factorisé ?
                    La longueur a surtout augmenté parce que les nombreux :
                    s_truc = SDL_LoadBMP ("truc.bmp") ;
                    pos_truc.x = 0 ;
                    pos_truc.y = 0 ;
                    se sont transformés en :
                    s_truc = SDL_LoadBMP ("truc.bmp") ;
                    pos_truc.x = 0 ;
                    pos_truc.y = 0 ;
                    pos_truc.w = s_truc->w ;
                    pos_truc.h = s_truc->h ;
                    truc = SDL_CreateTextureFromSurface (renderer, s_truc) ;
                    Et d'autres choses...


                    Enfaite le problème est une fonction avec une 20taine d'arguments. Quand je la commente le programme s'arrête plus.
                    Il devrait alors pouvoir tourner sans cette fonction(je verrais plus tard), mais ce qu'il se passe maintenant est que le programme se freeze sans aucun message d'erreur. Du coup j'ai fait un nouveau mini programme de test, qui fait avancer un carré sur l'écran. Et là il bloque quand je le lance la première fois après quelques minutes. Si je le relance juste après cet essais bloquant(même 10 fois de suite), il ne bloque plus, si j'attends un peu et que je le relance il bloque. C'est vraiment bizarre... :/
                    Du coup je vous montre mon nouveau code de ce mini programme de test et une fois ce problème résolut, je me reconcentre sur la fonction...
                    #include <stdlib.h>
                    #include <stdio.h>
                    #include <SDL.h>
                    
                    #define RESX 1366
                    #define RESY 768
                    #define COLBIT 32
                    
                    int main(int argc, char *argv[])
                    {
                    ///////////////////////////////////////// VARIABLES (chargement) :
                        
                        int a=0, i=0, cont=1 ;
                        char key='r' ;
                        Uint32 tp_a, tp_p ;
                        
                        SDL_Event ev ;
                        
                        SDL_Window *ecran = NULL ;
                        
                        SDL_Renderer *renderer = NULL;
                    	
                        SDL_Texture *cube = NULL ;
                        SDL_Surface *s_cube = NULL ; 
                        SDL_Rect pos_cube ;
                        
                    ///////////////////////////////////////// Chargement SDL :
                        
                        SDL_Init (SDL_INIT_VIDEO) ;
                    
                    ///////////////////////////////////////// Ouverture de fenetre :
                        
                        ecran = SDL_CreateWindow("Programme de test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, RESX, RESY, SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN);
                    	
                    ///////////////////////////////////////// Création render :
                        
                        renderer = SDL_CreateRenderer(ecran, -1, SDL_RENDERER_ACCELERATED) ;
                        
                    ///////////////////////////////////////// Chargement Images :
                    	
                        s_cube = SDL_LoadBMP ("cube.bmp") ;
                    
                    ///////////////////////////////////////// Variables de positions :
                    	
                        pos_cube.x = 0 ;
                        pos_cube.y = 0 ;
                        pos_cube.w = s_cube->w ;
                        pos_cube.h = s_cube->h ;
                    
                     ///////////////////////////////////////// Surfaces vers Textures :
                    	
                        cube = SDL_CreateTextureFromSurface (renderer, s_cube) ;
                        
                    ///////////////////////////////////////// Boucle :
                        
                        //SDL_EnableKeyRepeat (10, 10) ;
                        
                        while (cont)
                        {
                              tp_p = SDL_GetTicks () ;
                              while(SDL_PollEvent (&ev)){} ;
                              if (ev.window.type==SDL_KEYDOWN)
                              {
                                   switch (ev.key.keysym.sym)
                                   {
                                          case SDLK_ESCAPE : cont = 0 ; break ;
                                          case SDL_WINDOWEVENT_CLOSE : cont = 0 ; break ; 
                                          case SDLK_RIGHT : key = 'r' ; break ;
                                          case SDLK_LEFT :  key = 'l' ; break ;
                                          case SDLK_UP :    key = 'u' ; break ;
                                          case SDLK_DOWN :  key = 'd' ; break ;
                                          case SDLK_RCTRL :  key = 'c' ; break ;
                                          case SDLK_LCTRL :  key = 'c' ; break ;
                                          case SDLK_LESS :  key = 'c' ; break ;
                                          case SDLK_GREATER :  key = 'c' ; break ;
                                          case SDLK_RSHIFT :  key = 's' ; break ;
                                          case SDLK_LSHIFT :  key = 's' ; break ;
                                   }
                              }
                              
                              
                              
                        if(a==255) a = 0 ; else a = a + 1 ;
                    	pos_cube.x = a ;
                    
                        SDL_SetRenderDrawColor(renderer, 255, a, 255-a, 255) ;
                        SDL_RenderClear(renderer) ;
                        SDL_RenderCopy(renderer, cube, NULL, &pos_cube) ;
                        SDL_RenderPresent (renderer) ;
                              
                    ///////////////////////////////////////// Calculs fin boucle :
                        
                        key = 'a' ;
                              tp_a = SDL_GetTicks () ;
                              SDL_Delay (30 - tp_a + tp_p) ;
                        }
                        
                    ///////////////////////////////////////// Libération mémoire + Fin :
                           
                    	SDL_FreeSurface(s_cube) ;
                        SDL_DestroyTexture (cube) ;
                        SDL_DestroyRenderer(renderer);
                        SDL_DestroyWindow(ecran);
                    
                        SDL_Quit() ;
                     
                        return EXIT_SUCCESS ;
                    }


                    Quand je la commente et que je teste mon programme sans cette fonction

                    -
                    Edité par C++eur 20 février 2017 à 1:43:54

                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 février 2017 à 1:56:17

                      D’où l’importance d’avoir des fonctions qui font le travail. Par exemple, je me fais une structure s_sprite et les fonctions pour les manipuler.

                      struct s_sprite
                      {
                          SDL_Texture *texture;
                          int w;
                          int h;
                      };
                      
                      void destroy_sprite(s_sprite *sprite);
                      s_sprite *create_sprite_from_surface(SDL_Renderer *renderer, SDL_Surface *surface);
                      s_sprite *create_sprite_from_bmp(SDL_Renderer *renderer, char path[]);
                      s_sprite *create_sprite_from_surface_with_color_key(SDL_Renderer *renderer, SDL_Surface *surface, SDL_Color color);
                      s_sprite *create_sprite_from_bmp_with_color_key(SDL_Renderer *renderer, char path[], SDL_Color c);
                      
                      int display_sprite(SDL_Renderer *renderer, s_sprite *sprite, int x, int y);
                      int display_scaled_sprite(SDL_Renderer *renderer, s_sprite *sprite, int x, int y, int scale);
                      int display_sprite_in_background(SDL_Renderer *renderer, s_sprite *sprite);
                      int display_cliped_sprite(SDL_Renderer *renderer, s_sprite *sprite, int x, int y, SDL_Rect *src);
                      int display_scaled_cliped_sprite(SDL_Renderer *renderer, s_sprite *sprite, int x, int y, SDL_Rect *src, int scale);
                      int display_cliped_sprite_in_background(SDL_Renderer *renderer, s_sprite *sprite, SDL_Rect *src);
                      extern SDL_Surface *load_surface(const char path[]);
                      

                      Comme ça, tout ça est écrit une fois pour toute avec les vérifications de chargement et tout le reste.

                      Je regarde ton programme de test plus tard.

                      EDIT :

                      Et donc, avec des fonctions, on peut faire un programme du genre qui peut encore être amélioré.

                      int main(int argc, char *argv[])
                      {
                          if(SDL_Init(SDL_INIT_VIDEO) < 0)
                              fprintf(stderr, "Erreur SDL_Init : %s.", SDL_GetError());
                          else
                          {
                              SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
                                                                    RESX, RESY, SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN);
                              if(!window)
                                  fprintf(stderr, "Erreur SDL_CreateWindow : %s.", SDL_GetError());
                              else
                              {
                                  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
                                  if(!renderer)
                                      fprintf(stderr, "Erreur SDL_CreateWindow : %s.", SDL_GetError());
                                  else
                                  {
                                      struct Sprite *cube = create_sprite_from_bmp(renderer, "cube.bmp");
                                      if(cube)
                                          run(renderer, cube);
                                  }
                              }
                          }
                      }
                      
                      void run(SDL_Renderer *renderer, struct Sprite *cube)
                      {
                          int x_cube = 0, y_cube = 0;
                          unsigned int a = 0;
                          struct Input in = {SDL_FALSE, {SDL_FALSE}};
                          while(!in.quit && !in.key[SDL_SCANCODE_ESCAPE])
                          {
                              update_event(&in);
                              if(in.key[SDL_SCANCODE_UP])
                                  y_cube--;
                              else if(in.key[SDL_SCANCODE_DOWN])
                                  y_cube++;
                              if(in.key[SDL_SCANCODE_LEFT])
                                  x_cube--;
                              else if(in.key[SDL_SCANCODE_RIGHT])
                                  x_cube++;
                              a++;
                              if(a > 255)
                                  a = 0;
                              SDL_SetRenderDrawColor(renderer, 255, a, 255-a, 255) ;
                              SDL_RenderClear(renderer);
                              display_sprite(renderer, cube, x_cube, y_cube);
                              SDL_RenderPresent(renderer);
                              SDL_Delay(20);
                          }
                      }
                      

                      Et les fonctions et structures autour.

                      struct Input
                      {
                          SDL_bool key[SDL_NUM_SCANCODES];
                          SDL_bool quit;
                      };
                      
                      void update_event(struct Input *input);
                      
                      
                      struct Sprite
                      {
                          SDL_Texture *texture;
                          int w;
                          int h;
                      };
                      
                      void destroy_sprite(struct Sprite *sprite);
                      struct Sprite *create_sprite_from_surface(SDL_Renderer *renderer, SDL_Surface *surface);
                      struct Sprite *create_sprite_from_bmp(SDL_Renderer *renderer, char path[]);
                      int display_sprite(SDL_Renderer *renderer, struct Sprite *sprite, int x, int y);
                      
                      
                      SDL_Surface *load_surface(const char path[]);
                      
                      SDL_Surface *load_surface(const char path[])
                      {
                          SDL_Surface *tmp = SDL_LoadBMP(path);
                          if(NULL == tmp)
                              fprintf(stderr, "Erreur SDL_LoadBMP : %s", SDL_GetError());
                          return tmp;
                      }
                      
                      struct Sprite *create_sprite_from_surface(SDL_Renderer *renderer, SDL_Surface *surface)
                      {
                          struct Sprite *sprite = malloc(sizeof(*sprite));
                          if(NULL == sprite)
                          {
                              perror("Error creating sprite : ");
                              return NULL;
                          }
                          sprite->texture = SDL_CreateTextureFromSurface(renderer, surface);
                          if(NULL == sprite->texture)
                          {
                              fprintf(stderr, "Error creating sprite : %s.", SDL_GetError());
                              return NULL;
                          }
                          sprite->w = surface->w;
                          sprite->h = surface->h;
                          return sprite;
                      }
                      
                      struct Sprite *create_sprite_from_bmp(SDL_Renderer *renderer, char path[])
                      {
                          SDL_Surface *tmp = load_surface(path);
                          if(NULL == tmp)
                              return NULL;
                          return create_sprite_from_surface(renderer, tmp);
                      }
                      
                      int display_sprite(SDL_Renderer *renderer, struct Sprite *sprite, int x, int y)
                      {
                          SDL_Rect dst = {x, y, sprite->w, sprite->h};
                          return SDL_RenderCopy(renderer, sprite->texture, NULL, &dst);
                      }
                      
                      void destroy_sprite(struct Sprite *sprite)
                      {
                          if(sprite)
                          {
                              if(sprite->texture)
                                  SDL_DestroyTexture(sprite->texture);
                              free(sprite);
                          }
                      }
                      
                      void update_event(struct Input *input)
                      {
                          SDL_Event event;
                          while(SDL_PollEvent(&event))
                          {
                              if(event.type == SDL_QUIT)
                                  input->quit = SDL_TRUE;
                              else if(event.type == SDL_KEYDOWN)
                                  input->key[event.key.keysym.scancode] = SDL_TRUE;
                              else if(event.type == SDL_KEYUP)
                                  input->key[event.key.keysym.scancode] = SDL_FALSE;
                          }
                      }
                      

                      Dans un exemple aussi court, les fonctions rendent le code plus lourd et tout, mais sur de plus gros codes et à long-terme c’est une grande aide.

                      -
                      Edité par yo@n97one 20 février 2017 à 2:52:28

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs

                      Programme en C avec SDL et DevC++ qui plante !

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown