2011-09-13 12:06:49 +00:00
|
|
|
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
|
|
|
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
|
|
|
*
|
|
|
|
* Some code herein may be based on code found in BSNES.
|
|
|
|
*
|
|
|
|
* SSNES 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 Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* SSNES 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 SSNES.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sdlwrap.h"
|
|
|
|
#include "SDL_syswm.h"
|
|
|
|
#include "general.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
#include <OpenGL/OpenGL.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// SDL 1.2 is portable, sure, but you still need some platform specific workarounds ;)
|
|
|
|
// Hopefully SDL 1.3 will solve this more cleanly :D
|
|
|
|
|
|
|
|
static bool g_fullscreen;
|
|
|
|
|
|
|
|
static unsigned g_interval;
|
|
|
|
void sdlwrap_set_swap_interval(unsigned interval, bool inited)
|
|
|
|
{
|
|
|
|
g_interval = interval;
|
|
|
|
|
2011-09-13 13:00:26 +00:00
|
|
|
#if SDL_MODERN
|
|
|
|
SDL_GL_SetSwapInterval(g_interval);
|
|
|
|
#else
|
2011-09-13 12:06:49 +00:00
|
|
|
if (inited)
|
|
|
|
{
|
|
|
|
#if defined(_WIN32)
|
|
|
|
static BOOL (APIENTRY *wgl_swap_interval)(int) = NULL;
|
|
|
|
if (!wgl_swap_interval)
|
|
|
|
{
|
|
|
|
SDL_SYM_WRAP(wgl_swap_interval, "wglSwapIntervalEXT");
|
|
|
|
}
|
|
|
|
if (wgl_swap_interval) wgl_swap_interval(g_interval);
|
|
|
|
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
GLint val = g_interval;
|
|
|
|
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &val);
|
|
|
|
#else
|
|
|
|
static int (*glx_swap_interval)(int) = NULL;
|
|
|
|
if (!glx_swap_interval)
|
|
|
|
{
|
|
|
|
SDL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalSGI");
|
|
|
|
}
|
|
|
|
if (!glx_swap_interval)
|
|
|
|
{
|
|
|
|
SDL_SYM_WRAP(glx_swap_interval, "glXSwapIntervalMESA");
|
|
|
|
}
|
|
|
|
if (glx_swap_interval)
|
|
|
|
glx_swap_interval(g_interval);
|
|
|
|
else
|
|
|
|
SSNES_WARN("Could not find GLX VSync call. :(\n");
|
|
|
|
#endif
|
|
|
|
}
|
2011-09-13 13:00:26 +00:00
|
|
|
#endif
|
2011-09-13 12:06:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool sdlwrap_set_video_mode(
|
|
|
|
unsigned width, unsigned height,
|
|
|
|
unsigned bits, bool fullscreen)
|
|
|
|
{
|
|
|
|
// Resizing in windowed mode appears to be broken on OSX. Yay!
|
|
|
|
#ifndef __APPLE__
|
|
|
|
static const int resizable = SDL_RESIZABLE;
|
|
|
|
#else
|
|
|
|
static const int resizable = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
|
|
|
|
|
|
#if !SDL_MODERN
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, g_interval);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!SDL_SetVideoMode(width, height, bits,
|
|
|
|
SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : resizable)))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int attr = 0;
|
|
|
|
#if SDL_MODERN
|
|
|
|
SDL_GL_SetSwapInterval(g_interval);
|
|
|
|
#else
|
|
|
|
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &attr);
|
|
|
|
if (attr <= 0 && g_interval)
|
|
|
|
{
|
|
|
|
SSNES_WARN("SDL failed to setup VSync, attempting to recover using native calls!\n");
|
|
|
|
sdlwrap_set_swap_interval(g_interval, true);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
g_fullscreen = fullscreen;
|
|
|
|
|
|
|
|
attr = 0;
|
|
|
|
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &attr);
|
|
|
|
if (attr <= 0)
|
|
|
|
SSNES_WARN("GL double buffer has not been enabled!\n");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sdlwrap_wm_set_caption(const char *str)
|
|
|
|
{
|
|
|
|
SDL_WM_SetCaption(str, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sdlwrap_swap_buffers(void)
|
|
|
|
{
|
|
|
|
SDL_GL_SwapBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool sdlwrap_key_pressed(int key)
|
|
|
|
{
|
|
|
|
int num_keys;
|
|
|
|
#if SDL_MODERN
|
|
|
|
Uint8 *keymap = SDL_GetKeyboardState(&num_keys);
|
|
|
|
key = SDL_GetScancodeFromKey(key);
|
|
|
|
if (key >= num_keys)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return keymap[key];
|
|
|
|
#else
|
|
|
|
Uint8 *keymap = SDL_GetKeyState(&num_keys);
|
|
|
|
if (key >= num_keys)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return keymap[key];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
|
|
|
static void sdlwrap_get_window_size(unsigned *width, unsigned *height)
|
|
|
|
{
|
|
|
|
SDL_SysWMinfo info;
|
|
|
|
SDL_VERSION(&info.version);
|
|
|
|
SDL_GetWMInfo(&info);
|
|
|
|
XWindowAttributes target;
|
|
|
|
|
|
|
|
#if SDL_MODERN
|
|
|
|
XGetWindowAttributes(info.info.x11.display, info.info.x11.window,
|
|
|
|
&target);
|
|
|
|
#else
|
|
|
|
info.info.x11.lock_func();
|
|
|
|
XGetWindowAttributes(info.info.x11.display, info.info.x11.window,
|
|
|
|
&target);
|
|
|
|
info.info.x11.unlock_func();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*width = target.width;
|
|
|
|
*height = target.height;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void sdlwrap_check_window(bool *quit,
|
|
|
|
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
|
|
|
{
|
|
|
|
*quit = false;
|
|
|
|
*resize = false;
|
|
|
|
|
|
|
|
SDL_Event event;
|
|
|
|
|
|
|
|
while (SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
switch (event.type)
|
|
|
|
{
|
|
|
|
case SDL_QUIT:
|
|
|
|
*quit = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_VIDEORESIZE:
|
|
|
|
*resize = true;
|
|
|
|
*width = event.resize.w;
|
|
|
|
*height = event.resize.h;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
|
|
|
// Hack to workaround limitations in tiling WMs ...
|
|
|
|
if (!*resize && !g_fullscreen)
|
|
|
|
{
|
|
|
|
unsigned new_width, new_height;
|
|
|
|
sdlwrap_get_window_size(&new_width, &new_height);
|
|
|
|
if ((new_width != *width || new_height != *height) || (frame_count == 10)) // Ugly hack :D
|
|
|
|
{
|
|
|
|
*resize = true;
|
|
|
|
*width = new_width;
|
|
|
|
*height = new_height;
|
|
|
|
SSNES_LOG("GL: Verified window size: %u x %u\n", *width, *height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|