#include "SDL/SDL_ttf.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL.h"
#include <string>
// screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP =32;
// surfaces
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *message = NULL;
SDL_Surface *up = NULL;
SDL_Surface *down = NULL;
SDL_Surface *left = NULL;
SDL_Surface *right = NULL;
// event handler
SDL_Event event;
// the fonts & font color
TTF_Font *font = NULL;
SDL_Color textColor = {255, 255, 255};
// func decs
bool loadFiles();
bool init();
void clean_up();
SDL_Surface *loadImage(std::string);
void applySurface( int, int, SDL_Surface*, SDL_Surface*, SDL_Rect*);
bool init()
{
// init SDL
if (SDL_Init( SDL_INIT_EVERYTHING) == -1)
return false;
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
SCREEN_BPP, SDL_SWSURFACE);
if (screen == NULL)
return false;
// init ttf
if (TTF_Init() == -1)
return false;
SDL_WM_SetCaption( "Keypress Testing", NULL);
return true;
}
bool loadFiles()
{
background = loadImage( "background.png" );
font = TTF_OpenFont( "lazy.ttf", 72 );
if (background == NULL)
return false;
if (font == NULL)
return false;
// Everything loaded fine
return true;
}
// Free's the surfaces, fonts, and exits SDL
void clean_up()
{
SDL_FreeSurface( background );
SDL_FreeSurface( message );
SDL_FreeSurface( up );
SDL_FreeSurface( down );
SDL_FreeSurface( left );
SDL_FreeSurface( right );
TTF_CloseFont( font );
TTF_Quit();
SDL_Quit();
}
// load a image into memory as a surface
SDL_Surface *loadImage(std::string filename)
{
// temp image
SDL_Surface* loadedImage = NULL;
// optimized image
SDL_Surface* optimizedImage = NULL;
// load the image
loadedImage = IMG_Load( filename.c_str() );
if (loadedImage != NULL)
{
// optimize image and free old image
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if (optimizedImage != NULL)
{ // Color key the surface
SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY,
SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}
return optimizedImage;
}
// Blit a surface from source to the destination at x,y
void applySurface( int x, int y, SDL_Surface* source,
SDL_Surface* destination,
SDL_Rect* clip = NULL)
{
// temp rec to hold offsets
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
int main( int argc, char* args[] )
{
bool quit = false;
// Initialize SDL and load the files
if ( init() == false )
return 1;
if ( loadFiles() == false )
return 1;
// Create the messages
up = TTF_RenderText_Solid(font, "Up was pressed", textColor);
down = TTF_RenderText_Solid(font, "Down was pressed", textColor);
left = TTF_RenderText_Solid(font, "Left was pressed", textColor);
right = TTF_RenderText_Solid(font, "Right was pressed", textColor);
applySurface(0, 0, background, screen);
while (!quit)
{
if ( SDL_PollEvent( &event ) )
{
if( event.type == SDL_KEYDOWN )
{
// set the text
switch( event.key.keysym.sym )
{
case SDLK_UP: message = up; break;
case SDLK_DOWN: message = down; break;
case SDLK_LEFT: message = left; break;
case SDLK_RIGHT: message = right; break;
}
}
else if( event.type == SDL_QUIT )
quit = true;
}
// Message to the screen
if ( message != NULL )
{
applySurface(0, 0, background, screen);
applySurface( (SCREEN_WIDTH - message->w) / 2,
(SCREEN_HEIGHT - message->h) / 2,
message, screen );
message = NULL;
}
// Update the screen
if ( SDL_Flip( screen ) == -1 )
return 1;
}
// Clean and exit
clean_up();
return 0;
}
SDL and key press events
So I'm working my way through the SDL tutorials written by lazy foo productions as suggested by the faq. I'm on the 8th lesson and I'm not quite sure why but the window loads fine, however nothing happens when I actually press an arrow key. When it's run, it doesn't respond at all (doesn't seem to even make it to the switch statement?). Downloading lazy foo's original code behaves in the same way. Any help?
I compile it by:
g++ -o lesson8 main.cpp -lSDL -lSDL_image -lSDL_ttf
Here's my version of the source code:
I'm not awake enough to look at it in depth but just real quick what is keeping it from clearing the message instantly? At first glance it looks like a message is displayed only when message != NULL. But then message is instantly set back to NULL which would happen way to fast to really see.
SDL only tracks Changes so if you press the key it will only set the message ONE time then get reset by the desplay function. So you cant hold the key down but would have to press it reeeeeeeeeeeeeally fast to see anything.
I'm thinking you shouldn't reset the message var until you get SDL_KEYUP or RELEASED(whichever it is)
SDL only tracks Changes so if you press the key it will only set the message ONE time then get reset by the desplay function. So you cant hold the key down but would have to press it reeeeeeeeeeeeeally fast to see anything.
I'm thinking you shouldn't reset the message var until you get SDL_KEYUP or RELEASED(whichever it is)
Goober King seems to be correct. You should keep that message != NULL for a longer time to see anything, or you'll end up with a single frame and, since your program is very simple, your framerate may be high enough for you to see anything on a single frame alone.
I second his advice on keeping that message until you get a SDL_KEYUP event.
I second his advice on keeping that message until you get a SDL_KEYUP event.
Well I took your advice but the problem seems to be that the message isn't being set to whatever key is pressed, it just stays null. I did make the changes to wait for a keyup event to make message = null. Out of curiousity I tried putting one of the messages on the screen as soon as main gets going. When I run it with:
applySurface( (SCREEN_WIDTH - up->w) / 2,(SCREEN_HEIGHT - up->h) / 2,up, screen );
I get a segmentation fault, so I'm still confused. What would cause it to do that? Here's the new main method:
*********************** EDIT *************************
So I tried this all out on my spare WinXP partition using VC++ and it worked like a charm, so the code isn't at fault from what I can tell. Thanks for the help on that other problem I thought I had.
[Edited by - raeb on June 6, 2007 2:48:47 PM]
applySurface( (SCREEN_WIDTH - up->w) / 2,(SCREEN_HEIGHT - up->h) / 2,up, screen );
I get a segmentation fault, so I'm still confused. What would cause it to do that? Here's the new main method:
int main( int argc, char* args[] ){ bool quit = false; // Initialize SDL and load the files if ( init() == false ) return 1; if ( loadFiles() == false ) return 1; // Create the messages up = TTF_RenderText_Solid(font, "Up was pressed", textColor); down = TTF_RenderText_Solid(font, "Down was pressed", textColor); left = TTF_RenderText_Solid(font, "Left was pressed", textColor); right = TTF_RenderText_Solid(font, "Right was pressed", textColor); // Put the background on so it isn't just black. applySurface(0, 0, background, screen); // This next line causes segmentation fault //applySurface( (SCREEN_WIDTH - up->w) / 2, // (SCREEN_HEIGHT - up->h) / 2, // up, screen ); while (!quit) { if ( SDL_PollEvent( &event ) ) { if( event.type == SDL_KEYDOWN ) { switch( event.key.keysym.sym ) { case SDLK_UP: message = up; break; case SDLK_DOWN: message = down; break; case SDLK_LEFT: message = left; break; case SDLK_RIGHT: message = right; break; } } else if( event.type == SDL_KEYUP ) message = NULL; else if( event.type == SDL_QUIT ) quit = true; } // Draw the screen if ( message != NULL ) { applySurface(0, 0, background, screen); applySurface( (SCREEN_WIDTH - message->w) / 2, (SCREEN_HEIGHT - message->h) / 2, message, screen ); } if ( SDL_Flip( screen ) == -1 ) return 1; } // Clean and exit clean_up(); return 0;}
*********************** EDIT *************************
So I tried this all out on my spare WinXP partition using VC++ and it worked like a charm, so the code isn't at fault from what I can tell. Thanks for the help on that other problem I thought I had.
[Edited by - raeb on June 6, 2007 2:48:47 PM]
Quote:Original post by raeb
Well I took your advice but the problem seems to be that the message isn't being set to whatever key is pressed, it just stays null. I did make the changes to wait for a keyup event to make message = null. Out of curiousity I tried putting one of the messages on the screen as soon as main gets going. When I run it with:
applySurface( (SCREEN_WIDTH - up->w) / 2,(SCREEN_HEIGHT - up->h) / 2,up, screen );
I get a segmentation fault, so I'm still confused. What would cause it to do that? Here's the new main method:
*** Source Snippet Removed ***
*********************** EDIT *************************
So I tried this all out on my spare WinXP partition using VC++ and it worked like a charm, so the code isn't at fault from what I can tell. Thanks for the help on that other problem I thought I had.
Just because it works under one circumstance doen't mean the code is right. It is kinda fishy. What were you building under before?
**edit
BTW were you using SDL_Delay(X) function anyware to keep the message up without checking for the key up event? The lazy foo snippit I'm looking at does. If you plan on using SDL as input you need to know about that gotcha. They even talk about it in the Doc files which are really easy to use btw.
Works under WinXP using Visual Studio 2k5 standard ed.
It doesn't work using ubuntu (fiesty fawn). I have the libsdl-devel packages installed for the extentions. I'm compiling with g++ -o lesson main.cpp -lSDL -lSDL_image -lSDL_ttf. I'm not seeing any sdl delay function at the tutorials I'm following: http://lazyfoo.net/SDL_tutorials/lesson08/index.php What docs are you looking at as well? (for my reference, I'd appreciate it :)
It doesn't work using ubuntu (fiesty fawn). I have the libsdl-devel packages installed for the extentions. I'm compiling with g++ -o lesson main.cpp -lSDL -lSDL_image -lSDL_ttf. I'm not seeing any sdl delay function at the tutorials I'm following: http://lazyfoo.net/SDL_tutorials/lesson08/index.php What docs are you looking at as well? (for my reference, I'd appreciate it :)
Quote:Original post by raeb
Works under WinXP using Visual Studio 2k5 standard ed.
It doesn't work using ubuntu (fiesty fawn). I have the libsdl-devel packages installed for the extentions. I'm compiling with g++ -o lesson main.cpp -lSDL -lSDL_image -lSDL_ttf. I'm not seeing any sdl delay function at the tutorials I'm following: http://lazyfoo.net/SDL_tutorials/lesson08/index.php What docs are you looking at as well? (for my reference, I'd appreciate it :)
I think it was this one.
Quote:
//Wait 2 seconds SDL_Delay( 2000 );
We call SDL_Delay() so that the window doesn't just flash on the screen for a split second. SDL_Delay() accepts time in milliseconds, or 1/1000 of a second.
So the window will stay up for 2000/1000 of a second or 2 seconds.
It's near the end. As you can see it mentions the issue.
One think you may want to try is using Dev-Cpp which uses the windows version of gcc. Which makes a lot of sence if you are going to cross compile. I use it and have an OpenGL/SDL game that compiles under windows and linux with zero code changes. Anyway, not all compilers are created equal and not all enforce the standards in the same way or to the same extent.
You aren't checking the value returned by SDL_RenderText_Solid()[1]. I'm willing to bet it's the cause of all your problem, because you're attempting to render whitespaces, and that will trigger a bug in Freetype[2]. Replacing it with SDL_RenderText_Blended() will do the trick, but it'll be blended, not solid.
Is LazyFoo testing his tutorials on non-Microsoft systems at all? I'm asking because this is a common bug on recent X11 systems, and because of the unportable way the SDL header files are included. This isn't a criticism of his tutorials, BTW, just an honest question.
Hope this helps.
1. Just doing so and printing the output of SDL_GetError() in case of failure lead to this error message: "Failed loading DPMSDisable: /usr/lib/libX11.so.6: undefined symbol: DPMSDisable".
2. http://lists.libsdl.org/pipermail/sdl-libsdl.org/2007-March/060463.html
EDIT: typo
[Edited by - let_bound on June 6, 2007 10:42:46 PM]
Is LazyFoo testing his tutorials on non-Microsoft systems at all? I'm asking because this is a common bug on recent X11 systems, and because of the unportable way the SDL header files are included. This isn't a criticism of his tutorials, BTW, just an honest question.
Hope this helps.
1. Just doing so and printing the output of SDL_GetError() in case of failure lead to this error message: "Failed loading DPMSDisable: /usr/lib/libX11.so.6: undefined symbol: DPMSDisable".
2. http://lists.libsdl.org/pipermail/sdl-libsdl.org/2007-March/060463.html
EDIT: typo
[Edited by - let_bound on June 6, 2007 10:42:46 PM]
Quote:Original post by let_bound
Is LazyFoo testing his tutorials on non-Microsoft systems at all? I'm asking because this is a common bug on recent X11 systems.
It worked on my SuSE 9.3. I need to install a newer distro.
I do mention trying to use alternative rendering in the tutorial, though.
Quote:Original post by let_bound.
You aren't checking the value returned by SDL_RenderText_Solid()[1]. I'm willing to bet it's the cause of all your problem, because you're attempting to render whitespaces, and that will trigger a bug in Freetype[2]. Replacing it with SDL_RenderText_Blended() will do the trick, but it'll be blended, not solid.
Is LazyFoo testing his tutorials on non-Microsoft systems at all? I'm asking because this is a common bug on recent X11 systems, and because of the unportable way the SDL header files are included. This isn't a criticism of his tutorials, BTW, just an honest question.
Hope this helps.
1. Just doing so and printing the output of SDL_GetError() in case of failure lead to this error message: "Failed loading DPMSDisable: /usr/lib/libX11.so.6: undefined symbol: DPMSDisable"
2. http://lists.libsdl.org/pipermail/sdl-libsdl.org/2007-March/060463.html
EDIT: typo
Wow, that fixed it 100%. Thanks for the links (especially to the different functions and what they do).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement