I am completely stumped as to why this code does not get any SDL keypress events. The other SDL events (removed for clarity) work fine. It does not work on my XP or Vista machines. No compile/link errors, just never recieve a keydown event.
#include "SDL/SDL.h"
// Yes SDL.lib and SDLmain.lib are linked
Uint32 TimeLeft(void)
{
static Uint32 next_time = 0;
Uint32 now;
now = SDL_GetTicks();
if ( next_time <= now ) {
next_time = now + tickInterval;
return 0;
}
return(next_time-now);
}
int main( int argc, char **argv )
{
if( -1 == SDL_Init( SDL_INIT_EVERYTHING ) )
{
cerr << "Error: SDL_Init failed" << endl;
return -1;
}
SDL_Event event;
bool quit = false;
while( !quit )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
case SDLK_q:
quit = true;
break;
default:
break;
}
break;
case SDL_JOYAXISMOTION:
// stuff removed
break;
case SDL_QUIT:
quit = true;
break;
default:
break;
}
}
SDL_Delay( TimeLeft() );
}
SDL_Quit();
return 0;
}
You'll need to create a window with SDL_SetVideoMode to get mouse and keyboard events.
I don't think you'll have luck trying to SDL_WM_GrabInput the mouse and keyboard without a window. It may also raise security alerts the first time on moderm Windows machines.
Related
My program generates an image. I want to close the window by clicking on any key or by clicking with my pointer on the window cross.
It works only by clicking on the cross (Use of SDL_QUIT) but not with SDL_KEYDOWN. I tried also with SDL_SPACE, SDL_KEYUP but the result is the same.
So what am I missing in my code ?
I am using xcode.
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *imageDeFond = NULL, *zozor = NULL;
SDL_Rect positionFond, positionZozor;
SDL_Event event;
int continuer = 1;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
imageDeFond = SDL_LoadBMP("lac_en_montagne.bmp");
SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
SDL_Flip(ecran);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_KEYDOWN:
{
printf("use of SDL_KEYDOWN");
continuer=0;
break;
}
case SDL_QUIT:
{
printf("use of SDL_QUIT");
continuer = 0;
break;
}
}
}
SDL_FreeSurface(imageDeFond);
SDL_Quit();
return EXIT_SUCCESS;
}
What is e in
SDL_Event e;
How to pass e from one function to another function then to another function.
is it possible?
Basically is e bool or int
bool x_out_window()
{
bool quit = false;
SDL_Event e;
while( !quit )
{
while( SDL_PollEvent( &e ) != 0 )
{
if( e.type == SDL_QUIT )
quit = true;
else
detect_key_press(e.type);
}
}
}
bool detect_key_press(e.type)
{
//SDL_Event e;
if( e.type == SDL_KEYDOWN )
{
//Select surfaces based on key press
switch( e.key.keysym.sym )
{
case SDLK_UP:
gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_UP ];
break;
case SDLK_DOWN:
gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_DOWN ];
break;
case SDLK_LEFT:
gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_LEFT ];
break;
case SDLK_RIGHT:
gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_RIGHT ];
break;
default:
gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_DEFAULT ];
break;
}
SDL_BlitSurface( gXOut, NULL, gScreenSurface, NULL );
SDL_UpdateWindowSurface( gWindow );
}
}
I am sorry if this is a silly question but i am unable to understand the concept, i am novice in coding.
Just declare your function 2 as
void funtion2(SDL_Event e){
//...
}
in C++ you need to provide a type for both the function (probably void here) and all the parameters (a SDL_Event named e here)
whenever I press a key nothing happens, there are no errors either, rather odd this is.
Here is the init function:
bool Game::init(int resx, int resy, bool fullscreen)
{
tm = new TextureManager();
int flags = 0;
if(fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}
if(SDL_Init(SDL_INIT_EVERYTHING) >= 0)
{
g_pWindow = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, resx, resy, flags);
if(g_pWindow != 0)
{
g_pRenderer = SDL_CreateRenderer(g_pWindow, -1, 0);
if(g_pRenderer != 0)
{
running = true;
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/bg.png", "bg", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/paddle.png", "player1", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/paddle.png", "player2", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/ball.png", "ball", g_pRenderer);
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
return false;
}
Here is my event handler:
void Game::handleEvents()
{
SDL_Event event;
switch (SDL_PollEvent(&event)) {
case SDL_KEYDOWN:
p1MoveUp = true;
break;
case SDL_KEYUP:
p1MoveUp = false;
break;
default:
break;
}
}
Here is my update function:
void Game::update()
{
if (p1MoveUp)
{
std::cout << "asfasfasf" << std::endl; //for debug purposes :)
p1YPos -= 5;
}
}
and last but not least, here is main.cpp (excluding includes...)
Game *g_game = 0;
int main(int argc, const char * argv[])
{
g_game = new Game();
g_game->init(800, 600, false);
while(g_game->isRunning())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
SDL_Quit();
return 0;
}
You are using the SDL_PollEvent incorrectly. The function does not return the type of event, but rather 1 if there are still items in the event queue, or 0 if the queue is empty.
So you'd want to poll events as long as there are things in the queue and THEN do a switch over the event.type as such:
void Game::handleEvents()
{
SDL_Event event;
// Poll events until the queue is empty...
while(SDL_PollEvent(&event)) {
// ...then check the event.
switch (event.type) {
case SDL_KEYDOWN:
p1MoveUp = true;
break;
case SDL_KEYUP:
p1MoveUp = false;
break;
default:
break;
}
}
}
EDIT: Note that currently ALL key down and up events of each key on the keyboard would cause the p1MoveUp flag to switch. Within your SDL_KEYDOWN and SDL_KEYUP you normally would also check which key has been pressed and act accordingly. You can do this like this:
if(event.key.keysym.sym == SDLK_UP) ...
This would check if the keycode for the "Up Cursor" has been pressed or not. There is a difference between a key scancode and a keycode, for which I would advise you to check the latter as shown above. You can find all these SDL defined keycodes here (look at the rightmost column): https://wiki.libsdl.org/SDL_Keycode
Please note that the event handler can grow quite rapidly if you are checking for different keys and different key events, so I'd suggest that you implement an extra class or other means of encapsulation once you are comfortable with the event mechanism of SDL.
SDL_PollEvent returns true or false. https://wiki.libsdl.org/SDL_PollEvent
If SDL_PollEvent returns true, then 'event' is set. Then do your switch on event.type instead.
I am trying to catch the event for F1 key in SDL in C++.
But,somehow i cannot see any changes after pressing the F1 key.But,when i wnat to toggle my animation objects on the screen i make use SDL_t case to do so,and it is executing fine.
Just not geting why is it not taking the F1 key.
Here is the switch case for handling key press events:
SDL_Event event;
bool done = false;
bool keyPress = false;
while ( not done ) {
draw();
SDL_Flip(screen);
SDL_PollEvent(&event);
if (event.type == SDL_QUIT) { break; }
if(event.type == SDL_KEYUP) { keyCatch = false; }
if(event.type == SDL_KEYDOWN) {
switch ( event.key.keysym.sym ) {
case SDLK_ESCAPE : done = true; break;
case SDLK_q : done = true; break;
case SDLK_F1 : {
if(!keyCatch){
keyPress=true;
//this method is from another class.
io.printMessageAt("F1 is selected:",50,10);
currentOrb = (currentOrb+1) % orbs.size();
}
break;
}
case SDLK_t : case SDLK_SPACE :
if ( !keyPress ) {
//something
}
break;
case SDLK_p : {
if (!keyPress) {
keyPress = true;
//something
}
break;
}
default : break;
}
}
}
NOTE: i cannot give the entire code here.The above is my part what i am trying to do.
Double-check that your window manager or a hotkey daemon isn't consuming your F1's before they hit your process.
This works fine (F1 closes the program) on my system:
#include <SDL.h>
int main( int, char** )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_ANYFORMAT);
SDL_Event event;
bool done = false;
bool keyPress = false;
while ( !done )
{
SDL_Flip(screen);
SDL_PollEvent(&event);
if(event.type == SDL_QUIT)
{
break;
}
if(event.type == SDL_KEYUP)
{
keyPress = false;
}
if(event.type == SDL_KEYDOWN)
{
switch ( event.key.keysym.sym )
{
case SDLK_ESCAPE:
case SDLK_q:
done = true;
break;
case SDLK_F1:
if(!keyPress)
{
keyPress=true;
done = true;
}
break;
case SDLK_t:
case SDLK_SPACE:
if ( !keyPress )
{
//something
}
break;
case SDLK_p:
if (!keyPress)
{
keyPress = true;
//something
}
break;
default:
break;
}
}
}
SDL_Quit();
return 0;
}
I did notice that keyCatch was undefined. I replaced it with keyPress.
int main( int argc, char* args[] )
{
if( SDL_Init(SDL_INIT_EVERYTHING) < 0 )
std::cout<<"unable to init sdl";
SDL_Surface *screen = SDL_SetVideoMode(800,600,32,SDL_DOUBLEBUF);
std::cout<<"before while\n";
SDL_Event event;
while(SDL_PollEvent(&event))
{
std::cout<<"in while\n";
if(event.type == SDL_QUIT)
std::cout<<"SDL_QUIT\n";
}
std::cout<<"after while\n";
SDL_Quit();
}
For some unknown reason this SDL app quits after running in the while loop 4 times without me killing/closing/etc it and without printing "SDL_QUIT" to stdout.
Is there a reason for this? How do I fix it?
You need to keep your application alive by creating a main loop for it. As of now, your application just quits after you poll all the initial events:
int main( int argc, char* args[] )
{
if( SDL_Init(SDL_INIT_EVERYTHING) < 0 )
std::cout<<"unable to init sdl";
SDL_Surface *screen = SDL_SetVideoMode(800,600,32,SDL_DOUBLEBUF);
SDL_Event event;
bool active = true;
while(active)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
std::cout<<"SDL_QUIT\n";
active = false;
}
}
// TODO: add drawing to screen
SDL_Flip(screen);
}
SDL_Quit();
}
SDL_PollEvent will return false when there are no more events to handle, which is right after application startup in this case.
You need to nest the poll loop inside another loop that keeps the application alive:
int running = 1;
while (running)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
running = 0;
}
// Update and draw here usually
}