diff options
-rw-r--r-- | backends/graphics/opengl/gltexture.cpp | 46 | ||||
-rw-r--r-- | backends/graphics/opengl/gltexture.h | 45 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 152 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 43 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 82 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.h | 7 |
6 files changed, 288 insertions, 87 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp index de9bd13eaf..139222bc36 100644 --- a/backends/graphics/opengl/gltexture.cpp +++ b/backends/graphics/opengl/gltexture.cpp @@ -60,7 +60,11 @@ void GLTexture::initGLExtensions() { } } -GLTexture::GLTexture() : +GLTexture::GLTexture(byte bpp, GLenum format, GLenum type) + : + _bytesPerPixel(bpp), + _glFormat(format), + _glType(type), _textureWidth(0), _textureHeight(0) { @@ -81,29 +85,29 @@ GLTexture::~GLTexture() { void GLTexture::refresh() { // Generates the texture ID for GL - CHECK_GL_ERROR( glGenTextures(1, &_textureName) ); + //CHECK_GL_ERROR( glGenTextures(1, &_textureName) ); + updateBuffer(_surface.pixels, _surface.bytesPerPixel, 0, 0, _surface.w, _surface.h); } void GLTexture::allocBuffer(GLuint w, GLuint h) { - int bpp = bytesPerPixel(); _surface.w = w; _surface.h = h; - _surface.bytesPerPixel = bpp; + _surface.bytesPerPixel = _bytesPerPixel; if (w <= _textureWidth && h <= _textureHeight) // Already allocated a sufficiently large buffer return; if (npot_supported) { - _textureWidth = _surface.w; - _textureHeight = _surface.h; + _textureWidth = w; + _textureHeight = h; } else { - _textureWidth = nextHigher2(_surface.w); - _textureHeight = nextHigher2(_surface.h); + _textureWidth = nextHigher2(w); + _textureHeight = nextHigher2(h); } - _surface.pitch = _textureWidth * bpp; + _surface.pitch = w * _bytesPerPixel; - _surface.create(w, h, bytesPerPixel()); + //_surface.create(w, h, _bytesPerPixel); // Allocate room for the texture now, but pixel data gets uploaded // later (perhaps with multiple TexSubImage2D operations). @@ -112,26 +116,26 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) { CHECK_GL_ERROR( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ); CHECK_GL_ERROR( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ); CHECK_GL_ERROR( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); - CHECK_GL_ERROR( glTexImage2D(GL_TEXTURE_2D, 0, glFormat(), + CHECK_GL_ERROR( glTexImage2D(GL_TEXTURE_2D, 0, _glFormat, _textureWidth, _textureHeight, - 0, glFormat(), glType(), NULL) ); + 0, _glFormat, _glType, NULL) ); } -void GLTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h, const void* buf, int pitch) { +void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLuint w, GLuint h) { CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) ); - if (static_cast<int>(w) * bytesPerPixel() == pitch) { + if (static_cast<int>(w) * _bytesPerPixel == pitch) { CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, - glFormat(), glType(), buf) ); - memcpy(_surface.pixels, buf, w * pitch); + _glFormat, _glType, buf) ); + //memcpy(_surface.pixels, buf, w * pitch); } else { // GLES removed the ability to specify pitch, so we // have to do this row by row. const byte* src = static_cast<const byte*>(buf); do { CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, - w, 1, glFormat(), glType(), src) ); - memcpy(_surface.pixels, src, pitch); + w, 1, _glFormat, _glType, src) ); + //memcpy(_surface.pixels, src, pitch); ++y; src += pitch; } while (--h); @@ -139,11 +143,11 @@ void GLTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h, const void* } void GLTexture::fillBuffer(byte x) { - byte* tmpbuf = new byte[_surface.h * _surface.w * bytesPerPixel()]; - memset(tmpbuf, 0, _surface.h * _surface.w * bytesPerPixel()); + byte* tmpbuf = new byte[_surface.h * _surface.w * _bytesPerPixel]; + memset(tmpbuf, 0, _surface.h * _surface.w * _bytesPerPixel); CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) ); CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _surface.w, _surface.h, - glFormat(), glType(), tmpbuf) ); + _glFormat, _glType, tmpbuf) ); delete[] tmpbuf; } diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h index 9238b73cf4..88a2b59962 100644 --- a/backends/graphics/opengl/gltexture.h +++ b/backends/graphics/opengl/gltexture.h @@ -55,61 +55,32 @@ class GLTexture { public: static void initGLExtensions(); - GLTexture(); + GLTexture(byte bpp, GLenum format, GLenum type); virtual ~GLTexture(); virtual void refresh(); virtual void allocBuffer(GLuint width, GLuint height); virtual void fillBuffer(byte x); - virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height, - const void* buf, int pitch); + virtual void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, + GLuint w, GLuint h); virtual void drawTexture() { drawTexture(0, 0, _surface.w, _surface.h); } virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); - const Graphics::Surface* getSurface() const { return &_surface; } + Graphics::Surface *getSurface() { return &_surface; } GLuint getWidth() const { return _surface.w; } GLuint getHeight() const { return _surface.h; } GLuint getTextureName() const { return _textureName; } protected: - virtual byte bytesPerPixel() const = 0; - virtual GLenum glFormat() const = 0; - virtual GLenum glType() const = 0; + const byte _bytesPerPixel; + const GLenum _glFormat; + const GLenum _glType; + Graphics::Surface _surface; GLuint _textureName; GLuint _textureWidth; GLuint _textureHeight; }; - -/** - * OpenGL RGBA 32 bit texture - */ -class GL32Texture : public GLTexture { -protected: - virtual byte bytesPerPixel() const { return 4; } - virtual GLenum glFormat() const { return GL_RGBA; } - virtual GLenum glType() const { return GL_UNSIGNED_BYTE; } -}; - -/** - * OpenGL RGBA4444 texture - */ -class GL4444Texture : public GLTexture { -protected: - virtual byte bytesPerPixel() const { return 2; } - virtual GLenum glFormat() const { return GL_RGBA; } - virtual GLenum glType() const { return GL_UNSIGNED_SHORT_4_4_4_4; } -}; - -/** - * OpenGL RGB565 texture - */ -class GL565Texture : public GLTexture { -protected: - virtual byte bytesPerPixel() const { return 2; } - virtual GLenum glFormat() const { return GL_RGB; } - virtual GLenum glType() const { return GL_UNSIGNED_SHORT_5_6_5; } -}; diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 71f0213a50..fc864957d8 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -29,8 +29,11 @@ OpenGLGraphicsManager::OpenGLGraphicsManager() : _gameTexture(0), _overlayTexture(0), _mouseTexture(0), + _overlayVisible(false), + _mouseVisible(false), _mouseNeedsRedraw(false), _screenChangeCount(0), - _transactionMode(0) + _currentShakePos(0), _newShakePos(0), + _transactionMode(kTransactionNone) { @@ -48,7 +51,23 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() { } void OpenGLGraphicsManager::init() { + GLTexture::initGLExtensions(); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDisable(GL_DITHER); + glShadeModel(GL_FLAT); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_TEXTURE_2D); } // @@ -85,21 +104,17 @@ int OpenGLGraphicsManager::getDefaultGraphicsMode() const { } bool OpenGLGraphicsManager::setGraphicsMode(int mode) { - return false; + return true; } int OpenGLGraphicsManager::getGraphicsMode() const { - return 0; + return GFX_NORMAL; } #ifdef USE_RGB_COLOR Graphics::PixelFormat OpenGLGraphicsManager::getScreenFormat() const { - return Graphics::PixelFormat(); -} - -Common::List<Graphics::PixelFormat> OpenGLGraphicsManager::getSupportedFormats() { - return Common::List<Graphics::PixelFormat>(); + return _screenFormat; } #endif @@ -135,7 +150,7 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi } int OpenGLGraphicsManager::getScreenChangeID() const { - return 0; + return _screenChangeCount; } // @@ -267,28 +282,32 @@ void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) { } void OpenGLGraphicsManager::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { - + _gameTexture->updateBuffer(buf, pitch, x, y, w, h); } Graphics::Surface *OpenGLGraphicsManager::lockScreen() { - _lockedScreen = Graphics::Surface(); - return &_lockedScreen; + return _gameTexture->getSurface(); } void OpenGLGraphicsManager::unlockScreen() { - + _gameTexture->refresh(); } void OpenGLGraphicsManager::fillScreen(uint32 col) { + if (_gameTexture == NULL) + return; + _gameTexture->fillBuffer(col); } void OpenGLGraphicsManager::updateScreen() { - + assert (_transactionMode == kTransactionNone); + internUpdateScreen(); } void OpenGLGraphicsManager::setShakePos(int shakeOffset) { - + assert (_transactionMode == kTransactionNone); + _newShakePos = shakeOffset; } void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) { @@ -304,27 +323,43 @@ void OpenGLGraphicsManager::clearFocusRectangle() { // void OpenGLGraphicsManager::showOverlay() { + assert (_transactionMode == kTransactionNone); + _overlayVisible = true; } void OpenGLGraphicsManager::hideOverlay() { + assert (_transactionMode == kTransactionNone); + _overlayVisible = false; } Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const { - return Graphics::PixelFormat(); + return _overlayFormat; } void OpenGLGraphicsManager::clearOverlay() { - + _overlayTexture->fillBuffer(0); } void OpenGLGraphicsManager::grabOverlay(OverlayColor *buf, int pitch) { - + const Graphics::Surface* surface = _overlayTexture->getSurface(); + assert(surface->bytesPerPixel == sizeof(buf[0])); + int h = surface->h; + do { + //memcpy(buf, surface->pixels, surface->w * sizeof(buf[0])); + memset(buf, 0, surface->w * sizeof(buf[0])); + buf += pitch; + } while (--h); } void OpenGLGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { + assert (_transactionMode == kTransactionNone); + + if (_overlayTexture == NULL) + return; + _overlayTexture->updateBuffer(buf, pitch * sizeof(buf[0]), x, y, w, h); } int16 OpenGLGraphicsManager::getOverlayHeight() { @@ -340,11 +375,26 @@ int16 OpenGLGraphicsManager::getOverlayWidth() { // bool OpenGLGraphicsManager::showMouse(bool visible) { - return false; + if (_mouseVisible == visible) + return visible; + + bool last = _mouseVisible; + _mouseVisible = visible; + _mouseNeedsRedraw = true; + + return last; } -void OpenGLGraphicsManager::warpMouse(int x, int y) { +void OpenGLGraphicsManager::setMousePos(int x, int y) { + if (x != _mouseCurState.x || y != _mouseCurState.y) { + _mouseNeedsRedraw = true; + _mouseCurState.x = x; + _mouseCurState.y = y; + } +} +void OpenGLGraphicsManager::warpMouse(int x, int y) { + setMousePos(x, y); } void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { @@ -371,12 +421,72 @@ void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) { // Intern // +void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &glFormat, GLenum &type) { + if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888 + bpp = 4; + glFormat = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } else if (pixelFormat == Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0)) { // RGB888 + bpp = 3; + glFormat = GL_RGB; + type = GL_UNSIGNED_BYTE; + } else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565 + bpp = 2; + glFormat = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + } else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555 + bpp = 2; + glFormat = GL_RGB; + type = GL_UNSIGNED_SHORT_5_5_5_1; + } else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444 + bpp = 2; + glFormat = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4; + } else if (pixelFormat == Graphics::PixelFormat::createFormatCLUT8()) { // CLUT8 + bpp = 1; + glFormat = GL_RGB; + type = GL_COLOR_INDEX; + } else { + error("Not supported format"); + } +} + void OpenGLGraphicsManager::internUpdateScreen() { } bool OpenGLGraphicsManager::loadGFXMode() { - return false; + if (!_gameTexture) { + byte bpp; + GLenum format; + GLenum type; + getGLPixelFormat(_screenFormat, bpp, format, type); + _gameTexture = new GLTexture(bpp, format, type); + } else + _gameTexture->refresh(); + + if (!_overlayTexture) + _overlayTexture = new GLTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); + else + _overlayTexture->refresh(); + + if (!_mouseTexture) + _mouseTexture = new GLTexture(4, GL_RGBA, GL_UNSIGNED_BYTE); + else + _mouseTexture->refresh(); + + _gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight); + _overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight); + + glViewport(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _videoMode.hardwareWidth, _videoMode.hardwareHeight, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + return true; } void OpenGLGraphicsManager::unloadGFXMode() { diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index cbf81db9b0..f12e4b45d7 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -53,7 +53,7 @@ public: virtual int getGraphicsMode() const; #ifdef USE_RGB_COLOR virtual Graphics::PixelFormat getScreenFormat() const; - virtual Common::List<Graphics::PixelFormat> getSupportedFormats(); + virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0; #endif virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL); virtual int getScreenChangeID() const; @@ -91,11 +91,15 @@ public: virtual void displayMessageOnOSD(const char *msg); + virtual void setMousePos(int x, int y); + protected: GLTexture* _gameTexture; GLTexture* _overlayTexture; GLTexture* _mouseTexture; + virtual void getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &glFormat, GLenum &type); + virtual void internUpdateScreen(); virtual bool loadGFXMode(); virtual void unloadGFXMode(); @@ -109,6 +113,9 @@ protected: Graphics::PixelFormat _cursorFormat; #endif + bool _overlayVisible; + Graphics::PixelFormat _overlayFormat; + enum { kTransactionNone = 0, kTransactionActive = 1, @@ -144,6 +151,40 @@ protected: #endif }; VideoState _videoMode, _oldVideoMode; + + + struct MousePos { + // The mouse position, using either virtual (game) or real + // (overlay) coordinates. + int16 x, y; + + // The size and hotspot of the original cursor image. + int16 w, h; + int16 hotX, hotY; + + // The size and hotspot of the pre-scaled cursor image, in real + // coordinates. + int16 rW, rH; + int16 rHotX, rHotY; + + // The size and hotspot of the pre-scaled cursor image, in game + // coordinates. + int16 vW, vH; + int16 vHotX, vHotY; + + MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0), + rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0), + vHotX(0), vHotY(0) + { } + }; + + MousePos _mouseCurState; + bool _mouseVisible; + bool _mouseNeedsRedraw; + + // Shake mode + int _currentShakePos; + int _newShakePos; }; #endif diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 589e5aa2c6..6207561c07 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -45,6 +45,81 @@ void OpenGLSdlGraphicsManager::init() { OpenGLGraphicsManager::init(); } +#ifdef USE_RGB_COLOR + +const Graphics::PixelFormat RGBList[] = { +#if defined(ENABLE_32BIT) + Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), // RGBA8888 + Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), // RGB888 +#endif + Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), // RGB565 + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), // RGB555 + Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), // RGBA4444 +}; + +Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormats() { + static Common::List<Graphics::PixelFormat> list; + static bool inited = false; + + if (inited) + return list; + + int listLength = ARRAYSIZE(RGBList); + + Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); + if (_hwscreen) { + // Get our currently set hardware format + format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel, + 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss, + 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss, + _hwscreen->format->Rshift, _hwscreen->format->Gshift, + _hwscreen->format->Bshift, _hwscreen->format->Ashift); + + // Workaround to MacOSX SDL not providing an accurate Aloss value. + if (_hwscreen->format->Amask == 0) + format.aLoss = 8; + + // Push it first, as the prefered format. + for (int i = 0; i < listLength; i++) { + if (RGBList[i] == format) { + list.push_back(format); + break; + } + } + + // Mark that we don't need to do this any more. + inited = true; + } + + for (int i = 0; i < listLength; i++) { + if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel)) + continue; + if (RGBList[i] != format) + list.push_back(RGBList[i]); + } + //list.push_back(Graphics::PixelFormat::createFormatCLUT8()); + return list; +} + +#endif + +void OpenGLSdlGraphicsManager::warpMouse(int x, int y) { + if (_mouseCurState.x != x || _mouseCurState.y != y) { + int y1 = y; + + /*if (_videoMode.aspectRatioCorrection && !_overlayVisible) + y1 = real2Aspect(y);*/ + + if (!_overlayVisible) + SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor); + else + SDL_WarpMouse(x, y1); + + setMousePos(x, y); + } +} + + void OpenGLSdlGraphicsManager::forceFullRedraw() { } @@ -61,10 +136,6 @@ void OpenGLSdlGraphicsManager::adjustMouseEvent(Common::Event &event) { } -void OpenGLSdlGraphicsManager::setMousePos(int x, int y) { - -} - void OpenGLSdlGraphicsManager::toggleFullScreen() { } @@ -83,7 +154,6 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor; - _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, _videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : SDL_OPENGL ); @@ -99,7 +169,7 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { } } - return true; + return OpenGLGraphicsManager::loadGFXMode(); } void OpenGLSdlGraphicsManager::unloadGFXMode() { diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h index 9f18489430..0f69793c1b 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.h +++ b/backends/graphics/openglsdl/openglsdl-graphics.h @@ -44,11 +44,16 @@ public: virtual void init(); +#ifdef USE_RGB_COLOR + virtual Common::List<Graphics::PixelFormat> getSupportedFormats(); +#endif + + virtual void warpMouse(int x, int y); + virtual void forceFullRedraw(); virtual bool handleScalerHotkeys(const SDL_KeyboardEvent &key); virtual bool isScalerHotkey(const Common::Event &event); virtual void adjustMouseEvent(Common::Event &event); - virtual void setMousePos(int x, int y); virtual void toggleFullScreen(); virtual bool saveScreenshot(const char *filename); |