Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Black Screen for a short moment  (Read 4439 times)

0 Members and 1 Guest are viewing this topic.

Quillraven

  • Newbie
  • *
  • Posts: 11
    • View Profile
Black Screen for a short moment
« on: September 26, 2010, 07:52:14 am »
Hi,

i got a weird problem with my gamemenu class. when the game starts, the menu is loaded and displayed and as long, as the user doesn't press an arrow key, nothing happens.
when he presses an arrow key, another menuitem gets selected and the menu gets redrawn.

my problem now is, that when i start the game in fullscreen and when i press an arrow key the _FIRST_ time, i get a black screen for less than a second before the menu gets redrawn. in windowmode i haven't this problem or maybe it's just to fast to recognize it.

i don't see any problems with the code so maybe it's an sfml internal mechanic that i am using wrong or sthg.

here is the main function, but i think the problem isn't there:

Code: [Select]
#include <time.h>
#include <iostream>
#include "iqchallenge.h"
#include "title.h"
#include "game.h"
#include "information.h"
#include "KeySelection.h"
#include <fstream>

sf::RenderWindow* APPLICATION = NULL;



void FatalError( const char* text )
{
    printf( "%s\n", text );
    std::cin.ignore();
    exit( EXIT_FAILURE );
}    // end FatalError



// initializes the random generator and sfml
void Init()
{
    // initialize random generator
    srand((unsigned int)(time(NULL)));

    // read config.txt
    // it contains the videmode settings
    sf::VideoMode VMode = sf::VideoMode( 640, 480, 32 );
    std::ifstream File( "media/config.txt" );
    if( !File.is_open() )
        FatalError( "Couldn't load file \"config.txt\"" );

    std::map<std::string,std::string> values;
    while( File && !File.eof() )
    {
        std::string line;
        getline( File, line );
        if( line.length() > 1 )
        {
            int index = line.find( '=' );
            if( index != std::string::npos )
            {
                std::string key( line, 0, index );
                std::string v( line, index+1, line.length() );
                values.insert( std::make_pair( key, v ) );
            }
        }
    }
    File.close();

    // init sfml
    VMode.Width = atoi( values["width"].c_str() );
    VMode.Height = atoi( values["height"].c_str() );
    VMode.BitsPerPixel = atoi( values["color"].c_str() );
    if( !VMode.IsValid() )
        FatalError( "Couldn't initialize VideoMode" );
    if( atoi( values["fullscreen"].c_str() ) == 0 )
        APPLICATION = new sf::RenderWindow( VMode, "IQ Challenge" );
    else
        APPLICATION = new sf::RenderWindow( VMode, "IQ Challenge", sf::Style::Fullscreen );
    APPLICATION->SetFramerateLimit( 60 );
    APPLICATION->UseVerticalSync( atoi( values["vsync"].c_str() ) == 1 );
    APPLICATION->ShowMouseCursor( false );
}    // end Init



// shuts down the application by releasing the resources
// allocated in Init()
void CleanUp()
{
    delete APPLICATION;
    APPLICATION = NULL;
}    // end CleanUp



void Clear()
{
    APPLICATION->Clear();
}
void Show()
{
    APPLICATION->Display();
}    // end Clear and Show



// entry point of the application
int main()
{
    Init();

    while( APPLICATION->IsOpened() )
    {
        // handle "close application" events
        sf::Event Event;
        while( APPLICATION->GetEvent( Event ) )
        {
            if( Event.Type == sf::Event::Closed ||
                (Event.KeyPressed && Event.Key.Code == sf::Key::Escape) )
            {
                APPLICATION->Close();
            }
        }

        switch( Title() )
        {
        case( 0 ): Game(); break;
        case( 1 ): KeySelection(); break;
        case( 2 ): Information(); break;
        case( -1 ):
        case( 3 ): APPLICATION->Close(); break;
        }
    }

    CleanUp();
    return EXIT_SUCCESS;
}    // end main



and here is the menuclass:
Code: [Select]

#include "SimpleMenu.h"
#include "iqchallenge.h"


SimpleMenu::SimpleMenu() : BackGround( NULL )
{
FontSelected = NULL;
FontNormal = NULL;
for( int i=0; i<COUNT_MODES; ++i )
Color[i].r = Color[i].g = Color[i].b = 255;
} // end Konstructor



// this method automatically scales the background image to the boundaries
// given by the RunMenu Method and finally draws it
void SimpleMenu::DrawBackground( const sf::Rect<int>& Boundary )
{
if( BackGround )
{
sf::Sprite Sprite( *BackGround );
Sprite.SetScale( (float)Boundary.GetWidth() / Sprite.GetSubRect().GetWidth(), (float)Boundary.GetHeight() / Sprite.GetSubRect().GetHeight() );
Sprite.SetPosition( (float)Boundary.Left, (float)Boundary.Top );
APPLICATION->Draw( Sprite );
}
} // end DrawBackground



// sets a background image for the menu
void SimpleMenu::SetBackground( sf::Image& Image )
{
BackGround = &Image;
} // end SetBackground



// sets the fontcolor that will be used for a given mode
void SimpleMenu::SetColor( int mode, sf::Color& color )
{
if( mode >= 0 && mode <= COUNT_MODES )
Color[mode] = color;
} // end SetColor



// sets the font for a normal and selected item
void SimpleMenu::SetFonts( sf::Font& Normal, sf::Font& Selected )
{
FontNormal = &Normal;
FontSelected = &Selected;
} // end SetFonts



// draws an item at the middle of the boundary's width
// boundary is the boundary for the menu given by the runmenu method
// text is the text of the item
// x and y is the calculated offset for the item, that was calculated in the runmeenu method
// w is the width of the boundary
// h is the heightoffset between two items
// mode is the mode of the item (enabled,disabeld,selected)
void SimpleMenu::DrawItem( const sf::Rect<int>& Boundary, const std::string& Text, int x, int y, int w, int h, int mode )
{
sf::Font Font;
if( mode != SELECTED )
Font = ( FontNormal != NULL ? *FontNormal : sf::Font::GetDefaultFont() );
else
Font = ( FontSelected != NULL ? *FontSelected : sf::Font::GetDefaultFont() );

std::string Temp;
if( mode == SELECTED && ItemEyeCandy != 0 )
{
Temp = ItemEyeCandy;
Temp += "  ";
Temp += Text;
Temp += "  ";
Temp += ItemEyeCandy;
}
else
Temp = Text;


const int fontsize = Font.GetCharacterSize();
sf::String String;
String.SetText( Temp );
String.SetFont( Font );
String.SetColor( Color[mode] );
String.SetSize( (float)fontsize );
String.SetPosition( (Boundary.Left+Boundary.Right)/2.0f - String.GetRect().GetWidth()/2.0f + ItemOffsetX, Boundary.Top+y + ItemOffsetY - fontsize/2.0f );
APPLICATION->Draw( String );
} // end DrawItem



// this method controls the input of the user and draws all items
// the boundary parameter tells us the boundaryrect of the menu
// the menu is controlled via the arrow keys of the keyboard
// escape or window closed events return -1
int SimpleMenu::RunMenu( const sf::Rect<int>& Boundary )
{
bool IsDone = false;
int last = -1;
int y = 0;
int curY = 0;
// delta is the offset between two items
unsigned int delta = 0;
delta = ( FontNormal ? FontNormal->GetCharacterSize() : sf::Font::GetDefaultFont().GetCharacterSize() );
delta = std::max( delta, FontSelected ? FontSelected->GetCharacterSize() : sf::Font::GetDefaultFont().GetCharacterSize() );
y = (int)(( Boundary.GetHeight() - ( delta * Entries.size() ) ) / 2);

while( !IsDone )
{
// handle all events
sf::Event Event;
while( APPLICATION->GetEvent( Event ) )
{
switch( Event.Type )
{
case( sf::Event::Closed ): return -1;
case( sf::Event::KeyPressed ):
{
if( Event.Key.Code == sf::Key::Escape )
return -1;
else if( APPLICATION->GetInput().IsKeyDown( sf::Key::Up ) )
SelectedIndex = MoveSelection( -1 );
else if( APPLICATION->GetInput().IsKeyDown( sf::Key::Down ) )
SelectedIndex = MoveSelection( 1 );
else if( APPLICATION->GetInput().IsKeyDown( sf::Key::Return ) )
IsDone = true;
} break;
}
}

// check if the user pressed an arrow key
if( SelectedIndex != last )
{
// if so -> redraw the menu and set the new selected item
Clear();
last = SelectedIndex;
DrawBackground( Boundary );

curY = y;
for( unsigned int i=0; i<Entries.size(); ++i )
{
int mode = DISABLED;
if( IsEnabled( i ) )
{
if( i == SelectedIndex )
mode = SELECTED;
else
mode = ENABLED;
}
DrawItem( Boundary, *Entries[i], 0, curY, (int)Boundary.GetWidth(), delta, mode );
curY += delta;
}
Show();
}
}
return SelectedIndex;
} // end RunMenu



in the last method (runmenu) inside the if( selectedindex != last ) is the important code. i am confused why i only get this black screen the first time a press an arrow key in fullscreen mode. i then can't reconstruct this problem no matter how fast i press the keys.


hoping for help ;)


edit:
is there a better tag for code? only green without highlighting is hard to read imo.

Quillraven

  • Newbie
  • *
  • Posts: 11
    • View Profile
Black Screen for a short moment
« Reply #1 on: September 28, 2010, 08:48:58 pm »
no1 got any idea ? :(

i can attach the source code of an older version of the program. in the iqchallenge.cpp just set the windowmode to fullscreen and you should get the same error.

Source Code

Debilo

  • Newbie
  • *
  • Posts: 10
    • View Profile
Black Screen for a short moment
« Reply #2 on: October 01, 2010, 04:37:06 pm »
It might be very helpful to be provided with a minimal example reproducing the problem.

Quillraven

  • Newbie
  • *
  • Posts: 11
    • View Profile
Black Screen for a short moment
« Reply #3 on: October 01, 2010, 07:42:45 pm »
start the application in fullscreen and press the arrow up or down button. the window is then blacked out for a short moment.

or what kind of example do you mean?

Debilo

  • Newbie
  • *
  • Posts: 10
    • View Profile
Black Screen for a short moment
« Reply #4 on: October 03, 2010, 10:33:43 am »
No, I was talking about a minimal example in code, so that your problem can be understood without having to compile and look through tons of source files. I, for example, can't even compile the source code you uploaded, since you were using a different version of SFML, thus the interface has become incompatible.

Quillraven

  • Newbie
  • *
  • Posts: 11
    • View Profile
Black Screen for a short moment
« Reply #5 on: October 03, 2010, 01:10:02 pm »
Quote
in the last method (runmenu) inside the if( selectedindex != last ) is the important code. i am confused why i only get this black screen the first time a press an arrow key in fullscreen mode. i then can't reconstruct this problem no matter how fast i press the keys.



Code: [Select]

// check if the user pressed an arrow key
      if( SelectedIndex != last )
      {
         // if so -> redraw the menu and set the new selected item
         Clear();
         last = SelectedIndex;
         DrawBackground( Boundary );

         curY = y;
         for( unsigned int i=0; i<Entries.size(); ++i )
         {
            int mode = DISABLED;
            if( IsEnabled( i ) )
            {
               if( i == SelectedIndex )
                  mode = SELECTED;
               else
                  mode = ENABLED;
            }
            DrawItem( Boundary, *Entries[i], 0, curY, (int)Boundary.GetWidth(), delta, mode );
            curY += delta;
         }
         Show();
      }



i already posted that in the first post. it's that part that causes the problem but only when it runs the code for the first time. when i then repeat pressing arrow keys, there is no black screen.

clear is a simple application->Clear() statement and Show is application->Display() statement.

the drawmethods make a call to application->Display( Sprite )/application->Display( String ) to render the sprites/strings.

since the resources are already loaded, before entering the runmenu method, it cant be a cause of preloading images or sthg like that.

 

anything