简体   繁体   中英

No response from SDL poll event in C

I am trying to learn SDL in C. The tutorial I found online is http://lazyfoo.net/tutorials/SDL/03_event_driven_programming/index.php . I'm running Ubuntu in VMware.

I downloaded the sample code(.cpp files) from the tutorial website. The C++ files worked perfectly. However, if I change the C++ to C files with a bit modification, the program can no longer detect any events. (This is a school project that requires to program in C).

The main function including the initialization of SDL_event:

int main( int argc, char* args[] )
{
    //Start up SDL and create window
    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {
        //Load media
        if( !loadMedia() )
        {
            printf( "Failed to load media!\n" );
        }
        else
        {           
            //Main loop flag
            bool quit = false;

            //Event handler
            SDL_Event e;

            //While application is running

            //This is the loop that the program got stuck on:
            while( !quit )
            {
                //Handle events on queue
                while( SDL_PollEvent( &e ) )
                {
                    //The program never comes here
                    //User requests quit
                    if( e.type == SDL_QUIT )
                    {
                        quit = true;
                    }
                }

                //Apply the image
                SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );

                //Update the surface
                SDL_UpdateWindowSurface( gWindow );
            }
        }
    }
    //Free resources and close SDL
    close();

    return 0;
}

The program is supposed to look for a user input of closing the window. The SDL_PollEvent was always 0, though I did click the 'X' in the window. And the program did not respond any more after the first click. The CPU usage was quite high before I killed the program. This does not only happen to closing the window, any actions that require SDL_PollEvent will result in the program non-response.

The command I used to compile is:

gcc -o test test.c `sdl2-config --cflags --libs`

Since c++ worked fine, I'm wondering if I missed any changes in C which made SDL_PollEvent not working? or the command line I used to compile was not correct? I have googled for several hours but still could not find the answer. I will be much appreciated it if someone can save me. Thank you!

Your problem most likely lies in the fact that you check boolean conditions via while( quit == false ) and while (SDL_PollEvent( &e ) == true) . This does not work properly, because you compare to a single value, while what you actually want is to test for 0 / non-0.

Prefer writing things like:

while ( SDL_PollEvent( &e ) )
{
   ...
}

and

while (!quit)
{
   ...
}

This erroneous check is probably what broke your code.

The values true and false should only be used for initialisation of boolean variables, not for checking.

First of all, you're using a really outdated version of SDL. SDL 2.0 doesn't really use SDL_Surface; it uses SDL_Texture. SDL 2 is miles ahead of 1.2, so start using that.

The key thing here is that you actually make an extra SDL_PollEvent call when you do the printf statement. If you simply remove it, you probably will solve your problem.

If you poll for an event, and that event happens to be the quit event, of course, when you receive it first, it won't get handled. This is because SDL will probably receive it in the first SDL_PollEvent call, and not the second and so on. Remove the printf statement; if you really need it, put it in the second while loop.

Here is some example code for SDL 2 (a small part of it is in C++):

while(!done) {
    while(SDL_PollEvent(&e)) {
      if(e.type == SDL_QUIT) {
        done = true;
      }

      const Uint8* keystates = SDL_GetKeyboardState(NULL);
      if (keystates[SDL_SCANCODE_UP]) {
        speedy -= 2;
      } else if (keystates[SDL_SCANCODE_DOWN]) {
        speedy += 2;
      } else if (keystates[SDL_SCANCODE_LEFT]) {
        speedx -= 2;
      } else if (keystates[SDL_SCANCODE_RIGHT]) {
        speedx += 2;
      }
    }
    SDL_RenderClear(base_system.get_renderer());
    SDL_RenderCopy(base_system.get_renderer(), tp.get("bg.png"), nullptr, nullptr);
    SDL_RenderCopy(base_system.get_renderer(), tp.get("square.png"), nullptr, &rekt);
    SDL_RenderPresent(base_system.get_renderer());
}

Note that you should be using SDL_Renderer in SDL 2 as well. Here is a related link: What is a SDL renderer?

I also encountered this problem. The solution is to rename the exit() function to another name. For example: exitWin() . Maybe we blocked another function with ours. I hope it will work.

Your code example does not show the SDL_Init() code section. Please double check it is run correctly and has all required flags set. See https://wiki.libsdl.org/SDL_Init for the possible flags. Note that if you modified it and removed the SDL_INIT_VIDEO flag because you don't wanted video you will need SDL_INIT_EVENTS for the event system to work.

The syntax looks right to me from what I can tell, so:

  1. check where exactly in your code it is messing up (using printf() at different spots) to make sure you know that the issue isn't something else
  2. double check your init() function, make sure you are setting up correctly
  3. If this doesn't help, then try creating a separate program with only the event checking. If that works, add each of the other pieces to it until it stops working, and you will probably find the issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM