From: andy Date: Mon, 5 Apr 2004 21:39:32 +0000 (+0000) Subject: Early-access version of an SDL implementation of the fg_os API. It works, X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=52a2f920092cdc52a1f7d580aaf3eea305fa3b91;p=flightgear.git 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. --- diff --git a/src/Main/fg_os_sdl.cxx b/src/Main/fg_os_sdl.cxx new file mode 100644 index 000000000..fd3b7242e --- /dev/null +++ b/src/Main/fg_os_sdl.cxx @@ -0,0 +1,210 @@ +#include + +#include +#include + +#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 + // 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; }