system.cpp

来自「Source code (C++) of the Amoebax game fo」· C++ 代码 · 共 777 行 · 第 1/2 页

CPP
777
字号
/// of the system class.////// \param fadeOut Tells if add a fade out when the state is removed.///voidSystem::removeActiveState (bool fadeOut){    if ( !m_States.empty () )    {        IState *stateToDelete = m_States.back ();        // Remove the state from the active states list.        m_States.pop_back ();        // And add it to the list of states to delete at the end of the frame.        m_StatesToDelete.push_back (stateToDelete);        if ( fadeOut )        {            setActiveState (new FadeOutState (), FadeNone);        }    }}////// \brief Removes all states until the only remaining state is the main menu.////// The main menu should be the first state, since this function removes/// all states until one is left.///voidSystem::returnToMainMenu (void){    while ( m_States.size () > 2 )    {        removeActiveState (false);    }    removeActiveState (true);}////// \brief Redraws the state's background.///voidSystem::redrawStateBackground (void){    if ( 0 != m_ActiveState &&         m_InvalidatedRegion.x1 < m_InvalidatedRegion.x2 &&         m_InvalidatedRegion.y1 < m_InvalidatedRegion.y2 )    {        SDL_Rect redrawRegion;        redrawRegion.h = m_InvalidatedRegion.y2 - m_InvalidatedRegion.y1;        redrawRegion.w = m_InvalidatedRegion.x2 - m_InvalidatedRegion.x1;        redrawRegion.x = m_InvalidatedRegion.x1;        redrawRegion.y = m_InvalidatedRegion.y1;        m_ActiveState->redrawBackground (&redrawRegion, getScreenSDLSurface ());        m_InvalidatedRegion.x1 = std::numeric_limits<int16_t>::max ();        m_InvalidatedRegion.y1 = std::numeric_limits<int16_t>::max ();        m_InvalidatedRegion.x2 = std::numeric_limits<int16_t>::min ();        m_InvalidatedRegion.y2 = std::numeric_limits<int16_t>::min ();    }}////// \brief System's main loop.////// This is the loop that drivers the whole system./// The call to this function doesn't return until the/// system must shown down, in which case the application/// can exit.///voidSystem::run (void){    assert (0 != getScreenSDLSurface () &&            "Tried to run the system without initializing it.");    bool end = false;    do    {        // Get the active state or set it 0 if no state is active.        if ( m_States.empty () )        {            m_ActiveState = 0;        }        else        {            m_ActiveState = m_States.back ();        }        // If we are going too fast, slow down so we won't burn the CPU.        FrameManager::update ();        // If there's no active state, then we are done.        if ( 0 == m_ActiveState )        {            SDL_Event quitEvent;            quitEvent.type = SDL_QUIT;            SDL_PushEvent (&quitEvent);        }        // If the current active state is different from the previously        // active state, then activate the current state.        else if ( m_ActiveState != m_PreviousActiveState )        {            m_ActiveState->activate ();            invalidateWholeScreen ();        }        // Process all pending events.        SDL_Event event;        while ( SDL_PollEvent (&event) )        {            if ( SDL_QUIT == event.type )            {                end = true;            }            else if ( 0 != m_ActiveState )            {                switch ( event.type )                {                    case SDL_JOYAXISMOTION:                        m_ActiveState->joyMotion (event.jaxis.which,                                                  event.jaxis.axis,                                                  event.jaxis.value);                        break;                    case SDL_JOYBUTTONDOWN:#if defined (IS_GP2X_HOST) && !defined (__SYMBIAN32__)                        if ( GP2X_BUTTON_VOLUP == event.jbutton.button )                        {                            Options::getInstance ().incrementVolume ();                            m_VolumeDisplayTime = k_VolumeDisplayTime;                            applyVolumeLevel ();                        }                        else if ( GP2X_BUTTON_VOLDOWN == event.jbutton.button )                        {                            Options::getInstance ().decrementVolume ();                            m_VolumeDisplayTime = k_VolumeDisplayTime;                            applyVolumeLevel ();                        }                        else#endif  // IS_GP2X_HOST                        {                            m_ActiveState->joyDown (event.jbutton.which,                                                    event.jbutton.button);                        }                        break;                    case SDL_JOYBUTTONUP:                        m_ActiveState->joyUp (event.jbutton.which,                                              event.jbutton.button);                        break;#if !defined (IS_GP2X_HOST)|| defined (__SYMBIAN32__)                    case SDL_ACTIVEEVENT:                        if ( event.active.state & SDL_APPACTIVE )                        {                            // Window is minimized.                            if ( 0 == event.active.gain )                            {                                Music::pause ();                                pause ();                            }                        }                        break;                    case SDL_KEYDOWN:                        // ALT+RETURN is reserved to toggle full screen                        if ( SDLK_RETURN == event.key.keysym.sym &&                             (event.key.keysym.mod & KMOD_ALT) != 0 )                        {                            toggleFullScreen ();                        }                        else                        {                            m_ActiveState->keyDown (event.key.keysym.sym);                        }                        // Check if unicode translation is enabled                        // and send the unicode code if so.                        if ( isUnicodeTranslationEnabled () &&                             0 != event.key.keysym.unicode )                        {                            m_ActiveState->unicodeCharacterPressed (event.key.keysym.unicode);                        }                        break;                    case SDL_KEYUP:                        m_ActiveState->keyUp (event.key.keysym.sym);                        break;#endif // !IS_GP2X_HOST                }            }        }        // Update and render the active state.        if ( 0 != m_ActiveState )        {            // Update the state's logic.            m_ActiveState->update (FrameManager::getElapsedTime ());            // Remove any previously set clip rectangle.            SDL_SetClipRect (getScreenSDLSurface (), NULL);            // Draw the state's background for the invalided screen region.            redrawStateBackground ();            // Render the state.            m_ActiveState->render (getScreenSDLSurface ());        }#if defined (IS_GP2X_HOST) && !defined (__SYMBIAN32__)        // Show the current volume level if it has been changed.        if ( m_VolumeDisplayTime > 0 )        {            // Remove any previously set clip rectangle.            SDL_SetClipRect (getScreenSDLSurface (), NULL);            // Show the display.            uint16_t x = Options::getInstance ().getScreenWidth () / 2 -                         m_VolumeDisplay->getWidth () / 2;            uint16_t y = Options::getInstance ().getScreenHeight () / 2 -                         m_VolumeDisplay->getHeight () / 2;            m_VolumeDisplay->blit (x, y, getScreenSDLSurface ());            // Show the current level in white (upper part of the            // image) and the remaining up to the maximum level            // in gray (lower part of the image.)            //uint8_t volumeLevel = Options::getVolumeLevel ();            uint16_t width = m_VolumeLevel->getWidth () *                             Options::getInstance ().getVolumeLevel () /                             Options::getMaxVolumeLevel ();            if ( !isSoundEnabled () )            {                width = 0;            }            x = Options::getInstance ().getScreenWidth () / 2 -                m_VolumeLevel->getWidth () / 2;            y += m_VolumeDisplay->getHeight () - 10 -                 m_VolumeLevel->getHeight () / 2;            m_VolumeLevel->blit (0, 0,                                 width, m_VolumeLevel->getHeight () / 2,                                 x, y, getScreenSDLSurface ());            x += width;            m_VolumeLevel->blit (width, m_VolumeLevel->getHeight () / 2,                                 m_VolumeLevel->getWidth () - width,                                 m_VolumeLevel->getHeight () / 2,                                 x, y, getScreenSDLSurface ());            // Update the time to show the display.            m_VolumeDisplayTime -= FrameManager::getElapsedTime ();        }#endif // IS_GP2X_HOST        // Refresh the screen.        SDL_Flip (getScreenSDLSurface ());        // Deletes the not longer used states.        if ( !m_StatesToDelete.empty () )        {            std::for_each (m_StatesToDelete.begin (), m_StatesToDelete.end (),                           DeleteObject<IState> ());            m_StatesToDelete.clear ();        }        // Set the active state as the previous active state.        m_PreviousActiveState = m_ActiveState;    }    while ( !end );}////// \brief Sets the current active state.////// The System class takes ownership of the \a state class/// and is responsable to delete it when no longer needed.////// \param state The state to set as the current active state./// \param fade Tells which type of fade to set when the state is active.///voidSystem::setActiveState (IState *state, uint8_t fade){    assert ( 0 != state && "Tried to set a NULL state as the active.");    m_States.push_back (state);    if ( FadeIn == (fade & FadeIn) )    {        m_States.push_back (new FadeInState (state));    }    if ( FadeOut == (fade & FadeOut) )    {        m_States.push_back (new FadeOutState ());    }}////// \brief Sets the video mode reading the parameters from the options.///voidSystem::setVideoMode (void){    // Check if we should go to full screen.    uint32_t videoFlags = SDL_SWSURFACE;    if ( Options::getInstance ().isFullScreen () )    {        videoFlags |= SDL_FULLSCREEN;    }    // Sets the video mode.    m_Screen = SDL_SetVideoMode (Options::getInstance ().getScreenWidth (),                                 Options::getInstance ().getScreenHeight (),                                 Options::getInstance ().getScreenDepth (),                                 videoFlags);    if ( 0 == m_Screen )    {        // First check if the video settings are the defaults (which should        // be the most secure) and if they aren't, reset back to them and        // try again.        if ( !Options::getInstance ().isVideoOptionsAtDefault () )        {            Options::getInstance ().setDefaultVideoOptions ();            setVideoMode ();            // If the system was already initialized, then tell            // the user that her video settings couldn't be set.            if ( !m_States.empty () )            {                setActiveState (new VideoErrorState (m_States.back ()),                                FadeNone);            }        }        else        {            throw std::runtime_error (SDL_GetError ());        }    }    // Get the current screen's scale factor.    // Take into consideration the "odd" factor we need to have when    // using a 1024x768 screen resolution.    if ( 1024 == m_Screen->w )    {        m_ScreenScaleFactor = 0.75f;    }    else    {        m_ScreenScaleFactor = std::max (m_Screen->w / k_ScreenMaxWidth,                                        m_Screen->h / k_ScreenMaxHeight);    }    // Hide the cursor on the screen. Do only if the video mode is set    // to full screen, otherwise it feels awkward to make the cursor desappear    // when it passes over the window...    SDL_ShowCursor (Options::getInstance ().isFullScreen () ? SDL_DISABLE :                                                              SDL_ENABLE);}////// \brief Pressents a fatal error to the user.////// \param error The actual error message.///voidSystem::showFatalError (const std::string &error){    std::string title ("There was a fatal error an the application could not continue");    std::ostringstream fullMessage;    fullMessage << "Reinstall the application and try again." << std::endl;    fullMessage << "If the error still occurs, please contact the" << std::endl;    fullMessage << "authors at <" << PACKAGE_BUGREPORT << "> ";    fullMessage << "attaching the following error message: " << std::endl;    fullMessage << std::endl << error << std::endl;#if defined (IS_WIN32_HOST)    MessageBox (NULL, (title + "\r\n" + fullMessage.str ()).c_str (),                "Amoebax", MB_ICONERROR);#elif defined (IS_OSX_HOST)    OSXAlert (title.c_str (), fullMessage.str ().c_str ());#else    std::cerr << title << std::endl;    std::cerr << fullMessage.str () << std::endl;#endif}////// \brief Toggles between full screen and windowed mode.///voidSystem::toggleFullScreen (void){    Options::getInstance ().setFullScreen (!Options::getInstance ().isFullScreen ());    changeVideoMode ();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?