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 + -
显示快捷键?