Theres this thing that i dont fully understand. Im using this tutorial: http://lazyfoo.net/SDL_tutorials/lesson08/index.php and i in here we first set up some surfaces with text and then asign their value to the message and then for some reason we have to reset the message value to 0 in order for the program to quit properly, but if i dont set up the surfaces with text from the start and just set up the message myself when coding the event itself, i dont need to reset it and everything works just fine, whats the deal? I think i wasnt very clear but i think it should not be hard to understand if you see the tutorial i gave you.
He sets it to NULL (or 0) because that way he doesn't reprint the same message constantly. Whenever you press a key message becomes non-NULL and it redraws and this has nothing to do with the program quitting.
Well, when i use the method in the tutorial and dont set it to 0, when i try to quit the program it just freezes, works fine when doing my way. By the way, when i use the tut method, the message appear for half a second and dissapears, it worked last time, dont know whats the problem.
I'd have to look at the source code you were running. The download-able code on his website doesn't seem to have any problems. The message flashing part makes me think that you had apply_surface( 0, 0, background, screen ); outside of the message != NULL check.
As for the freezing part I'm not sure because I'd have to look at what you had.
void eve()
{
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT )
{
run = false;
}
if ( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: message = Up; break;
case SDLK_DOWN: message = Down; break;
case SDLK_RIGHT: message = Right; break;
case SDLK_LEFT: message = Left; break;
}
}
}
blit(back,screen,0,0);
if ( message != 0 )
{
blit(back,screen,0,0);
blit(message,screen,100,300);
message = 0;
}
SDL_Flip(screen);
}
}
I see that if i remove the blit before the "if ( message != 0 )" it works fine, why is that? Oh and one more question, why when we use key states, we see lets say text for the time we are holding a key down, but when we use the method i posted earlier in the tut, it changes permenantly, it seems fine, but shouldnt the values change permenantly using key state method too? Key state tut: http://lazyfoo.net/SDL_tutorials/lesson10/index.php
No values in your code are "changing permanently". When a key is pressed, an event is triggered, you catch the event, and you assign a value to your message variable. As soon as you blit your message, you set your message variable back to 0. That doesn't look permanent to me. If you wish to keep the displayed message visible, then (as you noticed yourself), don't blit the background over top of it every time through your while(run) loop. In fact, you shouldn't call SDL_Flip(screen) until there's actually a change to bother with.
So if you want the displayed message to persist until the next keystroke:
if ( message != 0 )
{
blit(back,screen,0,0);
blit(message,screen,100,300);
SDL_Flip(screen);
message = 0;
}
If you want to clear the message if you press any key other than up/down/left/right, then create a fifth non-zero value to assign to message as a default in your switch() statement at line 14.
When i use the keys in event based method, how can i make the messages dissapear after i let go of the key, because in the key state method its done easily and cant understand why it doesnt work the same way on event based method.
What you would need is a check for when the even is SDL_KEYUP and then set the message to 0 there rather than after the message is displayed.
void eve()
{
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT )
{
run = false;
}
if ( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: message = Up; break;
case SDLK_DOWN: message = Down; break;
case SDLK_RIGHT: message = Right; break;
case SDLK_LEFT: message = Left; break;
}
}
if ( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
default: message = 0; break; //set message to 0 when key is released (this is if any key is released)
}
}
}
blit(back,screen,0,0); //always draw the background
if ( message != 0 ) //draw the message if there is one
blit(message,screen,100,300);
SDL_Flip(screen);
}
}Since i dont want to flood the forum with new topics, i will just ask all of my SDL questions here. Its not exactly a problem but something i dont understand, i initialized the font in the Global:
TTF_Font* font = TTF_OpenFont("lazy.ttf",30);
And later i was doing some timing stuff and i was getting an error that something was not found, then i set the font to NULL and initialized it in the other function and then the program worked perfectly, why is that? I basicly did the exact same thing, but just initialized the font not in the Global but elsewhere. And one more thing im unsure of is that when i do something in the event thats based on some variable and lets say it was set to 0 ( the variable ) first, and lets say if i press and hold the Up key, the value of that variable will be changed, but after i release the Up key, the value is changed back to 0, seems good and all, but when i try to do something based like that on a simple console app, the value doesnt change back, why is that?
As far as the font issue, it doesn't look as though the problem is with loading the font, but what you do with the returned font-handle after that point. I'm also not entirely sure what you mean by "in the Global" ... you can't call functions outside of main() or other functions, so you should be within the scope of -some- function when you call TTF_OpenFont(). And if you've coded your line exactly as you provided it above, then you've also created a local variable at that point, which won't exist in some other function when you try to use it. If this isn't entirely clear, try posting more of your code, and I'll be able to tell exactly what went wrong.
Then, if by "simple console app", you mean something that doesn't use SDL, then you don't have the same event-loop at your disposal, though there are still platform-specific ways to get at the same information (which is what SDL uses internally so that it is portable across multiple operating systems). Otherwise, post the smallest amount of code that demonstrates the problem, and again, we'll be happy to take a look. Unfortunately, despite many years of software development experience, I still can't read your screen from way over here! ;-)
I thnk you already answered the Global thing questions, i was calling a function outside of any other function, in the Global scope that is, but when i did that in a function it worked perfectly. Thanks to you, now i know that i cant call functions in the Global Scope :)
By Global Scope i mean like this:
#include "stdafx.h"
#include <iostream>
int x = 5, y = 10;
void bye()
{
}
void hi()
{
}
int main()
{
char f;cin>>f;
return 0;
}
I created a variable which will be available for all of my created functions below.
About the app question, its not exacly a problem, but something i would like to understand, so lets say in SDL we do this :
message = 0;
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { run = false; }
if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_UP )
{
message = Up;
}
And the value only changes when i am holding the UP key, when i let go of it, it changes back to 0 ( its just a part of the code ), but when i try to do something based on this using iostream, the value doesnt reset in the Next loop, it just stays 5 no matther how many loops i go through, like this:
int x = 0, y = 1;
while(true)
{
if ( y == 1 )
{
x = 5;
}
cout << x << endl;
y++;
char z;cin>>z;
}For you first example, when you say "it changes back to 0 ( its just a part of the code )", I assume you mean there's additional code you haven't included (but is relevant to the behavior we're discussing) which reads something like:
if ( event.type == SDL_KEYUP )
{
if ( event.key.keysym.sym == SDLK_UP )
{
message = 0;
}
...
}
Also, to clarify, the value doesn't change "while you're holding the key", it changes to Up when you first press the key (which generates a key-down event) and changes back to 0 when you release the key (which generates a key-up event). It doesn't do anything in between the time you press the key and release the key unless you also track key-repeat events (like when you hold down a key in a text-editor and after a short pause it starts repeating).
Then as far as your second example, why would you expect the value of x to go back to zero? Very little happens "automatically" in programming, and if it does, it's for a reason and -should- be well documented (though documentation is often not nearly as clear or as complete as it should be -- that's a different issue). But your variables shouldn't change value out from under you. If you tell x it should now have the value 5, it should keep that value until you tell it you want it to have some other value. You don't do that in your code, so there you go.
If you added additional code after line 8, then it would do what you expect:
int x = 0, y = 1;
while(true)
{
if ( y == 1 )
{
x = 5;
}
else {
x = 0;
}
cout << x << endl;
y++;
char z;cin>>z;
}I thought about these questions and red your answers and it seems very clear and simple now, the problem with the font was that i was calling the function, before i declared it and it is now clear about the 0 thing. At this time i dont have any more questions, thanks for quick and helpful answers.
SDL_FillRect(screen,&screen->clip_rect,SDL_MapRGB(screen->format,0,0,0));
if ( timer == true )
{
stringstream time;
time << "Watch: " << SDL_GetTicks() - start;
timing = TTF_RenderText_Solid(font,time.str().c_str(),c);
blit(timing,screen,200,200);
SDL_FreeSurface(timing);
}
SDL_Flip(screen);
Taken from a tutorial: http://lazyfoo.net/SDL_tutorials/lesson12/index.php
This part of the code is from the main loop and i would like to ask why do we keep cleaning out the Surface
SDL_FreeSurface(timing)
, is it really necessary? By the way, i dont fully understand the part in the tutorial about the
time << "Timer: " << SDL_GetTicks() - start;
, dont understand the explanation of the " - " thing in the tutorial, dont know, maybe my english is simply not good enough :)
As far as the surface, from the SDL reference for TTF_RenderText_Solid() : "Returns: a pointer to a new SDL_Surface. NULL is returned on errors." This means the function has allocated a new SDL_Surface object to render the text onto, and it is the caller's responsibility (yours, in this case) to free the allocated object when you're done with it. Otherwise you have a memory leak (as the loop allocated more and more of these surfaces without giving them back) and eventually the program crashes.
The "-" thing is a simple subtraction. SDL_GetTicks() probably returns large and relatively meaningless numbers (but a bigger one each time), so what you want instead is how many have gone by since you started. You capture the first value into variable "start", and then later find out how many ticks have gone by by subtracting that first value from the current value returned.
About the " ...- start ", in this tutorial its there so when we press the "s" key and when we press it again, the timer starts from 0, so ok, i get that, we subtract the time we have from the same time value so we get a 0 seconds, when we start the timer again by pressing s, but my question is, shouldnt the subtraction work on every loop? It seems that it only subtracts one time and just ignores the " ...- start " line after. All in this tut: http://lazyfoo.net/SDL_tutorials/lesson12/index.php
For convenience, I'm posting the main() routine from the tutorial (as provided in the download link), so we can refer to the same line numbers:
int main( int argc, char* args[] )
{
//Quit flag
bool quit = false;
//The timer starting time
Uint32 start = 0;
//The timer start/stop flag
bool running = true;
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Generate the message surface
startStop = TTF_RenderText_Solid( font, "Press S to start or stop the timer", textColor );
//Start the timer
start = SDL_GetTicks();
//While the user hasn't quit
while( quit == false )
{
//While there's an event to handle
while( SDL_PollEvent( &event ) )
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//If s was pressed
if( event.key.keysym.sym == SDLK_s )
{
//If the timer is running
if( running == true )
{
//Stop the timer
running = false;
start = 0;
}
else
{
//Start the timer
running = true;
start = SDL_GetTicks();
}
}
}
//If the user has Xed out the window
else if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
//Apply the background
apply_surface( 0, 0, background, screen );
//Apply the message
apply_surface( ( SCREEN_WIDTH - startStop->w ) / 2, 200, startStop, screen );
//If the timer is running
if( running == true )
{
//The timer's time as a string
std::stringstream time;
//Convert the timer's time to a string
time << "Timer: " << SDL_GetTicks() - start;
//Render the time surface
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
//Apply the time surface
apply_surface( ( SCREEN_WIDTH - seconds->w ) / 2, 50, seconds, screen );
//Free the time surface
SDL_FreeSurface( seconds );
}
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
//Clean up
clean_up();
return 0;
}
It looks to me like the subtraction time << "Timer: " << SDL_GetTicks() - start; (line 79 above) is being performed every time through the while( quit == false ){...} loop, as long as the running flag is true.
Yes, and the thing i dont understand is this, when we press "s" while the timer is running:
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//If s was pressed
if( event.key.keysym.sym == SDLK_s )
{
//If the timer is running
if( running == true )
{
//Stop the timer
running = false;
start = 0;
}
When we press "s" again:
else
{
//Start the timer
running = true;
start = SDL_GetTicks();
}
So the start variable has SDL_GetTicks value and it subracts:
time << "Timer: " << SDL_GetTicks() - start;
So my question is, shouldnt it subtract from the "start" value every loop? It seems that it only activates once, when i press "s" two times, but after that, the time timer starts running as if theres no "- start" line. Its as if the "start" value takes the SDL_GetTicks value and then sets to 0 after it does his thing, but its not.
Its as if the "start" value takes the SDL_GetTicks value and then sets to 0 after it does his thing
What makes you think this is the case?
From the tutorial description text:So if you started the timer when SDL_GetTicks() was 10,000 and now SDL_GetTicks() is 20,000, it will return 10,000 meaning 10 seconds have passed since the timer started.
Meaning SDL_GetTicks() is returning values in units of milliseconds, not seconds. Perhaps this is the source of confusion? Since the code calls the rendered text-surface "seconds", it might be more obvious if you convert to the expected units:
...
time << "Timer: " << (SDL_GetTicks() - start)/1000; // or use 1000.0 to see fractions of seconds
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
...