1
0
Fork 0

Early-access version of an SDL implementation of the fg_os API. It works,

but is not integrated into the build process.  It also lacks support for
changing mouse cursors, which works rather differently in SDL vs. Glut.
This commit is contained in:
andy 2004-04-05 21:39:32 +00:00
parent f46f962ca0
commit 52a2f92009

210
src/Main/fg_os_sdl.cxx Normal file
View file

@ -0,0 +1,210 @@
#include <stdlib.h>
#include <SDL/SDL.h>
#include <plib/pu.h>
#include "fg_os.hxx"
//
// fg_os callback registration APIs
//
static fgIdleHandler IdleHandler = 0;
static fgDrawHandler DrawHandler = 0;
static fgKeyHandler KeyHandler = 0;
static fgMouseClickHandler MouseClickHandler = 0;
static fgMouseMotionHandler MouseMotionHandler = 0;
static int CurrentModifiers = 0;
static int CurrentMouseX = 0;
static int CurrentMouseY = 0;
static bool NeedRedraw = false;
void fgRegisterIdleHandler(fgIdleHandler func)
{
IdleHandler = func;
}
void fgRegisterDrawHandler(fgDrawHandler func)
{
DrawHandler = func;
NeedRedraw = true;
}
void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
{
// Noop. SDL does not support window resize.
}
void fgRegisterKeyHandler(fgKeyHandler func)
{
KeyHandler = func;
}
void fgRegisterMouseClickHandler(fgMouseClickHandler func)
{
MouseClickHandler = func;
}
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
{
MouseMotionHandler = func;
}
//
// fg_os implementation
//
void fgOSOpenWindow(int w, int h, int bpp, bool alpha, bool fullscreen)
{
int cbits = (bpp <= 16) ? 5 : 8;
int zbits = (bpp <= 16) ? 16 : 32;
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE); // FIXME: handle errors
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, cbits);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, cbits);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, cbits);
if(alpha)
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, zbits);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int vidmask = SDL_OPENGL;
if(fullscreen) vidmask |= SDL_FULLSCREEN;
SDL_SetVideoMode(w, h, 16, vidmask); // FIXME: handle errors
SDL_WM_SetCaption("FlightGear", "FlightGear");
// This enables keycode translation (e.g. capital letters when
// shift is pressed, as well as i18n input methods). Eventually,
// we may want to port the input maps to specify <mod-shift>
// explicitly, and will turn this off.
SDL_EnableUNICODE(1);
// FIXME: we may not get what we asked for (especially in full
// screen modes), so these need to be propagated back to the
// property tree for the rest of the code to inspect...
//
// SDL_Surface* screen = SDL_GetVideoSurface();
// int realw = screen->w;
// int realh = screen->h;
}
static void handleKey(int key, int keyup)
{
int modmask = 0;
switch(key) {
case SDLK_RSHIFT: modmask = KEYMOD_SHIFT; break;
case SDLK_LSHIFT: modmask = KEYMOD_SHIFT; break;
case SDLK_RCTRL: modmask = KEYMOD_CTRL; break;
case SDLK_LCTRL: modmask = KEYMOD_CTRL; break;
case SDLK_RALT: modmask = KEYMOD_ALT; break;
case SDLK_LALT: modmask = KEYMOD_ALT; break;
case SDLK_LEFT: key = PU_KEY_LEFT; break;
case SDLK_UP: key = PU_KEY_UP; break;
case SDLK_RIGHT: key = PU_KEY_RIGHT; break;
case SDLK_DOWN: key = PU_KEY_DOWN; break;
case SDLK_PAGEUP: key = PU_KEY_PAGE_UP; break;
case SDLK_PAGEDOWN: key = PU_KEY_PAGE_DOWN; break;
case SDLK_HOME: key = PU_KEY_HOME; break;
case SDLK_END: key = PU_KEY_END; break;
case SDLK_INSERT: key = PU_KEY_INSERT; break;
case SDLK_F1: key = PU_KEY_F1; break;
case SDLK_F2: key = PU_KEY_F2; break;
case SDLK_F3: key = PU_KEY_F3; break;
case SDLK_F4: key = PU_KEY_F4; break;
case SDLK_F5: key = PU_KEY_F5; break;
case SDLK_F6: key = PU_KEY_F6; break;
case SDLK_F7: key = PU_KEY_F7; break;
case SDLK_F8: key = PU_KEY_F8; break;
case SDLK_F9: key = PU_KEY_F9; break;
case SDLK_F10: key = PU_KEY_F10; break;
case SDLK_F11: key = PU_KEY_F11; break;
case SDLK_F12: key = PU_KEY_F12; break;
}
if(keyup) CurrentModifiers &= ~modmask;
else CurrentModifiers |= modmask;
if(modmask == 0 && KeyHandler)
(*KeyHandler)(key, CurrentModifiers, CurrentMouseX, CurrentMouseY);
}
// FIXME: need to export this and get the rest of FlightGear to use
// it, the SDL hook is required to do things like reset the video
// mode and key repeat. Integrate with existing fgExit() in util.cxx.
void fgOSExit(int code)
{
SDL_Quit();
exit(code);
}
void fgOSMainLoop()
{
while(1) {
SDL_Event e;
while(SDL_PollEvent(&e)) {
switch(e.type) {
case SDL_QUIT:
fgOSExit(0);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
handleKey(e.key.keysym.unicode, e.key.state == SDL_RELEASED);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
// Note offset: SDL uses buttons 1,2,3 not 0,1,2
CurrentMouseX = e.button.x;
CurrentMouseY = e.button.y;
if(MouseClickHandler)
(*MouseClickHandler)(e.button.button - 1,
e.button.state == SDL_RELEASED,
e.button.x, e.button.y);
break;
case SDL_MOUSEMOTION:
CurrentMouseX = e.motion.x;
CurrentMouseY = e.motion.y;
if(MouseMotionHandler)
(*MouseMotionHandler)(e.motion.x, e.motion.y);
break;
}
}
if(IdleHandler) (*IdleHandler)();
if(NeedRedraw && DrawHandler) {
(*DrawHandler)();
SDL_GL_SwapBuffers();
NeedRedraw = false;
}
}
}
int fgGetKeyModifiers()
{
return CurrentModifiers;
}
void fgWarpMouse(int x, int y)
{
SDL_WarpMouse(x, y);
}
void fgRequestRedraw()
{
NeedRedraw = true;
}
void fgOSInit(int* argc, char** argv)
{
// Nothing to do here. SDL has no command line options.
}
void fgOSFullScreen()
{
// Noop. SDL must set fullscreen at window open time and cannot
// change modes.
}
// Figure out what to do with these
void fgSetMouseCursor(int cursor) {}
int fgGetMouseCursor() { return MOUSE_CURSOR_POINTER; }