Jump to content
  • Advertisement
Sign in to follow this  
fadeh

[SDL] simple menu trouble

This topic is 4813 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, i'm writing a little menu for a game (i'm pretty new in game programming) but a problem, i can't realize why, occurs.. If u try to compile this little piece of code u can figure out what the problem is because it's hard to explain in simple words... Let me try anyway... When i press down the up or down button i can choose between 2 condition ("1 vs 1" and "multiplayer"), then when i release the button the choice is stopped on the last condition highilited. But switching between that two condition is too fast so it's hard to choose the right condition. I found a function SDL_EnableKeyRepeat(int delay, int interval) that seems to be the right choice but i tried to use it in many ways without success...
//Menu Keyboard Handling
Menu Input_Menu(Menu menu)
{	
	SDL_Event event;

    while (SDL_PollEvent(&event)) 
    {
	switch(event.type) 
        {
		case SDL_KEYDOWN:
		switch(event.key.keysym.sym)
		{
		case SDLK_UP:
                        menu.pressed = 1;
			break;							
                case SDLK_DOWN:
			menu.pressed = 1;
                        break;							
		case SDLK_RETURN:
			menu.state = 1;
			break;
		default:
                        break;
            }
            break;

		case SDL_KEYUP:
                switch(event.key.keysym.sym)
		{
			case SDLK_UP:
				if(menu.pressed > 0)
					menu.pressed = 0;
                                break;
                        case SDLK_DOWN:
				if(menu.pressed > 0)
					menu.pressed = 0;
				break;
                        default:
                                break;
               }
			break;
				
      }
	return menu;
}

//Display Menu

int menu_routine(SDL_Surface *screen)
{
	const int vx = 220;
	const int vy = 200;
	const int mx = 220;
	const int my = 300;
	SDL_Color white = {255, 255, 255};
	SDL_Color red   = {255, 0, 0};
	SDL_Surface *versus = 0;
	SDL_Surface *multip = 0;

	TTF_Font *font = 0;
	Menu menu;
	SDL_Surface *background = 0;
	background = initsprite(background, "data/background.png");
	menu.state = menu.pressed = 0;
	int temp = 0;

	SDL_BlitSurface(background, NULL, screen, NULL);


	while(1)
	{
		
		if(menu.pressed == 1)
			if(temp == 1)
				temp = 0;
			else
				temp = 1;
		
		if(temp == 0)
		{
		drawttf(screen, versus, font, "1  Versus  1", vx, vy, white);
		drawttf(screen, multip, font, "Multiplayer", mx, my, red);
		}
		else 
		{
		drawttf(screen, versus, font, "1  Versus  1", vx, vy, red);
		drawttf(screen, multip, font, "Multiplayer", mx, my, white);
		}
	

		SDL_Flip(screen);
		
		menu = Input_Menu(menu);
		if(menu.state == 1)
			return temp;
	}
}

// Other function u may need if u want to compile it
SDL_Surface *initsprite(SDL_Surface *sprite, char *filename)
{
	
	SDL_Surface *temp = IMG_Load(filename);
	if(temp == NULL)
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}
	if(SDL_SetColorKey(temp, SDL_SRCCOLORKEY, 0x00ff00) == -1)
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}

	if((sprite  = SDL_DisplayFormat(temp)) == NULL)
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}

	SDL_FreeSurface(temp);

	return sprite;
}

int drawttf(SDL_Surface *screen, SDL_Surface *message, TTF_Font *font, char *text, int x, int y, SDL_Color textColor)
{
	SDL_Rect where;
	if((font = TTF_OpenFont("arial.ttf", 15)) == NULL)
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}


	if(!(message = TTF_RenderText_Blended(font, text, textColor)))
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}


	where.x = x;
	where.y = y;

	if(SDL_BlitSurface(message, NULL, screen, &where) == -1)
	{
		fprintf(stderr, "\n%s\n", SDL_GetError());
		exit(-1);
	}

	TTF_CloseFont(font);
	return 0;
}


Regards, fadeh

Share this post


Link to post
Share on other sites
Advertisement
Idealy what you want to do is this:

Rather than use those SDL_KepUp/KeyDown, you will want use the SDL_GetKeyState function - Uint8* keys = SDL_GetKeyState( 0 ); This will be at the start of your 'update' code.

Now when you are displaying the menu screen, you will have a check to see if a key was pressed. if( keys[SDLK_UP] ) { ... }. You will have the same thing for the other keys as well.

However, this will make it hard to select, so what you do is simply 'clear' the key if it is pressed. keys[ SDLK_UP] = 0;. So now in relation to your code:


//Menu Keyboard Handling
Menu Input_Menu(Menu menu)
{
SDL_Event event;

while (SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
menu.state = 1;
break;
default:
break;
}
break;

case SDL_KEYUP:
switch(event.key.keysym.sym)
{
default:
break;
}
break;

}
return menu;
}





//Display Menu

int menu_routine(SDL_Surface *screen)
{
const int vx = 220;
const int vy = 200;
const int mx = 220;
const int my = 300;
SDL_Color white = {255, 255, 255};
SDL_Color red = {255, 0, 0};
SDL_Surface *versus = 0;
SDL_Surface *multip = 0;

TTF_Font *font = 0;
Menu menu;
SDL_Surface *background = 0;
background = initsprite(background, "data/background.png");
menu.state = menu.pressed = 0;
int temp = 0;

SDL_BlitSurface(background, NULL, screen, NULL);
SDLK_UP
/************************************************/
Uint8* keys = 0;
/************************************************/
while(1)
{
/************************************************/
keys = SDL_GetKeyState(0);
/************************************************/
if( keys[SDLK_UP] || keys[SDLK_DOWN])
{
temp = !temp;
keys[SDLK_UP] = keys[SDLK_DOWN] = 0;
}

if(temp == 0)
{
drawttf(screen, versus, font, "1 Versus 1", vx, vy, white);
drawttf(screen, multip, font, "Multiplayer", mx, my, red);
}
else
{
drawttf(screen, versus, font, "1 Versus 1", vx, vy, red);
drawttf(screen, multip, font, "Multiplayer", mx, my, white);
}


SDL_Flip(screen);

menu = Input_Menu(menu);
if(menu.state == 1)
return temp;
}
}




The last source block stays the same.

Now of course the way I've shown changes is very specific to this example of having only 2 menu options, but it should give you the idea.

If you wanted a menu system that had X items, it's just a matter of this:

// First itme
int curItem = 0;
// 6 total items, 0,1,2,3,4,5 indices
int maxItemIndex = 5;
if( keys[SDLK_DOWN] )
{
curItem++;
if( curItem > maxItemIndex )
curItem = 0;
keys[SDLK_DOWN] = 0;
}

if( keys[SDLK_UP] )
{
curItem--;
if( curItem < 0 )
curItem = maxItemIndex;
keys[SDLK_DOWN] = 0;
}




That should get you where you need to be. Let us know if it doesn't work as expected still or you need more explanation/guidance. Good luck!

Share this post


Link to post
Share on other sites
Many many thanx Drew, your explanation is really clear and you're code works fine.. Thanx, again :D

fadeh

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!