system.cpp

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

CPP
777
字号
//// Cross-platform free Puyo-Puyo clone.// Copyright (C) 2006, 2007 Emma's Software//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.//#if defined (HAVE_CONFIG_H)#include <config.h>#endif // HAVE_CONFIG_H#include <assert.h>#include <cstdlib>#include <iostream>#include <limits>#include <SDL.h>#include <SDL_mixer.h>#include <sstream>#include <stdexcept>#include <string>#include <algorithm>
#if defined (IS_WIN32_HOST)#include <windows.h>#endif // IS_WIN32_HOST#if defined (IS_OSX_HOST)extern "C" void OSXAlert (const char *title, const char *message);#endif // IS_OSX_HOST#include "FrameManager.h"#include "FadeInState.h"#include "FadeOutState.h"#include "File.h"#include "IState.h"#include "Options.h"#include "PauseState.h"#include "System.h"#include "VideoErrorState.h"using namespace Amoebax;/// The buffer system to use for audio.#if defined (IS_GP2X_HOST)static const int k_AudioBuffers = 1024; // Otherwise it gets delayed.#else // !IS_GP2X_HOSTstatic const int k_AudioBuffers = 4096;#endif // IS_GP2X_HOST/// The numnber of audio channels.static const int k_AudioChannels = 2;/// The audio format to use.static const int k_AudioFormat = AUDIO_S16SYS;/// The audio rate to use.static const int k_AudioRate = 22050;/// Maximum frame rate (in FPS.)static const float k_FrameRate = 30.0f;/// Maximum screen's vertical resolution (in pixels.)static const float k_ScreenMaxHeight = 960.0f;/// Maximum screen's horizontal resolution (in pixels.)static const float k_ScreenMaxWidth = 1280.0f;/// The time to show the volume level (in ms.)static const int k_VolumeDisplayTime = 1000;System System::m_SystemInstance;#if defined (IS_WIN32_HOST)////// \brief Sets the current directory to be the executable's directory.////// This is used when on Windows to be at the same directory as the/// executable, so we can load any data as a relative path.///static voidchangeToExecutableDirectory (void){    // Get the executable path.    TCHAR executablePath[MAX_PATH];    if ( GetModuleFileName (NULL, executablePath, MAX_PATH - 1) > 0 )    {        std::string executableDirectory (executablePath);        std::string::size_type backslashPosition = executableDirectory.rfind ("\\");        if ( std::string::npos != backslashPosition )        {            executableDirectory.erase (backslashPosition);            File::ChangeWorkDirectory (executableDirectory);        }    }}#endif // IS_WIN32_HOST////// \brief System object's default constructor.///System::System (void):    m_ActiveState (0),    m_InvalidatedRegion (),    m_PreviousActiveState (0),    m_Screen (0),    m_ScreenScaleFactor (1.0f),    m_SoundEnabled (false),    m_States (0),    m_StatesToDelete (0),    m_UnicodeTranslationEnabled (false){}////// \brief System object's destructor.///System::~System (void){    // Deletes all states.    std::for_each (m_StatesToDelete.begin (), m_StatesToDelete.end (),                   DeleteObject<IState> ());    m_StatesToDelete.clear ();    std::for_each (m_States.begin (), m_States.end (),                   DeleteObject<IState> ());    m_States.clear ();    // Closes all opened joysticks.    std::for_each (m_Joysticks.begin (), m_Joysticks.end (),                   SDL_JoystickClose);    // Shuts down all SDL systems.    if ( m_SoundEnabled )    {        Mix_CloseAudio ();    }    SDL_Quit ();}////// \brief Applies the video mode in the options.///voidSystem::applyVideoMode (void){    changeVideoMode ();}////// \brief Applies the volume level in the options.///voidSystem::applyVolumeLevel (void){    if ( isSoundEnabled () )    {        Mix_Volume (-1, Options::getInstance ().getVolumeLevel () *                        MIX_MAX_VOLUME / Options::getMaxVolumeLevel ());        Mix_VolumeMusic (Options::getInstance ().getVolumeLevel () *                         MIX_MAX_VOLUME / Options::getMaxVolumeLevel ());    }}////// \brief Sets the new video mode and notifies all states.////// This function should be used when the video mode options (resolution,/// full screen, etc...) are changed. It sets again the new video mode/// and notifies all states (not only the active).///voidSystem::changeVideoMode (void){    // Sets the new video mode from the options.    setVideoMode ();    // Notifies all states.    for ( std::vector<IState *>::iterator currentState = m_States.begin () ;          currentState < m_States.end () ; ++currentState )    {        (*currentState)->videoModeChanged ();    }    // Invalidates the whole screen.    invalidateWholeScreen ();}////// \brief Enables or disables unicode translations.////// \param enabled If set to \a true, the unicode translation of key pressed///                is activated and send through calls to///                IState::unicodeCharacterPressed().////// \note Enabling unicode translation can incur an overhead for each key///       pressed. So enable with care.///voidSystem::enableUnicodeTranslation (bool enabled){    SDL_EnableUNICODE (enabled ? 1 : 0);    m_UnicodeTranslationEnabled = enabled;}////// \brief Gets the factor between the maxium screen resolution and the current.////// \return A factor between the maximum resolution and the current resolution.///floatSystem::getScreenScaleFactor (void){    return m_ScreenScaleFactor;}////// \brief Gets the SDL surface that represents the screen.////// \return The SDL surface of the screen.///SDL_Surface *System::getScreenSDLSurface (void){    return m_Screen;}////// \brief Initializes the system.////// If anything goes wrong, this function throws a runtime_error exception.///voidSystem::init (void){#if defined (IS_OSX_HOST)    // Tell SDL to send key events to Cocoa, so shortcuts will work.    SDL_putenv ("SDL_ENABLEAPPEVENTS=1");#endif // IS_OSX_HOST#if defined (IS_WIN32_HOST)    // When running under windows, set the current directory to be    // the executable directory.    changeToExecutableDirectory ();#endif // IS_WIN32_HOST    // Initialize pseudo-random generator.    srand ( (unsigned)time (0));    // Initialize SDL.    if ( SDL_Init (SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) < 0 )    {        throw std::runtime_error (SDL_GetError ());    }    // Sets the video mode from the configuration parameters.    setVideoMode ();    // Set the window's title for windowed modes.    SDL_WM_SetCaption (PACKAGE_NAME, PACKAGE_NAME);    // Set the maximum frame rate.    FrameManager::init (k_FrameRate);    // Open the audio device, if enabled.    if ( Options::getInstance ().isSoundEnabled () )    {        if ( Mix_OpenAudio (k_AudioRate, k_AudioFormat, k_AudioChannels,                            k_AudioBuffers) < 0 )        {            // Just print a warning, not being able to open a sound            // device is not a complete failure, the game is still playable.            std::cerr << "Couldn't open sound system: " << Mix_GetError ();            std::cerr << std::endl;        }        else        {            m_SoundEnabled = true;            applyVolumeLevel ();        }    }#if defined (IS_GP2X_HOST)    // When the program is launched from the GP2X main menu, it is possible    // that the SDL event queue registered the button down event of the    // "B" button. To prevent the game to think the user pressed the    // "B" button, I retrieve a single event from the event queue and    // just ignore it.    {        SDL_Event event;        SDL_PollEvent (&event);    }    // Open the only joystic.    SDL_Joystick *joystick = SDL_JoystickOpen (0);    if ( NULL == joystick )    {        throw std::runtime_error (SDL_GetError ());    }    m_Joysticks.push_back (joystick);    // Load the volume level display and gauge bar.
#ifndef __SYMBIAN32__    m_VolumeDisplay.reset (            Surface::fromFile (File::getGraphicsFilePath ("volume.png")));    m_VolumeLevel.reset (Surface::fromFile (                File::getGraphicsFilePath ("volume-level.png")));    m_VolumeDisplayTime = 0;
#endif#else // !IS_GP2X_HOST    int numJoysticks = SDL_NumJoysticks ();    for (int currentJoystick = 0 ; currentJoystick < numJoysticks ;         ++currentJoystick )    {        SDL_Joystick *joystick = SDL_JoystickOpen (currentJoystick);        if ( NULL != joystick )        {            // The joystick needs to have at least two axes and one            // button.            if ( 1 < SDL_JoystickNumAxes (joystick) &&                 0 < SDL_JoystickNumButtons (joystick) )            {                m_Joysticks.push_back (joystick);            }        }    }#endif // IS_GP2X_HOST}////// \brief Invalidates the whole screen.////// When the whole screen is invalidated, the state will redraw/// the whole background.///voidSystem::invalidateWholeScreen (void){    SDL_Rect invalidatedRect;    invalidatedRect.h = Options::getInstance ().getScreenHeight ();    invalidatedRect.w = Options::getInstance ().getScreenWidth ();    invalidatedRect.x = 0;    invalidatedRect.y = 0;    invalidateScreenRegion (&invalidatedRect);}////// \brief Tells if the video is in fullscreen mode.////// \return true if the mode video is in fullscreen and falss otherwise.///boolSystem::isFullScreen (void){    return Options::getInstance().isFullScreen();}////// \brief Tells if the sound subsystem could be initialized.////// \return \a true if the sound is enabled, \a false otherwise.///boolSystem::isSoundEnabled (void){    return m_SoundEnabled;}////// \brief Tells if unicode translation is enabled.////// \return \a true if unicode translation is enabled, \a false otherwise.///boolSystem::isUnicodeTranslationEnabled (void) const{    return m_UnicodeTranslationEnabled;}////// \brief Sets a new PauseState as the active state.///voidSystem::pause (void){    if ( 0 != m_ActiveState && m_ActiveState->shouldBePaused () )    {        setActiveState (new PauseState (), FadeNone);    }}////// \brief Removes the active state from the stack.////// The state doesn't get deleted at this time, it's scheduled/// to be deleted at the end of the current frame or at the end

⌨️ 快捷键说明

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