2
votes

I am beginning SDL programming in C. This simple program loops through rainbow colors and fills the window with them. (This is on Debian with Gnome if that helps.)

For some reason the program never registers the quit signal if I click to close the window. How can I fix the loop structure so that the program exits properly?

#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main(void)
{
  SDL_Window *window;
  SDL_Renderer *renderer;
  SDL_Event event;
  bool quit = false;
  int i;
  int rgb_rainbow[6][3] = { {255, 0, 0},
                            {255, 127, 0},
                            {255, 255, 0},
                            {0, 255, 0},
                            {0, 0, 255},
                            {75, 0, 130} };

  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                 "Couldn't initialize SDL: %s", SDL_GetError());
    return(3);
  }
  if (SDL_CreateWindowAndRenderer(640,640,
                                  SDL_WINDOW_RESIZABLE, &window, &renderer)) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                 "Couldn't create window and renderer: %s", SDL_GetError());
    return(3);
  }

  while (quit == false) {
    for (i = 0; i < 6; ++i ) {
      SDL_PollEvent(&event);
      if (event.type == SDL_QUIT) {
        quit = true;
        break;
      }
      SDL_SetRenderDrawColor(renderer,
                             rgb_rainbow[i][0],
                             rgb_rainbow[i][1],
                             rgb_rainbow[i][2], 255);
      SDL_RenderClear(renderer);
      SDL_RenderPresent(renderer);
      SDL_Delay(500);
    }
  }

  SDL_DestroyRenderer(renderer);
  SDL_DestroyWindow(window);

  SDL_Quit();

  return(0);
}
1

1 Answers

3
votes

Window closing event is SDL_WINDOWEVENT with window.event set to SDL_WINDOWEVENT_CLOSE. You also getting only one event fron queue, and not even checking if queue had one. Check this out:

  while (quit == false) {
    for (i = 0; i < 6; ++i ) {
      while(SDL_PollEvent(&event)) {
          if (event.type == SDL_QUIT ||
                  (event.type == SDL_WINDOWEVENT &&
                   event.window.event == SDL_WINDOWEVENT_CLOSE)) {
            quit = true;
          }
      }
      if(quit) { break; }

      SDL_SetRenderDrawColor(renderer,
                             rgb_rainbow[i][0],
                             rgb_rainbow[i][1],
                             rgb_rainbow[i][2], 255);
      SDL_RenderClear(renderer);
      SDL_RenderPresent(renderer);
      SDL_Delay(500);
    }
  }

It is generally good practice to have your main loop render just one frame, not 6 (or any other number).