/* * PlanetPenguin Racer * Copyright (C) 2004-2005 Volker Stroebel * * Copyright (C) 1999-2001 Jasmin F. Patry * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "winsys.h" #include "loop.h" #include "render_util.h" #include "ppogl/base/glwrappers.h" extern void cleanup(); /* Windowing System Abstraction Layer */ /* Abstracts creation of windows, handling of events, etc. */ #if defined( HAVE_SDL_MIXER ) # include "SDL_mixer.h" #endif static SDL_Surface *screen = NULL; /*---------------------------------------------------------------------------*/ /*! Copies the OpenGL back buffer to the front buffer \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_swap_buffers() { SDL_GL_SwapBuffers(); } /*---------------------------------------------------------------------------*/ /*! Moves the mouse pointer to (x,y) \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_warp_pointer( int x, int y ) { SDL_WarpMouse( x, y ); } /*---------------------------------------------------------------------------*/ /*! Sets up the SDL OpenGL rendering context \author jfpatry \date Created: 2000-10-20 \date Modified: 2000-10-20 */ void setup_sdl_video_mode() { Uint32 video_flags = SDL_OPENGL; int bpp = 0; int width, height; if (ppogl::Config::getInstance().getBool("fullscreen")) { video_flags |= SDL_FULLSCREEN; } else { video_flags |= SDL_RESIZABLE; } #if SDL_VERSION_ATLEAST(1,2,6) if(ppogl::Config::getInstance().getBool("enable_fsaa")){ //enable FSAA SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, PPConfig.getInt("multisamples")); } #endif if(ppogl::Config::getInstance().getBool("stencil_buffer")){ SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); } switch(PPConfig.getInt("bpp_mode")){ case 0: /* Use current bpp */ bpp = 0; break; case 1: /* 16 bpp */ bpp = 16; break; case 2: /* 32 bpp */ bpp = 32; break; default: PPConfig.setInt("bpp_mode", 0); bpp = 0; } width = PPConfig.getInt("x_resolution"); if(PPConfig.getBool("x_resolution_half_width")){ width /=2; } height = PPConfig.getInt("y_resolution"); if ( ( screen = SDL_SetVideoMode( width, height, bpp, video_flags ) ) == NULL ){ PP_ERROR( "Couldn't initialize video: " << SDL_GetError() ); } GameMode::resolutionX = width; GameMode::resolutionY = height; gl::Viewport(0,0,width,height); } /*---------------------------------------------------------------------------*/ /*! Initializes the OpenGL rendering context, and creates a window (or sets up fullscreen mode if selected) \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_init(char *window_title, char *icon_title) { Uint32 sdl_flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; /* * Initialize SDL */ if(SDL_Init(sdl_flags) < 0){ PP_ERROR("Couldn't initialize SDL: " << SDL_GetError()); } /* * Init video */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); setup_sdl_video_mode(); SDL_WM_SetCaption(window_title, icon_title); } /*---------------------------------------------------------------------------*/ /*! Deallocates resources in preparation for program termination \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_shutdown() { SDL_Quit(); } /*---------------------------------------------------------------------------*/ /*! Enables/disables key repeat messages from being generated \return \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_enable_key_repeat( bool enabled ) { if ( enabled ) { SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); } else { SDL_EnableKeyRepeat( 0, 0 ); } } /*---------------------------------------------------------------------------*/ /*! Shows/hides mouse cursor \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_show_cursor( bool visible ) { SDL_ShowCursor( visible ); } /*---------------------------------------------------------------------------*/ /*! Processes and dispatches events. This function never returns. \return No. \author jfpatry \date Created: 2000-10-19 \date Modified: 2000-10-19 */ void winsys_process_events() { SDL_Event event; int x, y; while (true) { SDL_LockAudio(); SDL_UnlockAudio(); while ( SDL_PollEvent( &event ) ) { switch ( event.type ) { case SDL_KEYDOWN: SDL_GetMouseState( &x, &y ); loop_keyboard_func( event.key.keysym.sym, event.key.keysym.mod, false, x, y ); break; case SDL_KEYUP: SDL_GetMouseState( &x, &y ); loop_keyboard_func( event.key.keysym.sym, event.key.keysym.mod, true, x, y ); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: loop_mouse_func( event.button.button, event.button.state, event.button.x, event.button.y ); break; case SDL_MOUSEMOTION: if ( event.motion.state ) { /* buttons are down */ loop_mouse_motion_func( event.motion.x, event.motion.y ); } else { /* no buttons are down */ loop_mouse_motion_func( event.motion.x, event.motion.y ); } break; case SDL_VIDEORESIZE: PPConfig.setInt("x_resolution",event.resize.w); PPConfig.setInt("y_resolution",event.resize.h); setup_sdl_video_mode(); reshape( event.resize.w, event.resize.h ); break; case SDL_QUIT: winsys_exit(0); break; } SDL_LockAudio(); SDL_UnlockAudio(); } GameMode::mainLoop(); /* Delay for 1 ms. This allows the other threads to do some work (otherwise the audio thread gets starved). */ SDL_Delay(1); } /* Never exits */ PP_NOT_REACHED(); } /*---------------------------------------------------------------------------*/ /*! Exits the program \author jfpatry \date Created: 2000-10-20 \date Modified: 2000-10-20 */ void winsys_exit(int code) { cleanup(); exit(code); }