Files
itgmania212121/stepmania/src/arch/LowLevelWindow/LowLevelWindow_SDL.cpp
T

265 lines
8.2 KiB
C++
Raw Normal View History

2003-04-07 00:54:32 +00:00
#include "global.h"
#include "LowLevelWindow_SDL.h"
2003-05-25 21:58:34 +00:00
#include "SDL_utils.h"
2003-04-07 00:54:32 +00:00
#include "RageLog.h"
#include "RageDisplay.h" // for REFRESH_DEFAULT
2004-06-14 03:13:13 +00:00
#include "StepMania.h"
2005-12-17 13:03:04 +00:00
#include "arch/ArchHooks/ArchHooks.h"
2005-11-28 17:17:16 +00:00
#include "DisplayResolutions.h"
2003-04-07 00:54:32 +00:00
#if defined(MACOSX)
extern "C"
{
extern void SetupWindow();
extern void SM_ShowCursor( bool b );
}
// SDL_ShowCursor doesn't seem to work on OS X any longer
#define SDL_ShowCursor(x) SM_ShowCursor( (x) == SDL_ENABLE )
#endif
2004-06-14 05:50:40 +00:00
2003-04-07 00:54:32 +00:00
LowLevelWindow_SDL::LowLevelWindow_SDL()
{
/* By default, ignore all SDL events. We'll enable them as we need them.
* We must not enable any events we don't actually want, since we won't
* query for them and they'll fill up the event queue.
*
* This needs to be done after we initialize video, since it's really part
* of the SDL video system--it'll be reinitialized on us if we do this first. */
SDL_EventState(0xFF /*SDL_ALLEVENTS*/, SDL_IGNORE);
2004-06-14 03:55:38 +00:00
SDL_EventState( SDL_VIDEORESIZE, SDL_ENABLE );
SDL_EventState( SDL_ACTIVEEVENT, SDL_ENABLE );
SDL_EventState( SDL_QUIT, SDL_ENABLE );
}
LowLevelWindow_SDL::~LowLevelWindow_SDL()
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
2004-06-14 03:55:38 +00:00
mySDL_EventState( SDL_VIDEORESIZE, SDL_IGNORE );
mySDL_EventState( SDL_ACTIVEEVENT, SDL_IGNORE );
mySDL_EventState( SDL_QUIT, SDL_IGNORE );
}
void *LowLevelWindow_SDL::GetProcAddress(CString s)
{
return SDL_GL_GetProcAddress(s);
}
2005-11-26 07:22:33 +00:00
CString LowLevelWindow_SDL::TryVideoMode( const VideoModeParams &p, bool &bNewDeviceOut )
{
bool wasWindowed = CurrentParams.windowed;
2003-06-05 19:29:27 +00:00
CurrentParams = p;
/* We need to preserve the event mask and all events, since they're lost by
* SDL_QuitSubSystem(SDL_INIT_VIDEO). */
vector<SDL_Event> events;
mySDL_GetAllEvents(events);
Uint8 EventEnabled[SDL_NUMEVENTS];
/* Queue up key-up events for all keys that are currently down (eg. alt-enter).
* This is normally done by SDL, but since we're shutting down the video system
* we're also shutting down the event system. */
{
const Uint8 *KeyState = SDL_GetKeyState(NULL);
for ( SDLKey key=SDLK_FIRST; key<SDLK_LAST; key = (SDLKey)(key+1) )
{
if ( KeyState[key] != SDL_PRESSED )
continue;
SDL_Event e;
memset(&e, 0, sizeof(e));
e.key.type = SDL_KEYUP;
e.key.keysym.sym = key;
events.push_back(e);
}
}
2004-09-25 05:10:10 +00:00
for( int i = 0; i < SDL_NUMEVENTS; ++i )
EventEnabled[i] = mySDL_EventState( (Uint8) i, SDL_QUERY );
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if( SDL_InitSubSystem(SDL_INIT_VIDEO) == -1 )
2004-05-20 23:50:34 +00:00
{
const CString err = mySDL_GetError();
2004-05-20 23:50:34 +00:00
/* Check for a confusing SDL error message. */
if( !err.CompareNoCase( "X11 driver not configured with OpenGL" ) )
RageException::Throw( "Your installation of SDL was not compiled with OpenGL enabled." );
RageException::Throw( "SDL_INIT_VIDEO failed: %s", err.c_str() );
}
/* Put them back. */
2004-09-25 05:10:10 +00:00
for( int i = 0; i < SDL_NUMEVENTS; ++i)
mySDL_EventState((Uint8) i, EventEnabled[i]);
mySDL_PushEvents(events);
/* Set SDL window title, icon and cursor -before- creating the window */
2003-06-05 19:29:27 +00:00
SDL_WM_SetCaption( p.sWindowTitle, "");
mySDL_WM_SetIcon( p.sIconFile );
SDL_ShowCursor( p.windowed ? SDL_ENABLE : SDL_DISABLE );
2004-05-20 23:50:34 +00:00
int flags = SDL_RESIZABLE | SDL_OPENGL;
2003-06-05 19:29:27 +00:00
if( !p.windowed )
2003-04-07 00:54:32 +00:00
flags |= SDL_FULLSCREEN;
2003-06-05 19:29:27 +00:00
ASSERT( p.bpp == 16 || p.bpp == 32 );
switch( p.bpp )
2003-04-07 00:54:32 +00:00
{
case 16:
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
break;
case 32:
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
}
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true);
2005-01-20 02:07:02 +00:00
#if defined(LINUX)
/* nVidia cards:
*
* This only works the first time we set up a window; after that, the
* drivers appear to cache the value, so you have to actually restart
* the program to change it again. */
static char buf[128];
strcpy( buf, "__GL_SYNC_TO_VBLANK=" );
strcat( buf, p.vsync?"1":"0" );
putenv( buf );
2003-04-07 00:54:32 +00:00
#endif
SDL_Surface *screen = SDL_SetVideoMode( p.width, p.height, p.bpp, flags );
if( !screen )
2003-06-05 19:29:27 +00:00
{
LOG->Trace( "SDL_SetVideoMode failed: %s", mySDL_GetError().c_str() );
SDL_ShowCursor( wasWindowed ? SDL_ENABLE : SDL_DISABLE );
return mySDL_GetError(); // failed to set mode
2003-06-05 19:29:27 +00:00
}
2003-06-05 19:29:27 +00:00
bNewDeviceOut = true; // always a new context because we're resetting SDL_Video
2003-04-07 00:54:32 +00:00
2004-06-14 05:19:42 +00:00
static bool bLogged = false;
if( !bLogged )
{
bLogged = true;
const SDL_version *ver = SDL_Linked_Version();
LOG->Info( "SDL version: %i.%i.%i", ver->major, ver->minor, ver->patch );
}
#if defined(MACOSX)
if (p.windowed)
SetupWindow();
#endif
2004-06-14 05:50:40 +00:00
2003-04-07 00:54:32 +00:00
{
/* Find out what we really got. */
int r,g,b,a, colorbits, depth, stencil;
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &colorbits);
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth);
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil);
LOG->Info("Got %i bpp (%i%i%i%i), %i depth, %i stencil",
colorbits, r, g, b, a, depth, stencil);
}
return ""; // we set the video mode successfully
2003-04-07 00:54:32 +00:00
}
void LowLevelWindow_SDL::SwapBuffers()
{
SDL_GL_SwapBuffers();
}
2005-07-12 23:14:21 +00:00
void LowLevelWindow_SDL::Update()
{
2004-06-14 03:55:38 +00:00
/* This needs to be called before anything that handles SDL events. */
SDL_PumpEvents();
2004-06-14 03:13:13 +00:00
SDL_Event event;
2004-06-14 03:55:38 +00:00
while(SDL_GetEvent(event, SDL_VIDEORESIZEMASK|SDL_ACTIVEEVENTMASK|SDL_QUITMASK))
{
switch(event.type)
{
case SDL_VIDEORESIZE:
2003-06-05 19:29:27 +00:00
CurrentParams.width = event.resize.w;
CurrentParams.height = event.resize.h;
/* Let DISPLAY know that our resolution has changed. */
DISPLAY->ResolutionChanged();
break;
case SDL_ACTIVEEVENT:
2004-06-14 03:13:13 +00:00
/* We don't care about mouse focus. */
if(event.active.state == SDL_APPMOUSEFOCUS)
break;
if( event.active.gain && // app regaining focus
!DISPLAY->GetActualVideoModeParams().windowed ) // full screen
{
// need to reacquire an OGL context
2004-06-14 03:13:13 +00:00
/* This hasn't been done in a long time, since HandleSDLEvents was
* handling this event before we got it. I tried reenablng it, and
* it resulted in input not being regained and textures being erased,
* so I left it disabled; but this might be needed on some cards (with
* the above fixed) ... */
// DISPLAY->SetVideoMode( DISPLAY->GetActualVideoModeParams() );
2004-06-14 03:13:13 +00:00
}
{
uint8_t i = SDL_GetAppState();
2004-09-14 19:05:53 +00:00
LOG->Trace( "SDL_GetAppState: %i", i );
2005-12-07 00:34:11 +00:00
StepMania::FocusChanged( i&SDL_APPINPUTFOCUS && i&SDL_APPACTIVE );
}
break;
2004-06-14 03:55:38 +00:00
case SDL_QUIT:
LOG->Trace("SDL_QUIT: shutting down");
2005-12-17 13:03:04 +00:00
ArchHooks::SetUserQuit();
2004-06-14 03:55:38 +00:00
break;
}
}
}
2005-11-28 17:17:16 +00:00
void LowLevelWindow_SDL::GetDisplayResolutions( DisplayResolutions &out ) const
{
SDL_Rect **modes = SDL_ListModes(NULL, SDL_RESIZABLE | SDL_OPENGL | SDL_FULLSCREEN );
ASSERT_M( modes, "No modes available" );
for(int i=0; modes[i]; ++i )
{
DisplayResolution res = { modes[i]->w, modes[i]->h };
out.s.insert( res );
}
}
2004-05-15 22:30:30 +00:00
/*
* (c) 2003-2004 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/