student96
student96

Reputation: 345

keypress using in SDL2 correctly?

I tried to move a rectangle in a window by using keys from keyboard, but I get a Failreport with after start/compile my program.

  keystate=NULL;
if (keystate[SDLK_LEFT] ) 
{
  rect2.x -= 2;
}
if (keystate[SDLK_RIGHT] ) 
{
  rect2.x += 2;
}
if (keystate[SDLK_DOWN] ) 
{
  rect2.y += 2;
}
if (keystate[SDLK_UP] ) 
{
  rect2.y -= 2;
}

This is the code that not works. At the beginning of main() I put this line:

Uint8 *keystate; I use the lib SDL.h in C to do this.

The failmessage contains:

Program Received signal SIGSEGV Stack trace is available in the 'Call Stack' tab PS: After I think it is better to post the whole code . It is slightly modified :

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


int main()
{
  //Request successful execute
  if(SDL_Init(SDL_INIT_EVERYTHING)!=0)
  {
    printf("fehler");
    return 1;
  }

  //create window 800x600
  SDL_Window *win;
  win = SDL_CreateWindow("test",100,100,800,600,SDL_WINDOW_SHOWN);

  //create renderwindow with vysnc enabled
  SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

  if(ren==NULL)
  {
    printf("Fehler");
    SDL_Quit();
    return 1;
  }

  Uint8 *keystate=SDL_GetKeyboardState(NULL);
  //boolean data type not supported
  int gameRunning = 1;

 SDL_Event event;

//create rectangle which is the whole window
 SDL_Rect rect={
    0,0,800,600
  };
  //smaller rectangle 
  SDL_Rect rect2={
    0,0,50,50
  };

//while loop to hold the window opened
  while (gameRunning)
  {
    if (SDL_PollEvent(&event))//close the window 
    {
      if (event.type == SDL_QUIT)
      {
          gameRunning = 0;
      }
    }
    //color of the first rectangle(red)
    SDL_SetRenderDrawColor(ren, 255,0,0,255);
    SDL_RenderClear(ren);
    SDL_RenderFillRect( ren, &rect );

    //second rectangle (blue)
    SDL_SetRenderDrawColor(ren, 0,0,255,255);
    SDL_RenderFillRect( ren, &rect2 );
    //change/update the render
    SDL_RenderPresent(ren);

    //rect2.x+=5.f;

   if (keystate[SDLK_LEFT] ) 
    {
      rect2.x -= 2;
    }
    if (keystate[SDLK_RIGHT] ) 
    {
      rect2.x += 2;
    }
    if (keystate[SDLK_DOWN] ) 
    {
      rect2.y += 2;
    }
    if (keystate[SDLK_UP] ) 
    {
      rect2.y -= 2;
    }

  }
  //give heap free
  SDL_DestroyRenderer(ren);
  SDL_DestroyWindow(win);
  SDL_Quit();
    return 0;
}

Upvotes: 2

Views: 2858

Answers (1)

rsethc
rsethc

Reputation: 2664

These are macros. You are offsetting a pointer to NULL by a macro value, and then trying to dereference it. That's the cause of the segmentation fault (SIGSEGV).

Uint8* keys = SDL_GetKeyboardState(NULL); // NOT "keys = NULL;"
if (keys[SDLK_LEFT]) rect2.x -= 2;
if (keys[SDLK_RIGHT]) rect2.x += 2;
if (keys[SDLK_DOWN]) rect2.y += 2;
if (keys[SDLK_UP]) rect2.y -= 2;

Keep in mind that this is an internal array. You are not supposed to free it! This is a common mistake... "I am getting a copy of the list from the library, so I better delete it later to avoid memory leaks." But actually this is not allocated by SDL_GetKeyboardState, rather the function just gives you a pointer to the internal storage of the key states. So check the rest of your program and if you were freeing this, stop it because that also will contribute to an application crash.


EDIT Alright, so here's the TRUE problem!

You're offsetting the address keys by SDLK_LEFT. The SDLK_... macros are not intended to be used for this purpose! Instead, offset by SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, and SDL_SCANCODE_DOWN.

Since the SDLK_... macros aren't intended for this purpose, they are different values. Probably the reason you are getting a segmentation fault is that these are defined to large values that extend far beyond the length of the array keys.

Upvotes: 1

Related Questions